diff options
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/pf_lb.c | 15 | ||||
-rw-r--r-- | sys/net/pf_table.c | 12 | ||||
-rw-r--r-- | sys/net/pfvar.h | 4 |
3 files changed, 23 insertions, 8 deletions
diff --git a/sys/net/pf_lb.c b/sys/net/pf_lb.c index b80ac0da564..3eb1a6c1ebd 100644 --- a/sys/net/pf_lb.c +++ b/sys/net/pf_lb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_lb.c,v 1.13 2010/06/27 01:39:43 henning Exp $ */ +/* $OpenBSD: pf_lb.c,v 1.14 2011/05/17 12:44:05 mikeb Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -103,6 +103,7 @@ void pf_hash(struct pf_addr *, struct pf_addr *, int pf_get_sport(struct pf_pdesc *, struct pf_rule *, struct pf_addr *, u_int16_t *, u_int16_t, u_int16_t, struct pf_src_node **); +int pf_islinklocal(sa_family_t, struct pf_addr *); #define mix(a,b,c) \ do { \ @@ -264,6 +265,14 @@ pf_get_sport(struct pf_pdesc *pd, struct pf_rule *r, } int +pf_islinklocal(sa_family_t af, struct pf_addr *addr) +{ + if (af == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&addr->v6)) + return (1); + return (0); +} + +int pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr, struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_src_node **sns, struct pf_pool *rpool, enum pf_sn_types type) @@ -383,12 +392,12 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr, if (rpool->addr.type == PF_ADDR_TABLE) { if (pfr_pool_get(rpool->addr.p.tbl, &rpool->tblidx, &rpool->counter, - &raddr, &rmask, &rpool->kif, af)) + &raddr, &rmask, &rpool->kif, af, NULL)) return (1); } else if (rpool->addr.type == PF_ADDR_DYNIFTL) { if (pfr_pool_get(rpool->addr.p.dyn->pfid_kt, &rpool->tblidx, &rpool->counter, - &raddr, &rmask, &rpool->kif, af)) + &raddr, &rmask, &rpool->kif, af, pf_islinklocal)) return (1); } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af)) return (1); diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c index ab56c8d5ece..59e4db6252d 100644 --- a/sys/net/pf_table.c +++ b/sys/net/pf_table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_table.c,v 1.88 2010/11/20 23:58:13 tedu Exp $ */ +/* $OpenBSD: pf_table.c,v 1.89 2011/05/17 12:44:05 mikeb Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -2109,7 +2109,7 @@ pfr_detach_table(struct pfr_ktable *kt) int pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter, struct pf_addr **raddr, struct pf_addr **rmask, struct pfi_kif **kif, - sa_family_t af) + sa_family_t af, int (*filter)(sa_family_t, struct pf_addr *)) { struct pfr_kentry *ke, *ke2; struct pf_addr *addr; @@ -2163,6 +2163,10 @@ _next_block: if (!KENTRY_NETWORK(ke)) { /* this is a single IP address - no possible nested block */ + if (filter && filter(af, addr)) { + idx++; + goto _next_block; + } PF_ACPY(counter, addr, af); *pidx = idx; kt->pfrkt_match++; @@ -2181,6 +2185,8 @@ _next_block: /* no need to check KENTRY_RNF_ROOT() here */ if (ke2 == ke) { /* lookup return the same block - perfect */ + if (filter && filter(af, addr)) + goto _next_entry; PF_ACPY(counter, addr, af); *pidx = idx; kt->pfrkt_match++; @@ -2188,7 +2194,7 @@ _next_block: *kif = ((struct pfr_kentry_route *)ke)->kif; return (0); } - +_next_entry: /* we need to increase the counter past the nested block */ pfr_prepare_network(&mask, AF_INET, ke2->pfrke_net); PF_POOLMASK(addr, addr, SUNION2PF(&mask, af), &pfr_ffaddr, af); diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index b10e21f0156..0024b3d489f 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.329 2011/04/23 10:00:36 bluhm Exp $ */ +/* $OpenBSD: pfvar.h,v 1.330 2011/05/17 12:44:05 mikeb Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1812,7 +1812,7 @@ void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t, u_int64_t, int, int, int); int pfr_pool_get(struct pfr_ktable *, int *, struct pf_addr *, struct pf_addr **, struct pf_addr **, struct pfi_kif **, - sa_family_t); + sa_family_t, int (*)(sa_family_t, struct pf_addr *)); void pfr_dynaddr_update(struct pfr_ktable *, struct pfi_dynaddr *); struct pfr_ktable * pfr_attach_table(struct pf_ruleset *, char *, int); |