From a6823ba758d2d2fbe66f74b8ff78263e0d3ac22b Mon Sep 17 00:00:00 2001 From: Sonic Build Admin Date: Mon, 5 Jan 2026 18:08:31 +0000 Subject: [PATCH] [orchagent] support single ASIC VOQ Fixed-System **What I did** Orchagent changes needed to support single ASIC VOQ Fixed-System (#3847) was reverted via (#4035) because vms-kvm-t2 tests were failing. That was because the `isChassisAppDbPresent()` was using an incorrect path to `database_config.json` This PR brings back the original #3847 and fixes the `isChassisAppDbPresent()` to use the correct path. **Why I did it** Single-asic VOQ systems do need #3847 **How I verified it** Tests on vms-kvm-t2 and also single-asic voq systems Verified on vms-kvm-t2 the test_bgp_fact is passing ``` bgp/test_bgp_fact.py::test_bgp_facts[vlab-t2-1-1-0] PASSED [ 25%] bgp/test_bgp_fact.py::test_bgp_facts[vlab-t2-1-1-1] PASSED [ 50%] bgp/test_bgp_fact.py::test_bgp_facts[lvlab-t2-1-2-0] PASSED [ 75%] bgp/test_bgp_fact.py::test_bgp_facts[vlab-t2-1-2-1] PASSED [100%] ``` **Details if related** --- .azure-pipelines/docker-sonic-vs/start.sh | 7 +- .../test-docker-sonic-vs-template.yml | 2 + orchagent/intfsorch.cpp | 7 +- orchagent/main.cpp | 39 ++- orchagent/neighorch.cpp | 10 +- orchagent/p4orch/tests/test_main.cpp | 6 + orchagent/portsorch.cpp | 32 +- tests/conftest.py | 31 +- tests/mock_tests/mock_orchagent_main.cpp | 6 + tests/single_asic_voq_fs/default_config.json | 276 ++++++++++++++++++ 10 files changed, 386 insertions(+), 30 deletions(-) create mode 100644 tests/single_asic_voq_fs/default_config.json diff --git a/.azure-pipelines/docker-sonic-vs/start.sh b/.azure-pipelines/docker-sonic-vs/start.sh index 337661fd091..752c9ff675f 100755 --- a/.azure-pipelines/docker-sonic-vs/start.sh +++ b/.azure-pipelines/docker-sonic-vs/start.sh @@ -61,10 +61,15 @@ else qos_cmd="-j /tmp/qos.json" fi + if [ -f /usr/share/sonic/single_asic_voq_fs/default_config.json ]; then + sonic-cfggen -j /usr/share/sonic/single_asic_voq_fs/default_config.json --print-data > /tmp/voq.json + voq_cmd="-j /tmp/voq.json" + fi + sonic-cfggen -p /usr/share/sonic/device/$PLATFORM/$PLATFORM_CONF -k $HWSKU --print-data > /tmp/ports.json # change admin_status from up to down; Test cases dependent sed -i "s/up/down/g" /tmp/ports.json - sonic-cfggen -j /etc/sonic/init_cfg.json $buffers_cmd $qos_cmd -j /tmp/ports.json --print-data > /etc/sonic/config_db.json + sonic-cfggen -j /etc/sonic/init_cfg.json $buffers_cmd $qos_cmd $voq_cmd -j /tmp/ports.json --print-data > /etc/sonic/config_db.json fi sonic-cfggen -t /usr/share/sonic/templates/copp_cfg.j2 > /etc/sonic/copp_cfg.json diff --git a/.azure-pipelines/test-docker-sonic-vs-template.yml b/.azure-pipelines/test-docker-sonic-vs-template.yml index 3639f9de123..0e826a002f1 100644 --- a/.azure-pipelines/test-docker-sonic-vs-template.yml +++ b/.azure-pipelines/test-docker-sonic-vs-template.yml @@ -180,6 +180,8 @@ jobs: retry=3 IMAGE_NAME=docker-sonic-vs:$(Build.DefinitionName).$(Build.BuildNumber).asan-${{ parameters.asan }} echo $all_tests | xargs -n 1 | xargs -P 8 -I TEST_MODULE sudo DEFAULT_CONTAINER_REGISTRY=publicmirror.azurecr.io/ ./run-tests.sh "$IMAGE_NAME" "$params" "TEST_MODULE" 3 + single_asic_voq_tests="test_portchannel.py test_neighbor.py test_route.py" + echo $single_asic_voq_tests | xargs -n 1 | xargs -P 3 -I TEST_MODULE sudo ./run-tests.sh "$IMAGE_NAME" "--force-recreate-dvs --switch-mode=single_asic_voq_fs" "TEST_MODULE" 3 rm -rf $(Build.ArtifactStagingDirectory)/download displayName: "Run vs tests" diff --git a/orchagent/intfsorch.cpp b/orchagent/intfsorch.cpp index a5fa104c9ab..a19100f7211 100644 --- a/orchagent/intfsorch.cpp +++ b/orchagent/intfsorch.cpp @@ -38,6 +38,7 @@ extern NeighOrch *gNeighOrch; extern string gMySwitchType; extern int32_t gVoqMySwitchId; extern bool gTraditionalFlexCounter; +extern bool isChassisDbInUse(); const int intfsorch_pri = 35; @@ -98,7 +99,7 @@ IntfsOrch::IntfsOrch(DBConnector *db, string tableName, VRFOrch *vrf_orch, DBCon RIF_PLUGIN_FIELD, rifRateSha); - if(gMySwitchType == "voq") + if(isChassisDbInUse()) { //Add subscriber to process VOQ system interface tableName = CHASSIS_APP_SYSTEM_INTERFACE_TABLE_NAME; @@ -1310,7 +1311,7 @@ bool IntfsOrch::addRouterIntfs(sai_object_id_t vrf_id, Port &port, string loopba SWSS_LOG_NOTICE("Create router interface %s MTU %u", port.m_alias.c_str(), port.m_mtu); - if(gMySwitchType == "voq") + if(isChassisDbInUse()) { // Sync the interface of local port/LAG to the SYSTEM_INTERFACE table of CHASSIS_APP_DB voqSyncAddIntf(port.m_alias); @@ -1363,7 +1364,7 @@ bool IntfsOrch::removeRouterIntfs(Port &port) SWSS_LOG_NOTICE("Remove router interface for port %s", port.m_alias.c_str()); - if(gMySwitchType == "voq") + if(isChassisDbInUse()) { // Sync the removal of interface of local port/LAG to the SYSTEM_INTERFACE table of CHASSIS_APP_DB voqSyncDelIntf(port.m_alias); diff --git a/orchagent/main.cpp b/orchagent/main.cpp index 397ae279462..21e63d2df81 100644 --- a/orchagent/main.cpp +++ b/orchagent/main.cpp @@ -17,6 +17,8 @@ extern "C" { #include #include #include +#include +#include #include #include @@ -77,6 +79,12 @@ string gMyHostName = ""; string gMyAsicName = ""; bool gTraditionalFlexCounter = false; uint32_t create_switch_timeout = 0; +bool gMultiAsicVoq = false; + +bool isChassisDbInUse() +{ + return gMultiAsicVoq; +} void usage() { @@ -208,6 +216,18 @@ void getCfgSwitchType(DBConnector *cfgDb, string &switch_type, string &switch_su } +bool isChassisAppDbPresent() +{ + std::ifstream file(SonicDBConfig::DEFAULT_SONIC_DB_CONFIG_FILE); + if (!file.is_open()) return false; + + nlohmann::json db_config; + file >> db_config; + + return db_config.contains("DATABASES") && + db_config["DATABASES"].contains("CHASSIS_APP_DB"); +} + bool getSystemPortConfigList(DBConnector *cfgDb, DBConnector *appDb, vector &sysportcfglist) { Table cfgDeviceMetaDataTable(cfgDb, CFG_DEVICE_METADATA_TABLE_NAME); @@ -617,7 +637,18 @@ int main(int argc, char **argv) //Connect to CHASSIS_APP_DB in redis-server in control/supervisor card as per //connection info in database_config.json - chassis_app_db = make_shared("CHASSIS_APP_DB", 0, true); + if (isChassisAppDbPresent()) + { + gMultiAsicVoq = true; + try + { + chassis_app_db = make_shared("CHASSIS_APP_DB", 0, true); + } + catch (const std::exception& e) + { + SWSS_LOG_NOTICE("CHASSIS_APP_DB not available, operating in standalone VOQ mode"); + } + } } else if (gMySwitchType == "fabric") { @@ -867,7 +898,7 @@ int main(int argc, char **argv) } shared_ptr orchDaemon; - + DBConnector *chassis_db = chassis_app_db.get(); /* * Declare shared pointers for dpu specific databases. * These dpu databases exist on the npu for smartswitch. @@ -884,7 +915,7 @@ int main(int argc, char **argv) else if (gMySwitchType != "fabric") { - orchDaemon = make_shared(&appl_db, &config_db, &state_db, chassis_app_db.get(), zmq_server.get()); + orchDaemon = make_shared(&appl_db, &config_db, &state_db, chassis_db, zmq_server.get()); if (gMySwitchType == "voq") { orchDaemon->setFabricEnabled(true); @@ -894,7 +925,7 @@ int main(int argc, char **argv) } else { - orchDaemon = make_shared(&appl_db, &config_db, &state_db, chassis_app_db.get(), zmq_server.get()); + orchDaemon = make_shared(&appl_db, &config_db, &state_db, chassis_db, zmq_server.get()); } if (gRingMode) { diff --git a/orchagent/neighorch.cpp b/orchagent/neighorch.cpp index 88cba35779f..1eb425a90ad 100644 --- a/orchagent/neighorch.cpp +++ b/orchagent/neighorch.cpp @@ -25,6 +25,8 @@ extern BfdOrch *gBfdOrch; extern size_t gMaxBulkSize; extern string gMyHostName; +extern bool isChassisDbInUse(); + const int neighorch_pri = 30; NeighOrch::NeighOrch(DBConnector *appDb, string tableName, IntfsOrch *intfsOrch, FdbOrch *fdbOrch, PortsOrch *portsOrch, DBConnector *chassisAppDb) : @@ -46,7 +48,7 @@ NeighOrch::NeighOrch(DBConnector *appDb, string tableName, IntfsOrch *intfsOrch, gBfdOrch->attach(this); } - if(gMySwitchType == "voq") + if(isChassisDbInUse()) { //Add subscriber to process VOQ system neigh tableName = CHASSIS_APP_SYSTEM_NEIGH_TABLE_NAME; @@ -794,7 +796,7 @@ bool NeighOrch::getNeighborEntry(const NextHopKey &nexthop, NeighborEntry &neigh { return false; } - if (gMySwitchType == "voq") + if (m_intfsOrch->isRemoteSystemPortIntf(nexthop.alias)) { gPortsOrch->getInbandPort(inbp); assert(inbp.m_alias.length()); @@ -1230,7 +1232,7 @@ bool NeighOrch::addNeighbor(NeighborContext& ctx) NeighborUpdate update = { neighborEntry, macAddress, true }; notify(SUBJECT_TYPE_NEIGH_CHANGE, static_cast(&update)); - if(gMySwitchType == "voq") + if(isChassisDbInUse()) { //Sync the neighbor to add to the CHASSIS_APP_DB voqSyncAddNeigh(alias, ip_address, macAddress, neighbor_entry); @@ -1379,7 +1381,7 @@ bool NeighOrch::removeNeighbor(NeighborContext& ctx, bool disable) NeighborUpdate update = { neighborEntry, MacAddress(), false }; notify(SUBJECT_TYPE_NEIGH_CHANGE, static_cast(&update)); - if(gMySwitchType == "voq") + if(isChassisDbInUse()) { //Sync the neighbor to delete from the CHASSIS_APP_DB voqSyncDelNeigh(alias, ip_address); diff --git a/orchagent/p4orch/tests/test_main.cpp b/orchagent/p4orch/tests/test_main.cpp index 0ad50751bcc..976cc9ec44e 100644 --- a/orchagent/p4orch/tests/test_main.cpp +++ b/orchagent/p4orch/tests/test_main.cpp @@ -38,6 +38,12 @@ sai_object_id_t gUnderlayIfId = 0x101; string gMyAsicName = ""; event_handle_t g_events_handle; +bool gMultiAsicVoq = false; +bool isChassisDbInUse() +{ + return gMultiAsicVoq; +} + #define DEFAULT_BATCH_SIZE 128 #define DEFAULT_MAX_BULK_SIZE 1000 extern int gBatchSize; diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 7f3c29f3c9e..7cc0cb23d8f 100644 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -69,6 +69,8 @@ extern int32_t gVoqMySwitchId; extern string gMyHostName; extern string gMyAsicName; extern event_handle_t g_events_handle; +extern bool isChassisDbInUse(); +extern bool gMultiAsicVoq; // defines ------------------------------------------------------------------------------------------------------------ @@ -989,7 +991,7 @@ PortsOrch::PortsOrch(DBConnector *db, DBConnector *stateDb, vectorlagIdAdd(system_lag_alias, 0); - - if ((int32_t)spa_id <= 0) + if (gMultiAsicVoq) { - SWSS_LOG_ERROR("Failed to allocate unique LAG id for local lag %s rv:%d", lag_alias.c_str(), spa_id); - return false; + // Allocate unique lag id + spa_id = m_lagIdAllocator->lagIdAdd(system_lag_alias, 0); + + if ((int32_t)spa_id <= 0) + { + SWSS_LOG_ERROR("Failed to allocate unique LAG id for local lag %s rv:%d", lag_alias.c_str(), spa_id); + return false; + } } } @@ -7702,7 +7707,7 @@ bool PortsOrch::removeLag(Port lag) m_counterLagTable->hdel("", lag.m_alias); - if (gMySwitchType == "voq") + if (isChassisDbInUse()) { // Free the lag id, if this is local LAG @@ -7815,7 +7820,7 @@ bool PortsOrch::addLagMember(Port &lag, Port &port, string member_status) LagMemberUpdate update = { lag, port, true }; notify(SUBJECT_TYPE_LAG_MEMBER_CHANGE, static_cast(&update)); - if (gMySwitchType == "voq") + if (isChassisDbInUse()) { //Sync to SYSTEM_LAG_MEMBER_TABLE of CHASSIS_APP_DB voqSyncAddLagMember(lag, port, member_status); @@ -7863,7 +7868,7 @@ bool PortsOrch::removeLagMember(Port &lag, Port &port) LagMemberUpdate update = { lag, port, false }; notify(SUBJECT_TYPE_LAG_MEMBER_CHANGE, static_cast(&update)); - if (gMySwitchType == "voq") + if (isChassisDbInUse()) { //Sync to SYSTEM_LAG_MEMBER_TABLE of CHASSIS_APP_DB voqSyncDelLagMember(lag, port); @@ -9100,7 +9105,7 @@ void PortsOrch::updatePortOperStatus(Port &port, sai_port_oper_status_t status) } } - if(gMySwitchType == "voq") + if(isChassisDbInUse()) { if (gIntfsOrch->isLocalSystemPortIntf(port.m_alias)) { @@ -10247,7 +10252,8 @@ void PortsOrch::voqSyncAddLag (Port &lag) // Sync only local lag add to CHASSIS_APP_DB - if (switch_id != gVoqMySwitchId) + if (switch_id != gVoqMySwitchId || + !gMultiAsicVoq) { return; } diff --git a/tests/conftest.py b/tests/conftest.py index 89420cd74c1..527f4b59b3c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -44,6 +44,8 @@ # Voq asics will have 16 fabric ports created (defined in Azure/sonic-buildimage#7629). FABRIC_NUM_PORTS = 16 +SINGLE_ASIC_VOQ_FS = "single_asic_voq_fs" + def ensure_system(cmd): rc, output = subprocess.getstatusoutput(cmd) if rc: @@ -112,6 +114,12 @@ def pytest_addoption(parser): default=False, help="Collect the test coverage information") + parser.addoption("--switch-mode", + action="store", + default=None, + type=str, + help="Set switch mode information") + def random_string(size=4, chars=string.ascii_uppercase + string.digits): return "".join(random.choice(chars) for x in range(size)) @@ -294,7 +302,8 @@ def __init__( newctnname: str = None, ctnmounts: Dict[str, str] = None, buffer_model: str = None, - enable_coverage: bool = False + enable_coverage: bool = False, + switch_mode: str = None ): self.basicd = ["redis-server", "rsyslogd"] self.swssd = [ @@ -317,6 +326,7 @@ def __init__( self.vct = vct self.ctn = None self.enable_coverage = enable_coverage + self.switch_mode = switch_mode self.cleanup = not keeptb @@ -583,7 +593,10 @@ def check_swss_ready(self, timeout: int = 300) -> None: self.get_config_db() metadata = self.config_db.get_entry('DEVICE_METADATA|localhost', '') if metadata.get('switch_type', 'npu') in ['voq', 'fabric']: - num_ports = NUM_PORTS + FABRIC_NUM_PORTS + if self.switch_mode and self.switch_mode == SINGLE_ASIC_VOQ_FS: + num_ports = NUM_PORTS + else: + num_ports = NUM_PORTS + FABRIC_NUM_PORTS # Verify that all ports have been initialized and configured app_db = self.get_app_db() @@ -603,8 +616,9 @@ def _polling_function(): # Verify that fabric ports are monitored in STATE_DB if metadata.get('switch_type', 'npu') in ['voq', 'fabric']: - self.get_state_db() - self.state_db.wait_for_n_keys("FABRIC_PORT_TABLE", FABRIC_NUM_PORTS) + if not self.switch_mode or (self.switch_mode and self.switch_mode != SINGLE_ASIC_VOQ_FS): + self.get_state_db() + self.state_db.wait_for_n_keys("FABRIC_PORT_TABLE", FABRIC_NUM_PORTS) def net_cleanup(self) -> None: """Clean up network, remove extra links.""" @@ -1880,6 +1894,7 @@ def manage_dvs(request) -> str: force_recreate = request.config.getoption("--force-recreate-dvs") graceful_stop = request.config.getoption("--graceful-stop") enable_coverage = request.config.getoption("--enable-coverage") + switch_mode = request.config.getoption("--switch-mode") dvs = None curr_dvs_env = [] # lgtm[py/unused-local-variable] @@ -1911,7 +1926,13 @@ def update_dvs(log_path, new_dvs_env=[]): dvs.get_logs() dvs.destroy() - dvs = DockerVirtualSwitch(name, imgname, keeptb, new_dvs_env, log_path, max_cpu, forcedvs, buffer_model = buffer_model, enable_coverage=enable_coverage) + vol = {} + if switch_mode and switch_mode == SINGLE_ASIC_VOQ_FS: + cwd = os.getcwd() + voq_configs = cwd + "/single_asic_voq_fs" + vol[voq_configs] = {"bind": "/usr/share/sonic/single_asic_voq_fs", "mode": "ro"} + + dvs = DockerVirtualSwitch(name, imgname, keeptb, new_dvs_env, log_path, max_cpu, forcedvs, buffer_model = buffer_model, enable_coverage=enable_coverage, ctnmounts=vol, switch_mode=switch_mode) curr_dvs_env = new_dvs_env diff --git a/tests/mock_tests/mock_orchagent_main.cpp b/tests/mock_tests/mock_orchagent_main.cpp index c14753c62a5..6fa8b19a8b7 100644 --- a/tests/mock_tests/mock_orchagent_main.cpp +++ b/tests/mock_tests/mock_orchagent_main.cpp @@ -24,3 +24,9 @@ sai_redis_communication_mode_t gRedisCommunicationMode = SAI_REDIS_COMMUNICATION VRFOrch *gVrfOrch; void syncd_apply_view() {} + +bool gMultiAsicVoq = false; +bool isChassisDbInUse() +{ + return gMultiAsicVoq; +} diff --git a/tests/single_asic_voq_fs/default_config.json b/tests/single_asic_voq_fs/default_config.json new file mode 100644 index 00000000000..85292999eee --- /dev/null +++ b/tests/single_asic_voq_fs/default_config.json @@ -0,0 +1,276 @@ +{ + "DEVICE_METADATA": { + "localhost": { + "asic_name" : "Asic0", + "switch_type": "voq", + "switch_id": "0", + "max_cores": "8" + } + }, + "SYSTEM_PORT": { + "VS|Asic0|Cpu0": { + "speed": "10000", + "system_port_id": "0", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "0" + }, + "VS|Asic0|Ethernet0": { + "speed": "40000", + "system_port_id": "1", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "1" + }, + "VS|Asic0|Ethernet4": { + "speed": "40000", + "system_port_id": "2", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "2" + }, + "VS|Asic0|Ethernet8": { + "speed": "40000", + "system_port_id": "3", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "3" + }, + "VS|Asic0|Ethernet12": { + "speed": "40000", + "system_port_id": "4", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "4" + }, + "VS|Asic0|Ethernet16": { + "speed": "40000", + "system_port_id": "5", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "5" + }, + "VS|Asic0|Ethernet20": { + "speed": "40000", + "system_port_id": "6", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "6" + }, + "VS|Asic0|Ethernet24": { + "speed": "40000", + "system_port_id": "7", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "7" + }, + "VS|Asic0|Ethernet28": { + "speed": "40000", + "system_port_id": "8", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "8" + }, + "VS|Asic0|Ethernet32": { + "speed": "40000", + "system_port_id": "9", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "9" + }, + "VS|Asic0|Ethernet36": { + "speed": "40000", + "system_port_id": "10", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "10" + }, + "VS|Asic0|Ethernet40": { + "speed": "40000", + "system_port_id": "11", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "11" + }, + "VS|Asic0|Ethernet44": { + "speed": "40000", + "system_port_id": "12", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "12" + }, + "VS|Asic0|Ethernet48": { + "speed": "40000", + "system_port_id": "13", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "13" + }, + "VS|Asic0|Ethernet52": { + "speed": "40000", + "system_port_id": "14", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "14" + }, + "VS|Asic0|Ethernet56": { + "speed": "40000", + "system_port_id": "15", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "15" + }, + "VS|Asic0|Ethernet60": { + "speed": "40000", + "system_port_id": "16", + "switch_id": "0", + "core_index": "0", + "num_voq":8, + "core_port_index": "16" + }, + "VS|Asic0|Ethernet64": { + "speed": "40000", + "system_port_id": "17", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "1" + }, + "VS|Asic0|Ethernet68": { + "speed": "40000", + "system_port_id": "18", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "2" + }, + "VS|Asic0|Ethernet72": { + "speed": "40000", + "system_port_id": "19", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "3" + }, + "VS|Asic0|Ethernet76": { + "speed": "40000", + "system_port_id": "20", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "4" + }, + "VS|Asic0|Ethernet80": { + "speed": "40000", + "system_port_id": "21", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "5" + }, + "VS|Asic0|Ethernet84": { + "speed": "40000", + "system_port_id": "22", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "6" + }, + "VS|Asic0|Ethernet88": { + "speed": "40000", + "system_port_id": "23", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "7" + }, + "VS|Asic0|Ethernet92": { + "speed": "40000", + "system_port_id": "24", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "8" + }, + "VS|Asic0|Ethernet96": { + "speed": "40000", + "system_port_id": "25", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "9" + }, + "VS|Asic0|Ethernet100": { + "speed": "40000", + "system_port_id": "26", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "10" + }, + "VS|Asic0|Ethernet104": { + "speed": "40000", + "system_port_id": "27", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "11" + }, + "VS|Asic0|Ethernet108": { + "speed": "40000", + "system_port_id": "28", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "12" + }, + "VS|Asic0|Ethernet112": { + "speed": "40000", + "system_port_id": "29", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "13" + }, + "VS|Asic0|Ethernet116": { + "speed": "40000", + "system_port_id": "30", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "14" + }, + "VS|Asic0|Ethernet120": { + "speed": "40000", + "system_port_id": "31", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "15" + }, + "VS|Asic0|Ethernet124": { + "speed": "40000", + "system_port_id": "32", + "switch_id": "0", + "core_index": "1", + "num_voq":8, + "core_port_index": "16" + } + } +}