summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikeb <mikeb@openbsd.org>2014-08-12 15:29:33 +0000
committermikeb <mikeb@openbsd.org>2014-08-12 15:29:33 +0000
commit7b8072cec770783f0772643a99481ce3d117023e (patch)
tree0ce7188281b80e6247024695e58b2ae600754a09
parentReplace intrinsic ROTATE macros with an inline. (diff)
downloadwireguard-openbsd-7b8072cec770783f0772643a99481ce3d117023e.tar.xz
wireguard-openbsd-7b8072cec770783f0772643a99481ce3d117023e.zip
Finally implement what's stated in the man page regarding parent
anchors for "once" rules: "In case this is the only rule in the anchor, the anchor will be destroyed automatically after the rule is matched." Employ an additional pointer pair to keep track of the parent ruleset containing the anchor that we want to remove. OK henning
-rw-r--r--sys/net/pf.c18
-rw-r--r--sys/net/pf_ioctl.c18
-rw-r--r--sys/net/pfvar.h3
3 files changed, 28 insertions, 11 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index b5fdc93ef4c..2546586ae13 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.885 2014/08/12 14:42:06 mikeb Exp $ */
+/* $OpenBSD: pf.c,v 1.886 2014/08/12 15:29:33 mikeb Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -3102,6 +3102,8 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm,
struct pf_rule *r;
struct pf_rule *nr = NULL;
struct pf_rule *a = NULL;
+ struct pf_ruleset *arsm = NULL;
+ struct pf_ruleset *aruleset = NULL;
struct pf_ruleset *ruleset = NULL;
struct pf_rule_slist rules;
struct pf_rule_item *ri;
@@ -3297,6 +3299,7 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm,
*rm = r;
*am = a;
*rsm = ruleset;
+ arsm = aruleset;
if (act.log & PF_LOG_MATCHES) {
REASON_SET(&reason, PFRES_MATCH);
PFLOG_PACKET(pd, reason, r, a, ruleset);
@@ -3306,17 +3309,20 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm,
if (r->quick)
break;
r = TAILQ_NEXT(r, entries);
- } else
+ } else {
+ aruleset = ruleset;
pf_step_into_anchor(&asd, &ruleset, &r, &a);
+ }
nextrule:
if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset,
&r, &a, &match))
break;
}
- r = *rm;
- a = *am;
- ruleset = *rsm;
+ r = *rm; /* matching rule */
+ a = *am; /* rule that defines an anchor containing 'r' */
+ ruleset = *rsm; /* ruleset of the anchor defined by the rule 'a' */
+ aruleset = arsm;/* ruleset of the 'a' rule itself */
/* apply actions for last matching pass/block rule */
pf_rule_to_actions(r, &act);
@@ -3449,7 +3455,7 @@ pf_test_rule(struct pf_pdesc *pd, struct pf_rule **rm, struct pf_state **sm,
#endif
if (r->rule_flag & PFRULE_ONCE)
- pf_purge_rule(ruleset, r);
+ pf_purge_rule(ruleset, r, aruleset, a);
#if INET && INET6
if (rewrite && skw->af != sks->af)
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index a4dba038b8d..eaf17584c6d 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.275 2014/08/12 14:38:28 mikeb Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.276 2014/08/12 15:29:33 mikeb Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -307,9 +307,10 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
}
void
-pf_purge_rule(struct pf_ruleset *ruleset, struct pf_rule *rule)
+pf_purge_rule(struct pf_ruleset *ruleset, struct pf_rule *rule,
+ struct pf_ruleset *aruleset, struct pf_rule *arule)
{
- u_int32_t nr = 0;
+ u_int32_t nr = 0;
KASSERT(ruleset != NULL && rule != NULL);
@@ -319,7 +320,16 @@ pf_purge_rule(struct pf_ruleset *ruleset, struct pf_rule *rule)
rule->nr = nr++;
ruleset->rules.active.ticket++;
pf_calc_skip_steps(ruleset->rules.active.ptr);
- pf_remove_if_empty_ruleset(ruleset);
+
+ /* remove the parent anchor rule */
+ if (nr == 0 && arule && aruleset) {
+ pf_rm_rule(aruleset->rules.active.ptr, arule);
+ aruleset->rules.active.rcount--;
+ TAILQ_FOREACH(rule, aruleset->rules.active.ptr, entries)
+ rule->nr = nr++;
+ aruleset->rules.active.ticket++;
+ pf_calc_skip_steps(aruleset->rules.active.ptr);
+ }
}
u_int16_t
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 20f39bbe699..222c885a529 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.401 2014/07/02 13:02:08 mikeb Exp $ */
+/* $OpenBSD: pfvar.h,v 1.402 2014/08/12 15:29:33 mikeb Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1786,6 +1786,7 @@ extern void pf_addrcpy(struct pf_addr *, struct pf_addr *,
void pf_rm_rule(struct pf_rulequeue *,
struct pf_rule *);
void pf_purge_rule(struct pf_ruleset *,
+ struct pf_rule *, struct pf_ruleset *,
struct pf_rule *);
struct pf_divert *pf_find_divert(struct mbuf *);
int pf_setup_pdesc(struct pf_pdesc *, void *,