Nest: Reimplement fib_route() and add some consts

This commit is contained in:
Ondrej Zajicek (work) 2015-12-20 18:16:48 +01:00
parent 29a6416276
commit 0f7d5b1a88
2 changed files with 70 additions and 50 deletions

View file

@ -66,9 +66,9 @@ struct fib {
}; };
void fib_init(struct fib *f, pool *p, uint addr_type, uint node_size, uint node_offset, uint hash_order, fib_init_fn init); void fib_init(struct fib *f, pool *p, uint addr_type, uint node_size, uint node_offset, uint hash_order, fib_init_fn init);
void *fib_find(struct fib *, net_addr *); /* Find or return NULL if doesn't exist */ void *fib_find(struct fib *, const net_addr *); /* Find or return NULL if doesn't exist */
void *fib_get(struct fib *, net_addr *); /* Find or create new if nonexistent */ void *fib_get(struct fib *, const net_addr *); /* Find or create new if nonexistent */
void *fib_route(struct fib *, net_addr *); /* Longest-match routing lookup */ void *fib_route(struct fib *, const net_addr *); /* Longest-match routing lookup */
void fib_delete(struct fib *, void *); /* Remove fib entry */ void fib_delete(struct fib *, void *); /* Remove fib entry */
void fib_free(struct fib *); /* Destroy the fib */ void fib_free(struct fib *); /* Destroy the fib */
void fib_check(struct fib *); /* Consistency check for debugging */ void fib_check(struct fib *); /* Consistency check for debugging */

View file

@ -81,7 +81,7 @@ fib_ht_free(struct fib_node **h)
static u32 static u32
fib_hash(struct fib *f, net_addr *a); fib_hash(struct fib *f, const net_addr *a);
/** /**
* fib_init - initialize a new FIB * fib_init - initialize a new FIB
@ -158,7 +158,8 @@ fib_rehash(struct fib *f, int step)
fib_ht_free(m); fib_ht_free(m);
} }
#define CAST(t) (net_addr_##t *) #define CAST(t) (const net_addr_##t *)
#define CAST2(t) (net_addr_##t *)
#define FIB_HASH(f,a,t) (net_hash_##t(CAST(t) a) >> f->hash_shift) #define FIB_HASH(f,a,t) (net_hash_##t(CAST(t) a) >> f->hash_shift)
@ -179,14 +180,14 @@ fib_rehash(struct fib *f, int step)
while ((g = *ee) && (net_hash_##t(CAST(t) g->addr) < h)) \ while ((g = *ee) && (net_hash_##t(CAST(t) g->addr) < h)) \
ee = &g->next; \ ee = &g->next; \
\ \
net_copy_##t(CAST(t) e->addr, CAST(t) a); \ net_copy_##t(CAST2(t) e->addr, CAST(t) a); \
e->next = *ee; \ e->next = *ee; \
*ee = e; \ *ee = e; \
}) })
static u32 static u32
fib_hash(struct fib *f, net_addr *a) fib_hash(struct fib *f, const net_addr *a)
{ {
switch (f->addr_type) switch (f->addr_type)
{ {
@ -198,8 +199,16 @@ fib_hash(struct fib *f, net_addr *a)
} }
} }
/**
* fib_find - search for FIB node by prefix
* @f: FIB to search in
* @n: network address
*
* Search for a FIB node corresponding to the given prefix, return
* a pointer to it or %NULL if no such node exists.
*/
void * void *
fib_find(struct fib *f, net_addr *a) fib_find(struct fib *f, const net_addr *a)
{ {
ASSERT(f->addr_type == a->type); ASSERT(f->addr_type == a->type);
@ -214,7 +223,7 @@ fib_find(struct fib *f, net_addr *a)
} }
static void static void
fib_insert(struct fib *f, net_addr *a, struct fib_node *e) fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
{ {
switch (f->addr_type) switch (f->addr_type)
{ {
@ -227,39 +236,16 @@ fib_insert(struct fib *f, net_addr *a, struct fib_node *e)
} }
/**
* fib_find - search for FIB node by prefix
* @f: FIB to search in
* @a: pointer to IP address of the prefix
* @len: prefix length
*
* Search for a FIB node corresponding to the given prefix, return
* a pointer to it or %NULL if no such node exists.
*/
/*
void *
fib_find(struct fib *f, net_addr *a)
{
struct fib_node *e = f->hash_table[fib_hash(f, a)];
while (e && (e->pxlen != len || !ipa_equal(*a, e->prefix)))
e = e->next;
return e;
}
*/
/** /**
* fib_get - find or create a FIB node * fib_get - find or create a FIB node
* @f: FIB to work with * @f: FIB to work with
* @a: pointer to IP address of the prefix * @n: network address
* @len: prefix length
* *
* Search for a FIB node corresponding to the given prefix and * Search for a FIB node corresponding to the given prefix and
* return a pointer to it. If no such node exists, create it. * return a pointer to it. If no such node exists, create it.
*/ */
void * void *
fib_get(struct fib *f, net_addr *a) fib_get(struct fib *f, const net_addr *a)
{ {
char *b = fib_find(f, a); char *b = fib_find(f, a);
if (b) if (b)
@ -286,34 +272,68 @@ fib_get(struct fib *f, net_addr *a)
return b; return b;
} }
static void *
fib_route_ip4(struct fib *f, const net_addr *n0)
{
net_addr net;
net_addr_ip4 *n = (net_addr_ip4 *) &net;
void *b;
net_copy(&net, n0);
while (!(b = fib_find(f, &net)) && (n->pxlen > 0))
{
n->pxlen--;
ip4_clrbit(&n->prefix, n->pxlen);
}
return b;
}
static void *
fib_route_ip6(struct fib *f, const net_addr *n0)
{
net_addr net;
net_addr_ip6 *n = (net_addr_ip6 *) &net;
void *b;
net_copy(&net, n0);
while (!(b = fib_find(f, &net)) && (n->pxlen > 0))
{
n->pxlen--;
ip6_clrbit(&n->prefix, n->pxlen);
}
return b;
}
/** /**
* fib_route - CIDR routing lookup * fib_route - CIDR routing lookup
* @f: FIB to search in * @f: FIB to search in
* @a: pointer to IP address of the prefix * @n: network address
* @len: prefix length
* *
* Search for a FIB node with longest prefix matching the given * Search for a FIB node with longest prefix matching the given
* network, that is a node which a CIDR router would use for routing * network, that is a node which a CIDR router would use for routing
* that network. * that network.
*/ */
/*
void * void *
fib_route(struct fib *f, ip_addr a, int len) fib_route(struct fib *f, const net_addr *n)
{ {
ip_addr a0; ASSERT(f->addr_type == n->type);
void *t;
while (len >= 0) switch (n->type)
{ {
a0 = ipa_and(a, ipa_mkmask(len)); case NET_IP4:
t = fib_find(f, &a0, len); case NET_VPN4:
if (t) return fib_route_ip4(f, n);
return t;
len--; case NET_IP6:
} case NET_VPN6:
return fib_route_ip6(f, n);
default:
return NULL; return NULL;
}
} }
*/
static inline void static inline void
fib_merge_readers(struct fib_iterator *i, struct fib_node *to) fib_merge_readers(struct fib_iterator *i, struct fib_node *to)