diff options
| author | Jafar Al-Gharaibeh <jafar@atcorp.com> | 2025-02-11 11:58:00 -0600 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-02-11 11:58:00 -0600 | 
| commit | ba2b63991ac9aac7bc1d7aa2bf82a070abada4fd (patch) | |
| tree | c669ba23cfcf014f146e0bbcde57b6fc3492e770 /lib/nexthop.c | |
| parent | 0245b8ed9246a588a761fbc9388281e0f63d84a6 (diff) | |
| parent | f1d22e011601e5c41a051fa7719170429256f055 (diff) | |
Merge pull request #18085 from FRRouting/mergify/bp/stable/10.1/pr-17901
lib: actually hash all 16 bytes of IPv6 addresses, not just 4 (backport #17901)
Diffstat (limited to 'lib/nexthop.c')
| -rw-r--r-- | lib/nexthop.c | 87 | 
1 files changed, 12 insertions, 75 deletions
diff --git a/lib/nexthop.c b/lib/nexthop.c index 26c338256f..b35f3b4e7e 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -723,68 +723,30 @@ unsigned int nexthop_level(const struct nexthop *nexthop)  	return rv;  } -/* Only hash word-sized things, let cmp do the rest. */ -uint32_t nexthop_hash_quick(const struct nexthop *nexthop) +uint32_t nexthop_hash(const struct nexthop *nexthop)  {  	uint32_t key = 0x45afe398; -	int i; -	key = jhash_3words(nexthop->type, nexthop->vrf_id, -			   nexthop->nh_label_type, key); - -	if (nexthop->nh_label) { -		int labels = nexthop->nh_label->num_labels; +	/* type, vrf, ifindex, ip addresses - see nexthop.h */ +	key = _nexthop_hash_bytes(nexthop, key); -		i = 0; +	key = jhash_1word(nexthop->flags & NEXTHOP_FLAGS_HASHED, key); -		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 (nexthop->nh_label) { +		const struct mpls_label_stack *ls = nexthop->nh_label; -		if (labels >= 1) -			key = jhash_1word(nexthop->nh_label->label[i], key); +		/* num_labels itself isn't useful to hash, if the number of +		 * labels is different, the hash value will change just due to +		 * that already. +		 */ +		key = jhash(ls->label, sizeof(ls->label[0]) * ls->num_labels, key);  	} -	key = jhash_2words(nexthop->ifindex, -			   CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK), -			   key); -  	/* Include backup nexthops, if present */  	if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {  		int backups = nexthop->backup_num; -		i = 0; - -		while (backups >= 3) { -			key = jhash_3words(nexthop->backup_idx[i], -					   nexthop->backup_idx[i + 1], -					   nexthop->backup_idx[i + 2], key); -			backups -= 3; -			i += 3; -		} - -		while (backups >= 2) { -			key = jhash_2words(nexthop->backup_idx[i], -					   nexthop->backup_idx[i + 1], key); -			backups -= 2; -			i += 2; -		} - -		if (backups >= 1) -			key = jhash_1word(nexthop->backup_idx[i], key); +		key = jhash(nexthop->backup_idx, sizeof(nexthop->backup_idx[0]) * backups, key);  	}  	if (nexthop->nh_srv6) { @@ -819,31 +781,6 @@ uint32_t nexthop_hash_quick(const struct nexthop *nexthop)  	return key;  } - -#define GATE_SIZE 4 /* Number of uint32_t words in struct g_addr */ - -/* For a more granular hash */ -uint32_t nexthop_hash(const struct nexthop *nexthop) -{ -	uint32_t gate_src_rmap_raw[GATE_SIZE * 3] = {}; -	/* Get all the quick stuff */ -	uint32_t key = nexthop_hash_quick(nexthop); - -	assert(((sizeof(nexthop->gate) + sizeof(nexthop->src) -		 + sizeof(nexthop->rmap_src)) -		/ 3) -	       == (GATE_SIZE * sizeof(uint32_t))); - -	memcpy(gate_src_rmap_raw, &nexthop->gate, GATE_SIZE); -	memcpy(gate_src_rmap_raw + GATE_SIZE, &nexthop->src, GATE_SIZE); -	memcpy(gate_src_rmap_raw + (2 * GATE_SIZE), &nexthop->rmap_src, -	       GATE_SIZE); - -	key = jhash2(gate_src_rmap_raw, (GATE_SIZE * 3), key); - -	return key; -} -  void nexthop_copy_no_recurse(struct nexthop *copy,  			     const struct nexthop *nexthop,  			     struct nexthop *rparent)  | 
