From: Maria Matejka Date: Tue, 31 Oct 2023 15:48:48 +0000 (+0100) Subject: Merge commit 'df5a08e7c717ff421a52b4144d741f0a9749159f' into thread-next X-Git-Tag: v3.0.0~364 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9ebd380593a0825f892459d6f18952f31b816543;p=thirdparty%2Fbird.git Merge commit 'df5a08e7c717ff421a52b4144d741f0a9749159f' into thread-next --- 9ebd380593a0825f892459d6f18952f31b816543 diff --cc filter/data.c index ee10c5ac1,5d36b0f50..8ea6de05c --- a/filter/data.c +++ b/filter/data.c @@@ -16,6 -16,6 +16,7 @@@ #include "lib/unaligned.h" #include "lib/net.h" #include "lib/ip.h" ++#include "lib/hash.h" #include "nest/route.h" #include "nest/protocol.h" #include "nest/iface.h" @@@ -578,6 -586,75 +579,79 @@@ val_in_range(const struct f_val *v1, co 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: ++ case T_OPAQUE: ++ case T_NEXTHOP_LIST: ++ case T_HOSTENTRY: ++ case T_IFACE: + bug("Invalid type %s in f_val hashing", f_type_name(v->type)); + } + } + /* * rte_format - format route information */ diff --cc filter/data.h index 99f122c87,fbf21dcbc..baee14c8e --- a/filter/data.h +++ b/filter/data.h @@@ -230,8 -305,9 +230,11 @@@ void val_format(const struct f_val *v, 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 *); + +struct f_val *lp_val_copy(struct linpool *lp, const struct f_val *v); + 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); diff --cc lib/hash.h index ebb2857a8,b30f78307..f46e769da --- a/lib/hash.h +++ b/lib/hash.h @@@ -235,6 -215,6 +235,14 @@@ mem_hash_mix(u64 *h, const void *p, uin *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 mem_hash_mix_num(u64 *h, u64 val) {