diff options
-rw-r--r-- | sys/net/pf.c | 18 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 18 | ||||
-rw-r--r-- | sys/net/pfvar.h | 3 |
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 *, |