diff options
author | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2002-12-17 12:30:14 +0000 |
---|---|---|
committer | Ryan Thomas McBride <mcbride@cvs.openbsd.org> | 2002-12-17 12:30:14 +0000 |
commit | 12659caaaa187bfb87d1b80b80544d0efe9d32d9 (patch) | |
tree | 98046872610eb696ff8cb314d21fba0db75a3a74 /sys/net | |
parent | 97c718358eb70e8053558830745f3801e2591c94 (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.c | 658 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 1419 | ||||
-rw-r--r-- | sys/net/pf_norm.c | 6 | ||||
-rw-r--r-- | sys/net/pfvar.h | 211 |
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); |