summaryrefslogtreecommitdiffstats
path: root/sys/netpfil
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2016-01-25 06:33:15 +0000
committermelifaro <melifaro@FreeBSD.org>2016-01-25 06:33:15 +0000
commit23582454c7061201dc41b9ab4083ccbefd5dd88c (patch)
treee3d1ff0a530bc18a45f34e089f84583c63d778c7 /sys/netpfil
parent23ee6b6bf28dd68ee75ec7a21424cd765fb32fb4 (diff)
downloadFreeBSD-src-23582454c7061201dc41b9ab4083ccbefd5dd88c.zip
FreeBSD-src-23582454c7061201dc41b9ab4083ccbefd5dd88c.tar.gz
MFP r287070,r287073: split radix implementation and route table structure.
There are number of radix consumers in kernel land (pf,ipfw,nfs,route) with different requirements. In fact, first 3 don't have _any_ requirements and first 2 does not use radix locking. On the other hand, routing structure do have these requirements (rnh_gen, multipath, custom to-be-added control plane functions, different locking). Additionally, radix should not known anything about its consumers internals. So, radix code now uses tiny 'struct radix_head' structure along with internal 'struct radix_mask_head' instead of 'struct radix_node_head'. Existing consumers still uses the same 'struct radix_node_head' with slight modifications: they need to pass pointer to (embedded) 'struct radix_head' to all radix callbacks. Routing code now uses new 'struct rib_head' with different locking macro: RADIX_NODE_HEAD prefix was renamed to RIB_ (which stands for routing information base). New net/route_var.h header was added to hold routing subsystem internal data. 'struct rib_head' was placed there. 'struct rtentry' will also be moved there soon.
Diffstat (limited to 'sys/netpfil')
-rw-r--r--sys/netpfil/ipfw/ip_fw_table_algo.c47
-rw-r--r--sys/netpfil/pf/pf_table.c62
2 files changed, 55 insertions, 54 deletions
diff --git a/sys/netpfil/ipfw/ip_fw_table_algo.c b/sys/netpfil/ipfw/ip_fw_table_algo.c
index 2ce550e..c04ee86 100644
--- a/sys/netpfil/ipfw/ip_fw_table_algo.c
+++ b/sys/netpfil/ipfw/ip_fw_table_algo.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <net/if.h> /* ip_fw.h requires IFNAMSIZ */
#include <net/radix.h>
#include <net/route.h>
+#include <net/route_var.h>
#include <netinet/in.h>
#include <netinet/in_fib.h>
@@ -409,7 +410,7 @@ ta_lookup_radix(struct table_info *ti, void *key, uint32_t keylen,
KEY_LEN(sa) = KEY_LEN_INET;
sa.sin_addr.s_addr = *((in_addr_t *)key);
rnh = (struct radix_node_head *)ti->state;
- ent = (struct radix_addr_entry *)(rnh->rnh_matchaddr(&sa, rnh));
+ ent = (struct radix_addr_entry *)(rnh->rnh_matchaddr(&sa, &rnh->rh));
if (ent != NULL) {
*val = ent->value;
return (1);
@@ -420,7 +421,7 @@ ta_lookup_radix(struct table_info *ti, void *key, uint32_t keylen,
KEY_LEN(sa6) = KEY_LEN_INET6;
memcpy(&sa6.sin6_addr, key, sizeof(struct in6_addr));
rnh = (struct radix_node_head *)ti->xstate;
- xent = (struct radix_addr_xentry *)(rnh->rnh_matchaddr(&sa6, rnh));
+ xent = (struct radix_addr_xentry *)(rnh->rnh_matchaddr(&sa6, &rnh->rh));
if (xent != NULL) {
*val = xent->value;
return (1);
@@ -461,7 +462,7 @@ flush_radix_entry(struct radix_node *rn, void *arg)
struct radix_addr_entry *ent;
ent = (struct radix_addr_entry *)
- rnh->rnh_deladdr(rn->rn_key, rn->rn_mask, rnh);
+ rnh->rnh_deladdr(rn->rn_key, rn->rn_mask, &rnh->rh);
if (ent != NULL)
free(ent, M_IPFW_TBL);
return (0);
@@ -476,11 +477,11 @@ ta_destroy_radix(void *ta_state, struct table_info *ti)
cfg = (struct radix_cfg *)ta_state;
rnh = (struct radix_node_head *)(ti->state);
- rnh->rnh_walktree(rnh, flush_radix_entry, rnh);
+ rnh->rnh_walktree(&rnh->rh, flush_radix_entry, rnh);
rn_detachhead(&ti->state);
rnh = (struct radix_node_head *)(ti->xstate);
- rnh->rnh_walktree(rnh, flush_radix_entry, rnh);
+ rnh->rnh_walktree(&rnh->rh, flush_radix_entry, rnh);
rn_detachhead(&ti->xstate);
free(cfg, M_IPFW);
@@ -548,13 +549,13 @@ ta_find_radix_tentry(void *ta_state, struct table_info *ti,
KEY_LEN(sa) = KEY_LEN_INET;
sa.sin_addr.s_addr = tent->k.addr.s_addr;
rnh = (struct radix_node_head *)ti->state;
- e = rnh->rnh_matchaddr(&sa, rnh);
+ e = rnh->rnh_matchaddr(&sa, &rnh->rh);
} else {
struct sa_in6 sa6;
KEY_LEN(sa6) = KEY_LEN_INET6;
memcpy(&sa6.sin6_addr, &tent->k.addr6, sizeof(struct in6_addr));
rnh = (struct radix_node_head *)ti->xstate;
- e = rnh->rnh_matchaddr(&sa6, rnh);
+ e = rnh->rnh_matchaddr(&sa6, &rnh->rh);
}
if (e != NULL) {
@@ -572,10 +573,10 @@ ta_foreach_radix(void *ta_state, struct table_info *ti, ta_foreach_f *f,
struct radix_node_head *rnh;
rnh = (struct radix_node_head *)(ti->state);
- rnh->rnh_walktree(rnh, (walktree_f_t *)f, arg);
+ rnh->rnh_walktree(&rnh->rh, (walktree_f_t *)f, arg);
rnh = (struct radix_node_head *)(ti->xstate);
- rnh->rnh_walktree(rnh, (walktree_f_t *)f, arg);
+ rnh->rnh_walktree(&rnh->rh, (walktree_f_t *)f, arg);
}
@@ -722,7 +723,7 @@ ta_add_radix(void *ta_state, struct table_info *ti, struct tentry_info *tei,
}
/* Search for an entry first */
- rn = rnh->rnh_lookup(tb->addr_ptr, tb->mask_ptr, rnh);
+ rn = rnh->rnh_lookup(tb->addr_ptr, tb->mask_ptr, &rnh->rh);
if (rn != NULL) {
if ((tei->flags & TEI_FLAGS_UPDATE) == 0)
return (EEXIST);
@@ -746,7 +747,7 @@ ta_add_radix(void *ta_state, struct table_info *ti, struct tentry_info *tei,
if ((tei->flags & TEI_FLAGS_DONTADD) != 0)
return (EFBIG);
- rn = rnh->rnh_addaddr(tb->addr_ptr, tb->mask_ptr, rnh, tb->ent_ptr);
+ rn = rnh->rnh_addaddr(tb->addr_ptr, tb->mask_ptr, &rnh->rh,tb->ent_ptr);
if (rn == NULL) {
/* Unknown error */
return (EINVAL);
@@ -817,7 +818,7 @@ ta_del_radix(void *ta_state, struct table_info *ti, struct tentry_info *tei,
else
rnh = ti->xstate;
- rn = rnh->rnh_deladdr(tb->addr_ptr, tb->mask_ptr, rnh);
+ rn = rnh->rnh_deladdr(tb->addr_ptr, tb->mask_ptr, &rnh->rh);
if (rn == NULL)
return (ENOENT);
@@ -4042,21 +4043,21 @@ static void
ta_foreach_kfib(void *ta_state, struct table_info *ti, ta_foreach_f *f,
void *arg)
{
- struct radix_node_head *rnh;
+ struct rib_head *rh;
int error;
- rnh = rt_tables_get_rnh(ti->data, AF_INET);
- if (rnh != NULL) {
- RADIX_NODE_HEAD_RLOCK(rnh);
- error = rnh->rnh_walktree(rnh, (walktree_f_t *)f, arg);
- RADIX_NODE_HEAD_RUNLOCK(rnh);
+ rh = rt_tables_get_rnh(ti->data, AF_INET);
+ if (rh != NULL) {
+ RIB_RLOCK(rh);
+ error = rh->rnh_walktree(&rh->head, (walktree_f_t *)f, arg);
+ RIB_RUNLOCK(rh);
}
- rnh = rt_tables_get_rnh(ti->data, AF_INET6);
- if (rnh != NULL) {
- RADIX_NODE_HEAD_RLOCK(rnh);
- error = rnh->rnh_walktree(rnh, (walktree_f_t *)f, arg);
- RADIX_NODE_HEAD_RUNLOCK(rnh);
+ rh = rt_tables_get_rnh(ti->data, AF_INET6);
+ if (rh != NULL) {
+ RIB_RLOCK(rh);
+ error = rh->rnh_walktree(&rh->head, (walktree_f_t *)f, arg);
+ RIB_RUNLOCK(rh);
}
}
diff --git a/sys/netpfil/pf/pf_table.c b/sys/netpfil/pf/pf_table.c
index b9f13b9..b9889b9 100644
--- a/sys/netpfil/pf/pf_table.c
+++ b/sys/netpfil/pf/pf_table.c
@@ -559,10 +559,10 @@ pfr_get_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int *size,
w.pfrw_op = PFRW_GET_ADDRS;
w.pfrw_addr = addr;
w.pfrw_free = kt->pfrkt_cnt;
- rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+ rv = kt->pfrkt_ip4->rnh_walktree(&kt->pfrkt_ip4->rh, pfr_walktree, &w);
if (!rv)
- rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
- &w);
+ rv = kt->pfrkt_ip6->rnh_walktree(&kt->pfrkt_ip6->rh,
+ pfr_walktree, &w);
if (rv)
return (rv);
@@ -601,10 +601,10 @@ pfr_get_astats(struct pfr_table *tbl, struct pfr_astats *addr, int *size,
w.pfrw_op = PFRW_GET_ASTATS;
w.pfrw_astats = addr;
w.pfrw_free = kt->pfrkt_cnt;
- rv = kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+ rv = kt->pfrkt_ip4->rnh_walktree(&kt->pfrkt_ip4->rh, pfr_walktree, &w);
if (!rv)
- rv = kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
- &w);
+ rv = kt->pfrkt_ip6->rnh_walktree(&kt->pfrkt_ip6->rh,
+ pfr_walktree, &w);
if (!rv && (flags & PFR_FLAG_CLSTATS)) {
pfr_enqueue_addrs(kt, &workq, NULL, 0);
pfr_clstats_kentries(&workq, tzero, 0);
@@ -710,12 +710,12 @@ pfr_enqueue_addrs(struct pfr_ktable *kt, struct pfr_kentryworkq *workq,
w.pfrw_op = sweep ? PFRW_SWEEP : PFRW_ENQUEUE;
w.pfrw_workq = workq;
if (kt->pfrkt_ip4 != NULL)
- if (kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree,
- &w))
+ if (kt->pfrkt_ip4->rnh_walktree(&kt->pfrkt_ip4->rh,
+ pfr_walktree, &w))
printf("pfr_enqueue_addrs: IPv4 walktree failed.\n");
if (kt->pfrkt_ip6 != NULL)
- if (kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree,
- &w))
+ if (kt->pfrkt_ip6->rnh_walktree(&kt->pfrkt_ip6->rh,
+ pfr_walktree, &w))
printf("pfr_enqueue_addrs: IPv6 walktree failed.\n");
if (naddr != NULL)
*naddr = w.pfrw_cnt;
@@ -728,9 +728,9 @@ pfr_mark_addrs(struct pfr_ktable *kt)
bzero(&w, sizeof(w));
w.pfrw_op = PFRW_MARK;
- if (kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w))
+ if (kt->pfrkt_ip4->rnh_walktree(&kt->pfrkt_ip4->rh, pfr_walktree, &w))
printf("pfr_mark_addrs: IPv4 walktree failed.\n");
- if (kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w))
+ if (kt->pfrkt_ip6->rnh_walktree(&kt->pfrkt_ip6->rh, pfr_walktree, &w))
printf("pfr_mark_addrs: IPv6 walktree failed.\n");
}
@@ -739,7 +739,7 @@ static struct pfr_kentry *
pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
{
union sockaddr_union sa, mask;
- struct radix_node_head *head = NULL;
+ struct radix_head *head = NULL;
struct pfr_kentry *ke;
PF_RULES_ASSERT();
@@ -747,10 +747,10 @@ pfr_lookup_addr(struct pfr_ktable *kt, struct pfr_addr *ad, int exact)
bzero(&sa, sizeof(sa));
if (ad->pfra_af == AF_INET) {
FILLIN_SIN(sa.sin, ad->pfra_ip4addr);
- head = kt->pfrkt_ip4;
+ head = &kt->pfrkt_ip4->rh;
} else if ( ad->pfra_af == AF_INET6 ) {
FILLIN_SIN6(sa.sin6, ad->pfra_ip6addr);
- head = kt->pfrkt_ip6;
+ head = &kt->pfrkt_ip6->rh;
}
if (ADDR_NETWORK(ad)) {
pfr_prepare_network(&mask, ad->pfra_af, ad->pfra_net);
@@ -929,15 +929,15 @@ pfr_route_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
{
union sockaddr_union mask;
struct radix_node *rn;
- struct radix_node_head *head = NULL;
+ struct radix_head *head = NULL;
PF_RULES_WASSERT();
bzero(ke->pfrke_node, sizeof(ke->pfrke_node));
if (ke->pfrke_af == AF_INET)
- head = kt->pfrkt_ip4;
+ head = &kt->pfrkt_ip4->rh;
else if (ke->pfrke_af == AF_INET6)
- head = kt->pfrkt_ip6;
+ head = &kt->pfrkt_ip6->rh;
if (KENTRY_NETWORK(ke)) {
pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
@@ -953,12 +953,12 @@ pfr_unroute_kentry(struct pfr_ktable *kt, struct pfr_kentry *ke)
{
union sockaddr_union mask;
struct radix_node *rn;
- struct radix_node_head *head = NULL;
+ struct radix_head *head = NULL;
if (ke->pfrke_af == AF_INET)
- head = kt->pfrkt_ip4;
+ head = &kt->pfrkt_ip4->rh;
else if (ke->pfrke_af == AF_INET6)
- head = kt->pfrkt_ip6;
+ head = &kt->pfrkt_ip6->rh;
if (KENTRY_NETWORK(ke)) {
pfr_prepare_network(&mask, ke->pfrke_af, ke->pfrke_net);
@@ -1907,7 +1907,7 @@ pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
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);
+ ke = (struct pfr_kentry *)rn_match(&sin, &kt->pfrkt_ip4->rh);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
@@ -1922,7 +1922,7 @@ pfr_match_addr(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af)
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);
+ ke = (struct pfr_kentry *)rn_match(&sin6, &kt->pfrkt_ip6->rh);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
@@ -1958,7 +1958,7 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
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);
+ ke = (struct pfr_kentry *)rn_match(&sin, &kt->pfrkt_ip4->rh);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
@@ -1973,7 +1973,7 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
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);
+ ke = (struct pfr_kentry *)rn_match(&sin6, &kt->pfrkt_ip6->rh);
if (ke && KENTRY_RNF_ROOT(ke))
ke = NULL;
break;
@@ -2120,11 +2120,11 @@ _next_block:
switch (af) {
case AF_INET:
ke2 = (struct pfr_kentry *)rn_match(&uaddr,
- kt->pfrkt_ip4);
+ &kt->pfrkt_ip4->rh);
break;
case AF_INET6:
ke2 = (struct pfr_kentry *)rn_match(&uaddr,
- kt->pfrkt_ip6);
+ &kt->pfrkt_ip6->rh);
break;
}
/* no need to check KENTRY_RNF_ROOT() here */
@@ -2162,12 +2162,12 @@ pfr_kentry_byidx(struct pfr_ktable *kt, int idx, int af)
switch (af) {
#ifdef INET
case AF_INET:
- kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+ kt->pfrkt_ip4->rnh_walktree(&kt->pfrkt_ip4->rh, pfr_walktree, &w);
return (w.pfrw_kentry);
#endif /* INET */
#ifdef INET6
case AF_INET6:
- kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
+ kt->pfrkt_ip6->rnh_walktree(&kt->pfrkt_ip6->rh, pfr_walktree, &w);
return (w.pfrw_kentry);
#endif /* INET6 */
default:
@@ -2187,7 +2187,7 @@ pfr_dynaddr_update(struct pfr_ktable *kt, struct pfi_dynaddr *dyn)
dyn->pfid_acnt4 = 0;
dyn->pfid_acnt6 = 0;
if (!dyn->pfid_af || dyn->pfid_af == AF_INET)
- kt->pfrkt_ip4->rnh_walktree(kt->pfrkt_ip4, pfr_walktree, &w);
+ kt->pfrkt_ip4->rnh_walktree(&kt->pfrkt_ip4->rh, pfr_walktree, &w);
if (!dyn->pfid_af || dyn->pfid_af == AF_INET6)
- kt->pfrkt_ip6->rnh_walktree(kt->pfrkt_ip6, pfr_walktree, &w);
+ kt->pfrkt_ip6->rnh_walktree(&kt->pfrkt_ip6->rh, pfr_walktree, &w);
}
OpenPOWER on IntegriCloud