From fea134334a22b9de9c1513e310eee5bfe781ebf8 Mon Sep 17 00:00:00 2001 From: malletvapid23 Date: Wed, 11 May 2022 07:57:33 +0800 Subject: [PATCH] [autoneg] add support for remote speed advertisement (#2124) * [autoneg] add support for remote speed advertisement Add support for remote speed advertisement, such that users could easily identify the connection issues when autoneg is enabled. HLD: Azure/SONiC#924 - What I did Add support for remote speed advertisement - How I did it Implementation is done according to the AutoNeg HLD Signed-off-by: Dante Su * fix test failures in dump_state_test.py Signed-off-by: Dante Su * address review comments Signed-off-by: Dante Su * drop PORT_ADV_SPEEDS from state_db_port_status_get() Signed-off-by: Dante Su * address review comments Signed-off-by: Dante Su --- scripts/intfutil | 27 ++++++++++++++++++++-- tests/dump_tests/dump_state_test.py | 7 +++--- tests/intfutil_test.py | 36 ++++++++++++++--------------- tests/mock_tables/state_db.json | 1 + 4 files changed, 48 insertions(+), 23 deletions(-) diff --git a/scripts/intfutil b/scripts/intfutil index c25b896..375e2c1 100755 --- a/scripts/intfutil +++ b/scripts/intfutil @@ -45,6 +45,7 @@ PORT_OPTICS_TYPE = "type" PORT_PFC_ASYM_STATUS = "pfc_asym" PORT_AUTONEG = 'autoneg' PORT_ADV_SPEEDS = 'adv_speeds' +PORT_RMT_ADV_SPEEDS = 'rmt_adv_speeds' PORT_INTERFACE_TYPE = 'interface_type' PORT_ADV_INTERFACE_TYPES = 'adv_interface_types' PORT_TPID = "tpid" @@ -140,8 +141,12 @@ def port_speed_parse(in_speed, optics_type): speed = int(in_speed) if optics_type == OPTICS_TYPE_RJ45 and speed <= 1000: out_speed = '{}M'.format(speed) + elif speed < 1000: + out_speed = '{}M'.format(speed) + elif speed % 1000 >= 100: + out_speed = '{:.1f}G'.format(speed / 1000) else: - out_speed = '{}G'.format(int(speed/1000)) + out_speed = '{:.0f}G'.format(speed / 1000) return out_speed @@ -165,6 +170,23 @@ def appl_db_port_status_get(appl_db, intf_name, status_type): status = ','.join(new_speed_list) return status +def state_db_port_status_get(db, intf_name, field): + """ + Get the port status + """ + full_table_id = PORT_STATE_TABLE_PREFIX + intf_name + status = db.get(db.STATE_DB, full_table_id, field) + if not status: + return "N/A" + if field in [PORT_RMT_ADV_SPEEDS] and status not in ["N/A", "all"]: + optics_type = state_db_port_optics_get(db, intf_name, PORT_OPTICS_TYPE) + speed_list = status.split(',') + new_speed_list = [] + for s in natsorted(speed_list): + new_speed_list.append(port_speed_parse(s, optics_type)) + status = ','.join(new_speed_list) + return status + def port_oper_speed_get(db, intf_name): """ Get port oper speed @@ -566,7 +588,7 @@ class IntfDescription(object): # ========================== interface-autoneg logic ========================== -header_autoneg = ['Interface', 'Auto-Neg Mode', 'Speed', 'Adv Speeds', 'Type', 'Adv Types', 'Oper', 'Admin'] +header_autoneg = ['Interface', 'Auto-Neg Mode', 'Speed', 'Adv Speeds', 'Rmt Adv Speeds', 'Type', 'Adv Types', 'Oper', 'Admin'] class IntfAutoNegStatus(object): @@ -616,6 +638,7 @@ class IntfAutoNegStatus(object): autoneg_mode, port_oper_speed_get(self.db, key), appl_db_port_status_get(self.db, key, PORT_ADV_SPEEDS), + state_db_port_status_get(self.db, key, PORT_RMT_ADV_SPEEDS), appl_db_port_status_get(self.db, key, PORT_INTERFACE_TYPE), appl_db_port_status_get(self.db, key, PORT_ADV_INTERFACE_TYPES), appl_db_port_status_get(self.db, key, PORT_OPER_STATUS), diff --git a/tests/dump_tests/dump_state_test.py b/tests/dump_tests/dump_state_test.py index fb1a211..8e3cda0 100644 --- a/tests/dump_tests/dump_state_test.py +++ b/tests/dump_tests/dump_state_test.py @@ -34,6 +34,7 @@ def compare_json_output(exp_json, rec, exclude_paths=None): | | | | PORT_TABLE|Ethernet0 | +------------------+--------------------------+ | | | | | | | | field | value | | | | | | | | |------------------+--------------------------| | | +| | | | | | rmt_adv_speeds | 10,100,1000 | | | | | | | | | speed | 100000 | | | | | | | | | supported_speeds | 10000,25000,40000,100000 | | | | | | | | +------------------+--------------------------+ | | @@ -120,7 +121,7 @@ def test_identifier_single(self): expected = {'Ethernet0': {'CONFIG_DB': {'keys': [{'PORT|Ethernet0': {'alias': 'etp1', 'description': 'etp1', 'index': '0', 'lanes': '25,26,27,28', 'mtu': '9100', 'pfc_asym': 'off', 'speed': '40000'}}], 'tables_not_found': []}, 'APPL_DB': {'keys': [{'PORT_TABLE:Ethernet0': {'index': '0', 'lanes': '0', 'alias': 'Ethernet0', 'description': 'ARISTA01T2:Ethernet1', 'speed': '25000', 'oper_status': 'down', 'pfc_asym': 'off', 'mtu': '9100', 'fec': 'rs', 'admin_status': 'up'}}], 'tables_not_found': []}, 'ASIC_DB': {'keys': [{'ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF:oid:0xd00000000056d': {'SAI_HOSTIF_ATTR_NAME': 'Ethernet0', 'SAI_HOSTIF_ATTR_OBJ_ID': 'oid:0x10000000004a4', 'SAI_HOSTIF_ATTR_OPER_STATUS': 'true', 'SAI_HOSTIF_ATTR_TYPE': 'SAI_HOSTIF_TYPE_NETDEV', 'SAI_HOSTIF_ATTR_VLAN_TAG': 'SAI_HOSTIF_VLAN_TAG_STRIP'}}, {'ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000004a4': {'NULL': 'NULL', 'SAI_PORT_ATTR_ADMIN_STATE': 'true', 'SAI_PORT_ATTR_MTU': '9122', 'SAI_PORT_ATTR_SPEED': '100000'}}], 'tables_not_found': [], 'vidtorid': {'oid:0xd00000000056d': 'oid:0xd', 'oid:0x10000000004a4': 'oid:0x1690000000001'}}, - 'STATE_DB': {'keys': [{'PORT_TABLE|Ethernet0': {'speed': '100000', 'supported_speeds': '10000,25000,40000,100000'}}], 'tables_not_found': []}}} + 'STATE_DB': {'keys': [{'PORT_TABLE|Ethernet0': {'rmt_adv_speeds': '10,100,1000', 'speed': '100000', 'supported_speeds': '10000,25000,40000,100000'}}], 'tables_not_found': []}}} assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info) # Cause other tests depend and change these paths in the mock_db, this test would fail everytime when a field or a value in changed in this path, creating noise @@ -137,7 +138,7 @@ def test_identifier_multiple(self): {"CONFIG_DB": {"keys": [{"PORT|Ethernet0": {"alias": "etp1", "description": "etp1", "index": "0", "lanes": "25,26,27,28", "mtu": "9100", "pfc_asym": "off", "speed": "40000"}}], "tables_not_found": []}, "APPL_DB": {"keys": [{"PORT_TABLE:Ethernet0": {"index": "0", "lanes": "0", "alias": "Ethernet0", "description": "ARISTA01T2:Ethernet1", "speed": "25000", "oper_status": "down", "pfc_asym": "off", "mtu": "9100", "fec": "rs", "admin_status": "up"}}], "tables_not_found": []}, "ASIC_DB": {"keys": [{"ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF:oid:0xd00000000056d": {"SAI_HOSTIF_ATTR_NAME": "Ethernet0", "SAI_HOSTIF_ATTR_OBJ_ID": "oid:0x10000000004a4", "SAI_HOSTIF_ATTR_OPER_STATUS": "true", "SAI_HOSTIF_ATTR_TYPE": "SAI_HOSTIF_TYPE_NETDEV", "SAI_HOSTIF_ATTR_VLAN_TAG": "SAI_HOSTIF_VLAN_TAG_STRIP"}}, {"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000004a4": {"NULL": "NULL", "SAI_PORT_ATTR_ADMIN_STATE": "true", "SAI_PORT_ATTR_MTU": "9122", "SAI_PORT_ATTR_SPEED": "100000"}}], "tables_not_found": [], "vidtorid": {"oid:0xd00000000056d": "oid:0xd", "oid:0x10000000004a4": "oid:0x1690000000001"}}, - "STATE_DB": {"keys": [{"PORT_TABLE|Ethernet0": {"speed": "100000", "supported_speeds": "10000,25000,40000,100000"}}], "tables_not_found": []}}, + "STATE_DB": {"keys": [{"PORT_TABLE|Ethernet0": {"rmt_adv_speeds": "10,100,1000", "speed": "100000", "supported_speeds": "10000,25000,40000,100000"}}], "tables_not_found": []}}, "Ethernet4": {"CONFIG_DB": {"keys": [{"PORT|Ethernet4": {"admin_status": "up", "alias": "etp2", "description": "Servers0:eth0", "index": "1", "lanes": "29,30,31,32", "mtu": "9100", "pfc_asym": "off", "speed": "40000"}}], "tables_not_found": []}, "APPL_DB": {"keys": [], "tables_not_found": ["PORT_TABLE"]}, @@ -166,7 +167,7 @@ def test_option_db_filtering(self): result = runner.invoke(dump.state, ["port", "Ethernet0", "--db", "ASIC_DB", "--db", "STATE_DB"]) print(result.output) expected = {"Ethernet0": {"ASIC_DB": {"keys": [{"ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF:oid:0xd00000000056d": {"SAI_HOSTIF_ATTR_NAME": "Ethernet0", "SAI_HOSTIF_ATTR_OBJ_ID": "oid:0x10000000004a4", "SAI_HOSTIF_ATTR_OPER_STATUS": "true", "SAI_HOSTIF_ATTR_TYPE": "SAI_HOSTIF_TYPE_NETDEV", "SAI_HOSTIF_ATTR_VLAN_TAG": "SAI_HOSTIF_VLAN_TAG_STRIP"}}, {"ASIC_STATE:SAI_OBJECT_TYPE_PORT:oid:0x10000000004a4": {"NULL": "NULL", "SAI_PORT_ATTR_ADMIN_STATE": "true", "SAI_PORT_ATTR_MTU": "9122", "SAI_PORT_ATTR_SPEED": "100000"}}], "tables_not_found": [], "vidtorid": {"oid:0xd00000000056d": "oid:0xd", "oid:0x10000000004a4": "oid:0x1690000000001"}}, - "STATE_DB": {"keys": [{"PORT_TABLE|Ethernet0": {"speed": "100000", "supported_speeds": "10000,25000,40000,100000"}}], "tables_not_found": []}}} + "STATE_DB": {"keys": [{"PORT_TABLE|Ethernet0": {"rmt_adv_speeds": "10,100,1000", "speed": "100000", "supported_speeds": "10000,25000,40000,100000"}}], "tables_not_found": []}}} assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info) ddiff = compare_json_output(expected, result.output) assert not ddiff, ddiff diff --git a/tests/intfutil_test.py b/tests/intfutil_test.py index 0129573..2023b59 100644 --- a/tests/intfutil_test.py +++ b/tests/intfutil_test.py @@ -71,30 +71,30 @@ """ show_interface_auto_neg_status_output = """\ - Interface Auto-Neg Mode Speed Adv Speeds Type Adv Types Oper Admin ------------ --------------- ------- ------------ ------ ----------- ------ ------- - Ethernet0 enabled 25G 10G,50G CR4 CR4,CR2 down up - Ethernet16 N/A 100M N/A N/A N/A up up - Ethernet24 N/A 1G N/A N/A N/A up up - Ethernet28 N/A 1000M N/A N/A N/A up up - Ethernet32 disabled 40G all N/A all up up - Ethernet36 N/A 10M N/A N/A N/A up up -Ethernet112 N/A 40G N/A N/A N/A up up -Ethernet116 N/A 40G N/A N/A N/A up up -Ethernet120 N/A 40G N/A N/A N/A up up -Ethernet124 N/A 40G N/A N/A N/A up up + Interface Auto-Neg Mode Speed Adv Speeds Rmt Adv Speeds Type Adv Types Oper Admin +----------- --------------- ------- ------------ ---------------- ------ ----------- ------ ------- + Ethernet0 enabled 25G 10G,50G 10M,100M,1G CR4 CR4,CR2 down up + Ethernet16 N/A 100M N/A N/A N/A N/A up up + Ethernet24 N/A 1G N/A N/A N/A N/A up up + Ethernet28 N/A 1000M N/A N/A N/A N/A up up + Ethernet32 disabled 40G all N/A N/A all up up + Ethernet36 N/A 10M N/A N/A N/A N/A up up +Ethernet112 N/A 40G N/A N/A N/A N/A up up +Ethernet116 N/A 40G N/A N/A N/A N/A up up +Ethernet120 N/A 40G N/A N/A N/A N/A up up +Ethernet124 N/A 40G N/A N/A N/A N/A up up """ show_interface_auto_neg_status_Ethernet0_output = """\ - Interface Auto-Neg Mode Speed Adv Speeds Type Adv Types Oper Admin ------------ --------------- ------- ------------ ------ ----------- ------ ------- - Ethernet0 enabled 25G 10G,50G CR4 CR4,CR2 down up + Interface Auto-Neg Mode Speed Adv Speeds Rmt Adv Speeds Type Adv Types Oper Admin +----------- --------------- ------- ------------ ---------------- ------ ----------- ------ ------- + Ethernet0 enabled 25G 10G,50G 10M,100M,1G CR4 CR4,CR2 down up """ show_interface_auto_neg_status_eth9_output = """\ - Interface Auto-Neg Mode Speed Adv Speeds Type Adv Types Oper Admin ------------ --------------- ------- ------------ ------ ----------- ------ ------- - Ethernet32 disabled 40G all N/A all up up + Interface Auto-Neg Mode Speed Adv Speeds Rmt Adv Speeds Type Adv Types Oper Admin +----------- --------------- ------- ------------ ---------------- ------ ----------- ------ ------- + Ethernet32 disabled 40G all N/A N/A all up up """ diff --git a/tests/mock_tables/state_db.json b/tests/mock_tables/state_db.json index fc0fb8b..720c14d 100644 --- a/tests/mock_tables/state_db.json +++ b/tests/mock_tables/state_db.json @@ -683,6 +683,7 @@ "access": "False" }, "PORT_TABLE|Ethernet0": { + "rmt_adv_speeds" : "10,100,1000", "speed" : "100000", "supported_speeds": "10000,25000,40000,100000" },