diff options
| author | 2005-09-28 01:46:32 +0000 | |
|---|---|---|
| committer | 2005-09-28 01:46:32 +0000 | |
| commit | 208fe50506f6988183baa7e86d5eca6dc6916b50 (patch) | |
| tree | 1cc486a197aeb89d63c87b32b33864f6c815d4e9 /sys/net/pf_if.c | |
| parent | make -s print information about kmapent as well, reminded by deraadt@ (diff) | |
| download | wireguard-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.c | 11 |
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); |
