Skip to content

Commit

Permalink
[ECMP][Multi-ASIC] Have different ECMP seed value on each ASIC (#5357)
Browse files Browse the repository at this point in the history
* Calculate ECMP hash seed based on ASIC ID on multi ASIC platform. Each ASIC will have a unique ECMP hash seed value.
  • Loading branch information
smaheshm authored Oct 8, 2020
1 parent 895f4e0 commit 744612d
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 8 deletions.
11 changes: 8 additions & 3 deletions dockers/docker-orchagent/switch.json.j2
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
{# the range of hash_seed is 0-15 #}
{# set default hash seed to 0 #}
{% set hash_seed = 0 %}
{% set hash_seed_offset = 0 %}
{% if DEVICE_METADATA.localhost.type %}
{% if DEVICE_METADATA.localhost.type == "ToRRouter" %}
{% set hash_seed = 0 %}
{% elif DEVICE_METADATA.localhost.type == "LeafRouter" %}
{% set hash_seed = 10 %}
{% elif DEVICE_METADATA.localhost.type == "SpineRouter" %}
{% set hash_seed = 15 %}
{% set hash_seed = 25 %}
{% endif %}
{% endif %}
{% if DEVICE_METADATA.localhost.namespace_id %}
{% set hash_seed_offset = DEVICE_METADATA.localhost.namespace_id | int %}
{% endif %}
{% set hash_seed_value = hash_seed_offset + hash_seed %}
[
{
"SWITCH_TABLE:switch": {
"ecmp_hash_seed": "{{ hash_seed }}",
"lag_hash_seed": "{{ hash_seed }}",
"ecmp_hash_seed": "{{ hash_seed_value }}",
"lag_hash_seed": "{{ hash_seed_value }}",
"fdb_aging_time": "600"
},
"OP": "SET"
Expand Down
14 changes: 10 additions & 4 deletions src/sonic-config-engine/sonic-cfggen
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import contextlib
import jinja2
import json
import netaddr
import os.path
import os
import sys
import yaml

Expand Down Expand Up @@ -61,7 +61,7 @@ def sort_by_port_index(value):
if not value:
return
if isinstance(value, list):
# In multi-ASIC platforms backend ethernet ports are identified as
# In multi-ASIC platforms backend ethernet ports are identified as
# 'Ethernet-BPxy'. Add 1024 to sort backend ports to the end.
value.sort(
key = lambda k: int(k[8:]) if "BP" not in k else int(k[11:]) + 1024
Expand Down Expand Up @@ -296,8 +296,14 @@ def main():
asic_id = None
if asic_name is not None:
asic_id = get_asic_id_from_name(asic_name)


# get the namespace ID
namespace_id = os.getenv("NAMESPACE_ID")
if namespace_id:
deep_update(data, {
'DEVICE_METADATA': {
'localhost': {'namespace_id': namespace_id}
}
})
# Load the database config for the namespace from global database json
if args.namespace is not None:
SonicDBConfig.load_sonic_global_db_config(namespace=args.namespace)
Expand Down
10 changes: 10 additions & 0 deletions src/sonic-config-engine/tests/sample_output/t0-switch-masic1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"SWITCH_TABLE:switch": {
"ecmp_hash_seed": "11",
"lag_hash_seed": "11",
"fdb_aging_time": "600"
},
"OP": "SET"
}
]
10 changes: 10 additions & 0 deletions src/sonic-config-engine/tests/sample_output/t0-switch-masic3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"SWITCH_TABLE:switch": {
"ecmp_hash_seed": "13",
"lag_hash_seed": "13",
"fdb_aging_time": "600"
},
"OP": "SET"
}
]
10 changes: 10 additions & 0 deletions src/sonic-config-engine/tests/sample_output/t0-switch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"SWITCH_TABLE:switch": {
"ecmp_hash_seed": "0",
"lag_hash_seed": "0",
"fdb_aging_time": "600"
},
"OP": "SET"
}
]
10 changes: 10 additions & 0 deletions src/sonic-config-engine/tests/sample_output/t1-switch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"SWITCH_TABLE:switch": {
"ecmp_hash_seed": "10",
"lag_hash_seed": "10",
"fdb_aging_time": "600"
},
"OP": "SET"
}
]
63 changes: 62 additions & 1 deletion src/sonic-config-engine/tests/test_j2files.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,68 @@ def test_ipinip_multi_asic(self):
sample_output_file = os.path.join(self.test_dir, 'multi_npu_data', utils.PYvX_DIR, 'ipinip.json')
assert filecmp.cmp(sample_output_file, self.output_file)

def test_swss_switch_render_template(self):
switch_template = os.path.join(
self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent',
'switch.json.j2'
)
constants_yml = os.path.join(
self.test_dir, '..', '..', '..', 'files', 'image_config',
'constants', 'constants.yml'
)
test_list = {
"t1": {
"graph": self.t1_mlnx_minigraph,
"output": "t1-switch.json"
},
"t0": {
"graph": self.t0_minigraph,
"output": "t0-switch.json"
},
}
for _, v in test_list.items():
argument = " -m {} -y {} -t {} > {}".format(
v["graph"], constants_yml, switch_template, self.output_file
)
sample_output_file = os.path.join(
self.test_dir, 'sample_output', v["output"]
)
self.run_script(argument)
assert filecmp.cmp(sample_output_file, self.output_file)

def test_swss_switch_render_template_multi_asic(self):
# verify the ECMP hash seed changes per namespace
switch_template = os.path.join(
self.test_dir, '..', '..', '..', 'dockers', 'docker-orchagent',
'switch.json.j2'
)
constants_yml = os.path.join(
self.test_dir, '..', '..', '..', 'files', 'image_config',
'constants', 'constants.yml'
)
test_list = {
"0": {
"namespace_id": "1",
"output": "t0-switch-masic1.json"
},
"1": {
"namespace_id": "3",
"output": "t0-switch-masic3.json"
},
}
for _, v in test_list.items():
os.environ["NAMESPACE_ID"] = v["namespace_id"]
argument = " -m {} -y {} -t {} > {}".format(
self.t1_mlnx_minigraph, constants_yml, switch_template,
self.output_file
)
sample_output_file = os.path.join(
self.test_dir, 'sample_output', v["output"]
)
self.run_script(argument)
assert filecmp.cmp(sample_output_file, self.output_file)
os.environ["NAMESPACE_ID"] = ""

def test_ndppd_conf(self):
conf_template = os.path.join(self.test_dir, "ndppd.conf.j2")
vlan_interfaces_json = os.path.join(self.test_dir, "data", "ndppd", "vlan_interfaces.json")
Expand All @@ -180,7 +242,6 @@ def test_ndppd_conf(self):
self.run_script(argument)
assert filecmp.cmp(expected, self.output_file), self.run_diff(expected, self.output_file)


def tearDown(self):
try:
os.remove(self.output_file)
Expand Down

0 comments on commit 744612d

Please sign in to comment.