diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-O28/hwsku.json b/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-O28/hwsku.json index 86d6ec991a64..194730c605af 100644 --- a/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-O28/hwsku.json +++ b/device/mellanox/x86_64-mlnx_msn4700-r0/Mellanox-SN4700-O28/hwsku.json @@ -113,20 +113,28 @@ "subport": "1" }, "Ethernet224": { - "default_brkout_mode": "1x200G[400G,100G,50G,40G,25G,10G,1G]", - "subport": "1" + "default_brkout_mode": "1x200G[400G,100G,50G,40G,25G,10G,1G]", + "subport": "1", + "autoneg": "on", + "role": "Dpc" }, "Ethernet232": { - "default_brkout_mode": "1x200G[400G,100G,50G,40G,25G,10G,1G]", - "subport": "1" + "default_brkout_mode": "1x200G[400G,100G,50G,40G,25G,10G,1G]", + "subport": "1", + "autoneg": "on", + "role": "Dpc" }, "Ethernet240": { - "default_brkout_mode": "1x200G[400G,100G,50G,40G,25G,10G,1G]", - "subport": "1" + "default_brkout_mode": "1x200G[400G,100G,50G,40G,25G,10G,1G]", + "subport": "1", + "autoneg": "on", + "role": "Dpc" }, "Ethernet248": { - "default_brkout_mode": "1x200G[400G,100G,50G,40G,25G,10G,1G]", - "subport": "1" + "default_brkout_mode": "1x200G[400G,100G,50G,40G,25G,10G,1G]", + "subport": "1", + "autoneg": "on", + "role": "Dpc" } } } diff --git a/src/sonic-config-engine/portconfig.py b/src/sonic-config-engine/portconfig.py index 81b3dfb8f5bc..dcc535eed0f1 100644 --- a/src/sonic-config-engine/portconfig.py +++ b/src/sonic-config-engine/portconfig.py @@ -37,7 +37,7 @@ BRKOUT_MODE = "default_brkout_mode" CUR_BRKOUT_MODE = "brkout_mode" INTF_KEY = "interfaces" -OPTIONAL_HWSKU_ATTRIBUTES = ["fec", "autoneg", "subport"] +OPTIONAL_HWSKU_ATTRIBUTES = ["fec", "autoneg", "subport", "role"] BRKOUT_PATTERN = r'(\d{1,6})x(\d{1,6}G?)(\[(\d{1,6}G?,?)*\])?(\((\d{1,6})\))?' BRKOUT_PATTERN_GROUPS = 6 diff --git a/src/sonic-config-engine/tests/sample_hwsku.json b/src/sonic-config-engine/tests/sample_hwsku.json index 3615cda2680b..53754a2eabec 100644 --- a/src/sonic-config-engine/tests/sample_hwsku.json +++ b/src/sonic-config-engine/tests/sample_hwsku.json @@ -268,7 +268,8 @@ "default_brkout_mode": "2x25G(2)+1x50000(2)" }, "Ethernet142": { - "default_brkout_mode": "2x25G(2)+1x50000(2)" + "default_brkout_mode": "2x25G(2)+1x50000(2)", + "role": "Dpc" }, "Ethernet144": { "default_brkout_mode": "1x100000[50G,40000,25G,10000]" diff --git a/src/sonic-config-engine/tests/sample_output/platform_output.json b/src/sonic-config-engine/tests/sample_output/platform_output.json index 4c6cf197c389..15bd4a29da50 100644 --- a/src/sonic-config-engine/tests/sample_output/platform_output.json +++ b/src/sonic-config-engine/tests/sample_output/platform_output.json @@ -908,7 +908,8 @@ "mtu": "9100", "alias": "Eth36/3", "pfc_asym": "off", - "speed": "50000" + "speed": "50000", + "role": "Dpc" }, "Ethernet144": { "index": "37", diff --git a/src/sonic-device-data/tests/hwsku_json_checker b/src/sonic-device-data/tests/hwsku_json_checker index 4abf62c159ba..f2016ed6bb98 100755 --- a/src/sonic-device-data/tests/hwsku_json_checker +++ b/src/sonic-device-data/tests/hwsku_json_checker @@ -7,7 +7,7 @@ import sys # Global variable PORT_ATTRIBUTES = ["default_brkout_mode"] -OPTIONAL_PORT_ATTRIBUTES = ["fec", "autoneg", "port_type", "subport"] +OPTIONAL_PORT_ATTRIBUTES = ["fec", "autoneg", "port_type", "subport", "role"] PORT_REG = "Ethernet(\d+)" HWSKU_JSON = '*hwsku.json' INTF_KEY = "interfaces" 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 d35c39c44b94..8aac9bde4437 100644 --- a/src/sonic-py-common/sonic_py_common/multi_asic.py +++ b/src/sonic-py-common/sonic_py_common/multi_asic.py @@ -7,6 +7,7 @@ from .device_info import get_asic_conf_file_path from .device_info import is_supervisor, is_chassis +from .interface import inband_prefix, backplane_prefix, recirc_prefix, front_panel_prefix ASIC_NAME_PREFIX = 'asic' NAMESPACE_PATH_GLOB = '/run/netns/*' @@ -17,7 +18,8 @@ EXTERNAL_PORT = 'Ext' INTERNAL_PORT = 'Int' INBAND_PORT = 'Inb' -RECIRC_PORT ='Rec' +RECIRC_PORT = 'Rec' +DPU_CONNECT_PORT = 'Dpc' PORT_CHANNEL_MEMBER_CFG_DB_TABLE = 'PORTCHANNEL_MEMBER' PORT_CFG_DB_TABLE = 'PORT' BGP_NEIGH_CFG_DB_TABLE = 'BGP_NEIGHBOR' @@ -323,15 +325,18 @@ def get_port_role(port_name, namespace=None): role = ports_config[PORT_ROLE] return role +def is_role_internal(role=None): + """ + Check if the role belongs to one of the internal variants + """ + if role and role in [INTERNAL_PORT, INBAND_PORT, RECIRC_PORT, DPU_CONNECT_PORT]: + return True + return False -def is_port_internal(port_name, namespace=None): +def is_port_internal(port_name, namespace=None): role = get_port_role(port_name, namespace) - - if role in [INTERNAL_PORT, INBAND_PORT, RECIRC_PORT]: - return True - - return False + return is_role_internal(role) def get_external_ports(port_names, namespace=None): @@ -487,3 +492,21 @@ def get_asic_presence_list(): # This is not multi-asic, all asics should be present. asics_list = list(range(0, get_num_asics())) return asics_list + + +def is_front_panel_port(port, role=None): + """ + @summary: This function will check if the interface is a front-panel port + @return: Boolean + """ + if not port.startswith(front_panel_prefix()): + return False + + if port.startswith((backplane_prefix(), inband_prefix(), recirc_prefix())): + return False + + # subinterfaces + if '.' in port: + return False + + return not is_role_internal(role) diff --git a/src/sonic-py-common/tests/interface_test.py b/src/sonic-py-common/tests/interface_test.py index 4ee6b3ed98d8..a6e454b9385b 100644 --- a/src/sonic-py-common/tests/interface_test.py +++ b/src/sonic-py-common/tests/interface_test.py @@ -2,6 +2,7 @@ import sys from sonic_py_common import interface +from sonic_py_common.multi_asic import is_front_panel_port class TestInterface(object): def test_get_interface_table_name(self): @@ -39,3 +40,14 @@ def test_get_port_table_name(self): assert result == "VLAN_SUB_INTERFACE" result = interface.get_port_table_name("Po0.1001") assert result == "VLAN_SUB_INTERFACE" + + def test_verify_front_panel_api(self): + assert is_front_panel_port("Ethernet0") + assert not is_front_panel_port("Ethernet-BP") + assert not is_front_panel_port("Ethernet-IB") + assert not is_front_panel_port("Ethernet-Rec") + assert not is_front_panel_port("Ethernet254", "Dpc") + assert not is_front_panel_port("Ethernet254", "Int") + assert is_front_panel_port("Ethernet254", "Ext") + assert not is_front_panel_port("Ethernet254.30") + assert not is_front_panel_port("PortConfigDone") diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 050f4433bac6..9522d4247d29 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -601,6 +601,7 @@ "speed": "11100", "tpid": "0x8100", "admin_status": "up", + "role": "Dpc", "autoneg": "on", "adv_speeds": "all", "adv_interface_types": "all", diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/port.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/port.json index 3e8899b6e6da..77f70c57bd94 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/port.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/port.json @@ -728,5 +728,21 @@ ] } } + }, + + "PORT_DPC_ROLE_TEST": { + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "name": "Ethernet0", + "alias": "etp1a", + "lanes": "60, 61", + "speed": 100000, + "role": "Dpc" + } + ] + } + } } } diff --git a/src/sonic-yang-models/yang-models/sonic-port.yang b/src/sonic-yang-models/yang-models/sonic-port.yang index f82d74465c97..c508ed168f1e 100644 --- a/src/sonic-yang-models/yang-models/sonic-port.yang +++ b/src/sonic-yang-models/yang-models/sonic-port.yang @@ -145,9 +145,9 @@ module sonic-port{ leaf role { type string { - pattern "Ext|Int|Inb|Rec"; + pattern "Ext|Int|Inb|Rec|Dpc"; } - description "Internal port or External port for multi-asic platform"; + description "Internal port or External port for multi-asic or SmartSwitch platform"; default "Ext"; }