From 0c7d22f2c919d149adc7ff9de5a58ffc58aeae6d Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Tue, 14 Jul 2020 17:40:36 -0700 Subject: [PATCH 01/19] Changes for identifing the cli object's role Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-config-engine/sonic_device_util.py | 80 +++++++++++++++++++ .../multi_npu_data/sample_port_config-0.ini | 18 ++--- .../multi_npu_data/sample_port_config-1.ini | 18 ++--- .../multi_npu_data/sample_port_config-2.ini | 18 ++--- .../multi_npu_data/sample_port_config-3.ini | 18 ++--- .../tests/test_multinpu_cfggen.py | 13 +++ 6 files changed, 129 insertions(+), 36 deletions(-) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index ddfa751250c5..ba4b8185f638 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -6,6 +6,7 @@ from natsort import natsorted import glob from swsssdk import ConfigDBConnector, SonicDBConfig +from portconfig import get_port_config DOCUMENTATION = ''' --- @@ -26,6 +27,13 @@ ASIC_CONF_FILENAME = 'asic.conf' FRONTEND_ASIC_SUB_ROLE = 'FrontEnd' BACKEND_ASIC_SUB_ROLE = 'BackEnd' +EXTERNAL_PORT = 'E' +INTERNAL_PORT = 'I' +PORT_CHANNEL_CFG_DB_TABLE = 'PORTCHANNEL' +PORT_CFG_DB_TABLE = 'PORT' +BGP_NEIGH_CFG_DB_TABLE = 'BGP_NEIGHBOR' +NEIGH_DEVICE_METADATA_CFG_DB_TABLE = "DEVICE_NEIGHBOR_METADATA" + def get_machine_info(): if not os.path.isfile('/host/machine.conf'): return None @@ -125,6 +133,78 @@ def get_all_namespaces(): return {'front_ns':front_ns, 'back_ns':back_ns} +def get_port_config_from_all_asics(): + if not is_multi_npu(): + return get_port_config() + ns_list = get_namespaces() + platform = get_platform() + hwsku = get_hwsku() + all_ports = {} + ns_list = get_namespaces() + + for ns in ns_list: + asic_id = get_npu_id_from_name(ns) + (ports, _, _) = get_port_config(hwsku=hwsku, platform=platform, asic=asic_id) + all_ports.update(ports) + + return all_ports + +def get_port_role(port_name): + ports_config = get_port_config_from_all_asics() + if not ports_config[port_name].has_key('role'): + return EXTERNAL_PORT + + role = ports_config[port_name]['role'] + return role + +def is_port_internal(port_name): + role = get_port_role(port_name) + if role is INTERNAL_PORT: + return True + return False + +def is_port_channel_internal(port_channel, namespace=None): + if not is_multi_npu(): + return False + if namespace is None: + ns_list = get_namespaces() + else: + ns_list = [namespace] + + for ns in ns_list: + config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=ns) + config_db.connect() + #import pdb; pdb.set_trace() + port_channels = config_db.get_table(PORT_CHANNEL_CFG_DB_TABLE) + if not port_channels.has_key(port_channel): + continue + members = port_channels[port_channel]['members'] + for member in members: + if is_port_internal(member): + return True + return False + +def is_bgp_session_internal(bgp_neigh_ip, namespace=None): + if not is_multi_npu(): + return False + + if namespace is None: + ns_list = get_namespaces() + else: + ns_list = [namespace] + + for ns in ns_list: + config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=ns) + config_db.connect() + bgp_sessions = config_db.get_table(BGP_NEIGH_CFG_DB_TABLE) + if not bgp_sessions.has_key(bgp_neigh_ip): + continue + bgp_neigh_name = bgp_sessions[bgp_neigh_ip]['name'] + neighbor_metadata = config_db.get_table(NEIGH_DEVICE_METADATA_CFG_DB_TABLE) + if neighbor_metadata[bgp_neigh_name]['type'].lower() == 'asic': + return True + return False + def get_platform_info(machine_info): if machine_info != None: if machine_info.has_key('onie_platform'): diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini index 3fe912c98c45..9f290b1a2f58 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini @@ -1,9 +1,9 @@ -# name lanes alias asic_port_name -Ethernet0 33,34,35,36 Ethernet1/1 Eth0-ASIC0 -Ethernet4 29,30,31,32 Ethernet1/2 Eth1-ASIC0 -Ethernet8 41,42,43,44 Ethernet1/3 Eth2-ASIC0 -Ethernet12 37,38,39,40 Ethernet1/4 Eth3-ASIC0 -Ethernet-BP0 13,14,15,16 Ethernet-BP0 Eth4-ASIC0 -Ethernet-BP4 17,18,19,20 Ethernet-BP4 Eth5-ASIC0 -Ethernet-BP8 21,22,23,24 Ethernet-BP8 Eth6-ASIC0 -Ethernet-BP12 25,26,27,28 Ethernet-BP12 Eth7-ASIC0 \ No newline at end of file +# name lanes alias asic_port_name role +Ethernet0 33,34,35,36 Ethernet1/1 Eth0-ASIC0 E +Ethernet4 29,30,31,32 Ethernet1/2 Eth1-ASIC0 E +Ethernet8 41,42,43,44 Ethernet1/3 Eth2-ASIC0 E +Ethernet12 37,38,39,40 Ethernet1/4 Eth3-ASIC0 E +Ethernet-BP0 13,14,15,16 Ethernet-BP0 Eth4-ASIC0 I +Ethernet-BP4 17,18,19,20 Ethernet-BP4 Eth5-ASIC0 I +Ethernet-BP8 21,22,23,24 Ethernet-BP8 Eth6-ASIC0 I +Ethernet-BP12 25,26,27,28 Ethernet-BP12 Eth7-ASIC0 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini index c496e0712a49..b2f5724faafd 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini @@ -1,9 +1,9 @@ -# name lanes alias asic_port_name -Ethernet16 33,34,35,36 Ethernet1/5 Eth0-ASIC1 -Ethernet20 29,30,31,32 Ethernet1/6 Eth1-ASIC1 -Ethernet24 41,42,43,44 Ethernet1/7 Eth2-ASIC1 -Ethernet28 37,38,39,40 Ethernet1/8 Eth3-ASIC1 -Ethernet-BP16 13,14,15,16 Ethernet-BP16 Eth4-ASIC1 -Ethernet-BP20 17,18,19,20 Ethernet-BP20 Eth5-ASIC1 -Ethernet-BP24 21,22,23,24 Ethernet-BP24 Eth6-ASIC1 -Ethernet-BP28 25,26,27,28 Ethernet-BP28 Eth7-ASIC1 \ No newline at end of file +# name lanes alias asic_port_name role +Ethernet16 33,34,35,36 Ethernet1/5 Eth0-ASIC1 E +Ethernet20 29,30,31,32 Ethernet1/6 Eth1-ASIC1 E +Ethernet24 41,42,43,44 Ethernet1/7 Eth2-ASIC1 E +Ethernet28 37,38,39,40 Ethernet1/8 Eth3-ASIC1 E +Ethernet-BP16 13,14,15,16 Ethernet-BP16 Eth4-ASIC1 I +Ethernet-BP20 17,18,19,20 Ethernet-BP20 Eth5-ASIC1 I +Ethernet-BP24 21,22,23,24 Ethernet-BP24 Eth6-ASIC1 I +Ethernet-BP28 25,26,27,28 Ethernet-BP28 Eth7-ASIC1 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini index 4ae0575835a7..527979a8542a 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini @@ -1,9 +1,9 @@ -# name lanes alias asic_port_name -Ethernet-BP256 61,62,63,64 Ethernet-BP256 Eth0-ASIC2 -Ethernet-BP260 57,58,59,60 Ethernet-BP260 Eth1-ASIC2 -Ethernet-BP264 53,54,55,56 Ethernet-BP264 Eth2-ASIC2 -Ethernet-BP268 49,50,51,52 Ethernet-BP268 Eth3-ASIC2 -Ethernet-BP272 45,46,47,48 Ethernet-BP272 Eth4-ASIC2 -Ethernet-BP276 41,42,43,44 Ethernet-BP276 Eth5-ASIC2 -Ethernet-BP280 37,38,39,40 Ethernet-BP280 Eth6-ASIC2 -Ethernet-BP284 33,34,35,36 Ethernet-BP284 Eth7-ASIC2 \ No newline at end of file +# name lanes alias asic_port_name role +Ethernet-BP256 61,62,63,64 Ethernet-BP256 Eth0-ASIC2 I +Ethernet-BP260 57,58,59,60 Ethernet-BP260 Eth1-ASIC2 I +Ethernet-BP264 53,54,55,56 Ethernet-BP264 Eth2-ASIC2 I +Ethernet-BP268 49,50,51,52 Ethernet-BP268 Eth3-ASIC2 I +Ethernet-BP272 45,46,47,48 Ethernet-BP272 Eth4-ASIC2 I +Ethernet-BP276 41,42,43,44 Ethernet-BP276 Eth5-ASIC2 I +Ethernet-BP280 37,38,39,40 Ethernet-BP280 Eth6-ASIC2 I +Ethernet-BP284 33,34,35,36 Ethernet-BP284 Eth7-ASIC2 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini index 8f45ed14946e..cebdd3c7ec46 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini @@ -1,9 +1,9 @@ -# name lanes alias asic_port_name -Ethernet-BP384 29,30,31,32 Ethernet-BP384 Eth0-ASIC3 -Ethernet-BP388 25,26,27,28 Ethernet-BP388 Eth1-ASIC3 -Ethernet-BP392 21,22,23,24 Ethernet-BP392 Eth2-ASIC3 -Ethernet-BP396 17,18,19,20 Ethernet-BP396 Eth3-ASIC3 -Ethernet-BP400 13,14,15,16 Ethernet-BP400 Eth4-ASIC3 -Ethernet-BP404 9,10,11,12 Ethernet-BP404 Eth5-ASIC3 -Ethernet-BP408 5,6,7,8 Ethernet-BP408 Eth6-ASIC3 -Ethernet-BP412 1,2,3,4 Ethernet-BP412 Eth7-ASIC3 \ No newline at end of file +# name lanes alias asic_port_name role +Ethernet-BP384 29,30,31,32 Ethernet-BP384 Eth0-ASIC3 I +Ethernet-BP388 25,26,27,28 Ethernet-BP388 Eth1-ASIC3 I +Ethernet-BP392 21,22,23,24 Ethernet-BP392 Eth2-ASIC3 I +Ethernet-BP396 17,18,19,20 Ethernet-BP396 Eth3-ASIC3 I +Ethernet-BP400 13,14,15,16 Ethernet-BP400 Eth4-ASIC3 I +Ethernet-BP404 9,10,11,12 Ethernet-BP404 Eth5-ASIC3 I +Ethernet-BP408 5,6,7,8 Ethernet-BP408 Eth6-ASIC3 I +Ethernet-BP412 1,2,3,4 Ethernet-BP412 Eth7-ASIC3 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 7511ce9bcdd1..4cd5f37e5084 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -157,6 +157,19 @@ def test_backend_asic_portchannel_intf(self): self.assertListEqual(output.keys(), \ ['PortChannel4013', 'PortChannel4013|10.1.0.2/31', 'PortChannel4014', 'PortChannel4014|10.1.0.6/31']) + def test_frontend_asic_ports(self): + argument = "-m {} -p {} -n asic0 --var-json \"PORT\"".format(self.sample_graph, self.port_config[0]) + output = json.loads(self.run_script(argument)) + self.assertDictEqual(output, \ + { + "Ethernet0": {"admin_status": "up", "alias": "Ethernet1/1", "asic_port_name": "Eth0-ASIC0", "description": "01T2:Ethernet1", "lanes": "33,34,35,36", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, + "Ethernet4": {"admin_status": "up", "alias": "Ethernet1/2", "asic_port_name": "Eth1-ASIC0", "description": "01T2:Ethernet2", "lanes": "29,30,31,32", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, + "Ethernet8": {"alias": "Ethernet1/3", "asic_port_name": "Eth2-ASIC0", "description": "Ethernet1/3", "lanes": "41,42,43,44", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000"}, + "Ethernet12": {"alias": "Ethernet1/4", "asic_port_name": "Eth3-ASIC0", "description": "Ethernet1/4", "lanes": "37,38,39,40", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000"}, + "Ethernet-BP0": {"admin_status": "up", "alias": "Ethernet-BP0", "asic_port_name": "Eth4-ASIC0", "description": "ASIC2:Eth0-ASIC2", "lanes": "13,14,15,16", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000"}, + "Ethernet-BP4": {"admin_status": "up", "alias": "Ethernet-BP4", "asic_port_name": "Eth5-ASIC0", "description": "ASIC2:Eth1-ASIC2", "lanes": "17,18,19,20", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000"}, + "Ethernet-BP8": {"admin_status": "up", "alias": "Ethernet-BP8", "asic_port_name": "Eth6-ASIC0", "description": "ASIC3:Eth0-ASIC3", "lanes": "21,22,23,24", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000"}, + "Ethernet-BP12": {"admin_status": "up", "alias": "Ethernet-BP12", "asic_port_name": "Eth7-ASIC0", "description": "ASIC3:Eth1-ASIC3", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000"}}) def test_frontend_asic_device_neigh(self): argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) output = json.loads(self.run_script(argument)) From 062098276b816a1862197b76b598795c908ed460 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Wed, 15 Jul 2020 11:03:59 -0700 Subject: [PATCH 02/19] Fix lgtm warning Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-config-engine/sonic_device_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index ba4b8185f638..146d34fbcf6c 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -136,7 +136,7 @@ def get_all_namespaces(): def get_port_config_from_all_asics(): if not is_multi_npu(): return get_port_config() - ns_list = get_namespaces() + platform = get_platform() hwsku = get_hwsku() all_ports = {} From 00e34d0e720ed38a06a80f7238fef03ddaeba20f Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Thu, 16 Jul 2020 14:45:40 -0700 Subject: [PATCH 03/19] address review comment Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-config-engine/sonic_device_util.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index 146d34fbcf6c..ac30ab8854e5 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -179,8 +179,7 @@ def is_port_channel_internal(port_channel, namespace=None): if not port_channels.has_key(port_channel): continue members = port_channels[port_channel]['members'] - for member in members: - if is_port_internal(member): + if is_port_internal(members[0]): return True return False From b133dc100a2012e7074024274f35058652c38772 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Thu, 16 Jul 2020 14:56:21 -0700 Subject: [PATCH 04/19] Fixed review comments Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-config-engine/sonic_device_util.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index ac30ab8854e5..9b62b82b6f44 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -202,6 +202,8 @@ def is_bgp_session_internal(bgp_neigh_ip, namespace=None): neighbor_metadata = config_db.get_table(NEIGH_DEVICE_METADATA_CFG_DB_TABLE) if neighbor_metadata[bgp_neigh_name]['type'].lower() == 'asic': return True + else: + return False return False def get_platform_info(machine_info): From 3c671c132f378b32a8cffd72916ea11c808c8ab4 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Mon, 20 Jul 2020 14:10:25 -0700 Subject: [PATCH 05/19] Add index to port_config and minor fixes --- src/sonic-config-engine/sonic_device_util.py | 4 +++- .../multi_npu_data/sample_port_config-0.ini | 18 +++++++++--------- .../multi_npu_data/sample_port_config-1.ini | 18 +++++++++--------- .../multi_npu_data/sample_port_config-2.ini | 18 +++++++++--------- .../multi_npu_data/sample_port_config-3.ini | 18 +++++++++--------- .../tests/test_multinpu_cfggen.py | 19 ++++++++++--------- 6 files changed, 49 insertions(+), 46 deletions(-) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index 9b62b82b6f44..dddbe82373cb 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -7,6 +7,7 @@ import glob from swsssdk import ConfigDBConnector, SonicDBConfig from portconfig import get_port_config +from portconfig import get_port_config_file_name DOCUMENTATION = ''' --- @@ -144,7 +145,8 @@ def get_port_config_from_all_asics(): for ns in ns_list: asic_id = get_npu_id_from_name(ns) - (ports, _, _) = get_port_config(hwsku=hwsku, platform=platform, asic=asic_id) + port_config = get_port_config_file_name(hwsku, platform, asic_id) + (ports, _, _) = get_port_config(hwsku=hwsku, platform=platform, port_config_file=port_config, asic=asic_id) all_ports.update(ports) return all_ports diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini index 9f290b1a2f58..0dbd387a99e5 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini @@ -1,9 +1,9 @@ -# name lanes alias asic_port_name role -Ethernet0 33,34,35,36 Ethernet1/1 Eth0-ASIC0 E -Ethernet4 29,30,31,32 Ethernet1/2 Eth1-ASIC0 E -Ethernet8 41,42,43,44 Ethernet1/3 Eth2-ASIC0 E -Ethernet12 37,38,39,40 Ethernet1/4 Eth3-ASIC0 E -Ethernet-BP0 13,14,15,16 Ethernet-BP0 Eth4-ASIC0 I -Ethernet-BP4 17,18,19,20 Ethernet-BP4 Eth5-ASIC0 I -Ethernet-BP8 21,22,23,24 Ethernet-BP8 Eth6-ASIC0 I -Ethernet-BP12 25,26,27,28 Ethernet-BP12 Eth7-ASIC0 I \ No newline at end of file +# name lanes alias index asic_port_name role +Ethernet0 33,34,35,36 Ethernet1/1 0 Eth0-ASIC0 E +Ethernet4 29,30,31,32 Ethernet1/2 1 Eth1-ASIC0 E +Ethernet8 41,42,43,44 Ethernet1/3 2 Eth2-ASIC0 E +Ethernet12 37,38,39,40 Ethernet1/4 3 Eth3-ASIC0 E +Ethernet-BP0 13,14,15,16 Ethernet-BP0 4 Eth4-ASIC0 I +Ethernet-BP4 17,18,19,20 Ethernet-BP4 5 Eth5-ASIC0 I +Ethernet-BP8 21,22,23,24 Ethernet-BP8 6 Eth6-ASIC0 I +Ethernet-BP12 25,26,27,28 Ethernet-BP12 7 Eth7-ASIC0 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini index b2f5724faafd..f911056f6063 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini @@ -1,9 +1,9 @@ -# name lanes alias asic_port_name role -Ethernet16 33,34,35,36 Ethernet1/5 Eth0-ASIC1 E -Ethernet20 29,30,31,32 Ethernet1/6 Eth1-ASIC1 E -Ethernet24 41,42,43,44 Ethernet1/7 Eth2-ASIC1 E -Ethernet28 37,38,39,40 Ethernet1/8 Eth3-ASIC1 E -Ethernet-BP16 13,14,15,16 Ethernet-BP16 Eth4-ASIC1 I -Ethernet-BP20 17,18,19,20 Ethernet-BP20 Eth5-ASIC1 I -Ethernet-BP24 21,22,23,24 Ethernet-BP24 Eth6-ASIC1 I -Ethernet-BP28 25,26,27,28 Ethernet-BP28 Eth7-ASIC1 I \ No newline at end of file +# name lanes alias index asic_port_name role +Ethernet16 33,34,35,36 Ethernet1/5 8 Eth0-ASIC1 E +Ethernet20 29,30,31,32 Ethernet1/6 9 Eth1-ASIC1 E +Ethernet24 41,42,43,44 Ethernet1/7 10 Eth2-ASIC1 E +Ethernet28 37,38,39,40 Ethernet1/8 11 Eth3-ASIC1 E +Ethernet-BP16 13,14,15,16 Ethernet-BP16 12 Eth4-ASIC1 I +Ethernet-BP20 17,18,19,20 Ethernet-BP20 13 Eth5-ASIC1 I +Ethernet-BP24 21,22,23,24 Ethernet-BP24 14 Eth6-ASIC1 I +Ethernet-BP28 25,26,27,28 Ethernet-BP28 15 Eth7-ASIC1 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini index 527979a8542a..43278eb6429a 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini @@ -1,9 +1,9 @@ -# name lanes alias asic_port_name role -Ethernet-BP256 61,62,63,64 Ethernet-BP256 Eth0-ASIC2 I -Ethernet-BP260 57,58,59,60 Ethernet-BP260 Eth1-ASIC2 I -Ethernet-BP264 53,54,55,56 Ethernet-BP264 Eth2-ASIC2 I -Ethernet-BP268 49,50,51,52 Ethernet-BP268 Eth3-ASIC2 I -Ethernet-BP272 45,46,47,48 Ethernet-BP272 Eth4-ASIC2 I -Ethernet-BP276 41,42,43,44 Ethernet-BP276 Eth5-ASIC2 I -Ethernet-BP280 37,38,39,40 Ethernet-BP280 Eth6-ASIC2 I -Ethernet-BP284 33,34,35,36 Ethernet-BP284 Eth7-ASIC2 I \ No newline at end of file +# name lanes alias index asic_port_name role +Ethernet-BP256 61,62,63,64 Ethernet-BP256 16 Eth0-ASIC2 I +Ethernet-BP260 57,58,59,60 Ethernet-BP260 17 Eth1-ASIC2 I +Ethernet-BP264 53,54,55,56 Ethernet-BP264 18 Eth2-ASIC2 I +Ethernet-BP268 49,50,51,52 Ethernet-BP268 19 Eth3-ASIC2 I +Ethernet-BP272 45,46,47,48 Ethernet-BP272 20 Eth4-ASIC2 I +Ethernet-BP276 41,42,43,44 Ethernet-BP276 21 Eth5-ASIC2 I +Ethernet-BP280 37,38,39,40 Ethernet-BP280 22 Eth6-ASIC2 I +Ethernet-BP284 33,34,35,36 Ethernet-BP284 23 Eth7-ASIC2 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini index cebdd3c7ec46..5c5b6dfe48fb 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini @@ -1,9 +1,9 @@ -# name lanes alias asic_port_name role -Ethernet-BP384 29,30,31,32 Ethernet-BP384 Eth0-ASIC3 I -Ethernet-BP388 25,26,27,28 Ethernet-BP388 Eth1-ASIC3 I -Ethernet-BP392 21,22,23,24 Ethernet-BP392 Eth2-ASIC3 I -Ethernet-BP396 17,18,19,20 Ethernet-BP396 Eth3-ASIC3 I -Ethernet-BP400 13,14,15,16 Ethernet-BP400 Eth4-ASIC3 I -Ethernet-BP404 9,10,11,12 Ethernet-BP404 Eth5-ASIC3 I -Ethernet-BP408 5,6,7,8 Ethernet-BP408 Eth6-ASIC3 I -Ethernet-BP412 1,2,3,4 Ethernet-BP412 Eth7-ASIC3 I \ No newline at end of file +# name lanes alias index asic_port_name role +Ethernet-BP384 29,30,31,32 Ethernet-BP384 24 Eth0-ASIC3 I +Ethernet-BP388 25,26,27,28 Ethernet-BP388 25 Eth1-ASIC3 I +Ethernet-BP392 21,22,23,24 Ethernet-BP392 26 Eth2-ASIC3 I +Ethernet-BP396 17,18,19,20 Ethernet-BP396 27 Eth3-ASIC3 I +Ethernet-BP400 13,14,15,16 Ethernet-BP400 28 Eth4-ASIC3 I +Ethernet-BP404 9,10,11,12 Ethernet-BP404 29 Eth5-ASIC3 I +Ethernet-BP408 5,6,7,8 Ethernet-BP408 30 Eth6-ASIC3 I +Ethernet-BP412 1,2,3,4 Ethernet-BP412 31 Eth7-ASIC3 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 4cd5f37e5084..98fe682eef98 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -161,15 +161,16 @@ def test_frontend_asic_ports(self): argument = "-m {} -p {} -n asic0 --var-json \"PORT\"".format(self.sample_graph, self.port_config[0]) output = json.loads(self.run_script(argument)) self.assertDictEqual(output, \ - { - "Ethernet0": {"admin_status": "up", "alias": "Ethernet1/1", "asic_port_name": "Eth0-ASIC0", "description": "01T2:Ethernet1", "lanes": "33,34,35,36", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, - "Ethernet4": {"admin_status": "up", "alias": "Ethernet1/2", "asic_port_name": "Eth1-ASIC0", "description": "01T2:Ethernet2", "lanes": "29,30,31,32", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, - "Ethernet8": {"alias": "Ethernet1/3", "asic_port_name": "Eth2-ASIC0", "description": "Ethernet1/3", "lanes": "41,42,43,44", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000"}, - "Ethernet12": {"alias": "Ethernet1/4", "asic_port_name": "Eth3-ASIC0", "description": "Ethernet1/4", "lanes": "37,38,39,40", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000"}, - "Ethernet-BP0": {"admin_status": "up", "alias": "Ethernet-BP0", "asic_port_name": "Eth4-ASIC0", "description": "ASIC2:Eth0-ASIC2", "lanes": "13,14,15,16", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000"}, - "Ethernet-BP4": {"admin_status": "up", "alias": "Ethernet-BP4", "asic_port_name": "Eth5-ASIC0", "description": "ASIC2:Eth1-ASIC2", "lanes": "17,18,19,20", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000"}, - "Ethernet-BP8": {"admin_status": "up", "alias": "Ethernet-BP8", "asic_port_name": "Eth6-ASIC0", "description": "ASIC3:Eth0-ASIC3", "lanes": "21,22,23,24", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000"}, - "Ethernet-BP12": {"admin_status": "up", "alias": "Ethernet-BP12", "asic_port_name": "Eth7-ASIC0", "description": "ASIC3:Eth1-ASIC3", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000"}}) + { + "Ethernet0": { "admin_status": "up", "alias": "Ethernet1/1", "asic_port_name": "Eth0-ASIC0", "description": "01T2:Ethernet1", "index": "0", "lanes": "33,34,35,36", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, + "Ethernet4": { "admin_status": "up", "alias": "Ethernet1/2", "asic_port_name": "Eth1-ASIC0", "description": "01T2:Ethernet2", "index": "1", "lanes": "29,30,31,32", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, + "Ethernet8": { "alias": "Ethernet1/3", "asic_port_name": "Eth2-ASIC0", "description": "Ethernet1/3", "index": "2", "lanes": "41,42,43,44", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, + "Ethernet12": { "alias": "Ethernet1/4", "asic_port_name": "Eth3-ASIC0", "description": "Ethernet1/4", "index": "3", "lanes": "37,38,39,40", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, + "Ethernet-BP0": { "admin_status": "up", "alias": "Ethernet-BP0", "asic_port_name": "Eth4-ASIC0", "description": "ASIC2:Eth0-ASIC2", "index": "4", "lanes": "13,14,15,16", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, + "Ethernet-BP4": { "admin_status": "up", "alias": "Ethernet-BP4", "asic_port_name": "Eth5-ASIC0", "description": "ASIC2:Eth1-ASIC2", "index": "5", "lanes": "17,18,19,20", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, + "Ethernet-BP8": { "admin_status": "up", "alias": "Ethernet-BP8", "asic_port_name": "Eth6-ASIC0", "description": "ASIC3:Eth0-ASIC3", "index": "6", "lanes": "21,22,23,24", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, + "Ethernet-BP12": { "admin_status": "up", "alias": "Ethernet-BP12", "asic_port_name": "Eth7-ASIC0", "description": "ASIC3:Eth1-ASIC3", "index": "7", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }}) + def test_frontend_asic_device_neigh(self): argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) output = json.loads(self.run_script(argument)) From 4985d2de4720fcea94aeb0bb8130cb02197733a4 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Tue, 28 Jul 2020 08:45:20 -0700 Subject: [PATCH 06/19] move common functions to sonic_py_common package Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-config-engine/sonic_device_util.py | 99 ------ .../multi_npu_data/sample_port_config-0.ini | 8 +- .../multi_npu_data/sample_port_config-1.ini | 16 +- .../multi_npu_data/sample_port_config-2.ini | 16 +- .../multi_npu_data/sample_port_config-3.ini | 16 +- .../tests/test_multinpu_cfggen.py | 8 +- .../sonic_py_common/device_info.py | 100 +----- .../sonic_py_common/multi_asic_device_info.py | 292 ++++++++++++++++++ 8 files changed, 326 insertions(+), 229 deletions(-) create mode 100644 src/sonic-py-common/sonic_py_common/multi_asic_device_info.py diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index dddbe82373cb..6de973768fb8 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -109,105 +109,6 @@ def is_multi_npu(): num_npus = get_num_npus() return (num_npus > 1) -def get_all_namespaces(): - """ - In case of Multi-Asic platform, Each ASIC will have a linux network namespace created. - So we loop through the databases in different namespaces and depending on the sub_role - decide whether this is a front end ASIC/namespace or a back end one. - """ - front_ns = [] - back_ns = [] - num_npus = get_num_npus() - SonicDBConfig.load_sonic_global_db_config() - - if is_multi_npu(): - for npu in range(num_npus): - namespace = "{}{}".format(NPU_NAME_PREFIX, npu) - config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=namespace) - config_db.connect() - - metadata = config_db.get_table('DEVICE_METADATA') - if metadata['localhost']['sub_role'] == FRONTEND_ASIC_SUB_ROLE: - front_ns.append(namespace) - elif metadata['localhost']['sub_role'] == BACKEND_ASIC_SUB_ROLE: - back_ns.append(namespace) - - return {'front_ns':front_ns, 'back_ns':back_ns} - -def get_port_config_from_all_asics(): - if not is_multi_npu(): - return get_port_config() - - platform = get_platform() - hwsku = get_hwsku() - all_ports = {} - ns_list = get_namespaces() - - for ns in ns_list: - asic_id = get_npu_id_from_name(ns) - port_config = get_port_config_file_name(hwsku, platform, asic_id) - (ports, _, _) = get_port_config(hwsku=hwsku, platform=platform, port_config_file=port_config, asic=asic_id) - all_ports.update(ports) - - return all_ports - -def get_port_role(port_name): - ports_config = get_port_config_from_all_asics() - if not ports_config[port_name].has_key('role'): - return EXTERNAL_PORT - - role = ports_config[port_name]['role'] - return role - -def is_port_internal(port_name): - role = get_port_role(port_name) - if role is INTERNAL_PORT: - return True - return False - -def is_port_channel_internal(port_channel, namespace=None): - if not is_multi_npu(): - return False - if namespace is None: - ns_list = get_namespaces() - else: - ns_list = [namespace] - - for ns in ns_list: - config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=ns) - config_db.connect() - #import pdb; pdb.set_trace() - port_channels = config_db.get_table(PORT_CHANNEL_CFG_DB_TABLE) - if not port_channels.has_key(port_channel): - continue - members = port_channels[port_channel]['members'] - if is_port_internal(members[0]): - return True - return False - -def is_bgp_session_internal(bgp_neigh_ip, namespace=None): - if not is_multi_npu(): - return False - - if namespace is None: - ns_list = get_namespaces() - else: - ns_list = [namespace] - - for ns in ns_list: - config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=ns) - config_db.connect() - bgp_sessions = config_db.get_table(BGP_NEIGH_CFG_DB_TABLE) - if not bgp_sessions.has_key(bgp_neigh_ip): - continue - bgp_neigh_name = bgp_sessions[bgp_neigh_ip]['name'] - neighbor_metadata = config_db.get_table(NEIGH_DEVICE_METADATA_CFG_DB_TABLE) - if neighbor_metadata[bgp_neigh_name]['type'].lower() == 'asic': - return True - else: - return False - return False - def get_platform_info(machine_info): if machine_info != None: if machine_info.has_key('onie_platform'): diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini index 0dbd387a99e5..824a870fb628 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini @@ -3,7 +3,7 @@ Ethernet0 33,34,35,36 Ethernet1/1 0 Eth0-ASIC0 E Ethernet4 29,30,31,32 Ethernet1/2 1 Eth1-ASIC0 E Ethernet8 41,42,43,44 Ethernet1/3 2 Eth2-ASIC0 E Ethernet12 37,38,39,40 Ethernet1/4 3 Eth3-ASIC0 E -Ethernet-BP0 13,14,15,16 Ethernet-BP0 4 Eth4-ASIC0 I -Ethernet-BP4 17,18,19,20 Ethernet-BP4 5 Eth5-ASIC0 I -Ethernet-BP8 21,22,23,24 Ethernet-BP8 6 Eth6-ASIC0 I -Ethernet-BP12 25,26,27,28 Ethernet-BP12 7 Eth7-ASIC0 I \ No newline at end of file +Ethernet-BP0 13,14,15,16 Ethernet-BP0 0 Eth4-ASIC0 I +Ethernet-BP4 17,18,19,20 Ethernet-BP4 1 Eth5-ASIC0 I +Ethernet-BP8 21,22,23,24 Ethernet-BP8 2 Eth6-ASIC0 I +Ethernet-BP12 25,26,27,28 Ethernet-BP12 3 Eth7-ASIC0 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini index f911056f6063..c5f011c2cc6c 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini @@ -1,9 +1,9 @@ # name lanes alias index asic_port_name role -Ethernet16 33,34,35,36 Ethernet1/5 8 Eth0-ASIC1 E -Ethernet20 29,30,31,32 Ethernet1/6 9 Eth1-ASIC1 E -Ethernet24 41,42,43,44 Ethernet1/7 10 Eth2-ASIC1 E -Ethernet28 37,38,39,40 Ethernet1/8 11 Eth3-ASIC1 E -Ethernet-BP16 13,14,15,16 Ethernet-BP16 12 Eth4-ASIC1 I -Ethernet-BP20 17,18,19,20 Ethernet-BP20 13 Eth5-ASIC1 I -Ethernet-BP24 21,22,23,24 Ethernet-BP24 14 Eth6-ASIC1 I -Ethernet-BP28 25,26,27,28 Ethernet-BP28 15 Eth7-ASIC1 I \ No newline at end of file +Ethernet16 33,34,35,36 Ethernet1/5 4 Eth0-ASIC1 E +Ethernet20 29,30,31,32 Ethernet1/6 5 Eth1-ASIC1 E +Ethernet24 41,42,43,44 Ethernet1/7 6 Eth2-ASIC1 E +Ethernet28 37,38,39,40 Ethernet1/8 7 Eth3-ASIC1 E +Ethernet-BP16 13,14,15,16 Ethernet-BP16 4 Eth4-ASIC1 I +Ethernet-BP20 17,18,19,20 Ethernet-BP20 5 Eth5-ASIC1 I +Ethernet-BP24 21,22,23,24 Ethernet-BP24 6 Eth6-ASIC1 I +Ethernet-BP28 25,26,27,28 Ethernet-BP28 7 Eth7-ASIC1 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini index 43278eb6429a..66590b3aec01 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini @@ -1,9 +1,9 @@ # name lanes alias index asic_port_name role -Ethernet-BP256 61,62,63,64 Ethernet-BP256 16 Eth0-ASIC2 I -Ethernet-BP260 57,58,59,60 Ethernet-BP260 17 Eth1-ASIC2 I -Ethernet-BP264 53,54,55,56 Ethernet-BP264 18 Eth2-ASIC2 I -Ethernet-BP268 49,50,51,52 Ethernet-BP268 19 Eth3-ASIC2 I -Ethernet-BP272 45,46,47,48 Ethernet-BP272 20 Eth4-ASIC2 I -Ethernet-BP276 41,42,43,44 Ethernet-BP276 21 Eth5-ASIC2 I -Ethernet-BP280 37,38,39,40 Ethernet-BP280 22 Eth6-ASIC2 I -Ethernet-BP284 33,34,35,36 Ethernet-BP284 23 Eth7-ASIC2 I \ No newline at end of file +Ethernet-BP256 61,62,63,64 Ethernet-BP256 8 Eth0-ASIC2 I +Ethernet-BP260 57,58,59,60 Ethernet-BP260 9 Eth1-ASIC2 I +Ethernet-BP264 53,54,55,56 Ethernet-BP264 10 Eth2-ASIC2 I +Ethernet-BP268 49,50,51,52 Ethernet-BP268 11 Eth3-ASIC2 I +Ethernet-BP272 45,46,47,48 Ethernet-BP272 12 Eth4-ASIC2 I +Ethernet-BP276 41,42,43,44 Ethernet-BP276 13 Eth5-ASIC2 I +Ethernet-BP280 37,38,39,40 Ethernet-BP280 14 Eth6-ASIC2 I +Ethernet-BP284 33,34,35,36 Ethernet-BP284 15 Eth7-ASIC2 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini index 5c5b6dfe48fb..d29f94671163 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini @@ -1,9 +1,9 @@ # name lanes alias index asic_port_name role -Ethernet-BP384 29,30,31,32 Ethernet-BP384 24 Eth0-ASIC3 I -Ethernet-BP388 25,26,27,28 Ethernet-BP388 25 Eth1-ASIC3 I -Ethernet-BP392 21,22,23,24 Ethernet-BP392 26 Eth2-ASIC3 I -Ethernet-BP396 17,18,19,20 Ethernet-BP396 27 Eth3-ASIC3 I -Ethernet-BP400 13,14,15,16 Ethernet-BP400 28 Eth4-ASIC3 I -Ethernet-BP404 9,10,11,12 Ethernet-BP404 29 Eth5-ASIC3 I -Ethernet-BP408 5,6,7,8 Ethernet-BP408 30 Eth6-ASIC3 I -Ethernet-BP412 1,2,3,4 Ethernet-BP412 31 Eth7-ASIC3 I \ No newline at end of file +Ethernet-BP384 29,30,31,32 Ethernet-BP384 16 Eth0-ASIC3 I +Ethernet-BP388 25,26,27,28 Ethernet-BP388 17 Eth1-ASIC3 I +Ethernet-BP392 21,22,23,24 Ethernet-BP392 18 Eth2-ASIC3 I +Ethernet-BP396 17,18,19,20 Ethernet-BP396 19 Eth3-ASIC3 I +Ethernet-BP400 13,14,15,16 Ethernet-BP400 20 Eth4-ASIC3 I +Ethernet-BP404 9,10,11,12 Ethernet-BP404 21 Eth5-ASIC3 I +Ethernet-BP408 5,6,7,8 Ethernet-BP408 22 Eth6-ASIC3 I +Ethernet-BP412 1,2,3,4 Ethernet-BP412 23 Eth7-ASIC3 I \ No newline at end of file diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 07a89767ffc6..c80b570b2343 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -167,10 +167,10 @@ def test_frontend_asic_ports(self): "Ethernet4": { "admin_status": "up", "alias": "Ethernet1/2", "asic_port_name": "Eth1-ASIC0", "description": "01T2:Ethernet2", "index": "1", "lanes": "29,30,31,32", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, "Ethernet8": { "alias": "Ethernet1/3", "asic_port_name": "Eth2-ASIC0", "description": "Ethernet1/3", "index": "2", "lanes": "41,42,43,44", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, "Ethernet12": { "alias": "Ethernet1/4", "asic_port_name": "Eth3-ASIC0", "description": "Ethernet1/4", "index": "3", "lanes": "37,38,39,40", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, - "Ethernet-BP0": { "admin_status": "up", "alias": "Ethernet-BP0", "asic_port_name": "Eth4-ASIC0", "description": "ASIC2:Eth0-ASIC2", "index": "4", "lanes": "13,14,15,16", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, - "Ethernet-BP4": { "admin_status": "up", "alias": "Ethernet-BP4", "asic_port_name": "Eth5-ASIC0", "description": "ASIC2:Eth1-ASIC2", "index": "5", "lanes": "17,18,19,20", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, - "Ethernet-BP8": { "admin_status": "up", "alias": "Ethernet-BP8", "asic_port_name": "Eth6-ASIC0", "description": "ASIC3:Eth0-ASIC3", "index": "6", "lanes": "21,22,23,24", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, - "Ethernet-BP12": { "admin_status": "up", "alias": "Ethernet-BP12", "asic_port_name": "Eth7-ASIC0", "description": "ASIC3:Eth1-ASIC3", "index": "7", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }}) + "Ethernet-BP0": { "admin_status": "up", "alias": "Ethernet-BP0", "asic_port_name": "Eth4-ASIC0", "description": "ASIC2:Eth0-ASIC2", "index": "0", "lanes": "13,14,15,16", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, + "Ethernet-BP4": { "admin_status": "up", "alias": "Ethernet-BP4", "asic_port_name": "Eth5-ASIC0", "description": "ASIC2:Eth1-ASIC2", "index": "1", "lanes": "17,18,19,20", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, + "Ethernet-BP8": { "admin_status": "up", "alias": "Ethernet-BP8", "asic_port_name": "Eth6-ASIC0", "description": "ASIC3:Eth0-ASIC3", "index": "2", "lanes": "21,22,23,24", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, + "Ethernet-BP12": { "admin_status": "up", "alias": "Ethernet-BP12", "asic_port_name": "Eth7-ASIC0", "description": "ASIC3:Eth1-ASIC3", "index": "3", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }}) def test_frontend_asic_device_neigh(self): argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index 72b9e5a28644..ae714fa4a13d 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -1,9 +1,7 @@ -import glob import os import subprocess import yaml -from natsort import natsorted # TODD: Replace with swsscommon from swsssdk import ConfigDBConnector, SonicDBConfig @@ -19,13 +17,6 @@ PORT_CONFIG_FILE = "port_config.ini" PLATFORM_JSON_FILE = "platform.json" -# Multi-NPU constants -# TODO: Move Multi-ASIC-related functions and constants to a "multi_asic.py" module -NPU_NAME_PREFIX = "asic" -NAMESPACE_PATH_GLOB = "/run/netns/*" -ASIC_CONF_FILENAME = "asic.conf" -FRONTEND_ASIC_SUB_ROLE = "FrontEnd" -BACKEND_ASIC_SUB_ROLE = "BackEnd" def get_machine_info(): @@ -111,30 +102,6 @@ def get_platform_and_hwsku(): return (platform, hwsku) - -def get_asic_conf_file_path(): - """ - Retrieves the path to the ASIC conguration file on the device - - Returns: - A string containing the path to the ASIC conguration file on success, - None on failure - """ - asic_conf_path_candidates = [] - - asic_conf_path_candidates.append(os.path.join(CONTAINER_PLATFORM_PATH, ASIC_CONF_FILENAME)) - - platform = get_platform() - if platform: - asic_conf_path_candidates.append(os.path.join(HOST_DEVICE_PATH, platform, ASIC_CONF_FILENAME)) - - for asic_conf_file_path in asic_conf_path_candidates: - if os.path.isfile(asic_conf_file_path): - return asic_conf_file_path - - return None - - def get_paths_to_platform_and_hwsku_dirs(): """ Retreives the paths to the device's platform and hardware SKU data @@ -199,73 +166,9 @@ def get_sonic_version_info(): # -# Multi-NPU functionality +# Multi-ASIC functionality # -def get_num_npus(): - asic_conf_file_path = get_asic_conf_file_path() - if asic_conf_file_path is None: - return 1 - with open(asic_conf_file_path) as asic_conf_file: - for line in asic_conf_file: - tokens = line.split('=') - if len(tokens) < 2: - continue - if tokens[0].lower() == 'num_asic': - num_npus = tokens[1].strip() - return int(num_npus) - - -def is_multi_npu(): - num_npus = get_num_npus() - return (num_npus > 1) - - -def get_npu_id_from_name(npu_name): - if npu_name.startswith(NPU_NAME_PREFIX): - return npu_name[len(NPU_NAME_PREFIX):] - else: - return None - - -def get_namespaces(): - """ - In a multi NPU platform, each NPU is in a Linux Namespace. - This method returns list of all the Namespace present on the device - """ - ns_list = [] - for path in glob.glob(NAMESPACE_PATH_GLOB): - ns = os.path.basename(path) - ns_list.append(ns) - return natsorted(ns_list) - - -def get_all_namespaces(): - """ - In case of Multi-Asic platform, Each ASIC will have a linux network namespace created. - So we loop through the databases in different namespaces and depending on the sub_role - decide whether this is a front end ASIC/namespace or a back end one. - """ - front_ns = [] - back_ns = [] - num_npus = get_num_npus() - SonicDBConfig.load_sonic_global_db_config() - - if is_multi_npu(): - for npu in range(num_npus): - namespace = "{}{}".format(NPU_NAME_PREFIX, npu) - config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=namespace) - config_db.connect() - - metadata = config_db.get_table('DEVICE_METADATA') - if metadata['localhost']['sub_role'] == FRONTEND_ASIC_SUB_ROLE: - front_ns.append(namespace) - elif metadata['localhost']['sub_role'] == BACKEND_ASIC_SUB_ROLE: - back_ns.append(namespace) - - return {'front_ns':front_ns, 'back_ns':back_ns} - - def _valid_mac_address(mac): return bool(re.match("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", mac)) @@ -342,3 +245,4 @@ def get_system_routing_stack(): raise OSError("Cannot detect routing stack") return result + diff --git a/src/sonic-py-common/sonic_py_common/multi_asic_device_info.py b/src/sonic-py-common/sonic_py_common/multi_asic_device_info.py new file mode 100644 index 000000000000..282deaf4864f --- /dev/null +++ b/src/sonic-py-common/sonic_py_common/multi_asic_device_info.py @@ -0,0 +1,292 @@ +import glob +import importlib +import os +from os import name +import sys + +from natsort import natsorted + +from sonic_py_common.device_info import CONTAINER_PLATFORM_PATH +from sonic_py_common.device_info import HOST_DEVICE_PATH +from sonic_py_common.device_info import get_platform +from swsssdk import ConfigDBConnector, SonicDBConfig +from swsssdk import SonicV2Connector + + +ASIC_NAME_PREFIX = "asic" +NAMESPACE_PATH_GLOB = "/run/netns/*" +ASIC_CONF_FILENAME = "asic.conf" +FRONTEND_ASIC_SUB_ROLE = "FrontEnd" +BACKEND_ASIC_SUB_ROLE = "BackEnd" +EXTERNAL_PORT = 'E' +INTERNAL_PORT = 'I' +PORT_CHANNEL_CFG_DB_TABLE = 'PORTCHANNEL' +PORT_CFG_DB_TABLE = 'PORT' +BGP_NEIGH_CFG_DB_TABLE = 'BGP_NEIGHBOR' +NEIGH_DEVICE_METADATA_CFG_DB_TABLE = "DEVICE_NEIGHBOR_METADATA" +DEFAULT_NAMESPACE = '' + + +def connect_config_db_for_ns(namespace=DEFAULT_NAMESPACE): + ''' + The function connects to the config DB for a given namespace and + returns the handle + If no namespace is provided, it will connect to the db in the + default namespace. + In case of multi ASIC, the default namespace is the database + instance running the on the host + + Returns: + handle to the config_db for a namespace + ''' + SonicDBConfig.load_sonic_global_db_config() + config_db = ConfigDBConnector( + use_unix_socket_path=True, namespace=namespace) + config_db.connect() + return config_db + + +def connect_to_all_dbs_for_ns(namespace=DEFAULT_NAMESPACE): + ''' + The function connects to the DBs for a given namespace and + returns the handle + If no namespace is provided, it will connect to the db in the + default namespace. + In case of multi ASIC, the default namespace is the + database instance running the on the host + In case of single ASIC, the namespace has to be DEFAULT_NAMESPACE + + Returns: + handle to all the dbs for a namespaces + ''' + SonicDBConfig.load_sonic_global_db_config() + db = SonicV2Connector(use_unix_socket_path=True, namespace=namespace) + for db_id in db.get_db_list(): + db.connect(db_id) + return db + + +def get_asic_conf_file_path(): + """ + Retrieves the path to the ASIC conguration file on the device + + Returns: + A string containing the path to the ASIC conguration file on success, + None on failure + """ + asic_conf_path_candidates = [] + + asic_conf_path_candidates.append(os.path.join(CONTAINER_PLATFORM_PATH, + ASIC_CONF_FILENAME)) + + platform = get_platform() + if platform: + asic_conf_path_candidates.append(os.path.join( + HOST_DEVICE_PATH, platform, ASIC_CONF_FILENAME)) + + for asic_conf_file_path in asic_conf_path_candidates: + if os.path.isfile(asic_conf_file_path): + return asic_conf_file_path + + return None + + +def get_num_asics(): + """ + Retrieves the num of asics present in the multi ASIC platform + + Returns: + Num of asics + """ + asic_conf_file_path = get_asic_conf_file_path() + + if asic_conf_file_path is None: + return 1 + + with open(asic_conf_file_path) as asic_conf_file: + for line in asic_conf_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + if tokens[0].lower() == 'num_asic': + num_asics = tokens[1].strip() + return int(num_asics) + + +def is_multi_asic(): + """ + Checks if the device is multi asic or not + + Returns: + True: if the num of asic is more than 1 + """ + num_asics = get_num_asics() + + return (num_asics > 1) + + +def get_asic_id_from_name(asic_name): + + if asic_name.startswith(ASIC_NAME_PREFIX): + return asic_name[len(ASIC_NAME_PREFIX):] + else: + return None + + +def get_namespaces(): + """ + In a multi asic platform, each ASIC is in a Linux Namespace. + This method returns list of all the Namespace present on the device + + Note: This function can be used only when the config_db is not available + + Returns: + List of the namespaces present in the system + """ + ns_list = [] + for path in glob.glob(NAMESPACE_PATH_GLOB): + ns = os.path.basename(path) + ns_list.append(ns) + return natsorted(ns_list) + + +def get_all_namespaces(): + """ + In case of Multi-Asic platform, Each ASIC will have a linux network namespace created. + So we loop through the databases in different namespaces and depending on the sub_role + decide whether this is a front end ASIC/namespace or a back end one. + """ + front_ns = [] + back_ns = [] + num_asics = get_num_asics() + + if is_multi_asic(): + for asic in range(num_asics): + namespace = "{}{}".format(ASIC_NAME_PREFIX, asic) + config_db = connect_config_db_for_ns(namespace) + + metadata = config_db.get_table('DEVICE_METADATA') + if metadata['localhost']['sub_role'] == FRONTEND_ASIC_SUB_ROLE: + front_ns.append(namespace) + elif metadata['localhost']['sub_role'] == BACKEND_ASIC_SUB_ROLE: + back_ns.append(namespace) + + return {'front_ns': front_ns, 'back_ns': back_ns} + + +def get_namespace_list(namespace=None): + if not is_multi_asic(): + ns_list = [DEFAULT_NAMESPACE] + + if namespace is None: + namespaces = get_all_namespaces() + ns_list = namespaces['front_ns'] + namespaces['back_ns'] + else: + ns_list = [namespace] + + return ns_list + + +def get_port_table(namespace=None): + """ + Retrieves the ports from all the asic present on the devices + + Returns: + a dict of all the ports + """ + all_ports = {} + ns_list = get_namespace_list(namespace) + + for ns in ns_list: + ports = get_port_table_for_asic(ns) + all_ports.update(ports) + + return all_ports + + +def get_port_table_for_asic(namespace): + + config_db = connect_config_db_for_ns(namespace) + ports = config_db.get_table(PORT_CFG_DB_TABLE) + return ports + + +def get_namespace_for_port(port_name): + + ns_list = get_namespace_list() + port_namespace = None + + for ns in ns_list: + ports = get_port_table_for_asic(ns) + if port_name in ports: + port_namespace = ns + break + + if port_namespace is None: + raise ValueError('Unknown port name {}'.format(port_name)) + + return port_namespace + + +def get_port_role(port_name, namespace=None): + + ports_config = get_port_table(namespace) + if not ports_config[port_name].has_key('role'): + return EXTERNAL_PORT + + role = ports_config[port_name]['role'] + return role + + +def is_port_internal(port_name, namespace=None): + + role = get_port_role(port_name, namespace) + + if role is INTERNAL_PORT: + return True + + return False + + +def is_port_channel_internal(port_channel, namespace=None): + + if not is_multi_asic(): + return False + + ns_list = get_namespace_list(namespace) + + for ns in ns_list: + config_db = connect_config_db_for_ns(ns) + port_channels = config_db.get_table(PORT_CHANNEL_CFG_DB_TABLE) + + if port_channel in port_channels: + members = port_channels[port_channel]['members'] + if is_port_internal(members[0], namespace): + return True + + return False + + +def is_bgp_session_internal(bgp_neigh_ip, namespace=None): + + if not is_multi_asic(): + return False + + ns_list = get_namespace_list(namespace) + + for ns in ns_list: + + config_db = connect_config_db_for_ns(ns) + bgp_sessions = config_db.get_table(BGP_NEIGH_CFG_DB_TABLE) + if bgp_neigh_ip not in bgp_sessions: + continue + + bgp_neigh_name = bgp_sessions[bgp_neigh_ip]['name'] + neighbor_metadata = config_db.get_table( + NEIGH_DEVICE_METADATA_CFG_DB_TABLE) + + if neighbor_metadata[bgp_neigh_name]['type'].lower() == 'asic': + return True + else: + return False + return False From 525b6b4407343141731ee01639c51213b6ce4326 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Thu, 30 Jul 2020 14:00:19 -0700 Subject: [PATCH 07/19] fix compilation issue Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-config-engine/sonic_device_util.py | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index 6de973768fb8..81382a8fa151 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -109,6 +109,32 @@ def is_multi_npu(): num_npus = get_num_npus() return (num_npus > 1) + +def get_all_namespaces(): + """ + In case of MultiAsic platform, Each ASIC will have a linux network namespace created. + So we loop through the databases in different namespaces and depending on the sub_role + decide whether this is a front end ASIC/namespace or a back end one. + """ + front_ns = [] + back_ns = [] + num_npus = get_num_npus() + SonicDBConfig.load_sonic_global_db_config() + + if is_multi_npu(): + for npu in range(num_npus): + namespace = "{}{}".format(NPU_NAME_PREFIX, npu) + config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=namespace) + config_db.connect() + + metadata = config_db.get_table('DEVICE_METADATA') + if metadata['localhost']['sub_role'] == FRONTEND_ASIC_SUB_ROLE: + front_ns.append(namespace) + elif metadata['localhost']['sub_role'] == BACKEND_ASIC_SUB_ROLE: + back_ns.append(namespace) + + return {'front_ns':front_ns, 'back_ns':back_ns} + def get_platform_info(machine_info): if machine_info != None: if machine_info.has_key('onie_platform'): From 2af60055d90da3ec1ac9011ce68adb4c0027cac0 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Wed, 5 Aug 2020 13:43:41 -0700 Subject: [PATCH 08/19] Address review comments Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- .../{multi_asic_device_info.py => multi_asic.py} | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) rename src/sonic-py-common/sonic_py_common/{multi_asic_device_info.py => multi_asic.py} (97%) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic_device_info.py b/src/sonic-py-common/sonic_py_common/multi_asic.py similarity index 97% rename from src/sonic-py-common/sonic_py_common/multi_asic_device_info.py rename to src/sonic-py-common/sonic_py_common/multi_asic.py index 282deaf4864f..58678dfcc507 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic_device_info.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -1,14 +1,13 @@ import glob import importlib import os -from os import name import sys from natsort import natsorted -from sonic_py_common.device_info import CONTAINER_PLATFORM_PATH -from sonic_py_common.device_info import HOST_DEVICE_PATH -from sonic_py_common.device_info import get_platform +from .device_info import CONTAINER_PLATFORM_PATH +from .device_info import HOST_DEVICE_PATH +from .device_info import get_platform from swsssdk import ConfigDBConnector, SonicDBConfig from swsssdk import SonicV2Connector From 3028347d380591559358e95abbfa43b79a198532 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Wed, 5 Aug 2020 13:54:54 -0700 Subject: [PATCH 09/19] reorganize imports Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-py-common/sonic_py_common/multi_asic.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index 58678dfcc507..aa109c431d6d 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -5,12 +5,13 @@ from natsort import natsorted +from swsssdk import ConfigDBConnector +from swsssdk import SonicDBConfig +from swsssdk import SonicV2Connector + from .device_info import CONTAINER_PLATFORM_PATH from .device_info import HOST_DEVICE_PATH from .device_info import get_platform -from swsssdk import ConfigDBConnector, SonicDBConfig -from swsssdk import SonicV2Connector - ASIC_NAME_PREFIX = "asic" NAMESPACE_PATH_GLOB = "/run/netns/*" From c69a6c3e73762ca29219003f1675ffa525529dc5 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Wed, 5 Aug 2020 19:27:17 -0700 Subject: [PATCH 10/19] Fix compilation Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-config-engine/minigraph.py | 4 ++-- src/sonic-config-engine/sonic-cfggen | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index 5ee209d17ddf..fbbe8b8444e3 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -14,7 +14,7 @@ from lxml.etree import QName from portconfig import get_port_config -from sonic_py_common.device_info import get_npu_id_from_name +from sonic_py_common.multi_asic import get_asic_id_from_name """minigraph.py version_added: "1.9" @@ -840,7 +840,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw # hostname is the asic_name, get the asic_id from the asic_name if asic_name is not None: - asic_id = get_npu_id_from_name(asic_name) + asic_id = get_asic_id_from_name(asic_name) else: asic_id = None diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index b062fbda6b0d..fe6306e4c708 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -42,7 +42,7 @@ from minigraph import parse_device_desc_xml from minigraph import parse_asic_sub_role from portconfig import get_port_config, get_port_config_file_name, get_breakout_mode from sonic_py_common.device_info import get_platform, get_system_mac -from sonic_py_common.device_info import get_npu_id_from_name, is_multi_npu +from sonic_py_common.multi_asic import get_asic_id_from_name, is_multi_asic from config_samples import generate_sample_config from config_samples import get_available_config from swsssdk import SonicV2Connector, ConfigDBConnector, SonicDBConfig @@ -243,7 +243,7 @@ def main(): asic_name = args.namespace asic_id = None if asic_name is not None: - asic_id = get_npu_id_from_name(asic_name) + asic_id = get_asic_id_from_name(asic_name) # Load the database config for the namespace from global database json @@ -346,8 +346,8 @@ def main(): env.filters['ip_network'] = ip_network for attr in ['ip', 'network', 'prefixlen', 'netmask', 'broadcast']: env.filters[attr] = partial(prefix_attr, attr) - # Pass the is_multi_npu function as global - env.globals['multi_asic'] = is_multi_npu + # Pass the is_multi_asic function as global + env.globals['multi_asic'] = is_multi_asic template = env.get_template(template_file) print(template.render(sort_data(data))) From ea16670c671ef5ca07f7519243b616d6c6caedb4 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Wed, 5 Aug 2020 21:03:41 -0700 Subject: [PATCH 11/19] fix lgtm warnings Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-config-engine/sonic_device_util.py | 3 +-- src/sonic-py-common/sonic_py_common/device_info.py | 2 +- src/sonic-py-common/sonic_py_common/multi_asic.py | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/sonic-config-engine/sonic_device_util.py b/src/sonic-config-engine/sonic_device_util.py index 81382a8fa151..5bf384d9616d 100644 --- a/src/sonic-config-engine/sonic_device_util.py +++ b/src/sonic-config-engine/sonic_device_util.py @@ -6,8 +6,7 @@ from natsort import natsorted import glob from swsssdk import ConfigDBConnector, SonicDBConfig -from portconfig import get_port_config -from portconfig import get_port_config_file_name + DOCUMENTATION = ''' --- diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index 5397db2d4eec..dce4f37fc30a 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -5,7 +5,7 @@ import yaml # TODD: Replace with swsscommon -from swsssdk import ConfigDBConnector, SonicDBConfig +from swsssdk import ConfigDBConnector USR_SHARE_SONIC_PATH = "/usr/share/sonic" HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index aa109c431d6d..b5a5fcd0e0d5 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -1,7 +1,5 @@ import glob -import importlib import os -import sys from natsort import natsorted @@ -177,6 +175,7 @@ def get_all_namespaces(): def get_namespace_list(namespace=None): if not is_multi_asic(): ns_list = [DEFAULT_NAMESPACE] + return ns_list if namespace is None: namespaces = get_all_namespaces() From 413b06d04d38a57d248aa67dae8ee7b65193246b Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Fri, 7 Aug 2020 11:03:25 -0700 Subject: [PATCH 12/19] use TCP instead of Unix socket Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-py-common/sonic_py_common/multi_asic.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index b5a5fcd0e0d5..a47809a100b6 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -38,8 +38,7 @@ def connect_config_db_for_ns(namespace=DEFAULT_NAMESPACE): handle to the config_db for a namespace ''' SonicDBConfig.load_sonic_global_db_config() - config_db = ConfigDBConnector( - use_unix_socket_path=True, namespace=namespace) + config_db = ConfigDBConnector(namespace=namespace) config_db.connect() return config_db @@ -58,7 +57,7 @@ def connect_to_all_dbs_for_ns(namespace=DEFAULT_NAMESPACE): handle to all the dbs for a namespaces ''' SonicDBConfig.load_sonic_global_db_config() - db = SonicV2Connector(use_unix_socket_path=True, namespace=namespace) + db = SonicV2Connector(namespace=namespace) for db_id in db.get_db_list(): db.connect(db_id) return db From 6a3009c4d43c99ffef9f9e17b26da5e0419f28ac Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Fri, 7 Aug 2020 15:30:02 -0700 Subject: [PATCH 13/19] address review commit Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- .../sonic_py_common/multi_asic.py | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index a47809a100b6..5c63c6ea42d1 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -16,13 +16,14 @@ ASIC_CONF_FILENAME = "asic.conf" FRONTEND_ASIC_SUB_ROLE = "FrontEnd" BACKEND_ASIC_SUB_ROLE = "BackEnd" -EXTERNAL_PORT = 'E' -INTERNAL_PORT = 'I' +EXTERNAL_PORT = 'Ext' +INTERNAL_PORT = 'Int' PORT_CHANNEL_CFG_DB_TABLE = 'PORTCHANNEL' PORT_CFG_DB_TABLE = 'PORT' BGP_NEIGH_CFG_DB_TABLE = 'BGP_NEIGHBOR' NEIGH_DEVICE_METADATA_CFG_DB_TABLE = "DEVICE_NEIGHBOR_METADATA" DEFAULT_NAMESPACE = '' +PORT_ROLE = 'role' def connect_config_db_for_ns(namespace=DEFAULT_NAMESPACE): @@ -130,12 +131,14 @@ def get_asic_id_from_name(asic_name): return None -def get_namespaces(): +def get_namespaces_from_linux(): """ In a multi asic platform, each ASIC is in a Linux Namespace. This method returns list of all the Namespace present on the device - Note: This function can be used only when the config_db is not available + Note: It is preferable to use this function can be used only + when the config_db is not available. + When configdb is available use get_all_namespaces() Returns: List of the namespaces present in the system @@ -229,10 +232,13 @@ def get_namespace_for_port(port_name): def get_port_role(port_name, namespace=None): ports_config = get_port_table(namespace) - if not ports_config[port_name].has_key('role'): + if port_name not in ports_config: + raise ValueError('Unknown port name {}'.format(port_name)) + + if PORT_ROLE not in ports_config[port_name]: return EXTERNAL_PORT - role = ports_config[port_name]['role'] + role = ports_config[port_name][PORT_ROLE] return role @@ -240,7 +246,7 @@ def is_port_internal(port_name, namespace=None): role = get_port_role(port_name, namespace) - if role is INTERNAL_PORT: + if role == INTERNAL_PORT: return True return False @@ -258,9 +264,10 @@ def is_port_channel_internal(port_channel, namespace=None): port_channels = config_db.get_table(PORT_CHANNEL_CFG_DB_TABLE) if port_channel in port_channels: - members = port_channels[port_channel]['members'] - if is_port_internal(members[0], namespace): - return True + if 'members' in port_channel: + members = port_channels[port_channel]['members'] + if is_port_internal(members[0], namespace): + return True return False @@ -283,7 +290,9 @@ def is_bgp_session_internal(bgp_neigh_ip, namespace=None): neighbor_metadata = config_db.get_table( NEIGH_DEVICE_METADATA_CFG_DB_TABLE) - if neighbor_metadata[bgp_neigh_name]['type'].lower() == 'asic': + if ((neighbor_metadata) and + (neighbor_metadata[bgp_neigh_name]['type'].lower() == + ASIC_NAME_PREFIX)): return True else: return False From 7628bbd1b44e9941afefa82af983be5cf9d638bc Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Fri, 7 Aug 2020 15:33:40 -0700 Subject: [PATCH 14/19] change the port in port_config to Ext\Int Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- .../multi_npu_data/sample_port_config-0.ini | 16 ++++++++-------- .../multi_npu_data/sample_port_config-1.ini | 16 ++++++++-------- .../multi_npu_data/sample_port_config-2.ini | 16 ++++++++-------- .../multi_npu_data/sample_port_config-3.ini | 16 ++++++++-------- .../tests/test_multinpu_cfggen.py | 16 ++++++++-------- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini index 824a870fb628..5b2786fd8aa8 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-0.ini @@ -1,9 +1,9 @@ # name lanes alias index asic_port_name role -Ethernet0 33,34,35,36 Ethernet1/1 0 Eth0-ASIC0 E -Ethernet4 29,30,31,32 Ethernet1/2 1 Eth1-ASIC0 E -Ethernet8 41,42,43,44 Ethernet1/3 2 Eth2-ASIC0 E -Ethernet12 37,38,39,40 Ethernet1/4 3 Eth3-ASIC0 E -Ethernet-BP0 13,14,15,16 Ethernet-BP0 0 Eth4-ASIC0 I -Ethernet-BP4 17,18,19,20 Ethernet-BP4 1 Eth5-ASIC0 I -Ethernet-BP8 21,22,23,24 Ethernet-BP8 2 Eth6-ASIC0 I -Ethernet-BP12 25,26,27,28 Ethernet-BP12 3 Eth7-ASIC0 I \ No newline at end of file +Ethernet0 33,34,35,36 Ethernet1/1 0 Eth0-ASIC0 Ext +Ethernet4 29,30,31,32 Ethernet1/2 1 Eth1-ASIC0 Ext +Ethernet8 41,42,43,44 Ethernet1/3 2 Eth2-ASIC0 Ext +Ethernet12 37,38,39,40 Ethernet1/4 3 Eth3-ASIC0 Ext +Ethernet-BP0 13,14,15,16 Ethernet-BP0 0 Eth4-ASIC0 Int +Ethernet-BP4 17,18,19,20 Ethernet-BP4 1 Eth5-ASIC0 Int +Ethernet-BP8 21,22,23,24 Ethernet-BP8 2 Eth6-ASIC0 Int +Ethernet-BP12 25,26,27,28 Ethernet-BP12 3 Eth7-ASIC0 Int \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini index c5f011c2cc6c..9764ede9736a 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-1.ini @@ -1,9 +1,9 @@ # name lanes alias index asic_port_name role -Ethernet16 33,34,35,36 Ethernet1/5 4 Eth0-ASIC1 E -Ethernet20 29,30,31,32 Ethernet1/6 5 Eth1-ASIC1 E -Ethernet24 41,42,43,44 Ethernet1/7 6 Eth2-ASIC1 E -Ethernet28 37,38,39,40 Ethernet1/8 7 Eth3-ASIC1 E -Ethernet-BP16 13,14,15,16 Ethernet-BP16 4 Eth4-ASIC1 I -Ethernet-BP20 17,18,19,20 Ethernet-BP20 5 Eth5-ASIC1 I -Ethernet-BP24 21,22,23,24 Ethernet-BP24 6 Eth6-ASIC1 I -Ethernet-BP28 25,26,27,28 Ethernet-BP28 7 Eth7-ASIC1 I \ No newline at end of file +Ethernet16 33,34,35,36 Ethernet1/5 4 Eth0-ASIC1 Ext +Ethernet20 29,30,31,32 Ethernet1/6 5 Eth1-ASIC1 Ext +Ethernet24 41,42,43,44 Ethernet1/7 6 Eth2-ASIC1 Ext +Ethernet28 37,38,39,40 Ethernet1/8 7 Eth3-ASIC1 Ext +Ethernet-BP16 13,14,15,16 Ethernet-BP16 4 Eth4-ASIC1 Int +Ethernet-BP20 17,18,19,20 Ethernet-BP20 5 Eth5-ASIC1 Int +Ethernet-BP24 21,22,23,24 Ethernet-BP24 6 Eth6-ASIC1 Int +Ethernet-BP28 25,26,27,28 Ethernet-BP28 7 Eth7-ASIC1 Int \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini index 66590b3aec01..b3bc03dbe915 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-2.ini @@ -1,9 +1,9 @@ # name lanes alias index asic_port_name role -Ethernet-BP256 61,62,63,64 Ethernet-BP256 8 Eth0-ASIC2 I -Ethernet-BP260 57,58,59,60 Ethernet-BP260 9 Eth1-ASIC2 I -Ethernet-BP264 53,54,55,56 Ethernet-BP264 10 Eth2-ASIC2 I -Ethernet-BP268 49,50,51,52 Ethernet-BP268 11 Eth3-ASIC2 I -Ethernet-BP272 45,46,47,48 Ethernet-BP272 12 Eth4-ASIC2 I -Ethernet-BP276 41,42,43,44 Ethernet-BP276 13 Eth5-ASIC2 I -Ethernet-BP280 37,38,39,40 Ethernet-BP280 14 Eth6-ASIC2 I -Ethernet-BP284 33,34,35,36 Ethernet-BP284 15 Eth7-ASIC2 I \ No newline at end of file +Ethernet-BP256 61,62,63,64 Ethernet-BP256 8 Eth0-ASIC2 Int +Ethernet-BP260 57,58,59,60 Ethernet-BP260 9 Eth1-ASIC2 Int +Ethernet-BP264 53,54,55,56 Ethernet-BP264 10 Eth2-ASIC2 Int +Ethernet-BP268 49,50,51,52 Ethernet-BP268 11 Eth3-ASIC2 Int +Ethernet-BP272 45,46,47,48 Ethernet-BP272 12 Eth4-ASIC2 Int +Ethernet-BP276 41,42,43,44 Ethernet-BP276 13 Eth5-ASIC2 Int +Ethernet-BP280 37,38,39,40 Ethernet-BP280 14 Eth6-ASIC2 Int +Ethernet-BP284 33,34,35,36 Ethernet-BP284 15 Eth7-ASIC2 Int \ No newline at end of file diff --git a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini index d29f94671163..2fb7f4ae6ad0 100644 --- a/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini +++ b/src/sonic-config-engine/tests/multi_npu_data/sample_port_config-3.ini @@ -1,9 +1,9 @@ # name lanes alias index asic_port_name role -Ethernet-BP384 29,30,31,32 Ethernet-BP384 16 Eth0-ASIC3 I -Ethernet-BP388 25,26,27,28 Ethernet-BP388 17 Eth1-ASIC3 I -Ethernet-BP392 21,22,23,24 Ethernet-BP392 18 Eth2-ASIC3 I -Ethernet-BP396 17,18,19,20 Ethernet-BP396 19 Eth3-ASIC3 I -Ethernet-BP400 13,14,15,16 Ethernet-BP400 20 Eth4-ASIC3 I -Ethernet-BP404 9,10,11,12 Ethernet-BP404 21 Eth5-ASIC3 I -Ethernet-BP408 5,6,7,8 Ethernet-BP408 22 Eth6-ASIC3 I -Ethernet-BP412 1,2,3,4 Ethernet-BP412 23 Eth7-ASIC3 I \ No newline at end of file +Ethernet-BP384 29,30,31,32 Ethernet-BP384 16 Eth0-ASIC3 Int +Ethernet-BP388 25,26,27,28 Ethernet-BP388 17 Eth1-ASIC3 Int +Ethernet-BP392 21,22,23,24 Ethernet-BP392 18 Eth2-ASIC3 Int +Ethernet-BP396 17,18,19,20 Ethernet-BP396 19 Eth3-ASIC3 Int +Ethernet-BP400 13,14,15,16 Ethernet-BP400 20 Eth4-ASIC3 Int +Ethernet-BP404 9,10,11,12 Ethernet-BP404 21 Eth5-ASIC3 Int +Ethernet-BP408 5,6,7,8 Ethernet-BP408 22 Eth6-ASIC3 Int +Ethernet-BP412 1,2,3,4 Ethernet-BP412 23 Eth7-ASIC3 Int \ No newline at end of file diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index c80b570b2343..5a07a2b719ae 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -163,14 +163,14 @@ def test_frontend_asic_ports(self): output = json.loads(self.run_script(argument)) self.assertDictEqual(output, \ { - "Ethernet0": { "admin_status": "up", "alias": "Ethernet1/1", "asic_port_name": "Eth0-ASIC0", "description": "01T2:Ethernet1", "index": "0", "lanes": "33,34,35,36", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, - "Ethernet4": { "admin_status": "up", "alias": "Ethernet1/2", "asic_port_name": "Eth1-ASIC0", "description": "01T2:Ethernet2", "index": "1", "lanes": "29,30,31,32", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, - "Ethernet8": { "alias": "Ethernet1/3", "asic_port_name": "Eth2-ASIC0", "description": "Ethernet1/3", "index": "2", "lanes": "41,42,43,44", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, - "Ethernet12": { "alias": "Ethernet1/4", "asic_port_name": "Eth3-ASIC0", "description": "Ethernet1/4", "index": "3", "lanes": "37,38,39,40", "mtu": "9100", "pfc_asym": "off", "role": "E", "speed": "40000" }, - "Ethernet-BP0": { "admin_status": "up", "alias": "Ethernet-BP0", "asic_port_name": "Eth4-ASIC0", "description": "ASIC2:Eth0-ASIC2", "index": "0", "lanes": "13,14,15,16", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, - "Ethernet-BP4": { "admin_status": "up", "alias": "Ethernet-BP4", "asic_port_name": "Eth5-ASIC0", "description": "ASIC2:Eth1-ASIC2", "index": "1", "lanes": "17,18,19,20", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, - "Ethernet-BP8": { "admin_status": "up", "alias": "Ethernet-BP8", "asic_port_name": "Eth6-ASIC0", "description": "ASIC3:Eth0-ASIC3", "index": "2", "lanes": "21,22,23,24", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }, - "Ethernet-BP12": { "admin_status": "up", "alias": "Ethernet-BP12", "asic_port_name": "Eth7-ASIC0", "description": "ASIC3:Eth1-ASIC3", "index": "3", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "role": "I", "speed": "40000" }}) + "Ethernet0": { "admin_status": "up", "alias": "Ethernet1/1", "asic_port_name": "Eth0-ASIC0", "description": "01T2:Ethernet1", "index": "0", "lanes": "33,34,35,36", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, + "Ethernet4": { "admin_status": "up", "alias": "Ethernet1/2", "asic_port_name": "Eth1-ASIC0", "description": "01T2:Ethernet2", "index": "1", "lanes": "29,30,31,32", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, + "Ethernet8": { "alias": "Ethernet1/3", "asic_port_name": "Eth2-ASIC0", "description": "Ethernet1/3", "index": "2", "lanes": "41,42,43,44", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, + "Ethernet12": { "alias": "Ethernet1/4", "asic_port_name": "Eth3-ASIC0", "description": "Ethernet1/4", "index": "3", "lanes": "37,38,39,40", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, + "Ethernet-BP0": { "admin_status": "up", "alias": "Ethernet-BP0", "asic_port_name": "Eth4-ASIC0", "description": "ASIC2:Eth0-ASIC2", "index": "0", "lanes": "13,14,15,16", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, + "Ethernet-BP4": { "admin_status": "up", "alias": "Ethernet-BP4", "asic_port_name": "Eth5-ASIC0", "description": "ASIC2:Eth1-ASIC2", "index": "1", "lanes": "17,18,19,20", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, + "Ethernet-BP8": { "admin_status": "up", "alias": "Ethernet-BP8", "asic_port_name": "Eth6-ASIC0", "description": "ASIC3:Eth0-ASIC3", "index": "2", "lanes": "21,22,23,24", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }, + "Ethernet-BP12": { "admin_status": "up", "alias": "Ethernet-BP12", "asic_port_name": "Eth7-ASIC0", "description": "ASIC3:Eth1-ASIC3", "index": "3", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "role": "Int", "speed": "40000" }}) def test_frontend_asic_device_neigh(self): argument = "-m {} -p {} -n asic0 --var-json \"DEVICE_NEIGHBOR\"".format(self.sample_graph, self.port_config[0]) From cabc2f34ffbd4c5f8db1d22df3e8afca7972c395 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Mon, 10 Aug 2020 12:40:17 -0700 Subject: [PATCH 15/19] revert the changes in device_info.py Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- .../sonic_py_common/device_info.py | 102 +++++++++++++++++- 1 file changed, 99 insertions(+), 3 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/device_info.py b/src/sonic-py-common/sonic_py_common/device_info.py index dce4f37fc30a..99f818b0f27e 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -1,11 +1,13 @@ +import glob import os import re import subprocess import yaml +from natsort import natsorted # TODD: Replace with swsscommon -from swsssdk import ConfigDBConnector +from swsssdk import ConfigDBConnector, SonicDBConfig USR_SHARE_SONIC_PATH = "/usr/share/sonic" HOST_DEVICE_PATH = USR_SHARE_SONIC_PATH + "/device" @@ -18,6 +20,13 @@ PORT_CONFIG_FILE = "port_config.ini" PLATFORM_JSON_FILE = "platform.json" +# Multi-NPU constants +# TODO: Move Multi-ASIC-related functions and constants to a "multi_asic.py" module +NPU_NAME_PREFIX = "asic" +NAMESPACE_PATH_GLOB = "/run/netns/*" +ASIC_CONF_FILENAME = "asic.conf" +FRONTEND_ASIC_SUB_ROLE = "FrontEnd" +BACKEND_ASIC_SUB_ROLE = "BackEnd" def get_machine_info(): @@ -121,6 +130,30 @@ def get_platform_and_hwsku(): return (platform, hwsku) + +def get_asic_conf_file_path(): + """ + Retrieves the path to the ASIC conguration file on the device + + Returns: + A string containing the path to the ASIC conguration file on success, + None on failure + """ + asic_conf_path_candidates = [] + + asic_conf_path_candidates.append(os.path.join(CONTAINER_PLATFORM_PATH, ASIC_CONF_FILENAME)) + + platform = get_platform() + if platform: + asic_conf_path_candidates.append(os.path.join(HOST_DEVICE_PATH, platform, ASIC_CONF_FILENAME)) + + for asic_conf_file_path in asic_conf_path_candidates: + if os.path.isfile(asic_conf_file_path): + return asic_conf_file_path + + return None + + def get_paths_to_platform_and_hwsku_dirs(): """ Retreives the paths to the device's platform and hardware SKU data @@ -185,9 +218,73 @@ def get_sonic_version_info(): # -# Multi-ASIC functionality +# Multi-NPU functionality # +def get_num_npus(): + asic_conf_file_path = get_asic_conf_file_path() + if asic_conf_file_path is None: + return 1 + with open(asic_conf_file_path) as asic_conf_file: + for line in asic_conf_file: + tokens = line.split('=') + if len(tokens) < 2: + continue + if tokens[0].lower() == 'num_asic': + num_npus = tokens[1].strip() + return int(num_npus) + + +def is_multi_npu(): + num_npus = get_num_npus() + return (num_npus > 1) + + +def get_npu_id_from_name(npu_name): + if npu_name.startswith(NPU_NAME_PREFIX): + return npu_name[len(NPU_NAME_PREFIX):] + else: + return None + + +def get_namespaces(): + """ + In a multi NPU platform, each NPU is in a Linux Namespace. + This method returns list of all the Namespace present on the device + """ + ns_list = [] + for path in glob.glob(NAMESPACE_PATH_GLOB): + ns = os.path.basename(path) + ns_list.append(ns) + return natsorted(ns_list) + + +def get_all_namespaces(): + """ + In case of Multi-Asic platform, Each ASIC will have a linux network namespace created. + So we loop through the databases in different namespaces and depending on the sub_role + decide whether this is a front end ASIC/namespace or a back end one. + """ + front_ns = [] + back_ns = [] + num_npus = get_num_npus() + SonicDBConfig.load_sonic_global_db_config() + + if is_multi_npu(): + for npu in range(num_npus): + namespace = "{}{}".format(NPU_NAME_PREFIX, npu) + config_db = ConfigDBConnector(use_unix_socket_path=True, namespace=namespace) + config_db.connect() + + metadata = config_db.get_table('DEVICE_METADATA') + if metadata['localhost']['sub_role'] == FRONTEND_ASIC_SUB_ROLE: + front_ns.append(namespace) + elif metadata['localhost']['sub_role'] == BACKEND_ASIC_SUB_ROLE: + back_ns.append(namespace) + + return {'front_ns':front_ns, 'back_ns':back_ns} + + def _valid_mac_address(mac): return bool(re.match("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", mac)) @@ -264,4 +361,3 @@ def get_system_routing_stack(): raise OSError("Cannot detect routing stack") return result - From 789a548dd70c91abd692f61673fa2820e584f127 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Wed, 12 Aug 2020 10:25:37 -0700 Subject: [PATCH 16/19] address review comments signoff --- .../tests/test_multinpu_cfggen.py | 3 +-- src/sonic-py-common/sonic_py_common/multi_asic.py | 13 ++++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py index 5a07a2b719ae..13bda903144a 100644 --- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py +++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py @@ -162,8 +162,7 @@ def test_frontend_asic_ports(self): argument = "-m {} -p {} -n asic0 --var-json \"PORT\"".format(self.sample_graph, self.port_config[0]) output = json.loads(self.run_script(argument)) self.assertDictEqual(output, \ - { - "Ethernet0": { "admin_status": "up", "alias": "Ethernet1/1", "asic_port_name": "Eth0-ASIC0", "description": "01T2:Ethernet1", "index": "0", "lanes": "33,34,35,36", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, + {"Ethernet0": { "admin_status": "up", "alias": "Ethernet1/1", "asic_port_name": "Eth0-ASIC0", "description": "01T2:Ethernet1", "index": "0", "lanes": "33,34,35,36", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, "Ethernet4": { "admin_status": "up", "alias": "Ethernet1/2", "asic_port_name": "Eth1-ASIC0", "description": "01T2:Ethernet2", "index": "1", "lanes": "29,30,31,32", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, "Ethernet8": { "alias": "Ethernet1/3", "asic_port_name": "Eth2-ASIC0", "description": "Ethernet1/3", "index": "2", "lanes": "41,42,43,44", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, "Ethernet12": { "alias": "Ethernet1/4", "asic_port_name": "Eth3-ASIC0", "description": "Ethernet1/4", "index": "3", "lanes": "37,38,39,40", "mtu": "9100", "pfc_asym": "off", "role": "Ext", "speed": "40000" }, diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index 5c63c6ea42d1..5303dfa62cea 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -1,6 +1,5 @@ import glob import os - from natsort import natsorted from swsssdk import ConfigDBConnector @@ -11,17 +10,17 @@ from .device_info import HOST_DEVICE_PATH from .device_info import get_platform -ASIC_NAME_PREFIX = "asic" -NAMESPACE_PATH_GLOB = "/run/netns/*" -ASIC_CONF_FILENAME = "asic.conf" -FRONTEND_ASIC_SUB_ROLE = "FrontEnd" -BACKEND_ASIC_SUB_ROLE = "BackEnd" +ASIC_NAME_PREFIX = 'asic' +NAMESPACE_PATH_GLOB = '/run/netns/*' +ASIC_CONF_FILENAME = 'asic.conf' +FRONTEND_ASIC_SUB_ROLE = 'FrontEnd' +BACKEND_ASIC_SUB_ROLE = 'BackEnd' EXTERNAL_PORT = 'Ext' INTERNAL_PORT = 'Int' PORT_CHANNEL_CFG_DB_TABLE = 'PORTCHANNEL' PORT_CFG_DB_TABLE = 'PORT' BGP_NEIGH_CFG_DB_TABLE = 'BGP_NEIGHBOR' -NEIGH_DEVICE_METADATA_CFG_DB_TABLE = "DEVICE_NEIGHBOR_METADATA" +NEIGH_DEVICE_METADATA_CFG_DB_TABLE = 'DEVICE_NEIGHBOR_METADATA' DEFAULT_NAMESPACE = '' PORT_ROLE = 'role' From b65012e1225d50e942b3be259d81b1437a2c997a Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Wed, 12 Aug 2020 12:17:46 -0700 Subject: [PATCH 17/19] For cli get the namespace list from linux Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-py-common/sonic_py_common/multi_asic.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index 5303dfa62cea..481f05c17bf4 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -179,8 +179,10 @@ def get_namespace_list(namespace=None): return ns_list if namespace is None: - namespaces = get_all_namespaces() - ns_list = namespaces['front_ns'] + namespaces['back_ns'] + # there are few commands that needs to work even if the + # config db is not present. So get the namespaces + # list from linux + ns_list = get_namespaces_from_linux() else: ns_list = [namespace] From f1a4f07f2292e94fe844932708691fc02a343b88 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Thu, 13 Aug 2020 14:50:30 -0700 Subject: [PATCH 18/19] fix import spacing Signed-off-by: Arvindsrinivasan Lakshmi Narasimhan --- src/sonic-py-common/sonic_py_common/multi_asic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index 481f05c17bf4..8d2b80c5ad14 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -1,7 +1,7 @@ import glob import os -from natsort import natsorted +from natsort import natsorted from swsssdk import ConfigDBConnector from swsssdk import SonicDBConfig from swsssdk import SonicV2Connector From 0b0cfd51a608f1549db15e35a8095698bde8e4a0 Mon Sep 17 00:00:00 2001 From: Arvindsrinivasan Lakshmi Narasimhan Date: Thu, 13 Aug 2020 16:13:58 -0700 Subject: [PATCH 19/19] address review comments signoff --- src/sonic-py-common/sonic_py_common/multi_asic.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py index 8d2b80c5ad14..966b5d238e25 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -26,7 +26,7 @@ def connect_config_db_for_ns(namespace=DEFAULT_NAMESPACE): - ''' + """ The function connects to the config DB for a given namespace and returns the handle If no namespace is provided, it will connect to the db in the @@ -36,7 +36,7 @@ def connect_config_db_for_ns(namespace=DEFAULT_NAMESPACE): Returns: handle to the config_db for a namespace - ''' + """ SonicDBConfig.load_sonic_global_db_config() config_db = ConfigDBConnector(namespace=namespace) config_db.connect() @@ -44,7 +44,7 @@ def connect_config_db_for_ns(namespace=DEFAULT_NAMESPACE): def connect_to_all_dbs_for_ns(namespace=DEFAULT_NAMESPACE): - ''' + """ The function connects to the DBs for a given namespace and returns the handle If no namespace is provided, it will connect to the db in the @@ -55,7 +55,7 @@ def connect_to_all_dbs_for_ns(namespace=DEFAULT_NAMESPACE): Returns: handle to all the dbs for a namespaces - ''' + """ SonicDBConfig.load_sonic_global_db_config() db = SonicV2Connector(namespace=namespace) for db_id in db.get_db_list():