changeset 2047:e21b6f0a829b

6408047 DL_NOTE_LINK_DOWN might be missing when a port is removed from an aggregation 6423463 Bogus check of aggregation lg_closing flag when removing a port from the aggregation 6423580 The MAC address of an aggregated device isn't changed back when the aggregation is deleted
author yz147064
date Wed, 24 May 2006 09:39:06 -0700
parents ef717412c771
children 8ceabdf91507
files usr/src/uts/common/io/aggr/aggr_grp.c usr/src/uts/common/io/aggr/aggr_port.c usr/src/uts/common/sys/aggr_impl.h
diffstat 3 files changed, 191 insertions(+), 111 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/aggr/aggr_grp.c	Tue May 23 15:29:12 2006 -0700
+++ b/usr/src/uts/common/io/aggr/aggr_grp.c	Wed May 24 09:39:06 2006 -0700
@@ -69,7 +69,8 @@
 static void aggr_m_ioctl(void *, queue_t *, mblk_t *);
 
 static aggr_port_t *aggr_grp_port_lookup(aggr_grp_t *, const char *, uint32_t);
-static int aggr_grp_rem_port(aggr_grp_t *, aggr_port_t *, boolean_t *);
+static int aggr_grp_rem_port(aggr_grp_t *, aggr_port_t *, boolean_t *,
+    boolean_t *);
 static void aggr_stats_op(enum mac_stat, uint64_t *, uint64_t *, boolean_t);
 static void aggr_grp_capab_set(aggr_grp_t *);
 static boolean_t aggr_grp_capab_check(aggr_grp_t *, aggr_port_t *);
