Parts of routing table code. Data structure declarations should be
complete now.
This commit is contained in:
parent
18c8241a91
commit
62aa008abd
5 changed files with 189 additions and 38 deletions
|
@ -1,3 +1,4 @@
|
||||||
OBJS=main.o
|
THISDIR=nest
|
||||||
|
OBJS=rt-table.o rt-fib.o
|
||||||
|
|
||||||
include $(TOPDIR)/Rules
|
include $(TOPDIR)/Rules
|
||||||
|
|
20
nest/main.c
20
nest/main.c
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
* BIRD Internet Routing Daemon
|
|
||||||
*
|
|
||||||
* (c) 1998 Martin Mares <mj@ucw.cz>
|
|
||||||
*
|
|
||||||
* Can be freely distributed and used under the terms of the GNU GPL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "nest/bird.h"
|
|
||||||
#include "lib/lists.h"
|
|
||||||
#include "lib/resource.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
main(void)
|
|
||||||
{
|
|
||||||
log_init_debug(NULL);
|
|
||||||
resource_init();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
42
nest/route.h
42
nest/route.h
|
@ -13,14 +13,13 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic data structure for storing network prefixes. Also used
|
* Generic data structure for storing network prefixes. Also used
|
||||||
* for the master routing table. Currently implemented as a radix
|
* for the master routing table. Currently implemented as a hash
|
||||||
* trie.
|
* table.
|
||||||
*
|
*
|
||||||
* Available operations:
|
* Available operations:
|
||||||
* - insertion of new entry
|
* - insertion of new entry
|
||||||
* - deletion of entry
|
* - deletion of entry
|
||||||
* - searching of entry by network prefix
|
* - searching for entry by network prefix
|
||||||
* - searching of entry by IP address (longest match)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct fib_node {
|
struct fib_node {
|
||||||
|
@ -32,9 +31,11 @@ struct fib_node {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fib {
|
struct fib {
|
||||||
slab fib_slab; /* Slab holding all fib nodes */
|
pool *fib_pool; /* Pool holding all our data */
|
||||||
struct fib_node *hash_table; /* Node hash table */
|
slab *fib_slab; /* Slab holding all fib nodes */
|
||||||
|
struct fib_node **hash_table; /* Node hash table */
|
||||||
unsigned int hash_size; /* Number of hash table entries (a power of two) */
|
unsigned int hash_size; /* Number of hash table entries (a power of two) */
|
||||||
|
unsigned int hash_mask; /* hash_size - 1 */
|
||||||
unsigned int entries; /* Number of entries */
|
unsigned int entries; /* Number of entries */
|
||||||
unsigned int entries_min, entries_max;/* Entry count limits (else start rehashing) */
|
unsigned int entries_min, entries_max;/* Entry count limits (else start rehashing) */
|
||||||
void (*init)(struct fib_node *); /* Constructor */
|
void (*init)(struct fib_node *); /* Constructor */
|
||||||
|
@ -43,18 +44,18 @@ struct fib {
|
||||||
void fib_init(struct fib *, pool *, unsigned node_size, unsigned hash_size, void (*init)(struct fib_node *));
|
void fib_init(struct fib *, pool *, unsigned node_size, unsigned hash_size, void (*init)(struct fib_node *));
|
||||||
void *fib_find(struct fib *, ip_addr *, int); /* Find or return NULL if doesn't exist */
|
void *fib_find(struct fib *, ip_addr *, int); /* Find or return NULL if doesn't exist */
|
||||||
void *fib_get(struct fib *, ip_addr *, int); /* Find or create new if nonexistent */
|
void *fib_get(struct fib *, ip_addr *, int); /* Find or create new if nonexistent */
|
||||||
void fib_delete(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 */
|
||||||
|
|
||||||
#define FIB_WALK(fib, op) { \
|
#define FIB_WALK(fib, z, op) do { \
|
||||||
struct fib_node *f, **ff = (fib)->hash_table; \
|
struct fib_node *z, **ff = (fib)->hash_table; \
|
||||||
unsigned int count = (fib)->hash_size; \
|
unsigned int count = (fib)->hash_size; \
|
||||||
while (count--) \
|
while (count--) \
|
||||||
for(f = *ff++; f; f=f->next) \
|
for(z = *ff++; z; z=z->next) \
|
||||||
{ \
|
{ \
|
||||||
op \
|
op; \
|
||||||
} \
|
} \
|
||||||
}
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Neighbor Cache. We hold (direct neighbor, protocol) pairs we've seen
|
* Neighbor Cache. We hold (direct neighbor, protocol) pairs we've seen
|
||||||
|
@ -76,12 +77,21 @@ typedef struct neighbor {
|
||||||
neighbor *neigh_find(ip_addr *); /* NULL if not a neighbor */
|
neighbor *neigh_find(ip_addr *); /* NULL if not a neighbor */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Master Routing Table. Generally speaking, it's a FIB with each entry
|
* Master Routing Tables. Generally speaking, each of them is a list
|
||||||
* pointing to a list of route entries representing routes to given network.
|
* of FIB (one per TOS) with each entry pointing to a list of route entries
|
||||||
|
* representing routes to given network.
|
||||||
* Each of the RTE's contains variable data (the preference and protocol-dependent
|
* Each of the RTE's contains variable data (the preference and protocol-dependent
|
||||||
* metrics) and a pointer to route attribute block common for many routes).
|
* metrics) and a pointer to a route attribute block common for many routes).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct rtable {
|
||||||
|
struct rtable *sibling; /* Our sibling for different TOS */
|
||||||
|
byte tos; /* TOS for this table */
|
||||||
|
struct fib fib;
|
||||||
|
char *name; /* Name of this table */
|
||||||
|
/* FIXME: Data for kernel synchronization */
|
||||||
|
} rtable;
|
||||||
|
|
||||||
typedef struct network {
|
typedef struct network {
|
||||||
struct fib_node n;
|
struct fib_node n;
|
||||||
struct rte *routes; /* Available routes for this network */
|
struct rte *routes; /* Available routes for this network */
|
||||||
|
@ -121,8 +131,6 @@ typedef struct rte {
|
||||||
|
|
||||||
#define REF_CHOSEN 1 /* Currently chosen route */
|
#define REF_CHOSEN 1 /* Currently chosen route */
|
||||||
|
|
||||||
typedef struct rte rte;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Route Attributes
|
* Route Attributes
|
||||||
*
|
*
|
||||||
|
|
150
nest/rt-fib.c
Normal file
150
nest/rt-fib.c
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
/*
|
||||||
|
* BIRD -- Forwarding Information Base -- Data Structures
|
||||||
|
*
|
||||||
|
* (c) 1998 Martin Mares <mj@ucw.cz>
|
||||||
|
*
|
||||||
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define LOCAL_DEBUG
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "nest/bird.h"
|
||||||
|
#include "nest/route.h"
|
||||||
|
|
||||||
|
#define HASH_DEF_SIZE 1024
|
||||||
|
#define HASH_HI_MARK *16
|
||||||
|
#define HASH_LO_MARK *0
|
||||||
|
#define HASH_LO_MIN 128
|
||||||
|
#define HASH_HI_RESIZE *16
|
||||||
|
#define HASH_LO_RESIZE *0
|
||||||
|
|
||||||
|
static void
|
||||||
|
fib_ht_alloc(struct fib *f)
|
||||||
|
{
|
||||||
|
f->hash_mask = f->hash_size - 1;
|
||||||
|
f->entries_max = f->hash_size HASH_HI_MARK;
|
||||||
|
f->entries_min = f->hash_size HASH_LO_MARK;
|
||||||
|
if (f->entries_min < HASH_LO_MIN)
|
||||||
|
f->entries_min = 0;
|
||||||
|
DBG("Allocating FIB: %d entries, %d low, %d high", f->hash_size, f->entries_min, f->entries_max);
|
||||||
|
f->hash_table = mb_alloc(f->fib_pool, f->hash_size * sizeof(struct fib_node *));
|
||||||
|
bzero(f->hash_table, f->hash_size * sizeof(struct fib_node *));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
fib_ht_free(struct fib_node **h)
|
||||||
|
{
|
||||||
|
mb_free(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned
|
||||||
|
fib_hash(struct fib *f, ip_addr *a)
|
||||||
|
{
|
||||||
|
return ipa_hash(*a) & f->hash_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fib_init(struct fib *f, pool *p, unsigned node_size, unsigned hash_size, void (*init)(struct fib_node *))
|
||||||
|
{
|
||||||
|
if (!hash_size)
|
||||||
|
hash_size = HASH_DEF_SIZE;
|
||||||
|
f->fib_pool = p;
|
||||||
|
f->fib_slab = sl_new(p, node_size);
|
||||||
|
f->hash_size = hash_size;
|
||||||
|
fib_ht_alloc(f);
|
||||||
|
f->entries = 0;
|
||||||
|
f->entries_min = 0;
|
||||||
|
f->init = init;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fib_rehash(struct fib *f, unsigned new)
|
||||||
|
{
|
||||||
|
unsigned old;
|
||||||
|
struct fib_node **n, *e, *x, **t, **m, **h;
|
||||||
|
|
||||||
|
old = f->hash_size;
|
||||||
|
m = h = f->hash_table;
|
||||||
|
DBG("Re-hashing FIB from %d to %d", old, new);
|
||||||
|
f->hash_size = new;
|
||||||
|
fib_ht_alloc(f);
|
||||||
|
n = f->hash_table;
|
||||||
|
while (old--)
|
||||||
|
{
|
||||||
|
x = *h++;
|
||||||
|
while (e = x)
|
||||||
|
{
|
||||||
|
x = e->next;
|
||||||
|
t = n + fib_hash(f, &e->prefix);
|
||||||
|
e->next = *t;
|
||||||
|
*t = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fib_ht_free(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
fib_find(struct fib *f, ip_addr *a, int len)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
fib_get(struct fib *f, ip_addr *a, int len)
|
||||||
|
{
|
||||||
|
struct fib_node **ee = f->hash_table + fib_hash(f, a);
|
||||||
|
struct fib_node *e = *ee;
|
||||||
|
|
||||||
|
while (e && (e->pxlen != len || !ipa_equal(*a, e->prefix)))
|
||||||
|
e = e->next;
|
||||||
|
if (e)
|
||||||
|
return e;
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (len < 0 || len > BITS_PER_IP_ADDRESS || !ip_is_prefix(*a,len))
|
||||||
|
die("fib_get() called for invalid address");
|
||||||
|
#endif
|
||||||
|
e = sl_alloc(f->fib_slab);
|
||||||
|
e->prefix = *a;
|
||||||
|
e->pxlen = len;
|
||||||
|
e->flags = 0;
|
||||||
|
e->next = *ee;
|
||||||
|
*ee = e;
|
||||||
|
f->init(e);
|
||||||
|
if (f->entries++ > f->entries_max)
|
||||||
|
fib_rehash(f, f->hash_size HASH_HI_RESIZE);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fib_delete(struct fib *f, void *E)
|
||||||
|
{
|
||||||
|
struct fib_node *e = E;
|
||||||
|
struct fib_node **ee = f->hash_table + fib_hash(f, &e->prefix);
|
||||||
|
|
||||||
|
while (*ee)
|
||||||
|
{
|
||||||
|
if (*ee == e)
|
||||||
|
{
|
||||||
|
*ee = e->next;
|
||||||
|
sl_free(f->fib_slab, e);
|
||||||
|
if (f->entries-- < f->entries_min)
|
||||||
|
fib_rehash(f, f->hash_size HASH_LO_RESIZE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ee = &((*ee)->next);
|
||||||
|
}
|
||||||
|
die("fib_delete() called for invalid node");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fib_free(struct fib *f)
|
||||||
|
{
|
||||||
|
fib_ht_free(f->hash_table);
|
||||||
|
rfree(f->fib_slab);
|
||||||
|
}
|
12
nest/rt-table.c
Normal file
12
nest/rt-table.c
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* BIRD -- Routing Table
|
||||||
|
*
|
||||||
|
* (c) 1998 Martin Mares <mj@ucw.cz>
|
||||||
|
*
|
||||||
|
* Can be freely distributed and used under the terms of the GNU GPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nest/bird.h"
|
||||||
|
#include "nest/route.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue