summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 *,