]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Merge commit 'df5a08e7c717ff421a52b4144d741f0a9749159f' into thread-next
authorMaria Matejka <mq@ucw.cz>
Tue, 31 Oct 2023 15:48:48 +0000 (16:48 +0100)
committerMaria Matejka <mq@ucw.cz>
Tue, 31 Oct 2023 15:48:48 +0000 (16:48 +0100)
1  2 
filter/data.c
filter/data.h
lib/hash.h

diff --cc filter/data.c
index ee10c5ac1895fb9c60db79a197f0dae8dd69fb9d,5d36b0f5084752ce1d1c0796514f2029ecb42e20..8ea6de05c40f8e6d39554b7b131785602493585f
@@@ -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 99f122c872745006d7939d2a1891e3bec67a2db8,fbf21dcbcbf46f6d5ac5142c67d78101829bb451..baee14c8e20e9e24df085f0bec114419433377b0
@@@ -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 ebb2857a8c2f0783fcdbcdfa72aea05b9568b7ea,b30f7830744a84917548c2345d559b897360e7d0..f46e769dab7c14bc6234d071dbaff5fbf861f8a8
@@@ -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)
  {