mpi@ suggested that it would be possible to use if_detachhooks to handle the interface teardown instead of adding code to if.c, so this diff does exactly that.
Not only we get to remove switch(4) code from if.c, we also get less lines of code by removing some duplicated teardown procedure in switch_clone_destroy(). ok? Index: net/if_switch.c =================================================================== RCS file: /home/obsdcvs/src/sys/net/if_switch.c,v retrieving revision 1.7 diff -u -p -r1.7 if_switch.c --- net/if_switch.c 29 Sep 2016 11:37:44 -0000 1.7 +++ net/if_switch.c 2 Oct 2016 20:03:33 -0000 @@ -74,6 +74,7 @@ int switch_port_set_local(struct switch int switch_port_unset_local(struct switch_softc *, struct switch_port *); int switch_ioctl(struct ifnet *, unsigned long, caddr_t); int switch_port_add(struct switch_softc *, struct ifbreq *); +void switch_port_detach(void *); int switch_port_del(struct switch_softc *, struct ifbreq *); int switch_port_list(struct switch_softc *, struct ifbifconf *); int switch_output(struct ifnet *, struct mbuf *, struct sockaddr *, @@ -215,16 +216,9 @@ switch_clone_destroy(struct ifnet *ifp) struct ifnet *ifs; TAILQ_FOREACH_SAFE(swpo, &sc->sc_swpo_list, swpo_list_next, tp) { - if ((ifs = if_get(swpo->swpo_ifindex)) != NULL) { - if (swpo->swpo_flags & IFBIF_LOCAL) - switch_port_unset_local(sc, swpo); - ifs->if_switchport = NULL; - ifpromisc(ifs, 0); - if_ih_remove(ifs, switch_input, NULL); - if_put(ifs); - TAILQ_REMOVE(&sc->sc_swpo_list, swpo, swpo_list_next); - free(swpo, M_DEVBUF, sizeof(*swpo)); - } else + if ((ifs = if_get(swpo->swpo_ifindex)) != NULL) + switch_port_detach(ifs); + else log(LOG_ERR, "failed to cleanup on ifindex(%d)\n", swpo->swpo_ifindex); } @@ -576,6 +570,8 @@ switch_port_add(struct switch_softc *sc, ifs->if_switchport = (caddr_t)swpo; if_ih_insert(ifs, switch_input, NULL); swpo->swpo_port_no = swofp_assign_portno(sc, ifs->if_index); + swpo->swpo_dhcookie = hook_establish(ifs->if_detachhooks, 0, + switch_port_detach, ifs); nanouptime(&swpo->swpo_appended); @@ -630,8 +626,9 @@ done: } void -switch_port_detach(struct ifnet *ifp) +switch_port_detach(void *arg) { + struct ifnet *ifp = (struct ifnet *)arg; struct switch_softc *sc = ifp->if_softc; struct switch_port *swpo; @@ -640,6 +637,7 @@ switch_port_detach(struct ifnet *ifp) switch_port_unset_local(sc, swpo); ifp->if_switchport = NULL; + hook_disestablish(ifp->if_detachhooks, swpo->swpo_dhcookie); ifpromisc(ifp, 0); if_ih_remove(ifp, switch_input, NULL); TAILQ_REMOVE(&sc->sc_swpo_list, swpo, swpo_list_next); Index: net/if_switch.h =================================================================== RCS file: /home/obsdcvs/src/sys/net/if_switch.h,v retrieving revision 1.3 diff -u -p -r1.3 if_switch.h --- net/if_switch.h 28 Sep 2016 08:31:42 -0000 1.3 +++ net/if_switch.h 2 Oct 2016 19:47:44 -0000 @@ -174,6 +174,7 @@ struct switch_port { struct timespec swpo_appended; struct switch_softc *swpo_switch; uint32_t swpo_flags; + void *swpo_dhcookie; void (*swop_bk_start)(struct ifnet *); }; @@ -215,7 +216,6 @@ void switch_port_egress(struct switch_s int switch_swfcl_dup(struct switch_flow_classify *, struct switch_flow_classify *); void switch_swfcl_free(struct switch_flow_classify *); -void switch_port_detach(struct ifnet *); /* switchctl.c */ void switch_dev_destroy(struct switch_softc *); 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 19:51:40 -0000 @@ -130,10 +130,6 @@ #include <net/pfvar.h> #endif -#if NSWITCH > 0 -#include <net/if_switch.h> -#endif - void if_attachsetup(struct ifnet *); void if_attachdomain(struct ifnet *); void if_attach_common(struct ifnet *); @@ -899,11 +895,6 @@ if_deactivate(struct ifnet *ifp) /* 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); #endif #if NCARP > 0