On Wed, Nov 06, 2019 at 03:12:27PM +1000, David Gwynne wrote:
> this is a follow-up to "use tasks and a task_list to manage
> if_detachhooks" and converts the link state hooks to a task_list
> with pre-allocated tasks.
> 
> it's mostly mechanical, except for carp. each carp interface has a link
> state hook it registers on its parent, but each hook then runs against
> every carp device on that parent. the diff changes it so the link state
> hook is only run for the relevant carp interface.
> 
> it also reorders the addition of the carp link state hook till after the
> old link state hook is removed.
> 
> unless anyone objects i am going to commit this around 10am GMT+10
> tomorrow (7th nov).

hrvoje points out i missed a file in my diff.

Index: net/bridgestp.c
===================================================================
RCS file: /cvs/src/sys/net/bridgestp.c,v
retrieving revision 1.72
diff -u -p -r1.72 bridgestp.c
--- net/bridgestp.c     13 May 2019 18:20:13 -0000      1.72
+++ net/bridgestp.c     6 Nov 2019 11:13:24 -0000
@@ -1986,9 +1986,8 @@ bstp_add(struct bstp_state *bs, struct i
        bstp_update_roles(bs, bp);
 
        /* Register callback for physical link state changes */
-       if (ifp->if_linkstatehooks != NULL)
-               bp->bp_lhcookie = hook_establish(ifp->if_linkstatehooks, 1,
-                   bstp_ifstate, ifp);
+       task_set(&bp->bp_ltask, bstp_ifstate, ifp);
+       if_linkstatehook_add(ifp, &bp->bp_ltask);
 
        return (bp);
 }
@@ -2002,8 +2001,7 @@ bstp_delete(struct bstp_port *bp)
        if (!bp->bp_active)
                panic("not a bstp member");
 
-       if (ifp != NULL && ifp->if_linkstatehooks != NULL)
-               hook_disestablish(ifp->if_linkstatehooks, bp->bp_lhcookie);
+       if_linkstatehook_del(ifp, &bp->bp_ltask);
 
        LIST_REMOVE(bp, bp_next);
        free(bp, M_DEVBUF, sizeof *bp);
Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.589
diff -u -p -r1.589 if.c
--- net/if.c    6 Nov 2019 03:51:26 -0000       1.589
+++ net/if.c    6 Nov 2019 11:13:24 -0000
@@ -629,9 +629,7 @@ if_attach_common(struct ifnet *ifp)
        ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks),
            M_TEMP, M_WAITOK);
        TAILQ_INIT(ifp->if_addrhooks);
-       ifp->if_linkstatehooks = malloc(sizeof(*ifp->if_linkstatehooks),
-           M_TEMP, M_WAITOK);
-       TAILQ_INIT(ifp->if_linkstatehooks);
+       TAILQ_INIT(&ifp->if_linkstatehooks);
        TAILQ_INIT(&ifp->if_detachhooks);
 
        if (ifp->if_rtrequest == NULL)
@@ -1055,8 +1053,6 @@ if_deactivate(struct ifnet *ifp)
        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();
 }
 
@@ -1148,7 +1144,8 @@ 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));
+       KASSERT(TAILQ_EMPTY(&ifp->if_linkstatehooks));
+       KASSERT(TAILQ_EMPTY(&ifp->if_detachhooks));
 
        for (i = 0; (dp = domains[i]) != NULL; i++) {
                if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family])
