Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.588 diff -u -p -r1.588 if.c --- net/if.c 21 Aug 2019 15:32:18 -0000 1.588 +++ net/if.c 4 Nov 2019 22:51:52 -0000 @@ -632,9 +623,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 +1035,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 +1140,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]) Index: net/if_aggr.c =================================================================== RCS file: /cvs/src/sys/net/if_aggr.c,v retrieving revision 1.19 diff -u -p -r1.19 if_aggr.c --- net/if_aggr.c 5 Aug 2019 10:42:51 -0000 1.19 +++ net/if_aggr.c 4 Nov 2019 22:51:52 -0000 @@ -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; @@ -1138,8 +1138,9 @@ aggr_add_port(struct aggr_softc *sc, con 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 +1428,7 @@ aggr_p_dtor(struct aggr_softc *sc, struc 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); Index: net/if_bpe.c =================================================================== RCS file: /cvs/src/sys/net/if_bpe.c,v retrieving revision 1.8 diff -u -p -r1.8 if_bpe.c --- net/if_bpe.c 17 Jul 2019 16:46:17 -0000 1.8 +++ net/if_bpe.c 4 Nov 2019 22:51:52 -0000 @@ -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, i 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); } Index: net/if_bridge.c =================================================================== RCS file: /cvs/src/sys/net/if_bridge.c,v retrieving revision 1.337 diff -u -p -r1.337 if_bridge.c --- net/if_bridge.c 20 Jul 2019 23:01:51 -0000 1.337 +++ net/if_bridge.c 4 Nov 2019 22:51:52 -0000 @@ -325,8 +325,8 @@ bridge_ioctl(struct ifnet *ifp, u_long c 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 c 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 *bi 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 * 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(); Index: net/if_bridge.h =================================================================== RCS file: /cvs/src/sys/net/if_bridge.h,v retrieving revision 1.65 diff -u -p -r1.65 if_bridge.h --- net/if_bridge.h 12 May 2019 19:53:22 -0000 1.65 +++ net/if_bridge.h 4 Nov 2019 22:51:52 -0000 @@ -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 Index: net/if_gre.c =================================================================== RCS file: /cvs/src/sys/net/if_gre.c,v retrieving revision 1.152 diff -u -p -r1.152 if_gre.c --- net/if_gre.c 29 Jul 2019 16:28:25 -0000 1.152 +++ net/if_gre.c 4 Nov 2019 22:51:52 -0000 @@ -430,7 +407,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 +769,7 @@ nvgre_clone_create(struct if_clone *ifc, 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 +3630,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 +3641,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 +3686,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); Index: net/if_pfsync.c =================================================================== RCS file: /cvs/src/sys/net/if_pfsync.c,v retrieving revision 1.264 diff -u -p -r1.264 if_pfsync.c --- net/if_pfsync.c 10 Jun 2019 16:32:51 -0000 1.264 +++ net/if_pfsync.c 4 Nov 2019 22:51:52 -0000 @@ -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 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 cm 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 cm 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 cm 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); Index: net/if_switch.c =================================================================== RCS file: /cvs/src/sys/net/if_switch.c,v retrieving revision 1.29 diff -u -p -r1.29 if_switch.c --- net/if_switch.c 30 Sep 2019 01:53:05 -0000 1.29 +++ net/if_switch.c 4 Nov 2019 22:51:52 -0000 @@ -533,8 +533,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); + 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); Index: net/if_switch.h =================================================================== RCS file: /cvs/src/sys/net/if_switch.h,v retrieving revision 1.11 diff -u -p -r1.11 if_switch.h --- net/if_switch.h 10 May 2019 15:13:38 -0000 1.11 +++ net/if_switch.h 4 Nov 2019 22:51:52 -0000 @@ -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 *); }; Index: net/if_tpmr.c =================================================================== RCS file: /cvs/src/sys/net/if_tpmr.c,v retrieving revision 1.4 diff -u -p -r1.4 if_tpmr.c --- net/if_tpmr.c 12 Sep 2019 02:02:54 -0000 1.4 +++ net/if_tpmr.c 4 Nov 2019 22:51:52 -0000 @@ -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; @@ -565,8 +565,8 @@ tpmr_add_port(struct tpmr_softc *sc, con 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, struc 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(); Index: net/if_trunk.c =================================================================== RCS file: /cvs/src/sys/net/if_trunk.c,v retrieving revision 1.141 diff -u -p -r1.141 if_trunk.c --- net/if_trunk.c 5 Jul 2019 01:24:56 -0000 1.141 +++ net/if_trunk.c 4 Nov 2019 22:51:52 -0000 @@ -376,8 +376,8 @@ trunk_port_create(struct trunk_softc *tr 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); Index: net/if_trunk.h =================================================================== RCS file: /cvs/src/sys/net/if_trunk.h,v retrieving revision 1.27 diff -u -p -r1.27 if_trunk.h --- net/if_trunk.h 29 Apr 2019 04:26:47 -0000 1.27 +++ net/if_trunk.h 4 Nov 2019 22:51:52 -0000 @@ -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); Index: net/if_var.h =================================================================== RCS file: /cvs/src/sys/net/if_var.h,v retrieving revision 1.100 diff -u -p -r1.100 if_var.h --- net/if_var.h 26 Jun 2019 09:36:06 -0000 1.100 +++ net/if_var.h 4 Nov 2019 22:51:52 -0000 @@ -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) */ @@ -373,6 +373,9 @@ void if_ih_insert(struct ifnet *, int (* void *), void *); 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); Index: net/if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.200 diff -u -p -r1.200 if_vlan.c --- net/if_vlan.c 4 Nov 2019 04:17:31 -0000 1.200 +++ net/if_vlan.c 4 Nov 2019 22:51:52 -0000 @@ -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, 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); Index: net/if_vxlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vxlan.c,v retrieving revision 1.73 diff -u -p -r1.73 if_vxlan.c --- net/if_vxlan.c 10 Jun 2019 16:32:51 -0000 1.73 +++ net/if_vxlan.c 4 Nov 2019 22:51:52 -0000 @@ -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, 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 *if 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, * 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); Index: netinet/ip_carp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.338 diff -u -p -r1.338 ip_carp.c --- netinet/ip_carp.c 10 Jun 2019 16:32:51 -0000 1.338 +++ netinet/ip_carp.c 4 Nov 2019 22:51:52 -0000 @@ -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, 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, stru 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, stru 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, stru rm_lh: hook_disestablish(ifp0->if_linkstatehooks, sc->lh_cookie); -rm_dh: - hook_disestablish(ifp0->if_detachhooks, sc->dh_cookie); return (error); }