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 /sys/net/if_bridge.c | |
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@
Diffstat (limited to 'sys/net/if_bridge.c')
-rw-r--r-- | sys/net/if_bridge.c | 14 |
1 files changed, 7 insertions, 7 deletions
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(); |