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");
}
}