@@ -1646,11 +1643,29 @@ if_linkstate_task(void *xifidx)
 void
 if_linkstate(struct ifnet *ifp)
 {
+       struct task *t, *nt;
+
        NET_ASSERT_LOCKED();
 
        rtm_ifchg(ifp);
        rt_if_track(ifp);
-       dohooks(ifp->if_linkstatehooks, 0);
+
+       TAILQ_FOREACH_SAFE(t, &ifp->if_linkstatehooks, t_entry, nt)
+               (*t->t_func)(t->t_arg);
+}
+
+void
+if_linkstatehook_add(struct ifnet *ifp, struct task *t)
+{
+       NET_ASSERT_LOCKED();
+       TAILQ_INSERT_TAIL(&ifp->if_linkstatehooks, t, t_entry);
+}
+
+void
+if_linkstatehook_del(struct ifnet *ifp, struct task *t)
+{
+       NET_ASSERT_LOCKED();
+       TAILQ_REMOVE(&ifp->if_linkstatehooks, t, t_entry);
 }
 
 /*
Index: net/if_aggr.c
===================================================================
RCS file: /cvs/src/sys/net/if_aggr.c,v
retrieving revision 1.20
diff -u -p -r1.20 if_aggr.c
--- net/if_aggr.c       6 Nov 2019 03:51:26 -0000       1.20
+++ net/if_aggr.c       6 Nov 2019 11:13:24 -0000
@@ -335,7 +335,7 @@ struct aggr_port {
        int (*p_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
            struct rtentry *);
 
-       void                    *p_lcookie;
+       struct task              p_lhook;
        struct task              p_dhook;
 
        struct aggr_softc       *p_aggr;
@@ -1135,8 +1135,8 @@ aggr_add_port(struct aggr_softc *sc, con
                }
        }
 
-       p->p_lcookie = hook_establish(ifp0->if_linkstatehooks, 1,
-           aggr_p_linkch, p);
+       task_set(&p->p_lhook, aggr_p_linkch, p);
+       if_linkstatehook_add(ifp0, &p->p_lhook);
 
        task_set(&p->p_dhook, aggr_p_detach, p);
        if_detachhook_add(ifp0, &p->p_dhook);
@@ -1428,7 +1428,7 @@ aggr_p_dtor(struct aggr_softc *sc, struc
        }
 
        if_detachhook_del(ifp0, &p->p_dhook);
-       hook_disestablish(ifp0->if_linkstatehooks, p->p_lcookie);
+       if_linkstatehook_del(ifp0, &p->p_lhook);
 
        if_put(ifp0);
        free(p, M_DEVBUF, sizeof(*p));
Index: net/if_bpe.c
===================================================================
RCS file: /cvs/src/sys/net/if_bpe.c,v
retrieving revision 1.9
diff -u -p -r1.9 if_bpe.c
--- net/if_bpe.c        6 Nov 2019 03:51:26 -0000       1.9
+++ net/if_bpe.c        6 Nov 2019 11:13:24 -0000
@@ -102,7 +102,7 @@ struct bpe_softc {
        int                     sc_rxhprio;
        uint8_t                 sc_group[ETHER_ADDR_LEN];
 
-       void *                  sc_lh_cookie;
+       struct task             sc_ltask;
        struct task             sc_dtask;
 
        struct bpe_map          sc_bridge_map;
@@ -174,6 +174,7 @@ bpe_clone_create(struct if_clone *ifc, i
        sc->sc_txhprio = IF_HDRPRIO_PACKET;
        sc->sc_rxhprio = IF_HDRPRIO_OUTER;
 
+       task_set(&sc->sc_ltask, bpe_link_hook, sc);
        task_set(&sc->sc_dtask, bpe_detach_hook, sc);
 
        rw_init(&sc->sc_bridge_lock, "bpebr");
@@ -634,8 +635,7 @@ bpe_up(struct bpe_softc *sc)
        }
 
        /* Register callback for physical link state changes */
-       sc->sc_lh_cookie = hook_establish(ifp0->if_linkstatehooks, 1,
-           bpe_link_hook, sc);
+       if_linkstatehook_add(ifp0, &sc->sc_ltask);
 
        /* Register callback if parent wants to unregister */
        if_detachhook_add(ifp0, &sc->sc_dtask);
@@ -676,7 +676,7 @@ bpe_down(struct bpe_softc *sc)
        ifp0 = if_get(sc->sc_key.k_if);
        if (ifp0 != NULL) {
                if_detachhook_del(ifp0, &sc->sc_dtask);
-               hook_disestablish(ifp0->if_linkstatehooks, sc->sc_lh_cookie);
+               if_linkstatehook_del(ifp0, &sc->sc_ltask);
                bpe_multi(sc, ifp0, SIOCDELMULTI);
        }
        if_put(ifp0);
