summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/net/ieee8023ad_lacp.c4
-rw-r--r--sys/net/if_lagg.c19
-rw-r--r--sys/net/if_lagg.h1
3 files changed, 16 insertions, 8 deletions
diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c
index 2753c98..b022035 100644
--- a/sys/net/ieee8023ad_lacp.c
+++ b/sys/net/ieee8023ad_lacp.c
@@ -485,7 +485,9 @@ lacp_port_destroy(struct lagg_port *lgp)
lacp_unselect(lp);
lgp->lp_flags &= ~LAGG_PORT_DISABLED;
- if_delmulti_ifma(lp->lp_ifma);
+ /* The address may have already been removed by if_purgemaddrs() */
+ if (!lgp->lp_detaching)
+ if_delmulti_ifma(lp->lp_ifma);
LIST_REMOVE(lp, lp_next);
free(lp, M_DEVBUF);
diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c
index bb23d29..8eddf4c 100644
--- a/sys/net/if_lagg.c
+++ b/sys/net/if_lagg.c
@@ -332,7 +332,8 @@ lagg_port_lladdr(struct lagg_port *lp, uint8_t *lladdr)
struct ifnet *ifp = lp->lp_ifp;
int error;
- if (memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)
+ if (lp->lp_detaching ||
+ memcmp(lladdr, IF_LLADDR(ifp), ETHER_ADDR_LEN) == 0)
return;
/* Set the link layer address */
@@ -467,9 +468,15 @@ lagg_port_destroy(struct lagg_port *lp, int runpd)
if (runpd && sc->sc_port_destroy != NULL)
(*sc->sc_port_destroy)(lp);
- /* Remove multicast addresses and interface flags from this port */
- lagg_ether_cmdmulti(lp, 0);
- lagg_setflags(lp, 0);
+ /*
+ * Remove multicast addresses and interface flags from this port and
+ * reset the MAC address, skip if the interface is being detached.
+ */
+ if (!lp->lp_detaching) {
+ lagg_ether_cmdmulti(lp, 0);
+ lagg_setflags(lp, 0);
+ lagg_port_lladdr(lp, lp->lp_lladdr);
+ }
/* Restore interface */
ifp->if_type = lp->lp_iftype;
@@ -499,9 +506,6 @@ lagg_port_destroy(struct lagg_port *lp, int runpd)
lagg_port_lladdr(lp_ptr, lladdr);
}
- /* Reset the port lladdr */
- lagg_port_lladdr(lp, lp->lp_lladdr);
-
if (lp->lp_ifflags)
if_printf(ifp, "%s: lp_ifflags unclean\n", __func__);
@@ -598,6 +602,7 @@ lagg_port_ifdetach(void *arg __unused, struct ifnet *ifp)
sc = lp->lp_lagg;
LAGG_LOCK(sc);
+ lp->lp_detaching = 1;
lagg_port_destroy(lp, 1);
LAGG_UNLOCK(sc);
}
diff --git a/sys/net/if_lagg.h b/sys/net/if_lagg.h
index 3c648f0..968568a 100644
--- a/sys/net/if_lagg.h
+++ b/sys/net/if_lagg.h
@@ -176,6 +176,7 @@ struct lagg_port {
int lp_ifflags; /* saved ifp flags */
void *lh_cookie; /* if state hook */
caddr_t lp_psc; /* protocol data */
+ int lp_detaching; /* ifnet is detaching */
SLIST_HEAD(__mclhd, lagg_mc) lp_mc_head; /* multicast addresses */
OpenPOWER on IntegriCloud