Skip to content

Commit

Permalink
[hash]: Add ECMP/LAG hash algorithm CLI (#3036)
Browse files Browse the repository at this point in the history
**HLD:** sonic-net/SONiC#1501

#### What I did
* Implemented CLI for Generic Hash feature

#### How I did it
* Integrated Generic Hash interface into `config` and `show` CLI root

#### How to verify it
* Run Generic Hash CLI UTs

#### Previous command output (if the output of a command-line utility has changed)
```
root@sonic:/home/admin# show switch-hash global
ECMP HASH          LAG HASH
-----------------  -----------------
DST_MAC            DST_MAC
SRC_MAC            SRC_MAC
ETHERTYPE          ETHERTYPE
IP_PROTOCOL        IP_PROTOCOL
DST_IP             DST_IP
SRC_IP             SRC_IP
L4_DST_PORT        L4_DST_PORT
L4_SRC_PORT        L4_SRC_PORT
INNER_DST_MAC      INNER_DST_MAC
INNER_SRC_MAC      INNER_SRC_MAC
INNER_ETHERTYPE    INNER_ETHERTYPE
INNER_IP_PROTOCOL  INNER_IP_PROTOCOL
INNER_DST_IP       INNER_DST_IP
INNER_SRC_IP       INNER_SRC_IP
INNER_L4_DST_PORT  INNER_L4_DST_PORT
INNER_L4_SRC_PORT  INNER_L4_SRC_PORT
```

#### New command output (if the output of a command-line utility has changed)
```
root@sonic:/home/admin# show switch-hash global
+--------+-------------------------------------+
| Hash   | Configuration                       |
+========+=====================================+
| ECMP   | +-------------------+-------------+ |
|        | | Hash Field        | Algorithm   | |
|        | |-------------------+-------------| |
|        | | DST_MAC           | CRC         | |
|        | | SRC_MAC           |             | |
|        | | ETHERTYPE         |             | |
|        | | IP_PROTOCOL       |             | |
|        | | DST_IP            |             | |
|        | | SRC_IP            |             | |
|        | | L4_DST_PORT       |             | |
|        | | L4_SRC_PORT       |             | |
|        | | INNER_DST_MAC     |             | |
|        | | INNER_SRC_MAC     |             | |
|        | | INNER_ETHERTYPE   |             | |
|        | | INNER_IP_PROTOCOL |             | |
|        | | INNER_DST_IP      |             | |
|        | | INNER_SRC_IP      |             | |
|        | | INNER_L4_DST_PORT |             | |
|        | | INNER_L4_SRC_PORT |             | |
|        | +-------------------+-------------+ |
+--------+-------------------------------------+
| LAG    | +-------------------+-------------+ |
|        | | Hash Field        | Algorithm   | |
|        | |-------------------+-------------| |
|        | | DST_MAC           | CRC         | |
|        | | SRC_MAC           |             | |
|        | | ETHERTYPE         |             | |
|        | | IP_PROTOCOL       |             | |
|        | | DST_IP            |             | |
|        | | SRC_IP            |             | |
|        | | L4_DST_PORT       |             | |
|        | | L4_SRC_PORT       |             | |
|        | | INNER_DST_MAC     |             | |
|        | | INNER_SRC_MAC     |             | |
|        | | INNER_ETHERTYPE   |             | |
|        | | INNER_IP_PROTOCOL |             | |
|        | | INNER_DST_IP      |             | |
|        | | INNER_SRC_IP      |             | |
|        | | INNER_L4_DST_PORT |             | |
|        | | INNER_L4_SRC_PORT |             | |
|        | +-------------------+-------------+ |
+--------+-------------------------------------+
```
  • Loading branch information
nazariig authored Dec 1, 2023
1 parent 17e77fe commit 3037959
Show file tree
Hide file tree
Showing 15 changed files with 1,158 additions and 201 deletions.
159 changes: 153 additions & 6 deletions config/plugins/sonic-hash.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@
CFG_SWITCH_HASH,
STATE_SWITCH_CAPABILITY,
SW_CAP_HASH_FIELD_LIST_KEY,
SW_CAP_ECMP_HASH_KEY,
SW_CAP_LAG_HASH_KEY,
SW_CAP_ECMP_HASH_ALGORITHM_KEY,
SW_CAP_LAG_HASH_ALGORITHM_KEY,
SW_CAP_ECMP_HASH_CAPABLE_KEY,
SW_CAP_LAG_HASH_CAPABLE_KEY,
SW_CAP_ECMP_HASH_ALGORITHM_CAPABLE_KEY,
SW_CAP_LAG_HASH_ALGORITHM_CAPABLE_KEY,
SW_HASH_KEY,
SW_CAP_KEY,
HASH_FIELD_LIST,
HASH_ALGORITHM,
SYSLOG_IDENTIFIER,
get_param,
get_param_hint,
Expand Down Expand Up @@ -47,6 +52,22 @@ def hash_field_validator(ctx, param, value):
return list(value)


def hash_algorithm_validator(ctx, param, value):
"""
Check if hash algorithm argument is valid
Args:
ctx: click context
param: click parameter context
value: value of parameter
Returns:
str: validated parameter
"""

click.Choice(HASH_ALGORITHM).convert(value, param, ctx)

return value


def ecmp_hash_validator(ctx, db, ecmp_hash):
"""
Check if ECMP hash argument is valid
Expand All @@ -66,9 +87,9 @@ def ecmp_hash_validator(ctx, db, ecmp_hash):
entry = db.get_all(db.STATE_DB, "{}|{}".format(STATE_SWITCH_CAPABILITY, SW_CAP_KEY))

entry.setdefault(SW_CAP_HASH_FIELD_LIST_KEY, 'N/A')
entry.setdefault(SW_CAP_ECMP_HASH_KEY, 'false')
entry.setdefault(SW_CAP_ECMP_HASH_CAPABLE_KEY, 'false')

if entry[SW_CAP_ECMP_HASH_KEY] == 'false':
if entry[SW_CAP_ECMP_HASH_CAPABLE_KEY] == 'false':
raise click.UsageError("Failed to configure {}: operation is not supported".format(
get_param_hint(ctx, "ecmp_hash")), ctx
)
Expand Down Expand Up @@ -106,9 +127,9 @@ def lag_hash_validator(ctx, db, lag_hash):
entry = db.get_all(db.STATE_DB, "{}|{}".format(STATE_SWITCH_CAPABILITY, SW_CAP_KEY))

entry.setdefault(SW_CAP_HASH_FIELD_LIST_KEY, 'N/A')
entry.setdefault(SW_CAP_LAG_HASH_KEY, 'false')
entry.setdefault(SW_CAP_LAG_HASH_CAPABLE_KEY, 'false')

if entry[SW_CAP_LAG_HASH_KEY] == 'false':
if entry[SW_CAP_LAG_HASH_CAPABLE_KEY] == 'false':
raise click.UsageError("Failed to configure {}: operation is not supported".format(
get_param_hint(ctx, "lag_hash")), ctx
)
Expand All @@ -126,6 +147,72 @@ def lag_hash_validator(ctx, db, lag_hash):
for hash_field in lag_hash:
click.Choice(cap_list).convert(hash_field, get_param(ctx, "lag_hash"), ctx)


def ecmp_hash_algorithm_validator(ctx, db, ecmp_hash_algorithm):
"""
Check if ECMP hash algorithm argument is valid
Args:
ctx: click context
db: State DB connector object
ecmp_hash_algorithm: ECMP hash algorithm
"""

entry = db.get_all(db.STATE_DB, "{}|{}".format(STATE_SWITCH_CAPABILITY, SW_CAP_KEY))

entry.setdefault(SW_CAP_ECMP_HASH_ALGORITHM_KEY, 'N/A')
entry.setdefault(SW_CAP_ECMP_HASH_ALGORITHM_CAPABLE_KEY, 'false')

if entry[SW_CAP_ECMP_HASH_ALGORITHM_CAPABLE_KEY] == 'false':
raise click.UsageError("Failed to configure {}: operation is not supported".format(
get_param_hint(ctx, "ecmp_hash_algorithm")), ctx
)

if not entry[SW_CAP_ECMP_HASH_ALGORITHM_KEY]:
raise click.UsageError("Failed to configure {}: no hash algorithm capabilities".format(
get_param_hint(ctx, "ecmp_hash_algorithm")), ctx
)

if entry[SW_CAP_ECMP_HASH_ALGORITHM_KEY] == 'N/A':
return

cap_list = entry[SW_CAP_ECMP_HASH_ALGORITHM_KEY].split(',')

click.Choice(cap_list).convert(ecmp_hash_algorithm, get_param(ctx, "ecmp_hash_algorithm"), ctx)


def lag_hash_algorithm_validator(ctx, db, lag_hash_algorithm):
"""
Check if LAG hash algorithm argument is valid
Args:
ctx: click context
db: State DB connector object
lag_hash_algorithm: LAG hash algorithm
"""

entry = db.get_all(db.STATE_DB, "{}|{}".format(STATE_SWITCH_CAPABILITY, SW_CAP_KEY))

entry.setdefault(SW_CAP_LAG_HASH_ALGORITHM_KEY, 'N/A')
entry.setdefault(SW_CAP_LAG_HASH_ALGORITHM_CAPABLE_KEY, 'false')

if entry[SW_CAP_LAG_HASH_ALGORITHM_CAPABLE_KEY] == 'false':
raise click.UsageError("Failed to configure {}: operation is not supported".format(
get_param_hint(ctx, "lag_hash_algorithm")), ctx
)

if not entry[SW_CAP_LAG_HASH_ALGORITHM_KEY]:
raise click.UsageError("Failed to configure {}: no hash algorithm capabilities".format(
get_param_hint(ctx, "lag_hash_algorithm")), ctx
)

if entry[SW_CAP_LAG_HASH_ALGORITHM_KEY] == 'N/A':
return

cap_list = entry[SW_CAP_LAG_HASH_ALGORITHM_KEY].split(',')

click.Choice(cap_list).convert(lag_hash_algorithm, get_param(ctx, "lag_hash_algorithm"), ctx)

#
# Hash DB interface ---------------------------------------------------------------------------------------------------
#
Expand Down Expand Up @@ -258,6 +345,66 @@ def SWITCH_HASH_GLOBAL_lag_hash(ctx, db, lag_hash):
ctx.fail(str(err))


@SWITCH_HASH_GLOBAL.command(
name="ecmp-hash-algorithm"
)
@click.argument(
"ecmp-hash-algorithm",
nargs=1,
required=True,
callback=hash_algorithm_validator,
)
@clicommon.pass_db
@click.pass_context
def SWITCH_HASH_GLOBAL_ecmp_hash_algorithm(ctx, db, ecmp_hash_algorithm):
""" Hash algorithm for hashing packets going through ECMP """

ecmp_hash_algorithm_validator(ctx, db.db, ecmp_hash_algorithm)

table = CFG_SWITCH_HASH
key = SW_HASH_KEY
data = {
"ecmp_hash_algorithm": ecmp_hash_algorithm,
}

try:
update_entry_validated(db.cfgdb, table, key, data, create_if_not_exists=True)
log.log_notice("Configured switch global ECMP hash algorithm: {}".format(ecmp_hash_algorithm))
except Exception as e:
log.log_error("Failed to configure switch global ECMP hash algorithm: {}".format(str(e)))
ctx.fail(str(e))


@SWITCH_HASH_GLOBAL.command(
name="lag-hash-algorithm"
)
@click.argument(
"lag-hash-algorithm",
nargs=1,
required=True,
callback=hash_algorithm_validator,
)
@clicommon.pass_db
@click.pass_context
def SWITCH_HASH_GLOBAL_lag_hash_algorithm(ctx, db, lag_hash_algorithm):
""" Hash algorithm for hashing packets going through LAG """

lag_hash_algorithm_validator(ctx, db.db, lag_hash_algorithm)

table = CFG_SWITCH_HASH
key = SW_HASH_KEY
data = {
"lag_hash_algorithm": lag_hash_algorithm,
}

try:
update_entry_validated(db.cfgdb, table, key, data, create_if_not_exists=True)
log.log_notice("Configured switch global LAG hash algorithm: {}".format(lag_hash_algorithm))
except Exception as e:
log.log_error("Failed to configure switch global LAG hash algorithm: {}".format(str(e)))
ctx.fail(str(e))


def register(cli):
""" Register new CLI nodes in root CLI.
Expand Down
153 changes: 134 additions & 19 deletions doc/Command-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -4248,34 +4248,130 @@ This command displays switch hash global configuration.
show switch-hash global
```

- Options:
- _-j,--json_: display in JSON format

- Example:
```bash
admin@sonic:~$ show switch-hash global
ECMP HASH LAG HASH
----------------- -----------------
DST_MAC DST_MAC
SRC_MAC SRC_MAC
ETHERTYPE ETHERTYPE
IP_PROTOCOL IP_PROTOCOL
DST_IP DST_IP
SRC_IP SRC_IP
L4_DST_PORT L4_DST_PORT
L4_SRC_PORT L4_SRC_PORT
INNER_DST_MAC INNER_DST_MAC
INNER_SRC_MAC INNER_SRC_MAC
INNER_ETHERTYPE INNER_ETHERTYPE
INNER_IP_PROTOCOL INNER_IP_PROTOCOL
INNER_DST_IP INNER_DST_IP
INNER_SRC_IP INNER_SRC_IP
INNER_L4_DST_PORT INNER_L4_DST_PORT
INNER_L4_SRC_PORT INNER_L4_SRC_PORT
+--------+-------------------------------------+
| Hash | Configuration |
+========+=====================================+
| ECMP | +-------------------+-------------+ |
| | | Hash Field | Algorithm | |
| | |-------------------+-------------| |
| | | DST_MAC | CRC | |
| | | SRC_MAC | | |
| | | ETHERTYPE | | |
| | | IP_PROTOCOL | | |
| | | DST_IP | | |
| | | SRC_IP | | |
| | | L4_DST_PORT | | |
| | | L4_SRC_PORT | | |
| | | INNER_DST_MAC | | |
| | | INNER_SRC_MAC | | |
| | | INNER_ETHERTYPE | | |
| | | INNER_IP_PROTOCOL | | |
| | | INNER_DST_IP | | |
| | | INNER_SRC_IP | | |
| | | INNER_L4_DST_PORT | | |
| | | INNER_L4_SRC_PORT | | |
| | +-------------------+-------------+ |
+--------+-------------------------------------+
| LAG | +-------------------+-------------+ |
| | | Hash Field | Algorithm | |
| | |-------------------+-------------| |
| | | DST_MAC | CRC | |
| | | SRC_MAC | | |
| | | ETHERTYPE | | |
| | | IP_PROTOCOL | | |
| | | DST_IP | | |
| | | SRC_IP | | |
| | | L4_DST_PORT | | |
| | | L4_SRC_PORT | | |
| | | INNER_DST_MAC | | |
| | | INNER_SRC_MAC | | |
| | | INNER_ETHERTYPE | | |
| | | INNER_IP_PROTOCOL | | |
| | | INNER_DST_IP | | |
| | | INNER_SRC_IP | | |
| | | INNER_L4_DST_PORT | | |
| | | INNER_L4_SRC_PORT | | |
| | +-------------------+-------------+ |
+--------+-------------------------------------+
```

**show switch-hash capabilities**

This command displays switch hash capabilities.

- Usage:
```bash
show switch-hash capabilities
```

- Options:
- _-j,--json_: display in JSON format

- Example:
```bash
admin@sonic:~$ show switch-hash capabilities
+--------+-------------------------------------+
| Hash | Capabilities |
+========+=====================================+
| ECMP | +-------------------+-------------+ |
| | | Hash Field | Algorithm | |
| | |-------------------+-------------| |
| | | IN_PORT | CRC | |
| | | DST_MAC | XOR | |
| | | SRC_MAC | RANDOM | |
| | | ETHERTYPE | CRC_32LO | |
| | | VLAN_ID | CRC_32HI | |
| | | IP_PROTOCOL | CRC_CCITT | |
| | | DST_IP | CRC_XOR | |
| | | SRC_IP | | |
| | | L4_DST_PORT | | |
| | | L4_SRC_PORT | | |
| | | INNER_DST_MAC | | |
| | | INNER_SRC_MAC | | |
| | | INNER_ETHERTYPE | | |
| | | INNER_IP_PROTOCOL | | |
| | | INNER_DST_IP | | |
| | | INNER_SRC_IP | | |
| | | INNER_L4_DST_PORT | | |
| | | INNER_L4_SRC_PORT | | |
| | +-------------------+-------------+ |
+--------+-------------------------------------+
| LAG | +-------------------+-------------+ |
| | | Hash Field | Algorithm | |
| | |-------------------+-------------| |
| | | IN_PORT | CRC | |
| | | DST_MAC | XOR | |
| | | SRC_MAC | RANDOM | |
| | | ETHERTYPE | CRC_32LO | |
| | | VLAN_ID | CRC_32HI | |
| | | IP_PROTOCOL | CRC_CCITT | |
| | | DST_IP | CRC_XOR | |
| | | SRC_IP | | |
| | | L4_DST_PORT | | |
| | | L4_SRC_PORT | | |
| | | INNER_DST_MAC | | |
| | | INNER_SRC_MAC | | |
| | | INNER_ETHERTYPE | | |
| | | INNER_IP_PROTOCOL | | |
| | | INNER_DST_IP | | |
| | | INNER_SRC_IP | | |
| | | INNER_L4_DST_PORT | | |
| | | INNER_L4_SRC_PORT | | |
| | +-------------------+-------------+ |
+--------+-------------------------------------+
```

### Hash Config Commands

This subsection explains how to configure switch hash.

**config switch-hash global**
**config switch-hash global ecmp/lag hash**

This command is used to manage switch hash global configuration.

Expand Down Expand Up @@ -4326,6 +4422,25 @@ This command is used to manage switch hash global configuration.
'INNER_L4_SRC_PORT'
```

**config switch-hash global ecmp/lag hash algorithm**

This command is used to manage switch hash algorithm global configuration.

- Usage:
```bash
config switch-hash global ecmp-hash-algorithm <hash_algorithm>
config switch-hash global lag-hash-algorithm <hash_algorithm>
```

- Parameters:
- _hash_algorithm_: hash algorithm for hashing packets going through ECMP/LAG

- Examples:
```bash
admin@sonic:~$ config switch-hash global ecmp-hash-algorithm 'CRC'
admin@sonic:~$ config switch-hash global lag-hash-algorithm 'CRC'
```

## Interfaces

### Interface Show Commands
Expand Down
Loading

0 comments on commit 3037959

Please sign in to comment.