summaryrefslogtreecommitdiff
path: root/sys/net/if_vlan.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2019-11-06 03:51:27 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2019-11-06 03:51:27 +0000
commit37183277edd5b48bb15c17a71ef7e126f8bbe9a6 (patch)
treebf26c22343f9120a4cb97280389dbe66513dc176 /sys/net/if_vlan.c
parenta6c76ac42cc0d920d495823ca251191871c97868 (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@
Diffstat (limited to 'sys/net/if_vlan.c')
-rw-r--r--sys/net/if_vlan.c10
1 files changed, 5 insertions, 5 deletions
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);