svn commit: r236397 - projects/pf/head/sys/contrib/pf/net
Gleb Smirnoff
glebius at FreeBSD.org
Fri Jun 1 13:37:19 UTC 2012
Author: glebius
Date: Fri Jun 1 13:37:19 2012
New Revision: 236397
URL: http://svn.freebsd.org/changeset/base/236397
Log:
Make pf table code more re-entrant:
- kill global V_pfr_sin, V_pfr_sin6, V_pfr_mask which are used in some
functions and use instead structure on stack.
- pfr_ffaddr can be initialized statically and doesn't need V
Make pfr_pool_get() more smp-safe (not yet really safe, but better):
- Don't pass raddr and rmask from pf_map_addr() to
pfr_pool_get(), and thus do not modify pools cur.
- Use on stack sockaddr_union instead of global.
Modified:
projects/pf/head/sys/contrib/pf/net/pf_ioctl.c
projects/pf/head/sys/contrib/pf/net/pf_lb.c
projects/pf/head/sys/contrib/pf/net/pf_table.c
projects/pf/head/sys/contrib/pf/net/pfvar.h
Modified: projects/pf/head/sys/contrib/pf/net/pf_ioctl.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf_ioctl.c Fri Jun 1 13:21:32 2012 (r236396)
+++ projects/pf/head/sys/contrib/pf/net/pf_ioctl.c Fri Jun 1 13:37:19 2012 (r236397)
@@ -252,7 +252,6 @@ pfattach(void)
int error;
pf_initialize();
- pfr_initialize();
pfi_initialize();
pf_osfp_initialize();
pf_normalize_init();
Modified: projects/pf/head/sys/contrib/pf/net/pf_lb.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf_lb.c Fri Jun 1 13:21:32 2012 (r236396)
+++ projects/pf/head/sys/contrib/pf/net/pf_lb.c Fri Jun 1 13:37:19 2012 (r236397)
@@ -458,13 +458,11 @@ pf_map_addr(sa_family_t af, struct pf_ru
case PF_POOL_ROUNDROBIN:
if (rpool->cur->addr.type == PF_ADDR_TABLE) {
if (!pfr_pool_get(rpool->cur->addr.p.tbl,
- &rpool->tblidx, &rpool->counter,
- &raddr, &rmask, af))
+ &rpool->tblidx, &rpool->counter, af))
goto get_addr;
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
if (!pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
- &rpool->tblidx, &rpool->counter,
- &raddr, &rmask, af))
+ &rpool->tblidx, &rpool->counter, af))
goto get_addr;
} else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
goto get_addr;
@@ -475,8 +473,7 @@ pf_map_addr(sa_family_t af, struct pf_ru
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)) {
+ &rpool->tblidx, &rpool->counter, af)) {
/* table contains no address of type 'af' */
if (rpool->cur != acur)
goto try_next;
@@ -485,8 +482,7 @@ pf_map_addr(sa_family_t af, struct pf_ru
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
rpool->tblidx = -1;
if (pfr_pool_get(rpool->cur->addr.p.dyn->pfid_kt,
- &rpool->tblidx, &rpool->counter,
- &raddr, &rmask, af)) {
+ &rpool->tblidx, &rpool->counter, af)) {
/* table contains no address of type 'af' */
if (rpool->cur != acur)
goto try_next;
Modified: projects/pf/head/sys/contrib/pf/net/pf_table.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf_table.c Fri Jun 1 13:21:32 2012 (r236396)
+++ projects/pf/head/sys/contrib/pf/net/pf_table.c Fri Jun 1 13:37:19 2012 (r236397)
@@ -122,14 +122,10 @@ VNET_DEFINE(uma_zone_t, pfr_ktable_z);
VNET_DEFINE(uma_zone_t, pfr_kentry_z);
VNET_DEFINE(uma_zone_t, pfr_kcounters_z);
#define V_pfr_kcounters_z VNET(pfr_kcounters_z)
-VNET_DEFINE(struct sockaddr_in, pfr_sin);
-#define V_pfr_sin VNET(pfr_sin)
-VNET_DEFINE(struct sockaddr_in6, pfr_sin6);
-#define V_pfr_sin6 VNET(pfr_sin6)
-VNET_DEFINE(union sockaddr_union, pfr_mask);
-#define V_pfr_mask VNET(pfr_mask)
-VNET_DEFINE(struct pf_addr, pfr_ffaddr);
-#define V_pfr_ffaddr VNET(pfr_ffaddr)
+
+static struct pf_addr pfr_ffaddr = {
+ .addr32 = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }
+};
static void pfr_copyout_addr(struct pfr_addr *,
struct pfr_kentry *ke);
@@ -189,17 +185,6 @@ struct pfr_ktablehead pfr_ktables;
struct pfr_table pfr_nulltable;
int pfr_ktable_cnt;
-void
-pfr_initialize(void)
-{
- V_pfr_sin.sin_len = sizeof(V_pfr_sin);
- V_pfr_sin.sin_family = AF_INET;
- V_pfr_sin6.sin6_len = sizeof(V_pfr_sin6);
- V_pfr_sin6.sin6_family = AF_INET6;
-
- memset(&V_pfr_ffaddr, 0xff, sizeof(V_pfr_ffaddr));
-}
-
int
pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags)
{
@@ -1029,24 +1014,28 @@ pfr_walktree(struct radix_node *rn, void
}
break;
case PFRW_DYNADDR_UPDATE:
+ {
+ union sockaddr_union pfr_mask;
+
if (ke->pfrke_af == AF_INET) {
if (w->pfrw_dyn->pfid_acnt4++ > 0)
break;
- pfr_prepare_network(&V_pfr_mask, AF_INET, ke->pfrke_net);
- w->pfrw_dyn->pfid_addr4 = *SUNION2PF(
- &ke->pfrke_sa, AF_INET);
- w->pfrw_dyn->pfid_mask4 = *SUNION2PF(
- &V_pfr_mask, AF_INET);
+ pfr_prepare_network(&pfr_mask, AF_INET, ke->pfrke_net);
+ w->pfrw_dyn->pfid_addr4 = *SUNION2PF(&ke->pfrke_sa,
+ AF_INET);
+ w->pfrw_dyn->pfid_mask4 = *SUNION2PF(&pfr_mask,
+ AF_INET);
} else if (ke->pfrke_af == AF_INET6){
if (w->pfrw_dyn->pfid_acnt6++ > 0)
break;
- pfr_prepare_network(&V_pfr_mask, AF_INET6, ke->pfrke_net);
- w->pfrw_dyn->pfid_addr6 = *SUNION2PF(
- &ke->pfrke_sa, AF_INET6);
- w->pfrw_dyn->pfid_mask6 = *SUNION2PF(
- &V_pfr_mask, AF_INET6);
+ pfr_prepare_network(&pfr_mask, AF_INET6, ke->pfrke_net);
+ w->pfrw_dyn->pfid_addr6 = *SUNION2PF(&ke->pfrke_sa,
+ AF_INET6);
+ w->pfrw_dyn->pfid_mask6 = *SUNION2PF(&pfr_mask,
+ AF_INET6);
}
break;
+ }
}
return (0);
}
@@ -1886,19 +1875,31 @@ pfr_match_addr(struct pfr_ktable *kt, st
switch (af) {
#ifdef INET
case AF_INET:
- V_pfr_sin.sin_addr.s_addr = a->addr32[0];
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin, kt->pfrkt_ip4);
+ {
+ struct sockaddr_in sin;
+
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = a->addr32[0];
+ ke = (struct pfr_kentry *)rn_match(&sin, kt->pfrkt_ip4);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
+ }
#endif /* INET */
#ifdef INET6
case AF_INET6:
- bcopy(a, &V_pfr_sin6.sin6_addr, sizeof(V_pfr_sin6.sin6_addr));
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin6, kt->pfrkt_ip6);
+ {
+ struct sockaddr_in6 sin6;
+
+ sin6.sin6_len = sizeof(sin6);
+ sin6.sin6_family = AF_INET6;
+ bcopy(a, &sin6.sin6_addr, sizeof(sin6.sin6_addr));
+ ke = (struct pfr_kentry *)rn_match(&sin6, kt->pfrkt_ip6);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
+ }
#endif /* INET6 */
}
match = (ke && !ke->pfrke_not);
@@ -1923,19 +1924,31 @@ pfr_update_stats(struct pfr_ktable *kt,
switch (af) {
#ifdef INET
case AF_INET:
- V_pfr_sin.sin_addr.s_addr = a->addr32[0];
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin, kt->pfrkt_ip4);
+ {
+ struct sockaddr_in sin;
+
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = a->addr32[0];
+ ke = (struct pfr_kentry *)rn_match(&sin, kt->pfrkt_ip4);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
+ }
#endif /* INET */
#ifdef INET6
case AF_INET6:
- bcopy(a, &V_pfr_sin6.sin6_addr, sizeof(V_pfr_sin6.sin6_addr));
- ke = (struct pfr_kentry *)rn_match(&V_pfr_sin6, kt->pfrkt_ip6);
+ {
+ struct sockaddr_in6 sin6;
+
+ sin6.sin6_len = sizeof(sin6);
+ sin6.sin6_family = AF_INET6;
+ bcopy(a, &sin6.sin6_addr, sizeof(sin6.sin6_addr));
+ ke = (struct pfr_kentry *)rn_match(&sin6, kt->pfrkt_ip6);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
+ }
#endif /* INET6 */
default:
;
@@ -2011,17 +2024,25 @@ 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, sa_family_t af)
+ sa_family_t af)
{
+ struct pf_addr *addr, *cur, *mask;
+ union sockaddr_union uaddr, umask;
struct pfr_kentry *ke, *ke2 = NULL;
- struct pf_addr *addr = NULL;
- union sockaddr_union mask;
int idx = -1, use_counter = 0;
- if (af == AF_INET)
- addr = (struct pf_addr *)&V_pfr_sin.sin_addr;
- else if (af == AF_INET6)
- addr = (struct pf_addr *)&V_pfr_sin6.sin6_addr;
+ switch (af) {
+ case AF_INET:
+ uaddr.sin.sin_len = sizeof(struct sockaddr_in);
+ uaddr.sin.sin_family = AF_INET;
+ break;
+ case AF_INET6:
+ uaddr.sin6.sin6_len = sizeof(struct sockaddr_in6);
+ uaddr.sin6.sin6_family = AF_INET6;
+ break;
+ }
+ addr = SUNION2PF(&uaddr, af);
+
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)
kt = kt->pfrkt_root;
if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE))
@@ -2040,13 +2061,13 @@ _next_block:
kt->pfrkt_nomatch++;
return (1);
}
- pfr_prepare_network(&V_pfr_mask, af, ke->pfrke_net);
- *raddr = SUNION2PF(&ke->pfrke_sa, af);
- *rmask = SUNION2PF(&V_pfr_mask, af);
+ pfr_prepare_network(&umask, af, ke->pfrke_net);
+ cur = SUNION2PF(&ke->pfrke_sa, af);
+ mask = SUNION2PF(&umask, af);
if (use_counter) {
/* is supplied address within block? */
- if (!PF_MATCHA(0, *raddr, *rmask, counter, af)) {
+ if (!PF_MATCHA(0, cur, mask, counter, af)) {
/* no, go to next block in table */
idx++;
use_counter = 0;
@@ -2055,7 +2076,7 @@ _next_block:
PF_ACPY(addr, counter, af);
} else {
/* use first address of block */
- PF_ACPY(addr, *raddr, af);
+ PF_ACPY(addr, cur, af);
}
if (!KENTRY_NETWORK(ke)) {
@@ -2067,12 +2088,16 @@ _next_block:
}
for (;;) {
/* we don't want to use a nested block */
- if (af == AF_INET)
- ke2 = (struct pfr_kentry *)rn_match(&V_pfr_sin,
+ switch (af) {
+ case AF_INET:
+ ke2 = (struct pfr_kentry *)rn_match(&uaddr,
kt->pfrkt_ip4);
- else if (af == AF_INET6)
- ke2 = (struct pfr_kentry *)rn_match(&V_pfr_sin6,
+ break;
+ case AF_INET6:
+ ke2 = (struct pfr_kentry *)rn_match(&uaddr,
kt->pfrkt_ip6);
+ break;
+ }
/* no need to check KENTRY_RNF_ROOT() here */
if (ke2 == ke) {
/* lookup return the same block - perfect */
@@ -2083,10 +2108,10 @@ _next_block:
}
/* 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), &V_pfr_ffaddr, af);
+ pfr_prepare_network(&umask, AF_INET, ke2->pfrke_net);
+ PF_POOLMASK(addr, addr, SUNION2PF(&umask, af), &pfr_ffaddr, af);
PF_AINC(addr, af);
- if (!PF_MATCHA(0, *raddr, *rmask, addr, af)) {
+ if (!PF_MATCHA(0, cur, mask, addr, af)) {
/* ok, we reached the end of our main block */
/* go to next block in table */
idx++;
Modified: projects/pf/head/sys/contrib/pf/net/pfvar.h
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pfvar.h Fri Jun 1 13:21:32 2012 (r236396)
+++ projects/pf/head/sys/contrib/pf/net/pfvar.h Fri Jun 1 13:37:19 2012 (r236397)
@@ -1868,12 +1868,10 @@ int pf_routable(struct pf_addr *addr, sa
int);
int pf_socket_lookup(int, struct pf_pdesc *);
struct pf_state_key *pf_alloc_state_key(int);
-void pfr_initialize(void);
int pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t);
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 **, sa_family_t);
+int pfr_pool_get(struct pfr_ktable *, int *, struct pf_addr *, sa_family_t);
void pfr_dynaddr_update(struct pfr_ktable *, struct pfi_dynaddr *);
struct pfr_ktable *
pfr_attach_table(struct pf_ruleset *, char *);
More information about the svn-src-projects
mailing list