diff --git a/sys/net/if_lagg.c b/sys/net/if_lagg.c index d4c259e..4bc81e4d 100644 --- a/sys/net/if_lagg.c +++ b/sys/net/if_lagg.c @@ -130,6 +130,8 @@ static int lagg_media_change(struct ifnet *); static void lagg_media_status(struct ifnet *, struct ifmediareq *); static struct lagg_port *lagg_link_active(struct lagg_softc *, struct lagg_port *); +static void lagg_remove_pending_lladdr_changes( + struct lagg_softc *, struct ifnet *); /* Simple round robin */ static void lagg_rr_attach(struct lagg_softc *); @@ -541,6 +543,9 @@ lagg_clone_destroy(struct ifnet *ifp) /* Shutdown and remove lagg ports */ while ((lp = SLIST_FIRST(&sc->sc_ports)) != NULL) lagg_port_destroy(lp, 1); + + lagg_remove_pending_lladdr_changes(sc, ifp); + /* Unhook the aggregation protocol */ lagg_proto_detach(sc); LAGG_UNLOCK_ASSERT(sc); @@ -877,7 +882,6 @@ lagg_port_destroy(struct lagg_port *lp, int rundelport) { struct lagg_softc *sc = lp->lp_softc; struct lagg_port *lp_ptr, *lp0; - struct lagg_llq *llq; struct ifnet *ifp = lp->lp_ifp; uint64_t *pval, vdiff; int i; @@ -940,14 +944,7 @@ lagg_port_destroy(struct lagg_port *lp, int rundelport) /* Remove any pending lladdr changes from the queue */ if (lp->lp_detaching) { - SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) { - if (llq->llq_ifp == ifp) { - SLIST_REMOVE(&sc->sc_llq_head, llq, lagg_llq, - llq_entries); - free(llq, M_DEVBUF); - break; /* Only appears once */ - } - } + lagg_remove_pending_lladdr_changes(sc, ifp); } if (lp->lp_ifflags) @@ -1868,6 +1865,23 @@ found: return (rval); } +static void +lagg_remove_pending_lladdr_changes(struct lagg_softc *sc, struct ifnet *ifp) +{ + struct lagg_llq *llq; + + LAGG_WLOCK_ASSERT(sc); + + SLIST_FOREACH(llq, &sc->sc_llq_head, llq_entries) { + if (llq->llq_ifp == ifp) { + SLIST_REMOVE(&sc->sc_llq_head, llq, lagg_llq, + llq_entries); + free(llq, M_DEVBUF); + break; /* Only appears once */ + } + } +} + int lagg_enqueue(struct ifnet *ifp, struct mbuf *m) {