diff options
author | 2016-09-28 08:31:42 +0000 | |
---|---|---|
committer | 2016-09-28 08:31:42 +0000 | |
commit | 1bfa6094fbcd01d60c8a4f7c0f94d343d4ec22e4 (patch) | |
tree | 0a3601c58829eadbacec1e842130effa471b244e | |
parent | Rate limit TIOCSWINSZ on a timer to avoid programs getting hammered with (diff) | |
download | wireguard-openbsd-1bfa6094fbcd01d60c8a4f7c0f94d343d4ec22e4.tar.xz wireguard-openbsd-1bfa6094fbcd01d60c8a4f7c0f94d343d4ec22e4.zip |
Fix a kernel panic that happened when destroying interfaces attached to
the switch(4) without prior removal.
ok reyk@, goda@
-rw-r--r-- | sys/net/if.c | 11 | ||||
-rw-r--r-- | sys/net/if_switch.c | 27 | ||||
-rw-r--r-- | sys/net/if_switch.h | 3 |
3 files changed, 31 insertions, 10 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 480f080d29b..5abe7516a51 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.450 2016/09/22 14:50:11 mpi Exp $ */ +/* $OpenBSD: if.c,v 1.451 2016/09/28 08:31:42 rzalamena Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -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 *); @@ -897,6 +901,11 @@ if_deactivate(struct ifnet *ifp) bridge_ifdetach(ifp); #endif +#if NSWITCH > 0 + if (ifp->if_switchport) + switch_port_detach(ifp); +#endif + #if NCARP > 0 /* Remove the interface from any carp group it is a part of. */ if (ifp->if_carp && ifp->if_type != IFT_CARP) diff --git a/sys/net/if_switch.c b/sys/net/if_switch.c index 6309d28f364..c8079cf32c3 100644 --- a/sys/net/if_switch.c +++ b/sys/net/if_switch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_switch.c,v 1.5 2016/09/04 17:11:09 goda Exp $ */ +/* $OpenBSD: if_switch.c,v 1.6 2016/09/28 08:31:42 rzalamena Exp $ */ /* * Copyright (c) 2016 Kazuya GODA <goda@openbsd.org> @@ -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, struct ifbreq *req) } 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 diff --git a/sys/net/if_switch.h b/sys/net/if_switch.h index 7765ac20e11..cb5a9f35b09 100644 --- a/sys/net/if_switch.h +++ b/sys/net/if_switch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_switch.h,v 1.2 2016/09/04 16:47:41 goda Exp $ */ +/* $OpenBSD: if_switch.h,v 1.3 2016/09/28 08:31:42 rzalamena Exp $ */ /* * Copyright (c) 2016 Kazuya GODA <goda@openbsd.org> @@ -215,6 +215,7 @@ void switch_port_egress(struct switch_softc *, struct switch_fwdp_queue *, 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 *); |