-/* $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
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;
*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);
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);
#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)
-/* $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
}
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);
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
-/* $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
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 *,