Just like the switch(4) diff, this one does the same thing for the bridge(4).
This diff removes bridge(4) code from if.c and uses the detach hook to be notified about interface removals. ok? Index: net/if.c =================================================================== RCS file: /home/obsdcvs/src/sys/net/if.c,v retrieving revision 1.451 diff -u -p -r1.451 if.c --- net/if.c 28 Sep 2016 08:31:42 -0000 1.451 +++ net/if.c 2 Oct 2016 20:40:30 -0000 @@ -895,12 +895,6 @@ if_deactivate(struct ifnet *ifp) */ dohooks(ifp->if_detachhooks, HOOK_REMOVE | HOOK_FREE); -#if NBRIDGE > 0 - /* Remove the interface from any bridge it is part of. */ - if (ifp->if_bridgeport) - bridge_ifdetach(ifp); -#endif - #if NSWITCH > 0 if (ifp->if_switchport) switch_port_detach(ifp); Index: net/if_bridge.c =================================================================== RCS file: /home/obsdcvs/src/sys/net/if_bridge.c,v retrieving revision 1.285 diff -u -p -r1.285 if_bridge.c --- net/if_bridge.c 29 Sep 2016 11:37:44 -0000 1.285 +++ net/if_bridge.c 2 Oct 2016 20:39:56 -0000 @@ -106,6 +106,7 @@ void bridgeattach(int); int bridge_ioctl(struct ifnet *, u_long, caddr_t); +void bridge_ifdetach(void *); int bridge_input(struct ifnet *, struct mbuf *, void *); void bridge_process(struct ifnet *, struct mbuf *); void bridgeintr_frame(struct bridge_softc *, struct ifnet *, struct mbuf *); @@ -244,6 +245,7 @@ bridge_delete(struct bridge_softc *sc, s p->ifp->if_bridgeport = NULL; error = ifpromisc(p->ifp, 0); + hook_disestablish(p->ifp->if_detachhooks, p->bif_dhcookie); if_ih_remove(p->ifp, bridge_input, NULL); TAILQ_REMOVE(&sc->sc_iflist, p, next); @@ -356,6 +358,8 @@ bridge_ioctl(struct ifnet *ifp, u_long c SIMPLEQ_INIT(&p->bif_brlin); SIMPLEQ_INIT(&p->bif_brlout); ifs->if_bridgeport = (caddr_t)p; + p->bif_dhcookie = hook_establish(ifs->if_detachhooks, 0, + bridge_ifdetach, ifs); if_ih_insert(p->ifp, bridge_input, NULL); TAILQ_INSERT_TAIL(&sc->sc_iflist, p, next); break; @@ -567,8 +571,9 @@ bridge_ioctl(struct ifnet *ifp, u_long c /* Detach an interface from a bridge. */ void -bridge_ifdetach(struct ifnet *ifp) +bridge_ifdetach(void *arg) { + struct ifnet *ifp = (struct ifnet *)arg; struct bridge_softc *sc; struct bridge_iflist *bif; Index: net/if_bridge.h =================================================================== RCS file: /home/obsdcvs/src/sys/net/if_bridge.h,v retrieving revision 1.52 diff -u -p -r1.52 if_bridge.h --- net/if_bridge.h 29 Sep 2016 11:37:44 -0000 1.52 +++ net/if_bridge.h 2 Oct 2016 20:35:26 -0000 @@ -398,6 +398,7 @@ struct bridge_iflist { struct brl_head bif_brlout; /* output rules */ struct ifnet *ifp; /* member interface */ u_int32_t bif_flags; /* member flags */ + void *bif_dhcookie; }; #define bif_state bif_stp->bp_state @@ -450,7 +451,6 @@ struct bridge_softc { extern const u_int8_t bstp_etheraddr[]; struct llc; -void bridge_ifdetach(struct ifnet *); int bridge_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); void bridge_update(struct ifnet *, struct ether_addr *, int);