aggr_grp.c revision 19c868a072e70eef88eef7c471242486b2b1f152
c28749e97052f09388969427adf7df641cdcdc22kais * CDDL HEADER START
c28749e97052f09388969427adf7df641cdcdc22kais * The contents of this file are subject to the terms of the
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * Common Development and Distribution License (the "License").
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * You may not use this file except in compliance with the License.
c28749e97052f09388969427adf7df641cdcdc22kais * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c28749e97052f09388969427adf7df641cdcdc22kais * See the License for the specific language governing permissions
c28749e97052f09388969427adf7df641cdcdc22kais * and limitations under the License.
c28749e97052f09388969427adf7df641cdcdc22kais * When distributing Covered Code, include this CDDL HEADER in each
c28749e97052f09388969427adf7df641cdcdc22kais * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c28749e97052f09388969427adf7df641cdcdc22kais * If applicable, add the following below this CDDL HEADER, with the
c28749e97052f09388969427adf7df641cdcdc22kais * fields enclosed by brackets "[]" replaced with your own identifying
c28749e97052f09388969427adf7df641cdcdc22kais * information: Portions Copyright [yyyy] [name of copyright owner]
c28749e97052f09388969427adf7df641cdcdc22kais * CDDL HEADER END
c892ebf1bef94f4f922f282c11516677c134dbe0krishna * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
c28749e97052f09388969427adf7df641cdcdc22kais * Use is subject to license terms.
c28749e97052f09388969427adf7df641cdcdc22kais * IEEE 802.3ad Link Aggregation -- Link Aggregation Groups.
c28749e97052f09388969427adf7df641cdcdc22kais * An instance of the structure aggr_grp_t is allocated for each
c28749e97052f09388969427adf7df641cdcdc22kais * link aggregation group. When created, aggr_grp_t objects are
c28749e97052f09388969427adf7df641cdcdc22kais * entered into the aggr_grp_hash hash table maintained by the modhash
c28749e97052f09388969427adf7df641cdcdc22kais * module. The hash key is the linkid associated with the link
c28749e97052f09388969427adf7df641cdcdc22kais * aggregation group.
c28749e97052f09388969427adf7df641cdcdc22kais * A set of MAC ports are associated with each association group.
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int aggr_m_start(void *);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void aggr_m_stop(void *);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int aggr_m_multicst(void *, boolean_t, const uint8_t *);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic boolean_t aggr_m_capab_get(void *, mac_capab_t, void *);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int aggr_m_setprop(void *, const char *, mac_prop_id_t, uint_t,
c28749e97052f09388969427adf7df641cdcdc22kais const void *);
c892ebf1bef94f4f922f282c11516677c134dbe0krishnastatic int aggr_m_getprop(void *, const char *, mac_prop_id_t, uint_t,
c892ebf1bef94f4f922f282c11516677c134dbe0krishnastatic aggr_port_t *aggr_grp_port_lookup(aggr_grp_t *, datalink_id_t);
c892ebf1bef94f4f922f282c11516677c134dbe0krishnastatic int aggr_grp_rem_port(aggr_grp_t *, aggr_port_t *, boolean_t *,
c892ebf1bef94f4f922f282c11516677c134dbe0krishnastatic boolean_t aggr_grp_capab_check(aggr_grp_t *, aggr_port_t *);
c892ebf1bef94f4f922f282c11516677c134dbe0krishnastatic boolean_t aggr_grp_sdu_check(aggr_grp_t *, aggr_port_t *);
c892ebf1bef94f4f922f282c11516677c134dbe0krishnastatic boolean_t aggr_grp_margin_check(aggr_grp_t *, aggr_port_t *);
c892ebf1bef94f4f922f282c11516677c134dbe0krishnastatic int aggr_add_pseudo_rx_group(aggr_port_t *, aggr_pseudo_rx_group_t *);
c892ebf1bef94f4f922f282c11516677c134dbe0krishnastatic void aggr_rem_pseudo_rx_group(aggr_port_t *, aggr_pseudo_rx_group_t *);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic int aggr_pseudo_start_ring(mac_ring_driver_t, uint64_t);
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void aggr_fill_ring(void *, mac_ring_type_t, const int,
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void aggr_fill_group(void *, mac_ring_type_t, const int,
c892ebf1bef94f4f922f282c11516677c134dbe0krishna#define GRP_HASH_KEY(linkid) ((mod_hash_key_t)(uintptr_t)linkid)
c28749e97052f09388969427adf7df641cdcdc22kais/*ARGSUSED*/
c28749e97052f09388969427adf7df641cdcdc22kais mutex_init(&grp->lg_lacp_lock, NULL, MUTEX_DEFAULT, NULL);
c28749e97052f09388969427adf7df641cdcdc22kais mutex_init(&grp->lg_port_lock, NULL, MUTEX_DEFAULT, NULL);
c28749e97052f09388969427adf7df641cdcdc22kais return (0);
c28749e97052f09388969427adf7df641cdcdc22kais/*ARGSUSED*/
c28749e97052f09388969427adf7df641cdcdc22kaisstatic void
c28749e97052f09388969427adf7df641cdcdc22kais aggr_grp_hash = mod_hash_create_idhash("aggr_grp_hash",
c28749e97052f09388969427adf7df641cdcdc22kais * Allocate an id space to manage key values (when key is not
c28749e97052f09388969427adf7df641cdcdc22kais * specified). The range of the id space will be from
c28749e97052f09388969427adf7df641cdcdc22kais * (AGGR_MAX_KEY + 1) to UINT16_MAX, because the LACP protocol
c28749e97052f09388969427adf7df641cdcdc22kais * uses a 16-bit key.
c28749e97052f09388969427adf7df641cdcdc22kais key_ids = id_space_create("aggr_key_ids", AGGR_MAX_KEY + 1, UINT16_MAX);
c28749e97052f09388969427adf7df641cdcdc22kais * Since both aggr_port_notify_cb() and aggr_port_timer_thread() functions
c28749e97052f09388969427adf7df641cdcdc22kais * requires the mac perimeter, this function holds a reference of the aggr
c28749e97052f09388969427adf7df641cdcdc22kais * and aggr won't call mac_unregister() until this reference drops to 0.
c28749e97052f09388969427adf7df641cdcdc22kais * Release the reference of the grp and inform aggr_grp_delete() calling
c28749e97052f09388969427adf7df641cdcdc22kais * mac_unregister() is now safe.
return (B_FALSE);
return (B_FALSE);
return (B_FALSE);
return (link_state_changed);
return (B_FALSE);
return (link_state_changed);
return (link_state_changed);
int err;
if (err != 0)
return (err);
int err;
for (j = 0; j < MAX_RINGS_PER_GROUP; j++) {
if (j == MAX_RINGS_PER_GROUP)
return (EIO);
return (err);
for (j = 0; j < MAX_RINGS_PER_GROUP; j++) {
int hw_rh_cnt, i = 0, j;
int err = 0;
if (err != 0) {
done:
return (err);
int hw_rh_cnt, i;
goto done;
for (i = 0; i < hw_rh_cnt; i++)
done:
int err;
if (err == 0)
return (err);
return (ENOENT);
for (i = 0; i < nports; i++) {
goto bail;
nadded++;
goto bail;
if (rc != 0)
goto bail;
if (rc != 0) {
goto bail;
if (rc != 0) {
goto bail;
if (link_state_changed)
bail:
if (rc != 0) {
for (i = 0; i < nadded; i++) {
if (rc == 0)
return (rc);
return (EINVAL);
if (mac_fixed) {
if (mac_addr_changed)
if (link_state_changed)
if (mac_addr_changed)
int err;
return (ENOENT);
return (err);
int err;
if (nports == 0)
return (EINVAL);
if (err == 0) {
return (EEXIST);
goto bail;
for (i = 0; i < nports; i++) {
if (err != 0)
goto bail;
goto bail;
goto bail;
if (err != 0)
goto bail;
goto bail;
if (link_state_changed)
aggr_grp_cnt++;
bail:
return (err);
static aggr_port_t *
return (port);
int rc = 0;
uint_t i;
goto done;
for (i = 0; i < MAC_NSTAT; i++) {
for (i = 0; i < ETHER_NSTAT; i++) {
done:
return (rc);
int rc = 0, i;
return (ENOENT);
goto bail;
for (i = 0; i < nports; i++) {
goto bail;
if (rc != 0) {
for (i = 0; i < nports; i++) {
goto bail;
for (i = 0; i < nports; i++) {
bail:
if (mac_addr_update)
if (link_state_update)
if (rc == 0)
return (rc);
int err;
return (ENOENT);
return (err);
return (err);
aggr_grp_cnt--;
int rc = 0;
return (ENOENT);
if (rc != 0)
goto bail;
if (rc != 0)
goto bail;
bail:
return (rc);
return (ENOTSUP);
*val = 0;
int rval = 0;
switch (stat) {
case MAC_STAT_IFSPEED:
case ETHER_STAT_LINK_DUPLEX:
return (rval);
goto bail;
int err = 0;
if (err != 0) {
if (link_state_changed)
bail:
char *clnt_name;
static boolean_t
switch (cap) {
case MAC_CAPAB_HCKSUM: {
case MAC_CAPAB_LSO: {
return (B_FALSE);
case MAC_CAPAB_NO_NATIVEVLAN:
case MAC_CAPAB_NO_ZCOPY:
case MAC_CAPAB_RINGS: {
return (B_FALSE);
case MAC_CAPAB_AGGR:
return (B_TRUE);
return (B_FALSE);
return (B_TRUE);
switch (rtype) {
case MAC_RING_TYPE_RX: {
static mblk_t *
return (mp_chain);
return (mp_chain);
int err = 0;
return (EEXIST);
if (err != 0) {
return (err);
int err = 0;
return (EINVAL);
return (err);
return (err);
int err;
return (err);
cksum = 0;
static boolean_t
return (B_FALSE);
return (B_FALSE);
return (B_FALSE);
return (B_FALSE);
return (B_FALSE);
return (B_FALSE);
return (B_FALSE);
return (B_TRUE);
static uint_t
return (max_sdu);
static boolean_t
static uint32_t
return (margin);
static boolean_t
return (B_TRUE);
return (B_FALSE);
return (B_TRUE);
goto try_again;
return (err);
if (sdu == 0)
return (EINVAL);
if (err != 0) {
goto bail;
bail:
return (err);
switch (pr_num) {
case MAC_PROP_MTU: {
return (err);
return (ENOTSUP);