Skip to content

Commit cc8df63

Browse files
committed
Add Jenkins hash to supported hash algorithms.
Add the option to configure the hash algorithm to the lower or upper 16 bits of a Jenkins hash algorithm (https://en.wikipedia.org/wiki/Jenkins_hash_function). This provides a stronger alternative to the CRC-based algorithms where supported. Signed-off-by: Mike Beresford <mberes@google.com>
1 parent 58d95ce commit cc8df63

2 files changed

Lines changed: 133 additions & 0 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# [SAI] Jenkins Hash Algorithm
2+
3+
--------------------------------------------------------------------------------
4+
5+
Title | Jenkins Hash Algorithm
6+
----------- | ---------------------------------------
7+
Authors | Mike Beresford, Abhishek Verma (Google)
8+
Status | In-Review
9+
Type | Standards track
10+
Created | 2026-02-05
11+
SAI-Version | 1.18
12+
13+
--------------------------------------------------------------------------------
14+
15+
## 1. Introduction
16+
17+
ECMP or Next hop groups (NHG) and LAG use load balancing techniques to spread
18+
the traffic across the various members. The most common load balancing technique
19+
is to use hash-based member selection. In this technique, flows are identified
20+
by performing a hash on a set of packet fields like the 5-tuple, and then
21+
selecting the group member based on the computed hash value.
22+
23+
This proposal introduces the addition of Jenkins hash algorithm to
24+
_sai_hash_algorithm_t.
25+
26+
## 2. Motivation
27+
28+
Limitation of CRC/XOR: Traditional CRC and XOR algorithms are susceptible to
29+
polarization when traffic passes through multiple next hops.
30+
31+
Jenkins hash function is a non-cryptographic hash function that offers better
32+
avalanche properties compared to CRC and XOR. This results in a more uniform
33+
distribution of flows across members, especially in multi-stage networks (e.g.,
34+
CLOS topologies) where polarization is a concern.
35+
36+
## 3. Behavior
37+
38+
The Jenkins algorithm (specifically `lookup3`) produces a 32-bit hash value for
39+
a given input (e.g., packet 5-tuple). Switching ASICs generally rely on a 16-bit
40+
hash value for load balancing. To accommodate this, the 32-bit Jenkins hash is
41+
split into two 16-bit segments.
42+
43+
Two new enums are introduced to allow selecting either the lower 16 bits
44+
(`_LO`) or the upper 16 bits (`_HI`) of the computed hash. This provides
45+
flexibility, for example allowing different hash values for ECMP and LAG even
46+
if the same flow keys are used.
47+
48+
## 4. SAI Enhancement
49+
50+
New enums added to the `sai_hash_algorithm_t`.
51+
52+
Enum defining the Jenkins hash algorithm:
53+
54+
```c
55+
/**
56+
* @brief Attribute data for #SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_ALGORITHM
57+
* and #SAI_SWITCH_ATTR_LAG_DEFAULT_HASH_ALGORITHM
58+
*/
59+
typedef enum _sai_hash_algorithm_t
60+
{
61+
...
62+
63+
/** Round-robin based hash algorithm (per-packet round-robin spraying) */
64+
SAI_HASH_ALGORITHM_ROUND_ROBIN = 8,
65+
66+
/** Lower 16 bits of Jenkins hash algorithm */
67+
SAI_HASH_ALGORITHM_JENKINS_LO = 9,
68+
69+
/** Upper 16 bits of Jenkins hash algorithm */
70+
SAI_HASH_ALGORITHM_JENKINS_HI = 10,
71+
72+
} sai_hash_algorithm_t;
73+
74+
```
75+
76+
## 5. API Example(s)
77+
78+
### Query supported hashing algorithms
79+
80+
```c
81+
sai_s32_list_t enum_values_capability;
82+
enum_values_capability.count = 0;
83+
enum_values_capability.list = nullptr;
84+
85+
// Fetch the number of supported hash algorithms, then allocate a buffer and
86+
// fetch the actual list.
87+
sai_status_t status = sai->queryAttributeEnumValuesCapability(
88+
switchid,
89+
SAI_OBJECT_TYPE_SWITCH,
90+
SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_ALGORITHM,
91+
&enum_values_capability);
92+
93+
std::vector<int32_t> list;
94+
list.resize(enum_values_capability.count);
95+
enum_values_capability.list = list.data();
96+
sai_status_t status = sai->queryAttributeEnumValuesCapability(
97+
switchid,
98+
SAI_OBJECT_TYPE_SWITCH,
99+
SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_ALGORITHM,
100+
&enum_values_capability);
101+
102+
ASSERT_EQ(status, SAI_STATUS_SUCCESS);
103+
104+
bool jenkins_hash_lo_supported = false;
105+
for (uint32_t i = 0; i < enum_values_capability.count; ++i)
106+
{
107+
if (enum_values_capability.list[i] == SAI_HASH_ALGORITHM_JENKINS_LO)
108+
{
109+
jenkins_hash_lo_supported = true;
110+
}
111+
}
112+
```
113+
114+
### Set Jenkins algorithm as the default hash algorithm
115+
116+
```c
117+
sai_attribute_t attr;
118+
attr.id = SAI_SWITCH_ATTR_ECMP_DEFAULT_HASH_ALGORITHM;
119+
attr.value.s32 = SAI_HASH_ALGORITHM_JENKINS_LO;
120+
status = sai->set(SAI_OBJECT_TYPE_SWITCH, switchid, &attr);
121+
ASSERT_EQ(status, SAI_STATUS_SUCCESS);
122+
```
123+
124+
## 6. References
125+
126+
https://burtleburtle.net/bob/c/lookup3.c
127+

inc/saiswitch.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,12 @@ typedef enum _sai_hash_algorithm_t
214214
/** Round-robin based hash algorithm (per-packet round-robin spraying) */
215215
SAI_HASH_ALGORITHM_ROUND_ROBIN = 8,
216216

217+
/** Lower 16 bits of Jenkins hash algorithm */
218+
SAI_HASH_ALGORITHM_JENKINS_LO = 9,
219+
220+
/** Upper 16 bits of Jenkins hash algorithm */
221+
SAI_HASH_ALGORITHM_JENKINS_HI = 10,
222+
217223
} sai_hash_algorithm_t;
218224

219225
/**

0 commit comments

Comments
 (0)