summaryrefslogtreecommitdiffstats
path: root/sys/net/pf_if.c
diff options
context:
space:
mode:
authorpascoe <pascoe@openbsd.org>2005-09-28 01:46:32 +0000
committerpascoe <pascoe@openbsd.org>2005-09-28 01:46:32 +0000
commit208fe50506f6988183baa7e86d5eca6dc6916b50 (patch)
tree1cc486a197aeb89d63c87b32b33864f6c815d4e9 /sys/net/pf_if.c
parentmake -s print information about kmapent as well, reminded by deraadt@ (diff)
downloadwireguard-openbsd-208fe50506f6988183baa7e86d5eca6dc6916b50.tar.xz
wireguard-openbsd-208fe50506f6988183baa7e86d5eca6dc6916b50.zip
Improve the safety of pf IOCTLs, taking into account that some paths can sleep.
- Introduces a rw_lock in pfioctl so that we can have concurrent readers but only one process performing updates at a time; - Separates state expiry into "unlink" and "free" parts; anyone can unlink a state/src node from the RB trees at any time, but a state can only be freed whilst the write lock is held; - Converts state_updates into list state_list containing all states, regardless of whether they are "linked" or "unlinked"; - Introduces a new PFTM_UNLINKED state that is used on the "unlinked" states to signal that they can be freed; - Converts pf_purge_expired_state to an "unlink" state routine, which only unlinks the state from the RB trees. Freeing the state/src nodes is left to the purge thread, which runs whilst holding a write lock, such that all "next" references remain valid; - Converts pfsync_bulk_update and DIOCGETSTATES to walk state_list rather than the RB trees; - Converts the purge thread to use the new state_list and perform a partial purge every second, with the target rate a full state table walk every PFTM_INTERVAL seconds. seen by mcbride, henning, dhartmei pre-3.8, but too intrusive for then
Diffstat (limited to 'sys/net/pf_if.c')
-rw-r--r--sys/net/pf_if.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/sys/net/pf_if.c b/sys/net/pf_if.c
index 549182217a5..25f83e6df1b 100644
--- a/sys/net/pf_if.c
+++ b/sys/net/pf_if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_if.c,v 1.43 2005/08/18 10:28:14 pascoe Exp $ */
+/* $OpenBSD: pf_if.c,v 1.44 2005/09/28 01:46:32 pascoe Exp $ */
/*
* Copyright 2005 Henning Brauer <henning@openbsd.org>
@@ -653,20 +653,25 @@ pfi_clr_istats(const char *name)
int
pfi_get_ifaces(const char *name, struct pfi_kif *buf, int *size)
{
- struct pfi_kif *p;
+ struct pfi_kif *p, *nextp;
int s, n = 0;
s = splsoftnet();
- RB_FOREACH(p, pfi_ifhead, &pfi_ifs) {
+ for (p = RB_MIN(pfi_ifhead, &pfi_ifs); p; p = nextp) {
+ nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p);
if (pfi_skip_if(name, p))
continue;
if (*size > n++) {
if (!p->pfik_tzero)
p->pfik_tzero = time_second;
+ pfi_kif_ref(p, PFI_KIF_REF_RULE);
if (copyout(p, buf++, sizeof(*buf))) {
+ pfi_kif_unref(p, PFI_KIF_REF_RULE);
splx(s);
return (EFAULT);
}
+ nextp = RB_NEXT(pfi_ifhead, &pfi_ifs, p);
+ pfi_kif_unref(p, PFI_KIF_REF_RULE);
}
}
splx(s);