From 108fe96a44565352218d33f3f1944a89dade7256 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Mon, 7 May 2007 00:28:55 +0000 Subject: [PATCH] Avoid touching various unsafe parts if the interface is disappearing. --- sys/net/ieee8023ad_lacp.c | 4 +++- sys/net/if_lagg.c | 19 ++++++++++++------- sys/net/if_lagg.h | 1 + 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/sys/net/ieee8023ad_lacp.c b/sys/net/ieee8023ad_lacp.c index 2753c9869369..b02203526978 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 bb23d29ca22c..8eddf4c4bf6e 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 3c648f05d560..968568a8429f 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 */