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
d4d1f7bf736e9deaf99b53c54fc31cecd3a9e435Vasumathi Sundaram - Sun Microsystems * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Use is subject to license terms.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This RCM module adds support to the RCM framework for AGGR 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/* AGGR link representation */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* AGGR Cache state flags */
d62bc4badc1c1f1549c961cfb8b420e650e1272byztypedef enum {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz CACHE_AGGR_PORT_OFFLINED = 0x08, /* aggr port offlined */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz CACHE_AGGR_CONSUMER_OFFLINED = 0x10 /* consumers offlined */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* Network Cache lookup options */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#define CACHE_NO_REFRESH 0x1 /* cache refresh not needed */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Cache element. It is used to keep a list of links on the system and
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * their associated aggregations.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Global cache for network AGGRs
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * RCM module interface prototypes
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_get_info(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_resume(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_offline(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_undo_offline(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_remove(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz char **, rcm_info_t **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_notify_event(rcm_handle_t *, char *, id_t, uint_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_configure_all(rcm_handle_t *, datalink_id_t,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* Module private routines */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void aggr_list_free();
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic link_cache_t *cache_lookup(rcm_handle_t *, char *, char);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_consumer_offline(rcm_handle_t *, link_cache_t *,
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_consumer_online(rcm_handle_t *, link_cache_t *,
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_offline_port(link_cache_t *, cache_node_state_t);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int aggr_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 "AGGR: 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 ("AGGR module version 1.1");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * rcm_mod_fini() - Destroy the network AGGR cache.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Note that aggr_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 * aggr_list_insert - Insert an aggr in the global aggr list
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* insert at the head for best performance */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_list_remove - Remove an aggr from the global aggr list
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_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 _("AGGR: failed to register %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_unregister() - Walk the cache, unregistering all the networks.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Walk the cache, unregistering everything */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* unregister failed for whatever reason */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to unregister %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Unregister interest in all new resources
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to unregister %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_offline() - Offline AGGRs on a specific link.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: offline(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Lock the cache and lookup the resource */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* should not happen because the resource is registered. */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "offline, unrecognized resource");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If this given link is the only port in the aggregation, inform
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * VLANs and IP interfaces on associated AGGRs to be offlined
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: consumers agreed on offline\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "consumers offline failed");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check if it's a query */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr_offline_port(node, CACHE_NODE_OFFLINED) != RCM_SUCCESS) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(node->vc_linkid, errorp, "offline port failed");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: Offline succeeded(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_undo_offline() - Undo offline of a previously offlined link.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_undo_offline(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "undo offline, unrecognized resource");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check if no attempt should be made to online the link here */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_log_err(node->vc_linkid, errorp, "resource not offlined");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Inform VLANs and IP interfaces on associated AGGRs to be online
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (aggr_consumer_online(hd, node, errorp, flags, depend_info) ==
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_DEBUG, "AGGR: Consumers agree on online");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: online succeeded(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_offline_port(link_cache_t *node, cache_node_state_t state)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_offline_port %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Try to remove the given port from the AGGR or delete the AGGR
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: delete aggregation %u\n",
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_delete(dld_handle, aggr->da_aggrid,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: remove port (%s) from aggregation %u\n",
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_remove(dld_handle, aggr->da_aggrid, 1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: AGGR offline port failed (%u): %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: AGGR offline port succeeded (%u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_online_port %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Either add the port into the AGGR or recreate specific AGGR
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * depending on whether this link is the only port in the aggregation.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: delete aggregation %u\n",
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_up(dld_handle, aggr->da_aggrid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: add port (%s) to aggregation %u\n",
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_add(dld_handle, aggr->da_aggrid, 1, &port,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: AGGR online failed (%u): %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_get_info() - Gather usage information for this resource.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_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 **depend_info)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: get_info(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * *usagep will be freed by the caller.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* most likely malloc failure */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Set client/role properties */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) nvlist_add_string(props, RCM_CLIENT_NAME, "AGGR");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: get_info(%s) info = %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_suspend() - Nothing to do, always okay
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_suspend(rcm_handle_t *hd, char *rsrc, id_t id, timespec_t *interval,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: suspend(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_resume() - Nothing to do, always okay
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_resume(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_remove() - remove a resource from cache
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*ARGSUSED*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_remove(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* remove the cached entry for the resource */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If this link is not the only port in the associated aggregation,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * the CACHE_AGGR_CONSUMER_OFFLINED flags won't be set.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(exported, RCM_LINK_RESOURCE_MAX, "%s/%u",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rv = rcm_notify_remove(hd, exported, flags, depend_info);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to notify remove dependent %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (rv);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_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*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_notify_event(rcm_handle_t *hd, char *rsrc, id_t id, uint_t flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: notify_event(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "unrecognized event");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Update cache to reflect latest AGGRs */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "private Cache update failed");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Process the nvlist for the event */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "cannot get linkid");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "failed configuring AGGR links");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Notify all VLAN and IP AGGR consumers */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (up && aggr_consumer_notify(hd, linkid, errorp, flags,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: notify_event: link configuration complete\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (rv);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_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, "AGGR: 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 _("AGGR: usage(%s) get port name failure(%s)\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* space for resources and message */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: usage(%s) malloc failure(%s)\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Nothing else to do */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: usage (%s) info = %s\n",
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey if ((status = dladm_datalink_id2info(dld_handle,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey node->vc_aggr->da_aggrid, NULL, NULL, NULL, name,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: usage(%s) get aggr %u name failure(%s)\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: 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, "AGGR: 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 * 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.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Call with the cache_lock held.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_port_update(rcm_handle_t *hd, dl_aggr_t *aggr, datalink_id_t portid)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_port_update aggr:%u port:%u\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: resource malloc error(%s)\n"), strerror(errno));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: %s already registered (aggrid:%u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Update vc_aggr directly as only one aggregation can be
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * created on one port.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: %s is a new resource (aggrid:%u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_update() - Update physical interface properties
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskeyaggr_update(dladm_handle_t handle, datalink_id_t aggrid, void *arg)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: aggr_update(%u)\n", aggrid);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_info(handle, aggrid, &aggr_attr,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: cannot get aggr information for %u error(%s)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Try to find the aggr from the aggr list.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (aggr = aggr_head.da_next; aggr != &aggr_tail; aggr = aggr->da_next)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Update aggregation information. */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz datalink_id_t portid = (aggr_attr.lg_ports[i]).lp_linkid;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ret == 0 ? DLADM_WALK_CONTINUE : DLADM_WALK_TERMINATE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_update_all() - Determine all AGGR links in the system
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey (void) dladm_walk_datalink_id(aggr_update, dld_handle, &arg,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey DATALINK_CLASS_AGGR, DATALINK_ANY_MEDIATYPE, DLADM_OPT_ACTIVE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * cache_update() - Update cache with latest interface info
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* first we walk the entire aggr list, marking each entry stale */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (aggr = aggr_head.da_next; aggr != &aggr_tail; aggr = aggr->da_next)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* then we walk the entire cache, marking each entry stale */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Even aggr_update_all() fails, continue to delete all the stale
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * resources. First, unregister links that are not offlined and
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * still in cache.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz for (node = cache_head.vc_next; node != &cache_tail; node = next) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to register %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* delete stale AGGRs */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_log_err() - RCM error log wrapper
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_log_err(datalink_id_t linkid, char **errorp, char *errmsg)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_ERROR, _("AGGR: %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 _("AGGR: cannot get link name of (%s) %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz errfmt = strlen(link) > 0 ? _("AGGR: %s(%s)") : _("AGGR: %s");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz len = strlen(errfmt) + strlen(errmsg) + MAXLINKNAMELEN + 1;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_consumer_offline()
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Offline AGGR consumers.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_consumer_offline(rcm_handle_t *hd, link_cache_t *node, char **errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_consumer_offline %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Inform associated VLANs and IP interfaces to be offlined
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_consumer_offline done\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_consumer_online()
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * online AGGR consumers.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_consumer_online(rcm_handle_t *hd, link_cache_t *node, char **errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_consumer_online %s\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: no consumers offlined (%s)\n", node->vc_resource);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_consumer_online done\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Send RCM_RESOURCE_LINK_NEW events to other modules about new aggregations.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Return 0 on success, -1 on failure.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_notify_new_aggr (%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check for the interface in the cache */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((node = cache_lookup(hd, rsrc, CACHE_REFRESH)) == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_notify_new_aggr() unrecognized resource (%s)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to allocate nvlist\n"));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_notify_new_aggr add (%u)\n",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to construct nvlist\n"));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If this link is not the only port in the aggregation, the aggregation
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * is not new. No need to inform other consumers in that case.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (is_only_port && rcm_notify_event(hd, RCM_RESOURCE_LINK_NEW,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: failed to notify %s event for %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_consumer_notify() - Notify consumers of AGGRs coming back online.
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_consumer_notify(rcm_handle_t *hd, datalink_id_t linkid, char **errorp,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: aggr_consumer_notify(%s)\n", rsrc);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Inform IP and VLAN consumers to be online.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((node = cache_lookup(hd, rsrc, CACHE_NO_REFRESH)) != NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (-1);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE2, "AGGR: aggr_consumer_notify succeeded\n");
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskeyaggr_configure(dladm_handle_t handle, datalink_id_t aggrid, void *arg)
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_datalink_id2info(handle, aggrid, &flags, NULL, NULL,
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_info(handle, aggrid, &aggr_attr, DLADM_OPT_PERSIST);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * The aggregation doesn't contain this port.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If this aggregation already exists, add this port to this
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggregation, otherwise, bring up this aggregation.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "AGGR: aggr_configure dladm_aggr_add port %u (%u)\n",
4ac67f0276a8313b5cefec38af347b94b7bfb526Anurag S. Maskey status = dladm_aggr_add(handle, aggrid, 1, &port_attr,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Print a warning message and continue to UP other AGGRs.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz _("AGGR: AGGR online failed (%u): %s\n"),
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * aggr_configure_all() - Configure AGGRs over a physical link after it attaches
d62bc4badc1c1f1549c961cfb8b420e650e1272byzaggr_configure_all(rcm_handle_t *hd, datalink_id_t linkid, boolean_t *up)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz aggr_configure_arg_t arg = {DATALINK_INVALID_LINKID, 0, B_FALSE};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /* Check for the AGGRs in the cache */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz (void) snprintf(rsrc, sizeof (rsrc), "%s/%u", RCM_LINK_PREFIX, linkid);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rcm_log_message(RCM_TRACE1, "AGGR: aggr_configure_all(%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(aggr_configure, dld_handle, &arg,