mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-03 15:17:05 +00:00
bgpd: use Jenkins hash for BGP transit, cluster and attr hashes
* bgp_attr.c: I observed while doing some debugging that even for simple tests there was a lot of hash collisions for BGP attributes. Switch to using Jhash rather than additive hashing. Probably overkill, but the function is fast and available. ({attrhash,cluster,transit}_hask_key_make) convert to Jenkins hash, instead of additive hash.
This commit is contained in:
parent
6392aa83c4
commit
c8e7b89590
@ -28,6 +28,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|||||||
#include "stream.h"
|
#include "stream.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
#include "jhash.h"
|
||||||
|
|
||||||
#include "bgpd/bgpd.h"
|
#include "bgpd/bgpd.h"
|
||||||
#include "bgpd/bgp_attr.h"
|
#include "bgpd/bgp_attr.h"
|
||||||
@ -116,18 +117,9 @@ cluster_loop_check (struct cluster_list *cluster, struct in_addr originator)
|
|||||||
static unsigned int
|
static unsigned int
|
||||||
cluster_hash_key_make (void *p)
|
cluster_hash_key_make (void *p)
|
||||||
{
|
{
|
||||||
struct cluster_list * cluster = (struct cluster_list *) p;
|
const struct cluster_list *cluster = p;
|
||||||
unsigned int key = 0;
|
|
||||||
int length;
|
|
||||||
caddr_t pnt;
|
|
||||||
|
|
||||||
length = cluster->length;
|
return jhash(cluster->list, cluster->length, 0);
|
||||||
pnt = (caddr_t) cluster->list;
|
|
||||||
|
|
||||||
while (length)
|
|
||||||
key += pnt[--length];
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -258,18 +250,9 @@ transit_unintern (struct transit *transit)
|
|||||||
static unsigned int
|
static unsigned int
|
||||||
transit_hash_key_make (void *p)
|
transit_hash_key_make (void *p)
|
||||||
{
|
{
|
||||||
struct transit * transit = (struct transit *) p;
|
const struct transit * transit = p;
|
||||||
unsigned int key = 0;
|
|
||||||
int length;
|
|
||||||
caddr_t pnt;
|
|
||||||
|
|
||||||
length = transit->length;
|
return jhash(transit->val, transit->length, 0);
|
||||||
pnt = (caddr_t) transit->val;
|
|
||||||
|
|
||||||
while (length)
|
|
||||||
key += pnt[--length];
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -352,51 +335,47 @@ attr_unknown_count (void)
|
|||||||
unsigned int
|
unsigned int
|
||||||
attrhash_key_make (void *p)
|
attrhash_key_make (void *p)
|
||||||
{
|
{
|
||||||
struct attr * attr = (struct attr *) p;
|
const struct attr * attr = (struct attr *) p;
|
||||||
unsigned int key = 0;
|
uint32_t key = 0;
|
||||||
|
#define MIX(val) key = jhash_1word(val, key)
|
||||||
|
|
||||||
|
MIX(attr->origin);
|
||||||
|
MIX(attr->nexthop.s_addr);
|
||||||
|
MIX(attr->med);
|
||||||
|
MIX(attr->local_pref);
|
||||||
|
|
||||||
key += attr->origin;
|
|
||||||
key += attr->nexthop.s_addr;
|
|
||||||
key += attr->med;
|
|
||||||
key += attr->local_pref;
|
|
||||||
if (attr->pathlimit.as)
|
if (attr->pathlimit.as)
|
||||||
{
|
{
|
||||||
key += attr->pathlimit.ttl;
|
MIX(attr->pathlimit.ttl);
|
||||||
key += attr->pathlimit.as;
|
MIX(attr->pathlimit.as);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->extra)
|
if (attr->extra)
|
||||||
{
|
{
|
||||||
key += attr->extra->aggregator_as;
|
MIX(attr->extra->aggregator_as);
|
||||||
key += attr->extra->aggregator_addr.s_addr;
|
MIX(attr->extra->aggregator_addr.s_addr);
|
||||||
key += attr->extra->weight;
|
MIX(attr->extra->weight);
|
||||||
key += attr->extra->mp_nexthop_global_in.s_addr;
|
MIX(attr->extra->mp_nexthop_global_in.s_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attr->aspath)
|
if (attr->aspath)
|
||||||
key += aspath_key_make (attr->aspath);
|
MIX(aspath_key_make (attr->aspath));
|
||||||
if (attr->community)
|
if (attr->community)
|
||||||
key += community_hash_make (attr->community);
|
MIX(community_hash_make (attr->community));
|
||||||
|
|
||||||
if (attr->extra)
|
if (attr->extra)
|
||||||
{
|
{
|
||||||
if (attr->extra->ecommunity)
|
if (attr->extra->ecommunity)
|
||||||
key += ecommunity_hash_make (attr->extra->ecommunity);
|
MIX(ecommunity_hash_make (attr->extra->ecommunity));
|
||||||
if (attr->extra->cluster)
|
if (attr->extra->cluster)
|
||||||
key += cluster_hash_key_make (attr->extra->cluster);
|
MIX(cluster_hash_key_make (attr->extra->cluster));
|
||||||
if (attr->extra->transit)
|
if (attr->extra->transit)
|
||||||
key += transit_hash_key_make (attr->extra->transit);
|
MIX(transit_hash_key_make (attr->extra->transit));
|
||||||
|
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
{
|
MIX(attr->extra->mp_nexthop_len);
|
||||||
int i;
|
key = jhash2(attr->extra->mp_nexthop_global.s6_addr32, 4, key);
|
||||||
|
key = jhash2(attr->extra->mp_nexthop_local.s6_addr32, 4, key);
|
||||||
key += attr->extra->mp_nexthop_len;
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
key += attr->extra->mp_nexthop_global.s6_addr[i];
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
key += attr->extra->mp_nexthop_local.s6_addr[i];
|
|
||||||
}
|
|
||||||
#endif /* HAVE_IPV6 */
|
#endif /* HAVE_IPV6 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user