diff --git a/.azure-pipelines/azure-pipelines-UpgrateVersion.yml b/.azure-pipelines/azure-pipelines-UpgrateVersion.yml index 4f1625b297a9..03593c551cff 100644 --- a/.azure-pipelines/azure-pipelines-UpgrateVersion.yml +++ b/.azure-pipelines/azure-pipelines-UpgrateVersion.yml @@ -18,6 +18,14 @@ schedules: - 202006 always: true +resources: + repositories: + - repository: buildimage + type: github + name: Azure/sonic-buildimage + ref: master + endpoint: build + pool: sonicbld parameters: @@ -43,9 +51,9 @@ stages: - template: azure-pipelines-build.yml parameters: jobFilters: ${{ parameters.jobFilters }} - buildOptions: '${{ variables.VERSION_CONTROL_OPTIONS }} SONIC_BUILD_JOBS=$(nproc) ENABLE_IMAGE_SIGNATURE=y' + buildOptions: '${{ variables.VERSION_CONTROL_OPTIONS }} ENABLE_DOCKER_BASE_PULL=n SONIC_BUILD_JOBS=$(nproc) ENABLE_IMAGE_SIGNATURE=y' preSteps: - - template: template-clean-sonic-slave.yml + - template: .azure-pipelines/template-clean-sonic-slave.yml@buildimage - stage: UpgradeVersions jobs: - job: UpgradeVersions diff --git a/.azure-pipelines/build-commonlib.yml b/.azure-pipelines/build-commonlib.yml new file mode 100644 index 000000000000..df9bcb25ae70 --- /dev/null +++ b/.azure-pipelines/build-commonlib.yml @@ -0,0 +1,19 @@ +pr: none +trigger: none +schedules: +- cron: "0 0 * * *" + displayName: Daily build + branches: + include: + - master + - 202??? +resources: + repositories: + - repository: buildimage + type: github + name: Azure/sonic-buildimage + ref: master + endpoint: build + +jobs: +- template: .azure-pipelines/template-commonlib.yml@buildimage diff --git a/.azure-pipelines/docker-sonic-slave-arm64.yml b/.azure-pipelines/docker-sonic-slave-arm64.yml index 94c6143eed55..6bb9203b49ae 100644 --- a/.azure-pipelines/docker-sonic-slave-arm64.yml +++ b/.azure-pipelines/docker-sonic-slave-arm64.yml @@ -23,6 +23,7 @@ pr: - sonic-slave-stretch - sonic-slave-buster - sonic-slave-bullseye + - .azure-pipelines parameters: - name: 'dists' diff --git a/.azure-pipelines/docker-sonic-slave-armhf.yml b/.azure-pipelines/docker-sonic-slave-armhf.yml index ab0cefebf61f..250bf7400a69 100644 --- a/.azure-pipelines/docker-sonic-slave-armhf.yml +++ b/.azure-pipelines/docker-sonic-slave-armhf.yml @@ -23,6 +23,7 @@ pr: - sonic-slave-stretch - sonic-slave-buster - sonic-slave-bullseye + - .azure-pipelines parameters: - name: 'dists' diff --git a/.azure-pipelines/docker-sonic-slave-template.yml b/.azure-pipelines/docker-sonic-slave-template.yml index 212b449abb18..40a937a8c89a 100644 --- a/.azure-pipelines/docker-sonic-slave-template.yml +++ b/.azure-pipelines/docker-sonic-slave-template.yml @@ -3,6 +3,13 @@ # Add steps that build, run tests, deploy, and more: # https://aka.ms/yaml # Build and push sonic-slave-[buster|jessie|stretch] images for amd64/armhf/arm64 +resources: + repositories: + - repository: buildimage + type: github + name: Azure/sonic-buildimage + ref: master + endpoint: build parameters: - name: arch @@ -38,7 +45,7 @@ jobs: pool: ${{ parameters.pool }} steps: - template: cleanup.yml - - template: template-clean-sonic-slave.yml + - template: .azure-pipelines/template-clean-sonic-slave.yml@buildimage - checkout: self clean: true submodules: recursive @@ -81,6 +88,10 @@ jobs: docker tag $SLAVE_BASE_IMAGE:$SLAVE_BASE_TAG $REGISTRY_SERVER/$SLAVE_BASE_IMAGE_UPLOAD:latest docker tag $SLAVE_BASE_IMAGE:$SLAVE_BASE_TAG $REGISTRY_SERVER/$SLAVE_BASE_IMAGE_UPLOAD:$SLAVE_BASE_TAG + if [ "$SLAVE_BASE_IMAGE_UPLOAD" != "$SLAVE_DIR" ]; then + docker tag $SLAVE_BASE_IMAGE:$SLAVE_BASE_TAG $REGISTRY_SERVER/$SLAVE_DIR:latest-${{ parameters.arch }} + docker tag $SLAVE_BASE_IMAGE:$SLAVE_BASE_TAG $REGISTRY_SERVER/$SLAVE_DIR:$SLAVE_BASE_TAG + fi set +x echo "##vso[task.setvariable variable=VARIABLE_SLAVE_BASE_IMAGE]$SLAVE_BASE_IMAGE_UPLOAD" echo "##vso[task.setvariable variable=VARIABLE_SLAVE_BASE_TAG]$SLAVE_BASE_TAG" @@ -89,6 +100,7 @@ jobs: displayName: Build sonic-slave-${{ parameters.dist }}-${{ parameters.arch }} - task: Docker@2 + condition: ne(variables['Build.Reason'], 'PullRequest') displayName: Upload image inputs: containerRegistry: ${{ parameters.registry_conn }} @@ -97,3 +109,13 @@ jobs: tags: | $(VARIABLE_SLAVE_BASE_TAG) latest + - ${{ if ne(parameters.arch, 'amd64') }}: + - task: Docker@2 + condition: ne(variables['Build.Reason'], 'PullRequest') + displayName: Upload image ${{ parameters.dist }} + inputs: + containerRegistry: ${{ parameters.registry_conn }} + repository: "sonic-slave-${{ parameters.dist }}" + command: push + tags: | + $(VARIABLE_SLAVE_BASE_TAG) diff --git a/.azure-pipelines/docker-sonic-slave.yml b/.azure-pipelines/docker-sonic-slave.yml index a0b156bfde19..bf5fce77a722 100644 --- a/.azure-pipelines/docker-sonic-slave.yml +++ b/.azure-pipelines/docker-sonic-slave.yml @@ -24,6 +24,7 @@ pr: - sonic-slave-buster - sonic-slave-bullseye - src/sonic-build-hooks + - .azure-pipelines parameters: - name: 'arches' diff --git a/.azure-pipelines/template-commonlib.yml b/.azure-pipelines/template-commonlib.yml new file mode 100644 index 000000000000..0e42cb4e17ac --- /dev/null +++ b/.azure-pipelines/template-commonlib.yml @@ -0,0 +1,34 @@ +jobs: +- job: Build + timeoutInMinutes: 120 + pool: sonicbld + steps: + - checkout: self + clean: true + submodules: recursive + - script: | + set -ex + case $(Build.SourceBranchName) in + 202012 | 202106) + bldenv=buster + ;; + *) + bldenv=bullseye + ;; + esac + BLDENV=$bldenv make -f Makefile.work configure PLATFORM=vs ENABLE_DOCKER_BASE_PULL=y + echo "##vso[task.setvariable variable=bldenv;]$bldenv" + displayName: Make configure + - script: | + set -ex + LIBNL3_VERSION_BASE=$(grep "LIBNL3_VERSION_BASE =" rules/libnl3.mk | awk '{print$3}') + LIBNL3_VERSION=$(grep "LIBNL3_VERSION =" rules/libnl3.mk | awk '{print$3}' | sed -e "s/(//" -e "s/)//" -e "s/\\$//" -e "s/LIBNL3_VERSION_BASE/$LIBNL3_VERSION_BASE/") + BLDENV=$(bldenv) make -f Makefile.work target/debs/$(bldenv)/libnl-3-200_${LIBNL3_VERSION}_amd64.deb ENABLE_DOCKER_BASE_PULL=y + + LIBYANG_VERSION_BASE=$(grep "LIBYANG_VERSION_BASE =" rules/libyang.mk | awk '{print$3}') + LIBYANG_VERSION=$(grep "LIBYANG_VERSION =" rules/libyang.mk | awk '{print$3}' | sed -e "s/\\$//" -e "s/(//" -e "s/)//" -e "s/LIBYANG_VERSION_BASE/$LIBYANG_VERSION_BASE/") + BLDENV=$(bldenv) make -f Makefile.work target/debs/$(bldenv)/libyang_${LIBYANG_VERSION}_amd64.deb + find target -name *.deb | xargs -i cp {} $(Build.ArtifactStagingDirectory) + displayName: Make common lib packages + - publish: $(Build.ArtifactStagingDirectory) + artifact: common-lib diff --git a/build_debian.sh b/build_debian.sh index 62de5a8218fb..c509b7097151 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -492,6 +492,7 @@ export build_version="${SONIC_IMAGE_VERSION}" export debian_version="$(cat $FILESYSTEM_ROOT/etc/debian_version)" export kernel_version="${kversion}" export asic_type="${sonic_asic_platform}" +export asic_subtype="${TARGET_MACHINE}" export commit_id="$(git rev-parse --short HEAD)" export branch="$(git rev-parse --abbrev-ref HEAD)" export release="$(if [ -f $FILESYSTEM_ROOT/etc/sonic/sonic_release ]; then cat $FILESYSTEM_ROOT/etc/sonic/sonic_release; fi)" diff --git a/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json index 584a14b9d942..a3b204e20d8d 100644 --- a/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as5835_54t-r0/pmon_daemon_control.json @@ -1,5 +1,5 @@ { "skip_ledd": true, - "skip_thermalctld": true + "skip_pcied": true } diff --git a/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json index 59bdebeb4b52..a3b204e20d8d 100644 --- a/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7712_32x-r0/pmon_daemon_control.json @@ -1,5 +1,5 @@ { "skip_ledd": true, - "skip_thermalctld": true, "skip_pcied": true } + diff --git a/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json index 0d3f1fb4561d..a3b204e20d8d 100644 --- a/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as7726_32x-r0/pmon_daemon_control.json @@ -1,6 +1,5 @@ { "skip_ledd": true, - "skip_pcied": true, - "skip_thermalctld": true + "skip_pcied": true } diff --git a/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json index 584a14b9d942..a3b204e20d8d 100644 --- a/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json +++ b/device/accton/x86_64-accton_as9716_32d-r0/pmon_daemon_control.json @@ -1,5 +1,5 @@ { "skip_ledd": true, - "skip_thermalctld": true + "skip_pcied": true } diff --git a/dockers/docker-orchagent/enable_counters.py b/dockers/docker-orchagent/enable_counters.py index 7d25643bba43..c45a931e0553 100755 --- a/dockers/docker-orchagent/enable_counters.py +++ b/dockers/docker-orchagent/enable_counters.py @@ -38,16 +38,18 @@ def enable_rates(): def enable_counters(): db = swsssdk.ConfigDBConnector() db.connect() - enable_counter_group(db, 'PORT') - enable_counter_group(db, 'RIF') - enable_counter_group(db, 'QUEUE') - enable_counter_group(db, 'PFCWD') - enable_counter_group(db, 'PG_WATERMARK') - enable_counter_group(db, 'PG_DROP') - enable_counter_group(db, 'QUEUE_WATERMARK') - enable_counter_group(db, 'BUFFER_POOL_WATERMARK') - enable_counter_group(db, 'PORT_BUFFER_DROP') - enable_counter_group(db, 'ACL') + default_enabled_counters = ['PORT', 'RIF', 'QUEUE', 'PFCWD', 'PG_WATERMARK', 'PG_DROP', + 'QUEUE_WATERMARK', 'BUFFER_POOL_WATERMARK', 'PORT_BUFFER_DROP', 'ACL'] + + # Enable those default counters + for key in default_enabled_counters: + enable_counter_group(db, key) + + # Set FLEX_COUNTER_DELAY_STATUS to false for those non-default counters + keys = db.get_keys('FLEX_COUNTER_TABLE') + for key in keys: + if key not in default_enabled_counters: + enable_counter_group(db, key) enable_rates() diff --git a/dockers/docker-orchagent/orchagent.sh b/dockers/docker-orchagent/orchagent.sh index aaa047a42036..7585e4896cf4 100755 --- a/dockers/docker-orchagent/orchagent.sh +++ b/dockers/docker-orchagent/orchagent.sh @@ -5,6 +5,7 @@ SWSS_VARS_FILE=/usr/share/sonic/templates/swss_vars.j2 # Retrieve SWSS vars from sonic-cfggen SWSS_VARS=$(sonic-cfggen -d -y /etc/sonic/sonic_version.yml -t $SWSS_VARS_FILE) || exit 1 export platform=$(echo $SWSS_VARS | jq -r '.asic_type') +export sub_platform=$(echo $SWSS_VARS | jq -r '.asic_subtype') MAC_ADDRESS=$(echo $SWSS_VARS | jq -r '.mac') if [ "$MAC_ADDRESS" == "None" ] || [ -z "$MAC_ADDRESS" ]; then diff --git a/dockers/docker-orchagent/tunnel_packet_handler.py b/dockers/docker-orchagent/tunnel_packet_handler.py index 3d9b48b450b6..682316eb6d49 100755 --- a/dockers/docker-orchagent/tunnel_packet_handler.py +++ b/dockers/docker-orchagent/tunnel_packet_handler.py @@ -51,6 +51,10 @@ def __init__(self): self._portchannel_intfs = None self.up_portchannels = None self.netlink_api = IPRoute() + self.sniffer = None + self.self_ip = '' + self.packet_filter = '' + self.sniff_intfs = [] @property def portchannel_intfs(self): @@ -270,6 +274,39 @@ def sniffer_restart_required(self, messages): return True return False + def start_sniffer(self): + """ + Starts an AsyncSniffer and waits for it to inititalize fully + """ + self.sniffer = AsyncSniffer( + iface=self.sniff_intfs, + filter=self.packet_filter, + prn=self.ping_inner_dst, + store=0 + ) + self.sniffer.start() + + while not hasattr(self.sniffer, 'stop_cb'): + time.sleep(0.1) + + def ping_inner_dst(self, packet): + """ + Pings the inner destination IP for an encapsulated packet + + Args: + packet: The encapsulated packet received + """ + inner_packet_type = self.get_inner_pkt_type(packet) + if inner_packet_type and packet[IP].dst == self.self_ip: + cmds = ['timeout', '0.2', 'ping', '-c1', + '-W1', '-i0', '-n', '-q'] + if inner_packet_type == IPv6: + cmds.append('-6') + dst_ip = packet[IP].payload[inner_packet_type].dst + cmds.append(dst_ip) + logger.log_info("Running command '{}'".format(' '.join(cmds))) + subprocess.run(cmds, stdout=subprocess.DEVNULL) + def listen_for_tunnel_pkts(self): """ Listens for tunnel packets that are trapped to CPU @@ -277,59 +314,28 @@ def listen_for_tunnel_pkts(self): These packets may be trapped if there is no neighbor info for the inner packet destination IP in the hardware. """ - - def _ping_inner_dst(packet): - """ - Pings the inner destination IP for an encapsulated packet - - Args: - packet: The encapsulated packet received - """ - inner_packet_type = self.get_inner_pkt_type(packet) - if inner_packet_type and packet[IP].dst == self_ip: - cmds = ['timeout', '0.2', 'ping', '-c1', - '-W1', '-i0', '-n', '-q'] - if inner_packet_type == IPv6: - cmds.append('-6') - dst_ip = packet[IP].payload[inner_packet_type].dst - cmds.append(dst_ip) - logger.log_info("Running command '{}'".format(' '.join(cmds))) - subprocess.run(cmds, stdout=subprocess.DEVNULL) - - self_ip, peer_ip = self.get_ipinip_tunnel_addrs() - if self_ip is None or peer_ip is None: + self.self_ip, peer_ip = self.get_ipinip_tunnel_addrs() + if self.self_ip is None or peer_ip is None: logger.log_notice('Could not get tunnel addresses from ' 'config DB, exiting...') return None - packet_filter = 'host {} and host {}'.format(self_ip, peer_ip) + self.packet_filter = 'host {} and host {}'.format(self.self_ip, peer_ip) logger.log_notice('Starting tunnel packet handler for {}' - .format(packet_filter)) + .format(self.packet_filter)) - sniff_intfs = self.get_up_portchannels() - logger.log_info("Listening on interfaces {}".format(sniff_intfs)) + self.sniff_intfs = self.get_up_portchannels() + logger.log_info("Listening on interfaces {}".format(self.sniff_intfs)) - sniffer = AsyncSniffer( - iface=sniff_intfs, - filter=packet_filter, - prn=_ping_inner_dst, - store=0 - ) - sniffer.start() + self.start_sniffer() while True: msgs = self.wait_for_netlink_msgs() if self.sniffer_restart_required(msgs): - sniffer.stop() + self.sniffer.stop() sniff_intfs = self.get_up_portchannels() logger.log_notice('Restarting tunnel packet handler on ' 'interfaces {}'.format(sniff_intfs)) - sniffer = AsyncSniffer( - iface=sniff_intfs, - filter=packet_filter, - prn=_ping_inner_dst, - store=0 - ) - sniffer.start() + self.start_sniffer() def run(self): """ diff --git a/files/build_templates/sonic_version.yml.j2 b/files/build_templates/sonic_version.yml.j2 index 34486061ea8a..6e3f3acac95a 100644 --- a/files/build_templates/sonic_version.yml.j2 +++ b/files/build_templates/sonic_version.yml.j2 @@ -7,6 +7,9 @@ debian_version: '{{ debian_version }}' kernel_version: '{{ kernel_version }}' {% endif -%} asic_type: {{ asic_type }} +{% if asic_subtype is defined and asic_subtype != '' -%} +asic_subtype: '{{ asic_subtype }}' +{% endif -%} commit_id: '{{ commit_id }}' branch: '{{ branch }}' {% if release is defined and release != '' -%} diff --git a/files/build_templates/swss_vars.j2 b/files/build_templates/swss_vars.j2 index df5e4d038f51..1cd95d16a6d6 100644 --- a/files/build_templates/swss_vars.j2 +++ b/files/build_templates/swss_vars.j2 @@ -1,5 +1,8 @@ { "asic_type": "{{ asic_type }}", + {% if asic_subtype is defined and asic_subtype != '' -%} + "asic_subtype": "{{ asic_subtype }}", + {% endif -%} "asic_id": "{{ DEVICE_METADATA.localhost.asic_id }}", "mac": "{{ DEVICE_METADATA.localhost.mac }}", "resource_type": "{{ DEVICE_METADATA.localhost.resource_type }}", diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk index b4f28f125687..1236e06d6240 100644 --- a/platform/broadcom/sai-modules.mk +++ b/platform/broadcom/sai-modules.mk @@ -1,6 +1,6 @@ # Broadcom SAI modules -BRCM_OPENNSL_KERNEL_VERSION = 6.0.0.13 +BRCM_OPENNSL_KERNEL_VERSION = 6.1.0.3 BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb $(BRCM_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules @@ -10,7 +10,7 @@ $(BRCM_OPENNSL_KERNEL)_MACHINE = broadcom SONIC_DPKG_DEBS += $(BRCM_OPENNSL_KERNEL) # SAI bcm modules for DNX family ASIC -BRCM_DNX_OPENNSL_KERNEL_VERSION = 6.0.0.13 +BRCM_DNX_OPENNSL_KERNEL_VERSION = 6.1.0.3 BRCM_DNX_OPENNSL_KERNEL = opennsl-modules-dnx_$(BRCM_DNX_OPENNSL_KERNEL_VERSION)_amd64.deb $(BRCM_DNX_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules-dnx diff --git a/platform/broadcom/sai.mk b/platform/broadcom/sai.mk index e23515a1f5ea..1ec8d915e5bd 100644 --- a/platform/broadcom/sai.mk +++ b/platform/broadcom/sai.mk @@ -1,5 +1,5 @@ -LIBSAIBCM_VERSION = 6.0.0.13-3 -LIBSAIBCM_BRANCH_NAME = REL_6.0 +LIBSAIBCM_VERSION = 6.1.0.3 +LIBSAIBCM_BRANCH_NAME = REL_6.1 LIBSAIBCM_URL_PREFIX = "https://sonicstorage.blob.core.windows.net/public/sai/bcmsai/$(LIBSAIBCM_BRANCH_NAME)/$(LIBSAIBCM_VERSION)" BRCM_SAI = libsaibcm_$(LIBSAIBCM_VERSION)_amd64.deb diff --git a/platform/broadcom/saibcm-modules-dnx b/platform/broadcom/saibcm-modules-dnx index 3fc83d5e5f9d..6bf58f8310bc 160000 --- a/platform/broadcom/saibcm-modules-dnx +++ b/platform/broadcom/saibcm-modules-dnx @@ -1 +1 @@ -Subproject commit 3fc83d5e5f9d1abad3ddf7fa6767b8cdd6121232 +Subproject commit 6bf58f8310bcb29168ae5b2dabed84fc942429fc diff --git a/platform/broadcom/saibcm-modules/debian/changelog b/platform/broadcom/saibcm-modules/debian/changelog index e9e36aaaf302..0ff357c57279 100644 --- a/platform/broadcom/saibcm-modules/debian/changelog +++ b/platform/broadcom/saibcm-modules/debian/changelog @@ -1,3 +1,9 @@ +opennsl (6.1.0.3) unstable; urgency=medium + + * Update to Broadcom SAI 6.1.0.3 + + -- Tejaswini Chadaga Fri, 24 MAR 2022 12:30:00 +0000 + opennsl (6.0.0.13) unstable; urgency=medium * Update to Broadcom SAI 6.0.0.13 diff --git a/platform/broadcom/saibcm-modules/make/Make.config b/platform/broadcom/saibcm-modules/make/Make.config index b6f42bf65c48..01869634e295 100644 --- a/platform/broadcom/saibcm-modules/make/Make.config +++ b/platform/broadcom/saibcm-modules/make/Make.config @@ -120,7 +120,12 @@ ifndef SDKBUILD SDKBUILD :=build endif +ifdef SDK_OUTDIR +BLDROOT = ${SDK_OUTDIR}/${SDKBUILD}/$(if ${BLDCONFIG},${BLDCONFIG}/)${target}${all_suffix}${bldroot_suffix} +export DEST_DIR := ${SDK_OUTDIR}/${SDKBUILD}$(if ${BLDCONFIG},/${BLDCONFIG})$(DEST_DIR_SUFFIX) +else BLDROOT = ${SDK}/${SDKBUILD}/$(if ${BLDCONFIG},${BLDCONFIG}/)${target}${all_suffix}${bldroot_suffix} +endif endif # ifeq "$(HOSTTYPE)" "Windows2000PC" diff --git a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile index 3dc6425e6ee0..7a342f6ef60e 100644 --- a/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile +++ b/platform/broadcom/saibcm-modules/systems/linux/user/common/Makefile @@ -69,8 +69,12 @@ kernel-override=linux-$(platform) ifdef BLDCONFIG KERN_BLDROOT=${SDK}/${SDKBUILD}/${BLDCONFIG}/$(kernel-override)$(bldroot_suffix) else +ifdef SDK_OUTDIR +KERN_BLDROOT=${SDK_OUTDIR}/${SDKBUILD}/$(kernel-override)$(bldroot_suffix) +else KERN_BLDROOT=${SDK}/${SDKBUILD}/$(kernel-override)$(bldroot_suffix) endif +endif ifeq (,$(kernel_version)) kernel_version=2_4 diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..3b9bb607f632 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/sonic_platform/fan_drawer.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_fan_drawer import PddfFanDrawer +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(PddfFanDrawer): + """PDDF Platform-Specific Fan-Drawer class""" + + def __init__(self, tray_idx, pddf_data=None, pddf_plugin_data=None): + # idx is 0-based + PddfFanDrawer.__init__(self, tray_idx, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/sonic_platform/thermal.py index 5b829fc26caa..77d6ec7ae886 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/sonic_platform/thermal.py @@ -11,7 +11,7 @@ class Thermal(PddfThermal): """PDDF Platform-Specific Thermal class""" - def __init__(self, index, pddf_data=None, pddf_plugin_data=None): - PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data) + def __init__(self, index, pddf_data=None, pddf_plugin_data=None, is_psu_thermal=False, psu_index=0): + PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data, is_psu_thermal, psu_index) # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..3b9bb607f632 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/sonic_platform/fan_drawer.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_fan_drawer import PddfFanDrawer +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(PddfFanDrawer): + """PDDF Platform-Specific Fan-Drawer class""" + + def __init__(self, tray_idx, pddf_data=None, pddf_plugin_data=None): + # idx is 0-based + PddfFanDrawer.__init__(self, tray_idx, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/sonic_platform/thermal.py index 5b829fc26caa..77d6ec7ae886 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/sonic_platform/thermal.py @@ -11,7 +11,7 @@ class Thermal(PddfThermal): """PDDF Platform-Specific Thermal class""" - def __init__(self, index, pddf_data=None, pddf_plugin_data=None): - PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data) + def __init__(self, index, pddf_data=None, pddf_plugin_data=None, is_psu_thermal=False, psu_index=0): + PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data, is_psu_thermal, psu_index) # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..3b9bb607f632 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/sonic_platform/fan_drawer.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_fan_drawer import PddfFanDrawer +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(PddfFanDrawer): + """PDDF Platform-Specific Fan-Drawer class""" + + def __init__(self, tray_idx, pddf_data=None, pddf_plugin_data=None): + # idx is 0-based + PddfFanDrawer.__init__(self, tray_idx, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/sonic_platform/thermal.py index 5b829fc26caa..77d6ec7ae886 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7712-32x/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7712-32x/sonic_platform/thermal.py @@ -11,7 +11,7 @@ class Thermal(PddfThermal): """PDDF Platform-Specific Thermal class""" - def __init__(self, index, pddf_data=None, pddf_plugin_data=None): - PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data) + def __init__(self, index, pddf_data=None, pddf_plugin_data=None, is_psu_thermal=False, psu_index=0): + PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data, is_psu_thermal, psu_index) # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..3b9bb607f632 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/sonic_platform/fan_drawer.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_fan_drawer import PddfFanDrawer +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(PddfFanDrawer): + """PDDF Platform-Specific Fan-Drawer class""" + + def __init__(self, tray_idx, pddf_data=None, pddf_plugin_data=None): + # idx is 0-based + PddfFanDrawer.__init__(self, tray_idx, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/sonic_platform/thermal.py index 5b829fc26caa..77d6ec7ae886 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/sonic_platform/thermal.py @@ -11,7 +11,7 @@ class Thermal(PddfThermal): """PDDF Platform-Specific Thermal class""" - def __init__(self, index, pddf_data=None, pddf_plugin_data=None): - PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data) + def __init__(self, index, pddf_data=None, pddf_plugin_data=None, is_psu_thermal=False, psu_index=0): + PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data, is_psu_thermal, psu_index) # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..3b9bb607f632 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/sonic_platform/fan_drawer.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_fan_drawer import PddfFanDrawer +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(PddfFanDrawer): + """PDDF Platform-Specific Fan-Drawer class""" + + def __init__(self, tray_idx, pddf_data=None, pddf_plugin_data=None): + # idx is 0-based + PddfFanDrawer.__init__(self, tray_idx, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/sonic_platform/thermal.py index 5b829fc26caa..77d6ec7ae886 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/sonic_platform/thermal.py @@ -11,7 +11,7 @@ class Thermal(PddfThermal): """PDDF Platform-Specific Thermal class""" - def __init__(self, index, pddf_data=None, pddf_plugin_data=None): - PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data) + def __init__(self, index, pddf_data=None, pddf_plugin_data=None, is_psu_thermal=False, psu_index=0): + PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data, is_psu_thermal, psu_index) # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/sonic_platform/fan_drawer.py new file mode 100644 index 000000000000..3b9bb607f632 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/sonic_platform/fan_drawer.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python + + +try: + from sonic_platform_pddf_base.pddf_fan_drawer import PddfFanDrawer +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(PddfFanDrawer): + """PDDF Platform-Specific Fan-Drawer class""" + + def __init__(self, tray_idx, pddf_data=None, pddf_plugin_data=None): + # idx is 0-based + PddfFanDrawer.__init__(self, tray_idx, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/sonic_platform/thermal.py index 5b829fc26caa..77d6ec7ae886 100644 --- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/sonic_platform/thermal.py @@ -11,7 +11,7 @@ class Thermal(PddfThermal): """PDDF Platform-Specific Thermal class""" - def __init__(self, index, pddf_data=None, pddf_plugin_data=None): - PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data) + def __init__(self, index, pddf_data=None, pddf_plugin_data=None, is_psu_thermal=False, psu_index=0): + PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data, is_psu_thermal, psu_index) # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/mellanox/hw-management.mk b/platform/mellanox/hw-management.mk index 1f2a08b32d4d..fac7bddc2c24 100644 --- a/platform/mellanox/hw-management.mk +++ b/platform/mellanox/hw-management.mk @@ -16,7 +16,7 @@ # # Mellanox HW Management -MLNX_HW_MANAGEMENT_VERSION = 7.0020.1300 +MLNX_HW_MANAGEMENT_VERSION = 7.0020.2004 export MLNX_HW_MANAGEMENT_VERSION diff --git a/platform/mellanox/hw-management/0003-Remove-unused-non-upstream-kernel-modules-from-load.patch b/platform/mellanox/hw-management/0003-Remove-unused-non-upstream-kernel-modules-from-load.patch index fb114224494b..496085e9d4d8 100644 --- a/platform/mellanox/hw-management/0003-Remove-unused-non-upstream-kernel-modules-from-load.patch +++ b/platform/mellanox/hw-management/0003-Remove-unused-non-upstream-kernel-modules-from-load.patch @@ -16,7 +16,7 @@ index 39f621e..c0980bc 100644 mp2888 i2c-mux-pca954x -emc2305 --ads1015 +-ti-ads1015 powr1220 gpio-pca953x pmbus diff --git a/platform/mellanox/hw-management/hw-mgmt b/platform/mellanox/hw-management/hw-mgmt index cd4e3f7bdc9f..ec2e9173e9f2 160000 --- a/platform/mellanox/hw-management/hw-mgmt +++ b/platform/mellanox/hw-management/hw-mgmt @@ -1 +1 @@ -Subproject commit cd4e3f7bdc9fe77f0dc78b405e52fe876f7ca490 +Subproject commit ec2e9173e9f24cbc02eb87d81889d408528e090b diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py index 29d1c7c081f6..7ebe9d5e5e57 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/sfp.py @@ -121,6 +121,13 @@ # parameters for SFP presence SFP_STATUS_INSERTED = '1' +# SFP constants +SFP_PAGE_SIZE = 256 +SFP_UPPER_PAGE_OFFSET = 128 +SFP_VENDOR_PAGE_START = 640 + +BYTES_IN_DWORD = 4 + # Global logger class instance logger = Logger() @@ -146,6 +153,72 @@ def deinitialize_sdk_handle(sdk_handle): logger.log_warning("Sdk handle is none") return False +class MlxregManager: + def __init__(self, mst_pci_device, slot_id, sdk_index): + self.mst_pci_device = mst_pci_device + self.slot_id = slot_id + self.sdk_index = sdk_index + + def construct_dword(self, write_buffer): + if len(write_buffer) == 0: + return None + + used_bytes_in_dword = len(write_buffer) % BYTES_IN_DWORD + + res = "dword[0]=0x" + for idx, x in enumerate(write_buffer): + word = hex(x)[2:] + + if (idx > 0) and (idx % BYTES_IN_DWORD) == 0: + res += ",dword[{}]=0x".format(str((idx + 1)//BYTES_IN_DWORD)) + res += word.zfill(2) + + if used_bytes_in_dword > 0: + res += (BYTES_IN_DWORD - used_bytes_in_dword) * "00" + return res + + def write_mlxreg_eeprom(self, num_bytes, dword, device_address, page): + if not dword: + return False + + try: + cmd = "mlxreg -d /dev/mst/{} --reg_name MCIA --indexes \ + slot_index={},module={},device_address={},page_number={},i2c_device_address=0x50,size={},bank_number=0 \ + --set {} -y".format(self.mst_pci_device, self.slot_id, self.sdk_index, device_address, page, num_bytes, dword) + subprocess.check_call(cmd, shell=True, universal_newlines=True, stdout=subprocess.DEVNULL) + except subprocess.CalledProcessError as e: + logger.log_error("Error! Unable to write data for {} port, page {} offset {}, rc = {}, err msg: {}".format(self.sdk_index, page, device_address, e.returncode, e.output)) + return False + return True + + def read_mlxred_eeprom(self, offset, page, num_bytes): + try: + cmd = "mlxreg -d /dev/mst/{} --reg_name MCIA --indexes \ + slot_index={},module={},device_address={},page_number={},i2c_device_address=0x50,size={},bank_number=0 \ + --get".format(self.mst_pci_device, self.slot_id, self.sdk_index, offset, page, num_bytes) + result = subprocess.check_output(cmd, universal_newlines=True, shell=True) + except subprocess.CalledProcessError as e: + logger.log_error("Error! Unable to write data for {} port, page {} offset {}, rc = {}, err msg: {}".format(self.sdk_index, page, device_address, e.returncode, e.output)) + return None + return result + + def parse_mlxreg_read_output(self, read_output, num_bytes): + res = "" + dword_num = num_bytes // BYTES_IN_DWORD + used_bytes_in_dword = num_bytes % BYTES_IN_DWORD + arr = [value for value in read_output.split('\n') if value[0:5] == "dword"] + for i in range(dword_num): + dword = arr[i].split()[2] + res += dword[2:] + + if used_bytes_in_dword > 0: + # Cut needed info and insert into final hex string + # Example: 3 bytes : 0x12345600 + # ^ ^ + dword = arr[dword_num].split()[2] + res += dword[2 : 2 + used_bytes_in_dword * 2] + + return bytearray.fromhex(res) if res else None class SdkHandleContext(object): def __init__(self): @@ -194,6 +267,16 @@ def __init__(self, sfp_index, slot_id=0, linecard_port_count=0, lc_name=None): self._thermal_list = initialize_linecard_sfp_thermal(lc_name, slot_id, sfp_index) self.slot_id = slot_id + self.mst_pci_device = self.get_mst_pci_device() + + # get MST PCI device name + def get_mst_pci_device(self): + device_name = None + try: + device_name = subprocess.check_output("ls /dev/mst/ | grep pciconf", universal_newlines=True, shell=True).strip() + except subprocess.CalledProcessError as e: + logger.log_error("Failed to find mst PCI device rc={} err.msg={}".format(e.returncode, e.output)) + return device_name @property def sdk_handle(self): @@ -222,7 +305,11 @@ def get_presence(self): return eeprom_raw is not None # Read out any bytes from any offset - def read_eeprom(self, offset, num_bytes): + def _read_eeprom_specific_bytes(self, offset, num_bytes): + if offset + num_bytes > SFP_VENDOR_PAGE_START: + logger.log_error("Error mismatch between page size and bytes to read (offset: {} num_bytes: {}) ".format(offset, num_bytes)) + return None + eeprom_raw = [] ethtool_cmd = "ethtool -m sfp{} hex on offset {} length {}".format(self.index, offset, num_bytes) try: @@ -241,6 +328,81 @@ def read_eeprom(self, offset, num_bytes): eeprom_raw = list(map(lambda h: int(h, base=16), eeprom_raw)) return bytearray(eeprom_raw) + # read eeprom specfic bytes beginning from offset with size as num_bytes + def read_eeprom(self, offset, num_bytes): + """ + Read eeprom specfic bytes beginning from a random offset with size as num_bytes + Returns: + bytearray, if raw sequence of bytes are read correctly from the offset of size num_bytes + None, if the read_eeprom fails + Example: + mlxreg -d /dev/mst/mt52100_pciconf0 --reg_name MCIA --indexes slot_index=0,module=1,device_address=148,page_number=0,i2c_device_address=0x50,size=16,bank_number=0 -g + Sending access register... + Field Name | Data + =================================== + status | 0x00000000 + slot_index | 0x00000000 + module | 0x00000001 + l | 0x00000000 + device_address | 0x00000094 + page_number | 0x00000000 + i2c_device_address | 0x00000050 + size | 0x00000010 + bank_number | 0x00000000 + dword[0] | 0x43726564 + dword[1] | 0x6f202020 + dword[2] | 0x20202020 + dword[3] | 0x20202020 + dword[4] | 0x00000000 + dword[5] | 0x00000000 + .... + 16 bytes to read from dword -> 0x437265646f2020202020202020202020 -> Credo + """ + # recalculate offset and page. Use 'ethtool' if there is no need to read vendor pages + if offset < SFP_VENDOR_PAGE_START: + return self._read_eeprom_specific_bytes(offset, num_bytes) + else: + page = (offset - SFP_PAGE_SIZE) // SFP_UPPER_PAGE_OFFSET + 1 + # calculate offset per page + device_address = (offset - SFP_PAGE_SIZE) % SFP_UPPER_PAGE_OFFSET + SFP_UPPER_PAGE_OFFSET + + if not self.mst_pci_device: + return None + + mlxreg_mngr = MlxregManager(self.mst_pci_device, self.slot_id, self.sdk_index) + read_output = mlxreg_mngr.read_mlxred_eeprom(device_address, page, num_bytes) + return mlxreg_mngr.parse_mlxreg_read_output(read_output, num_bytes) + + # write eeprom specfic bytes beginning from offset with size as num_bytes + def write_eeprom(self, offset, num_bytes, write_buffer): + """ + write eeprom specfic bytes beginning from a random offset with size as num_bytes + and write_buffer as the required bytes + Returns: + Boolean, true if the write succeeded and false if it did not succeed. + Example: + mlxreg -d /dev/mst/mt52100_pciconf0 --reg_name MCIA --indexes slot_index=0,module=1,device_address=154,page_number=5,i2c_device_address=0x50,size=1,bank_number=0 --set dword[0]=0x01000000 -y + """ + if num_bytes != len(write_buffer): + logger.log_error("Error mismatch between buffer length and number of bytes to be written") + return False + + # recalculate offset and page + if offset < SFP_PAGE_SIZE: + page = 0 + device_address = offset + else: + page = (offset - SFP_PAGE_SIZE) // SFP_UPPER_PAGE_OFFSET + 1 + # calculate offset per page + device_address = (offset - SFP_PAGE_SIZE) % SFP_UPPER_PAGE_OFFSET + SFP_UPPER_PAGE_OFFSET + + if not self.mst_pci_device: + return False + + mlxreg_mngr = MlxregManager(self.mst_pci_device, self.slot_id, self.sdk_index) + dword = mlxreg_mngr.construct_dword(write_buffer) + return mlxreg_mngr.write_mlxreg_eeprom(num_bytes, dword, device_address, page) + @classmethod def mgmt_phy_mod_pwr_attr_get(cls, power_attr_type, sdk_handle, sdk_index, slot_id): sx_mgmt_phy_mod_pwr_attr_p = new_sx_mgmt_phy_mod_pwr_attr_t_p() diff --git a/platform/mellanox/mlnx-platform-api/tests/input_platform/__init__.py b/platform/mellanox/mlnx-platform-api/tests/input_platform/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/mellanox/mlnx-platform-api/tests/input_platform/output_sfp.py b/platform/mellanox/mlnx-platform-api/tests/input_platform/output_sfp.py new file mode 100644 index 000000000000..20a09d1b54f6 --- /dev/null +++ b/platform/mellanox/mlnx-platform-api/tests/input_platform/output_sfp.py @@ -0,0 +1,55 @@ +""" +module holding the correct values for the sfp_test.py +""" + +read_eeprom_output = """ +Sending access register... +Field Name | Data +=================================== +status | 0x00000000 +slot_index | 0x00000000 +module | 0x00000001 +l | 0x00000000 +device_address | 0x000000a8 +page_number | 0x00000000 +i2c_device_address | 0x00000050 +size | 0x00000010 +bank_number | 0x00000000 +dword[0] | 0x43414331 +dword[1] | 0x31353332 +dword[2] | 0x31503250 +dword[3] | 0x41324d53 +dword[4] | 0x00000000 +dword[5] | 0x00000000 +dword[6] | 0x00000000 +dword[7] | 0x00000000 +dword[8] | 0x00000000 +dword[9] | 0x00000000 +dword[10] | 0x00000000 +dword[11] | 0x00000000 +dword[12] | 0x00000000 +dword[13] | 0x00000000 +dword[14] | 0x00000000 +dword[15] | 0x00000000 +dword[16] | 0x00000000 +dword[17] | 0x00000000 +dword[18] | 0x00000000 +dword[19] | 0x00000000 +dword[20] | 0x00000000 +dword[21] | 0x00000000 +dword[22] | 0x00000000 +dword[23] | 0x00000000 +dword[24] | 0x00000000 +dword[25] | 0x00000000 +dword[26] | 0x00000000 +dword[27] | 0x00000000 +dword[28] | 0x00000000 +dword[29] | 0x00000000 +dword[30] | 0x00000000 +dword[31] | 0x00000000 +=================================== +""" + +y_cable_part_number = "CAC115321P2PA2MS" +write_eeprom_dword1 = "dword[0]=0x01020304" +write_eeprom_dword2 = "dword[0]=0x01020304,dword[1]=0x05060000" diff --git a/platform/mellanox/mlnx-platform-api/tests/test_sfp.py b/platform/mellanox/mlnx-platform-api/tests/test_sfp.py index 261a03b527aa..dcb3953ded88 100644 --- a/platform/mellanox/mlnx-platform-api/tests/test_sfp.py +++ b/platform/mellanox/mlnx-platform-api/tests/test_sfp.py @@ -27,6 +27,9 @@ from sonic_platform.sfp import SFP, SX_PORT_MODULE_STATUS_INITIALIZING, SX_PORT_MODULE_STATUS_PLUGGED, SX_PORT_MODULE_STATUS_UNPLUGGED, SX_PORT_MODULE_STATUS_PLUGGED_WITH_ERROR, SX_PORT_MODULE_STATUS_PLUGGED_DISABLED from sonic_platform.chassis import Chassis +from sonic_platform.sfp import MlxregManager +from tests.input_platform import output_sfp + class TestSfp: @mock.patch('sonic_platform.device_data.DeviceDataManager.get_linecard_count', mock.MagicMock(return_value=8)) @@ -80,3 +83,29 @@ def test_sfp_get_error_status(self, mock_get_error_code): description = sfp.get_error_description() assert description == expected_description + + @mock.patch('sonic_platform.sfp.SFP.get_mst_pci_device', mock.MagicMock(return_value="pciconf")) + @mock.patch('sonic_platform.sfp.MlxregManager.write_mlxreg_eeprom', mock.MagicMock(return_value=True)) + def test_sfp_write_eeprom(self): + mlxreg_mngr = MlxregManager("", 0, 0) + write_buffer = bytearray([1,2,3,4]) + offset = 793 + + sfp = SFP(0) + sfp.write_eeprom(offset, 4, write_buffer) + MlxregManager.write_mlxreg_eeprom.assert_called_with(4, output_sfp.write_eeprom_dword1, 153, 5) + + offset = 641 + write_buffer = bytearray([1,2,3,4,5,6]) + sfp.write_eeprom(offset, 6, write_buffer) + MlxregManager.write_mlxreg_eeprom.assert_called_with(6, output_sfp.write_eeprom_dword2, 129, 4) + + @mock.patch('sonic_platform.sfp.SFP.get_mst_pci_device', mock.MagicMock(return_value="pciconf")) + @mock.patch('sonic_platform.sfp.MlxregManager.read_mlxred_eeprom', mock.MagicMock(return_value=output_sfp.read_eeprom_output)) + def test_sfp_read_eeprom(self): + mlxreg_mngr = MlxregManager("", 0, 0) + offset = 644 + + sfp = SFP(0) + assert output_sfp.y_cable_part_number == sfp.read_eeprom(offset, 16).decode() + MlxregManager.read_mlxred_eeprom.assert_called_with(132, 4, 16) diff --git a/scripts/docker_version_control.sh b/scripts/docker_version_control.sh index da8cd0484f49..e94370d0e2d9 100755 --- a/scripts/docker_version_control.sh +++ b/scripts/docker_version_control.sh @@ -23,7 +23,7 @@ tag=`echo $image_tag | cut -f2 -d:` if [[ ",$SONIC_VERSION_CONTROL_COMPONENTS," == *,all,* ]] || [[ ",$SONIC_VERSION_CONTROL_COMPONENTS," == *,docker,* ]]; then # if docker image not in white list, exit - if [[ "$image_tag" != */debian:* ]] && [[ "$image_tag" != multiarch/debian-debootstrap:* ]];then + if [[ "$image_tag" != */debian:* ]] && [[ "$image_tag" != debian:* ]] && [[ "$image_tag" != multiarch/debian-debootstrap:* ]];then exit 0 fi if [ -f $version_file ];then @@ -40,7 +40,7 @@ if [[ ",$SONIC_VERSION_CONTROL_COMPONENTS," == *,all,* ]] || [[ ",$SONIC_VERSION sed -i "s/$oldimage/$newimage/" $DOCKERFILE else hash_value=`docker pull $image_tag 2> ${new_version_file}.log | grep Digest | awk '{print$2}'` - if [ -z hash_value ];then + if [ -z "$hash_value" ];then hash_value=unknown fi fi diff --git a/scripts/prepare_slave_container_buildinfo.sh b/scripts/prepare_slave_container_buildinfo.sh index be6fe078bdfb..1fb2f006640b 100755 --- a/scripts/prepare_slave_container_buildinfo.sh +++ b/scripts/prepare_slave_container_buildinfo.sh @@ -14,6 +14,10 @@ symlink_build_hooks cp -rf $SLAVE_DIR/buildinfo/* /usr/local/share/buildinfo/ . /usr/local/share/buildinfo/scripts/buildinfo_base.sh +# Enable reproducible mirrors +set_reproducible_mirrors +apt-get update > /dev/null 2>&1 + # Build the slave version config [ -d /usr/local/share/buildinfo/versions ] && rm -rf /usr/local/share/buildinfo/versions scripts/versions_manager.py generate -t "/usr/local/share/buildinfo/versions" -n "build-${SLAVE_DIR}" -d "$DISTRO" -a "$ARCH" diff --git a/scripts/versions_manager.py b/scripts/versions_manager.py index c986e29a4e17..a20684e97bb4 100755 --- a/scripts/versions_manager.py +++ b/scripts/versions_manager.py @@ -174,11 +174,20 @@ def overwrite(self, module, for_all_dist=False, for_all_arch=False): self.components.append(tmp_component) self.adjust() - def get_config_module(self, default_module, dist, arch): + def get_config_module(self, source_path, dist, arch): if self.is_individule_version(): return self + default_module_path = VersionModule.get_module_path_by_name(source_path, DEFAULT_MODULE) + default_module = VersionModule() + default_module.load(default_module_path, filter_dist=dist, filter_arch=arch) module = default_module - if not self.is_aggregatable_module(self.name): + if self.name == 'host-image': + base_module_path = VersionModule.get_module_path_by_name(source_path, 'host-base-image') + base_module = VersionModule() + base_module.load(base_module_path, filter_dist=dist, filter_arch=arch) + module = default_module.clone(exclude_ctypes=DEFAULT_OVERWRITE_COMPONENTS) + module.overwrite(base_module, True, True) + elif not self.is_aggregatable_module(self.name): module = default_module.clone(exclude_ctypes=DEFAULT_OVERWRITE_COMPONENTS) return self._get_config_module(module, dist, arch) @@ -661,10 +670,7 @@ def generate(self): os.makedirs(args.target_path) module = VersionModule() module.load(module_path, filter_dist=args.distribution, filter_arch=args.architecture) - default_module_path = VersionModule.get_module_path_by_name(args.source_path, DEFAULT_MODULE) - default_module = VersionModule() - default_module.load(default_module_path, filter_dist=args.distribution, filter_arch=args.architecture) - config = module.get_config_module(default_module, args.distribution, args.architecture) + config = module.get_config_module(args.source_path, args.distribution, args.architecture) config.clean_info(force=True) config.dump(args.target_path, config=True, priority=args.priority) diff --git a/src/sonic-config-engine/tests/sample-chassis-packet-lc-graph.xml b/src/sonic-config-engine/tests/sample-chassis-packet-lc-graph.xml index 183c578385f0..ac83d87b96ca 100644 --- a/src/sonic-config-engine/tests/sample-chassis-packet-lc-graph.xml +++ b/src/sonic-config-engine/tests/sample-chassis-packet-lc-graph.xml @@ -394,7 +394,7 @@ SwitchType - chassis_packet + chassis-packet DeploymentId @@ -459,7 +459,7 @@ SwitchType - chassis_packet + chassis-packet diff --git a/src/sonic-host-services-data/templates/limits.conf.j2 b/src/sonic-host-services-data/templates/limits.conf.j2 new file mode 100755 index 000000000000..41b37221e41e --- /dev/null +++ b/src/sonic-host-services-data/templates/limits.conf.j2 @@ -0,0 +1,69 @@ +# /etc/security/limits.conf +# +# This file generate by j2 template file: src/sonic-host-services-data/templates/limits.conf.j2 +# +# Each line describes a limit for a user in the form: +# +# +# +# Where: +# can be: +# - a user name +# - a group name, with @group syntax +# - the wildcard *, for default entry +# - the wildcard %, can be also used with %group syntax, +# for maxlogin limit +# - NOTE: group and wildcard limits are not applied to root. +# To apply a limit to the root user, must be +# the literal username root. +# +# can have the two values: +# - "soft" for enforcing the soft limits +# - "hard" for enforcing hard limits +# +# can be one of the following: +# - core - limits the core file size (KB) +# - data - max data size (KB) +# - fsize - maximum filesize (KB) +# - memlock - max locked-in-memory address space (KB) +# - nofile - max number of open file descriptors +# - rss - max resident set size (KB) +# - stack - max stack size (KB) +# - cpu - max CPU time (MIN) +# - nproc - max number of processes +# - as - address space limit (KB) +# - maxlogins - max number of logins for this user +# - maxsyslogins - max number of logins on the system +# - priority - the priority to run user process with +# - locks - max number of file locks the user can hold +# - sigpending - max number of pending signals +# - msgqueue - max memory used by POSIX message queues (bytes) +# - nice - max nice priority allowed to raise to values: [-20, 19] +# - rtprio - max realtime priority +# - chroot - change root to directory (Debian-specific) +# +# +# is related with : +# All items support the values -1, unlimited or infinity indicating +# no limit, except for priority and nice. +# +# If a hard limit or soft limit of a resource is set to a valid value, +# but outside of the supported range of the local system, the system +# may reject the new limit or unexpected behavior may occur. If the +# control value required is used, the module will reject the login if +# a limit could not be set. +# +# +# + +# * soft core 0 +# root hard core 100000 +# * hard rss 10000 +# @student hard nproc 20 +# @faculty soft nproc 20 +# @faculty hard nproc 50 +# ftp hard nproc 0 +# ftp - chroot /ftp +# @student - maxlogins 4 + +# End of file diff --git a/src/sonic-host-services-data/templates/pam_limits.j2 b/src/sonic-host-services-data/templates/pam_limits.j2 new file mode 100755 index 000000000000..f87906932fb7 --- /dev/null +++ b/src/sonic-host-services-data/templates/pam_limits.j2 @@ -0,0 +1,12 @@ +#THIS IS AN AUTO-GENERATED FILE +# +# This file generate by j2 template file: src/sonic-host-services-data/templates/pam_limits.j2 +# +# /etc/pam.d/pam-limits settings common to all services +# This file is included from other service-specific PAM config files, +# and should contain a list of the authentication modules that define +# the central authentication scheme for use on the system +# (e.g., /etc/shadow, LDAP, Kerberos, etc.). The default is to use the +# traditional Unix authentication mechanisms. +# +# here are the per-package modules (the "Primary" block) \ No newline at end of file diff --git a/src/sonic-host-services/scripts/hostcfgd b/src/sonic-host-services/scripts/hostcfgd index be8317259e38..5b6693fbcdf7 100755 --- a/src/sonic-host-services/scripts/hostcfgd +++ b/src/sonic-host-services/scripts/hostcfgd @@ -25,6 +25,10 @@ PAM_RADIUS_AUTH_CONF_TEMPLATE = "/usr/share/sonic/templates/pam_radius_auth.conf NSS_CONF = "/etc/nsswitch.conf" ETC_PAMD_SSHD = "/etc/pam.d/sshd" ETC_PAMD_LOGIN = "/etc/pam.d/login" +PAM_LIMITS_CONF_TEMPLATE = "/usr/share/sonic/templates/pam_limits.j2" +LIMITS_CONF_TEMPLATE = "/usr/share/sonic/templates/limits.conf.j2" +PAM_LIMITS_CONF = "/etc/pam.d/pam-limits-conf" +LIMITS_CONF = "/etc/security/limits.conf" # TACACS+ TACPLUS_SERVER_PASSKEY_DEFAULT = "" @@ -966,6 +970,64 @@ class NtpCfg(object): syslog.syslog(syslog.LOG_INFO, 'ntp server update, restarting ntp-config, ntp servers configured {}'.format(self.ntp_servers)) run_cmd(cmd) +class PamLimitsCfg(object): + """ + PamLimit Config Daemon + 1) The pam_limits PAM module sets limits on the system resources that can be obtained in a user-session. + 2) Purpose of this daemon is to render pam_limits config file. + """ + def __init__(self, config_db): + self.config_db = config_db + self.hwsku = "" + self.type = "" + + # Load config from ConfigDb and render config file/ + def update_config_file(self): + device_metadata = self.config_db.get_table('DEVICE_METADATA') + if "localhost" not in device_metadata: + return + + self.read_localhost_config(device_metadata["localhost"]) + self.render_conf_file() + + # Read localhost config + def read_localhost_config(self, localhost): + if "hwsku" in localhost: + self.hwsku = localhost["hwsku"] + else: + self.hwsku = "" + + if "type" in localhost: + self.type = localhost["type"] + else: + self.type = "" + + # Render pam_limits config files + def render_conf_file(self): + env = jinja2.Environment(loader=jinja2.FileSystemLoader('/'), trim_blocks=True) + env.filters['sub'] = sub + + try: + template_file = os.path.abspath(PAM_LIMITS_CONF_TEMPLATE) + template = env.get_template(template_file) + pam_limits_conf = template.render( + hwsku=self.hwsku, + type=self.type) + with open(PAM_LIMITS_CONF, 'w') as f: + f.write(pam_limits_conf) + + template_file = os.path.abspath(LIMITS_CONF_TEMPLATE) + template = env.get_template(template_file) + limits_conf = template.render( + hwsku=self.hwsku, + type=self.type) + with open(LIMITS_CONF, 'w') as f: + f.write(limits_conf) + except Exception as e: + syslog.syslog(syslog.LOG_ERR, + "modify pam_limits config file failed with exception: {}" + .format(e)) + class HostConfigDaemon: def __init__(self): # Just a sanity check to verify if the CONFIG_DB has been initialized @@ -1007,6 +1069,9 @@ class HostConfigDaemon: self.hostname_cache="" self.aaacfg = AaaCfg() + # Initialize PamLimitsCfg + self.pamLimitsCfg = PamLimitsCfg(self.config_db) + self.pamLimitsCfg.update_config_file() def load(self): aaa = self.config_db.get_table('AAA') diff --git a/src/sonic-sairedis b/src/sonic-sairedis index b9337dc5787a..1ccda8d1d982 160000 --- a/src/sonic-sairedis +++ b/src/sonic-sairedis @@ -1 +1 @@ -Subproject commit b9337dc5787aadf71eee9d676d6b7f1181ac0787 +Subproject commit 1ccda8d1d9821a65f73eb5c8f88f9abea0623c0b diff --git a/src/sonic-swss b/src/sonic-swss index 00266891a9f4..d80094b248e7 160000 --- a/src/sonic-swss +++ b/src/sonic-swss @@ -1 +1 @@ -Subproject commit 00266891a9f41e5bd37100b05237e865cde429b2 +Subproject commit d80094b248e7df5ac9df309d785ddf21e0ab92d7 diff --git a/src/sonic-utilities b/src/sonic-utilities index a2e68a05a8e6..8389c8137d4f 160000 --- a/src/sonic-utilities +++ b/src/sonic-utilities @@ -1 +1 @@ -Subproject commit a2e68a05a8e6ab296978a59bf107971beb899546 +Subproject commit 8389c8137d4fdc5a2d1c803c9c06e6dcb4f849c1 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 6415fb6100e9..d33cf20e2038 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -900,11 +900,21 @@ } }, "VLAN_SUB_INTERFACE": { - "Ethernet120.10": { + "Ethernet12.10": { "admin_status": "up" }, - "Ethernet120.10|10.0.1.56/31": {}, - "Ethernet120.10|fc00::1:71/126": {} + "Ethernet12.10|10.0.1.56/31": {}, + "Ethernet12.10|fc00::1:71/126": {}, + "Po0003.10": { + "admin_status": "up" + }, + "Po0003.10|10.0.1.58/31": {}, + "Po0003.10|fc00::1:75/126": {}, + "Eth120.10": { + "admin_status": "up" + }, + "Eth120.10|10.0.1.60/31": {}, + "Eth120.10|fc00::1:79/126": {} }, "VLAN_MEMBER": { "Vlan111|Ethernet0": { diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/vlan_sub_interface.json b/src/sonic-yang-models/tests/yang_model_tests/tests/vlan_sub_interface.json index 789b7ddd364a..e3ffa9dc44b6 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests/vlan_sub_interface.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/vlan_sub_interface.json @@ -2,10 +2,28 @@ "VLAN_SUB_INTERFACE_MUST_CONDITION_TRUE_TEST": { "desc": "Configure valid vlan sub interface must condition true." }, + "VLAN_SUB_INTERFACE_SHORT_NAME_FORMAT_MUST_CONDITION_TRUE_TEST": { + "desc": "Configure valid short name format vlan sub interface must condition true." + }, "VLAN_SUB_INTERFACE_MUST_CONDITION_FALSE_TEST": { "desc": "Configure vlan sub interface must condition false.", "eStrKey": "Must" }, + "VLAN_SUB_INTERFACE_SHORT_NAME_FORMAT_MUST_CONDITION_FALSE_TEST": { + "desc": "Configure short name format vlan sub interface must condition false.", + "eStrKey": "Must" + }, + "VLAN_SUB_INTERFACE_PO_SHORT_NAME_FORMAT_MUST_CONDITION_TRUE_TEST": { + "desc": "Configure valid portchannel short name format vlan sub interface must condition true." + }, + "VLAN_SUB_INTERFACE_PO_MUST_CONDITION_FALSE_TEST": { + "desc": "Configure portchannel long name format vlan sub interface must condition false.", + "eStrKey": "Must" + }, + "VLAN_SUB_INTERFACE_PO_SHORT_NAME_FORMAT_MUST_CONDITION_FALSE_TEST": { + "desc": "Configure portchannel short name format vlan sub interface must condition false.", + "eStrKey": "Must" + }, "VLAN_SUB_INTERFACE_IP_PREFIX_PORT_NON_EXISTING_LEAF_TEST": { "desc": "Configure ip prefix vlan sub interface with non-existing reference.", "eStrKey": "LeafRef" diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/vlan_sub_interface.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/vlan_sub_interface.json index f95b1af8f049..8adff73e497c 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/vlan_sub_interface.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/vlan_sub_interface.json @@ -31,6 +31,38 @@ } } }, + "VLAN_SUB_INTERFACE_SHORT_NAME_FORMAT_MUST_CONDITION_TRUE_TEST": { + "sonic-vlan-sub-interface:sonic-vlan-sub-interface": { + "sonic-vlan-sub-interface:VLAN_SUB_INTERFACE": { + "VLAN_SUB_INTERFACE_LIST": [ + { + "name": "Eth8.10" + } + ], + "VLAN_SUB_INTERFACE_IPPREFIX_LIST": [ + { + "name": "Eth8.10", + "ip-prefix": "10.0.0.1/30" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "name": "Ethernet8", + "admin_status": "up", + "alias": "Ethernet8/1", + "description": "Ethernet8", + "lanes": "45,46,47,48", + "mtu": 9000, + "speed": 100000 + } + ] + } + } + }, "VLAN_SUB_INTERFACE_MUST_CONDITION_FALSE_TEST": { "sonic-vlan-sub-interface:sonic-vlan-sub-interface": { "sonic-vlan-sub-interface:VLAN_SUB_INTERFACE": { @@ -63,6 +95,188 @@ } } }, + "VLAN_SUB_INTERFACE_SHORT_NAME_FORMAT_MUST_CONDITION_FALSE_TEST": { + "sonic-vlan-sub-interface:sonic-vlan-sub-interface": { + "sonic-vlan-sub-interface:VLAN_SUB_INTERFACE": { + "VLAN_SUB_INTERFACE_LIST": [ + { + "name": "Eth8.10" + } + ], + "VLAN_SUB_INTERFACE_IPPREFIX_LIST": [ + { + "name": "Eth8.10", + "ip-prefix": "10.0.0.1/30" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "name": "Ethernet12", + "admin_status": "up", + "alias": "Ethernet12/1", + "description": "Ethernet12", + "lanes": "49,50,51,52", + "mtu": 9000, + "speed": 100000 + } + ] + } + } + }, + "VLAN_SUB_INTERFACE_PO_SHORT_NAME_FORMAT_MUST_CONDITION_TRUE_TEST": { + "sonic-vlan-sub-interface:sonic-vlan-sub-interface": { + "sonic-vlan-sub-interface:VLAN_SUB_INTERFACE": { + "VLAN_SUB_INTERFACE_LIST": [ + { + "name": "Po0001.10" + } + ], + "VLAN_SUB_INTERFACE_IPPREFIX_LIST": [ + { + "name": "Po0001.10", + "ip-prefix": "10.0.0.1/30" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "tpid": "0x8100", + "speed": 25000 + } + ] + } + }, + "sonic-portchannel:sonic-portchannel": { + "sonic-portchannel:PORTCHANNEL": { + "PORTCHANNEL_LIST": [ + { + "admin_status": "up", + "members": [ + "Ethernet0" + ], + "min_links": "1", + "mtu": "9100", + "tpid": "0x8100", + "lacp_key": "auto", + "name": "PortChannel0001" + } + ] + } + } + }, + "VLAN_SUB_INTERFACE_PO_MUST_CONDITION_FALSE_TEST": { + "sonic-vlan-sub-interface:sonic-vlan-sub-interface": { + "sonic-vlan-sub-interface:VLAN_SUB_INTERFACE": { + "VLAN_SUB_INTERFACE_LIST": [ + { + "name": "PortChannel0001.10" + } + ], + "VLAN_SUB_INTERFACE_IPPREFIX_LIST": [ + { + "name": "PortChannel0001.10", + "ip-prefix": "10.0.0.1/30" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "tpid": "0x8100", + "speed": 25000 + } + ] + } + }, + "sonic-portchannel:sonic-portchannel": { + "sonic-portchannel:PORTCHANNEL": { + "PORTCHANNEL_LIST": [ + { + "admin_status": "up", + "members": [ + "Ethernet0" + ], + "min_links": "1", + "mtu": "9100", + "tpid": "0x8100", + "lacp_key": "auto", + "name": "PortChannel0001" + } + ] + } + } + }, + "VLAN_SUB_INTERFACE_PO_SHORT_NAME_FORMAT_MUST_CONDITION_FALSE_TEST": { + "sonic-vlan-sub-interface:sonic-vlan-sub-interface": { + "sonic-vlan-sub-interface:VLAN_SUB_INTERFACE": { + "VLAN_SUB_INTERFACE_LIST": [ + { + "name": "Po0002.10" + } + ], + "VLAN_SUB_INTERFACE_IPPREFIX_LIST": [ + { + "name": "Po0002.10", + "ip-prefix": "10.0.0.1/30" + } + ] + } + }, + "sonic-port:sonic-port": { + "sonic-port:PORT": { + "PORT_LIST": [ + { + "admin_status": "up", + "alias": "eth0", + "description": "Ethernet0", + "lanes": "65", + "mtu": 9000, + "name": "Ethernet0", + "tpid": "0x8100", + "speed": 25000 + } + ] + } + }, + "sonic-portchannel:sonic-portchannel": { + "sonic-portchannel:PORTCHANNEL": { + "PORTCHANNEL_LIST": [ + { + "admin_status": "up", + "members": [ + "Ethernet0" + ], + "min_links": "1", + "mtu": "9100", + "tpid": "0x8100", + "lacp_key": "auto", + "name": "PortChannel0001" + } + ] + } + } + }, "VLAN_SUB_INTERFACE_IP_PREFIX_PORT_NON_EXISTING_LEAF_TEST": { "sonic-vlan-sub-interface:sonic-vlan-sub-interface": { "sonic-vlan-sub-interface:VLAN_SUB_INTERFACE": { diff --git a/src/sonic-yang-models/yang-models/sonic-vlan-sub-interface.yang b/src/sonic-yang-models/yang-models/sonic-vlan-sub-interface.yang index 6ce391033ab0..953aa7e14c80 100644 --- a/src/sonic-yang-models/yang-models/sonic-vlan-sub-interface.yang +++ b/src/sonic-yang-models/yang-models/sonic-vlan-sub-interface.yang @@ -14,6 +14,10 @@ module sonic-vlan-sub-interface { prefix port; } + import sonic-portchannel { + prefix lag; + } + import sonic-vrf { prefix vrf; } @@ -36,9 +40,13 @@ module sonic-vlan-sub-interface { key "name"; leaf name { - must "substring-before(current(), '.') = /port:sonic-port/port:PORT/port:PORT_LIST/port:name" + must "(substring-before(current(), '.') = /port:sonic-port/port:PORT/port:PORT_LIST/port:name) or " + + "(starts-with(substring-before(current(), '.'), 'Eth') and " + + "concat('Ethernet', substring-after(substring-before(current(), '.'), 'Eth')) = /port:sonic-port/port:PORT/port:PORT_LIST/port:name) or " + + "(starts-with(substring-before(current(), '.'), 'Po') and " + + "concat('PortChannel', substring-after(substring-before(current(), '.'), 'Po')) = /lag:sonic-portchannel/lag:PORTCHANNEL/lag:PORTCHANNEL_LIST/lag:name)" { - error-message "Must condition not satisfied, Try adding PORT: {}, Example: 'Ethernet0': {}"; + error-message "Must condition not satisfied, please follow vlan sub interface naming convention"; } // check if the vlan sub interface have the form as .