Move ID allocator to a separate file and use it also in OSPF
This commit is contained in:
parent
9a70c8d6c3
commit
74c838a870
11 changed files with 126 additions and 71 deletions
|
@ -7,8 +7,10 @@ sha1.h
|
|||
birdlib.h
|
||||
bitops.c
|
||||
bitops.h
|
||||
ip.h
|
||||
idm.c
|
||||
idm.h
|
||||
ip.c
|
||||
ip.h
|
||||
lists.c
|
||||
lists.h
|
||||
md5.c
|
||||
|
|
76
lib/idm.c
Normal file
76
lib/idm.c
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* BIRD Library -- ID Map
|
||||
*
|
||||
* (c) 2013--2015 Ondrej Zajicek <santiago@crfreenet.org>
|
||||
* (c) 2013--2015 CZ.NIC z.s.p.o.
|
||||
*
|
||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nest/bird.h"
|
||||
#include "lib/idm.h"
|
||||
#include "lib/resource.h"
|
||||
#include "lib/string.h"
|
||||
|
||||
|
||||
void
|
||||
idm_init(struct idm *m, pool *p, uint size)
|
||||
{
|
||||
m->pos = 0;
|
||||
m->used = 1;
|
||||
m->size = size;
|
||||
m->data = mb_allocz(p, m->size * sizeof(u32));
|
||||
|
||||
/* ID 0 is reserved */
|
||||
m->data[0] = 1;
|
||||
}
|
||||
|
||||
static inline int u32_cto(uint x) { return ffs(~x) - 1; }
|
||||
|
||||
u32
|
||||
idm_alloc(struct idm *m)
|
||||
{
|
||||
uint i, j;
|
||||
|
||||
for (i = m->pos; i < m->size; i++)
|
||||
if (m->data[i] != 0xffffffff)
|
||||
goto found;
|
||||
|
||||
/* If we are at least 7/8 full, expand */
|
||||
if (m->used > (m->size * 28))
|
||||
{
|
||||
m->size *= 2;
|
||||
m->data = mb_realloc(m->data, m->size * sizeof(u32));
|
||||
memset(m->data + i, 0, (m->size - i) * sizeof(u32));
|
||||
goto found;
|
||||
}
|
||||
|
||||
for (i = 0; i < m->pos; i++)
|
||||
if (m->data[i] != 0xffffffff)
|
||||
goto found;
|
||||
|
||||
ASSERT(0);
|
||||
|
||||
found:
|
||||
ASSERT(i < 0x8000000);
|
||||
|
||||
m->pos = i;
|
||||
j = u32_cto(m->data[i]);
|
||||
|
||||
m->data[i] |= (1 << j);
|
||||
m->used++;
|
||||
return 32 * i + j;
|
||||
}
|
||||
|
||||
void
|
||||
idm_free(struct idm *m, u32 id)
|
||||
{
|
||||
uint i = id / 32;
|
||||
uint j = id % 32;
|
||||
|
||||
ASSERT((i < m->size) && (m->data[i] & (1 << j)));
|
||||
m->data[i] &= ~(1 << j);
|
||||
m->used--;
|
||||
}
|
25
lib/idm.h
Normal file
25
lib/idm.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* BIRD Library -- ID Map
|
||||
*
|
||||
* (c) 2013--2015 Ondrej Zajicek <santiago@crfreenet.org>
|
||||
* (c) 2013--2015 CZ.NIC z.s.p.o.
|
||||
*
|
||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||
*/
|
||||
|
||||
#ifndef _BIRD_IDM_H_
|
||||
#define _BIRD_IDM_H_
|
||||
|
||||
struct idm
|
||||
{
|
||||
u32 *data;
|
||||
u32 pos;
|
||||
u32 used;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
void idm_init(struct idm *m, pool *p, uint size);
|
||||
u32 idm_alloc(struct idm *m);
|
||||
void idm_free(struct idm *m, u32 id);
|
||||
|
||||
#endif
|
|
@ -36,7 +36,6 @@ struct fib_node {
|
|||
struct fib_node *next; /* Next in hash chain */
|
||||
struct fib_iterator *readers; /* List of readers of this node */
|
||||
byte flags; /* User-defined, will be removed */
|
||||
u32 uid; /* Unique ID based on hash, will be removed */
|
||||
net_addr addr[0];
|
||||
};
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nest/attrs.h"
|
||||
#include "lib/alloca.h"
|
||||
#include "lib/hash.h"
|
||||
#include "lib/idm.h"
|
||||
#include "lib/resource.h"
|
||||
#include "lib/string.h"
|
||||
|
||||
|
@ -61,9 +62,7 @@ static slab *rta_slab;
|
|||
static slab *mpnh_slab;
|
||||
static slab *rte_src_slab;
|
||||
|
||||
/* rte source ID bitmap */
|
||||
static u32 *src_ids;
|
||||
static u32 src_id_size, src_id_used, src_id_pos;
|
||||
static struct idm src_ids;
|
||||
#define SRC_ID_INIT_SIZE 4
|
||||
|
||||
/* rte source hash */
|
||||
|
@ -87,64 +86,11 @@ rte_src_init(void)
|
|||
{
|
||||
rte_src_slab = sl_new(rta_pool, sizeof(struct rte_src));
|
||||
|
||||
src_id_pos = 0;
|
||||
src_id_size = SRC_ID_INIT_SIZE;
|
||||
src_ids = mb_allocz(rta_pool, src_id_size * sizeof(u32));
|
||||
|
||||
/* ID 0 is reserved */
|
||||
src_ids[0] = 1;
|
||||
src_id_used = 1;
|
||||
idm_init(&src_ids, rta_pool, SRC_ID_INIT_SIZE);
|
||||
|
||||
HASH_INIT(src_hash, rta_pool, RSH_INIT_ORDER);
|
||||
}
|
||||
|
||||
static inline int u32_cto(uint x) { return ffs(~x) - 1; }
|
||||
|
||||
static inline u32
|
||||
rte_src_alloc_id(void)
|
||||
{
|
||||
int i, j;
|
||||
for (i = src_id_pos; i < src_id_size; i++)
|
||||
if (src_ids[i] != 0xffffffff)
|
||||
goto found;
|
||||
|
||||
/* If we are at least 7/8 full, expand */
|
||||
if (src_id_used > (src_id_size * 28))
|
||||
{
|
||||
src_id_size *= 2;
|
||||
src_ids = mb_realloc(src_ids, src_id_size * sizeof(u32));
|
||||
bzero(src_ids + i, (src_id_size - i) * sizeof(u32));
|
||||
goto found;
|
||||
}
|
||||
|
||||
for (i = 0; i < src_id_pos; i++)
|
||||
if (src_ids[i] != 0xffffffff)
|
||||
goto found;
|
||||
|
||||
ASSERT(0);
|
||||
|
||||
found:
|
||||
ASSERT(i < 0x8000000);
|
||||
|
||||
src_id_pos = i;
|
||||
j = u32_cto(src_ids[i]);
|
||||
|
||||
src_ids[i] |= (1 << j);
|
||||
src_id_used++;
|
||||
return 32 * i + j;
|
||||
}
|
||||
|
||||
static inline void
|
||||
rte_src_free_id(u32 id)
|
||||
{
|
||||
int i = id / 32;
|
||||
int j = id % 32;
|
||||
|
||||
ASSERT((i < src_id_size) && (src_ids[i] & (1 << j)));
|
||||
src_ids[i] &= ~(1 << j);
|
||||
src_id_used--;
|
||||
}
|
||||
|
||||
|
||||
HASH_DEFINE_REHASH_FN(RSH, struct rte_src)
|
||||
|
||||
|
@ -165,7 +111,7 @@ rt_get_source(struct proto *p, u32 id)
|
|||
src = sl_alloc(rte_src_slab);
|
||||
src->proto = p;
|
||||
src->private_id = id;
|
||||
src->global_id = rte_src_alloc_id();
|
||||
src->global_id = idm_alloc(&src_ids);
|
||||
src->uc = 0;
|
||||
|
||||
HASH_INSERT2(src_hash, RSH, rta_pool, src);
|
||||
|
@ -181,7 +127,7 @@ rt_prune_sources(void)
|
|||
if (src->uc == 0)
|
||||
{
|
||||
HASH_DO_REMOVE(src_hash, RSH, sp);
|
||||
rte_src_free_id(src->global_id);
|
||||
idm_free(&src_ids, src->global_id);
|
||||
sl_free(rte_src_slab, src);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -253,7 +253,6 @@ fib_get(struct fib *f, const net_addr *a)
|
|||
struct fib_node *e = fib_user_to_node(f, b);
|
||||
e->readers = NULL;
|
||||
e->flags = 0;
|
||||
e->uid = 0;
|
||||
fib_insert(f, a, e);
|
||||
|
||||
memset(b, 0, f->node_offset);
|
||||
|
|
|
@ -240,6 +240,8 @@ ospf_start(struct proto *P)
|
|||
init_list(&(p->area_list));
|
||||
fib_init(&p->rtf, P->pool, p->ospf2 ? NET_IP4 : NET_IP6,
|
||||
sizeof(ort), OFFSETOF(ort, fn), 0, NULL);
|
||||
if (ospf_is_v3(p))
|
||||
idm_init(&p->idm, P->pool, 16);
|
||||
p->areano = 0;
|
||||
p->gr = ospf_top_new(p, P->pool);
|
||||
s_init_list(&(p->lsal));
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "nest/bird.h"
|
||||
|
||||
#include "lib/checksum.h"
|
||||
#include "lib/ip.h"
|
||||
#include "lib/idm.h"
|
||||
#include "lib/lists.h"
|
||||
#include "lib/slists.h"
|
||||
#include "lib/socket.h"
|
||||
|
@ -79,7 +79,6 @@
|
|||
|
||||
#define OSPF_VLINK_ID_OFFSET 0x80000000
|
||||
|
||||
|
||||
struct ospf_config
|
||||
{
|
||||
struct proto_config c;
|
||||
|
@ -215,6 +214,7 @@ struct ospf_proto
|
|||
int areano; /* Number of area I belong to */
|
||||
int padj; /* Number of neighbors in Exchange or Loading state */
|
||||
struct fib rtf; /* Routing table */
|
||||
struct idm idm; /* OSPFv3 LSA ID map */
|
||||
byte ospf2; /* OSPF v2 or v3 */
|
||||
byte rfc1583; /* RFC1583 compatibility */
|
||||
byte stub_router; /* Do not forward transit traffic */
|
||||
|
|
|
@ -2005,6 +2005,9 @@ again1:
|
|||
/* Remove unused rt entry, some special entries are persistent */
|
||||
if (!nf->n.type && !nf->external_rte && !nf->area_net)
|
||||
{
|
||||
if (nf->lsa_id)
|
||||
idm_free(&p->idm, nf->lsa_id);
|
||||
|
||||
FIB_ITERATE_PUT(&fit);
|
||||
fib_delete(fib, nf);
|
||||
goto again1;
|
||||
|
|
|
@ -81,6 +81,7 @@ typedef struct ort
|
|||
orta n;
|
||||
u32 old_metric1, old_metric2, old_tag, old_rid;
|
||||
rta *old_rta;
|
||||
u32 lsa_id;
|
||||
u8 external_rte;
|
||||
u8 area_net;
|
||||
|
||||
|
|
|
@ -513,8 +513,7 @@ ospf_update_lsadb(struct ospf_proto *p)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static inline u32
|
||||
static u32
|
||||
ort_to_lsaid(struct ospf_proto *p, ort *nf)
|
||||
{
|
||||
/*
|
||||
|
@ -542,14 +541,17 @@ ort_to_lsaid(struct ospf_proto *p, ort *nf)
|
|||
* network appeared, we choose a different way.
|
||||
*
|
||||
* In OSPFv3, it is simpler. There is not a requirement for membership of the
|
||||
* result in the input network, so we just use a hash-based unique ID of a
|
||||
* routing table entry for a route that originated given LSA. For ext-LSA, it
|
||||
* is an imported route in the nest's routing table (p->table). For summary-LSA,
|
||||
* it is a 'source' route in the protocol internal routing table (p->rtf).
|
||||
* result in the input network, so we just allocate a unique ID from ID map
|
||||
* and store it in nf->lsa_id for further reference.
|
||||
*/
|
||||
|
||||
if (ospf_is_v3(p))
|
||||
return nf->fn.uid;
|
||||
{
|
||||
if (!nf->lsa_id)
|
||||
nf->lsa_id = idm_alloc(&p->idm);
|
||||
|
||||
return nf->lsa_id;
|
||||
}
|
||||
|
||||
net_addr_ip4 *net = (void *) nf->fn.addr;
|
||||
u32 id = ip4_to_u32(net->prefix);
|
||||
|
|
Loading…
Reference in a new issue