switch(4) is currently not handling device removal when the interface is being destroyed.
Example: # ifconfig switch0 up # ifconfig vether0 up # ifconfig switch0 add vether0 # ifconfig vether0 destroy # kernel panic here This diff fixes it by calling the switch port detach on the right time. ok? Index: if.c =================================================================== RCS file: /home/obsdcvs/src/sys/net/if.c,v retrieving revision 1.450 diff -u -p -r1.450 if.c --- if.c 22 Sep 2016 14:50:11 -0000 1.450 +++ if.c 26 Sep 2016 16:05:45 -0000 @@ -130,6 +130,10 @@ #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 *); @@ -895,6 +899,11 @@ 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 Index: if_switch.c =================================================================== RCS file: /home/obsdcvs/src/sys/net/if_switch.c,v retrieving revision 1.5 diff -u -p -r1.5 if_switch.c --- if_switch.c 4 Sep 2016 17:11:09 -0000 1.5 +++ if_switch.c 26 Sep 2016 16:08:17 -0000 @@ -629,6 +629,23 @@ done: return (error); } +void +switch_port_detach(struct ifnet *ifp) +{ + struct switch_softc *sc = ifp->if_softc; + struct switch_port *swpo; + + swpo = (struct switch_port *)ifp->if_switchport; + if (swpo->swpo_flags & IFBIF_LOCAL) + switch_port_unset_local(sc, swpo); + + ifp->if_switchport = NULL; + ifpromisc(ifp, 0); + if_ih_remove(ifp, switch_input, NULL); + TAILQ_REMOVE(&sc->sc_swpo_list, swpo, swpo_list_next); + free(swpo, M_DEVBUF, sizeof(*swpo)); +} + int switch_port_del(struct switch_softc *sc, struct ifbreq *req) { @@ -645,13 +662,7 @@ switch_port_del(struct switch_softc *sc, } if (swpo) { - 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); - TAILQ_REMOVE(&sc->sc_swpo_list, swpo, swpo_list_next); - free(swpo, M_DEVBUF, sizeof(*swpo)); + switch_port_detach(ifs); if_put(ifs); error = 0; } else Index: if_switch.h =================================================================== RCS file: /home/obsdcvs/src/sys/net/if_switch.h,v retrieving revision 1.2 diff -u -p -r1.2 if_switch.h --- if_switch.h 4 Sep 2016 16:47:41 -0000 1.2 +++ if_switch.h 26 Sep 2016 16:05:45 -0000 @@ -215,6 +215,7 @@ 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 *);