summaryrefslogtreecommitdiff
path: root/sys/net/pf.c
diff options
context:
space:
mode:
authorCedric Berger <cedric@cvs.openbsd.org>2003-08-09 14:56:49 +0000
committerCedric Berger <cedric@cvs.openbsd.org>2003-08-09 14:56:49 +0000
commitb7323c0ae2f827695d5f116067f71a7ad66431e4 (patch)
treef6ecc8a86c5cf9a94655c88ee236f4c7979d31bf /sys/net/pf.c
parent0876dde502ec6049eb887678ab0a3bad64d94127 (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.c63
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;
}