Index: net/if_bridge.h
===================================================================
RCS file: /cvs/src/sys/net/if_bridge.h,v
retrieving revision 1.66
diff -u -p -r1.66 if_bridge.h
--- net/if_bridge.h     6 Nov 2019 03:51:26 -0000       1.66
+++ net/if_bridge.h     6 Nov 2019 11:13:24 -0000
@@ -331,7 +331,7 @@ struct bstp_port {
        LIST_ENTRY(bstp_port)   bp_next;
        struct ifnet            *bp_ifp;        /* parent if */
        struct bstp_state       *bp_bs;
-       void                    *bp_lhcookie;   /* if linkstate hook */
+       struct task             bp_ltask;       /* if linkstate hook */
        u_int8_t                bp_active;
        u_int8_t                bp_protover;
        u_int32_t               bp_flags;
Index: net/if_gre.c
===================================================================
RCS file: /cvs/src/sys/net/if_gre.c,v
retrieving revision 1.153
diff -u -p -r1.153 if_gre.c
--- net/if_gre.c        6 Nov 2019 03:51:26 -0000       1.153
+++ net/if_gre.c        6 Nov 2019 11:13:24 -0000
@@ -429,7 +429,7 @@ struct nvgre_softc {
        struct task              sc_send_task;
 
        void                    *sc_inm;
-       void                    *sc_lhcookie;
+       struct task              sc_ltask;
        struct task              sc_dtask;
 
        struct rwlock            sc_ether_lock;
@@ -792,6 +792,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_ltask, nvgre_link_change, sc);
        task_set(&sc->sc_dtask, nvgre_detach, sc);
 
        rw_init(&sc->sc_ether_lock, "nvgrelk");
@@ -3657,13 +3658,7 @@ nvgre_up(struct nvgre_softc *sc)
                unhandled_af(tunnel->t_af);
        }
 
-       sc->sc_lhcookie = hook_establish(ifp0->if_linkstatehooks, 0,
-           nvgre_link_change, sc);
-       if (sc->sc_lhcookie == NULL) {
-               error = ENOMEM;
-               goto delmulti;
-       }
-
+       if_linkstatehook_add(ifp0, &sc->sc_ltask);
        if_detachhook_add(ifp0, &sc->sc_dtask);
 
        if_put(ifp0);
@@ -3675,19 +3670,6 @@ nvgre_up(struct nvgre_softc *sc)
 
        return (0);
 
-delmulti:
-       switch (tunnel->t_af) {
-       case AF_INET:
-               in_delmulti(inm);
-               break;
-#ifdef INET6
-       case AF_INET6:
-               in6_delmulti(inm);
-               break;
-#endif
-       default:
-               unhandled_af(tunnel->t_af);
-       }
 remove_ucast:
        RBT_REMOVE(nvgre_ucast_tree, &nvgre_ucast_tree, sc);
 remove_mcast:
@@ -3721,7 +3703,7 @@ nvgre_down(struct nvgre_softc *sc)
        ifp0 = if_get(sc->sc_ifp0);
        if (ifp0 != NULL) {
                if_detachhook_del(ifp0, &sc->sc_dtask);
-               hook_disestablish(ifp0->if_linkstatehooks, sc->sc_lhcookie);
+               if_linkstatehook_del(ifp0, &sc->sc_ltask);
        }
        if_put(ifp0);
 
Index: net/if_pfsync.c
===================================================================
RCS file: /cvs/src/sys/net/if_pfsync.c,v
retrieving revision 1.265
diff -u -p -r1.265 if_pfsync.c
--- net/if_pfsync.c     6 Nov 2019 03:51:26 -0000       1.265
+++ net/if_pfsync.c     6 Nov 2019 11:13:24 -0000
@@ -235,7 +235,7 @@ struct pfsync_softc {
 
        TAILQ_HEAD(, tdb)        sc_tdb_q;
 
-       void                    *sc_lhcookie;
+       struct task              sc_ltask;
        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_ltask, pfsync_syncdev_state, sc);
        task_set(&sc->sc_dtask, pfsync_ifdetach, sc);
        sc->sc_deferred = 0;
 