@@ -170,7 +171,7 @@
 boolean_t
 aggr_grp_attach_port(aggr_grp_t *grp, aggr_port_t *port)
 {
-	boolean_t link_changed = B_FALSE;
+	boolean_t link_state_changed = B_FALSE;
 
 	ASSERT(AGGR_LACP_LOCK_HELD(grp));
 	ASSERT(RW_WRITE_HELD(&grp->lg_lock));
@@ -199,7 +200,7 @@
 		 * attached.
 		 */
 		grp->lg_ifspeed = port->lp_ifspeed;
-		link_changed = B_TRUE;
+		link_state_changed = B_TRUE;
 	} else if (grp->lg_ifspeed != port->lp_ifspeed) {
 		/*
 		 * The link speed of the MAC port must be the same as
@@ -217,7 +218,7 @@
 	if (grp->lg_link_state != LINK_STATE_UP) {
 		grp->lg_link_state = LINK_STATE_UP;
 		grp->lg_link_duplex = LINK_DUPLEX_FULL;
-		link_changed = B_TRUE;
+		link_state_changed = B_TRUE;
 	}
 
 	aggr_grp_multicst_port(port, B_TRUE);
@@ -245,13 +246,13 @@
 	else
 		aggr_lacp_port_attached(port);
 
-	return (link_changed);
+	return (link_state_changed);
 }
 
 boolean_t
 aggr_grp_detach_port(aggr_grp_t *grp, aggr_port_t *port)
 {
-	boolean_t link_changed = B_FALSE;
+	boolean_t link_state_changed = B_FALSE;
 
 	ASSERT(RW_WRITE_HELD(&grp->lg_lock));
 	ASSERT(RW_WRITE_HELD(&port->lp_lock));
@@ -277,10 +278,10 @@
 		grp->lg_ifspeed = 0;
 		grp->lg_link_state = LINK_STATE_DOWN;
 		grp->lg_link_duplex = LINK_DUPLEX_UNKNOWN;
-		link_changed = B_TRUE;
+		link_state_changed = B_TRUE;
 	}
 
-	return (link_changed);
+	return (link_state_changed);
 }
 
 /*
@@ -292,48 +293,73 @@
  *   that port was used for the MAC address of the group.
  * - after the MAC address of a port changed when the MAC address
  *   of that port was used for the MAC address of the group.
+ *
+ * Return true if the link state of the aggregation changed, for example
+ * as a result of a failure changing the MAC address of one of the
+ * constituent ports.
  */
-void
+boolean_t
 aggr_grp_update_ports_mac(aggr_grp_t *grp)
 {
 	aggr_port_t *cport;
+	boolean_t link_state_changed = B_FALSE;
 
 	ASSERT(RW_WRITE_HELD(&grp->lg_lock));
 
+	if (grp->lg_closing)
+		return (link_state_changed);
+
 	for (cport = grp->lg_ports; cport != NULL;
 	    cport = cport->lp_next) {
 		rw_enter(&cport->lp_lock, RW_WRITER);
-		if (aggr_port_unicst(cport, grp->lg_addr) != 0)
-			(void) aggr_grp_detach_port(grp, cport);
+		if (aggr_port_unicst(cport, grp->lg_addr) != 0) {
+			link_state_changed = link_state_changed ||
+			    aggr_grp_detach_port(grp, cport);
+		} else {
+			/*
+			 * If a port was detached because of a previous
+			 * failure changing the MAC address, the port is
+			 * reattached when it successfully changes the MAC
+			 * address now, and this might cause the link state
+			 * of the aggregation to change.
+			 */
+			link_state_changed = link_state_changed ||
+			    aggr_grp_attach_port(grp, cport);
+		}
 		rw_exit(&cport->lp_lock);
-		if (grp->lg_closing)
-			break;
 	}
+	return (link_state_changed);
 }
 
 /*
  * Invoked when the MAC address of a port has changed. If the port's
- * MAC address was used for the group MAC address, returns B_TRUE.
- * In that case, it is the responsibility of the caller to
- * invoke aggr_grp_update_ports_mac() after releasing the
- * the port lock, and aggr_grp_notify() after releasing the
- * group lock.
+ * MAC address was used for the group MAC address, set mac_addr_changedp
+ * to B_TRUE to indicate to the caller that it should send a MAC_NOTE_UNICST
+ * notification. If the link state changes due to detach/attach of
+ * the constituent port, set link_state_changedp to B_TRUE to indicate
+ * to the caller that it should send a MAC_NOTE_LINK notification. In both
+ * cases, it is the responsibility of the caller to invoke notification
+ * functions after releasing the the port lock.
  */
-boolean_t
-aggr_grp_port_mac_changed(aggr_grp_t *grp, aggr_port_t *port)
+void
+aggr_grp_port_mac_changed(aggr_grp_t *grp, aggr_port_t *port,
+    boolean_t *mac_addr_changedp, boolean_t *link_state_changedp)
 {
-	boolean_t grp_addr_changed = B_FALSE;
-
 	ASSERT(AGGR_LACP_LOCK_HELD(grp));
 	ASSERT(RW_WRITE_HELD(&grp->lg_lock));
 	ASSERT(RW_WRITE_HELD(&port->lp_lock));
+	ASSERT(mac_addr_changedp != NULL);
+	ASSERT(link_state_changedp != NULL);
+
+	*mac_addr_changedp = B_FALSE;
+	*link_state_changedp = B_FALSE;
 
 	if (grp->lg_addr_fixed) {
 		/*
 		 * The group is using a fixed MAC address or an automatic
 		 * MAC address has not been set.
 		 */
-		return (B_FALSE);
+		return;
 	}
 
 	if (grp->lg_mac_addr_port == port) {
@@ -342,17 +368,25 @@
 		 * MAC address. Update the group MAC address.
 		 */
 		bcopy(port->lp_addr, grp->lg_addr, ETHERADDRL);
-		grp_addr_changed = B_TRUE;
+		*mac_addr_changedp = B_TRUE;
 	} else {
 		/*
 		 * Update the actual port MAC address to the MAC address
 		 * of the group.
 		 */
-		if (aggr_port_unicst(port, grp->lg_addr) != 0)
-			(void) aggr_grp_detach_port(grp, port);
+		if (aggr_port_unicst(port, grp->lg_addr) != 0) {
+			*link_state_changedp = aggr_grp_detach_port(grp, port);
+		} else {
+			/*
+			 * If a port was detached because of a previous
+			 * failure changing the MAC address, the port is
+			 * reattached when it successfully changes the MAC
+			 * address now, and this might cause the link state
+			 * of the aggregation to change.
+			 */
+			*link_state_changedp = aggr_grp_attach_port(grp, port);
+		}
 	}
-
-	return (grp_addr_changed);
 }
 
 /*
@@ -458,7 +492,8 @@
 	}
 
 	/* update the MAC address of the constituent ports */
-	aggr_grp_update_ports_mac(grp);
+	if (aggr_grp_update_ports_mac(grp))
+		mac_link_update(&grp->lg_mac, grp->lg_link_state);
 
 bail:
 	if (rc != 0) {
@@ -472,7 +507,7 @@
 				aggr_port_stop(port);
 				rw_exit(&port->lp_lock);
 			}
-			(void) aggr_grp_rem_port(grp, port, NULL);
+			(void) aggr_grp_rem_port(grp, port, NULL, NULL);
 		}
 	}
 
