mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +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_
|
||||
#define _BIRD_ROUTE_H_
|
||||
|
||||
#include "lib/idm.h"
|
||||
#include "lib/lists.h"
|
||||
#include "lib/resource.h"
|
||||
#include "lib/timer.h"
|
||||
@ -54,6 +55,7 @@ typedef void (*fib_init_fn)(void *);
|
||||
struct fib {
|
||||
pool *fib_pool; /* Pool holding all our data */
|
||||
slab *fib_slab; /* Slab holding all fib nodes */
|
||||
struct idm *idm; /* ID Map for allocations */
|
||||
struct fib_node **hash_table; /* Node hash table */
|
||||
uint hash_size; /* Number of hash table entries (a power of two) */
|
||||
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];
|
||||
|
||||
if (addr_type == NET_MPLS)
|
||||
{
|
||||
f->idm = mb_alloc(p, sizeof(*f->idm));
|
||||
idm_init(f->idm, p, 64);
|
||||
}
|
||||
if (!hash_order)
|
||||
hash_order = HASH_DEF_ORDER;
|
||||
f->fib_pool = p;
|
||||
@ -238,7 +243,6 @@ static void
|
||||
fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
|
||||
{
|
||||
ASSERT(f->addr_type == a->type);
|
||||
|
||||
switch (f->addr_type)
|
||||
{
|
||||
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
|
||||
@ -264,10 +293,22 @@ fib_insert(struct fib *f, const net_addr *a, struct fib_node *e)
|
||||
void *
|
||||
fib_get(struct fib *f, const net_addr *a)
|
||||
{
|
||||
void *b = fib_find(f, a);
|
||||
if (b)
|
||||
void *b;
|
||||
if (a && (b = fib_find(f, a)))
|
||||
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)
|
||||
b = sl_alloc(f->fib_slab);
|
||||
else
|
||||
@ -426,6 +467,9 @@ fib_delete(struct fib *f, void *E)
|
||||
else
|
||||
mb_free(E);
|
||||
|
||||
if (f->idm)
|
||||
fib_idm_free(f, e);
|
||||
|
||||
if (f->entries-- < f->entries_min)
|
||||
fib_rehash(f, -HASH_LO_STEP);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user