@@ -379,9 +380,7 @@ pfsync_clone_destroy(struct ifnet *ifp)
                carp_group_demote_adj(&sc->sc_if, -1, "pfsync destroy");
 #endif
        if (sc->sc_sync_if) {
-               hook_disestablish(
-                   sc->sc_sync_if->if_linkstatehooks,
-                   sc->sc_lhcookie);
+               if_linkstatehook_del(sc->sc_sync_if, &sc->sc_ltask);
                if_detachhook_del(sc->sc_sync_if, &sc->sc_dtask);
        }
 
@@ -1347,9 +1346,8 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
 
                if (pfsyncr.pfsyncr_syncdev[0] == 0) {
                        if (sc->sc_sync_if) {
-                               hook_disestablish(
-                                   sc->sc_sync_if->if_linkstatehooks,
-                                   sc->sc_lhcookie);
+                               if_linkstatehook_del(sc->sc_sync_if,
+                                   &sc->sc_ltask);
                                if_detachhook_del(sc->sc_sync_if,
                                    &sc->sc_dtask);
                        }
@@ -1372,9 +1370,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
                        pfsync_sendout();
 
                if (sc->sc_sync_if) {
-                       hook_disestablish(
-                           sc->sc_sync_if->if_linkstatehooks,
-                           sc->sc_lhcookie);
+                       if_linkstatehook_del(sc->sc_sync_if, &sc->sc_ltask);
                        if_detachhook_del(sc->sc_sync_if, &sc->sc_dtask);
                }
                sc->sc_sync_if = sifp;
@@ -1418,9 +1414,7 @@ pfsyncioctl(struct ifnet *ifp, u_long cm
                ip->ip_src.s_addr = INADDR_ANY;
                ip->ip_dst.s_addr = sc->sc_sync_peer.s_addr;
 
-               sc->sc_lhcookie =
-                   hook_establish(sc->sc_sync_if->if_linkstatehooks, 1,
-                   pfsync_syncdev_state, sc);
+               if_linkstatehook_add(sc->sc_sync_if, &sc->sc_ltask);
                if_detachhook_add(sc->sc_sync_if, &sc->sc_dtask);
 
                pfsync_request_full_update(sc);
Index: net/if_tpmr.c
===================================================================
RCS file: /cvs/src/sys/net/if_tpmr.c,v
retrieving revision 1.5
diff -u -p -r1.5 if_tpmr.c
--- net/if_tpmr.c       6 Nov 2019 03:51:26 -0000       1.5
+++ net/if_tpmr.c       6 Nov 2019 11:13:24 -0000
@@ -86,7 +86,7 @@ struct tpmr_port {
        int (*p_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
            struct rtentry *);
 
-       void                    *p_lcookie;
+       struct task              p_ltask;
        struct task              p_dtask;
 
        struct tpmr_softc       *p_tpmr;
@@ -563,8 +563,9 @@ tpmr_add_port(struct tpmr_softc *sc, con
        if (error != 0)
                goto free;
 
-       p->p_lcookie = hook_establish(ifp0->if_linkstatehooks, 1,
-           tpmr_p_linkch, p);
+       task_set(&p->p_ltask, tpmr_p_linkch, p);
+       if_linkstatehook_add(ifp0, &p->p_ltask);
+
        task_set(&p->p_dtask, tpmr_p_detach, p);
        if_detachhook_add(ifp0, &p->p_dtask);
 
@@ -725,7 +726,7 @@ tpmr_p_dtor(struct tpmr_softc *sc, struc
        }
 
        if_detachhook_del(ifp0, &p->p_dtask);
-       hook_disestablish(ifp0->if_linkstatehooks, p->p_lcookie);
+       if_linkstatehook_del(ifp0, &p->p_ltask);
 
        smr_barrier();
 
Index: net/if_trunk.c
===================================================================
RCS file: /cvs/src/sys/net/if_trunk.c,v
retrieving revision 1.142
diff -u -p -r1.142 if_trunk.c
--- net/if_trunk.c      6 Nov 2019 03:51:26 -0000       1.142
+++ net/if_trunk.c      6 Nov 2019 11:13:24 -0000
@@ -372,8 +372,8 @@ trunk_port_create(struct trunk_softc *tr
        trunk_ether_cmdmulti(tp, SIOCADDMULTI);
 
        /* Register callback for physical link state changes */
-       tp->lh_cookie = hook_establish(ifp->if_linkstatehooks, 1,
-           trunk_port_state, tp);
+       task_set(&tp->tp_ltask, trunk_port_state, tp);
+       if_linkstatehook_add(ifp, &tp->tp_ltask);
 
        /* Register callback if parent wants to unregister */
        task_set(&tp->tp_dtask, trunk_port_ifdetach, tp);
@@ -436,8 +436,8 @@ trunk_port_destroy(struct trunk_port *tp
        ifp->if_ioctl = tp->tp_ioctl;
        ifp->if_output = tp->tp_output;
 
-       hook_disestablish(ifp->if_linkstatehooks, tp->lh_cookie);
        if_detachhook_del(ifp, &tp->tp_dtask);
+       if_linkstatehook_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.28
diff -u -p -r1.28 if_trunk.h
--- net/if_trunk.h      6 Nov 2019 03:51:26 -0000       1.28
+++ net/if_trunk.h      6 Nov 2019 11:13:24 -0000
@@ -165,7 +165,7 @@ struct trunk_port {
        u_char                          tp_iftype;      /* interface type */
        u_int32_t                       tp_prio;        /* port priority */
        u_int32_t                       tp_flags;       /* port flags */
-       void                            *lh_cookie;     /* if state hook */
+       struct task                     tp_ltask;       /* if state hook */
        struct task                     tp_dtask;       /* if detach hook */
 
        /* Redirected callbacks */
Index: net/if_var.h
===================================================================
RCS file: /cvs/src/sys/net/if_var.h,v
retrieving revision 1.101
diff -u -p -r1.101 if_var.h
--- net/if_var.h        6 Nov 2019 03:51:26 -0000       1.101
+++ net/if_var.h        6 Nov 2019 11:13:24 -0000
@@ -125,7 +125,7 @@ struct ifnet {                              /* and the 
entries */
        TAILQ_HEAD(, ifmaddr) if_maddrlist; /* [N] list of multicast records */
        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 task_list if_linkstatehooks; /* [I] link change callbacks*/
        struct task_list if_detachhooks; /* [I] detach callbacks */
                                /* [I] check or clean routes (+ or -)'d */
        void    (*if_rtrequest)(struct ifnet *, int, struct rtentry *);
@@ -376,6 +376,8 @@ void        if_ih_remove(struct ifnet *, int (*
 
 void   if_detachhook_add(struct ifnet *, struct task *);
 void   if_detachhook_del(struct ifnet *, struct task *);
+void   if_linkstatehook_add(struct ifnet *, struct task *);
+void   if_linkstatehook_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.201
diff -u -p -r1.201 if_vlan.c
--- net/if_vlan.c       6 Nov 2019 03:51:26 -0000       1.201
+++ net/if_vlan.c       6 Nov 2019 11:13:24 -0000
@@ -97,7 +97,7 @@ struct vlan_softc {
        SRPL_ENTRY(vlan_softc)   sc_list;
        int                      sc_flags;
        struct refcnt            sc_refcnt;
-       void                    *sc_lh_cookie;
+       struct task              sc_ltask;
        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_ltask, vlan_link_hook, sc);
        task_set(&sc->sc_dtask, vlan_ifdetach, sc);
        ifp = &sc->sc_if;
        ifp->if_softc = sc;
@@ -534,8 +535,7 @@ vlan_up(struct vlan_softc *sc)
        rw_exit(&vlan_tagh_lk);
 
        /* Register callback for physical link state changes */
-       sc->sc_lh_cookie = hook_establish(ifp0->if_linkstatehooks, 1,
-           vlan_link_hook, sc);
+       if_linkstatehook_add(ifp0, &sc->sc_ltask);
 
        /* Register callback if parent wants to unregister */
        if_detachhook_add(ifp0, &sc->sc_dtask);
@@ -592,7 +592,7 @@ vlan_down(struct vlan_softc *sc)
                        ifpromisc(ifp0, 0);
                vlan_multi_apply(sc, ifp0, SIOCDELMULTI);
                if_detachhook_del(ifp0, &sc->sc_dtask);
-               hook_disestablish(ifp0->if_linkstatehooks, sc->sc_lh_cookie);
+               if_linkstatehook_del(ifp0, &sc->sc_ltask);
        }
        if_put(ifp0);
 
Index: net/if_vxlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vxlan.c,v
retrieving revision 1.74
diff -u -p -r1.74 if_vxlan.c
--- net/if_vxlan.c      6 Nov 2019 03:51:26 -0000       1.74
+++ net/if_vxlan.c      6 Nov 2019 11:13:24 -0000
@@ -63,7 +63,7 @@ struct vxlan_softc {
 
        struct ip_moptions       sc_imo;
        void                    *sc_ahcookie;
-       void                    *sc_lhcookie;
+       struct task              sc_ltask;
        struct task              sc_dtask;
 
        struct sockaddr_storage  sc_src;
@@ -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_ltask, vxlan_link_change, sc);
        task_set(&sc->sc_dtask, vxlan_if_change, sc);
        task_set(&sc->sc_sendtask, vxlan_send_dispatch, sc);
 
@@ -219,11 +220,7 @@ vxlan_multicast_cleanup(struct ifnet *if
                        hook_disestablish(mifp->if_addrhooks, sc->sc_ahcookie);
                        sc->sc_ahcookie = NULL;
                }
-               if (sc->sc_lhcookie != NULL) {
-                       hook_disestablish(mifp->if_linkstatehooks,
-                           sc->sc_lhcookie);
-                       sc->sc_lhcookie = NULL;
-               }
+               if_linkstatehook_del(mifp, &sc->sc_ltask);
                if_detachhook_del(mifp, &sc->sc_dtask);
 
                if_put(mifp);
@@ -294,11 +291,10 @@ 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_linkstatehook_add(mifp, &sc->sc_ltask);
        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)
+           0, vxlan_addr_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.339
diff -u -p -r1.339 ip_carp.c
--- netinet/ip_carp.c   6 Nov 2019 03:51:26 -0000       1.339
+++ netinet/ip_carp.c   6 Nov 2019 11:13:24 -0000
@@ -132,7 +132,7 @@ struct carp_softc {
 #define        sc_if           sc_ac.ac_if
 #define        sc_carpdev      sc_ac.ac_if.if_carpdev
        void *ah_cookie;
-       void *lh_cookie;
+       struct task sc_ltask;
        struct task sc_dtask;
        struct ip_moptions sc_imo;
 #ifdef INET6
@@ -808,6 +808,7 @@ carp_clone_create(struct if_clone *ifc, 
                return (ENOMEM);
        }
 
+       task_set(&sc->sc_ltask, carp_carpdev_state, sc);
        task_set(&sc->sc_dtask, carpdetach, sc);
 
        sc->sc_suppress = 0;
@@ -956,7 +957,7 @@ carpdetach(void *arg)
                ifpromisc(ifp0, 0);
        sc->sc_carpdev = NULL;
 
-       hook_disestablish(ifp0->if_linkstatehooks, sc->lh_cookie);
+       if_linkstatehook_del(ifp0, &sc->sc_ltask);
        if_detachhook_del(ifp0, &sc->sc_dtask);
 }
 
@@ -1687,20 +1688,13 @@ carp_set_ifp(struct carp_softc *sc, stru
        if (ifp0->if_type != IFT_ETHER)
                return (EINVAL);
 
-       sc->lh_cookie = hook_establish(ifp0->if_linkstatehooks, 1,
-           carp_carpdev_state, ifp0);
-       if (sc->lh_cookie == NULL)
-               return (ENOMEM);
-
        cif = &ifp0->if_carp;
        if (SRPL_EMPTY_LOCKED(cif)) {
                if ((error = ifpromisc(ifp0, 1)))
-                       goto rm_lh;
+                       return (error);
 
-       } else if (carp_check_dup_vhids(sc, cif, NULL)) {
-               error = EINVAL;
-               goto rm_lh;
-       }
+       } else if (carp_check_dup_vhids(sc, cif, NULL))
+               return (EINVAL);
 
        /* detach from old interface */
        if (sc->sc_carpdev != NULL)
@@ -1708,6 +1702,8 @@ carp_set_ifp(struct carp_softc *sc, stru
 
        /* attach carp interface to physical interface */
        if_detachhook_add(ifp0, &sc->sc_dtask);
+       if_linkstatehook_add(ifp0, &sc->sc_ltask);
+
        sc->sc_carpdev = ifp0;
        sc->sc_if.if_capabilities = ifp0->if_capabilities &
            IFCAP_CSUM_MASK;
@@ -1745,14 +1741,9 @@ carp_set_ifp(struct carp_softc *sc, stru
        /* Change input handler of the physical interface. */
        if_ih_insert(ifp0, carp_input, NULL);
 
-       carp_carpdev_state(ifp0);
+       carp_carpdev_state(sc);
 
        return (0);
-
-rm_lh:
-       hook_disestablish(ifp0->if_linkstatehooks, sc->lh_cookie);
-
-       return (error);
 }
 
 void
@@ -2465,35 +2456,24 @@ carp_group_demote_count(struct carp_soft
 void
 carp_carpdev_state(void *v)
 {
-       struct srpl *cif;
-       struct carp_softc *sc;
-       struct ifnet *ifp0 = v;
-
-       if (ifp0->if_type != IFT_ETHER)
-               return;
-
-       cif = &ifp0->if_carp;
-
-       KERNEL_ASSERT_LOCKED(); /* touching if_carp */
-
-       SRPL_FOREACH_LOCKED(sc, cif, sc_list) {
-               int suppressed = sc->sc_suppress;
+       struct carp_softc *sc = v;
+       struct ifnet *ifp0 = sc->sc_carpdev;
+       int suppressed = sc->sc_suppress;
 
-               if (sc->sc_carpdev->if_link_state == LINK_STATE_DOWN ||
-                   !(sc->sc_carpdev->if_flags & IFF_UP)) {
-                       sc->sc_if.if_flags &= ~IFF_RUNNING;
-                       carp_del_all_timeouts(sc);
-                       carp_set_state_all(sc, INIT);
-                       sc->sc_suppress = 1;
-                       carp_setrun_all(sc, 0);
-                       if (!suppressed)
-                               carp_group_demote_adj(&sc->sc_if, 1, "carpdev");
-               } else if (suppressed) {
-                       carp_set_state_all(sc, INIT);
-                       sc->sc_suppress = 0;
-                       carp_setrun_all(sc, 0);
-                       carp_group_demote_adj(&sc->sc_if, -1, "carpdev");
-               }
+       if (ifp0->if_link_state == LINK_STATE_DOWN ||
+           !(ifp0->if_flags & IFF_UP)) {
+               sc->sc_if.if_flags &= ~IFF_RUNNING;
+               carp_del_all_timeouts(sc);
+               carp_set_state_all(sc, INIT);
+               sc->sc_suppress = 1;
+               carp_setrun_all(sc, 0);
+               if (!suppressed)
+                       carp_group_demote_adj(&sc->sc_if, 1, "carpdev");
+       } else if (suppressed) {
+               carp_set_state_all(sc, INIT);
+               sc->sc_suppress = 0;
+               carp_setrun_all(sc, 0);
+               carp_group_demote_adj(&sc->sc_if, -1, "carpdev");
        }
 }
 

Reply via email to