@@ -495,6 +530,7 @@
 	int rc = 0;
 	aggr_grp_t *grp = NULL;
 	boolean_t mac_addr_changed = B_FALSE;
+	boolean_t link_state_changed = B_FALSE;
 
 	if (grp_arg == NULL) {
 		/* get group corresponding to key */
@@ -550,7 +586,7 @@
 	}
 
 	if (mac_addr_changed)
-		aggr_grp_update_ports_mac(grp);
+		link_state_changed = aggr_grp_update_ports_mac(grp);
 
 	if (update_mask & AGGR_MODIFY_LACP_MODE)
 		aggr_lacp_update_mode(grp, lacp_mode);
@@ -559,15 +595,26 @@
 		aggr_lacp_update_timer(grp, lacp_timer);
 
 bail:
+	if (grp != NULL && !grp->lg_closing) {
+		/*
+		 * If grp_arg is non-NULL, this function is called from
+		 * mac_unicst_set(), and the MAC_NOTE_UNICST notification
+		 * will be sent there.
+		 */
+		if ((grp_arg == NULL) && mac_addr_changed)
+			mac_unicst_update(&grp->lg_mac, grp->lg_addr);
+
+		if (link_state_changed)
+			mac_link_update(&grp->lg_mac, grp->lg_link_state);
+
+	}
+
 	if (grp_arg == NULL) {
 		if (grp != NULL) {
 			rw_exit(&grp->lg_lock);
 			AGGR_LACP_UNLOCK(grp);
 		}
 		rw_exit(&aggr_grp_lock);
-		/* pass new unicast address up to MAC layer */
-		if (grp != NULL && mac_addr_changed && !grp->lg_closing)
-			mac_unicst_update(&grp->lg_mac, grp->lg_addr);
 	}
 
 	if (grp != NULL)
@@ -589,6 +636,7 @@
 	aggr_port_t *port;
 	mac_t *mac;
 	mac_info_t *mip;
+	boolean_t link_state_changed;
 	int err;
 	int i;
 
@@ -612,7 +660,7 @@
 	rw_enter(&grp->lg_lock, RW_WRITER);
 
 	grp->lg_refs = 1;
-	grp->lg_closing = 0;
+	grp->lg_closing = B_FALSE;
 	grp->lg_key = key;
 
 	grp->lg_ifspeed = 0;
@@ -652,8 +700,13 @@
 		grp->lg_mac_addr_port = grp->lg_ports;
 	}
 
-	/* update the MAC address of the constituent ports */
-	aggr_grp_update_ports_mac(grp);
+	/*
+	 * Update the MAC address of the constituent ports.
+	 * None of the port is attached at this time, the link state of the
+	 * aggregation will not change.
+	 */
+	link_state_changed = aggr_grp_update_ports_mac(grp);
+	ASSERT(!link_state_changed);
 
 	/* update outbound load balancing policy */
 	aggr_send_update_policy(grp, policy);
