summaryrefslogtreecommitdiffstats
path: root/sys/net/if.c
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2019-11-08 07:16:29 +0000
committerdlg <dlg@openbsd.org>2019-11-08 07:16:29 +0000
commitf22742ab73d4232c93319a7e0ff237cb69eb42d9 (patch)
treefe4bd549fa0e5a12e1089b62614867c278f2d218 /sys/net/if.c
parentduplicate 'x' character in getopt(3) optstring (diff)
downloadwireguard-openbsd-f22742ab73d4232c93319a7e0ff237cb69eb42d9.tar.xz
wireguard-openbsd-f22742ab73d4232c93319a7e0ff237cb69eb42d9.zip
convert interface address change hooks to tasks and a task_list.
this follows what's been done for detach and link state hooks, and makes handling of hooks generally more robust. address hooks are a bit different to detach/link state hooks in that there's only a few things that register hooks (carp, pf, vxlan), but a lot of places to run the hooks (lots of ipv4 and ipv6 address configuration). an address hook cookie was in struct pfi_kif, which is part of the pf abi. rather than break pfctl -sI, this maintains the void * used for the cookie and uses it to store a task, which is then used as intended with the new api.
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c47
1 files changed, 33 insertions, 14 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 9c029556acb..c251abd7283 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.591 2019/11/07 08:03:18 dlg Exp $ */
+/* $OpenBSD: if.c,v 1.592 2019/11/08 07:16:29 dlg Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -630,9 +630,7 @@ if_attach_common(struct ifnet *ifp)
ifp->if_iqs = ifp->if_rcv.ifiq_ifiqs;
ifp->if_niqs = 1;
- ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks),
- M_TEMP, M_WAITOK);
- TAILQ_INIT(ifp->if_addrhooks);
+ TAILQ_INIT(&ifp->if_addrhooks);
TAILQ_INIT(&ifp->if_linkstatehooks);
TAILQ_INIT(&ifp->if_detachhooks);
@@ -1046,19 +1044,18 @@ if_netisr(void *unused)
void
if_hooks_run(struct task_list *hooks)
{
- struct task *t, *nt, cursor;
+ struct task *t, *nt;
+ struct task cursor = { .t_func = NULL };
void (*func)(void *);
void *arg;
- /*
- * holding the NET_LOCK guarantees that concurrent if_hooks_run
- * calls can't happen, and they therefore can't try and call
- * each others cursors as actual hooks.
- */
- NET_ASSERT_LOCKED();
-
mtx_enter(&if_hooks_mtx);
for (t = TAILQ_FIRST(hooks); t != NULL; t = nt) {
+ while (t->t_func == NULL) { /* skip cursors */
+ t = TAILQ_NEXT(t, t_entry);
+ if (t == NULL)
+ break;
+ }
func = t->t_func;
arg = t->t_arg;
@@ -1177,7 +1174,7 @@ if_detach(struct ifnet *ifp)
}
}
- free(ifp->if_addrhooks, M_TEMP, sizeof(*ifp->if_addrhooks));
+ KASSERT(TAILQ_EMPTY(&ifp->if_addrhooks));
KASSERT(TAILQ_EMPTY(&ifp->if_linkstatehooks));
KASSERT(TAILQ_EMPTY(&ifp->if_detachhooks));
@@ -3100,7 +3097,7 @@ ifnewlladdr(struct ifnet *ifp)
ifa = &in6ifa_ifpforlinklocal(ifp, 0)->ia_ifa;
if (ifa) {
in6_purgeaddr(ifa);
- dohooks(ifp->if_addrhooks, 0);
+ if_hooks_run(&ifp->if_addrhooks);
in6_ifattach(ifp);
}
}
@@ -3114,6 +3111,28 @@ ifnewlladdr(struct ifnet *ifp)
splx(s);
}
+void
+if_addrhook_add(struct ifnet *ifp, struct task *t)
+{
+ mtx_enter(&if_hooks_mtx);
+ TAILQ_INSERT_TAIL(&ifp->if_addrhooks, t, t_entry);
+ mtx_leave(&if_hooks_mtx);
+}
+
+void
+if_addrhook_del(struct ifnet *ifp, struct task *t)
+{
+ mtx_enter(&if_hooks_mtx);
+ TAILQ_REMOVE(&ifp->if_addrhooks, t, t_entry);
+ mtx_leave(&if_hooks_mtx);
+}
+
+void
+if_addrhooks_run(struct ifnet *ifp)
+{
+ if_hooks_run(&ifp->if_addrhooks);
+}
+
int net_ticks;
u_int net_livelocks;