diff options
author | Cedric Berger <cedric@cvs.openbsd.org> | 2003-08-09 14:56:49 +0000 |
---|---|---|
committer | Cedric Berger <cedric@cvs.openbsd.org> | 2003-08-09 14:56:49 +0000 |
commit | b7323c0ae2f827695d5f116067f71a7ad66431e4 (patch) | |
tree | f6ecc8a86c5cf9a94655c88ee236f4c7979d31bf /sys/net/pf.c | |
parent | 0876dde502ec6049eb887678ab0a3bad64d94127 (diff) |
This patch remove the restriction that tables cannot be used in routing or
redirection rules...
The advantage of using tables in redirection/routing rules is not efficiency,
in fact it will run slower than straight address pools. However, this brings
a lot of flexibility to PF, allowing simple scripts/daemons to add/remove
addresses from redirection/routing pools easily.
This implementation support all table features, including cidr blocks and
negated addresses. So specifying { 10.0.0.0/29 !10.0.0.0 !10.0.0.7 } will
correctly round-robin between the six addresses: .1, .2, .3, .4, .5, .6.
Tables can also be combined with simple addresses, so the following rule
will work as expected: "nat on foo0 -> { 1.1.1.1 <bar> }"
ok henning@ mcbride@
Diffstat (limited to 'sys/net/pf.c')
-rw-r--r-- | sys/net/pf.c | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c index 9a1554da4a5..01c1d371d97 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.381 2003/08/07 14:20:50 henning Exp $ */ +/* $OpenBSD: pf.c,v 1.382 2003/08/09 14:56:48 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -176,13 +176,6 @@ struct pf_tag *pf_get_tag(struct mbuf *); int pf_match_tag(struct mbuf *, struct pf_rule *, struct pf_rule *, struct pf_rule *, struct pf_tag *, int *); - -#ifdef INET6 -void pf_poolmask(struct pf_addr *, struct pf_addr*, - struct pf_addr *, struct pf_addr *, u_int8_t); -void pf_addr_inc(struct pf_addr *, sa_family_t); -#endif /* INET6 */ - void pf_hash(struct pf_addr *, struct pf_addr *, struct pf_poolhashkey *, sa_family_t); int pf_map_addr(u_int8_t, struct pf_pool *, @@ -1573,15 +1566,22 @@ pf_map_addr(u_int8_t af, struct pf_pool *rpool, struct pf_addr *saddr, struct pf_addr *naddr, struct pf_addr *init_addr) { unsigned char hash[16]; - struct pf_addr *raddr = &rpool->cur->addr.v.a.addr; - struct pf_addr *rmask = &rpool->cur->addr.v.a.mask; + struct pf_addr *raddr; + struct pf_addr *rmask; + struct pf_pooladdr *acur = rpool->cur; - if (rpool->cur->addr.type == PF_ADDR_NOROUTE || - rpool->cur->addr.type == PF_ADDR_TABLE) + if (rpool->cur->addr.type == PF_ADDR_NOROUTE) return (1); if (rpool->cur->addr.type == PF_ADDR_DYNIFTL && rpool->cur->addr.p.dyn->undefined) return (1); + if (rpool->cur->addr.type == PF_ADDR_TABLE) { + if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN) + return (1); /* unsupported */ + } else { + raddr = &rpool->cur->addr.v.a.addr; + rmask = &rpool->cur->addr.v.a.mask; + } switch (rpool->opts & PF_POOL_TYPEMASK) { case PF_POOL_NONE: @@ -1630,19 +1630,36 @@ 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, &rpool->cur->addr.v.a.addr, - &rpool->cur->addr.v.a.mask, &rpool->counter, af)) { - PF_ACPY(naddr, &rpool->counter, af); - PF_AINC(&rpool->counter, af); + if (rpool->cur->addr.type == PF_ADDR_TABLE) { + if (!pfr_pool_get(rpool->cur->addr.p.tbl, + &rpool->tblidx, &rpool->counter, + &raddr, &rmask, af)) + goto get_addr; + } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af)) + goto get_addr; + + try_next: + if ((rpool->cur = TAILQ_NEXT(rpool->cur, entries)) == NULL) + rpool->cur = TAILQ_FIRST(&rpool->list); + if (rpool->cur->addr.type == PF_ADDR_TABLE) { + rpool->tblidx = -1; + if (pfr_pool_get(rpool->cur->addr.p.tbl, + &rpool->tblidx, &rpool->counter, + &raddr, &rmask, af)) { + /* table contain no address of type 'af' */ + if (rpool->cur != acur) + goto try_next; + return (1); + } } else { - if ((rpool->cur = - TAILQ_NEXT(rpool->cur, entries)) == NULL) - rpool->cur = TAILQ_FIRST(&rpool->list); - PF_ACPY(naddr, &rpool->cur->addr.v.a.addr, af); - PF_ACPY(&rpool->counter, - &rpool->cur->addr.v.a.addr, af); - PF_AINC(&rpool->counter, af); + raddr = &rpool->cur->addr.v.a.addr; + rmask = &rpool->cur->addr.v.a.mask; + PF_ACPY(&rpool->counter, raddr, af); } + + get_addr: + PF_ACPY(naddr, &rpool->counter, af); + PF_AINC(&rpool->counter, af); break; } |