@@ -715,7 +768,7 @@
 	if (grp != NULL) {
 		aggr_port_t *cport;
 
-		atomic_add_32(&grp->lg_closing, 1);
+		grp->lg_closing = B_TRUE;
 
 		port = grp->lg_ports;
 		while (port != NULL) {
@@ -758,25 +811,28 @@
  * Stop, detach and remove a port from a link aggregation group.
  */
 static int
-aggr_grp_rem_port(aggr_grp_t *grp, aggr_port_t *port, boolean_t *do_notify)
+aggr_grp_rem_port(aggr_grp_t *grp, aggr_port_t *port,
+    boolean_t *mac_addr_changedp, boolean_t *link_state_changedp)
 {
+	int rc = 0;
 	aggr_port_t **pport;
-	boolean_t grp_mac_addr_changed = B_FALSE;
+	boolean_t mac_addr_changed = B_FALSE;
+	boolean_t link_state_changed = B_FALSE;
 	uint64_t val;
 	uint_t i;
 
 	ASSERT(AGGR_LACP_LOCK_HELD(grp));
 	ASSERT(RW_WRITE_HELD(&grp->lg_lock));
 	ASSERT(grp->lg_nports > 1);
-
-	if (do_notify != NULL)
-		*do_notify = B_FALSE;
+	ASSERT(!grp->lg_closing);
 
 	/* unlink port */
 	for (pport = &grp->lg_ports; *pport != port;
 	    pport = &(*pport)->lp_next) {
-		if (*pport == NULL)
-			return (ENOENT);
+		if (*pport == NULL) {
+			rc = ENOENT;
+			goto done;
+		}
 	}
 	*pport = port->lp_next;
 
@@ -796,10 +852,10 @@
 		 */
 		bcopy(grp->lg_ports->lp_addr, grp->lg_addr, ETHERADDRL);
 		grp->lg_mac_addr_port = grp->lg_ports;
-		grp_mac_addr_changed = B_TRUE;
+		mac_addr_changed = B_TRUE;
 	}
 
-	(void) aggr_grp_detach_port(grp, port);
+	link_state_changed = aggr_grp_detach_port(grp, port);
 
 	/*
 	 * Add the statistics of the ports while it was aggregated
@@ -829,17 +885,17 @@
 	 * the remaining consistuent ports according to the new MAC
 	 * address of the group.
 	 */
-	if (grp->lg_closing) {
-		*do_notify = B_FALSE;
-	} else {
-		if (grp_mac_addr_changed)
-			aggr_grp_update_ports_mac(grp);
+	if (mac_addr_changed)
+		link_state_changed = link_state_changed ||
+		    aggr_grp_update_ports_mac(grp);
 
-		if (do_notify != NULL)
-			*do_notify = grp_mac_addr_changed;
-	}
+done:
+	if (mac_addr_changedp != NULL)
+		*mac_addr_changedp = mac_addr_changed;
+	if (link_state_changedp != NULL)
+		*link_state_changedp = link_state_changed;
 
-	return (0);
+	return (rc);
 }
 
 /*
@@ -851,7 +907,8 @@
 	int rc = 0, i;
 	aggr_grp_t *grp = NULL;
 	aggr_port_t *port;
-	boolean_t notify = B_FALSE, grp_mac_addr_changed;
+	boolean_t mac_addr_update = B_FALSE, mac_addr_changed;
+	boolean_t link_state_update = B_FALSE, link_state_changed;
 
 	/* get group corresponding to key */
 	rw_enter(&aggr_grp_lock, RW_READER);
@@ -897,17 +954,21 @@
 		}
 
 		/* remove port from group */
-		rc = aggr_grp_rem_port(grp, port, &grp_mac_addr_changed);
+		rc = aggr_grp_rem_port(grp, port, &mac_addr_changed,
+		    &link_state_changed);
 		ASSERT(rc == 0);
