mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-23 02:01:55 +00:00
FIB: Added label allocation option
Why is this inside FIB and not at some layer before? Simply only this layer knows whether fib_get() just returns an existing record or inserts a new one.
This commit is contained in:
parent
160239d523
commit
6adf16ca1b
@ -9,6 +9,7 @@
|
|||||||
#ifndef _BIRD_ROUTE_H_
|
#ifndef _BIRD_ROUTE_H_
|
||||||
#define _BIRD_ROUTE_H_
|
#define _BIRD_ROUTE_H_
|
||||||
|
|
||||||
|
#include "lib/idm.h"
|
||||||
#include "lib/lists.h"
|
#include "lib/lists.h"
|
||||||
#include "lib/resource.h"
|
#include "lib/resource.h"
|
||||||
#include "lib/timer.h"
|
#include "lib/timer.h"
|
||||||
@ -54,6 +55,7 @@ typedef void (*fib_init_fn)(void *);
|
|||||||
struct fib {
|
struct fib {
|
||||||
pool *fib_pool; /* Pool holding all our data */
|
pool *fib_pool; /* Pool holding all our data */
|
||||||
slab *fib_slab; /* Slab holding all fib nodes */
|
slab *fib_slab; /* Slab holding all fib nodes */
|
||||||
|
struct idm *idm; /* ID Map for allocations */
|
||||||
struct fib_node **hash_table; /* Node hash table */
|
struct fib_node **hash_table; /* Node hash table */
|
||||||
uint hash_size; /* Number of hash table entries (a power of two) */
|
uint hash_size; /* Number of hash table entries (a power of two) */
|
||||||
uint hash_order; /* Binary logarithm of hash_size */
|
uint hash_order; /* Binary logarithm of hash_size */
|
||||||
|
@ -95,6 +95,11 @@ fib_init(struct fib *f, pool *p, uint addr_type, uint node_size, uint node_offse
|
|||||||
{
|
{
|
||||||
uint addr_length = net_addr_length[addr_type];
|
uint addr_length = net_addr_length[addr_type];
|
||||||
|
|
||||||
|
if (addr_type == NET_MPLS)
|
||||||
|
{
|
||||||
|
f->idm = mb_alloc(p, sizeof(*f->idm));
|
||||||
|
idm_init(f->idm, p, 64);
|
||||||
|
}
|
||||||
if (!hash_order)
|
if (!hash_order)
|
||||||
hash_order = HASH_DEF_ORDER;
|
hash_order = HASH_DEF_ORDER;
|
||||||
f->fib_pool = p;
|
f->fib_pool = p;
|
||||||
@ -238,7 +243,6 @@ static void
|
|||||||
fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
|
fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
|
||||||
{
|
{
|
||||||
ASSERT(f->addr_type == a->type);
|
ASSERT(f->addr_type == a->type);
|
||||||
|
|
||||||
switch (f->addr_type)
|
switch (f->addr_type)
|
||||||
{
|
{
|
||||||
case NET_IP4: FIB_INSERT(f, a, e, ip4); return;
|
case NET_IP4: FIB_INSERT(f, a, e, ip4); return;
|
||||||
@ -252,6 +256,31 @@ fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
net_addr * const fib_idm_alloc(struct fib *f, const net_addr *a)
|
||||||
|
{
|
||||||
|
ASSERT(f->idm && (f->addr_type == NET_MPLS));
|
||||||
|
|
||||||
|
u32 label;
|
||||||
|
if (a)
|
||||||
|
label = idm_alloc(f->idm, ((net_addr_mpls *)a)->label, ((net_addr_mpls *)a)->label);
|
||||||
|
else
|
||||||
|
label = idm_alloc(f->idm, 16, (1<<20)-1);
|
||||||
|
|
||||||
|
if (!label)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
static net_addr_union nu;
|
||||||
|
net_fill_mpls(&nu.n, label);
|
||||||
|
return &nu.n;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fib_idm_free(struct fib *f, struct fib_node *e)
|
||||||
|
{
|
||||||
|
ASSERT(f->idm);
|
||||||
|
|
||||||
|
u32 label = ((net_addr_mpls *)e->addr)->label;
|
||||||
|
idm_free(f->idm, label);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fib_get - find or create a FIB node
|
* fib_get - find or create a FIB node
|
||||||
@ -264,10 +293,22 @@ fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
|
|||||||
void *
|
void *
|
||||||
fib_get(struct fib *f, const net_addr *a)
|
fib_get(struct fib *f, const net_addr *a)
|
||||||
{
|
{
|
||||||
void *b = fib_find(f, a);
|
void *b;
|
||||||
if (b)
|
if (a && (b = fib_find(f, a)))
|
||||||
return b;
|
return b;
|
||||||
|
|
||||||
|
ASSERT(a || f->idm);
|
||||||
|
if (f->idm)
|
||||||
|
{
|
||||||
|
const net_addr *ag = fib_idm_alloc(f, a);
|
||||||
|
if (!ag)
|
||||||
|
{
|
||||||
|
ASSERT(!a);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
a = ag;
|
||||||
|
}
|
||||||
|
|
||||||
if (f->fib_slab)
|
if (f->fib_slab)
|
||||||
b = sl_alloc(f->fib_slab);
|
b = sl_alloc(f->fib_slab);
|
||||||
else
|
else
|
||||||
@ -426,6 +467,9 @@ fib_delete(struct fib *f, void *E)
|
|||||||
else
|
else
|
||||||
mb_free(E);
|
mb_free(E);
|
||||||
|
|
||||||
|
if (f->idm)
|
||||||
|
fib_idm_free(f, e);
|
||||||
|
|
||||||
if (f->entries-- < f->entries_min)
|
if (f->entries-- < f->entries_min)
|
||||||
fib_rehash(f, -HASH_LO_STEP);
|
fib_rehash(f, -HASH_LO_STEP);
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user