mirror of
https://gitlab.labs.nic.cz/labs/bird.git
synced 2024-05-11 16:54:54 +00:00
Finishes add-path.
Fixes some bugs and uses generic hash implementation.
This commit is contained in:
@@ -106,13 +106,13 @@
|
||||
|
||||
#define HASH_ID_KEY(n) n->loc_id
|
||||
#define HASH_ID_NEXT(n) n->next_id
|
||||
#define HASH_ID_EQ(a,b) (a == b)
|
||||
#define HASH_ID_FN(k) (k)
|
||||
#define HASH_ID_EQ(a,b) a == b
|
||||
#define HASH_ID_FN(k) k
|
||||
|
||||
#define HASH_IP_KEY(n) n->addr
|
||||
#define HASH_IP_NEXT(n) n->next_ip
|
||||
#define HASH_IP_EQ(a,b) ipa_equal(a,b)
|
||||
#define HASH_IP_FN(k) ipa_hash(k)
|
||||
#define HASH_IP_FN(k) ipa_hash32(k)
|
||||
|
||||
static list bfd_proto_list;
|
||||
static list bfd_wait_list;
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
* bgp_reconstruct_4b_attrs()).
|
||||
*/
|
||||
|
||||
|
||||
static byte bgp_mandatory_attrs[] = { BA_ORIGIN, BA_AS_PATH
|
||||
#ifndef IPV6
|
||||
,BA_NEXT_HOP
|
||||
@@ -875,70 +876,40 @@ bgp_free_bucket(struct bgp_proto *p, struct bgp_bucket *buck)
|
||||
|
||||
/* Prefix hash table */
|
||||
|
||||
static inline u32 prefix_hash(ip_addr prefix, int pxlen, u32 path_id, u32 order)
|
||||
{
|
||||
u32 x = ipa_hash(prefix) + pxlen + path_id;
|
||||
return (x * 2902958171u) >> (32 - order);
|
||||
}
|
||||
#define PXH_KEY(n1) n1->n.prefix, n1->n.pxlen, n1->path_id
|
||||
#define PXH_NEXT(n) n->next
|
||||
#define PXH_EQ(p1,l1,i1,p2,l2,i2) ipa_equal(p1, p2) && l1 == l2 && i1 == i2
|
||||
#define PXH_FN(p,l,i) ipa_hash32(p) ^ u32_hash((l << 16) ^ i)
|
||||
|
||||
static inline u32 px_hash_size(struct bgp_proto *p)
|
||||
{ return 1 << p->px_hash_order; }
|
||||
#define PXH_REHASH bgp_pxh_rehash
|
||||
#define PXH_PARAMS /8, *2, 2, 2, 8, 20
|
||||
|
||||
|
||||
HASH_DEFINE_REHASH_FN(PXH, struct bgp_prefix)
|
||||
|
||||
void
|
||||
bgp_init_prefix_table(struct bgp_proto *p, u32 order)
|
||||
{
|
||||
p->px_hash_count = 0;
|
||||
p->px_hash_order = order;
|
||||
p->prefix_table = mb_allocz(p->p.pool, px_hash_size(p) * sizeof(struct bgp_prefix *));
|
||||
HASH_INIT(p->prefix_hash, p->p.pool, order);
|
||||
|
||||
p->prefix_slab = sl_new(p->p.pool, sizeof(struct bgp_prefix));
|
||||
}
|
||||
|
||||
static void
|
||||
bgp_rehash_prefix_table(struct bgp_proto *p, int step)
|
||||
{
|
||||
struct bgp_prefix **old_tab, *px, *px_next;
|
||||
u32 old_size, hash, i;
|
||||
|
||||
old_tab = p->prefix_table;
|
||||
old_size = px_hash_size(p);
|
||||
|
||||
p->px_hash_order += step;
|
||||
p->prefix_table = mb_allocz(p->p.pool, px_hash_size(p) * sizeof(struct bgp_prefix *));
|
||||
|
||||
for (i = 0; i < old_size; i++)
|
||||
for (px = old_tab[i]; px; px = px_next)
|
||||
{
|
||||
px_next = px->next;
|
||||
hash = prefix_hash(px->n.prefix, px->n.pxlen, px->path_id, p->px_hash_order);
|
||||
px->next = p->prefix_table[hash];
|
||||
p->prefix_table[hash] = px;
|
||||
}
|
||||
|
||||
mb_free(old_tab);
|
||||
}
|
||||
|
||||
static struct bgp_prefix *
|
||||
bgp_get_prefix(struct bgp_proto *p, ip_addr prefix, int pxlen, u32 path_id)
|
||||
{
|
||||
struct bgp_prefix *bp;
|
||||
u32 hash = prefix_hash(prefix, pxlen, path_id, p->px_hash_order);
|
||||
struct bgp_prefix *bp = HASH_FIND(p->prefix_hash, PXH, prefix, pxlen, path_id);
|
||||
|
||||
for (bp = p->prefix_table[hash]; bp; bp = bp->next)
|
||||
if (bp->n.pxlen == pxlen && ipa_equal(bp->n.prefix, prefix) && bp->path_id == path_id)
|
||||
return bp;
|
||||
if (bp)
|
||||
return bp;
|
||||
|
||||
bp = sl_alloc(p->prefix_slab);
|
||||
bp->n.prefix = prefix;
|
||||
bp->n.pxlen = pxlen;
|
||||
bp->path_id = path_id;
|
||||
bp->next = p->prefix_table[hash];
|
||||
p->prefix_table[hash] = bp;
|
||||
|
||||
bp->bucket_node.next = NULL;
|
||||
|
||||
p->px_hash_count++;
|
||||
if ((p->px_hash_count > px_hash_size(p)) && (p->px_hash_order < 18))
|
||||
bgp_rehash_prefix_table(p, 1);
|
||||
HASH_INSERT2(p->prefix_hash, PXH, p->p.pool, bp);
|
||||
|
||||
return bp;
|
||||
}
|
||||
@@ -946,19 +917,8 @@ bgp_get_prefix(struct bgp_proto *p, ip_addr prefix, int pxlen, u32 path_id)
|
||||
void
|
||||
bgp_free_prefix(struct bgp_proto *p, struct bgp_prefix *bp)
|
||||
{
|
||||
struct bgp_prefix **bpp;
|
||||
u32 hash = prefix_hash(bp->n.prefix, bp->n.pxlen, bp->path_id, p->px_hash_order);
|
||||
|
||||
for (bpp = &p->prefix_table[hash]; *bpp; *bpp = (*bpp)->next)
|
||||
if (*bpp == bp)
|
||||
break;
|
||||
|
||||
*bpp = bp->next;
|
||||
HASH_REMOVE2(p->prefix_hash, PXH, p->p.pool, bp);
|
||||
sl_free(p->prefix_slab, bp);
|
||||
|
||||
p->px_hash_count--;
|
||||
if ((p->px_hash_count < (px_hash_size(p) / 4)) && (p->px_hash_order > 10))
|
||||
bgp_rehash_prefix_table(p, -1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
|
||||
#include "bgp.h"
|
||||
|
||||
|
||||
struct linpool *bgp_linpool; /* Global temporary pool */
|
||||
static sock *bgp_listen_sk; /* Global listening socket */
|
||||
static int bgp_counter; /* Number of protocol instances using the listening socket */
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <stdint.h>
|
||||
#include "nest/route.h"
|
||||
#include "nest/bfd.h"
|
||||
#include "lib/hash.h"
|
||||
|
||||
struct linpool;
|
||||
struct eattr;
|
||||
@@ -118,10 +119,8 @@ struct bgp_proto {
|
||||
struct timer *startup_timer; /* Timer used to delay protocol startup due to previous errors (startup_delay) */
|
||||
struct bgp_bucket **bucket_hash; /* Hash table of attribute buckets */
|
||||
unsigned int hash_size, hash_count, hash_limit;
|
||||
// struct fib prefix_fib; /* Prefixes to be sent */
|
||||
struct bgp_prefix **prefix_table; /* Prefixes to be sent */
|
||||
HASH(struct bgp_prefix) prefix_hash; /* Prefixes to be sent */
|
||||
slab *prefix_slab; /* Slab holding prefix nodes */
|
||||
u32 px_hash_order, px_hash_count;
|
||||
list bucket_queue; /* Queue of buckets to send */
|
||||
struct bgp_bucket *withdraw_bucket; /* Withdrawn routes */
|
||||
unsigned startup_delay; /* Time to delay protocol startup by due to errors */
|
||||
|
||||
@@ -244,7 +244,7 @@ bgp_encode_prefixes(struct bgp_proto *p, byte *w, struct bgp_bucket *buck, unsig
|
||||
ip_addr a;
|
||||
int bytes;
|
||||
|
||||
while (!EMPTY_LIST(buck->prefixes) && remains >= (1+sizeof(ip_addr)))
|
||||
while (!EMPTY_LIST(buck->prefixes) && (remains >= (5+sizeof(ip_addr))))
|
||||
{
|
||||
struct bgp_prefix *px = SKIP_BACK(struct bgp_prefix, bucket_node, HEAD(buck->prefixes));
|
||||
DBG("\tDequeued route %I/%d\n", px->n.prefix, px->n.pxlen);
|
||||
@@ -253,6 +253,7 @@ bgp_encode_prefixes(struct bgp_proto *p, byte *w, struct bgp_bucket *buck, unsig
|
||||
{
|
||||
put_u32(w, px->path_id);
|
||||
w += 4;
|
||||
remains -= 4;
|
||||
}
|
||||
|
||||
*w++ = px->n.pxlen;
|
||||
|
||||
Reference in New Issue
Block a user