-		notify = notify || grp_mac_addr_changed;
+		mac_addr_update = mac_addr_update || mac_addr_changed;
+		link_state_update = link_state_update || link_state_changed;
 	}
 
 bail:
 	rw_exit(&grp->lg_lock);
 	AGGR_LACP_UNLOCK(grp);
-	if (notify && !grp->lg_closing)
+	if (mac_addr_update)
 		mac_unicst_update(&grp->lg_mac, grp->lg_addr);
-	if (rc == 0 && !grp->lg_closing)
+	if (link_state_update)
+		mac_link_update(&grp->lg_mac, grp->lg_link_state);
+	if (rc == 0)
 		mac_resource_update(&grp->lg_mac);
 	AGGR_GRP_REFRELE(grp);
 
@@ -929,11 +990,11 @@
 		return (ENOENT);
 	}
 
-	atomic_add_32(&grp->lg_closing, 1);
-
 	AGGR_LACP_LOCK(grp);
 	rw_enter(&grp->lg_lock, RW_WRITER);
 
+	grp->lg_closing = B_TRUE;
+
 	/*
 	 * Unregister from the MAC service module. Since this can
 	 * fail if a client hasn't closed the MAC port, we gracefully
@@ -1176,11 +1237,14 @@
 {
 	aggr_grp_t *grp = arg;
 	aggr_port_t *port;
+	boolean_t link_state_changed = B_FALSE;
 
 	AGGR_LACP_LOCK(grp);
 	rw_enter(&grp->lg_lock, RW_WRITER);
 	AGGR_GRP_REFHOLD(grp);
 
+	ASSERT(!grp->lg_closing);
+
 	if (on == grp->lg_promisc)
 		goto bail;
 
@@ -1188,17 +1252,30 @@
 		rw_enter(&port->lp_lock, RW_WRITER);
 		AGGR_PORT_REFHOLD(port);
 		if (port->lp_started) {
-			if (aggr_port_promisc(port, on) != 0)
-				(void) aggr_grp_detach_port(grp, port);
+			if (aggr_port_promisc(port, on) != 0) {
+				link_state_changed = link_state_changed ||
+				    aggr_grp_detach_port(grp, port);
+			} else {
+				/*
+				 * If a port was detached because of a previous
+				 * failure changing the promiscuity, the port
+				 * is reattached when it successfully changes
+				 * the promiscuity now, and this might cause
+				 * the link state of the aggregation to change.
+				 */
+				link_state_changed = link_state_changed ||
+				    aggr_grp_attach_port(grp, port);
+			}
 		}
 		rw_exit(&port->lp_lock);
 		AGGR_PORT_REFRELE(port);
-		if (grp->lg_closing)
-			break;
 	}
 
 	grp->lg_promisc = on;
 
+	if (link_state_changed)
+		mac_link_update(&grp->lg_mac, grp->lg_link_state);
+
 bail:
 	rw_exit(&grp->lg_lock);
 	AGGR_LACP_UNLOCK(grp);
--- a/usr/src/uts/common/io/aggr/aggr_port.c	Tue May 23 15:29:12 2006 -0700
+++ b/usr/src/uts/common/io/aggr/aggr_port.c	Wed May 24 09:39:06 2006 -0700
@@ -129,7 +129,6 @@
 	port->lp_port = portnum;
 	(void) strlcpy(port->lp_devname, name, sizeof (port->lp_devname));
 	port->lp_closing = 0;
-	port->lp_set_grpmac = B_FALSE;
 
 	/* get the port's original MAC address */
 	mac_unicst_get(port->lp_mh, port->lp_addr);
