summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorRyan Thomas McBride <mcbride@cvs.openbsd.org>2002-12-17 12:30:14 +0000
committerRyan Thomas McBride <mcbride@cvs.openbsd.org>2002-12-17 12:30:14 +0000
commit12659caaaa187bfb87d1b80b80544d0efe9d32d9 (patch)
tree98046872610eb696ff8cb314d21fba0db75a3a74 /sys/net
parent97c718358eb70e8053558830745f3801e2591c94 (diff)
Merge pf_nat/pf_binat/pf_rdr structs into pf_rule. Simplifies code, allows
skip steps on translation rules. Also: - Require a ticket for DIOCCHANGERULE operations to prevent races. - Remove pf_compare_* functions from pf_ioctl.c. DIOCCHANGE* operations use a rule number, and comparisons happen in userland. Testing and fixes from dhartmei@ and frantzen@ ok dhartmei@ henning@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/pf.c658
-rw-r--r--sys/net/pf_ioctl.c1419
-rw-r--r--sys/net/pf_norm.c6
-rw-r--r--sys/net/pfvar.h211
4 files changed, 427 insertions, 1867 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 210f7109704..bff784864e5 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.270 2002/12/13 21:48:30 henning Exp $ */
+/* $OpenBSD: pf.c,v 1.271 2002/12/17 12:30:13 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -139,9 +139,8 @@ int *pftm_timeouts[PFTM_MAX] = { &pftm_tcp_first_packet,
&pftm_interval };
-struct pool pf_tree_pl, pf_rule_pl, pf_nat_pl, pf_sport_pl;
-struct pool pf_rdr_pl, pf_state_pl, pf_binat_pl, pf_addr_pl;
-struct pool pf_altq_pl, pf_pooladdr_pl;
+struct pool pf_tree_pl, pf_rule_pl, pf_addr_pl;
+struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
void pf_addrcpy(struct pf_addr *, struct pf_addr *,
sa_family_t);
@@ -151,7 +150,6 @@ struct pf_state *pf_find_state(struct pf_state_tree *,
void pf_purge_expired_states(void);
void pf_purge_timeout(void *);
void pf_dynaddr_update(void *);
-
void pf_print_host(struct pf_addr *, u_int16_t, u_int8_t);
void pf_print_state(struct pf_state *);
void pf_print_flags(u_int8_t);
@@ -176,17 +174,13 @@ void pf_send_reset(int, struct tcphdr *,
struct pf_rule *);
void pf_send_icmp(struct mbuf *, u_int8_t, u_int8_t,
sa_family_t, struct pf_rule *);
-u_int16_t pf_map_port_range(struct pf_rdr *, u_int16_t);
-struct pf_nat *pf_get_nat(struct ifnet *, u_int8_t,
+struct pf_rule *pf_match_translation(int, struct ifnet *, u_int8_t,
+ struct pf_addr *, u_int16_t, struct pf_addr *,
+ u_int16_t, sa_family_t, int);
+struct pf_rule *pf_get_translation(int, struct ifnet *, u_int8_t,
struct pf_addr *, u_int16_t,
struct pf_addr *, u_int16_t,
struct pf_addr *, u_int16_t *, sa_family_t);
-struct pf_binat *pf_get_binat(int, struct ifnet *, u_int8_t,
- struct pf_addr *, struct pf_addr *,
- struct pf_addr *, sa_family_t);
-struct pf_rdr *pf_get_rdr(struct ifnet *, u_int8_t,
- struct pf_addr *, struct pf_addr *, u_int16_t,
- struct pf_addr *, sa_family_t);
int pf_test_tcp(struct pf_rule **, int, struct ifnet *,
struct mbuf *, int, int, void *, struct pf_pdesc *);
int pf_test_udp(struct pf_rule **, int, struct ifnet *,
@@ -769,33 +763,16 @@ void
pf_update_anchor_rules()
{
struct pf_rule *rule;
- struct pf_nat *nat;
- struct pf_rdr *rdr;
- struct pf_binat *binat;
+ int i;
- TAILQ_FOREACH(rule, pf_main_ruleset.rules.active.ptr, entries) {
- if (rule->anchorname[0])
- rule->anchor = pf_find_anchor(rule->anchorname);
- else
- rule->anchor = NULL;
- }
- TAILQ_FOREACH(nat, pf_main_ruleset.nats.active.ptr, entries) {
- if (nat->anchorname[0])
- nat->anchor = pf_find_anchor(nat->anchorname);
- else
- nat->anchor = NULL;
- }
- TAILQ_FOREACH(rdr, pf_main_ruleset.rdrs.active.ptr, entries) {
- if (rdr->anchorname[0])
- rdr->anchor = pf_find_anchor(rdr->anchorname);
- else
- rdr->anchor = NULL;
- }
- TAILQ_FOREACH(binat, pf_main_ruleset.binats.active.ptr, entries) {
- if (binat->anchorname[0])
- binat->anchor = pf_find_anchor(binat->anchorname);
- else
- binat->anchor = NULL;
+ for (i = 0; i < 4; i++) {
+ TAILQ_FOREACH(rule,
+ pf_main_ruleset.rules[i].active.ptr, entries) {
+ if (rule->anchorname[0])
+ rule->anchor = pf_find_anchor(rule->anchorname);
+ else
+ rule->anchor = NULL;
+ }
}
}
@@ -1213,6 +1190,8 @@ pf_match(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p)
return ((p > a1) && (p < a2));
case PF_OP_XRG:
return ((p < a1) || (p > a2));
+ case PF_OP_RRG:
+ return ((p >= a1) && (p <= a2));
case PF_OP_EQ:
return (p == a1);
case PF_OP_NE:
@@ -1262,8 +1241,8 @@ pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
(a) = (r); \
(s) = TAILQ_FIRST(&(r)->anchor->rulesets); \
(r) = NULL; \
- while ((s) != NULL && \
- ((r) = TAILQ_FIRST((s)->n.active.ptr)) == NULL) \
+ while ((s) != NULL && ((r) = \
+ TAILQ_FIRST((s)->rules[n].active.ptr)) == NULL) \
(s) = TAILQ_NEXT((s), entries); \
if ((r) == NULL) { \
(r) = TAILQ_NEXT((a), entries); \
@@ -1276,8 +1255,8 @@ pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g)
if ((r) != NULL || (a) == NULL || (s) == NULL) \
panic("PF_STEP_OUT_OF_ANCHOR"); \
(s) = TAILQ_NEXT((s), entries); \
- while ((s) != NULL && \
- ((r) = TAILQ_FIRST((s)->n.active.ptr)) == NULL) \
+ while ((s) != NULL && ((r) = \
+ TAILQ_FIRST((s)->rules[n].active.ptr)) == NULL) \
(s) = TAILQ_NEXT((s), entries); \
if ((r) == NULL) { \
(r) = TAILQ_NEXT((a), entries); \
@@ -1405,10 +1384,11 @@ pf_map_addr(u_int8_t af, struct pf_pool *rpool, struct pf_addr *saddr,
{
unsigned char hash[16];
struct pf_pooladdr *cur = rpool->cur;
- struct pf_addr *raddr = &rpool->cur->addr.addr;
- struct pf_addr *rmask = &rpool->cur->addr.mask;
+ struct pf_addr *raddr = &rpool->cur->addr.addr.addr;
+ struct pf_addr *rmask = &rpool->cur->addr.addr.mask;
- if (cur->addr.addr_dyn != NULL && cur->addr.addr_dyn->undefined)
+ if (cur->addr.addr.addr_dyn != NULL &&
+ cur->addr.addr.addr_dyn->undefined)
return (1);
@@ -1459,7 +1439,7 @@ pf_map_addr(u_int8_t af, struct pf_pool *rpool, struct pf_addr *saddr,
PF_POOLMASK(naddr, raddr, rmask, (struct pf_addr *)&hash, af);
break;
case PF_POOL_ROUNDROBIN:
- if (pf_match_addr(0, &cur->addr.addr, &cur->addr.mask,
+ if (pf_match_addr(0, &cur->addr.addr.addr, &cur->addr.addr.mask,
&rpool->counter, af)) {
PF_ACPY(naddr, &rpool->counter, af);
PF_AINC(&rpool->counter, af);
@@ -1467,8 +1447,8 @@ pf_map_addr(u_int8_t af, struct pf_pool *rpool, struct pf_addr *saddr,
if ((rpool->cur =
TAILQ_NEXT(rpool->cur, entries)) == NULL)
rpool->cur = TAILQ_FIRST(&rpool->list);
- PF_ACPY(naddr, &cur->addr.addr, af);
- PF_ACPY(&rpool->counter, &cur->addr.addr, af);
+ PF_ACPY(naddr, &cur->addr.addr.addr, af);
+ PF_ACPY(&rpool->counter, &cur->addr.addr.addr, af);
PF_AINC(&rpool->counter, af);
}
break;
@@ -1578,187 +1558,148 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_pool *rpool,
return (1); /* none available */
}
-struct pf_nat *
-pf_get_nat(struct ifnet *ifp, u_int8_t proto, struct pf_addr *saddr,
- u_int16_t sport, struct pf_addr *daddr, u_int16_t dport,
- struct pf_addr *naddr, u_int16_t *nport, sa_family_t af)
+struct pf_rule *
+pf_match_translation(int direction, struct ifnet *ifp, u_int8_t proto,
+ struct pf_addr *saddr, u_int16_t sport, struct pf_addr *daddr,
+ u_int16_t dport, sa_family_t af, int rs_num)
{
- struct pf_nat *n, *nm = NULL, *anchorrule = NULL;
+ struct pf_rule *r, *rm = NULL, *anchorrule = NULL;
struct pf_ruleset *ruleset = NULL;
- n = TAILQ_FIRST(pf_main_ruleset.nats.active.ptr);
- while (n && nm == NULL) {
- if (((n->ifp == NULL) || (n->ifp == ifp && !n->ifnot) ||
- (n->ifp != ifp && n->ifnot)) &&
- (!n->proto || n->proto == proto) &&
- (!n->af || n->af == af) &&
- (n->src.addr.addr_dyn == NULL ||
- !n->src.addr.addr_dyn->undefined) &&
- PF_MATCHA(n->src.not, &n->src.addr.addr, &n->src.addr.mask,
- saddr, af) &&
- (!n->src.port_op ||
- (proto != IPPROTO_TCP && proto != IPPROTO_UDP) ||
- pf_match_port(n->src.port_op, n->src.port[0],
- n->src.port[1], sport)) &&
- (n->dst.addr.addr_dyn == NULL ||
- !n->dst.addr.addr_dyn->undefined) &&
- PF_MATCHA(n->dst.not, &n->dst.addr.addr, &n->dst.addr.mask,
- daddr, af) &&
- (!n->dst.port_op ||
- (proto != IPPROTO_TCP && proto != IPPROTO_UDP) ||
- pf_match_port(n->dst.port_op, n->dst.port[0],
- n->dst.port[1], dport)) &&
- (!n->anchorname[0] || n->anchor != NULL)) {
- if (n->anchor == NULL)
- nm = n;
- else
- PF_STEP_INTO_ANCHOR(n, anchorrule, ruleset,
- nats);
- } else
- n = TAILQ_NEXT(n, entries);
- if (n == NULL && anchorrule != NULL)
- PF_STEP_OUT_OF_ANCHOR(n, anchorrule, ruleset, nats);
- }
- if (nm) {
- if (nm->no)
- return (NULL);
- else {
- if (pf_get_sport(af, proto,
- &nm->rpool, saddr, sport, daddr,
- dport, naddr, nport, nm->proxy_port[0],
- nm->proxy_port[1])) {
- DPFPRINTF(PF_DEBUG_MISC,
- ("pf: NAT proxy port allocation "
- "(%u-%u) failed\n",
- nm->proxy_port[0],
- nm->proxy_port[1]));
- }
- }
- }
+ r = TAILQ_FIRST(pf_main_ruleset.rules[rs_num].active.ptr);
+ while (r && rm == NULL) {
+ struct pf_rule_addr *src = NULL;
- return (nm);
+ if (r->action == PF_BINAT && direction == PF_IN)
+ src = &r->rpool.cur->addr;
+ else
+ src = &r->src;
+
+ r->evaluations++;
+ if (r->action == PF_SCRUB)
+ r = r->skip[PF_SKIP_ACTION];
+ else if (r->ifp != NULL && ((r->ifp != ifp && !r->ifnot) ||
+ (r->ifp == ifp && r->ifnot)))
+ r = r->skip[PF_SKIP_IFP];
+ else if (r->direction && r->direction != direction)
+ r = r->skip[PF_SKIP_DIR];
+ else if (r->af && r->af != af)
+ r = r->skip[PF_SKIP_AF];
+ else if (r->proto && r->proto != IPPROTO_TCP)
+ r = r->skip[PF_SKIP_PROTO];
+ else if (!PF_AZERO(&src->addr.mask, af) &&
+ !PF_MATCHA(src->not,
+ &src->addr.addr, &src->addr.mask, saddr, af))
+ r = r->skip[PF_SKIP_SRC_ADDR];
+ else if (src->port_op && !pf_match_port(src->port_op,
+ src->port[0], src->port[1], sport))
+ r = r->skip[PF_SKIP_SRC_PORT];
+ else if (!PF_AZERO(&r->dst.addr.mask, af) &&
+ !PF_MATCHA(r->dst.not,
+ &r->dst.addr.addr, &r->dst.addr.mask, daddr, af))
+ r = r->skip[PF_SKIP_DST_ADDR];
+ else if (r->dst.port_op && !pf_match_port(r->dst.port_op,
+ r->dst.port[0], r->dst.port[1], dport))
+ r = r->skip[PF_SKIP_DST_PORT];
+ else if (r->anchorname[0] && r->anchor == NULL)
+ r = TAILQ_NEXT(r, entries);
+ else if (r->anchor == NULL)
+ rm = r;
+ else
+ PF_STEP_INTO_ANCHOR(r, anchorrule, ruleset, rs_num);
+ if (r == NULL && anchorrule != NULL)
+ PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset,
+ rs_num);
+ }
+ return (rm);
}
-struct pf_binat *
-pf_get_binat(int direction, struct ifnet *ifp, u_int8_t proto,
- struct pf_addr *saddr, struct pf_addr *daddr, struct pf_addr *naddr,
- sa_family_t af)
+struct pf_rule *
+pf_get_translation(int direction, struct ifnet *ifp, u_int8_t proto,
+ struct pf_addr *saddr, u_int16_t sport,
+ struct pf_addr *daddr, u_int16_t dport,
+ struct pf_addr *naddr, u_int16_t *nport, sa_family_t af)
{
- struct pf_binat *b, *bm = NULL, *anchorrule = NULL;
- struct pf_ruleset *ruleset = NULL;
-
- b = TAILQ_FIRST(pf_main_ruleset.binats.active.ptr);
- while (b && bm == NULL) {
- struct pf_addr_wrap *src;
+ struct pf_rule *r = NULL;
- if (direction == PF_OUT)
- src = &b->saddr;
- else
- src = &b->raddr;
-
- if (b->ifp == ifp &&
- (!b->proto || b->proto == proto) &&
- (!b->af || b->af == af) &&
- (src->addr_dyn == NULL ||
- !src->addr_dyn->undefined) &&
- PF_MATCHA(0, &src->addr, &src->mask, saddr, af) &&
- (b->daddr.addr_dyn == NULL ||
- !b->daddr.addr_dyn->undefined) &&
- PF_MATCHA(b->dnot, &b->daddr.addr, &b->daddr.mask,
- daddr, af) &&
- (!b->anchorname[0] || b->anchor != NULL)) {
- if (b->anchor == NULL)
- bm = b;
- else
- PF_STEP_INTO_ANCHOR(b, anchorrule, ruleset,
- binats);
- } else
- b = TAILQ_NEXT(b, entries);
- if (b == NULL && anchorrule != NULL)
- PF_STEP_OUT_OF_ANCHOR(b, anchorrule, ruleset, binats);
+ if (direction == PF_OUT) {
+ r = pf_match_translation(direction, ifp, proto,
+ saddr, sport, daddr, dport, af, PF_RULESET_BINAT);
+ if (r == NULL)
+ r = pf_match_translation(direction, ifp, proto,
+ saddr, sport, daddr, dport, af, PF_RULESET_NAT);
+ } else {
+ r = pf_match_translation(direction, ifp, proto,
+ saddr, sport, daddr, dport, af, PF_RULESET_RDR);
+ if (r == NULL)
+ r = pf_match_translation(direction, ifp, proto,
+ saddr, sport, daddr, dport, af, PF_RULESET_BINAT);
}
- if (bm) {
- if (bm->no)
+ if (r != NULL) {
+ switch (r->action) {
+ case PF_NONAT:
+ case PF_NOBINAT:
+ case PF_NORDR:
return (NULL);
- switch (direction) {
- case PF_OUT:
- if (bm->raddr.addr_dyn != NULL &&
- bm->raddr.addr_dyn->undefined)
- return (NULL);
- else
- PF_POOLMASK(naddr, &bm->raddr.addr,
- &bm->raddr.mask, saddr, af);
break;
- case PF_IN:
- if (bm->saddr.addr_dyn != NULL &&
- bm->saddr.addr_dyn->undefined)
+ case PF_NAT:
+ if (pf_get_sport(af, proto,
+ &r->rpool, saddr, sport, daddr,
+ dport, naddr, nport, r->rpool.proxy_port[0],
+ r->rpool.proxy_port[1])) {
+ DPFPRINTF(PF_DEBUG_MISC,
+ ("pf: NAT proxy port allocation "
+ "(%u-%u) failed\n",
+ r->rpool.proxy_port[0],
+ r->rpool.proxy_port[1]));
return (NULL);
- else
- PF_POOLMASK(naddr, &bm->saddr.addr,
- &bm->saddr.mask, saddr, af);
+ }
break;
- }
- }
-
- return (bm);
-}
+ case PF_BINAT:
+ switch (direction) {
+ case PF_OUT:
+ if (r->rpool.cur->addr.addr.addr_dyn != NULL &&
+ r->rpool.cur->addr.addr.addr_dyn->undefined)
+ return (NULL);
+ else
+ PF_POOLMASK(naddr,
+ &r->rpool.cur->addr.addr.addr,
+ &r->rpool.cur->addr.addr.mask,
+ saddr, af);
+ break;
+ case PF_IN:
+ if (r->src.addr.addr_dyn != NULL &&
+ r->src.addr.addr_dyn->undefined)
+ return (NULL);
+ else
+ PF_POOLMASK(naddr, &r->src.addr.addr,
+ &r->src.addr.mask, saddr, af);
+ break;
+ }
+ break;
+ case PF_RDR: {
+ u_int32_t tmp_nport;
-struct pf_rdr *
-pf_get_rdr(struct ifnet *ifp, u_int8_t proto, struct pf_addr *saddr,
- struct pf_addr *daddr, u_int16_t dport, struct pf_addr *naddr,
- sa_family_t af)
-{
- struct pf_rdr *r, *rm = NULL, *anchorrule = NULL;
- struct pf_ruleset *ruleset = NULL;
+ if (pf_map_addr(r->af, &r->rpool,
+ &r->src.addr.addr, naddr, NULL))
+ return (NULL);
- r = TAILQ_FIRST(pf_main_ruleset.rdrs.active.ptr);
- while (r && rm == NULL) {
- if (((r->ifp == NULL) || (r->ifp == ifp && !r->ifnot) ||
- (r->ifp != ifp && r->ifnot)) &&
- (!r->proto || r->proto == proto) &&
- (!r->af || r->af == af) &&
- (r->saddr.addr_dyn == NULL ||
- !r->saddr.addr_dyn->undefined) &&
- PF_MATCHA(r->snot, &r->saddr.addr, &r->saddr.mask,
- saddr, af) &&
- (r->daddr.addr_dyn == NULL ||
- !r->daddr.addr_dyn->undefined) &&
- PF_MATCHA(r->dnot, &r->daddr.addr, &r->daddr.mask,
- daddr, af) &&
- ((!r->dport2 && (!r->dport || dport == r->dport)) ||
- (r->dport2 && (ntohs(dport) >= ntohs(r->dport)) &&
- ntohs(dport) <= ntohs(r->dport2))) &&
- (!r->anchorname[0] || r->anchor != NULL)) {
- if (r->anchor == NULL)
- rm = r;
- else
- PF_STEP_INTO_ANCHOR(r, anchorrule, ruleset,
- rdrs);
- } else
- r = TAILQ_NEXT(r, entries);
- if (r == NULL && anchorrule != NULL)
- PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset, rdrs);
- }
- if (rm) {
- if (rm->no || pf_map_addr(rm->af, &rm->rpool,
- &rm->saddr.addr, naddr, NULL))
+ tmp_nport = ntohs(r->rpool.proxy_port[0])
+ + (ntohs(dport) - ntohs(r->dst.port[0]));
+ /* wrap around if necessary */
+ if (tmp_nport > 65535)
+ tmp_nport -= 65535;
+ *nport = htons((u_int16_t)tmp_nport);
+ break;
+ }
+ default:
return (NULL);
+ break;
+ }
}
- return (rm);
-}
-
-u_int16_t
-pf_map_port_range(struct pf_rdr *rdr, u_int16_t port)
-{
- u_int32_t nport;
-
- nport = ntohs(rdr->rport) - ntohs(rdr->dport) + ntohs(port);
- /* wrap around if necessary */
- if (nport > 65535)
- nport -= 65535;
- return (htons((u_int16_t)nport));
+ return (r);
}
int
@@ -1816,9 +1757,7 @@ int
pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
struct mbuf *m, int ipoff, int off, void *h, struct pf_pdesc *pd)
{
- struct pf_nat *nat = NULL;
- struct pf_binat *binat = NULL;
- struct pf_rdr *rdr = NULL;
+ struct pf_rule *nat = NULL, *rdr = NULL;
struct pf_addr *saddr = pd->src, *daddr = pd->dst, baddr, naddr;
struct tcphdr *th = pd->hdr.tcp;
u_int16_t bport, nport = 0;
@@ -1835,52 +1774,29 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
if (direction == PF_OUT) {
bport = nport = th->th_sport;
- /* check outgoing packet for BINAT */
- if ((binat = pf_get_binat(PF_OUT, ifp, IPPROTO_TCP,
- saddr, daddr, &naddr, af)) != NULL) {
- PF_ACPY(&baddr, saddr, af);
- pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
- &th->th_sum, &naddr, th->th_sport, 0, af);
- rewrite++;
- }
- /* check outgoing packet for NAT */
- else if ((nat = pf_get_nat(ifp, IPPROTO_TCP,
- saddr, th->th_sport, daddr, th->th_dport,
+ /* check outgoing packet for BINAT/NAT */
+ if ((nat = pf_get_translation(PF_OUT, ifp, IPPROTO_TCP,
+ saddr, th->th_sport, daddr, th->th_dport,
&naddr, &nport, af)) != NULL) {
PF_ACPY(&baddr, saddr, af);
pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
- &th->th_sum, &naddr, htons(nport),
- 0, af);
+ &th->th_sum, &naddr, th->th_sport, 0, af);
rewrite++;
}
} else {
- /* check incoming packet for RDR */
- if ((rdr = pf_get_rdr(ifp, IPPROTO_TCP, saddr, daddr,
- th->th_dport, &naddr, af)) != NULL) {
- bport = th->th_dport;
- if (rdr->opts & PF_RPORT_RANGE)
- nport = pf_map_port_range(rdr, th->th_dport);
- else if (rdr->rport)
- nport = rdr->rport;
- else
- nport = bport;
+ bport = nport = th->th_dport;
+ /* check incoming packet for BINAT/RDR */
+ if ((rdr = pf_get_translation(PF_IN, ifp, IPPROTO_TCP,
+ saddr, th->th_sport, daddr, th->th_dport,
+ &naddr, &nport, af)) != NULL) {
PF_ACPY(&baddr, daddr, af);
pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
&th->th_sum, &naddr, nport, 0, af);
rewrite++;
}
- /* check incoming packet for BINAT */
- else if ((binat = pf_get_binat(PF_IN, ifp, IPPROTO_TCP,
- daddr, saddr, &naddr, af)) != NULL) {
- PF_ACPY(&baddr, daddr, af);
- bport = th->th_dport;
- pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
- &th->th_sum, &naddr, th->th_dport, 0, af);
- rewrite++;
- }
}
- r = TAILQ_FIRST(pf_main_ruleset.rules.active.ptr);
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_RULE].active.ptr);
while (r != NULL) {
r->evaluations++;
if (r->action == PF_SCRUB)
@@ -1941,10 +1857,11 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = TAILQ_NEXT(r, entries);
} else
PF_STEP_INTO_ANCHOR(r, anchorrule, ruleset,
- rules);
+ PF_RULESET_RULE);
}
if (r == NULL && anchorrule != NULL)
- PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset, rules);
+ PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset,
+ PF_RULESET_RULE);
}
if (*rm != NULL) {
@@ -1967,13 +1884,11 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
((*rm)->rule_flag & PFRULE_RETURNICMP) ||
((*rm)->rule_flag & PFRULE_RETURN))) {
/* undo NAT/RST changes, if they have taken place */
- if (nat != NULL ||
- (binat != NULL && direction == PF_OUT)) {
+ if (nat != NULL) {
pf_change_ap(saddr, &th->th_sport, pd->ip_sum,
&th->th_sum, &baddr, bport, 0, af);
rewrite++;
- } else if (rdr != NULL ||
- (binat != NULL && direction == PF_IN)) {
+ } else if (rdr != NULL) {
pf_change_ap(daddr, &th->th_dport, pd->ip_sum,
&th->th_sum, &baddr, bport, 0, af);
rewrite++;
@@ -1994,8 +1909,8 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
return (PF_DROP);
}
- if (((*rm != NULL) && (*rm)->keep_state) || nat != NULL ||
- binat != NULL || rdr != NULL) {
+ if (((*rm != NULL) && (*rm)->keep_state) ||
+ nat != NULL || rdr != NULL) {
/* create new state */
u_int16_t len;
struct pf_state *s = NULL;
@@ -2022,7 +1937,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
s->gwy.port = th->th_sport; /* sport */
PF_ACPY(&s->ext.addr, daddr, af);
s->ext.port = th->th_dport;
- if (nat != NULL || binat != NULL) {
+ if (nat != NULL) {
PF_ACPY(&s->lan.addr, &baddr, af);
s->lan.addr = baddr;
s->lan.port = bport;
@@ -2035,7 +1950,7 @@ pf_test_tcp(struct pf_rule **rm, int direction, struct ifnet *ifp,
s->lan.port = th->th_dport;
PF_ACPY(&s->ext.addr, saddr, af);
s->ext.port = th->th_sport;
- if (binat != NULL ||rdr != NULL) {
+ if (rdr != NULL) {
PF_ACPY(&s->gwy.addr, &baddr, af);
s->gwy.port = bport;
} else {
@@ -2089,9 +2004,7 @@ int
pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
struct mbuf *m, int ipoff, int off, void *h, struct pf_pdesc *pd)
{
- struct pf_nat *nat = NULL;
- struct pf_binat *binat = NULL;
- struct pf_rdr *rdr = NULL;
+ struct pf_rule *nat = NULL, *rdr = NULL;
struct pf_addr *saddr = pd->src, *daddr = pd->dst, baddr, naddr;
struct udphdr *uh = pd->hdr.udp;
u_int16_t bport, nport = 0;
@@ -2108,53 +2021,29 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
if (direction == PF_OUT) {
bport = nport = uh->uh_sport;
- /* check outgoing packet for BINAT */
- if ((binat = pf_get_binat(PF_OUT, ifp, IPPROTO_UDP,
- saddr, daddr, &naddr, af)) != NULL) {
- PF_ACPY(&baddr, saddr, af);
- pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum,
- &uh->uh_sum, &naddr, uh->uh_sport, 1, af);
- rewrite++;
- }
- /* check outgoing packet for NAT */
- else if ((nat = pf_get_nat(ifp, IPPROTO_UDP,
- saddr, uh->uh_sport, daddr, uh->uh_dport,
+ /* check outgoing packet for BINAT/NAT */
+ if ((nat = pf_get_translation(PF_OUT, ifp, IPPROTO_UDP,
+ saddr, uh->uh_sport, daddr, uh->uh_dport,
&naddr, &nport, af)) != NULL) {
PF_ACPY(&baddr, saddr, af);
pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum,
- &uh->uh_sum, &naddr, htons(nport),
- 1, af);
+ &uh->uh_sum, &naddr, uh->uh_sport, 1, af);
rewrite++;
}
} else {
- /* check incoming packet for RDR */
- if ((rdr = pf_get_rdr(ifp, IPPROTO_UDP, saddr, daddr,
- uh->uh_dport, &naddr, af)) != NULL) {
- bport = uh->uh_dport;
- if (rdr->opts & PF_RPORT_RANGE)
- nport = pf_map_port_range(rdr, uh->uh_dport);
- else if (rdr->rport)
- nport = rdr->rport;
- else
- nport = bport;
-
+ bport = nport = uh->uh_dport;
+ /* check incoming packet for BINAT/RDR */
+ if ((rdr = pf_get_translation(PF_IN, ifp, IPPROTO_UDP,
+ saddr, uh->uh_sport, daddr, uh->uh_dport,
+ &naddr, &nport, af)) != NULL) {
PF_ACPY(&baddr, daddr, af);
pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
&uh->uh_sum, &naddr, nport, 1, af);
rewrite++;
}
- /* check incoming packet for BINAT */
- else if ((binat = pf_get_binat(PF_IN, ifp, IPPROTO_UDP,
- daddr, saddr, &naddr, af)) != NULL) {
- PF_ACPY(&baddr, daddr, af);
- bport = uh->uh_dport;
- pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
- &uh->uh_sum, &naddr, uh->uh_dport, 1, af);
- rewrite++;
- }
}
- r = TAILQ_FIRST(pf_main_ruleset.rules.active.ptr);
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_RULE].active.ptr);
while (r != NULL) {
r->evaluations++;
if (r->action == PF_SCRUB)
@@ -2215,10 +2104,11 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = TAILQ_NEXT(r, entries);
} else
PF_STEP_INTO_ANCHOR(r, anchorrule, ruleset,
- rules);
+ PF_RULESET_RULE);
}
if (r == NULL && anchorrule != NULL)
- PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset, rules);
+ PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset,
+ PF_RULESET_RULE);
}
if (*rm != NULL) {
@@ -2240,13 +2130,11 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
(((*rm)->rule_flag & PFRULE_RETURNICMP) ||
((*rm)->rule_flag & PFRULE_RETURN))) {
/* undo NAT/RST changes, if they have taken place */
- if (nat != NULL ||
- (binat != NULL && direction == PF_OUT)) {
+ if (nat != NULL) {
pf_change_ap(saddr, &uh->uh_sport, pd->ip_sum,
&uh->uh_sum, &baddr, bport, 1, af);
rewrite++;
- } else if (rdr != NULL ||
- (binat != NULL && direction == PF_IN)) {
+ } else if (rdr != NULL) {
pf_change_ap(daddr, &uh->uh_dport, pd->ip_sum,
&uh->uh_sum, &baddr, bport, 1, af);
rewrite++;
@@ -2263,8 +2151,8 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
return (PF_DROP);
}
- if ((*rm != NULL && (*rm)->keep_state) || nat != NULL ||
- binat != NULL || rdr != NULL) {
+ if ((*rm != NULL && (*rm)->keep_state) ||
+ nat != NULL || rdr != NULL) {
/* create new state */
struct pf_state *s = NULL;
@@ -2287,7 +2175,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
s->gwy.port = uh->uh_sport;
PF_ACPY(&s->ext.addr, daddr, af);
s->ext.port = uh->uh_dport;
- if (nat != NULL || binat != NULL) {
+ if (nat != NULL) {
PF_ACPY(&s->lan.addr, &baddr, af);
s->lan.port = bport;
} else {
@@ -2299,7 +2187,7 @@ pf_test_udp(struct pf_rule **rm, int direction, struct ifnet *ifp,
s->lan.port = uh->uh_dport;
PF_ACPY(&s->ext.addr, saddr, af);
s->ext.port = uh->uh_sport;
- if (binat != NULL || rdr != NULL) {
+ if (rdr != NULL) {
PF_ACPY(&s->gwy.addr, &baddr, af);
s->gwy.port = bport;
} else {
@@ -2339,9 +2227,7 @@ int
pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
struct mbuf *m, int ipoff, int off, void *h, struct pf_pdesc *pd)
{
- struct pf_nat *nat = NULL;
- struct pf_binat *binat = NULL;
- struct pf_rdr *rdr = NULL;
+ struct pf_rule *nat = NULL, *rdr = NULL;
struct pf_addr *saddr = pd->src, *daddr = pd->dst, baddr, naddr;
struct pf_rule *r, *rs = NULL, *anchorrule = NULL;
struct pf_ruleset *ruleset = NULL;
@@ -2387,9 +2273,9 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
}
if (direction == PF_OUT) {
- /* check outgoing packet for BINAT */
- if ((binat = pf_get_binat(PF_OUT, ifp, IPPROTO_ICMP,
- saddr, daddr, &naddr, af)) != NULL) {
+ /* check outgoing packet for BINAT/NAT */
+ if ((nat = pf_get_translation(PF_OUT, ifp, pd->proto,
+ saddr, 0, daddr, 0, &naddr, NULL, af)) != NULL) {
PF_ACPY(&baddr, saddr, af);
switch (af) {
#ifdef INET
@@ -2407,50 +2293,10 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
#endif /* INET6 */
}
}
- /* check outgoing packet for NAT */
- else if ((nat = pf_get_nat(ifp, pd->proto,
- saddr, 0, daddr, 0, &naddr, NULL, af)) != NULL) {
- PF_ACPY(&baddr, saddr, af);
- switch (af) {
-#ifdef INET
- case AF_INET:
- pf_change_a(&saddr->v4.s_addr,
- pd->ip_sum, naddr.v4.s_addr, 0);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum,
- &naddr, 0);
- rewrite++;
- break;
-#endif /* INET6 */
- }
- }
} else {
- /* check incoming packet for RDR */
- if ((rdr = pf_get_rdr(ifp, pd->proto,
- saddr, daddr, 0, &naddr, af)) != NULL) {
- PF_ACPY(&baddr, daddr, af);
- switch (af) {
-#ifdef INET
- case AF_INET:
- pf_change_a(&daddr->v4.s_addr,
- pd->ip_sum, naddr.v4.s_addr, 0);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum,
- &naddr, 0);
- rewrite++;
- break;
-#endif /* INET6 */
- }
- }
- /* check incoming packet for BINAT */
- else if ((binat = pf_get_binat(PF_IN, ifp, IPPROTO_ICMP,
- daddr, saddr, &naddr, af)) != NULL) {
+ /* check incoming packet for BINAT/RDR */
+ if ((rdr = pf_get_translation(PF_IN, ifp, pd->proto,
+ saddr, 0, daddr, 0, &naddr, NULL, af)) != NULL) {
PF_ACPY(&baddr, daddr, af);
switch (af) {
#ifdef INET
@@ -2470,7 +2316,7 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
}
}
- r = TAILQ_FIRST(pf_main_ruleset.rules.active.ptr);
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_RULE].active.ptr);
while (r != NULL) {
r->evaluations++;
if (r->action == PF_SCRUB)
@@ -2515,10 +2361,11 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = TAILQ_NEXT(r, entries);
} else
PF_STEP_INTO_ANCHOR(r, anchorrule, ruleset,
- rules);
+ PF_RULESET_RULE);
}
if (r == NULL && anchorrule != NULL)
- PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset, rules);
+ PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset,
+ PF_RULESET_RULE);
}
if (*rm != NULL) {
@@ -2544,7 +2391,7 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
}
if (!state_icmp && ((*rm != NULL && (*rm)->keep_state) ||
- nat != NULL || rdr != NULL || binat != NULL)) {
+ nat != NULL || rdr != NULL)) {
/* create new state */
struct pf_state *s = NULL;
@@ -2567,7 +2414,7 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
s->gwy.port = icmpid;
PF_ACPY(&s->ext.addr, daddr, af);
s->ext.port = icmpid;
- if (nat != NULL || binat != NULL)
+ if (nat != NULL)
PF_ACPY(&s->lan.addr, &baddr, af);
else
PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
@@ -2577,7 +2424,7 @@ pf_test_icmp(struct pf_rule **rm, int direction, struct ifnet *ifp,
s->lan.port = icmpid;
PF_ACPY(&s->ext.addr, saddr, af);
s->ext.port = icmpid;
- if (binat != NULL || rdr != NULL)
+ if (rdr != NULL)
PF_ACPY(&s->gwy.addr, &baddr, af);
else
PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
@@ -2618,11 +2465,9 @@ int
pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
struct mbuf *m, void *h, struct pf_pdesc *pd)
{
+ struct pf_rule *nat = NULL, *rdr = NULL;
struct pf_rule *r, *rs = NULL, *anchorrule = NULL;
struct pf_ruleset *ruleset = NULL;
- struct pf_nat *nat = NULL;
- struct pf_binat *binat = NULL;
- struct pf_rdr *rdr = NULL;
struct pf_addr *saddr = pd->src, *daddr = pd->dst, baddr, naddr;
sa_family_t af = pd->af;
u_short reason;
@@ -2631,9 +2476,9 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
*rm = NULL;
if (direction == PF_OUT) {
- /* check outgoing packet for BINAT */
- if ((binat = pf_get_binat(PF_OUT, ifp, pd->proto,
- saddr, daddr, &naddr, af)) != NULL) {
+ /* check outgoing packet for BINAT/NAT */
+ if ((nat = pf_get_translation(PF_OUT, ifp, pd->proto,
+ saddr, 0, daddr, 0, &naddr, NULL, af)) != NULL) {
PF_ACPY(&baddr, saddr, af);
switch (af) {
#ifdef INET
@@ -2649,47 +2494,10 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
#endif /* INET6 */
}
}
- /* check outgoing packet for NAT */
- else if ((nat = pf_get_nat(ifp, pd->proto,
- saddr, 0, daddr, 0, &naddr, NULL, af)) != NULL) {
- PF_ACPY(&baddr, saddr, af);
- switch (af) {
-#ifdef INET
- case AF_INET:
- pf_change_a(&saddr->v4.s_addr,
- pd->ip_sum, naddr.v4.s_addr, 0);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- PF_ACPY(saddr, &naddr, af);
- break;
-#endif /* INET6 */
- }
- }
} else {
- /* check incoming packet for RDR */
- if ((rdr = pf_get_rdr(ifp, pd->proto,
- saddr, daddr, 0, &naddr, af)) != NULL) {
- PF_ACPY(&baddr, daddr, af);
- switch (af) {
-#ifdef INET
- case AF_INET:
- pf_change_a(&daddr->v4.s_addr,
- pd->ip_sum, naddr.v4.s_addr, 0);
- break;
-#endif /* INET */
-#ifdef INET6
- case AF_INET6:
- PF_ACPY(daddr, &naddr, af);
- break;
-#endif /* INET6 */
- }
- }
- /* check incoming packet for BINAT */
- else if ((binat = pf_get_binat(PF_IN, ifp, pd->proto,
- daddr, saddr, &naddr, af)) != NULL) {
- PF_ACPY(&baddr, daddr, af);
+ /* check incoming packet for BINAT/RDR */
+ if ((rdr = pf_get_translation(PF_IN, ifp, pd->proto,
+ saddr, 0, daddr, 0, &naddr, NULL, af)) != NULL) {
switch (af) {
#ifdef INET
case AF_INET:
@@ -2706,7 +2514,7 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
}
}
- r = TAILQ_FIRST(pf_main_ruleset.rules.active.ptr);
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_RULE].active.ptr);
while (r != NULL) {
r->evaluations++;
if (r->action == PF_SCRUB)
@@ -2747,10 +2555,11 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = TAILQ_NEXT(r, entries);
} else
PF_STEP_INTO_ANCHOR(r, anchorrule, ruleset,
- rules);
+ PF_RULESET_RULE);
}
if (r == NULL && anchorrule != NULL)
- PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset, rules);
+ PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset,
+ PF_RULESET_RULE);
}
if (*rm != NULL) {
@@ -2769,7 +2578,7 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
}
if ((*rm != NULL && (*rm)->keep_state) || nat != NULL ||
- rdr != NULL || binat != NULL) {
+ rdr != NULL) {
/* create new state */
struct pf_state *s = NULL;
@@ -2792,7 +2601,7 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
s->gwy.port = 0;
PF_ACPY(&s->ext.addr, daddr, af);
s->ext.port = 0;
- if (nat != NULL || binat != NULL)
+ if (nat != NULL)
PF_ACPY(&s->lan.addr, &baddr, af);
else
PF_ACPY(&s->lan.addr, &s->gwy.addr, af);
@@ -2802,7 +2611,7 @@ pf_test_other(struct pf_rule **rm, int direction, struct ifnet *ifp,
s->lan.port = 0;
PF_ACPY(&s->ext.addr, saddr, af);
s->ext.port = 0;
- if (binat != NULL || rdr != NULL)
+ if (rdr != NULL)
PF_ACPY(&s->gwy.addr, &baddr, af);
else
PF_ACPY(&s->gwy.addr, &s->lan.addr, af);
@@ -2845,7 +2654,7 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct ifnet *ifp,
*rm = NULL;
- r = TAILQ_FIRST(pf_main_ruleset.rules.active.ptr);
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_RULE].active.ptr);
while (r != NULL) {
r->evaluations++;
if (r->action == PF_SCRUB)
@@ -2887,10 +2696,11 @@ pf_test_fragment(struct pf_rule **rm, int direction, struct ifnet *ifp,
r = TAILQ_NEXT(r, entries);
} else
PF_STEP_INTO_ANCHOR(r, anchorrule, ruleset,
- rules);
+ PF_RULESET_RULE);
}
if (r == NULL && anchorrule != NULL)
- PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset, rules);
+ PF_STEP_OUT_OF_ANCHOR(r, anchorrule, ruleset,
+ PF_RULESET_RULE);
}
if (*rm != NULL) {
@@ -3962,18 +3772,18 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
if (ro->ro_rt->rt_flags & RTF_GATEWAY)
dst = satosin(ro->ro_rt->rt_gateway);
} else {
- if (!TAILQ_EMPTY(&r->rt_pool.list)) {
+ if (!TAILQ_EMPTY(&r->rpool.list)) {
if (s == NULL) {
- pf_map_addr(AF_INET, &r->rt_pool,
+ pf_map_addr(AF_INET, &r->rpool,
(struct pf_addr *)&ip->ip_src,
&naddr, NULL);
if (!PF_AZERO(&naddr, AF_INET))
dst->sin_addr.s_addr = naddr.v4.s_addr;
- ifp = r->rt_pool.cur->ifp;
+ ifp = r->rpool.cur->ifp;
} else {
if (s->rt_ifp == NULL) {
- s->rt_ifp = r->rt_pool.cur->ifp;
- pf_map_addr(AF_INET, &r->rt_pool,
+ s->rt_ifp = r->rpool.cur->ifp;
+ pf_map_addr(AF_INET, &r->rpool,
(struct pf_addr *)&ip->ip_src,
&naddr, NULL);
if (!PF_AZERO(&naddr, AF_INET))
@@ -4111,20 +3921,20 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
dst->sin6_len = sizeof(*dst);
dst->sin6_addr = ip6->ip6_dst;
- if (!TAILQ_EMPTY(&r->rt_pool.list)) {
+ if (!TAILQ_EMPTY(&r->rpool.list)) {
if (s == NULL) {
- pf_map_addr(AF_INET6, &r->rt_pool,
+ pf_map_addr(AF_INET6, &r->rpool,
(struct pf_addr *)&ip6->ip6_src, &naddr, NULL);
if (!PF_AZERO(&naddr, AF_INET6)) {
PF_ACPY(
(struct pf_addr *)&dst->sin6_addr,
&naddr, AF_INET6);
}
- ifp = r->rt_pool.cur->ifp;
+ ifp = r->rpool.cur->ifp;
} else {
if (s->rt_ifp == NULL) {
- s->rt_ifp = r->rt_pool.cur->ifp;
- pf_map_addr(AF_INET6, &r->rt_pool,
+ s->rt_ifp = r->rpool.cur->ifp;
+ pf_map_addr(AF_INET6, &r->rpool,
(struct pf_addr *)&ip6->ip6_src,
&naddr, NULL);
if (!PF_AZERO(&naddr, AF_INET6))
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index 36d4997ef3c..fc094cb62da 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.25 2002/12/13 21:48:30 henning Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.26 2002/12/17 12:30:13 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -71,32 +71,18 @@ void pfattach(int);
int pfopen(dev_t, int, int, struct proc *);
int pfclose(dev_t, int, int, struct proc *);
struct pf_pool *pf_get_pool(char *, char *, u_int32_t,
- u_int8_t, u_int8_t, u_int8_t, u_int8_t);
+ u_int8_t, u_int8_t, u_int8_t, u_int8_t, u_int8_t);
int pf_add_addr(struct pf_pool *, struct pf_pooladdr *,
u_int8_t);
-int pf_compare_addr_wrap(struct pf_addr_wrap *,
- struct pf_addr_wrap *, sa_family_t);
-int pf_compare_pool(struct pf_pool *, struct pf_pool *,
- sa_family_t);
-int pf_compare_rules(struct pf_rule *,
- struct pf_rule *);
-int pf_compare_nats(struct pf_nat *, struct pf_nat *);
-int pf_compare_binats(struct pf_binat *,
- struct pf_binat *);
-int pf_compare_pooladdrs(struct pf_pooladdr *,
- struct pf_pooladdr *, sa_family_t);
-int pf_compare_rdrs(struct pf_rdr *, struct pf_rdr *);
+int pf_get_ruleset_number(u_int8_t);
void pf_init_ruleset(struct pf_ruleset *);
struct pf_anchor *pf_find_anchor(const char *);
struct pf_ruleset *pf_find_ruleset(char *, char *);
-struct pf_ruleset *pf_find_or_create_ruleset(char *, char *);
+struct pf_ruleset *pf_find_or_create_ruleset(char *, char *, int);
void pf_remove_if_empty_ruleset(struct pf_ruleset *);
void pf_mv_pool(struct pf_palist *, struct pf_palist *);
void pf_empty_pool(struct pf_palist *);
void pf_rm_rule(struct pf_rulequeue *, struct pf_rule *);
-void pf_rm_nat(struct pf_natqueue *, struct pf_nat *);
-void pf_rm_binat(struct pf_binatqueue *, struct pf_binat *);
-void pf_rm_rdr(struct pf_rdrqueue *, struct pf_rdr *);
int pfioctl(dev_t, u_long, caddr_t, int, struct proc *);
extern struct timeout pf_expire_to;
@@ -110,16 +96,10 @@ pfattach(int num)
NULL);
pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl",
&pool_allocator_nointr);
- pool_init(&pf_nat_pl, sizeof(struct pf_nat), 0, 0, 0, "pfnatpl",
- &pool_allocator_nointr);
- pool_init(&pf_binat_pl, sizeof(struct pf_binat), 0, 0, 0, "pfbinatpl",
- &pool_allocator_nointr);
- pool_init(&pf_rdr_pl, sizeof(struct pf_rdr), 0, 0, 0, "pfrdrpl",
+ pool_init(&pf_addr_pl, sizeof(struct pf_addr_dyn), 0, 0, 0, "pfaddrpl",
&pool_allocator_nointr);
pool_init(&pf_state_pl, sizeof(struct pf_state), 0, 0, 0, "pfstatepl",
NULL);
- pool_init(&pf_addr_pl, sizeof(struct pf_addr_dyn), 0, 0, 0, "pfaddr",
- NULL);
pool_init(&pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl",
NULL);
pool_init(&pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0,
@@ -159,110 +139,43 @@ pfclose(dev_t dev, int flags, int fmt, struct proc *p)
struct pf_pool *
pf_get_pool(char *anchorname, char *rulesetname, u_int32_t ticket,
- u_int8_t r_id, u_int8_t r_num, u_int8_t active, u_int8_t check_ticket)
+ u_int8_t rule_action, u_int8_t rule_number, u_int8_t r_last,
+ u_int8_t active, u_int8_t check_ticket)
{
struct pf_ruleset *ruleset;
struct pf_rule *rule;
- struct pf_nat *nat;
- struct pf_rdr *rdr;
- u_int32_t nr = 0;
-
+ int rs_num;
ruleset = pf_find_ruleset(anchorname, rulesetname);
if (ruleset == NULL)
return (NULL);
- switch (r_id & PF_POOL_IDMASK) {
- case PF_POOL_RULE_RT:
- if (active) {
- if (check_ticket && ticket !=
- ruleset->rules.active.ticket)
- break;
- if (r_id & PF_POOL_LAST)
- rule = TAILQ_LAST(ruleset->rules.active.ptr,
- pf_rulequeue);
- else
- rule = TAILQ_FIRST(ruleset->rules.active.ptr);
- } else {
- if (check_ticket && ticket !=
- ruleset->rules.inactive.ticket)
- break;
- if (r_id & PF_POOL_LAST)
- rule = TAILQ_LAST(ruleset->rules.inactive.ptr,
- pf_rulequeue);
- else
- rule = TAILQ_FIRST(ruleset->rules.inactive.ptr);
- }
- if (!(r_id & PF_POOL_LAST)) {
- while ((rule != NULL) && (rule->nr < r_num))
- rule = TAILQ_NEXT(rule, entries);
- }
- if (rule == NULL)
- break;
- return(&rule->rt_pool);
- break;
-
- case PF_POOL_NAT_R:
- if (active) {
- if (check_ticket && ticket !=
- ruleset->nats.active.ticket)
- break;
- if (r_id & PF_POOL_LAST)
- nat = TAILQ_LAST(ruleset->nats.active.ptr,
- pf_natqueue);
- else
- nat = TAILQ_FIRST(ruleset->nats.active.ptr);
- } else {
- if (check_ticket && ticket !=
- ruleset->nats.inactive.ticket)
- break;
- if (r_id & PF_POOL_LAST)
- nat = TAILQ_LAST(ruleset->nats.inactive.ptr,
- pf_natqueue);
- else
- nat = TAILQ_FIRST(ruleset->nats.inactive.ptr);
- }
- if (!(r_id & PF_POOL_LAST)) {
- while ((nat != NULL) && (nr < r_num)) {
- nat = TAILQ_NEXT(nat, entries);
- nr++;
- }
- }
- if (nat == NULL)
- break;
- return(&nat->rpool);
- break;
-
- case PF_POOL_RDR_R:
- if (active) {
- if (check_ticket && ticket !=
- ruleset->rdrs.active.ticket)
- break;
- if (r_id & PF_POOL_LAST)
- rdr = TAILQ_LAST(ruleset->rdrs.active.ptr,
- pf_rdrqueue);
- else
- rdr = TAILQ_FIRST(ruleset->rdrs.active.ptr);
- } else {
- if (check_ticket && ticket !=
- ruleset->rdrs.inactive.ticket)
- break;
- if (r_id & PF_POOL_LAST)
- rdr = TAILQ_LAST(ruleset->rdrs.inactive.ptr,
- pf_rdrqueue);
- else
- rdr = TAILQ_FIRST(ruleset->rdrs.inactive.ptr);
- }
- if (!(r_id & PF_POOL_LAST)) {
- while ((rdr != NULL) && (nr < r_num)) {
- rdr = TAILQ_NEXT(rdr, entries);
- nr++;
- }
- }
- if (rdr == NULL)
- break;
- return(&rdr->rpool);
- break;
+ rs_num = pf_get_ruleset_number(rule_action);
+ if (active) {
+ if (check_ticket && ticket !=
+ ruleset->rules[rs_num].active.ticket)
+ return (NULL);
+ if (r_last)
+ rule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
+ pf_rulequeue);
+ else
+ rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
+ } else {
+ if (check_ticket && ticket !=
+ ruleset->rules[rs_num].inactive.ticket)
+ return (NULL);
+ if (r_last)
+ rule = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
+ pf_rulequeue);
+ else
+ rule = TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr);
}
- return (NULL);
+ if (!r_last) {
+ while ((rule != NULL) && (rule->nr != rule_number))
+ rule = TAILQ_NEXT(rule, entries);
+ }
+ if (rule == NULL)
+ return(NULL);
+
+ return (&rule->rpool);
}
int
@@ -283,213 +196,58 @@ pf_add_addr(struct pf_pool *pool, struct pf_pooladdr *addr, u_int8_t af)
}
} else
pa->ifp = NULL;
- if (pf_dynaddr_setup(&pa->addr, af)) {
- pf_dynaddr_remove(&pa->addr);
+ if (pf_dynaddr_setup(&pa->addr.addr, af)) {
+ pf_dynaddr_remove(&pa->addr.addr);
pool_put(&pf_pooladdr_pl, pa);
return (EBUSY);
}
if (TAILQ_EMPTY(&pool->list)) {
pool->cur = pa;
- PF_ACPY(&pool->counter, &pa->addr.addr, af);
+ PF_ACPY(&pool->counter, &pa->addr.addr.addr, af);
}
TAILQ_INSERT_TAIL(&pool->list, pa, entries);
return (0);
}
-int
-pf_compare_addr_wrap(struct pf_addr_wrap *a, struct pf_addr_wrap *b,
- sa_family_t af)
-{
- if (a->addr_dyn != NULL && b->addr_dyn != NULL) {
- if (strcmp(a->addr_dyn->ifname, b->addr_dyn->ifname))
- return (1);
- } else {
- if (a->addr_dyn != NULL || b->addr_dyn != NULL)
- return (1);
- if (PF_ANEQ(&a->addr, &b->addr, af))
- return (1);
- }
- if (PF_ANEQ(&a->mask, &b->mask, af))
- return (1);
- return (0);
-}
int
-pf_compare_pool(struct pf_pool *a, struct pf_pool *b, sa_family_t af)
+pf_get_ruleset_number(u_int8_t action)
{
- struct pf_pooladdr *pa_a, *pa_b;
-
- if (a->key.key32[0] != b->key.key32[0] ||
- a->key.key32[1] != b->key.key32[1] ||
- a->key.key32[2] != b->key.key32[2] ||
- a->key.key32[3] != b->key.key32[3] ||
- a->opts != b->opts)
- return(1);
- pa_a = TAILQ_FIRST(&a->list);
- pa_b = TAILQ_FIRST(&b->list);
- while (pa_a != NULL && pa_b != NULL) {
- if (pf_compare_addr_wrap(&pa_a->addr, &pa_b->addr, af))
- return (1);
- if (strcmp(pa_a->ifname, pa_b->ifname))
- return (1);
- pa_a = TAILQ_NEXT(pa_a, entries);
- pa_b = TAILQ_NEXT(pa_b, entries);
+ switch (action) {
+ case PF_PASS:
+ case PF_DROP:
+ case PF_SCRUB:
+ default:
+ return (PF_RULESET_RULE);
+ break;
+ case PF_NAT:
+ case PF_NONAT:
+ return (PF_RULESET_NAT);
+ break;
+ case PF_BINAT:
+ case PF_NOBINAT:
+ return (PF_RULESET_BINAT);
+ break;
+ case PF_RDR:
+ case PF_NORDR:
+ return (PF_RULESET_RDR);
+ break;
}
- return (0);
-}
-
-int
-pf_compare_rules(struct pf_rule *a, struct pf_rule *b)
-{
- if (a->return_icmp != b->return_icmp ||
- a->return_icmp6 != b->return_icmp6 ||
- a->action != b->action ||
- a->direction != b->direction ||
- a->log != b->log ||
- a->quick != b->quick ||
- a->keep_state != b->keep_state ||
- a->af != b->af ||
- a->proto != b->proto ||
- a->type != b->type ||
- a->code != b->code ||
- a->flags != b->flags ||
- a->flagset != b->flagset ||
- a->rule_flag != b->rule_flag ||
- a->min_ttl != b->min_ttl ||
- a->tos != b->tos ||
- a->allow_opts != b->allow_opts ||
- a->ifnot != b->ifnot)
- return (1);
- if (pf_compare_addr_wrap(&a->src.addr, &b->src.addr, a->af))
- return (1);
- if (a->src.port[0] != b->src.port[0] ||
- a->src.port[1] != b->src.port[1] ||
- a->src.not != b->src.not ||
- a->src.port_op != b->src.port_op)
- return (1);
- if (pf_compare_addr_wrap(&a->dst.addr, &b->dst.addr, a->af))
- return (1);
- if (a->dst.port[0] != b->dst.port[0] ||
- a->dst.port[1] != b->dst.port[1] ||
- a->dst.not != b->dst.not ||
- a->dst.port_op != b->dst.port_op)
- return (1);
- if (pf_compare_pool(&a->rt_pool, &b->rt_pool, a->af))
- return (1);
- if (strcmp(a->ifname, b->ifname) ||
- strcmp(a->anchorname, b->anchorname) ||
- strcmp(a->label, b->label))
- return (1);
- return (0);
-}
-
-int
-pf_compare_nats(struct pf_nat *a, struct pf_nat *b)
-{
- if (a->proto != b->proto ||
- a->af != b->af ||
- a->ifnot != b->ifnot ||
- a->no != b->no)
- return (1);
- if (pf_compare_addr_wrap(&a->src.addr, &b->src.addr, a->af))
- return (1);
- if (a->src.port[0] != b->src.port[0] ||
- a->src.port[1] != b->src.port[1] ||
- a->src.not != b->src.not ||
- a->src.port_op != b->src.port_op)
- return (1);
- if (pf_compare_addr_wrap(&a->dst.addr, &b->dst.addr, a->af))
- return (1);
- if (a->dst.port[0] != b->dst.port[0] ||
- a->dst.port[1] != b->dst.port[1] ||
- a->dst.not != b->dst.not ||
- a->dst.port_op != b->dst.port_op)
- return (1);
- if (pf_compare_pool(&a->rpool, &b->rpool, a->af))
- return (1);
- if (strcmp(a->ifname, b->ifname))
- return (1);
- return (0);
-}
-
-int
-pf_compare_binats(struct pf_binat *a, struct pf_binat *b)
-{
- if (a->proto != b->proto ||
- a->dnot != b->dnot ||
- a->af != b->af ||
- a->no != b->no)
- return (1);
- if (pf_compare_addr_wrap(&a->saddr, &b->saddr, a->af))
- return (1);
- if (PF_ANEQ(&a->saddr.mask, &b->saddr.mask, a->af))
- return (1);
- if (pf_compare_addr_wrap(&a->daddr, &b->daddr, a->af))
- return (1);
- if (PF_ANEQ(&a->daddr.mask, &b->daddr.mask, a->af))
- return (1);
- if (strcmp(a->ifname, b->ifname))
- return (1);
- return (0);
-}
-
-int
-pf_compare_rdrs(struct pf_rdr *a, struct pf_rdr *b)
-{
- if (a->dport != b->dport ||
- a->dport2 != b->dport2 ||
- a->rport != b->rport ||
- a->proto != b->proto ||
- a->af != b->af ||
- a->snot != b->snot ||
- a->dnot != b->dnot ||
- a->ifnot != b->ifnot ||
- a->opts != b->opts ||
- a->no != b->no)
- return (1);
- if (pf_compare_addr_wrap(&a->saddr, &b->saddr, a->af))
- return (1);
- if (pf_compare_addr_wrap(&a->daddr, &b->daddr, a->af))
- return (1);
- if (pf_compare_pool(&a->rpool, &b->rpool, a->af))
- return (1);
- if (strcmp(a->ifname, b->ifname))
- return (1);
- return (0);
-}
-
-int
-pf_compare_pooladdrs(struct pf_pooladdr *a, struct pf_pooladdr *b,
- sa_family_t af)
-{
- if (pf_compare_addr_wrap(&a->addr, &b->addr, af))
- return (1);
- if (strcmp(a->ifname, b->ifname))
- return (1);
- return (0);
}
void
pf_init_ruleset(struct pf_ruleset *ruleset)
{
+ int i;
+
memset(ruleset, 0, sizeof(struct pf_ruleset));
- TAILQ_INIT(&ruleset->rules.queues[0]);
- TAILQ_INIT(&ruleset->rules.queues[1]);
- ruleset->rules.active.ptr = &ruleset->rules.queues[0];
- ruleset->rules.inactive.ptr = &ruleset->rules.queues[1];
- TAILQ_INIT(&ruleset->nats.queues[0]);
- TAILQ_INIT(&ruleset->nats.queues[1]);
- ruleset->nats.active.ptr = &ruleset->nats.queues[0];
- ruleset->nats.inactive.ptr = &ruleset->nats.queues[1];
- TAILQ_INIT(&ruleset->rdrs.queues[0]);
- TAILQ_INIT(&ruleset->rdrs.queues[1]);
- ruleset->rdrs.active.ptr = &ruleset->rdrs.queues[0];
- ruleset->rdrs.inactive.ptr = &ruleset->rdrs.queues[1];
- TAILQ_INIT(&ruleset->binats.queues[0]);
- TAILQ_INIT(&ruleset->binats.queues[1]);
- ruleset->binats.active.ptr = &ruleset->binats.queues[0];
- ruleset->binats.inactive.ptr = &ruleset->binats.queues[1];
+ for(i = 0; i < PF_RULESET_MAX; i++) {
+ TAILQ_INIT(&ruleset->rules[i].queues[0]);
+ TAILQ_INIT(&ruleset->rules[i].queues[1]);
+ ruleset->rules[i].active.ptr = &ruleset->rules[i].queues[0];
+ ruleset->rules[i].inactive.ptr = &ruleset->rules[i].queues[1];
+ }
}
struct pf_anchor *
@@ -532,7 +290,7 @@ pf_find_ruleset(char *anchorname, char *rulesetname)
}
struct pf_ruleset *
-pf_find_or_create_ruleset(char *anchorname, char *rulesetname)
+pf_find_or_create_ruleset(char *anchorname, char *rulesetname, int rs_num)
{
struct pf_anchor *anchor, *a;
struct pf_ruleset *ruleset, *r;
@@ -586,14 +344,14 @@ pf_remove_if_empty_ruleset(struct pf_ruleset *ruleset)
struct pf_anchor *anchor;
if (ruleset == NULL || ruleset->anchor == NULL ||
- !TAILQ_EMPTY(ruleset->rules.active.ptr) ||
- !TAILQ_EMPTY(ruleset->rules.inactive.ptr) ||
- !TAILQ_EMPTY(ruleset->nats.active.ptr) ||
- !TAILQ_EMPTY(ruleset->nats.inactive.ptr) ||
- !TAILQ_EMPTY(ruleset->rdrs.active.ptr) ||
- !TAILQ_EMPTY(ruleset->rdrs.inactive.ptr) ||
- !TAILQ_EMPTY(ruleset->binats.active.ptr) ||
- !TAILQ_EMPTY(ruleset->binats.inactive.ptr))
+ !TAILQ_EMPTY(ruleset->rules[0].active.ptr) ||
+ !TAILQ_EMPTY(ruleset->rules[0].inactive.ptr) ||
+ !TAILQ_EMPTY(ruleset->rules[1].active.ptr) ||
+ !TAILQ_EMPTY(ruleset->rules[1].inactive.ptr) ||
+ !TAILQ_EMPTY(ruleset->rules[2].active.ptr) ||
+ !TAILQ_EMPTY(ruleset->rules[2].inactive.ptr) ||
+ !TAILQ_EMPTY(ruleset->rules[3].active.ptr) ||
+ !TAILQ_EMPTY(ruleset->rules[3].inactive.ptr))
return;
anchor = ruleset->anchor;
@@ -623,7 +381,7 @@ pf_empty_pool(struct pf_palist *poola)
struct pf_pooladdr *empty_pool_pa;
while ((empty_pool_pa = TAILQ_FIRST(poola)) != NULL) {
- pf_dynaddr_remove(&empty_pool_pa->addr);
+ pf_dynaddr_remove(&empty_pool_pa->addr.addr);
TAILQ_REMOVE(poola, empty_pool_pa, entries);
pool_put(&pf_pooladdr_pl, empty_pool_pa);
}
@@ -634,45 +392,12 @@ pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule)
{
pf_dynaddr_remove(&rule->src.addr);
pf_dynaddr_remove(&rule->dst.addr);
- pf_empty_pool(&rule->rt_pool.list);
+ pf_empty_pool(&rule->rpool.list);
if (rulequeue != NULL)
TAILQ_REMOVE(rulequeue, rule, entries);
pool_put(&pf_rule_pl, rule);
}
-void
-pf_rm_nat(struct pf_natqueue *natqueue, struct pf_nat *nat)
-{
- pf_dynaddr_remove(&nat->src.addr);
- pf_dynaddr_remove(&nat->dst.addr);
- pf_empty_pool(&nat->rpool.list);
- if (natqueue != NULL)
- TAILQ_REMOVE(natqueue, nat, entries);
- pool_put(&pf_nat_pl, nat);
-}
-
-void
-pf_rm_binat(struct pf_binatqueue *binatqueue, struct pf_binat *binat)
-{
- pf_dynaddr_remove(&binat->saddr);
- pf_dynaddr_remove(&binat->daddr);
- pf_dynaddr_remove(&binat->raddr);
- if (binatqueue != NULL)
- TAILQ_REMOVE(binatqueue, binat, entries);
- pool_put(&pf_binat_pl, binat);
-}
-
-void
-pf_rm_rdr(struct pf_rdrqueue *rdrqueue, struct pf_rdr *rdr)
-{
- pf_dynaddr_remove(&rdr->saddr);
- pf_dynaddr_remove(&rdr->daddr);
- pf_empty_pool(&rdr->rpool.list);
- if (rdrqueue != NULL)
- TAILQ_REMOVE(rdrqueue, rdr, entries);
- pool_put(&pf_rdr_pl, rdr);
-}
-
int
pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
{
@@ -686,12 +411,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
switch (cmd) {
case DIOCGETRULES:
case DIOCGETRULE:
- case DIOCGETNATS:
- case DIOCGETNAT:
- case DIOCGETBINATS:
- case DIOCGETBINAT:
- case DIOCGETRDRS:
- case DIOCGETRDR:
case DIOCGETADDRS:
case DIOCGETADDR:
case DIOCGETSTATE:
@@ -720,18 +439,12 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
switch (cmd) {
case DIOCGETRULES:
case DIOCGETRULE:
- case DIOCGETNATS:
- case DIOCGETNAT:
- case DIOCGETRDRS:
- case DIOCGETRDR:
case DIOCGETADDRS:
case DIOCGETADDR:
case DIOCGETSTATE:
case DIOCGETSTATUS:
case DIOCGETSTATES:
case DIOCGETTIMEOUT:
- case DIOCGETBINATS:
- case DIOCGETBINAT:
case DIOCGETLIMIT:
case DIOCGETALTQS:
case DIOCGETALTQ:
@@ -776,16 +489,19 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pfioc_rule *pr = (struct pfioc_rule *)addr;
struct pf_ruleset *ruleset;
struct pf_rule *rule;
+ int rs_num;
- ruleset = pf_find_or_create_ruleset(pr->anchor, pr->ruleset);
+ ruleset = pf_find_or_create_ruleset(pr->anchor,
+ pr->ruleset, rs_num);
if (ruleset == NULL) {
error = EINVAL;
break;
}
- while ((rule = TAILQ_FIRST(ruleset->rules.inactive.ptr)) !=
- NULL)
- pf_rm_rule(ruleset->rules.inactive.ptr, rule);
- pr->ticket = ++ruleset->rules.inactive.ticket;
+ rs_num = pf_get_ruleset_number(pr->rule.action);
+ while ((rule =
+ TAILQ_FIRST(ruleset->rules[rs_num].inactive.ptr)) != NULL)
+ pf_rm_rule(ruleset->rules[rs_num].inactive.ptr, rule);
+ pr->ticket = ++ruleset->rules[rs_num].inactive.ticket;
break;
}
@@ -793,17 +509,19 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pfioc_rule *pr = (struct pfioc_rule *)addr;
struct pf_ruleset *ruleset;
struct pf_rule *rule, *tail;
+ int rs_num;
ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
if (ruleset == NULL) {
error = EINVAL;
break;
}
+ rs_num = pf_get_ruleset_number(pr->rule.action);
if (pr->rule.anchorname[0] && ruleset != &pf_main_ruleset) {
error = EINVAL;
break;
}
- if (pr->ticket != ruleset->rules.inactive.ticket) {
+ if (pr->ticket != ruleset->rules[rs_num].inactive.ticket) {
error = EBUSY;
break;
}
@@ -819,7 +537,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
bcopy(&pr->rule, rule, sizeof(struct pf_rule));
rule->anchor = NULL;
rule->ifp = NULL;
- TAILQ_INIT(&rule->rt_pool.list);
+ TAILQ_INIT(&rule->rpool.list);
#ifndef INET
if (rule->af == AF_INET) {
pool_put(&pf_rule_pl, rule);
@@ -834,7 +552,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
#endif /* INET6 */
- tail = TAILQ_LAST(ruleset->rules.inactive.ptr, pf_rulequeue);
+ tail = TAILQ_LAST(ruleset->rules[rs_num].inactive.ptr,
+ pf_rulequeue);
if (tail)
rule->nr = tail->nr + 1;
else
@@ -847,10 +566,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
}
-#ifdef ALTQ
- if (rule->qid && !rule->pqid)
- rule->pqid = rule->qid;
-#endif /* ALTQ */
if (pf_dynaddr_setup(&rule->src.addr, rule->af))
error = EINVAL;
@@ -860,10 +575,11 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
pf_rm_rule(NULL, rule);
break;
}
- pf_mv_pool(&pf_pabuf[0], &rule->rt_pool.list);
- rule->rt_pool.cur = TAILQ_FIRST(&rule->rt_pool.list);
+ pf_mv_pool(&pf_pabuf[0], &rule->rpool.list);
+ rule->rpool.cur = TAILQ_FIRST(&rule->rpool.list);
rule->evaluations = rule->packets = rule->bytes = 0;
- TAILQ_INSERT_TAIL(ruleset->rules.inactive.ptr, rule, entries);
+ TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
+ rule, entries);
break;
}
@@ -873,13 +589,15 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pf_rulequeue *old_rules;
struct pf_rule *rule;
struct pf_tree_node *n;
+ int rs_num;
ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
if (ruleset == NULL) {
error = EINVAL;
break;
}
- if (pr->ticket != ruleset->rules.inactive.ticket) {
+ rs_num = pf_get_ruleset_number(pr->rule.action);
+ if (pr->ticket != ruleset->rules[rs_num].inactive.ticket) {
error = EBUSY;
break;
}
@@ -893,11 +611,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
RB_FOREACH(n, pf_state_tree, &tree_ext_gwy)
n->state->rule.ptr = NULL;
}
- old_rules = ruleset->rules.active.ptr;
- ruleset->rules.active.ptr = ruleset->rules.inactive.ptr;
- ruleset->rules.inactive.ptr = old_rules;
- ruleset->rules.active.ticket = ruleset->rules.inactive.ticket;
- pf_calc_skip_steps(ruleset->rules.active.ptr);
+ old_rules = ruleset->rules[rs_num].active.ptr;
+ ruleset->rules[rs_num].active.ptr =
+ ruleset->rules[rs_num].inactive.ptr;
+ ruleset->rules[rs_num].inactive.ptr = old_rules;
+ ruleset->rules[rs_num].active.ticket =
+ ruleset->rules[rs_num].inactive.ticket;
+ pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
/* Purge the old rule list. */
while ((rule = TAILQ_FIRST(old_rules)) != NULL)
@@ -912,19 +632,22 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pfioc_rule *pr = (struct pfioc_rule *)addr;
struct pf_ruleset *ruleset;
struct pf_rule *tail;
+ int rs_num;
ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
if (ruleset == NULL) {
error = EINVAL;
break;
}
+ rs_num = pf_get_ruleset_number(pr->rule.action);
s = splsoftnet();
- tail = TAILQ_LAST(ruleset->rules.active.ptr, pf_rulequeue);
+ tail = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
+ pf_rulequeue);
if (tail)
pr->nr = tail->nr + 1;
else
pr->nr = 0;
- pr->ticket = ruleset->rules.active.ticket;
+ pr->ticket = ruleset->rules[rs_num].active.ticket;
splx(s);
break;
}
@@ -933,18 +656,20 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pfioc_rule *pr = (struct pfioc_rule *)addr;
struct pf_ruleset *ruleset;
struct pf_rule *rule;
+ int rs_num;
ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
if (ruleset == NULL) {
error = EINVAL;
break;
}
- if (pr->ticket != ruleset->rules.active.ticket) {
+ rs_num = pf_get_ruleset_number(pr->rule.action);
+ if (pr->ticket != ruleset->rules[rs_num].active.ticket) {
error = EBUSY;
break;
}
s = splsoftnet();
- rule = TAILQ_FIRST(ruleset->rules.active.ptr);
+ rule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
while ((rule != NULL) && (rule->nr != pr->nr))
rule = TAILQ_NEXT(rule, entries);
if (rule == NULL) {
@@ -960,18 +685,21 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
case DIOCCHANGERULE: {
- struct pfioc_changerule *pcr = (struct pfioc_changerule *)addr;
+ struct pfioc_rule *pcr = (struct pfioc_rule *)addr;
struct pf_ruleset *ruleset;
struct pf_rule *oldrule = NULL, *newrule = NULL;
u_int32_t nr = 0;
+ int rs_num;
- if (pcr->pool_ticket != ticket_pabuf) {
+ if (!(pcr->action == PF_CHANGE_REMOVE ||
+ pcr->action == PF_CHANGE_GET_TICKET) &&
+ pcr->pool_ticket != ticket_pabuf) {
error = EBUSY;
break;
}
if (pcr->action < PF_CHANGE_ADD_HEAD ||
- pcr->action > PF_CHANGE_REMOVE) {
+ pcr->action > PF_CHANGE_GET_TICKET) {
error = EINVAL;
break;
}
@@ -980,6 +708,18 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = EINVAL;
break;
}
+ rs_num = pf_get_ruleset_number(pcr->rule.action);
+
+ if (pcr->action == PF_CHANGE_GET_TICKET) {
+ pcr->ticket = ++ruleset->rules[rs_num].active.ticket;
+ break;
+ } else {
+ if (pcr->ticket !=
+ ruleset->rules[rs_num].active.ticket) {
+ error = EINVAL;
+ break;
+ }
+ }
if (pcr->action != PF_CHANGE_REMOVE) {
newrule = pool_get(&pf_rule_pl, PR_NOWAIT);
@@ -987,8 +727,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = ENOMEM;
break;
}
- bcopy(&pcr->newrule, newrule, sizeof(struct pf_rule));
- TAILQ_INIT(&newrule->rt_pool.list);
+ bcopy(&pcr->rule, newrule, sizeof(struct pf_rule));
+ TAILQ_INIT(&newrule->rpool.list);
#ifndef INET
if (newrule->af == AF_INET) {
pool_put(&pf_rule_pl, newrule);
@@ -1021,7 +761,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
pf_rm_rule(NULL, newrule);
break;
}
- pf_mv_pool(&pf_pabuf[0], &newrule->rt_pool.list);
+ pf_mv_pool(&pf_pabuf[0], &newrule->rpool.list);
newrule->evaluations = newrule->packets = 0;
newrule->bytes = 0;
}
@@ -1030,17 +770,14 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
s = splsoftnet();
if (pcr->action == PF_CHANGE_ADD_HEAD)
- oldrule = TAILQ_FIRST(ruleset->rules.active.ptr);
+ oldrule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
else if (pcr->action == PF_CHANGE_ADD_TAIL)
- oldrule = TAILQ_LAST(ruleset->rules.active.ptr,
+ oldrule = TAILQ_LAST(ruleset->rules[rs_num].active.ptr,
pf_rulequeue);
else {
- pf_mv_pool(&pf_pabuf[0], &pcr->oldrule.rt_pool.list);
- oldrule = TAILQ_FIRST(ruleset->rules.active.ptr);
- while ((oldrule != NULL) && pf_compare_rules(oldrule,
- &pcr->oldrule))
+ oldrule = TAILQ_FIRST(ruleset->rules[rs_num].active.ptr);
+ while ((oldrule != NULL) && (oldrule->nr != pcr->nr))
oldrule = TAILQ_NEXT(oldrule, entries);
- pf_empty_pool(&pcr->oldrule.rt_pool.list);
if (oldrule == NULL) {
pf_rm_rule(NULL, newrule);
error = EINVAL;
@@ -1057,855 +794,31 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if (n->state->rule.ptr == oldrule)
n->state->rule.ptr = NULL;
}
- pf_rm_rule(NULL, oldrule);
+ pf_rm_rule(ruleset->rules[rs_num].active.ptr, oldrule);
} else {
if (oldrule == NULL)
- TAILQ_INSERT_TAIL(ruleset->rules.active.ptr,
+ TAILQ_INSERT_TAIL(
+ ruleset->rules[rs_num].active.ptr,
newrule, entries);
else if (pcr->action == PF_CHANGE_ADD_HEAD ||
pcr->action == PF_CHANGE_ADD_BEFORE)
TAILQ_INSERT_BEFORE(oldrule, newrule, entries);
else
- TAILQ_INSERT_AFTER(ruleset->rules.active.ptr,
+ TAILQ_INSERT_AFTER(
+ ruleset->rules[rs_num].active.ptr,
oldrule, newrule, entries);
}
- TAILQ_FOREACH(oldrule, ruleset->rules.active.ptr, entries)
- oldrule->nr = nr++;
-
- pf_calc_skip_steps(ruleset->rules.active.ptr);
- pf_remove_if_empty_ruleset(ruleset);
- pf_update_anchor_rules();
-
- ruleset->rules.active.ticket++;
- splx(s);
- break;
- }
-
- case DIOCBEGINNATS: {
- struct pfioc_nat *pn = (struct pfioc_nat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_nat *nat;
-
- ruleset = pf_find_or_create_ruleset(pn->anchor, pn->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- while ((nat = TAILQ_FIRST(ruleset->nats.inactive.ptr)) !=
- NULL)
- pf_rm_nat(ruleset->nats.inactive.ptr, nat);
- pn->ticket = ++ruleset->nats.inactive.ticket;
- break;
- }
-
- case DIOCADDNAT: {
- struct pfioc_nat *pn = (struct pfioc_nat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_nat *nat;
-
- ruleset = pf_find_ruleset(pn->anchor, pn->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- if (pn->nat.anchorname[0] && ruleset != &pf_main_ruleset) {
- error = EINVAL;
- break;
- }
- if (pn->ticket != ruleset->nats.inactive.ticket) {
- error = EBUSY;
- break;
- }
- if (pn->pool_ticket != ticket_pabuf) {
- error = EBUSY;
- break;
- }
- nat = pool_get(&pf_nat_pl, PR_NOWAIT);
- if (nat == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(&pn->nat, nat, sizeof(struct pf_nat));
- nat->anchor = NULL;
- nat->ifp = NULL;
- TAILQ_INIT(&nat->rpool.list);
-#ifndef INET
- if (nat->af == AF_INET) {
- pool_put(&pf_nat_pl, nat);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET */
-#ifndef INET6
- if (nat->af == AF_INET6) {
- pool_put(&pf_nat_pl, nat);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET6 */
- if (nat->ifname[0]) {
- nat->ifp = ifunit(nat->ifname);
- if (nat->ifp == NULL) {
- pool_put(&pf_nat_pl, nat);
- error = EINVAL;
- break;
- }
- }
-
- if (pf_dynaddr_setup(&nat->src.addr, nat->af))
- error = EINVAL;
- if (pf_dynaddr_setup(&nat->dst.addr, nat->af))
- error = EINVAL;
- if (error) {
- pf_rm_nat(NULL, nat);
- break;
- }
- pf_mv_pool(&pf_pabuf[0], &nat->rpool.list);
- nat->rpool.cur = TAILQ_FIRST(&nat->rpool.list);
- TAILQ_INSERT_TAIL(ruleset->nats.inactive.ptr, nat, entries);
- break;
- }
-
- case DIOCCOMMITNATS: {
- struct pfioc_nat *pn = (struct pfioc_nat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_natqueue *old_nats;
- struct pf_nat *nat;
-
- ruleset = pf_find_ruleset(pn->anchor, pn->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- if (pn->ticket != ruleset->nats.inactive.ticket) {
- error = EBUSY;
- break;
- }
-
- /* Swap nats, keep the old. */
- s = splsoftnet();
- old_nats = ruleset->nats.active.ptr;
- ruleset->nats.active.ptr = ruleset->nats.inactive.ptr;
- ruleset->nats.inactive.ptr = old_nats;
- ruleset->nats.active.ticket = ruleset->nats.inactive.ticket;
-
- /* Purge the old nat list */
- while ((nat = TAILQ_FIRST(old_nats)) != NULL)
- pf_rm_nat(old_nats, nat);
- pf_remove_if_empty_ruleset(ruleset);
- pf_update_anchor_rules();
- splx(s);
- break;
- }
-
- case DIOCGETNATS: {
- struct pfioc_nat *pn = (struct pfioc_nat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_nat *nat;
-
- ruleset = pf_find_ruleset(pn->anchor, pn->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- pn->nr = 0;
- s = splsoftnet();
- TAILQ_FOREACH(nat, ruleset->nats.active.ptr, entries)
- pn->nr++;
- pn->ticket = ruleset->nats.active.ticket;
- splx(s);
- break;
- }
-
- case DIOCGETNAT: {
- struct pfioc_nat *pn = (struct pfioc_nat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_nat *nat;
- u_int32_t nr;
-
- ruleset = pf_find_ruleset(pn->anchor, pn->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- if (pn->ticket != ruleset->nats.active.ticket) {
- error = EBUSY;
- break;
- }
nr = 0;
- s = splsoftnet();
- nat = TAILQ_FIRST(ruleset->nats.active.ptr);
- while ((nat != NULL) && (nr < pn->nr)) {
- nat = TAILQ_NEXT(nat, entries);
- nr++;
- }
- if (nat == NULL) {
- error = EBUSY;
- splx(s);
- break;
- }
- bcopy(nat, &pn->nat, sizeof(struct pf_nat));
- pf_dynaddr_copyout(&pn->nat.src.addr);
- pf_dynaddr_copyout(&pn->nat.dst.addr);
- splx(s);
- break;
- }
-
- case DIOCCHANGENAT: {
- struct pfioc_changenat *pcn = (struct pfioc_changenat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_nat *oldnat = NULL, *newnat = NULL;
-
- if (pcn->pool_ticket != ticket_pabuf) {
- error = EBUSY;
- break;
- }
-
- if (pcn->action < PF_CHANGE_ADD_HEAD ||
- pcn->action > PF_CHANGE_REMOVE) {
- error = EINVAL;
- break;
- }
- ruleset = pf_find_ruleset(pcn->anchor, pcn->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
-
- if (pcn->action != PF_CHANGE_REMOVE) {
- newnat = pool_get(&pf_nat_pl, PR_NOWAIT);
- if (newnat == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(&pcn->newnat, newnat, sizeof(struct pf_nat));
- TAILQ_INIT(&newnat->rpool.list);
-#ifndef INET
- if (newnat->af == AF_INET) {
- pool_put(&pf_nat_pl, newnat);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET */
-#ifndef INET6
- if (newnat->af == AF_INET6) {
- pool_put(&pf_nat_pl, newnat);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET6 */
- if (newnat->ifname[0]) {
- newnat->ifp = ifunit(newnat->ifname);
- if (newnat->ifp == NULL) {
- pool_put(&pf_nat_pl, newnat);
- error = EINVAL;
- break;
- }
- } else
- newnat->ifp = NULL;
-
- if (pf_dynaddr_setup(&newnat->src.addr, newnat->af))
- error = EINVAL;
- if (pf_dynaddr_setup(&newnat->dst.addr, newnat->af))
- error = EINVAL;
- if (error) {
- pf_rm_nat(NULL, newnat);
- break;
- }
- pf_mv_pool(&pf_pabuf[0], &newnat->rpool.list);
- }
- pf_empty_pool(&pf_pabuf[0]);
-
- s = splsoftnet();
-
- if (pcn->action == PF_CHANGE_ADD_HEAD)
- oldnat = TAILQ_FIRST(ruleset->nats.active.ptr);
- else if (pcn->action == PF_CHANGE_ADD_TAIL)
- oldnat = TAILQ_LAST(ruleset->nats.active.ptr,
- pf_natqueue);
- else {
- pf_mv_pool(&pf_pabuf[1], &pcn->oldnat.rpool.list);
- oldnat = TAILQ_FIRST(ruleset->nats.active.ptr);
- while ((oldnat != NULL) && pf_compare_nats(oldnat,
- &pcn->oldnat))
- oldnat = TAILQ_NEXT(oldnat, entries);
- pf_empty_pool(&pcn->oldnat.rpool.list);
- if (oldnat == NULL) {
- pf_rm_nat(NULL, newnat);
- error = EINVAL;
- splx(s);
- break;
- }
- }
-
- if (pcn->action == PF_CHANGE_REMOVE)
- pf_rm_nat(ruleset->nats.active.ptr, oldnat);
- else {
- if (oldnat == NULL)
- TAILQ_INSERT_TAIL(ruleset->nats.active.ptr,
- newnat, entries);
- else if (pcn->action == PF_CHANGE_ADD_HEAD ||
- pcn->action == PF_CHANGE_ADD_BEFORE)
- TAILQ_INSERT_BEFORE(oldnat, newnat, entries);
- else
- TAILQ_INSERT_AFTER(ruleset->nats.active.ptr,
- oldnat, newnat, entries);
- }
-
- pf_remove_if_empty_ruleset(ruleset);
- pf_update_anchor_rules();
-
- ruleset->nats.active.ticket++;
- splx(s);
- break;
- }
-
- case DIOCBEGINBINATS: {
- struct pfioc_binat *pb = (struct pfioc_binat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_binat *binat;
-
- ruleset = pf_find_or_create_ruleset(pb->anchor, pb->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- while ((binat = TAILQ_FIRST(ruleset->binats.inactive.ptr)) !=
- NULL)
- pf_rm_binat(ruleset->binats.inactive.ptr, binat);
- pb->ticket = ++ruleset->binats.inactive.ticket;
- break;
- }
-
- case DIOCADDBINAT: {
- struct pfioc_binat *pb = (struct pfioc_binat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_binat *binat;
-
- ruleset = pf_find_ruleset(pb->anchor, pb->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- if (pb->binat.anchorname[0] && ruleset != &pf_main_ruleset) {
- error = EINVAL;
- break;
- }
- if (pb->ticket != ruleset->binats.inactive.ticket) {
- error = EBUSY;
- break;
- }
- binat = pool_get(&pf_binat_pl, PR_NOWAIT);
- if (binat == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(&pb->binat, binat, sizeof(struct pf_binat));
- binat->anchor = NULL;
- binat->ifp = NULL;
-#ifndef INET
- if (binat->af == AF_INET) {
- pool_put(&pf_binat_pl, binat);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET */
-#ifndef INET6
- if (binat->af == AF_INET6) {
- pool_put(&pf_binat_pl, binat);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET6 */
- if (binat->ifname[0]) {
- binat->ifp = ifunit(binat->ifname);
- if (binat->ifp == NULL) {
- pool_put(&pf_binat_pl, binat);
- error = EINVAL;
- break;
- }
- }
-
- if (pf_dynaddr_setup(&binat->saddr, binat->af))
- error = EINVAL;
- if (pf_dynaddr_setup(&binat->daddr, binat->af))
- error = EINVAL;
- if (pf_dynaddr_setup(&binat->raddr, binat->af))
- error = EINVAL;
- if (error) {
- pf_rm_binat(NULL, binat);
- break;
- }
- TAILQ_INSERT_TAIL(ruleset->binats.inactive.ptr, binat,
- entries);
- break;
- }
-
- case DIOCCOMMITBINATS: {
- struct pfioc_binat *pb = (struct pfioc_binat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_binatqueue *old_binats;
- struct pf_binat *binat;
-
- ruleset = pf_find_ruleset(pb->anchor, pb->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- if (pb->ticket != ruleset->binats.inactive.ticket) {
- error = EBUSY;
- break;
- }
-
- /* Swap binats, keep the old. */
- s = splsoftnet();
- old_binats = ruleset->binats.active.ptr;
- ruleset->binats.active.ptr = ruleset->binats.inactive.ptr;
- ruleset->binats.inactive.ptr = old_binats;
- ruleset->binats.active.ticket = ruleset->binats.inactive.ticket;
-
- /* Purge the old binat list */
- while ((binat = TAILQ_FIRST(old_binats)) != NULL)
- pf_rm_binat(old_binats, binat);
- pf_remove_if_empty_ruleset(ruleset);
- pf_update_anchor_rules();
- splx(s);
- break;
- }
-
- case DIOCGETBINATS: {
- struct pfioc_binat *pb = (struct pfioc_binat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_binat *binat;
-
- ruleset = pf_find_ruleset(pb->anchor, pb->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- pb->nr = 0;
- s = splsoftnet();
- TAILQ_FOREACH(binat, ruleset->binats.active.ptr, entries)
- pb->nr++;
- pb->ticket = ruleset->binats.active.ticket;
- splx(s);
- break;
- }
-
- case DIOCGETBINAT: {
- struct pfioc_binat *pb = (struct pfioc_binat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_binat *binat;
- u_int32_t nr;
-
- ruleset = pf_find_or_create_ruleset(pb->anchor, pb->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- if (pb->ticket != ruleset->binats.active.ticket) {
- error = EBUSY;
- break;
- }
- nr = 0;
- s = splsoftnet();
- binat = TAILQ_FIRST(ruleset->binats.active.ptr);
- while ((binat != NULL) && (nr < pb->nr)) {
- binat = TAILQ_NEXT(binat, entries);
- nr++;
- }
- if (binat == NULL) {
- error = EBUSY;
- splx(s);
- break;
- }
- bcopy(binat, &pb->binat, sizeof(struct pf_binat));
- pf_dynaddr_copyout(&pb->binat.saddr);
- pf_dynaddr_copyout(&pb->binat.daddr);
- pf_dynaddr_copyout(&pb->binat.raddr);
- splx(s);
- break;
- }
-
- case DIOCCHANGEBINAT: {
- struct pfioc_changebinat *pcn =
- (struct pfioc_changebinat *)addr;
- struct pf_ruleset *ruleset;
- struct pf_binat *oldbinat = NULL, *newbinat = NULL;
-
- if (pcn->action < PF_CHANGE_ADD_HEAD ||
- pcn->action > PF_CHANGE_REMOVE) {
- error = EINVAL;
- break;
- }
- ruleset = pf_find_ruleset(pcn->anchor, pcn->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
-
- if (pcn->action != PF_CHANGE_REMOVE) {
- newbinat = pool_get(&pf_binat_pl, PR_NOWAIT);
- if (newbinat == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(&pcn->newbinat, newbinat,
- sizeof(struct pf_binat));
-#ifndef INET
- if (newbinat->af == AF_INET) {
- pool_put(&pf_binat_pl, newbinat);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET */
-#ifndef INET6
- if (newbinat->af == AF_INET6) {
- pool_put(&pf_binat_pl, newbinat);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET6 */
- if (newbinat->ifname[0]) {
- newbinat->ifp = ifunit(newbinat->ifname);
- if (newbinat->ifp == NULL) {
- pool_put(&pf_binat_pl, newbinat);
- error = EINVAL;
- break;
- }
- } else
- newbinat->ifp = NULL;
- if (pf_dynaddr_setup(&newbinat->saddr, newbinat->af))
- error = EINVAL;
- if (pf_dynaddr_setup(&newbinat->daddr, newbinat->af))
- error = EINVAL;
- if (pf_dynaddr_setup(&newbinat->raddr, newbinat->af))
- error = EINVAL;
- if (error) {
- pf_rm_binat(NULL, newbinat);
- break;
- }
- }
-
- s = splsoftnet();
-
- if (pcn->action == PF_CHANGE_ADD_HEAD)
- oldbinat = TAILQ_FIRST(ruleset->binats.active.ptr);
- else if (pcn->action == PF_CHANGE_ADD_TAIL)
- oldbinat = TAILQ_LAST(ruleset->binats.active.ptr,
- pf_binatqueue);
- else {
- oldbinat = TAILQ_FIRST(ruleset->binats.active.ptr);
- while ((oldbinat != NULL) && pf_compare_binats(oldbinat,
- &pcn->oldbinat))
- oldbinat = TAILQ_NEXT(oldbinat, entries);
- if (oldbinat == NULL) {
- pf_rm_binat(NULL, newbinat);
- error = EINVAL;
- splx(s);
- break;
- }
- }
-
- if (pcn->action == PF_CHANGE_REMOVE)
- pf_rm_binat(ruleset->binats.active.ptr, oldbinat);
- else {
- if (oldbinat == NULL)
- TAILQ_INSERT_TAIL(ruleset->binats.active.ptr,
- newbinat, entries);
- else if (pcn->action == PF_CHANGE_ADD_HEAD ||
- pcn->action == PF_CHANGE_ADD_BEFORE)
- TAILQ_INSERT_BEFORE(oldbinat, newbinat,
- entries);
- else
- TAILQ_INSERT_AFTER(ruleset->binats.active.ptr,
- oldbinat, newbinat, entries);
- }
-
- pf_remove_if_empty_ruleset(ruleset);
- pf_update_anchor_rules();
-
- ruleset->binats.active.ticket++;
- splx(s);
- break;
- }
-
- case DIOCBEGINRDRS: {
- struct pfioc_rdr *pr = (struct pfioc_rdr *)addr;
- struct pf_ruleset *ruleset;
- struct pf_rdr *rdr;
-
- ruleset = pf_find_or_create_ruleset(pr->anchor, pr->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- while ((rdr = TAILQ_FIRST(ruleset->rdrs.inactive.ptr)) !=
- NULL)
- pf_rm_rdr(ruleset->rdrs.inactive.ptr, rdr);
- pr->ticket = ++ruleset->rdrs.inactive.ticket;
- break;
- }
-
- case DIOCADDRDR: {
- struct pfioc_rdr *pr = (struct pfioc_rdr *)addr;
- struct pf_ruleset *ruleset;
- struct pf_rdr *rdr;
-
- ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- if (pr->rdr.anchorname[0] && ruleset != &pf_main_ruleset) {
- error = EINVAL;
- break;
- }
- if (pr->ticket != ruleset->rdrs.inactive.ticket) {
- error = EBUSY;
- break;
- }
- if (pr->pool_ticket != ticket_pabuf) {
- error = EBUSY;
- break;
- }
- rdr = pool_get(&pf_rdr_pl, PR_NOWAIT);
- if (rdr == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(&pr->rdr, rdr, sizeof(struct pf_rdr));
- rdr->anchor = NULL;
- rdr->ifp = NULL;
- TAILQ_INIT(&rdr->rpool.list);
-#ifndef INET
- if (rdr->af == AF_INET) {
- pool_put(&pf_rdr_pl, rdr);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET */
-#ifndef INET6
- if (rdr->af == AF_INET6) {
- pool_put(&pf_rdr_pl, rdr);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET6 */
- if (rdr->ifname[0]) {
- rdr->ifp = ifunit(rdr->ifname);
- if (rdr->ifp == NULL) {
- pool_put(&pf_rdr_pl, rdr);
- error = EINVAL;
- break;
- }
- }
-
- if (pf_dynaddr_setup(&rdr->saddr, rdr->af))
- error = EINVAL;
- if (pf_dynaddr_setup(&rdr->daddr, rdr->af))
- error = EINVAL;
- if (error) {
- pf_rm_rdr(NULL, rdr);
- break;
- }
- pf_mv_pool(&pf_pabuf[0], &rdr->rpool.list);
- rdr->rpool.cur = TAILQ_FIRST(&rdr->rpool.list);
- TAILQ_INSERT_TAIL(ruleset->rdrs.inactive.ptr, rdr, entries);
- break;
- }
-
- case DIOCCOMMITRDRS: {
- struct pfioc_rdr *pr = (struct pfioc_rdr *)addr;
- struct pf_ruleset *ruleset;
- struct pf_rdrqueue *old_rdrs;
- struct pf_rdr *rdr;
-
- ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- if (pr->ticket != ruleset->rdrs.inactive.ticket) {
- error = EBUSY;
- break;
- }
-
- /* Swap rdrs, keep the old. */
- s = splsoftnet();
- old_rdrs = ruleset->rdrs.active.ptr;
- ruleset->rdrs.active.ptr = ruleset->rdrs.inactive.ptr;
- ruleset->rdrs.inactive.ptr = old_rdrs;
- ruleset->rdrs.active.ticket = ruleset->rdrs.inactive.ticket;
-
- /* Purge the old rdr list */
- while ((rdr = TAILQ_FIRST(old_rdrs)) != NULL)
- pf_rm_rdr(old_rdrs, rdr);
- pf_remove_if_empty_ruleset(ruleset);
- pf_update_anchor_rules();
- splx(s);
- break;
- }
-
- case DIOCGETRDRS: {
- struct pfioc_rdr *pr = (struct pfioc_rdr *)addr;
- struct pf_ruleset *ruleset;
- struct pf_rdr *rdr;
-
- ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- pr->nr = 0;
- s = splsoftnet();
- TAILQ_FOREACH(rdr, ruleset->rdrs.active.ptr, entries)
- pr->nr++;
- pr->ticket = ruleset->rdrs.active.ticket;
- splx(s);
- break;
- }
-
- case DIOCGETRDR: {
- struct pfioc_rdr *pr = (struct pfioc_rdr *)addr;
- struct pf_ruleset *ruleset;
- struct pf_rdr *rdr;
- u_int32_t nr;
-
- ruleset = pf_find_ruleset(pr->anchor, pr->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
- if (pr->ticket != ruleset->rdrs.active.ticket) {
- error = EBUSY;
- break;
- }
- nr = 0;
- s = splsoftnet();
- rdr = TAILQ_FIRST(ruleset->rdrs.active.ptr);
- while ((rdr != NULL) && (nr < pr->nr)) {
- rdr = TAILQ_NEXT(rdr, entries);
- nr++;
- }
- if (rdr == NULL) {
- error = EBUSY;
- splx(s);
- break;
- }
- bcopy(rdr, &pr->rdr, sizeof(struct pf_rdr));
- pf_dynaddr_copyout(&pr->rdr.saddr);
- pf_dynaddr_copyout(&pr->rdr.daddr);
- splx(s);
- break;
- }
-
- case DIOCCHANGERDR: {
- struct pfioc_changerdr *pcn = (struct pfioc_changerdr *)addr;
- struct pf_ruleset *ruleset;
- struct pf_rdr *oldrdr = NULL, *newrdr = NULL;
-
- if (pcn->pool_ticket != ticket_pabuf) {
- error = EBUSY;
- break;
- }
-
- if (pcn->action < PF_CHANGE_ADD_HEAD ||
- pcn->action > PF_CHANGE_REMOVE) {
- error = EINVAL;
- break;
- }
- ruleset = pf_find_ruleset(pcn->anchor, pcn->ruleset);
- if (ruleset == NULL) {
- error = EINVAL;
- break;
- }
-
- if (pcn->action != PF_CHANGE_REMOVE) {
- newrdr = pool_get(&pf_rdr_pl, PR_NOWAIT);
- if (newrdr == NULL) {
- error = ENOMEM;
- break;
- }
- bcopy(&pcn->newrdr, newrdr, sizeof(struct pf_rdr));
- TAILQ_INIT(&newrdr->rpool.list);
-#ifndef INET
- if (newrdr->af == AF_INET) {
- pool_put(&pf_rdr_pl, newrdr);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET */
-#ifndef INET6
- if (newrdr->af == AF_INET6) {
- pool_put(&pf_rdr_pl, newrdr);
- error = EAFNOSUPPORT;
- break;
- }
-#endif /* INET6 */
- if (newrdr->ifname[0]) {
- newrdr->ifp = ifunit(newrdr->ifname);
- if (newrdr->ifp == NULL) {
- pool_put(&pf_rdr_pl, newrdr);
- error = EINVAL;
- break;
- }
- } else
- newrdr->ifp = NULL;
-
- if (pf_dynaddr_setup(&newrdr->saddr, newrdr->af))
- error = EINVAL;
- if (pf_dynaddr_setup(&newrdr->daddr, newrdr->af))
- error = EINVAL;
- if (error) {
- pf_rm_rdr(NULL, newrdr);
- break;
- }
- pf_mv_pool(&pf_pabuf[0], &newrdr->rpool.list);
- }
- pf_empty_pool(&pf_pabuf[0]);
-
- s = splsoftnet();
-
- if (pcn->action == PF_CHANGE_ADD_HEAD)
- oldrdr = TAILQ_FIRST(ruleset->rdrs.active.ptr);
- else if (pcn->action == PF_CHANGE_ADD_TAIL)
- oldrdr = TAILQ_LAST(ruleset->rdrs.active.ptr,
- pf_rdrqueue);
- else {
- pf_mv_pool(&pf_pabuf[1], &pcn->oldrdr.rpool.list);
- oldrdr = TAILQ_FIRST(ruleset->rdrs.active.ptr);
- while ((oldrdr != NULL) && pf_compare_rdrs(oldrdr,
- &pcn->oldrdr))
- oldrdr = TAILQ_NEXT(oldrdr, entries);
- pf_empty_pool(&pcn->oldrdr.rpool.list);
- if (oldrdr == NULL) {
- pf_rm_rdr(NULL, newrdr);
- error = EINVAL;
- splx(s);
- break;
- }
- }
-
- if (pcn->action == PF_CHANGE_REMOVE)
- pf_rm_rdr(ruleset->rdrs.active.ptr, oldrdr);
- else {
- if (oldrdr == NULL)
- TAILQ_INSERT_TAIL(ruleset->rdrs.active.ptr,
- newrdr, entries);
- else if (pcn->action == PF_CHANGE_ADD_HEAD ||
- pcn->action == PF_CHANGE_ADD_BEFORE)
- TAILQ_INSERT_BEFORE(oldrdr, newrdr, entries);
- else
- TAILQ_INSERT_AFTER(ruleset->rdrs.active.ptr,
- oldrdr, newrdr, entries);
- }
+ TAILQ_FOREACH(oldrule,
+ ruleset->rules[rs_num].active.ptr, entries)
+ oldrule->nr = nr++;
+ pf_calc_skip_steps(ruleset->rules[rs_num].active.ptr);
pf_remove_if_empty_ruleset(ruleset);
pf_update_anchor_rules();
- ruleset->rdrs.active.ticket++;
+ ruleset->rules[rs_num].active.ticket++;
splx(s);
break;
}
@@ -2220,7 +1133,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pf_rule *rule;
s = splsoftnet();
- TAILQ_FOREACH(rule, ruleset->rules.active.ptr, entries)
+ TAILQ_FOREACH(rule,
+ ruleset->rules[PF_RULESET_RULE].active.ptr, entries)
rule->evaluations = rule->packets =
rule->bytes = 0;
splx(s);
@@ -2486,7 +1400,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
struct pfioc_pooladdr *pp = (struct pfioc_pooladdr *)addr;
pf_empty_pool(&pf_pabuf[1]);
- pf_mv_pool(&pf_pabuf[0], &pf_pabuf[1]);
pp->ticket = ++ticket_pabuf;
break;
}
@@ -2520,8 +1433,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
}
- if (pf_dynaddr_setup(&pa->addr, pp->af)) {
- pf_dynaddr_remove(&pa->addr);
+ if (pf_dynaddr_setup(&pa->addr.addr, pp->af)) {
+ pf_dynaddr_remove(&pa->addr.addr);
pool_put(&pf_pooladdr_pl, pa);
error = EINVAL;
break;
@@ -2537,7 +1450,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
pp->nr = 0;
s = splsoftnet();
pool = pf_get_pool(pp->anchor, pp->ruleset, pp->ticket,
- pp->r_id, pp->r_num, 1, 0);
+ pp->r_action, pp->r_num, 0, 1, 0);
if (pool == NULL) {
error = EBUSY;
splx(s);
@@ -2555,7 +1468,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
s = splsoftnet();
pool = pf_get_pool(pp->anchor, pp->ruleset, pp->ticket,
- pp->r_id, pp->r_num, 1, 1);
+ pp->r_action, pp->r_num, 0, 1, 1);
if (pool == NULL) {
error = EBUSY;
splx(s);
@@ -2572,13 +1485,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
bcopy(pa, &pp->addr, sizeof(struct pf_pooladdr));
- pf_dynaddr_copyout(&pp->addr.addr);
+ pf_dynaddr_copyout(&pp->addr.addr.addr);
splx(s);
break;
}
case DIOCCHANGEADDR: {
- struct pfioc_changeaddr *pca = (struct pfioc_changeaddr *)addr;
+ struct pfioc_pooladdr *pca = (struct pfioc_pooladdr *)addr;
struct pf_pooladdr *oldpa = NULL, *newpa = NULL;
if (pca->action < PF_CHANGE_ADD_HEAD ||
@@ -2588,7 +1501,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
pool = pf_get_pool(pca->anchor, pca->ruleset, 0,
- pca->r_id, pca->r_num, 1, 0);
+ pca->r_action, pca->r_num, pca->r_last, 1, 1);
if (pool == NULL) {
error = EBUSY;
break;
@@ -2599,7 +1512,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
error = ENOMEM;
break;
}
- bcopy(&pca->newaddr, newpa, sizeof(struct pf_pooladdr));
+ bcopy(&pca->addr, newpa, sizeof(struct pf_pooladdr));
#ifndef INET
if (pca->af == AF_INET) {
pool_put(&pf_pooladdr_pl, newpa);
@@ -2623,8 +1536,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
} else
newpa->ifp = NULL;
- if (pf_dynaddr_setup(&newpa->addr, pca->af)) {
- pf_dynaddr_remove(&newpa->addr);
+ if (pf_dynaddr_setup(&newpa->addr.addr, pca->af)) {
+ pf_dynaddr_remove(&newpa->addr.addr);
pool_put(&pf_pooladdr_pl, newpa);
error = EINVAL;
break;
@@ -2638,10 +1551,12 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
else if (pca->action == PF_CHANGE_ADD_TAIL)
oldpa = TAILQ_LAST(&pool->list, pf_palist);
else {
+ int i = 0;
oldpa = TAILQ_FIRST(&pool->list);
- while ((oldpa != NULL) && pf_compare_pooladdrs(oldpa,
- &pca->oldaddr, pca->af))
+ while ((oldpa != NULL) && (i < pca->nr)) {
oldpa = TAILQ_NEXT(oldpa, entries);
+ i++;
+ }
if (oldpa == NULL) {
error = EINVAL;
splx(s);
@@ -2651,7 +1566,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if (pca->action == PF_CHANGE_REMOVE) {
TAILQ_REMOVE(&pool->list, oldpa, entries);
- pf_dynaddr_remove(&oldpa->addr);
+ pf_dynaddr_remove(&oldpa->addr.addr);
pool_put(&pf_pooladdr_pl, oldpa);
} else {
if (oldpa == NULL)
@@ -2665,7 +1580,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
}
pool->cur = TAILQ_FIRST(&pool->list);
- PF_ACPY(&pool->counter, &pool->cur->addr.addr, pca->af);
+ PF_ACPY(&pool->counter, &pool->cur->addr.addr.addr, pca->af);
splx(s);
break;
diff --git a/sys/net/pf_norm.c b/sys/net/pf_norm.c
index e10acfd93f4..5c11e0c1b65 100644
--- a/sys/net/pf_norm.c
+++ b/sys/net/pf_norm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_norm.c,v 1.40 2002/12/06 00:47:32 dhartmei Exp $ */
+/* $OpenBSD: pf_norm.c,v 1.41 2002/12/17 12:30:13 mcbride Exp $ */
/*
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
@@ -799,7 +799,7 @@ pf_normalize_ip(struct mbuf **m0, int dir, struct ifnet *ifp, u_short *reason)
int ip_len;
int ip_off;
- r = TAILQ_FIRST(pf_main_ruleset.rules.active.ptr);
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_RULE].active.ptr);
while (r != NULL) {
if (r->action != PF_SCRUB)
r = r->skip[PF_SKIP_ACTION];
@@ -1000,7 +1000,7 @@ pf_normalize_tcp(int dir, struct ifnet *ifp, struct mbuf *m, int ipoff,
u_int8_t flags;
sa_family_t af = pd->af;
- r = TAILQ_FIRST(pf_main_ruleset.rules.active.ptr);
+ r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_RULE].active.ptr);
while (r != NULL) {
if (r->action != PF_SCRUB)
r = r->skip[PF_SKIP_ACTION];
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index ca6456737ea..3c39a3ada98 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.111 2002/12/16 08:49:22 kjc Exp $ */
+/* $OpenBSD: pfvar.h,v 1.112 2002/12/17 12:30:13 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -38,13 +38,17 @@
#include <sys/tree.h>
enum { PF_IN=1, PF_OUT=2 };
-enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2 };
+enum { PF_PASS=0, PF_DROP=1, PF_SCRUB=2, PF_NAT=3, PF_NONAT=4,
+ PF_BINAT=5, PF_NOBINAT=6, PF_RDR=7, PF_NORDR=8 };
+enum { PF_RULESET_RULE=0, PF_RULESET_NAT=1,
+ PF_RULESET_BINAT=2, PF_RULESET_RDR=3 };
+#define PF_RULESET_MAX PF_RULESET_RDR + 1
enum { PF_OP_IRG=1, PF_OP_EQ=2, PF_OP_NE=3, PF_OP_LT=4,
- PF_OP_LE=5, PF_OP_GT=6, PF_OP_GE=7, PF_OP_XRG=8 };
+ PF_OP_LE=5, PF_OP_GT=6, PF_OP_GE=7, PF_OP_XRG=8, PF_OP_RRG=9 };
enum { PF_DEBUG_NONE=0, PF_DEBUG_URGENT=1, PF_DEBUG_MISC=2 };
enum { PF_CHANGE_ADD_HEAD=1, PF_CHANGE_ADD_TAIL=2,
PF_CHANGE_ADD_BEFORE=3, PF_CHANGE_ADD_AFTER=4,
- PF_CHANGE_REMOVE=5 };
+ PF_CHANGE_REMOVE=5, PF_CHANGE_GET_TICKET=6 };
enum { PFTM_TCP_FIRST_PACKET=0, PFTM_TCP_OPENING=1, PFTM_TCP_ESTABLISHED=2,
PFTM_TCP_CLOSING=3, PFTM_TCP_FIN_WAIT=4, PFTM_TCP_CLOSED=5,
PFTM_UDP_FIRST_PACKET=6, PFTM_UDP_SINGLE=7, PFTM_UDP_MULTIPLE=8,
@@ -53,9 +57,7 @@ enum { PFTM_TCP_FIRST_PACKET=0, PFTM_TCP_OPENING=1, PFTM_TCP_ESTABLISHED=2,
PFTM_OTHER_MULTIPLE=13, PFTM_FRAG=14, PFTM_INTERVAL=15, PFTM_MAX=16 };
enum { PF_FASTROUTE=1, PF_ROUTETO=2, PF_DUPTO=3, PF_REPLYTO=4 };
enum { PF_LIMIT_STATES=0, PF_LIMIT_FRAGS=1, PF_LIMIT_MAX=2 };
-enum { PF_POOL_RULE_RT=0, PF_POOL_NAT_R=1, PF_POOL_RDR_R=2 };
#define PF_POOL_IDMASK 0x0f
-#define PF_POOL_LAST 0x10
enum { PF_POOL_NONE=0, PF_POOL_BITMASK=1, PF_POOL_RANDOM=2,
PF_POOL_SRCHASH=3, PF_POOL_ROUNDROBIN=4 };
#define PF_POOL_TYPEMASK 0x0f
@@ -246,7 +248,7 @@ struct pf_rule_addr {
};
struct pf_pooladdr {
- struct pf_addr_wrap addr;
+ struct pf_rule_addr addr;
TAILQ_ENTRY(pf_pooladdr) entries;
char ifname[IFNAMSIZ];
struct ifnet *ifp;
@@ -270,6 +272,8 @@ struct pf_pool {
struct pf_pooladdr *cur;
struct pf_poolhashkey key;
struct pf_addr counter;
+ u_int16_t proxy_port[2];
+ u_int8_t port_op;
u_int8_t opts;
};
@@ -297,7 +301,7 @@ struct pf_rule {
#define PF_ANCHOR_NAME_SIZE 16
char anchorname[PF_ANCHOR_NAME_SIZE];
TAILQ_ENTRY(pf_rule) entries;
- struct pf_pool rt_pool;
+ struct pf_pool rpool;
u_int64_t evaluations;
u_int64_t packets;
@@ -401,67 +405,7 @@ struct pf_tree_node {
u_int8_t proto;
};
-
-struct pf_nat {
- struct pf_rule_addr src;
- struct pf_rule_addr dst;
- struct pf_pool rpool;
- struct pf_pooladdr *rcur;
- char ifname[IFNAMSIZ];
- char anchorname[PF_ANCHOR_NAME_SIZE];
- struct ifnet *ifp;
- struct pf_anchor *anchor;
- TAILQ_ENTRY(pf_nat) entries;
- u_int32_t rlistid;
- u_int16_t proxy_port[2];
- sa_family_t af;
- u_int8_t proto;
- u_int8_t ifnot;
- u_int8_t no;
-};
-
-struct pf_binat {
- char ifname[IFNAMSIZ];
- char anchorname[PF_ANCHOR_NAME_SIZE];
- struct ifnet *ifp;
- struct pf_anchor *anchor;
- TAILQ_ENTRY(pf_binat) entries;
- struct pf_addr_wrap saddr;
- struct pf_addr_wrap daddr;
- struct pf_addr_wrap raddr;
- sa_family_t af;
- u_int8_t proto;
- u_int8_t dnot;
- u_int8_t no;
-};
-
-struct pf_rdr {
- char ifname[IFNAMSIZ];
- char anchorname[PF_ANCHOR_NAME_SIZE];
- struct ifnet *ifp;
- struct pf_anchor *anchor;
- TAILQ_ENTRY(pf_rdr) entries;
- struct pf_addr_wrap saddr;
- struct pf_addr_wrap daddr;
- struct pf_pool rpool;
- struct pf_pooladdr *rcur;
- u_int32_t rlistid;
- u_int16_t dport;
- u_int16_t dport2;
- u_int16_t rport;
- sa_family_t af;
- u_int8_t proto;
- u_int8_t snot;
- u_int8_t dnot;
- u_int8_t ifnot;
- u_int8_t opts;
- u_int8_t no;
-};
-
TAILQ_HEAD(pf_rulequeue, pf_rule);
-TAILQ_HEAD(pf_natqueue, pf_nat);
-TAILQ_HEAD(pf_binatqueue, pf_binat);
-TAILQ_HEAD(pf_rdrqueue, pf_rdr);
struct pf_anchor;
@@ -475,28 +419,7 @@ struct pf_ruleset {
struct pf_rulequeue *ptr;
u_int32_t ticket;
} active, inactive;
- } rules;
- struct {
- struct pf_natqueue queues[2];
- struct {
- struct pf_natqueue *ptr;
- u_int32_t ticket;
- } active, inactive;
- } nats;
- struct {
- struct pf_rdrqueue queues[2];
- struct {
- struct pf_rdrqueue *ptr;
- u_int32_t ticket;
- } active, inactive;
- } rdrs;
- struct {
- struct pf_binatqueue queues[2];
- struct {
- struct pf_binatqueue *ptr;
- u_int32_t ticket;
- } active, inactive;
- } binats;
+ } rules[4];
struct pf_anchor *anchor;
};
@@ -685,61 +608,26 @@ struct pf_altq {
*/
struct pfioc_pooladdr {
+ u_int32_t action;
u_int32_t ticket;
u_int32_t nr;
u_int32_t r_num;
- u_int8_t r_id;
+ u_int8_t r_action;
+ u_int8_t r_last;
u_int8_t af;
char anchor[PF_ANCHOR_NAME_SIZE];
char ruleset[PF_RULESET_NAME_SIZE];
struct pf_pooladdr addr;
};
-struct pfioc_changeaddr {
- u_int32_t action;
- u_int32_t r_num;
- u_int8_t r_id;
- u_int8_t af;
- char anchor[PF_ANCHOR_NAME_SIZE];
- char ruleset[PF_RULESET_NAME_SIZE];
- struct pf_pooladdr newaddr;
- struct pf_pooladdr oldaddr;
-};
-
struct pfioc_rule {
- u_int32_t ticket;
- u_int32_t pool_ticket;
- u_int32_t nr;
- char anchor[PF_ANCHOR_NAME_SIZE];
- char ruleset[PF_RULESET_NAME_SIZE];
- struct pf_rule rule;
-};
-
-struct pfioc_changerule {
- u_int32_t pool_ticket;
u_int32_t action;
- char anchor[PF_ANCHOR_NAME_SIZE];
- char ruleset[PF_RULESET_NAME_SIZE];
- struct pf_rule oldrule;
- struct pf_rule newrule;
-};
-
-struct pfioc_nat {
u_int32_t ticket;
u_int32_t pool_ticket;
u_int32_t nr;
char anchor[PF_ANCHOR_NAME_SIZE];
char ruleset[PF_RULESET_NAME_SIZE];
- struct pf_nat nat;
-};
-
-struct pfioc_changenat {
- u_int32_t pool_ticket;
- u_int32_t action;
- char anchor[PF_ANCHOR_NAME_SIZE];
- char ruleset[PF_RULESET_NAME_SIZE];
- struct pf_nat oldnat;
- struct pf_nat newnat;
+ struct pf_rule rule;
};
struct pfioc_natlook {
@@ -756,40 +644,6 @@ struct pfioc_natlook {
u_int8_t direction;
};
-struct pfioc_binat {
- u_int32_t ticket;
- u_int32_t nr;
- char anchor[PF_ANCHOR_NAME_SIZE];
- char ruleset[PF_RULESET_NAME_SIZE];
- struct pf_binat binat;
-};
-
-struct pfioc_changebinat {
- u_int32_t action;
- char anchor[PF_ANCHOR_NAME_SIZE];
- char ruleset[PF_RULESET_NAME_SIZE];
- struct pf_binat oldbinat;
- struct pf_binat newbinat;
-};
-
-struct pfioc_rdr {
- u_int32_t ticket;
- u_int32_t pool_ticket;
- u_int32_t nr;
- char anchor[PF_ANCHOR_NAME_SIZE];
- char ruleset[PF_RULESET_NAME_SIZE];
- struct pf_rdr rdr;
-};
-
-struct pfioc_changerdr {
- u_int32_t pool_ticket;
- u_int32_t action;
- char anchor[PF_ANCHOR_NAME_SIZE];
- char ruleset[PF_RULESET_NAME_SIZE];
- struct pf_rdr oldrdr;
- struct pf_rdr newrdr;
-};
-
struct pfioc_state {
u_int32_t nr;
struct pf_state state;
@@ -870,16 +724,7 @@ struct pfioc_ruleset {
#define DIOCCOMMITRULES _IOWR('D', 5, struct pfioc_rule)
#define DIOCGETRULES _IOWR('D', 6, struct pfioc_rule)
#define DIOCGETRULE _IOWR('D', 7, struct pfioc_rule)
-#define DIOCBEGINNATS _IOWR('D', 8, struct pfioc_nat)
-#define DIOCADDNAT _IOWR('D', 9, struct pfioc_nat)
-#define DIOCCOMMITNATS _IOWR('D', 10, struct pfioc_nat)
-#define DIOCGETNATS _IOWR('D', 11, struct pfioc_nat)
-#define DIOCGETNAT _IOWR('D', 12, struct pfioc_nat)
-#define DIOCBEGINRDRS _IOWR('D', 13, struct pfioc_rdr)
-#define DIOCADDRDR _IOWR('D', 14, struct pfioc_rdr)
-#define DIOCCOMMITRDRS _IOWR('D', 15, struct pfioc_rdr)
-#define DIOCGETRDRS _IOWR('D', 16, struct pfioc_rdr)
-#define DIOCGETRDR _IOWR('D', 17, struct pfioc_rdr)
+/* XXX cut 8 - 17 */
#define DIOCCLRSTATES _IO ('D', 18)
#define DIOCGETSTATE _IOWR('D', 19, struct pfioc_state)
#define DIOCSETSTATUSIF _IOWR('D', 20, struct pfioc_if)
@@ -888,17 +733,10 @@ struct pfioc_ruleset {
#define DIOCNATLOOK _IOWR('D', 23, struct pfioc_natlook)
#define DIOCSETDEBUG _IOWR('D', 24, u_int32_t)
#define DIOCGETSTATES _IOWR('D', 25, struct pfioc_states)
-#define DIOCCHANGERULE _IOWR('D', 26, struct pfioc_changerule)
-#define DIOCCHANGENAT _IOWR('D', 27, struct pfioc_changenat)
-#define DIOCCHANGERDR _IOWR('D', 28, struct pfioc_changerdr)
+#define DIOCCHANGERULE _IOWR('D', 26, struct pfioc_rule)
+/* XXX cut 26 - 28 */
#define DIOCSETTIMEOUT _IOWR('D', 29, struct pfioc_tm)
#define DIOCGETTIMEOUT _IOWR('D', 30, struct pfioc_tm)
-#define DIOCBEGINBINATS _IOWR('D', 31, struct pfioc_binat)
-#define DIOCADDBINAT _IOWR('D', 32, struct pfioc_binat)
-#define DIOCCOMMITBINATS _IOWR('D', 33, struct pfioc_binat)
-#define DIOCGETBINATS _IOWR('D', 34, struct pfioc_binat)
-#define DIOCGETBINAT _IOWR('D', 35, struct pfioc_binat)
-#define DIOCCHANGEBINAT _IOWR('D', 36, struct pfioc_changebinat)
#define DIOCADDSTATE _IOWR('D', 37, struct pfioc_state)
#define DIOCCLRRULECTRS _IO ('D', 38)
#define DIOCGETLIMIT _IOWR('D', 39, struct pfioc_limit)
@@ -917,7 +755,7 @@ struct pfioc_ruleset {
#define DIOCADDADDR _IOWR('D', 52, struct pfioc_pooladdr)
#define DIOCGETADDRS _IOWR('D', 53, struct pfioc_pooladdr)
#define DIOCGETADDR _IOWR('D', 54, struct pfioc_pooladdr)
-#define DIOCCHANGEADDR _IOWR('D', 55, struct pfioc_changeaddr)
+#define DIOCCHANGEADDR _IOWR('D', 55, struct pfioc_pooladdr)
#define DIOCGETANCHORS _IOWR('D', 56, struct pfioc_anchor)
#define DIOCGETANCHOR _IOWR('D', 57, struct pfioc_anchor)
#define DIOCGETRULESETS _IOWR('D', 58, struct pfioc_ruleset)
@@ -951,11 +789,8 @@ extern int pf_dynaddr_setup(struct pf_addr_wrap *,
extern void pf_calc_skip_steps(struct pf_rulequeue *);
extern void pf_update_anchor_rules(void);
extern void pf_dynaddr_copyout(struct pf_addr_wrap *);
-extern struct pool pf_tree_pl, pf_rule_pl, pf_nat_pl;
-extern struct pool pf_rdr_pl, pf_state_pl, pf_binat_pl,
- pf_addr_pl;
-extern struct pool pf_altq_pl;
-extern struct pool pf_pooladdr_pl;
+extern struct pool pf_tree_pl, pf_rule_pl, pf_addr_pl;
+extern struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl;
extern void pf_purge_timeout(void *);
extern int pftm_interval;
extern void pf_purge_expired_states(void);