From df5a08e7c717ff421a52b4144d741f0a9749159f Mon Sep 17 00:00:00 2001 From: Maria Matejka Date: Tue, 31 Oct 2023 11:52:30 +0100 Subject: [PATCH] Filter: value hashing Added a code for computing hash of filter values. This is a split-commit of the neighboring aggregator branch with improved lvalue and attribute handling. --- filter/data.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ filter/data.h | 3 +++ 2 files changed, 72 insertions(+) diff --git a/filter/data.c b/filter/data.c index de745654..5d36b0f5 100644 --- a/filter/data.c +++ b/filter/data.c @@ -586,6 +586,75 @@ val_in_range(const struct f_val *v1, const struct f_val *v2) return F_CMP_ERROR; } +uint +val_hash(struct f_val *v) +{ + u64 haux; + mem_hash_init(&haux); + mem_hash_mix_f_val(&haux, v); + return mem_hash_value(&haux); +} + +void +mem_hash_mix_f_val(u64 *h, struct f_val *v) +{ + mem_hash_mix_num(h, v->type); + +#define MX(k) mem_hash_mix(h, &IT(k), sizeof IT(k)); +#define IT(k) v->val.k + + switch (v->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(h, net_hash(IT(net))); + break; + case T_STRING: + mem_hash_mix_str(h, IT(s)); + break; + case T_PATH_MASK: + mem_hash_mix(h, 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(h, IT(ad)->data, IT(ad)->length); + break; + case T_SET: + MX(t); + break; + case T_PREFIX_SET: + MX(ti); + break; + + case T_NONE: + case T_PATH_MASK_ITEM: + case T_ROUTE: + case T_ROUTES_BLOCK: + bug("Invalid type %s in f_val hashing", f_type_name(v->type)); + } +} + /* * rte_format - format route information */ diff --git a/filter/data.h b/filter/data.h index 103591b7..fbf21dcb 100644 --- a/filter/data.h +++ b/filter/data.h @@ -305,6 +305,9 @@ void val_format(const struct f_val *v, buffer *buf); char *val_format_str(struct linpool *lp, const struct f_val *v); const char *val_dump(const struct f_val *v); +uint val_hash(struct f_val *); +void mem_hash_mix_f_val(u64 *, struct f_val *); + static inline int val_is_ip4(const struct f_val *v) { return (v->type == T_IP) && ipa_is_ip4(v->val.ip); } int val_in_range(const struct f_val *v1, const struct f_val *v2);