@@ -208,7 +207,7 @@
 {
 	boolean_t do_attach = B_FALSE;
 	boolean_t do_detach = B_FALSE;
-	boolean_t grp_link_changed = B_TRUE;
+	boolean_t link_state_changed = B_TRUE;
 	uint64_t ifspeed;
 	link_state_t link_state;
 	link_duplex_t link_duplex;
@@ -249,64 +248,75 @@
 
 	if (do_attach) {
 		/* attempt to attach the port to the aggregation */
-		grp_link_changed = aggr_grp_attach_port(grp, port);
+		link_state_changed = aggr_grp_attach_port(grp, port);
 	} else if (do_detach) {
 		/* detach the port from the aggregation */
-		grp_link_changed = aggr_grp_detach_port(grp, port);
+		link_state_changed = aggr_grp_detach_port(grp, port);
 	}
 
 	rw_exit(&port->lp_lock);
 	rw_exit(&grp->lg_lock);
 	AGGR_LACP_UNLOCK(grp);
 
-	return (grp_link_changed);
+	return (link_state_changed);
 }
 
 /*
  * Invoked upon receiving a MAC_NOTE_UNICST for one of the constituent
  * ports of a group.
  */
-static boolean_t
-aggr_port_notify_unicst(aggr_grp_t *grp, aggr_port_t *port)
+static void
+aggr_port_notify_unicst(aggr_grp_t *grp, aggr_port_t *port,
+    boolean_t *mac_addr_changedp, boolean_t *link_state_changedp)
 {
-	boolean_t grp_mac_changed;
+	boolean_t mac_addr_changed = B_FALSE;
+	boolean_t link_state_changed = B_FALSE;
+	uint8_t mac_addr[ETHERADDRL];
+
+	ASSERT(mac_addr_changedp != NULL);
+	ASSERT(link_state_changedp != NULL);
+
+	AGGR_LACP_LOCK(grp);
+	rw_enter(&grp->lg_lock, RW_WRITER);
+
+	rw_enter(&port->lp_lock, RW_WRITER);
 
 	/*
 	 * If it is called when setting the MAC address to the
 	 * aggregation group MAC address, do nothing.
 	 */
-	if (port->lp_set_grpmac)
-		return (B_FALSE);
-
-	AGGR_LACP_LOCK(grp);
-	rw_enter(&grp->lg_lock, RW_WRITER);
-	rw_enter(&port->lp_lock, RW_WRITER);
+	mac_unicst_get(port->lp_mh, mac_addr);
+	if (bcmp(mac_addr, grp->lg_addr, ETHERADDRL) == 0) {
+		rw_exit(&port->lp_lock);
+		goto done;
+	}
 
 	/* save the new port MAC address */
-	mac_unicst_get(port->lp_mh, port->lp_addr);
+	bcopy(mac_addr, port->lp_addr, ETHERADDRL);
 
-	grp_mac_changed = aggr_grp_port_mac_changed(grp, port);
+	aggr_grp_port_mac_changed(grp, port, &mac_addr_changed,
+	    &link_state_changed);
 
 	rw_exit(&port->lp_lock);
 
-	if (grp->lg_closing) {
-		rw_exit(&grp->lg_lock);
-		AGGR_LACP_UNLOCK(grp);
-		return (B_FALSE);
-	}
+	if (grp->lg_closing)
+		goto done;
 
 	/*
 	 * If this port was used to determine the MAC address of
 	 * the group, update the MAC address of the constituent
 	 * ports.
 	 */
-	if (grp_mac_changed)
-		aggr_grp_update_ports_mac(grp);
+	if (mac_addr_changed) {
+		link_state_changed = link_state_changed ||
+		    aggr_grp_update_ports_mac(grp);
+	}
 
+done:
+	*mac_addr_changedp = mac_addr_changed;
+	*link_state_changedp = link_state_changed;
 	rw_exit(&grp->lg_lock);
 	AGGR_LACP_UNLOCK(grp);
-
-	return (grp_mac_changed);
 }
 
 /*
@@ -318,6 +328,7 @@
 {
 	aggr_port_t *port = arg;
 	aggr_grp_t *grp = port->lp_grp;
+	boolean_t mac_addr_changed, link_state_changed;
 
 	/*
 	 * Do nothing if the aggregation or the port is in the deletion
@@ -337,8 +348,12 @@
 			mac_link_update(&grp->lg_mac, grp->lg_link_state);
 		break;
 	case MAC_NOTE_UNICST:
-		if (aggr_port_notify_unicst(grp, port))
+		aggr_port_notify_unicst(grp, port, &mac_addr_changed,
+		    &link_state_changed);
+		if (mac_addr_changed)
 			mac_unicst_update(&grp->lg_mac, grp->lg_addr);
+		if (link_state_changed)
+			mac_link_update(&grp->lg_mac, grp->lg_link_state);
 		break;
 	case MAC_NOTE_PROMISC:
 		port->lp_txinfo = mac_tx_get(port->lp_mh);
@@ -414,16 +429,8 @@
 
 	ASSERT(RW_WRITE_HELD(&port->lp_lock));
 
-	/*
-	 * set lp_set_grpmac to indicate it is going to set the MAC
-	 * address to the aggregation MAC address.
-	 */
-	port->lp_set_grpmac = B_TRUE;
-
 	rc = mac_unicst_set(port->lp_mh, macaddr);
 
