diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2019-11-06 03:51:27 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2019-11-06 03:51:27 +0000 |
commit | 37183277edd5b48bb15c17a71ef7e126f8bbe9a6 (patch) | |
tree | bf26c22343f9120a4cb97280389dbe66513dc176 | |
parent | a6c76ac42cc0d920d495823ca251191871c97868 (diff) |
replace the hooks used with if_detachhooks with a task list.
the main semantic change is that things registering detach hooks
have to allocate and set a task structure that then gets added to
the list. this means if the task is allocated up front (eg, as part
of carps softc or bridges port structure), it avoids the possibility
that adding a hook can fail. a lot of drivers weren't checking for
failure, and unwinding state in the event of failure in other parts
was error prone.
while doing this i discovered that the list operations have to be
in a particular order, but drivers weren't doing that consistently
either. this diff wraps the list ops up so you have to seriously
go out of your way to screw them up.
ive also sprinkled some NET_ASSERT_LOCKED around the list operations
so we can make sure there's no potential for the list to be corrupted,
especially while it's being run.
hrvoje popovski has tested this a bit, and some issues he discovered
have been fixed.
ok sashan@
-rw-r--r-- | sys/net/if.c | 30 | ||||
-rw-r--r-- | sys/net/if_aggr.c | 18 | ||||
-rw-r--r-- | sys/net/if_bpe.c | 11 | ||||
-rw-r--r-- | sys/net/if_bridge.c | 14 | ||||
-rw-r--r-- | sys/net/if_bridge.h | 4 | ||||
-rw-r--r-- | sys/net/if_gre.c | 16 | ||||
-rw-r--r-- | sys/net/if_pfsync.c | 20 | ||||
-rw-r--r-- | sys/net/if_switch.c | 8 | ||||
-rw-r--r-- | sys/net/if_switch.h | 4 | ||||
-rw-r--r-- | sys/net/if_tpmr.c | 16 | ||||
-rw-r--r-- | sys/net/if_trunk.c | 8 | ||||
-rw-r--r-- | sys/net/if_trunk.h | 4 | ||||
-rw-r--r-- | sys/net/if_var.h | 7 | ||||
-rw-r--r-- | sys/net/if_vlan.c | 10 | ||||
-rw-r--r-- | sys/net/if_vxlan.c | 16 | ||||
-rw-r--r-- | sys/netinet/ip_carp.c | 22 |
16 files changed, 104 insertions, 104 deletions
diff --git a/sys/net/if.c b/sys/net/if.c index 17397b68831..0f3e07a53d8 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.588 2019/08/21 15:32:18 florian Exp $ */ +/* $OpenBSD: if.c,v 1.589 2019/11/06 03:51:26 dlg Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -632,9 +632,7 @@ if_attach_common(struct ifnet *ifp) ifp->if_linkstatehooks = malloc(sizeof(*ifp->if_linkstatehooks), M_TEMP, M_WAITOK); TAILQ_INIT(ifp->if_linkstatehooks); - ifp->if_detachhooks = malloc(sizeof(*ifp->if_detachhooks), - M_TEMP, M_WAITOK); - TAILQ_INIT(ifp->if_detachhooks); + TAILQ_INIT(&ifp->if_detachhooks); if (ifp->if_rtrequest == NULL) ifp->if_rtrequest = if_rtrequest_dummy; @@ -1046,17 +1044,36 @@ if_netisr(void *unused) void if_deactivate(struct ifnet *ifp) { - NET_LOCK(); + struct task *t, *nt; + /* * Call detach hooks from head to tail. To make sure detach * hooks are executed in the reverse order they were added, all * the hooks have to be added to the head! */ - dohooks(ifp->if_detachhooks, HOOK_REMOVE | HOOK_FREE); + NET_LOCK(); + TAILQ_FOREACH_SAFE(t, &ifp->if_detachhooks, t_entry, nt) + (*t->t_func)(t->t_arg); + + KASSERT(TAILQ_EMPTY(&ifp->if_detachhooks)); NET_UNLOCK(); } +void +if_detachhook_add(struct ifnet *ifp, struct task *t) +{ + NET_ASSERT_LOCKED(); + TAILQ_INSERT_HEAD(&ifp->if_detachhooks, t, t_entry); +} + +void +if_detachhook_del(struct ifnet *ifp, struct task *t) +{ + NET_ASSERT_LOCKED(); + TAILQ_REMOVE(&ifp->if_detachhooks, t, t_entry); +} + /* * Detach an interface from everything in the kernel. Also deallocate * private resources. @@ -1132,7 +1149,6 @@ if_detach(struct ifnet *ifp) free(ifp->if_addrhooks, M_TEMP, sizeof(*ifp->if_addrhooks)); free(ifp->if_linkstatehooks, M_TEMP, sizeof(*ifp->if_linkstatehooks)); - free(ifp->if_detachhooks, M_TEMP, sizeof(*ifp->if_detachhooks)); for (i = 0; (dp = domains[i]) != NULL; i++) { if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family]) diff --git a/sys/net/if_aggr.c b/sys/net/if_aggr.c index 45aa1588d2e..b73ea41caac 100644 --- a/sys/net/if_aggr.c +++ b/sys/net/if_aggr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_aggr.c,v 1.19 2019/08/05 10:42:51 dlg Exp $ */ +/* $OpenBSD: if_aggr.c,v 1.20 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 2019 The University of Queensland @@ -336,7 +336,7 @@ struct aggr_port { struct rtentry *); void *p_lcookie; - void *p_dcookie; + struct task p_dhook; struct aggr_softc *p_aggr; TAILQ_ENTRY(aggr_port) p_entry; @@ -583,15 +583,14 @@ aggr_clone_destroy(struct ifnet *ifp) if (ISSET(ifp->if_flags, IFF_RUNNING)) aggr_down(sc); + + while ((p = TAILQ_FIRST(&sc->sc_ports)) != NULL) + aggr_p_dtor(sc, p, "destroy"); NET_UNLOCK(); ether_ifdetach(ifp); if_detach(ifp); - /* last ref, no need to lock. aggr_p_dtor locks anyway */ - while ((p = TAILQ_FIRST(&sc->sc_ports)) != NULL) - aggr_p_dtor(sc, p, "destroy"); - free(sc, M_DEVBUF, sizeof(*sc)); return (0); @@ -1138,8 +1137,9 @@ aggr_add_port(struct aggr_softc *sc, const struct trunk_reqport *rp) p->p_lcookie = hook_establish(ifp0->if_linkstatehooks, 1, aggr_p_linkch, p); - p->p_dcookie = hook_establish(ifp0->if_detachhooks, 0, - aggr_p_detach, p); + + task_set(&p->p_dhook, aggr_p_detach, p); + if_detachhook_add(ifp0, &p->p_dhook); task_set(&p->p_rxm_task, aggr_rx, p); mq_init(&p->p_rxm_mq, 3, IPL_NET); @@ -1427,7 +1427,7 @@ aggr_p_dtor(struct aggr_softc *sc, struct aggr_port *p, const char *op) ifp->if_xname, op, ifp0->if_xname); } - hook_disestablish(ifp0->if_detachhooks, p->p_dcookie); + if_detachhook_del(ifp0, &p->p_dhook); hook_disestablish(ifp0->if_linkstatehooks, p->p_lcookie); if_put(ifp0); diff --git a/sys/net/if_bpe.c b/sys/net/if_bpe.c index bc9553d98be..5ad9a41b684 100644 --- a/sys/net/if_bpe.c +++ b/sys/net/if_bpe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bpe.c,v 1.8 2019/07/17 16:46:17 mpi Exp $ */ +/* $OpenBSD: if_bpe.c,v 1.9 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 2018 David Gwynne <dlg@openbsd.org> * @@ -103,7 +103,7 @@ struct bpe_softc { uint8_t sc_group[ETHER_ADDR_LEN]; void * sc_lh_cookie; - void * sc_dh_cookie; + struct task sc_dtask; struct bpe_map sc_bridge_map; struct rwlock sc_bridge_lock; @@ -174,6 +174,8 @@ bpe_clone_create(struct if_clone *ifc, int unit) sc->sc_txhprio = IF_HDRPRIO_PACKET; sc->sc_rxhprio = IF_HDRPRIO_OUTER; + task_set(&sc->sc_dtask, bpe_detach_hook, sc); + rw_init(&sc->sc_bridge_lock, "bpebr"); RBT_INIT(bpe_map, &sc->sc_bridge_map); sc->sc_bridge_num = 0; @@ -636,8 +638,7 @@ bpe_up(struct bpe_softc *sc) bpe_link_hook, sc); /* Register callback if parent wants to unregister */ - sc->sc_dh_cookie = hook_establish(ifp0->if_detachhooks, 0, - bpe_detach_hook, sc); + if_detachhook_add(ifp0, &sc->sc_dtask); /* we're running now */ SET(ifp->if_flags, IFF_RUNNING); @@ -674,7 +675,7 @@ bpe_down(struct bpe_softc *sc) ifp0 = if_get(sc->sc_key.k_if); if (ifp0 != NULL) { - hook_disestablish(ifp0->if_detachhooks, sc->sc_dh_cookie); + if_detachhook_del(ifp0, &sc->sc_dtask); hook_disestablish(ifp0->if_linkstatehooks, sc->sc_lh_cookie); bpe_multi(sc, ifp0, SIOCDELMULTI); } diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 25f4aa1485d..2096af48b24 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.337 2019/07/20 23:01:51 mpi Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.338 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -325,8 +325,8 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) SIMPLEQ_INIT(&bif->bif_brlin); SIMPLEQ_INIT(&bif->bif_brlout); ifs->if_bridgeidx = ifp->if_index; - bif->bif_dhcookie = hook_establish(ifs->if_detachhooks, 0, - bridge_ifdetach, bif); + task_set(&bif->bif_dtask, bridge_ifdetach, bif); + if_detachhook_add(ifs, &bif->bif_dtask); if_ih_insert(bif->ifp, bridge_input, NULL); SMR_SLIST_INSERT_HEAD_LOCKED(&sc->sc_iflist, bif, bif_next); break; @@ -385,8 +385,8 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) bif->bif_flags = IFBIF_SPAN; SIMPLEQ_INIT(&bif->bif_brlin); SIMPLEQ_INIT(&bif->bif_brlout); - bif->bif_dhcookie = hook_establish(ifs->if_detachhooks, 0, - bridge_spandetach, bif); + task_set(&bif->bif_dtask, bridge_spandetach, bif); + if_detachhook_add(ifs, &bif->bif_dtask); SMR_SLIST_INSERT_HEAD_LOCKED(&sc->sc_spanlist, bif, bif_next); break; case SIOCBRDGDELS: @@ -547,7 +547,7 @@ bridge_ifremove(struct bridge_iflist *bif) int error; SMR_SLIST_REMOVE_LOCKED(&sc->sc_iflist, bif, bridge_iflist, bif_next); - hook_disestablish(bif->ifp->if_detachhooks, bif->bif_dhcookie); + if_detachhook_del(bif->ifp, &bif->bif_dtask); if_ih_remove(bif->ifp, bridge_input, NULL); smr_barrier(); @@ -575,7 +575,7 @@ bridge_spanremove(struct bridge_iflist *bif) struct bridge_softc *sc = bif->bridge_sc; SMR_SLIST_REMOVE_LOCKED(&sc->sc_spanlist, bif, bridge_iflist, bif_next); - hook_disestablish(bif->ifp->if_detachhooks, bif->bif_dhcookie); + if_detachhook_del(bif->ifp, &bif->bif_dtask); smr_barrier(); diff --git a/sys/net/if_bridge.h b/sys/net/if_bridge.h index 74e1cfd9838..64393cf9ad2 100644 --- a/sys/net/if_bridge.h +++ b/sys/net/if_bridge.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.h,v 1.65 2019/05/12 19:53:22 mpi Exp $ */ +/* $OpenBSD: if_bridge.h,v 1.66 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -425,7 +425,7 @@ struct bridge_iflist { struct ifnet *ifp; /* [I] net interface */ u_int32_t bif_flags; /* member flags */ u_int32_t bif_protected; /* protected domains */ - void *bif_dhcookie; + struct task bif_dtask; }; #define bif_state bif_stp->bp_state diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c index 15f0b63c901..3d95bae3ae3 100644 --- a/sys/net/if_gre.c +++ b/sys/net/if_gre.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_gre.c,v 1.152 2019/07/29 16:28:25 bluhm Exp $ */ +/* $OpenBSD: if_gre.c,v 1.153 2019/11/06 03:51:26 dlg Exp $ */ /* $NetBSD: if_gre.c,v 1.9 1999/10/25 19:18:11 drochner Exp $ */ /* @@ -430,7 +430,7 @@ struct nvgre_softc { void *sc_inm; void *sc_lhcookie; - void *sc_dhcookie; + struct task sc_dtask; struct rwlock sc_ether_lock; struct nvgre_map sc_ether_map; @@ -792,6 +792,7 @@ nvgre_clone_create(struct if_clone *ifc, int unit) mq_init(&sc->sc_send_list, IFQ_MAXLEN * 2, IPL_SOFTNET); task_set(&sc->sc_send_task, nvgre_send, sc); + task_set(&sc->sc_dtask, nvgre_detach, sc); rw_init(&sc->sc_ether_lock, "nvgrelk"); RBT_INIT(nvgre_map, &sc->sc_ether_map); @@ -3663,12 +3664,7 @@ nvgre_up(struct nvgre_softc *sc) goto delmulti; } - sc->sc_dhcookie = hook_establish(ifp0->if_detachhooks, 0, - nvgre_detach, sc); - if (sc->sc_dhcookie == NULL) { - error = ENOMEM; - goto dislh; - } + if_detachhook_add(ifp0, &sc->sc_dtask); if_put(ifp0); @@ -3679,8 +3675,6 @@ nvgre_up(struct nvgre_softc *sc) return (0); -dislh: - hook_disestablish(ifp0->if_linkstatehooks, sc->sc_lhcookie); delmulti: switch (tunnel->t_af) { case AF_INET: @@ -3726,7 +3720,7 @@ nvgre_down(struct nvgre_softc *sc) ifp0 = if_get(sc->sc_ifp0); if (ifp0 != NULL) { - hook_disestablish(ifp0->if_detachhooks, sc->sc_dhcookie); + if_detachhook_del(ifp0, &sc->sc_dtask); hook_disestablish(ifp0->if_linkstatehooks, sc->sc_lhcookie); } if_put(ifp0); diff --git a/sys/net/if_pfsync.c b/sys/net/if_pfsync.c index fbfe28ea650..3bc01451c5e 100644 --- a/sys/net/if_pfsync.c +++ b/sys/net/if_pfsync.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pfsync.c,v 1.264 2019/06/10 16:32:51 mpi Exp $ */ +/* $OpenBSD: if_pfsync.c,v 1.265 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff @@ -236,7 +236,7 @@ struct pfsync_softc { TAILQ_HEAD(, tdb) sc_tdb_q; void *sc_lhcookie; - void *sc_dhcookie; + struct task sc_dtask; struct timeout sc_tmo; }; @@ -321,6 +321,7 @@ pfsync_clone_create(struct if_clone *ifc, int unit) NULL); TAILQ_INIT(&sc->sc_upd_req_list); TAILQ_INIT(&sc->sc_deferrals); + task_set(&sc->sc_dtask, pfsync_ifdetach, sc); sc->sc_deferred = 0; TAILQ_INIT(&sc->sc_tdb_q); @@ -381,8 +382,7 @@ pfsync_clone_destroy(struct ifnet *ifp) hook_disestablish( sc->sc_sync_if->if_linkstatehooks, sc->sc_lhcookie); - hook_disestablish(sc->sc_sync_if->if_detachhooks, - sc->sc_dhcookie); + if_detachhook_del(sc->sc_sync_if, &sc->sc_dtask); } /* XXXSMP breaks atomicity */ @@ -1350,9 +1350,8 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data) hook_disestablish( sc->sc_sync_if->if_linkstatehooks, sc->sc_lhcookie); - hook_disestablish( - sc->sc_sync_if->if_detachhooks, - sc->sc_dhcookie); + if_detachhook_del(sc->sc_sync_if, + &sc->sc_dtask); } sc->sc_sync_if = NULL; if (imo->imo_num_memberships > 0) { @@ -1376,9 +1375,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data) hook_disestablish( sc->sc_sync_if->if_linkstatehooks, sc->sc_lhcookie); - hook_disestablish( - sc->sc_sync_if->if_detachhooks, - sc->sc_dhcookie); + if_detachhook_del(sc->sc_sync_if, &sc->sc_dtask); } sc->sc_sync_if = sifp; @@ -1424,8 +1421,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cmd, caddr_t data) sc->sc_lhcookie = hook_establish(sc->sc_sync_if->if_linkstatehooks, 1, pfsync_syncdev_state, sc); - sc->sc_dhcookie = hook_establish(sc->sc_sync_if->if_detachhooks, - 0, pfsync_ifdetach, sc); + if_detachhook_add(sc->sc_sync_if, &sc->sc_dtask); pfsync_request_full_update(sc); diff --git a/sys/net/if_switch.c b/sys/net/if_switch.c index 97ff1d1fbba..3683044598c 100644 --- a/sys/net/if_switch.c +++ b/sys/net/if_switch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_switch.c,v 1.29 2019/09/30 01:53:05 dlg Exp $ */ +/* $OpenBSD: if_switch.c,v 1.30 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 2016 Kazuya GODA <goda@openbsd.org> @@ -533,8 +533,8 @@ switch_port_add(struct switch_softc *sc, struct ifbreq *req) 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); + task_set(&swpo->swpo_dtask, switch_port_detach, ifs); + if_detachhook_add(ifs, &swpo->swpo_dtask); nanouptime(&swpo->swpo_appended); @@ -601,7 +601,7 @@ switch_port_detach(void *arg) switch_port_unset_local(sc, swpo); ifp->if_switchport = NULL; - hook_disestablish(ifp->if_detachhooks, swpo->swpo_dhcookie); + if_detachhook_del(ifp, &swpo->swpo_dtask); ifpromisc(ifp, 0); if_ih_remove(ifp, switch_input, NULL); TAILQ_REMOVE(&sc->sc_swpo_list, swpo, swpo_list_next); diff --git a/sys/net/if_switch.h b/sys/net/if_switch.h index cda310729d5..f8bd6df55f9 100644 --- a/sys/net/if_switch.h +++ b/sys/net/if_switch.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_switch.h,v 1.11 2019/05/10 15:13:38 akoshibe Exp $ */ +/* $OpenBSD: if_switch.h,v 1.12 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 2016 Kazuya GODA <goda@openbsd.org> @@ -175,7 +175,7 @@ struct switch_port { struct switch_softc *swpo_switch; uint32_t swpo_flags; uint32_t swpo_protected; - void *swpo_dhcookie; + struct task swpo_dtask; void (*swop_bk_start)(struct ifnet *); }; diff --git a/sys/net/if_tpmr.c b/sys/net/if_tpmr.c index 6af11933c40..231e2e1968b 100644 --- a/sys/net/if_tpmr.c +++ b/sys/net/if_tpmr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_tpmr.c,v 1.4 2019/09/12 02:02:54 dlg Exp $ */ +/* $OpenBSD: if_tpmr.c,v 1.5 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 2019 The University of Queensland @@ -87,7 +87,7 @@ struct tpmr_port { struct rtentry *); void *p_lcookie; - void *p_dcookie; + struct task p_dtask; struct tpmr_softc *p_tpmr; unsigned int p_slot; @@ -197,9 +197,6 @@ tpmr_clone_destroy(struct ifnet *ifp) if (ISSET(ifp->if_flags, IFF_RUNNING)) tpmr_down(sc); - NET_UNLOCK(); - - if_detach(ifp); for (i = 0; i < nitems(sc->sc_ports); i++) { struct tpmr_port *p = SMR_PTR_GET_LOCKED(&sc->sc_ports[i]); @@ -207,6 +204,9 @@ tpmr_clone_destroy(struct ifnet *ifp) continue; tpmr_p_dtor(sc, p, "destroy"); } + NET_UNLOCK(); + + if_detach(ifp); free(sc, M_DEVBUF, sizeof(*sc)); @@ -565,8 +565,8 @@ tpmr_add_port(struct tpmr_softc *sc, const struct trunk_reqport *rp) p->p_lcookie = hook_establish(ifp0->if_linkstatehooks, 1, tpmr_p_linkch, p); - p->p_dcookie = hook_establish(ifp0->if_detachhooks, 0, - tpmr_p_detach, p); + task_set(&p->p_dtask, tpmr_p_detach, p); + if_detachhook_add(ifp0, &p->p_dtask); /* commit */ DPRINTF(sc, "%s %s trunkport: creating port\n", @@ -724,7 +724,7 @@ tpmr_p_dtor(struct tpmr_softc *sc, struct tpmr_port *p, const char *op) ifp->if_xname, ifp0->if_xname); } - hook_disestablish(ifp0->if_detachhooks, p->p_dcookie); + if_detachhook_del(ifp0, &p->p_dtask); hook_disestablish(ifp0->if_linkstatehooks, p->p_lcookie); smr_barrier(); diff --git a/sys/net/if_trunk.c b/sys/net/if_trunk.c index 877be962783..546ba1a8385 100644 --- a/sys/net/if_trunk.c +++ b/sys/net/if_trunk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_trunk.c,v 1.141 2019/07/05 01:24:56 dlg Exp $ */ +/* $OpenBSD: if_trunk.c,v 1.142 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org> @@ -376,8 +376,8 @@ trunk_port_create(struct trunk_softc *tr, struct ifnet *ifp) trunk_port_state, tp); /* Register callback if parent wants to unregister */ - tp->dh_cookie = hook_establish(ifp->if_detachhooks, 0, - trunk_port_ifdetach, tp); + task_set(&tp->tp_dtask, trunk_port_ifdetach, tp); + if_detachhook_add(ifp, &tp->tp_dtask); if (tr->tr_port_create != NULL) error = (*tr->tr_port_create)(tp); @@ -437,7 +437,7 @@ trunk_port_destroy(struct trunk_port *tp) ifp->if_output = tp->tp_output; hook_disestablish(ifp->if_linkstatehooks, tp->lh_cookie); - hook_disestablish(ifp->if_detachhooks, tp->dh_cookie); + if_detachhook_del(ifp, &tp->tp_dtask); /* Finally, remove the port from the trunk */ SLIST_REMOVE(&tr->tr_ports, tp, trunk_port, tp_entries); diff --git a/sys/net/if_trunk.h b/sys/net/if_trunk.h index 21c575f4933..28f93d7a196 100644 --- a/sys/net/if_trunk.h +++ b/sys/net/if_trunk.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_trunk.h,v 1.27 2019/04/29 04:26:47 dlg Exp $ */ +/* $OpenBSD: if_trunk.h,v 1.28 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org> @@ -166,7 +166,7 @@ struct trunk_port { u_int32_t tp_prio; /* port priority */ u_int32_t tp_flags; /* port flags */ void *lh_cookie; /* if state hook */ - void *dh_cookie; /* if detach hook */ + struct task tp_dtask; /* if detach hook */ /* Redirected callbacks */ int (*tp_ioctl)(struct ifnet *, u_long, caddr_t); diff --git a/sys/net/if_var.h b/sys/net/if_var.h index ce52d04184e..deb09ad44da 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_var.h,v 1.100 2019/06/26 09:36:06 claudio Exp $ */ +/* $OpenBSD: if_var.h,v 1.101 2019/11/06 03:51:26 dlg Exp $ */ /* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */ /* @@ -126,7 +126,7 @@ struct ifnet { /* and the entries */ TAILQ_HEAD(, ifg_list) if_groups; /* [N] list of groups per if */ struct hook_desc_head *if_addrhooks; /* [I] address change callbacks */ struct hook_desc_head *if_linkstatehooks; /* [I] link change callbacks*/ - struct hook_desc_head *if_detachhooks; /* [I] detach callbacks */ + struct task_list if_detachhooks; /* [I] detach callbacks */ /* [I] check or clean routes (+ or -)'d */ void (*if_rtrequest)(struct ifnet *, int, struct rtentry *); char if_xname[IFNAMSIZ]; /* [I] external name (name + unit) */ @@ -374,6 +374,9 @@ void if_ih_insert(struct ifnet *, int (*)(struct ifnet *, struct mbuf *, void if_ih_remove(struct ifnet *, int (*)(struct ifnet *, struct mbuf *, void *), void *); +void if_detachhook_add(struct ifnet *, struct task *); +void if_detachhook_del(struct ifnet *, struct task *); + void if_rxr_livelocked(struct if_rxring *); void if_rxr_init(struct if_rxring *, u_int, u_int); u_int if_rxr_get(struct if_rxring *, u_int); diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 84ca1d07bcf..441a14ce304 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vlan.c,v 1.200 2019/11/04 04:17:31 dlg Exp $ */ +/* $OpenBSD: if_vlan.c,v 1.201 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright 1998 Massachusetts Institute of Technology @@ -98,7 +98,7 @@ struct vlan_softc { int sc_flags; struct refcnt sc_refcnt; void *sc_lh_cookie; - void *sc_dh_cookie; + struct task sc_dtask; struct ifih *sc_ifih; }; @@ -192,6 +192,7 @@ vlan_clone_create(struct if_clone *ifc, int unit) sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK|M_ZERO); sc->sc_dead = 0; LIST_INIT(&sc->sc_mc_listhead); + task_set(&sc->sc_dtask, vlan_ifdetach, sc); ifp = &sc->sc_if; ifp->if_softc = sc; snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name, @@ -537,8 +538,7 @@ vlan_up(struct vlan_softc *sc) vlan_link_hook, sc); /* Register callback if parent wants to unregister */ - sc->sc_dh_cookie = hook_establish(ifp0->if_detachhooks, 0, - vlan_ifdetach, sc); + if_detachhook_add(ifp0, &sc->sc_dtask); /* configure the parent to handle packets for this vlan */ vlan_multi_apply(sc, ifp0, SIOCADDMULTI); @@ -591,7 +591,7 @@ vlan_down(struct vlan_softc *sc) if (ISSET(sc->sc_flags, IFVF_PROMISC)) ifpromisc(ifp0, 0); vlan_multi_apply(sc, ifp0, SIOCDELMULTI); - hook_disestablish(ifp0->if_detachhooks, sc->sc_dh_cookie); + if_detachhook_del(ifp0, &sc->sc_dtask); hook_disestablish(ifp0->if_linkstatehooks, sc->sc_lh_cookie); } if_put(ifp0); diff --git a/sys/net/if_vxlan.c b/sys/net/if_vxlan.c index 328af93cce7..a8838538305 100644 --- a/sys/net/if_vxlan.c +++ b/sys/net/if_vxlan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_vxlan.c,v 1.73 2019/06/10 16:32:51 mpi Exp $ */ +/* $OpenBSD: if_vxlan.c,v 1.74 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 2013 Reyk Floeter <reyk@openbsd.org> @@ -64,7 +64,7 @@ struct vxlan_softc { struct ip_moptions sc_imo; void *sc_ahcookie; void *sc_lhcookie; - void *sc_dhcookie; + struct task sc_dtask; struct sockaddr_storage sc_src; struct sockaddr_storage sc_dst; @@ -138,6 +138,7 @@ vxlan_clone_create(struct if_clone *ifc, int unit) sc->sc_vnetid = VXLAN_VNI_UNSET; sc->sc_txhprio = IFQ_TOS2PRIO(IPTOS_PREC_ROUTINE); /* 0 */ sc->sc_df = htons(0); + task_set(&sc->sc_dtask, vxlan_if_change, sc); task_set(&sc->sc_sendtask, vxlan_send_dispatch, sc); ifp = &sc->sc_ac.ac_if; @@ -223,11 +224,7 @@ vxlan_multicast_cleanup(struct ifnet *ifp) sc->sc_lhcookie); sc->sc_lhcookie = NULL; } - if (sc->sc_dhcookie != NULL) { - hook_disestablish(mifp->if_detachhooks, - sc->sc_dhcookie); - sc->sc_dhcookie = NULL; - } + if_detachhook_del(mifp, &sc->sc_dtask); if_put(mifp); } @@ -297,12 +294,11 @@ vxlan_multicast_join(struct ifnet *ifp, struct sockaddr *src, * Use interface hooks to track any changes on the interface * that is used to send out the tunnel traffic as multicast. */ + if_detachhook_add(mifp, &sc->sc_dtask); if ((sc->sc_ahcookie = hook_establish(mifp->if_addrhooks, 0, vxlan_addr_change, sc)) == NULL || (sc->sc_lhcookie = hook_establish(mifp->if_linkstatehooks, - 0, vxlan_link_change, sc)) == NULL || - (sc->sc_dhcookie = hook_establish(mifp->if_detachhooks, - 0, vxlan_if_change, sc)) == NULL) + 0, vxlan_link_change, sc)) == NULL) panic("%s: cannot allocate interface hook", mifp->if_xname); diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c index 80ce7cb4b38..da763361493 100644 --- a/sys/netinet/ip_carp.c +++ b/sys/netinet/ip_carp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_carp.c,v 1.338 2019/06/10 16:32:51 mpi Exp $ */ +/* $OpenBSD: ip_carp.c,v 1.339 2019/11/06 03:51:26 dlg Exp $ */ /* * Copyright (c) 2002 Michael Shalayeff. All rights reserved. @@ -133,7 +133,7 @@ struct carp_softc { #define sc_carpdev sc_ac.ac_if.if_carpdev void *ah_cookie; void *lh_cookie; - void *dh_cookie; + struct task sc_dtask; struct ip_moptions sc_imo; #ifdef INET6 struct ip6_moptions sc_im6o; @@ -808,6 +808,8 @@ carp_clone_create(struct if_clone *ifc, int unit) return (ENOMEM); } + task_set(&sc->sc_dtask, carpdetach, sc); + sc->sc_suppress = 0; sc->sc_advbase = CARP_DFLTINTV; sc->sc_naddrs = sc->sc_naddrs6 = 0; @@ -955,7 +957,7 @@ carpdetach(void *arg) sc->sc_carpdev = NULL; hook_disestablish(ifp0->if_linkstatehooks, sc->lh_cookie); - hook_disestablish(ifp0->if_detachhooks, sc->dh_cookie); + if_detachhook_del(ifp0, &sc->sc_dtask); } void @@ -1685,17 +1687,10 @@ carp_set_ifp(struct carp_softc *sc, struct ifnet *ifp0) if (ifp0->if_type != IFT_ETHER) return (EINVAL); - sc->dh_cookie = hook_establish(ifp0->if_detachhooks, 0, - carpdetach, sc); - if (sc->dh_cookie == NULL) - return (ENOMEM); - sc->lh_cookie = hook_establish(ifp0->if_linkstatehooks, 1, carp_carpdev_state, ifp0); - if (sc->lh_cookie == NULL) { - error = ENOMEM; - goto rm_dh; - } + if (sc->lh_cookie == NULL) + return (ENOMEM); cif = &ifp0->if_carp; if (SRPL_EMPTY_LOCKED(cif)) { @@ -1712,6 +1707,7 @@ carp_set_ifp(struct carp_softc *sc, struct ifnet *ifp0) carpdetach(sc); /* attach carp interface to physical interface */ + if_detachhook_add(ifp0, &sc->sc_dtask); sc->sc_carpdev = ifp0; sc->sc_if.if_capabilities = ifp0->if_capabilities & IFCAP_CSUM_MASK; @@ -1755,8 +1751,6 @@ carp_set_ifp(struct carp_softc *sc, struct ifnet *ifp0) rm_lh: hook_disestablish(ifp0->if_linkstatehooks, sc->lh_cookie); -rm_dh: - hook_disestablish(ifp0->if_detachhooks, sc->dh_cookie); return (error); } |