d62bc4badc1c1f1549c961cfb8b420e650e1272byz * CDDL HEADER START
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * The contents of this file are subject to the terms of the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Common Development and Distribution License (the "License").
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * You may not use this file except in compliance with the License.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * See the License for the specific language governing permissions
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * and limitations under the License.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * When distributing Covered Code, include this CDDL HEADER in each
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If applicable, add the following below this CDDL HEADER, with the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * fields enclosed by brackets "[]" replaced with your own identifying
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * information: Portions Copyright [yyyy] [name of copyright owner]
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * CDDL HEADER END
327151705b7439cb7ab35c370f682cac7ef9523aCathy Zhou * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This RCM module adds support to the RCM framework for VLAN links
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Definitions
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define _(x) gettext(x)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define _(x) x
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* Some generic well-knowns and defaults used in this module */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define RCM_LINK_PREFIX "SUNW_datalink" /* RCM datalink name prefix */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* VLAN link flags */
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef enum {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* link representation */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz struct dl_vlan *dv_next; /* next VLAN on the same link */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz struct dl_vlan *dv_prev; /* prev VLAN on the same link */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* VLAN Cache state flags */
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef enum {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* Network Cache lookup options */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define CACHE_NO_REFRESH 0x1 /* cache refresh not needed */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* Cache element */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Global cache for network VLANs
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * RCM module interface prototypes
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int vlan_get_info(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int vlan_resume(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int vlan_offline(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int vlan_undo_offline(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int vlan_remove(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int vlan_notify_event(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* Module private routines */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void cache_free();
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic link_cache_t *cache_lookup(rcm_handle_t *, char *, char);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int vlan_consumer_offline(rcm_handle_t *, link_cache_t *,
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void vlan_consumer_online(rcm_handle_t *, link_cache_t *,
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int vlan_consumer_notify(rcm_handle_t *, datalink_id_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* Module-Private data */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * rcm_mod_init() - Update registrations, and return the ops structure.
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems dladm_status_t status;
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems char errmsg[DLADM_STRSIZE];
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems if ((status = dladm_open(&dld_handle)) != DLADM_STATUS_OK) {
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems rcm_log_message(RCM_WARNING,
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems "VLAN: mod_init failed: cannot open datalink handle: %s\n",
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems dladm_status2str(status, errmsg));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Return the ops vectors */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * rcm_mod_info() - Return a string describing this module.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzconst char *
648495d6a097a39eaebc7e56d25f2463ff3bba65vikram return ("VLAN module version 1.2");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * rcm_mod_fini() - Destroy the network VLAN cache.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Note that vlan_unregister() does not seem to be called anywhere,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * therefore we free the cache nodes here. In theory we should call
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * rcm_register_interest() for each node before we free it, the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * framework does not provide the rcm_handle to allow us to do so.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_register() - Make sure the cache is properly sync'ed, and its
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * registrations are in order.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Need to register interest in all new resources
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * getting attached, so we get attach event notifications
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rcm_register_event(hd, RCM_RESOURCE_LINK_NEW, 0, NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: failed to register %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_unregister() - Walk the cache, unregistering all the networks.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Walk the cache, unregistering everything */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: failed to unregister %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Unregister interest in all new resources
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: failed to unregister %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_offline() - Offline VLANs on a specific node.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "VLAN: offline(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Lock the cache and lookup the resource */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* should not happen because the resource is registered. */
327151705b7439cb7ab35c370f682cac7ef9523aCathy Zhou "unrecognized resource");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Inform consumers (IP interfaces) of associated VLANs to be offlined
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (vlan_consumer_offline(hd, node, errorp, flags, info) ==
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "VLAN: consumers agreed on offline\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "consumers failed to offline");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check if it's a query */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (vlan_offline_vlan(node, VLAN_OFFLINED, CACHE_NODE_OFFLINED) !=
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "VLAN: Offline succeeded(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_undo_offline() - Undo offline of a previously offlined node.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_undo_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz vlan_log_err(DATALINK_INVALID_LINKID, errorp, "no such link");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check if no attempt should be made to online the link here */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz vlan_log_err(node->vc_linkid, errorp, "link not offlined");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Inform IP interfaces on associated VLANs to be onlined
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "VLAN: online succeeded(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Try to bring on all offlined VLANs
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_vlan_up(dld_handle, vlan->dv_vlanid)) !=
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Print a warning message and continue to online
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * other VLANs.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: VLAN online failed (%u): %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_offline_vlan(link_cache_t *node, uint32_t flags, cache_node_state_t state)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_offline_vlan (%s %u %u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Try to delete all explicit created VLAN
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_vlan_delete(dld_handle, vlan->dv_vlanid,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: VLAN offline failed (%u): %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "VLAN: VLAN offline succeeded(%u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_get_info() - Gather usage information for this resource.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_get_info(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **usagep, char **errorp, nvlist_t *props, rcm_info_t **info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "VLAN: get_info(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* most likely malloc failure */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Set client/role properties */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) nvlist_add_string(props, RCM_CLIENT_NAME, "VLAN");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "VLAN: get_info(%s) info = %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_suspend() - Nothing to do, always okay
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_suspend(rcm_handle_t *hd, char *rsrc, id_t id, timespec_t *interval,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "VLAN: suspend(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_resume() - Nothing to do, always okay
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_resume(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_consumer_remove()
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Notify VLAN consumers to remove cache.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_consumer_remove(rcm_handle_t *hd, link_cache_t *node, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_consumer_remove (%s)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This will only be called when the offline operation
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * succeeds, so the VLAN consumers must have been offlined
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * at this point.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_consumer_remove done\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_remove() - remove a resource from cache
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_remove(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* remove the cached entry for the resource */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (rv);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_notify_event - Project private implementation to receive new resource
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * events. It intercepts all new resource events. If the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * new resource is a network resource, pass up a notify
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * for it too. The new resource need not be cached, since
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * it is done at register again.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_notify_event(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "VLAN: notify_event(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "unrecognized event");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Update cache to reflect latest VLANs */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "private Cache update failed");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Try best to recover all configuration.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "cannot get linkid");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Notify all VLAN consumers */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "VLAN: notify_event: link configuration complete\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (rv);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_usage - Determine the usage of a link.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * The returned buffer is owned by caller, and the caller
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * must free it up when done.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic char *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: usage(%s)\n", node->vc_resource);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_datalink_id2info(dld_handle, node->vc_linkid, NULL,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey NULL, NULL, name, sizeof (name))) != DLADM_STATUS_OK) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: usage(%s) get link name failure(%s)\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* TRANSLATION_NOTE: separator used between VLAN linkids */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* space for VLANs and separators, plus message */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: usage(%s) malloc failure(%s)\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Nothing else to do */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: usage (%s) info = %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG, "VLAN:= %u\n", vlan->dv_vlanid);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_datalink_id2info(dld_handle,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: usage(%s) get vlan %u name failure(%s)\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: usage (%s) info = %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Cache management routines, all cache management functions should be
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * be called with cache_lock held.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * cache_lookup() - Get a cache node for a resource.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Call with cache lock held.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This ensures that the cache is consistent with the system state and
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * returns a pointer to the cache element corresponding to the resource.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: cache lookup(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* drop lock since update locks cache again */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * node_free - Free a node from the cache
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* free the VLAN list */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * cache_insert - Insert a resource node in cache
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* insert at the head for best performance */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * cache_remove() - Remove a resource node from cache.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_update() - Update physical interface properties
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskeyvlan_update(dladm_handle_t handle, datalink_id_t vlanid, void *arg)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_update(%u)\n", vlanid);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_vlan_info(handle, vlanid, &vlan_attr, DLADM_OPT_ACTIVE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "VLAN: vlan_update() cannot get vlan information for "
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR, _("VLAN: malloc error(%s): %u\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "VLAN: %s already registered (vlanid:%d)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "VLAN: %s is a new resource (vlanid:%d)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE3, "VLAN: vlan_update: succeeded(%u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ret == 0 ? DLADM_WALK_CONTINUE : DLADM_WALK_TERMINATE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_update_all() - Determine all VLAN links in the system
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey (void) dladm_walk_datalink_id(vlan_update, dld_handle, &arg,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey DATALINK_CLASS_VLAN, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * cache_update() - Update cache with latest interface info
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* first we walk the entire cache, marking each entry stale */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Continue to delete all stale nodes from the cache even
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_update_all() failed. Unregister link that are not offlined
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * and still in cache
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (node = cache_head.vc_next; node != &cache_tail; node = nnode) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* clear stale VLANs */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rcm_register_interest(hd, node->vc_resource, 0, NULL) !=
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: failed to register %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (rv);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * cache_free() - Empty the cache
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_log_err() - RCM error log wrapper
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_log_err(datalink_id_t linkid, char **errorp, char *errmsg)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR, _("VLAN: %s(%s)\n"), errmsg, rsrc);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_datalink_id2info(dld_handle, linkid, NULL,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey NULL, NULL, link, sizeof (link))) != DLADM_STATUS_OK) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: cannot get link name for (%s) %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz errfmt = strlen(link) > 0 ? _("VLAN: %s(%s)") : _("VLAN: %s");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz len = strlen(errfmt) + strlen(errmsg) + MAXLINKNAMELEN + 1;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_consumer_online()
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Notify online to VLAN consumers.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* ARGSUSED */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_consumer_online(rcm_handle_t *hd, link_cache_t *node, char **errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_consumer_online (%s)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rcm_notify_online(hd, rsrc, flags, info) == RCM_SUCCESS)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_consumer_online done\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_consumer_offline()
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Offline VLAN consumers.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_consumer_offline(rcm_handle_t *hd, link_cache_t *node, char **errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_consumer_offline (%s)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_consumer_offline done\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Send RCM_RESOURCE_LINK_NEW events to other modules about new VLANs.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Return 0 on success, -1 on failure.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_notify_new_vlan (%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((node = cache_lookup(hd, rsrc, CACHE_REFRESH)) == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: failed to allocate nvlist\n"));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (vlan = node->vc_vlan; vlan != NULL; vlan = vlan->dv_next) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng "VLAN: vlan_notify_new_vlan add (%u)\n",
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (nvlist_add_uint64(nvl, RCM_NV_LINKID, id) != 0) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng _("VLAN: failed to construct nvlist\n"));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rcm_notify_event(hd, RCM_RESOURCE_LINK_NEW, 0, nvl, NULL) !=
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: failed to notify %s event for %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_consumer_notify() - Notify consumers of VLANs coming back online.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzvlan_consumer_notify(rcm_handle_t *hd, datalink_id_t linkid, char **errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check for the interface in the cache */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(rsrc, RCM_LINK_RESOURCE_MAX, "%s/%u", RCM_LINK_PREFIX,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_consumer_notify(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Inform IP consumers of the new link.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH)) != NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (-1);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_consumer_notify succeeded\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskeyvlan_up(dladm_handle_t handle, datalink_id_t vlanid, void *arg)
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_vlan_info(handle, vlanid, &vlan_attr, DLADM_OPT_PERSIST);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "VLAN: vlan_up(): cannot get information for VLAN %u "
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE3, "VLAN: vlan_up(%u)\n", vlanid);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_vlan_up(handle, vlanid)) == DLADM_STATUS_OK)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Prompt the warning message and continue to UP other VLANs.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("VLAN: VLAN up failed (%u): %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * vlan_configure() - Configure VLANs over a physical link after it attaches
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check for the VLANs in the cache */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(rsrc, sizeof (rsrc), "%s/%u", RCM_LINK_PREFIX, linkid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "VLAN: vlan_configure(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check if the link is new or was previously offlined */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (((node = cache_lookup(hd, rsrc, CACHE_REFRESH)) != NULL) &&
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey (void) dladm_walk_datalink_id(vlan_up, dld_handle, &arg,