* Route bucket hash table
*/
-#define RBH_KEY(b) b->eattrs, b->hash
+#define RBH_KEY(b) b->attrs
#define RBH_NEXT(b) b->next
-#define RBH_EQ(a1,h1,a2,h2) h1 == h2 && ea_same(a1, a2)
-#define RBH_FN(a,h) h
+#define RBH_EQ(a1,a2) a1 == a2
+#define RBH_FN(a) ea_get_storage(a)->hash_key
#define RBH_REHASH bgp_rbh_rehash
#define RBH_PARAMS /8, *2, 2, 2, 12, 20
bgp_init_bucket_table(struct bgp_channel *c)
{
HASH_INIT(c->bucket_hash, c->pool, 8);
+ c->bucket_slab = sl_new(c->pool, sizeof(struct bgp_bucket));
init_list(&c->bucket_queue);
c->withdraw_bucket = NULL;
bgp_get_bucket(struct bgp_channel *c, ea_list *new)
{
/* Hash and lookup */
- u32 hash = ea_hash(new);
- struct bgp_bucket *b = HASH_FIND(c->bucket_hash, RBH, new, hash);
+ ea_list *ns = ea_lookup(new, 0, EALS_CUSTOM);
+ struct bgp_bucket *b = HASH_FIND(c->bucket_hash, RBH, ns);
if (b)
+ {
+ ea_free(ns);
return b;
-
- /* Scan the list for total size */
- uint ea_size = BIRD_CPU_ALIGN(ea_list_size(new));
- uint size = sizeof(struct bgp_bucket) + ea_size;
+ }
/* Allocate the bucket */
- b = mb_alloc(c->pool, size);
- *b = (struct bgp_bucket) { };
+ b = sl_alloc(c->bucket_slab);
+ *b = (struct bgp_bucket) {
+ .attrs = ns,
+ };
init_list(&b->prefixes);
- b->hash = hash;
-
- /* Copy the ea_list */
- ea_list_copy(b->eattrs, new, ea_size);
/* Insert the bucket to bucket hash */
HASH_INSERT2(c->bucket_hash, RBH, c->pool, b);
bgp_free_bucket(struct bgp_channel *c, struct bgp_bucket *b)
{
HASH_REMOVE2(c->bucket_hash, RBH, c->pool, b);
- mb_free(b);
+ ea_free(b->attrs);
+ sl_free(b);
}
int
HASH(struct bgp_prefix) prefix_hash; /* Prefixes to be sent */
slab *prefix_slab; /* Slab holding prefix nodes */
+ slab *bucket_slab; /* Slab holding buckets to send */
// struct rt_exporter prefix_exporter; /* Table-like exporter for ptx */
ip_addr next_hop_addr; /* Local address for NEXT_HOP attribute */
node send_node; /* Node in send queue */
struct bgp_bucket *next; /* Node in bucket hash table */
list prefixes; /* Prefixes to send in this bucket (struct bgp_prefix) */
- u32 hash; /* Hash over extended attributes */
+ ea_list *attrs; /* Attributes to encode */
u32 px_uc:31; /* How many prefixes are linking this bucket */
u32 bmp:1; /* Temporary bucket for BMP encoding */
- ea_list eattrs[0]; /* Per-bucket extended attributes */
};
struct bgp_export_state {
int lr, la;
- la = bgp_encode_attrs(s, buck->eattrs, buf+4, buf + MAX_ATTRS_LENGTH);
+ la = bgp_encode_attrs(s, buck->attrs, buf+4, buf + MAX_ATTRS_LENGTH);
if (la < 0)
{
/* Attribute list too long */
/* Encode attributes to temporary buffer */
byte *abuf = alloca(MAX_ATTRS_LENGTH);
- la = bgp_encode_attrs(s, buck->eattrs, abuf, abuf + MAX_ATTRS_LENGTH);
+ la = bgp_encode_attrs(s, buck->attrs, abuf, abuf + MAX_ATTRS_LENGTH);
if (la < 0)
{
/* Attribute list too long */