diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2011-08-30 00:40:48 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2011-08-30 00:40:48 +0000 |
commit | c6f0fd71946668a4b83671d6b2022ca8b32c2228 (patch) | |
tree | ef688bd48658b282d296173ac0000e0bae132d80 /sys/net | |
parent | bdbf27829b9a3d91a783816ef1652030405644c9 (diff) |
Add support for one shot rules that remove themselves from an active
ruleset after match. In case this is the only rule in the anchor,
the anchor will be destroyed automatically after the rule is matched.
This is an extremely handy technique for firewall proxies.
ok henning, mcbride
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/pf.c | 5 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 20 | ||||
-rw-r--r-- | sys/net/pfvar.h | 5 |
3 files changed, 27 insertions, 3 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c index 22013eb2aa1..35d8b3e3392 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.770 2011/08/03 12:28:40 mpf Exp $ */ +/* $OpenBSD: pf.c,v 1.771 2011/08/30 00:40:47 mikeb Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -3105,6 +3105,9 @@ pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, } #endif + if (r->rule_flag & PFRULE_ONCE) + pf_purge_rule(ruleset, r); + return (PF_PASS); cleanup: diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c index 730beaa6306..7e652ab561a 100644 --- a/sys/net/pf_ioctl.c +++ b/sys/net/pf_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_ioctl.c,v 1.241 2011/07/08 18:50:51 henning Exp $ */ +/* $OpenBSD: pf_ioctl.c,v 1.242 2011/08/30 00:40:47 mikeb Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -317,6 +317,24 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule) pool_put(&pf_rule_pl, rule); } +void +pf_purge_rule(struct pf_ruleset *ruleset, struct pf_rule *rule) +{ + u_int32_t nr; + + pf_rm_rule(ruleset->rules.active.ptr, rule); + ruleset->rules.active.rcount--; + + nr = 0; + TAILQ_FOREACH(rule, ruleset->rules.active.ptr, entries) + rule->nr = nr++; + + ruleset->rules.active.ticket++; + + pf_calc_skip_steps(ruleset->rules.active.ptr); + pf_remove_if_empty_ruleset(ruleset); +} + u_int16_t tagname2tag(struct pf_tags *head, char *tagname) { diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index eb0a887b96d..7959582e4b3 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.343 2011/08/03 00:01:30 dlg Exp $ */ +/* $OpenBSD: pfvar.h,v 1.344 2011/08/30 00:40:47 mikeb Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -673,6 +673,7 @@ struct pf_rule { #define PFRULE_IFBOUND 0x00010000 /* if-bound */ #define PFRULE_STATESLOPPY 0x00020000 /* sloppy state tracking */ #define PFRULE_PFLOW 0x00040000 +#define PFRULE_ONCE 0x00100000 /* one shot rule */ #define PFSTATE_HIWAT 10000 /* default state table size */ #define PFSTATE_ADAPT_START 6000 /* default adaptive timeout start */ @@ -1768,6 +1769,8 @@ extern void pf_addrcpy(struct pf_addr *, struct pf_addr *, u_int8_t); void pf_rm_rule(struct pf_rulequeue *, struct pf_rule *); +void pf_purge_rule(struct pf_ruleset *, + struct pf_rule *); struct pf_divert *pf_find_divert(struct mbuf *); int pf_setup_pdesc(sa_family_t, int, struct pf_pdesc *, struct mbuf **, |