Split radix implementation and system route table structure:
use new 'struct radix_head' for radix.
This commit is contained in:
parent
389d731d64
commit
22b08fd8b7
@ -56,15 +56,16 @@
|
||||
#include <net/radix.h>
|
||||
#endif /* !_KERNEL */
|
||||
|
||||
static int rn_walktree_from(struct radix_node_head *h, void *a, void *m,
|
||||
static int rn_walktree_from(struct radix_head *h, void *a, void *m,
|
||||
walktree_f_t *f, void *w);
|
||||
static int rn_walktree(struct radix_node_head *, walktree_f_t *, void *);
|
||||
static int rn_walktree(struct radix_head *, walktree_f_t *, void *);
|
||||
static struct radix_node
|
||||
*rn_insert(void *, struct radix_node_head *, int *,
|
||||
*rn_insert(void *, struct radix_head *, int *,
|
||||
struct radix_node [2]),
|
||||
*rn_newpair(void *, int, struct radix_node[2]),
|
||||
*rn_search(void *, struct radix_node *),
|
||||
*rn_search_m(void *, struct radix_node *, void *);
|
||||
static struct radix_node *rn_addmask(void *, struct radix_head *, int, int);
|
||||
|
||||
static void rn_detachhead_internal(void **head);
|
||||
static int rn_inithead_internal(void **head, int off);
|
||||
@ -215,7 +216,7 @@ rn_refines(void *m_arg, void *n_arg)
|
||||
* from host routes.
|
||||
*/
|
||||
struct radix_node *
|
||||
rn_lookup(void *v_arg, void *m_arg, struct radix_node_head *head)
|
||||
rn_lookup(void *v_arg, void *m_arg, struct radix_head *head)
|
||||
{
|
||||
struct radix_node *x;
|
||||
caddr_t netmask;
|
||||
@ -277,7 +278,7 @@ rn_satisfies_leaf(char *trial, struct radix_node *leaf, int skip)
|
||||
* Search for longest-prefix match in given @head
|
||||
*/
|
||||
struct radix_node *
|
||||
rn_match(void *v_arg, struct radix_node_head *head)
|
||||
rn_match(void *v_arg, struct radix_head *head)
|
||||
{
|
||||
caddr_t v = v_arg;
|
||||
struct radix_node *t = head->rnh_treetop, *x;
|
||||
@ -426,7 +427,7 @@ rn_newpair(void *v, int b, struct radix_node nodes[2])
|
||||
}
|
||||
|
||||
static struct radix_node *
|
||||
rn_insert(void *v_arg, struct radix_node_head *head, int *dupentry,
|
||||
rn_insert(void *v_arg, struct radix_head *head, int *dupentry,
|
||||
struct radix_node nodes[2])
|
||||
{
|
||||
caddr_t v = v_arg;
|
||||
@ -489,8 +490,9 @@ rn_insert(void *v_arg, struct radix_node_head *head, int *dupentry,
|
||||
return (tt);
|
||||
}
|
||||
|
||||
/* XXX: Convert mask tree to hash */
|
||||
struct radix_node *
|
||||
rn_addmask(void *n_arg, struct radix_node_head *maskhead, int search, int skip)
|
||||
rn_addmask(void *n_arg, struct radix_head *maskhead, int search, int skip)
|
||||
{
|
||||
unsigned char *netmask = n_arg;
|
||||
unsigned char *cp, *cplim;
|
||||
@ -505,7 +507,7 @@ rn_addmask(void *n_arg, struct radix_node_head *maskhead, int search, int skip)
|
||||
if (skip == 0)
|
||||
skip = 1;
|
||||
if (mlen <= skip)
|
||||
return (maskhead->rnh_nodes);
|
||||
return (((struct radix_node_head *)maskhead)->rnh_nodes);
|
||||
|
||||
bzero(addmask_key, RADIX_MAX_KEY_LEN);
|
||||
if (skip > 1)
|
||||
@ -518,7 +520,7 @@ rn_addmask(void *n_arg, struct radix_node_head *maskhead, int search, int skip)
|
||||
cp--;
|
||||
mlen = cp - addmask_key;
|
||||
if (mlen <= skip)
|
||||
return (maskhead->rnh_nodes);
|
||||
return (((struct radix_node_head *)maskhead)->rnh_nodes);
|
||||
*addmask_key = mlen;
|
||||
x = rn_search(addmask_key, maskhead->rnh_treetop);
|
||||
if (bcmp(addmask_key, x->rn_key, mlen) != 0)
|
||||
@ -598,7 +600,7 @@ rn_new_radix_mask(struct radix_node *tt, struct radix_mask *next)
|
||||
}
|
||||
|
||||
struct radix_node *
|
||||
rn_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
|
||||
rn_addroute(void *v_arg, void *n_arg, struct radix_head *head,
|
||||
struct radix_node treenodes[2])
|
||||
{
|
||||
caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
|
||||
@ -772,7 +774,7 @@ rn_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
|
||||
}
|
||||
|
||||
struct radix_node *
|
||||
rn_delete(void *v_arg, void *netmask_arg, struct radix_node_head *head)
|
||||
rn_delete(void *v_arg, void *netmask_arg, struct radix_head *head)
|
||||
{
|
||||
struct radix_node *t, *p, *x, *tt;
|
||||
struct radix_mask *m, *saved_m, **mp;
|
||||
@ -960,7 +962,7 @@ rn_delete(void *v_arg, void *netmask_arg, struct radix_node_head *head)
|
||||
* exit.
|
||||
*/
|
||||
static int
|
||||
rn_walktree_from(struct radix_node_head *h, void *a, void *m,
|
||||
rn_walktree_from(struct radix_head *h, void *a, void *m,
|
||||
walktree_f_t *f, void *w)
|
||||
{
|
||||
int error;
|
||||
@ -1066,7 +1068,7 @@ rn_walktree_from(struct radix_node_head *h, void *a, void *m,
|
||||
}
|
||||
|
||||
static int
|
||||
rn_walktree(struct radix_node_head *h, walktree_f_t *f, void *w)
|
||||
rn_walktree(struct radix_head *h, walktree_f_t *f, void *w)
|
||||
{
|
||||
int error;
|
||||
struct radix_node *base, *next;
|
||||
@ -1132,13 +1134,13 @@ rn_inithead_internal(void **head, int off)
|
||||
tt->rn_bit = -1 - off;
|
||||
*ttt = *tt;
|
||||
ttt->rn_key = rn_ones;
|
||||
rnh->rnh_addaddr = rn_addroute;
|
||||
rnh->rnh_deladdr = rn_delete;
|
||||
rnh->rnh_matchaddr = rn_match;
|
||||
rnh->rnh_lookup = rn_lookup;
|
||||
rnh->rnh_walktree = rn_walktree;
|
||||
rnh->rnh_walktree_from = rn_walktree_from;
|
||||
rnh->rnh_treetop = t;
|
||||
rnh->rnh_addaddr = (rn_addaddr_f_t *)rn_addroute;
|
||||
rnh->rnh_deladdr = (rn_deladdr_f_t *)rn_delete;
|
||||
rnh->rnh_matchaddr = (rn_matchaddr_f_t *)rn_match;
|
||||
rnh->rnh_lookup = (rn_lookup_f_t *)rn_lookup;
|
||||
rnh->rnh_walktree = (rn_walktree_t *)rn_walktree;
|
||||
rnh->rnh_walktree_from = (rn_walktree_from_t *)rn_walktree_from;
|
||||
rnh->rh.rnh_treetop = t;
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -1170,7 +1172,7 @@ rn_inithead(void **head, int off)
|
||||
|
||||
rnh = (struct radix_node_head *)(*head);
|
||||
|
||||
if (rn_inithead_internal((void **)&rnh->rnh_masks, 0) == 0) {
|
||||
if (rn_inithead_internal((void **)&rnh->rh.rnh_masks, 0) == 0) {
|
||||
rn_detachhead_internal(head);
|
||||
return (0);
|
||||
}
|
||||
@ -1181,7 +1183,7 @@ rn_inithead(void **head, int off)
|
||||
static int
|
||||
rn_freeentry(struct radix_node *rn, void *arg)
|
||||
{
|
||||
struct radix_node_head * const rnh = arg;
|
||||
struct radix_head * const rnh = arg;
|
||||
struct radix_node *x;
|
||||
|
||||
x = (struct radix_node *)rn_delete(rn + 2, NULL, rnh);
|
||||
@ -1200,8 +1202,8 @@ rn_detachhead(void **head)
|
||||
|
||||
rnh = *head;
|
||||
|
||||
rn_walktree(rnh->rnh_masks, rn_freeentry, rnh->rnh_masks);
|
||||
rn_detachhead_internal((void **)&rnh->rnh_masks);
|
||||
rn_walktree(rnh->rh.rnh_masks, rn_freeentry, rnh->rh.rnh_masks);
|
||||
rn_detachhead_internal((void **)&rnh->rh.rnh_masks);
|
||||
rn_detachhead_internal(head);
|
||||
return (1);
|
||||
}
|
||||
|
@ -118,10 +118,13 @@ typedef int rn_walktree_from_t(struct radix_node_head *head,
|
||||
void *a, void *m, walktree_f_t *f, void *w);
|
||||
typedef void rn_close_t(struct radix_node *rn, struct radix_node_head *head);
|
||||
|
||||
struct radix_head {
|
||||
struct radix_node *rnh_treetop;
|
||||
struct radix_head *rnh_masks; /* Storage for our masks */
|
||||
};
|
||||
|
||||
struct radix_node_head {
|
||||
struct radix_node *rnh_treetop;
|
||||
struct radix_node_head *rnh_masks; /* Storage for our masks */
|
||||
struct radix_head rh;
|
||||
u_int rnh_gen; /* generation counter */
|
||||
int rnh_multipath; /* multipath capable ? */
|
||||
rn_matchaddr_f_t *rnh_matchaddr; /* longest match for sockaddr */
|
||||
@ -163,13 +166,11 @@ struct radix_node_head {
|
||||
int rn_inithead(void **, int);
|
||||
int rn_detachhead(void **);
|
||||
int rn_refines(void *, void *);
|
||||
struct radix_node
|
||||
*rn_addmask(void *, struct radix_node_head *, int, int),
|
||||
*rn_addroute (void *, void *, struct radix_node_head *,
|
||||
struct radix_node [2]),
|
||||
*rn_delete(void *, void *, struct radix_node_head *),
|
||||
*rn_lookup (void *v_arg, void *m_arg,
|
||||
struct radix_node_head *head),
|
||||
*rn_match(void *, struct radix_node_head *);
|
||||
struct radix_node *rn_addroute (void *, void *, struct radix_head *,
|
||||
struct radix_node [2]);
|
||||
struct radix_node *rn_delete(void *, void *, struct radix_head *);
|
||||
struct radix_node *rn_lookup (void *v_arg, void *m_arg,
|
||||
struct radix_head *head);
|
||||
struct radix_node *rn_match(void *, struct radix_head *);
|
||||
|
||||
#endif /* _RADIX_H_ */
|
||||
|
@ -98,7 +98,7 @@ in_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
|
||||
if (rt->rt_mtu == 0 && rt->rt_ifp != NULL)
|
||||
rt->rt_mtu = rt->rt_ifp->if_mtu;
|
||||
|
||||
return (rn_addroute(v_arg, n_arg, head, treenodes));
|
||||
return (rn_addroute(v_arg, n_arg, &head->rh, treenodes));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -109,7 +109,7 @@ in_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
|
||||
static struct radix_node *
|
||||
in_matroute(void *v_arg, struct radix_node_head *head)
|
||||
{
|
||||
struct radix_node *rn = rn_match(v_arg, head);
|
||||
struct radix_node *rn = rn_match(v_arg, &head->rh);
|
||||
struct rtentry *rt = (struct rtentry *)rn;
|
||||
|
||||
if (rt) {
|
||||
@ -330,7 +330,8 @@ void
|
||||
in_setmatchfunc(struct radix_node_head *rnh, int val)
|
||||
{
|
||||
|
||||
rnh->rnh_matchaddr = (val != 0) ? rn_match : in_matroute;
|
||||
rnh->rnh_matchaddr = (val != 0) ?
|
||||
(rn_matchaddr_f_t *)rn_match : in_matroute;
|
||||
}
|
||||
|
||||
static int _in_rt_was_here;
|
||||
|
@ -140,7 +140,7 @@ in6_addroute(void *v_arg, void *n_arg, struct radix_node_head *head,
|
||||
if (!rt->rt_mtu && rt->rt_ifp)
|
||||
rt->rt_mtu = IN6_LINKMTU(rt->rt_ifp);
|
||||
|
||||
ret = rn_addroute(v_arg, n_arg, head, treenodes);
|
||||
ret = rn_addroute(v_arg, n_arg, &head->rh, treenodes);
|
||||
if (ret == NULL) {
|
||||
struct rtentry *rt2;
|
||||
/*
|
||||
|
@ -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 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter,
|
||||
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 */
|
||||
|
Loading…
Reference in New Issue
Block a user