On Mon, Dec 08, 2014 at 18:58, Ted Unangst wrote:
> bgpd seemed like a good place to try out the new siphash functions.
> 
> Three hash tables are pretty straight forward conversions. Diff below.

Done.

> rde_rib.c nexthop_hash uses hash32 for ipv6, and a simple xor hash for
> ipv4. I left that alone as the diff would be more than mechanical.
> 
> red_update.c up_generate also uses hash32 to generate a "hint" for the
> RB tree. I left that alone as well.

Now for these two. Convert nexthop_hash to actually hash the ip4
address. Probably an improvement. Am I missing a reason why this would
need to be deterministic?

The rb tree hint probably doesn't matter as much, but for the sake of
consistency, I think it's best.

Index: rde_rib.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_rib.c,v
retrieving revision 1.140
diff -u -p -r1.140 rde_rib.c
--- rde_rib.c   12 Dec 2014 18:15:51 -0000      1.140
+++ rde_rib.c   12 Dec 2014 20:12:01 -0000
@@ -18,7 +18,6 @@
 
 #include <sys/types.h>
 #include <sys/queue.h>
-#include <sys/hash.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -1065,6 +1064,8 @@ struct nexthop_table {
        u_int32_t                                nexthop_hashmask;
 } nexthoptable;
 
+SIPHASH_KEY nexthoptablekey;
+
 void
 nexthop_init(u_int32_t hashsize)
 {
@@ -1078,6 +1079,7 @@ nexthop_init(u_int32_t hashsize)
 
        for (i = 0; i < hs; i++)
                LIST_INIT(&nexthoptable.nexthop_hashtbl[i]);
+       arc4random_buf(&nexthoptablekey, sizeof(nexthoptablekey));
 
        nexthoptable.nexthop_hashmask = hs - 1;
 }
@@ -1308,17 +1310,16 @@ nexthop_hash(struct bgpd_addr *nexthop)
 
        switch (nexthop->aid) {
        case AID_INET:
-               h = (AF_INET ^ ntohl(nexthop->v4.s_addr) ^
-                   ntohl(nexthop->v4.s_addr) >> 13) &
-                   nexthoptable.nexthop_hashmask;
+               h = SipHash24(&nexthoptablekey, &nexthop->v4.s_addr,
+                   sizeof(nexthop->v4.s_addr));
                break;
        case AID_INET6:
-               h = hash32_buf(&nexthop->v6, sizeof(struct in6_addr),
-                   HASHINIT) & nexthoptable.nexthop_hashmask;
+               h = SipHash24(&nexthoptablekey, &nexthop->v6,
+                   sizeof(struct in6_addr));
                break;
        default:
                fatalx("nexthop_hash: unsupported AF");
        }
-       return (&nexthoptable.nexthop_hashtbl[h]);
+       return (&nexthoptable.nexthop_hashtbl[h & 
nexthoptable.nexthop_hashmask]);
 }
 
Index: rde_update.c
===================================================================
RCS file: /cvs/src/usr.sbin/bgpd/rde_update.c,v
retrieving revision 1.81
diff -u -p -r1.81 rde_update.c
--- rde_update.c        14 Aug 2013 20:34:27 -0000      1.81
+++ rde_update.c        12 Dec 2014 20:17:19 -0000
@@ -17,11 +17,11 @@
  */
 #include <sys/types.h>
 #include <sys/queue.h>
-#include <sys/hash.h>
 
 #include <limits.h>
 #include <stdlib.h>
 #include <string.h>
+#include <siphash.h>
 
 #include "bgpd.h"
 #include "rde.h"
@@ -63,6 +63,8 @@ RB_GENERATE(uptree_prefix, update_prefix
 RB_PROTOTYPE(uptree_attr, update_attr, entry, up_attr_cmp)
 RB_GENERATE(uptree_attr, update_attr, entry, up_attr_cmp)
 
+SIPHASH_KEY uptree_key;
+
 void
 up_init(struct rde_peer *peer)
 {
@@ -78,6 +80,7 @@ up_init(struct rde_peer *peer)
        peer->up_acnt = 0;
        peer->up_nlricnt = 0;
        peer->up_wcnt = 0;
+       arc4random_buf(&uptree_key, sizeof(uptree_key));
 }
 
 void
@@ -363,6 +366,7 @@ up_generate(struct rde_peer *peer, struc
 {
        struct update_attr              *ua = NULL;
        struct update_prefix            *up;
+       SIPHASH_CTX                     ctx;
 
        if (asp) {
                ua = calloc(1, sizeof(struct update_attr));
@@ -378,10 +382,11 @@ up_generate(struct rde_peer *peer, struc
                 * use aspath_hash as attr_hash, this may be unoptimal
                 * but currently I don't care.
                 */
-               ua->attr_hash = hash32_buf(ua->attr, ua->attr_len, HASHINIT);
+               SipHash24_Init(&ctx, &uptree_key);
+               SipHash24_Update(&ctx, ua->attr, ua->attr_len);
                if (ua->mpattr)
-                       ua->attr_hash = hash32_buf(ua->mpattr, ua->mpattr_len,
-                           ua->attr_hash);
+                       SipHash24_Update(&ctx, ua->mpattr, ua->mpattr_len);
+               ua->attr_hash = SipHash24_End(&ctx);
        }
 
        up = calloc(1, sizeof(struct update_prefix));

Reply via email to