Index: sys/net/if_bridge.c =================================================================== --- sys/net/if_bridge.c +++ sys/net/if_bridge.c @@ -778,9 +778,7 @@ struct ifdrv *ifd = (struct ifdrv *) data; const struct bridge_control *bc; int error = 0, oldmtu; - struct epoch_tracker et; - NET_EPOCH_ENTER(et); switch (cmd) { case SIOCADDMULTI: @@ -901,7 +899,6 @@ break; } - NET_EPOCH_EXIT(et); return (error); } @@ -933,9 +930,7 @@ /* strip off mask bits and enable them again if allowed */ enabled &= ~BRIDGE_IFCAPS_MASK; enabled |= mask; - BRIDGE_UNLOCK(sc); bridge_set_ifcap(sc, bif, enabled); - BRIDGE_LOCK(sc); } } @@ -946,12 +941,13 @@ struct ifreq ifr; int error, mask, stuck; - BRIDGE_UNLOCK_ASSERT(sc); + BRIDGE_LOCK_ASSERT(sc); bzero(&ifr, sizeof(ifr)); ifr.ifr_reqcap = set; if (ifp->if_capenable != set) { + MPASS(! in_epoch(net_epoch_preempt)); error = (*ifp->if_ioctl)(ifp, SIOCSIFCAP, (caddr_t)&ifr); if (error) if_printf(sc->sc_ifp, @@ -977,7 +973,7 @@ struct bridge_iflist *bif; struct ifnet *ifp; - NET_EPOCH_ASSERT(); + MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&sc->sc_mtx)); CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { ifp = bif->bif_ifp; @@ -998,7 +994,7 @@ { struct bridge_iflist *bif; - NET_EPOCH_ASSERT(); + MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&sc->sc_mtx)); CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { if (bif->bif_ifp == member_ifp) @@ -1015,6 +1011,9 @@ bif = __containerof(ctx, struct bridge_iflist, bif_epoch_ctx); + if (bif->bif_flags & IFBIF_STP) + bstp_destroy(&bif->bif_stp); /* prepare to free */ + free(bif, M_DEVBUF); } @@ -1068,7 +1067,6 @@ ifs->if_bridge_output = NULL; ifs->if_bridge_input = NULL; ifs->if_bridge_linkstate = NULL; - BRIDGE_UNLOCK(sc); if (!gone) { switch (ifs->if_type) { case IFT_ETHER: @@ -1094,8 +1092,6 @@ /* reneable any interface capabilities */ bridge_set_ifcap(sc, bif, bif->bif_savedcaps); } - bstp_destroy(&bif->bif_stp); /* prepare to free */ - BRIDGE_LOCK(sc); NET_EPOCH_CALL(bridge_delete_member_cb, &bif->bif_epoch_ctx); } @@ -1492,15 +1488,19 @@ static int bridge_ioctl_saddr(struct bridge_softc *sc, void *arg) { + struct epoch_tracker et; struct ifbareq *req = arg; struct bridge_iflist *bif; int error; - NET_EPOCH_ASSERT(); + NET_EPOCH_ENTER(et); + BRIDGE_LOCK_ASSERT(sc); bif = bridge_lookup_member(sc, req->ifba_ifsname); - if (bif == NULL) + if (bif == NULL) { + NET_EPOCH_EXIT(et); return (ENOENT); + } /* bridge_rtupdate() may acquire the lock. */ BRIDGE_UNLOCK(sc); @@ -1508,6 +1508,8 @@ req->ifba_flags); BRIDGE_LOCK(sc); + NET_EPOCH_EXIT(et); + return (error); } @@ -1532,9 +1534,15 @@ static int bridge_ioctl_daddr(struct bridge_softc *sc, void *arg) { + struct epoch_tracker et; struct ifbareq *req = arg; + int ret; - return (bridge_rtdaddr(sc, req->ifba_dst, req->ifba_vlan)); + NET_EPOCH_ENTER(et); + ret = bridge_rtdaddr(sc, req->ifba_dst, req->ifba_vlan); + NET_EPOCH_EXIT(et); + + return (ret); } static int @@ -3659,8 +3667,6 @@ struct bridge_iflist *bif; int new_link, hasls; - NET_EPOCH_ASSERT(); - new_link = LINK_STATE_DOWN; hasls = 0; /* Our link is considered up if at least one of our ports is active */