[ECMP][Multi-ASIC] Have different ECMP seed value on each ASIC (#5357)
* Calculate ECMP hash seed based on ASIC ID on multi ASIC platform. Each ASIC will have a unique ECMP hash seed value.
This commit is contained in:
parent
895f4e0bf7
commit
744612d269
@ -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"
|
||||
|
@ -31,7 +31,7 @@ import contextlib
|
||||
import jinja2
|
||||
import json
|
||||
import netaddr
|
||||
import os.path
|
||||
import os
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
@ -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
|
||||
@ -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)
|
||||
|
@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"SWITCH_TABLE:switch": {
|
||||
"ecmp_hash_seed": "11",
|
||||
"lag_hash_seed": "11",
|
||||
"fdb_aging_time": "600"
|
||||
},
|
||||
"OP": "SET"
|
||||
}
|
||||
]
|
@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"SWITCH_TABLE:switch": {
|
||||
"ecmp_hash_seed": "13",
|
||||
"lag_hash_seed": "13",
|
||||
"fdb_aging_time": "600"
|
||||
},
|
||||
"OP": "SET"
|
||||
}
|
||||
]
|
10
src/sonic-config-engine/tests/sample_output/t0-switch.json
Normal file
10
src/sonic-config-engine/tests/sample_output/t0-switch.json
Normal file
@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"SWITCH_TABLE:switch": {
|
||||
"ecmp_hash_seed": "0",
|
||||
"lag_hash_seed": "0",
|
||||
"fdb_aging_time": "600"
|
||||
},
|
||||
"OP": "SET"
|
||||
}
|
||||
]
|
10
src/sonic-config-engine/tests/sample_output/t1-switch.json
Normal file
10
src/sonic-config-engine/tests/sample_output/t1-switch.json
Normal file
@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"SWITCH_TABLE:switch": {
|
||||
"ecmp_hash_seed": "10",
|
||||
"lag_hash_seed": "10",
|
||||
"fdb_aging_time": "600"
|
||||
},
|
||||
"OP": "SET"
|
||||
}
|
||||
]
|
@ -171,6 +171,68 @@ class TestJ2Files(TestCase):
|
||||
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")
|
||||
@ -180,7 +242,6 @@ class TestJ2Files(TestCase):
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user