Skip to content

Commit

Permalink
lib: Add hash function for nexthop groups
Browse files Browse the repository at this point in the history
Add a hash function to turn a nexthop group into a
32 bit unsigned hash key with jhash. We do not care to
hash any recursively resolved nexthops, just the group.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
  • Loading branch information
sworleys committed Apr 5, 2019
1 parent 5eec461 commit bd495cc
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 7 deletions.
50 changes: 44 additions & 6 deletions lib/nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,14 +314,52 @@ unsigned int nexthop_level(struct nexthop *nexthop)
return rv;
}

uint32_t nexthop_hash(struct nexthop *nexthop)
uint32_t nexthop_hash(const struct nexthop *nexthop)
{
uint32_t key;
uint32_t key = 0x45afe398;

key = jhash_1word(nexthop->vrf_id, 0x45afe398);
key = jhash_1word(nexthop->ifindex, key);
key = jhash_1word(nexthop->type, key);
key = jhash(&nexthop->gate, sizeof(union g_addr), key);
key = jhash_3words(nexthop->type, nexthop->vrf_id,
nexthop->nh_label_type, key);
/* gate and blackhole are together in a union */
key = jhash(&nexthop->gate, sizeof(nexthop->gate), key);
key = jhash(&nexthop->src, sizeof(nexthop->src), key);
key = jhash(&nexthop->rmap_src, sizeof(nexthop->rmap_src), key);

if (nexthop->nh_label) {
int labels = nexthop->nh_label->num_labels;
int i = 0;

while (labels >= 3) {
key = jhash_3words(nexthop->nh_label->label[i],
nexthop->nh_label->label[i + 1],
nexthop->nh_label->label[i + 2],
key);
labels -= 3;
i += 3;
}

if (labels >= 2) {
key = jhash_2words(nexthop->nh_label->label[i],
nexthop->nh_label->label[i + 1],
key);
labels -= 2;
i += 2;
}

if (labels >= 1)
key = jhash_1word(nexthop->nh_label->label[i], key);
}

switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4_IFINDEX:
case NEXTHOP_TYPE_IPV6_IFINDEX:
case NEXTHOP_TYPE_IFINDEX:
key = jhash_1word(nexthop->ifindex, key);
break;
case NEXTHOP_TYPE_BLACKHOLE:
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV6:
break;
}
return key;
}
2 changes: 1 addition & 1 deletion lib/nexthop.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ void nexthop_del_labels(struct nexthop *);
* Returns:
* 32-bit hash of nexthop
*/
uint32_t nexthop_hash(struct nexthop *nexthop);
uint32_t nexthop_hash(const struct nexthop *nexthop);

extern bool nexthop_same(const struct nexthop *nh1, const struct nexthop *nh2);

Expand Down
16 changes: 16 additions & 0 deletions lib/nexthop_group.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <nexthop_group.h>
#include <vty.h>
#include <command.h>
#include <jhash.h>

#ifndef VTYSH_EXTRACT_PL
#include "lib/nexthop_group_clippy.c"
Expand Down Expand Up @@ -147,6 +148,21 @@ void copy_nexthops(struct nexthop **tnh, const struct nexthop *nh,
}
}

uint32_t nexthop_group_hash(const struct nexthop_group *nhg)
{
struct nexthop *nh;
uint32_t key = 0;

/*
* We are not interested in hashing over any recursively
* resolved nexthops
*/
for (nh = nhg->nexthop; nh; nh = nh->next) {
key = jhash_1word(nexthop_hash(nh), key);
}
return key;
}

static void nhgc_delete_nexthops(struct nexthop_group_cmd *nhgc)
{
struct nexthop *nexthop;
Expand Down
2 changes: 2 additions & 0 deletions lib/nexthop_group.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ void nexthop_del(struct nexthop_group *nhg, struct nexthop *nexthop);
void copy_nexthops(struct nexthop **tnh, const struct nexthop *nh,
struct nexthop *rparent);

uint32_t nexthop_group_hash(const struct nexthop_group *nhg);

/* The following for loop allows to iterate over the nexthop
* structure of routes.
*
Expand Down

0 comments on commit bd495cc

Please sign in to comment.