diff options
author | Rafael Zalamena <rzalamena@cvs.openbsd.org> | 2016-10-03 15:53:10 +0000 |
---|---|---|
committer | Rafael Zalamena <rzalamena@cvs.openbsd.org> | 2016-10-03 15:53:10 +0000 |
commit | 4298ffc0ed3b673be190d48f7acf5d5b23c0365a (patch) | |
tree | 6f72b02858e076b82a5869a01fe4d80d8e9a9980 | |
parent | 173fb3cb941741c47dc37d585b4e50d163823bb7 (diff) |
Use detach hook to notify bridge(4) about span port removals.
ok mpi@
-rw-r--r-- | sys/net/if_bridge.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index ee725ca8ad6..7b0c364cf60 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.286 2016/10/03 12:26:13 rzalamena Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.287 2016/10/03 15:53:09 rzalamena Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -107,6 +107,7 @@ void bridgeattach(int); int bridge_ioctl(struct ifnet *, u_long, caddr_t); void bridge_ifdetach(void *); +void bridge_spandetach(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 *); @@ -215,10 +216,8 @@ bridge_clone_destroy(struct ifnet *ifp) bridge_rtflush(sc, IFBF_FLUSHALL); while ((bif = TAILQ_FIRST(&sc->sc_iflist)) != NULL) bridge_delete(sc, bif); - while ((bif = TAILQ_FIRST(&sc->sc_spanlist)) != NULL) { - TAILQ_REMOVE(&sc->sc_spanlist, bif, next); - free(bif, M_DEVBUF, sizeof *bif); - } + while ((bif = TAILQ_FIRST(&sc->sc_spanlist)) != NULL) + bridge_spandetach(bif); bstp_destroy(sc->sc_stp); @@ -408,6 +407,9 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } p->ifp = ifs; p->bif_flags = IFBIF_SPAN; + p->bridge_sc = sc; + p->bif_dhcookie = hook_establish(ifs->if_detachhooks, 0, + bridge_spandetach, p); SIMPLEQ_INIT(&p->bif_brlin); SIMPLEQ_INIT(&p->bif_brlout); TAILQ_INSERT_TAIL(&sc->sc_spanlist, p, next); @@ -418,8 +420,7 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) TAILQ_FOREACH(p, &sc->sc_spanlist, next) { if (strncmp(p->ifp->if_xname, req->ifbr_ifsname, sizeof(p->ifp->if_xname)) == 0) { - TAILQ_REMOVE(&sc->sc_spanlist, p, next); - free(p, M_DEVBUF, sizeof *p); + bridge_spandetach(p); break; } } @@ -583,6 +584,17 @@ bridge_ifdetach(void *arg) bridge_delete(sc, bif); } +void +bridge_spandetach(void *arg) +{ + struct bridge_iflist *p = (struct bridge_iflist *)arg; + struct bridge_softc *sc = p->bridge_sc; + + hook_disestablish(p->ifp->if_detachhooks, p->bif_dhcookie); + TAILQ_REMOVE(&sc->sc_spanlist, p, next); + free(p, M_DEVBUF, sizeof(*p)); +} + int bridge_bifconf(struct bridge_softc *sc, struct ifbifconf *bifc) { |