diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2 index dc677204e726..d0b053459bbd 100644 --- a/files/build_templates/docker_image_ctl.j2 +++ b/files/build_templates/docker_image_ctl.j2 @@ -376,27 +376,32 @@ start() { DOCKERCHECK=`docker inspect --type container ${DOCKERNAME} 2>/dev/null` if [ "$?" -eq "0" ]; then - {%- if docker_container_name == "database" %} - DOCKERMOUNT="" + {%- if docker_container_name == "database" and sonic_asic_platform == "vs" %} + echo "Removing existing ${DOCKERNAME} container" + docker rm -f ${DOCKERNAME} {%- else %} - DOCKERMOUNT=`getMountPoint "$DOCKERCHECK"` - {%- endif %} - if [ x"$DOCKERMOUNT" == x"$MOUNTPATH" ]; then - preStartAction {%- if docker_container_name == "database" %} - echo "Starting existing ${DOCKERNAME} container" - docker start ${DOCKERNAME} + DOCKERMOUNT="" {%- else %} - echo "Starting existing ${DOCKERNAME} container with HWSKU $HWSKU" - /usr/local/bin/container start ${DOCKERNAME} + DOCKERMOUNT=`getMountPoint "$DOCKERCHECK"` {%- endif %} - postStartAction - exit $? - fi + if [ x"$DOCKERMOUNT" == x"$MOUNTPATH" ]; then + preStartAction + {%- if docker_container_name == "database" %} + echo "Starting existing ${DOCKERNAME} container" + docker start ${DOCKERNAME} + {%- else %} + echo "Starting existing ${DOCKERNAME} container with HWSKU $HWSKU" + /usr/local/bin/container start ${DOCKERNAME} + {%- endif %} + postStartAction + exit $? + fi - # docker created with a different HWSKU, remove and recreate - echo "Removing obsolete ${DOCKERNAME} container with HWSKU $DOCKERMOUNT" - docker rm -f ${DOCKERNAME} + # docker created with a different HWSKU, remove and recreate + echo "Removing obsolete ${DOCKERNAME} container with HWSKU $DOCKERMOUNT" + docker rm -f ${DOCKERNAME} + {%- endif %} fi {%- if docker_container_name == "database" %} diff --git a/files/image_config/topology/topology.service b/files/image_config/topology/topology.service index eea4bf65230a..73fa4d2d0145 100644 --- a/files/image_config/topology/topology.service +++ b/files/image_config/topology/topology.service @@ -12,5 +12,4 @@ ExecStart=/usr/bin/topology.sh start ExecStop=/usr/bin/topology.sh stop [Install] -WantedBy=multi-user.target - +WantedBy=sonic.target diff --git a/files/image_config/topology/topology.sh b/files/image_config/topology/topology.sh index 2f038095be62..995cb8804379 100755 --- a/files/image_config/topology/topology.sh +++ b/files/image_config/topology/topology.sh @@ -22,12 +22,99 @@ get_hwsku() { echo "${HWSKU}" } +bind_ports_to_ns() { + PLATFORM="$1" + HWSKU="$2" + BIND="$3" + + # Check if the directory exists + if [[ ! -d "/usr/share/sonic/device/$PLATFORM/$HWSKU" ]]; then + echo "Directory /usr/share/sonic/device/$PLATFORM/$HWSKU does not exist" + exit 1 + fi + + # Read NUM_ASIC from asic.conf file + asic_conf="/usr/share/sonic/device/$PLATFORM/asic.conf" + if [[ ! -f "$asic_conf" ]]; then + echo "Error: $asic_conf file not found" + exit 1 + fi + + # Read NUM_ASIC from asic.conf file + num_asic=$(awk -F "=" '/^NUM_ASIC=/ {print $2}' "$asic_conf") + if [[ -z $num_asic ]]; then + echo "NUM_ASIC not found in $asic_conf" + exit 1 + fi + + for ((asic_num = 0; asic_num < num_asic; asic_num++)); do + echo "Processing $PLATFORM/$HWSKU/$asic_num" + asic_dir="/usr/share/sonic/device/$PLATFORM/$HWSKU/$asic_num" + + # Check if the directory exists for the ASIC number + if [[ ! -d "$asic_dir" ]]; then + echo "Directory $asic_dir does not exist" + exit 1 + fi + + lanemap_ini="$asic_dir/lanemap.ini" + + if [[ ! -f "$lanemap_ini" ]]; then + echo "lanemap.ini not found in $asic_dir" + exit 1 + fi + + # Loop through each line of lanemap.ini + while IFS= read -r line; do + # Extract interface before ":" + intf=$(echo "$line" | cut -d ":" -f 1) + if [[ $BIND == true ]]; then + echo "Moving interface $intf to asic$asic_num" + if [[ $intf == "Cpu0" ]]; then + # Extract the numeric part of the interface name + num="${prev#eth}" + # Increment the numeric part + ((num++)) + # Construct the new interface name + cur="eth$num" + echo "Renaming $cur to $intf" + ip link sev dev $cur down + ip link set dev $cur name $intf + fi + ip link set dev $intf netns asic$asic_num + sudo ip netns exec asic$asic_num ip link set dev $intf mtu 9100 + sudo ip netns exec asic$asic_num ip link set $intf up + else + echo "Moving interface $intf back to default ns" + sudo ip netns exec asic$asic_num ip link set dev $intf netns 1 + if [[ $intf == "Cpu0" ]]; then + # Extract the numeric part of the interface name + num="${prev#eth}" + # Increment the numeric part + ((num++)) + # Construct the new interface name + cur="eth$num" + echo "Renaming $intf to $cur" + ip link set dev $intf down + ip link set dev $intf name $cur + ip link set dev $cur up + fi + fi + prev=$intf + done < "$lanemap_ini" + done + exit 0 # Exit script with success +} + + start() { TOPOLOGY_SCRIPT="topology.sh" PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` HWSKU=`get_hwsku` - if [[ $HWSKU != "" ]]; then + if [[ $HWSKU == "msft_"* ]]; then /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT start + elif [[ $HWSKU != "" ]]; then + bind_ports_to_ns "$PLATFORM" "$HWSKU" true else echo "Failed to get HWSKU" exit 1 @@ -38,8 +125,10 @@ stop() { TOPOLOGY_SCRIPT="topology.sh" PLATFORM=`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform` HWSKU=`get_hwsku` - if [[ $HWSKU != "" ]]; then + if [[ $HWSKU == "msft_"* ]]; then /usr/share/sonic/device/$PLATFORM/$HWSKU/$TOPOLOGY_SCRIPT stop + elif [[ $HWSKU != "" ]]; then + bind_ports_to_ns "$PLATFORM" "$HWSKU" false else echo "Failed to get HWSKU" exit 1 diff --git a/platform/vs/kvm-image.mk b/platform/vs/kvm-image.mk index 911b7e9a86be..08d013a66f52 100644 --- a/platform/vs/kvm-image.mk +++ b/platform/vs/kvm-image.mk @@ -2,6 +2,7 @@ SONIC_KVM_IMAGE = sonic-vs.img.gz $(SONIC_KVM_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +$(SONIC_KVM_IMAGE)_LAZY_INSTALLS += $(VS_PLATFORM_MODULE) $(SONIC_KVM_IMAGE)_MACHINE = vs $(SONIC_KVM_IMAGE)_IMAGE_TYPE = kvm ifeq ($(INSTALL_DEBUG_TOOLS),y) diff --git a/platform/vs/one-image.mk b/platform/vs/one-image.mk index a0e176df1497..0f344a101217 100644 --- a/platform/vs/one-image.mk +++ b/platform/vs/one-image.mk @@ -4,6 +4,7 @@ SONIC_ONE_IMAGE = sonic-vs.bin $(SONIC_ONE_IMAGE)_MACHINE = vs $(SONIC_ONE_IMAGE)_IMAGE_TYPE = onie $(SONIC_ONE_IMAGE)_INSTALLS += $(SYSTEMD_SONIC_GENERATOR) +$(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(VS_PLATFORM_MODULE) ifeq ($(INSTALL_DEBUG_TOOLS),y) $(SONIC_ONE_IMAGE)_DOCKERS += $(SONIC_INSTALL_DOCKER_DBG_IMAGES) $(SONIC_ONE_IMAGE)_DOCKERS += $(filter-out $(patsubst %-$(DBG_IMAGE_MARK).gz,%.gz, $(SONIC_INSTALL_DOCKER_DBG_IMAGES)), $(SONIC_INSTALL_DOCKER_IMAGES)) diff --git a/platform/vs/platform-modules-vs.mk b/platform/vs/platform-modules-vs.mk new file mode 100644 index 000000000000..20a5edb94d77 --- /dev/null +++ b/platform/vs/platform-modules-vs.mk @@ -0,0 +1,11 @@ +# VS Platform modules + +VS_PLATFORM_MODULE_VERSION = 1.0 + +export VS_PLATFORM_MODULE_VERSION + +VS_PLATFORM_MODULE = sonic-platform-vs_$(VS_PLATFORM_MODULE_VERSION)_amd64.deb +$(VS_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-vs +$(VS_PLATFORM_MODULE)_DEPENDS = +$(VS_PLATFORM_MODULE)_PLATFORM = x86_64-kvm_x86_64-r0 +SONIC_DPKG_DEBS += $(VS_PLATFORM_MODULE) diff --git a/platform/vs/rules.mk b/platform/vs/rules.mk index 461c3f84dd02..6f67778ea55b 100644 --- a/platform/vs/rules.mk +++ b/platform/vs/rules.mk @@ -6,6 +6,7 @@ include $(PLATFORM_PATH)/docker-gbsyncd-vs.mk include $(PLATFORM_PATH)/docker-ptf.mk include $(PLATFORM_PATH)/docker-ptf-sai.mk include $(PLATFORM_PATH)/libsaithrift-dev.mk +include $(PLATFORM_PATH)/platform-modules-vs.mk include $(PLATFORM_PATH)/one-image.mk include $(PLATFORM_PATH)/onie.mk include $(PLATFORM_PATH)/kvm-image.mk diff --git a/platform/vs/sonic-platform-modules-vs/debian/changelog b/platform/vs/sonic-platform-modules-vs/debian/changelog new file mode 100755 index 000000000000..600264d5112b --- /dev/null +++ b/platform/vs/sonic-platform-modules-vs/debian/changelog @@ -0,0 +1,10 @@ +sonic-platform-vs (1.0) UNRELEASED; urgency=low + + * Initial release of the sonic-platform-vs package. + * This package provides platform-specific modules for SONiC on virtualized VS platforms. + * Included modules: + - Chassis module + * This package is part of the initial release of SONiC for VS platforms. + + -- Deepak Singhal Fri, 26 Feb 2024 12:00:00 +0000 + diff --git a/platform/vs/sonic-platform-modules-vs/debian/compat b/platform/vs/sonic-platform-modules-vs/debian/compat new file mode 100644 index 000000000000..f599e28b8ab0 --- /dev/null +++ b/platform/vs/sonic-platform-modules-vs/debian/compat @@ -0,0 +1 @@ +10 diff --git a/platform/vs/sonic-platform-modules-vs/debian/control b/platform/vs/sonic-platform-modules-vs/debian/control new file mode 100755 index 000000000000..6f416e0d800d --- /dev/null +++ b/platform/vs/sonic-platform-modules-vs/debian/control @@ -0,0 +1,10 @@ +Source: sonic-platform-vs +Section: main +Priority: extra +Maintainer: Deepak Singhal +Build-Depends: debhelper (>= 9), bzip2 +Standards-Version: 3.9.3 + +Package: sonic-platform-vs +Architecture: amd64 +Description: Sonic VS platform Module diff --git a/platform/vs/sonic-platform-modules-vs/debian/rules b/platform/vs/sonic-platform-modules-vs/debian/rules new file mode 100755 index 000000000000..ab27fce12045 --- /dev/null +++ b/platform/vs/sonic-platform-modules-vs/debian/rules @@ -0,0 +1,58 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. + +include /usr/share/dpkg/pkg-info.mk + +# Uncomment this to turn on verbose mode. +export DH_VERBOSE=1 + +PYTHON ?= python3 +PACKAGE_PRE_NAME := sonic-platform-vs +SRC_DIR:= $(shell pwd) + +%: + dh $@ --with python3 --buildsystem=pybuild + +clean: + dh_testdir + dh_testroot + dh_clean + +build: + # Nothing to do + + +binary: binary-arch binary-indep + # Nothing to do + +binary-arch: + # Nothing to do + +binary-indep: +# temporary commented out +# dh_testdir + dh_installdirs + + # Custom package commands + $(PYTHON) setup.py install --root=$(SRC_DIR)/debian/$(PACKAGE_PRE_NAME) --install-layout=deb; + + # Resuming debhelper scripts + dh_testroot + dh_install + dh_installchangelogs + dh_installdocs + dh_systemd_enable + dh_installinit + dh_systemd_start + dh_link + dh_fixperms + dh_compress + dh_strip + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb +.PHONY: build binary binary-arch binary-indep clean diff --git a/platform/vs/sonic-platform-modules-vs/setup.py b/platform/vs/sonic-platform-modules-vs/setup.py new file mode 100755 index 000000000000..803081689748 --- /dev/null +++ b/platform/vs/sonic-platform-modules-vs/setup.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python + +import os +import sys +from setuptools import setup +os.listdir + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize VS platforms', + + packages=['sonic_platform'], + package_dir={'sonic_platform': 'sonic_platform'} +) diff --git a/platform/vs/sonic-platform-modules-vs/sonic_platform/__init__.py b/platform/vs/sonic-platform-modules-vs/sonic_platform/__init__.py new file mode 100644 index 000000000000..290d8cd1a50f --- /dev/null +++ b/platform/vs/sonic-platform-modules-vs/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform"] +from sonic_platform import * diff --git a/platform/vs/sonic-platform-modules-vs/sonic_platform/chassis.py b/platform/vs/sonic-platform-modules-vs/sonic_platform/chassis.py new file mode 100644 index 000000000000..32b8656c2cd0 --- /dev/null +++ b/platform/vs/sonic-platform-modules-vs/sonic_platform/chassis.py @@ -0,0 +1,56 @@ +# Description: Module contains the definitions of SONiC platform APIs +# which provide the chassis specific details +# +# Copyright (c) 2019, Nokia +# All rights reserved. +# + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform_base.module_base import ModuleBase + import os + import json + import threading + +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Chassis(ChassisBase): + """ + VS Platform-specific Chassis class + """ + def __init__(self): + ChassisBase.__init__(self) + self.metadata_file = '/etc/sonic/vs_chassis_metadata.json' + self.metadata = self._read_metadata() + + def _read_metadata(self): + metadata = {} + if os.path.exists(self.metadata_file): + with open(self.metadata_file, 'r') as f: + metadata = json.load(f) + else: + raise FileNotFoundError("Metadata file {} not found".format(self.metadata_file)) + return metadata + + def get_supervisor_slot(self): + if 'sup_slot_num' not in self.metadata: + raise KeyError("sup_slot_num not found in Metadata file {}".format(self.metadata_file)) + return self.metadata['sup_slot_num'] + + def get_linecard_slot(self): + if 'lc_slot_num' not in self.metadata: + raise KeyError("lc_slot_num not found in Metadata file {}".format(self.metadata_file)) + return self.metadata['lc_slot_num'] + + def get_my_slot(self): + if 'is_supervisor' not in self.metadata or 'is_linecard' not in self.metadata: + raise KeyError("is_supervisor or is_linecard not found in metadata file {}".format(self.metadata_file)) + + if self.metadata['is_supervisor']: + return self.get_supervisor_slot() + elif self.metadata['is_linecard']: + return self.get_linecard_slot() + else: + raise ValueError("Invalid configuration: Neither supervisor nor line card") diff --git a/platform/vs/sonic-platform-modules-vs/sonic_platform/platform.py b/platform/vs/sonic-platform-modules-vs/sonic_platform/platform.py new file mode 100644 index 000000000000..0e6a571aaa04 --- /dev/null +++ b/platform/vs/sonic-platform-modules-vs/sonic_platform/platform.py @@ -0,0 +1,40 @@ +# Name: platform.py, version: 1.0 +# +# Description: Module contains the definitions of SONiC platform APIs +# which provide the platform specific details +# +# Copyright (c) 2019, Nokia +# All rights reserved. +# + +try: + from sonic_platform_base.platform_base import PlatformBase +except ImportError as e: + raise ImportError("%s - required module not found" % e) + +platformDict = {'platform': 'vs'} + + +class Platform(PlatformBase): + def __init__(self): + self.platform = self.getPlatform() + try: + from sonic_platform.chassis import Chassis + except ImportError as e: + raise ImportError("%s - required module not found" % e) + self.chassis = Chassis() + + def getPlatformDict(self): + global platformDict + if platformDict: + return platformDict + + def readPlatformName(self): + return self.getPlatformDict().get('platform') + + def getPlatform(self): + platformCls = self.readPlatformName() + return platformCls + + def get_chassis(self): + return self.chassis diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py index dc73a16c082d..66f7f11515ea 100644 --- a/src/sonic-config-engine/minigraph.py +++ b/src/sonic-config-engine/minigraph.py @@ -2184,6 +2184,19 @@ def parse_device_desc_xml(filename): return results +def parse_hostname(filename): + hostName = None + if not os.path.isfile(filename): + return None + root = ET.parse(filename).getroot() + hostname_qn = QName(ns, "Hostname") + for child in root: + if child.tag == str(hostname_qn): + hostName = child.text + break + + return hostName + def parse_asic_sub_role(filename, asic_name): if not os.path.isfile(filename): return None diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen index 4fd5bc2763db..266e5fc23985 100755 --- a/src/sonic-config-engine/sonic-cfggen +++ b/src/sonic-config-engine/sonic-cfggen @@ -29,7 +29,7 @@ import yaml from collections import OrderedDict from config_samples import generate_sample_config, get_available_config from functools import partial -from minigraph import minigraph_encoder, parse_xml, parse_device_desc_xml, parse_asic_sub_role, parse_asic_switch_type +from minigraph import minigraph_encoder, parse_xml, parse_device_desc_xml, parse_asic_sub_role, parse_asic_switch_type, parse_hostname from portconfig import get_port_config, get_breakout_mode from sonic_py_common.multi_asic import get_asic_id_from_name, get_asic_device_id, is_multi_asic from sonic_py_common import device_info @@ -375,18 +375,24 @@ def main(): if args.platform_info: asic_role = None switch_type = None + hostname = None + + if args.minigraph is not None: + hostname = parse_hostname(args.minigraph) + if asic_name is not None: if args.minigraph is not None: asic_role = parse_asic_sub_role(args.minigraph, asic_name) switch_type = parse_asic_switch_type(args.minigraph, asic_name) if ((switch_type is not None and switch_type.lower() == "chassis-packet") or - (asic_role is not None and asic_role.lower() == "backend")): - mac = device_info.get_system_mac(namespace=asic_name) + (asic_role is not None and asic_role.lower() == "backend") or + (platform == device_info.VS_PLATFORM)) : + mac = device_info.get_system_mac(namespace=asic_name, hostname=hostname) else: mac = device_info.get_system_mac() else: - mac = device_info.get_system_mac() + mac = device_info.get_system_mac(hostname=hostname) hardware_data = {'DEVICE_METADATA': {'localhost': { 'platform': platform, diff --git a/src/sonic-device-data/Makefile b/src/sonic-device-data/Makefile index 2077e98f3e98..f14417cea85b 100644 --- a/src/sonic-device-data/Makefile +++ b/src/sonic-device-data/Makefile @@ -15,14 +15,89 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : cp -r -L ../../../device/*/* ./device/ # Create hwsku for virtual switch - for d in `find -L ../../../device -maxdepth 3 -mindepth 3 -type d | grep -vE "(plugins|led-code)"`; do \ + for d in `find -L ../../../device -maxdepth 3 -mindepth 3 -type d | grep -vE "(plugins|led-code|sonic_platform)"`; do \ + # check if hwsku dir exists, if yes, then continue + if [ -d device/x86_64-kvm_x86_64-r0/$$(basename $$d) ]; then \ + continue; \ + fi; \ cp -Lr $$d device/x86_64-kvm_x86_64-r0/ ; \ + if [ -f $$(dirname $$d)/asic.conf ]; then \ + cp $$(dirname $$d)/asic.conf device/x86_64-kvm_x86_64-r0/$$(basename $$d)/asic.conf; \ + fi; \ cp ./sai.vs_profile device/x86_64-kvm_x86_64-r0/$$(basename $$d)/sai.profile; \ cp ./sai_mlnx.vs_profile device/x86_64-kvm_x86_64-r0/$$(basename $$d)/sai_mlnx.profile; \ - grep -v ^# device/x86_64-kvm_x86_64-r0/$$(basename $$d)/port_config.ini | awk '{i=i+1;print "eth"i":"$$2}' > device/x86_64-kvm_x86_64-r0/$$(basename $$d)/lanemap.ini cp ./pai.vs_profile device/x86_64-kvm_x86_64-r0/$$(basename $$d)/pai.profile; \ - grep -v ^# device/x86_64-kvm_x86_64-r0/$$(basename $$d)/port_config.ini | awk '{i=i+1;print "eth"i":"$$2}' > device/x86_64-kvm_x86_64-r0/$$(basename $$d)/lanemap.ini - + cp ./fabriclanemap_vs.ini device/x86_64-kvm_x86_64-r0/$$(basename $$d)/fabriclanemap.ini; \ + if [ -f device/x86_64-kvm_x86_64-r0/$$(basename $$d)/port_config.ini ]; then \ + last_line=$$(tail -n 1 device/x86_64-kvm_x86_64-r0/$$(basename $$d)/port_config.ini); \ + num_columns=$$(echo $$last_line | awk '{print NF}'); \ + i=0; \ + if [ -f $$(dirname $$d)/chassisdb.conf ]; then \ + i=$$(($$i+1)); \ + fi; \ + while IFS= read -r line; do \ + if ! grep -q "^#" <<< "$$line"; then \ + i=$$(($$i+1)); \ + lanes=$$(echo "$$line" | awk '{print $$2}'); \ + echo "eth$$i:$$lanes" >> device/x86_64-kvm_x86_64-r0/$$(basename $$d)/lanemap.ini; \ + if [ $$num_columns -ge 9 ]; then \ + core=$$(echo "$$line" | awk '{print $$8}'); \ + core_port=$$(echo "$$line" | awk '{print $$9}'); \ + echo "eth$$i:$$core,$$core_port" >> device/x86_64-kvm_x86_64-r0/$$(basename $$d)/coreportindexmap.ini; \ + fi; \ + fi; \ + done < device/x86_64-kvm_x86_64-r0/$$(basename $$d)/port_config.ini; \ + fi; \ + if [ -f device/x86_64-kvm_x86_64-r0/$$(basename $$d)/context_config.json ]; then \ + rm device/x86_64-kvm_x86_64-r0/$$(basename $$d)/context_config.json; \ + fi; \ + i=0; \ + if [ -f $$(dirname $$d)/chassisdb.conf ]; then \ + # Append Cpu0 Port in lanemap.ini + if [ -f device/x86_64-kvm_x86_64-r0/$$(basename $$d)/lanemap.ini ]; then \ + echo "Cpu0:999" >> device/x86_64-kvm_x86_64-r0/$$(basename $$d)/lanemap.ini; \ + fi; \ + if [ -f device/x86_64-kvm_x86_64-r0/$$(basename $$d)/coreportindexmap.ini ]; then \ + echo "Cpu0:0,0" >> device/x86_64-kvm_x86_64-r0/$$(basename $$d)/coreportindexmap.ini; \ + fi; \ + i=$$(($$i+1)); \ + fi; \ + subdirs="0 1 2"; \ + for subdir_idx in $$subdirs; do \ + subdir="device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$subdir_idx"; \ + if [ -d "$$subdir" ]; then \ + cp ./sai.vs_profile device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/sai.profile; \ + cp ./fabriclanemap_vs.ini device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/fabriclanemap.ini; \ + if [ -f device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/context_config.json ]; then \ + rm device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/context_config.json; \ + fi; \ + if [ -f device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/port_config.ini ]; then \ + last_line=$$(tail -n 1 device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/port_config.ini); \ + num_columns=$$(echo $$last_line | awk '{print NF}'); \ + while IFS= read -r line; do \ + if ! grep -q "^#" <<< "$$line"; then \ + i=$$(($$i+1)); \ + lanes=$$(echo "$$line" | awk '{print $$2}'); \ + echo "eth$$i:$$lanes" >> device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/lanemap.ini; \ + if [ $$num_columns -ge 9 ]; then \ + core=$$(echo "$$line" | awk '{print $$8}'); \ + core_port=$$(echo "$$line" | awk '{print $$9}'); \ + echo "eth$$i:$$core,$$core_port" >> device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/coreportindexmap.ini; \ + fi; \ + fi; \ + done < device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/port_config.ini; \ + fi; \ + if [ -f $$(dirname $$d)/chassisdb.conf ]; then \ + if [ -f device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/lanemap.ini ]; then \ + echo "Cpu0:999" >> device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/lanemap.ini; \ + i=$$(($$i+1)); \ + fi; \ + if [ -f device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/coreportindexmap.ini ]; then \ + echo "Cpu0:0,0" >> device/x86_64-kvm_x86_64-r0/$$(basename $$d)/$$(basename $$subdir)/coreportindexmap.ini; \ + fi; \ + fi; \ + fi; \ + done; \ done; # Build the package diff --git a/src/sonic-device-data/src/fabriclanemap_vs.ini b/src/sonic-device-data/src/fabriclanemap_vs.ini new file mode 100644 index 000000000000..20ea8fe3a720 --- /dev/null +++ b/src/sonic-device-data/src/fabriclanemap_vs.ini @@ -0,0 +1,16 @@ +fabric1:1 +fabric2:2 +fabric3:3 +fabric4:4 +fabric5:5 +fabric6:6 +fabric7:7 +fabric8:8 +fabric9:9 +fabric10:10 +fabric11:11 +fabric12:12 +fabric13:13 +fabric14:14 +fabric15:15 +fabric16:16 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 eb1a270ceece..1029ae9ce7e8 100644 --- a/src/sonic-py-common/sonic_py_common/device_info.py +++ b/src/sonic-py-common/sonic_py_common/device_info.py @@ -1,6 +1,8 @@ import glob +import hashlib import json import os +import random import re import subprocess @@ -38,6 +40,7 @@ PLATFORM_ENV_CONF_FILENAME = "platform_env.conf" FRONTEND_ASIC_SUB_ROLE = "FrontEnd" BACKEND_ASIC_SUB_ROLE = "BackEnd" +VS_PLATFORM = "x86_64-kvm_x86_64-r0" # Chassis STATE_DB keys CHASSIS_INFO_TABLE = 'CHASSIS_INFO|chassis {}' @@ -671,11 +674,40 @@ def get_all_namespaces(config_db=None): def _valid_mac_address(mac): return bool(re.match("^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$", mac)) +def _modify_mac_for_asic(mac, namespace=None): + if namespace is None: + return mac + if namespace in get_namespaces(): + asic_id = namespace[-1] + mac = mac[:-1] + asic_id + return mac + +def generate_mac_for_vs(hostname, namespace): + mac = None + if hostname is None: + # return random mac address randomize each byte of mac address b/w 0-255 + mac = "22:%02x:%02x:%02x:%02x:%02x" % (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)) + else: + # Calculate the SHA-256 hash of the UTF-8 encoded hostname + hash_value = hashlib.sha256(hostname.encode('utf-8')).digest() + + # Extract the last 6 bytes (48 bits) from the hash value + mac_bytes = hash_value[-6:] + # Set the first octet to 02 to indicate a locally administered MAC address + mac_bytes = bytearray([0x22, mac_bytes[1], mac_bytes[2], mac_bytes[3], mac_bytes[4], mac_bytes[5]]) + # Format the MAC address with colons + mac = ':'.join('{:02x}'.format(byte) for byte in mac_bytes) -def get_system_mac(namespace=None): + return _modify_mac_for_asic(mac, namespace) + +def get_system_mac(namespace=None, hostname=None): version_info = get_sonic_version_info() + platform = get_platform() + + if platform == VS_PLATFORM: + return generate_mac_for_vs(hostname, namespace) - if (version_info['asic_type'] == 'mellanox'): + elif (version_info['asic_type'] == 'mellanox'): # With Mellanox ONIE release(2019.05-5.2.0012) and above # "onie_base_mac" was added to /host/machine.conf: # onie_base_mac=e4:1d:2d:44:5e:80 @@ -692,7 +724,6 @@ def get_system_mac(namespace=None): hw_mac_entry_cmds = [ "sudo decode-syseeprom -m" ] elif (version_info['asic_type'] == 'marvell'): # Try valid mac in eeprom, else fetch it from eth0 - platform = get_platform() machine_key = "onie_machine" machine_vars = get_machine_info() if machine_vars is not None and machine_key in machine_vars: @@ -703,7 +734,6 @@ def get_system_mac(namespace=None): hw_mac_entry_cmds = ["sudo decode-syseeprom -m", profile_cmd, "ip link show eth0 | grep ether | awk '{print $2}'"] elif (version_info['asic_type'] == 'cisco-8000'): # Try to get valid MAC from profile.ini first, else fetch it from syseeprom or eth0 - platform = get_platform() if namespace is not None: profile_cmd = 'cat ' + HOST_DEVICE_PATH + '/' + platform + '/profile.ini | grep ' + namespace + 'switchMacAddress | cut -f2 -d=' else: