0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-08 12:18:42 +00:00

Aggregator: Fixed hashing of adata

This commit is contained in:
Maria Matejka 2023-07-12 15:11:00 +02:00 committed by Ondrej Zajicek
parent 977b82fba4
commit 8674d7ab4b
2 changed files with 72 additions and 9 deletions

View File

@ -215,6 +215,14 @@ mem_hash_mix(u64 *h, const void *p, uint s)
*h = *h * multiplier + pp[i]; *h = *h * multiplier + pp[i];
} }
static inline void
mem_hash_mix_str(u64 *h, const char *s)
{
const u64 multiplier = 0xb38bc09a61202731ULL;
while (s)
*h = *h * multiplier + *s++;
}
static inline void static inline void
mem_hash_mix_num(u64 *h, u64 val) mem_hash_mix_num(u64 *h, u64 val)
{ {

View File

@ -62,14 +62,6 @@
#include "lib/flowspec.h" #include "lib/flowspec.h"
*/ */
/* Context of &f_val comparison. */
struct cmp_ctx {
const struct aggregator_proto *p;
const struct network *net;
const int val_count;
u32 failed:1;
};
extern linpool *rte_update_pool; extern linpool *rte_update_pool;
/* /*
@ -258,7 +250,10 @@ aggregator_reload_buckets(void *data)
HASH_WALK(p->buckets, next_hash, b) HASH_WALK(p->buckets, next_hash, b)
if (b->rte) if (b->rte)
{
aggregator_bucket_update(p, b, b->rte->net); aggregator_bucket_update(p, b, b->rte->net);
lp_flush(rte_update_pool);
}
HASH_WALK_END; HASH_WALK_END;
} }
@ -497,7 +492,67 @@ aggregator_rt_notify(struct proto *P, struct channel *src_ch, net *net, rte *new
} }
/* Compute the hash */ /* Compute the hash */
tmp_bucket->hash = mem_hash(tmp_bucket->aggr_data, AGGR_DATA_MEMSIZE); u64 haux;
mem_hash_init(&haux);
for (uint i = 0; i < p->aggr_on_count; i++)
{
mem_hash_mix_num(&haux, tmp_bucket->aggr_data[i].type);
#define MX(k) mem_hash_mix(&haux, &IT(k), sizeof IT(k));
#define IT(k) tmp_bucket->aggr_data[i].val.k
switch (tmp_bucket->aggr_data[i].type)
{
case T_VOID:
break;
case T_INT:
case T_BOOL:
case T_PAIR:
case T_QUAD:
case T_ENUM:
MX(i);
break;
case T_EC:
case T_RD:
MX(ec);
break;
case T_LC:
MX(lc);
break;
case T_IP:
MX(ip);
break;
case T_NET:
mem_hash_mix_num(&haux, net_hash(IT(net)));
break;
case T_STRING:
mem_hash_mix_str(&haux, IT(s));
break;
case T_PATH_MASK:
mem_hash_mix(&haux, IT(path_mask), sizeof(*IT(path_mask)) + IT(path_mask)->len * sizeof (IT(path_mask)->item));
break;
case T_PATH:
case T_CLIST:
case T_ECLIST:
case T_LCLIST:
case T_BYTESTRING:
mem_hash_mix(&haux, IT(ad)->data, IT(ad)->length);
break;
case T_NONE:
case T_PATH_MASK_ITEM:
case T_ROUTE:
case T_ROUTES_BLOCK:
bug("Invalid type %s in hashing", f_type_name(tmp_bucket->aggr_data[i].type));
case T_SET:
MX(t);
break;
case T_PREFIX_SET:
MX(ti);
break;
}
}
tmp_bucket->hash = mem_hash_value(&haux);
/* Find the existing bucket */ /* Find the existing bucket */
if (new_bucket = HASH_FIND(p->buckets, AGGR_BUCK, tmp_bucket)) if (new_bucket = HASH_FIND(p->buckets, AGGR_BUCK, tmp_bucket))