vlan_rcm.c revision d62bc4badc1c1f1549c961cfb8b420e650e1272b
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * CDDL HEADER START
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * The contents of this file are subject to the terms of the
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * Common Development and Distribution License (the "License").
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * You may not use this file except in compliance with the License.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * See the License for the specific language governing permissions
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * and limitations under the License.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * When distributing Covered Code, include this CDDL HEADER in each
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * If applicable, add the following below this CDDL HEADER, with the
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * fields enclosed by brackets "[]" replaced with your own identifying
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * information: Portions Copyright [yyyy] [name of copyright owner]
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * CDDL HEADER END
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * Use is subject to license terms.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#pragma ident "%Z%%M% %I% %E% SMI"
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * This RCM module adds support to the RCM framework for VLAN links
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Definitions
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#define _(x) gettext(x)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#define _(x) x
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/* Some generic well-knowns and defaults used in this module */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#define RCM_LINK_PREFIX "SUNW_datalink" /* RCM datalink name prefix */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#define RCM_LINK_RESOURCE_MAX (13 + LINKID_STR_WIDTH)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/* VLAN link flags */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstontypedef enum {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/* link representation */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstontypedef struct dl_vlan {
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock struct dl_vlan *dv_next; /* next VLAN on the same link */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston struct dl_vlan *dv_prev; /* prev VLAN on the same link */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/* VLAN Cache state flags */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstontypedef enum {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston CACHE_NODE_STALE = 0x1, /* stale cached data */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston CACHE_NODE_NEW = 0x2, /* new cached nodes */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston CACHE_NODE_OFFLINED = 0x4 /* nodes offlined */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/* Network Cache lookup options */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#define CACHE_NO_REFRESH 0x1 /* cache refresh not needed */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston#define CACHE_REFRESH 0x2 /* refresh cache */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/* Cache element */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstontypedef struct link_cache {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston struct link_cache *vc_next; /* next cached resource */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston struct link_cache *vc_prev; /* prev cached resource */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston dl_vlan_t *vc_vlan; /* VLAN list on this link */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston cache_node_state_t vc_state; /* cache state flags */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Global cache for network VLANs
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * RCM module interface prototypes
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int vlan_get_info(rcm_handle_t *, char *, id_t, uint_t,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston char **, char **, nvlist_t *, rcm_info_t **);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int vlan_suspend(rcm_handle_t *, char *, id_t,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int vlan_resume(rcm_handle_t *, char *, id_t, uint_t,
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrockstatic int vlan_offline(rcm_handle_t *, char *, id_t, uint_t,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int vlan_undo_offline(rcm_handle_t *, char *, id_t, uint_t,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int vlan_remove(rcm_handle_t *, char *, id_t, uint_t,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int vlan_notify_event(rcm_handle_t *, char *, id_t, uint_t,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int vlan_configure(rcm_handle_t *, datalink_id_t);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/* Module private routines */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic link_cache_t *cache_lookup(rcm_handle_t *, char *, char);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int vlan_consumer_offline(rcm_handle_t *, link_cache_t *,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic void vlan_consumer_online(rcm_handle_t *, link_cache_t *,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int vlan_offline_vlan(link_cache_t *, uint32_t,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic void vlan_online_vlan(link_cache_t *);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic void vlan_log_err(datalink_id_t, char **, char *);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonstatic int vlan_consumer_notify(rcm_handle_t *, datalink_id_t,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston/* Module-Private data */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * rcm_mod_init() - Update registrations, and return the ops structure.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: mod_init\n");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* Return the ops vectors */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * rcm_mod_info() - Return a string describing this module.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock rcm_log_message(RCM_TRACE1, "VLAN: mod_info\n");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston return ("VLAN module version %I%");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * rcm_mod_fini() - Destroy the network VLAN cache.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: mod_fini\n");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Note that vlan_unregister() does not seem to be called anywhere,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * therefore we free the cache nodes here. In theory we should call
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * rcm_register_interest() for each node before we free it, the
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * framework does not provide the rcm_handle to allow us to do so.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * vlan_register() - Make sure the cache is properly sync'ed, and its
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * registrations are in order.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: register\n");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Need to register interest in all new resources
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * getting attached, so we get attach event notifications
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (rcm_register_event(hd, RCM_RESOURCE_LINK_NEW, 0, NULL)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston _("VLAN: failed to register %s\n"),
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_DEBUG, "VLAN: registered %s\n",
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * vlan_unregister() - Walk the cache, unregistering all the networks.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: unregister\n");
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock /* Walk the cache, unregistering everything */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (rcm_unregister_interest(hd, node->vc_resource, 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston _("VLAN: failed to unregister %s\n"),
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Unregister interest in all new resources
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (rcm_unregister_event(hd, RCM_RESOURCE_LINK_NEW, 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston _("VLAN: failed to unregister %s\n"),
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock rcm_log_message(RCM_DEBUG, "VLAN: unregistered %s\n",
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * vlan_offline() - Offline VLANs on a specific node.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonvlan_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: offline(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* Lock the cache and lookup the resource */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston node = cache_lookup(hd, rsrc, CACHE_REFRESH);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* should not happen because the resource is registered. */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston vlan_log_err(node->vc_linkid, errorp, "unrecognized resource");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Inform consumers (IP interfaces) of associated VLANs to be offlined
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (vlan_consumer_offline(hd, node, errorp, flags, info) ==
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "VLAN: consumers agreed on offline\n");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "consumers failed to offline");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* Check if it's a query */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "VLAN: offline query succeeded(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (vlan_offline_vlan(node, VLAN_OFFLINED, CACHE_NODE_OFFLINED) !=
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston vlan_log_err(node->vc_linkid, errorp, "offline failed");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: Offline succeeded(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * vlan_undo_offline() - Undo offline of a previously offlined node.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonvlan_undo_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: online(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston vlan_log_err(DATALINK_INVALID_LINKID, errorp, "no such link");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* Check if no attempt should be made to online the link here */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (!(node->vc_state & CACHE_NODE_OFFLINED)) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston vlan_log_err(node->vc_linkid, errorp, "link not offlined");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Inform IP interfaces on associated VLANs to be onlined
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston vlan_consumer_online(hd, node, errorp, flags, info);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: online succeeded(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Try to bring on all offlined VLANs
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((status = dladm_vlan_up(vlan->dv_vlanid)) !=
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Print a warning message and continue to online
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * other VLANs.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston _("VLAN: VLAN online failed (%u): %s\n"),
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston vlan->dv_vlanid, dladm_status2str(status, errmsg));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonvlan_offline_vlan(link_cache_t *node, uint32_t flags, cache_node_state_t state)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE2, "VLAN: vlan_offline_vlan (%s %u %u)\n",
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Try to delete all explicit created VLAN
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((status = dladm_vlan_delete(vlan->dv_vlanid,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston _("VLAN: VLAN offline failed (%u): %s\n"),
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston vlan->dv_vlanid, dladm_status2str(status, errmsg));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "VLAN: VLAN offline succeeded(%u)\n",
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * vlan_get_info() - Gather usage information for this resource.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonvlan_get_info(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston char **usagep, char **errorp, nvlist_t *props, rcm_info_t **info)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: get_info(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston node = cache_lookup(hd, rsrc, CACHE_REFRESH);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston _("VLAN: get_info(%s) unrecognized resource\n"), rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* most likely malloc failure */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston _("VLAN: get_info(%s) malloc failure\n"), rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* Set client/role properties */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) nvlist_add_string(props, RCM_CLIENT_NAME, "VLAN");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: get_info(%s) info = %s\n",
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * vlan_suspend() - Nothing to do, always okay
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonvlan_suspend(rcm_handle_t *hd, char *rsrc, id_t id, timespec_t *interval,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston uint_t flags, char **errorp, rcm_info_t **info)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: suspend(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * vlan_resume() - Nothing to do, always okay
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonvlan_resume(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: resume(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * vlan_consumer_remove()
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Notify VLAN consumers to remove cache.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonvlan_consumer_remove(rcm_handle_t *hd, link_cache_t *node, uint_t flags,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE2, "VLAN: vlan_consumer_remove (%s)\n",
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * This will only be called when the offline operation
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * succeeds, so the VLAN consumers must have been offlined
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * at this point.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston assert(vlan->dv_flags & VLAN_CONSUMER_OFFLINED);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u",
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston ret = rcm_notify_remove(hd, rsrc, flags, info);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston _("VLAN: notify remove failed (%s)\n"), rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE2, "VLAN: vlan_consumer_remove done\n");
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock * vlan_remove() - remove a resource from cache
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonvlan_remove(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: remove(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston _("VLAN: remove(%s) unrecognized resource\n"), rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* remove the cached entry for the resource */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rv = vlan_consumer_remove(hd, node, flags, info);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * vlan_notify_event - Project private implementation to receive new resource
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * events. It intercepts all new resource events. If the
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * new resource is a network resource, pass up a notify
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * for it too. The new resource need not be cached, since
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * it is done at register again.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstonvlan_notify_event(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston char **errorp, nvlist_t *nvl, rcm_info_t **info)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE1, "VLAN: notify_event(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (strcmp(rsrc, RCM_RESOURCE_LINK_NEW) != 0) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston vlan_log_err(DATALINK_INVALID_LINKID, errorp,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "unrecognized event");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* Update cache to reflect latest VLANs */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston vlan_log_err(DATALINK_INVALID_LINKID, errorp,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "private Cache update failed");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Try best to recover all configuration.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_DEBUG, "VLAN: process_nvlist\n");
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock while ((nvp = nvlist_next_nvpair(nvl, nvp)) != NULL) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (strcmp(nvpair_name(nvp), RCM_NV_LINKID) != 0)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston vlan_log_err(DATALINK_INVALID_LINKID, errorp,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "cannot get linkid");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston vlan_log_err(linkid, errorp, "configuring failed");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* Notify all VLAN consumers */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if (vlan_consumer_notify(hd, linkid, errorp, flags,
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock vlan_log_err(linkid, errorp, "consumer notify failed");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "VLAN: notify_event: link configuration complete\n");
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * vlan_usage - Determine the usage of a link.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * The returned buffer is owned by caller, and the caller
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * must free it up when done.
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrockstatic char *
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE2, "VLAN: usage(%s)\n", node->vc_resource);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((status = dladm_datalink_id2info(node->vc_linkid, NULL, NULL, NULL,
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock _("VLAN: usage(%s) get link name failure(%s)\n"),
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston node->vc_resource, dladm_status2str(status, errmsg));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* TRANSLATION_NOTE: separator used between VLAN linkids */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* space for VLANs and separators, plus message */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston bufsz = nvlan * (MAXLINKNAMELEN + strlen(sep)) +
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston _("VLAN: usage(%s) malloc failure(%s)\n"),
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* Nothing else to do */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE2, "VLAN: usage (%s) info = %s\n",
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_DEBUG, "VLAN:= %u\n", vlan->dv_vlanid);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((status = dladm_datalink_id2info(vlan->dv_vlanid, NULL,
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston NULL, NULL, name, sizeof (name))) != DLADM_STATUS_OK) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston _("VLAN: usage(%s) get vlan %u name failure(%s)\n"),
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE2, "VLAN: usage (%s) info = %s\n",
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Cache management routines, all cache management functions should be
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * be called with cache_lock held.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * cache_lookup() - Get a cache node for a resource.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * Call with cache lock held.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * This ensures that the cache is consistent with the system state and
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * returns a pointer to the cache element corresponding to the resource.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnstoncache_lookup(rcm_handle_t *hd, char *rsrc, char options)
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE2, "VLAN: cache lookup(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* drop lock since update locks cache again */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (; node != &cache_tail; node = node->vc_next) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "VLAN: cache lookup succeeded(%s)\n", rsrc);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * node_free - Free a node from the cache
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* free the VLAN list */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston for (vlan = node->vc_vlan; vlan != NULL; vlan = next) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * cache_insert - Insert a resource node in cache
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston /* insert at the head for best performance */
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * cache_remove() - Remove a resource node from cache.
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston * vlan_update() - Update physical interface properties
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_TRACE2, "VLAN: vlan_update(%u)\n", vlanid);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston status = dladm_vlan_info(vlanid, &vlan_attr, DLADM_OPT_ACTIVE);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "VLAN: vlan_update() cannot get vlan information for "
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "%u(%s)\n", vlanid, dladm_status2str(status, errmsg));
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_ERROR, _("VLAN: malloc error(%s): %u\n"),
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u",
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH);
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "VLAN: %s already registered (vlanid:%d)\n",
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston "VLAN: %s is a new resource (vlanid:%d)\n",
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston if ((node = calloc(1, sizeof (link_cache_t))) == NULL) {
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock rcm_log_message(RCM_ERROR, _("VLAN: calloc: %s\n"),
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
283bfb4d4abcf7382b46f32663005b883ee2e3e0Eric Schrock if ((vlan = calloc(1, sizeof (dl_vlan_t))) == NULL) {
81d9f076db88c1f40c85831ce1ebb444a209c5a8Robert Johnston rcm_log_message(RCM_ERROR, _("VLAN: malloc: %s\n"),
vlanid);
ret = 0;
done:
int rv;
RCM_SUCCESS) {
return (rv);
int len;
const char *errfmt;
char *error;
return (ret);
goto done;
goto done;
RCM_SUCCESS) {
goto done;
ret = 0;
done:
return (ret);
linkid);
typedef struct vlan_up_arg_s {
int retval;
return (DLADM_WALK_CONTINUE);
return (DLADM_WALK_CONTINUE);
return (DLADM_WALK_CONTINUE);
return (DLADM_WALK_CONTINUE);