-	port->lp_set_grpmac = B_FALSE;
-
 	return (rc);
 }
 
--- a/usr/src/uts/common/sys/aggr_impl.h	Tue May 23 15:29:12 2006 -0700
+++ b/usr/src/uts/common/sys/aggr_impl.h	Wed May 24 09:39:06 2006 -0700
@@ -62,12 +62,7 @@
 			lp_tx_enabled : 1,
 			lp_collector_enabled : 1,
 			lp_promisc_on : 1,
-			/*
-			 * Indicates whether it is in the process of setting
-			 * MAC address to the aggregation group MAC
-			 */
-			lp_set_grpmac : 1,
-			lp_pad_bits : 27;
+			lp_pad_bits : 28;
 	uint32_t	lp_closing;
 	uint_t		lp_port;
 	mac_handle_t	lp_mh;
@@ -108,11 +103,11 @@
 	uint16_t	lg_nports;		/* number of MAC ports */
 	uint8_t		lg_addr[ETHERADDRL];	/* group MAC address */
 	uint16_t
+			lg_closing : 1,
 			lg_addr_fixed : 1,	/* fixed MAC address? */
 			lg_started : 1,		/* group started? */
 			lg_promisc : 1,		/* in promiscuous mode? */
-			lg_pad_bits : 13;
-	uint32_t	lg_closing;
+			lg_pad_bits : 12;
 	aggr_port_t	*lg_ports;		/* list of configured ports */
 	aggr_port_t	*lg_mac_addr_port;
 	mac_t		lg_mac;
@@ -178,10 +173,11 @@
 extern void aggr_grp_notify(aggr_grp_t *, uint32_t);
 extern boolean_t aggr_grp_attach_port(aggr_grp_t *, aggr_port_t *);
 extern boolean_t aggr_grp_detach_port(aggr_grp_t *, aggr_port_t *);
-extern boolean_t aggr_grp_port_mac_changed(aggr_grp_t *, aggr_port_t *);
+extern void aggr_grp_port_mac_changed(aggr_grp_t *, aggr_port_t *,
+    boolean_t *, boolean_t *);
 extern int aggr_grp_add_ports(uint32_t, uint_t, laioc_port_t *);
 extern int aggr_grp_rem_ports(uint32_t, uint_t, laioc_port_t *);
-extern void aggr_grp_update_ports_mac(aggr_grp_t *);
+extern boolean_t aggr_grp_update_ports_mac(aggr_grp_t *);
 extern int aggr_grp_modify(uint32_t, aggr_grp_t *, uint8_t, uint32_t,
     boolean_t, const uchar_t *, aggr_lacp_mode_t, aggr_lacp_timer_t);
 extern void aggr_grp_multicst_port(aggr_port_t *, boolean_t);