diff --git a/.azure-pipelines/azure-pipelines-build.yml b/.azure-pipelines/azure-pipelines-build.yml
index 815aa7b9fe14..eb3c3aa21bb8 100644
--- a/.azure-pipelines/azure-pipelines-build.yml
+++ b/.azure-pipelines/azure-pipelines-build.yml
@@ -65,7 +65,7 @@ jobs:
- name: centec-arm64
pool: sonicbld_8c
- timeoutInMinutes: 2160
+ timeoutInMinutes: 2880
variables:
PLATFORM_ARCH: arm64
@@ -79,7 +79,7 @@ jobs:
- name: marvell-armhf
pool: sonicbld_8c
- timeoutInMinutes: 2160
+ timeoutInMinutes: 2880
variables:
PLATFORM_ARCH: armhf
diff --git a/.azure-pipelines/azure-pipelines-image-template.yml b/.azure-pipelines/azure-pipelines-image-template.yml
index 81f181cf3cb9..3c437cc56664 100644
--- a/.azure-pipelines/azure-pipelines-image-template.yml
+++ b/.azure-pipelines/azure-pipelines-image-template.yml
@@ -44,7 +44,7 @@ jobs:
sudo modprobe overlay
sudo apt-get install -y acl
sudo bash -c "echo 1 > /proc/sys/vm/compact_memory"
- ENABLE_DOCKER_BASE_PULL=y make PLATFORM=$(PLATFORM_AZP) PLATFORM_ARCH=$(PLATFORM_ARCH) configure
+ ENABLE_DOCKER_BASE_PULL=y make PLATFORM=$(PLATFORM_AZP) PLATFORM_ARCH=$(PLATFORM_ARCH) $(BUILD_OPTIONS) configure
displayName: 'Make configure'
postSteps:
- script: cp target -r $(Build.ArtifactStagingDirectory)/
diff --git a/.azure-pipelines/docker-sonic-slave.yml b/.azure-pipelines/docker-sonic-slave.yml
index 071cc73e8790..a0a1993cd551 100644
--- a/.azure-pipelines/docker-sonic-slave.yml
+++ b/.azure-pipelines/docker-sonic-slave.yml
@@ -22,6 +22,7 @@ pr:
- sonic-slave-jessie
- sonic-slave-stretch
- sonic-slave-buster
+ - sonic-slave-bullseye
parameters:
- name: 'arches'
@@ -33,6 +34,7 @@ parameters:
- name: 'dists'
type: object
default:
+ - bullseye
- buster
- stretch
- jessie
@@ -43,6 +45,11 @@ parameters:
type: string
default: sonicdev
+variables:
+- ${{ if and(startsWith(variables['Build.SourceBranchName'], '202'), eq(length(variables['Build.SourceBranchName']), 6)) }}:
+ - name: BUILD_OPTIONS
+ value: 'SONIC_VERSION_CONTROL_COMPONENTS=deb,py2,py3,web'
+
stages:
- stage: Build
jobs:
@@ -81,7 +88,7 @@ stages:
echo ${{ arch }} > .arch
- DOCKER_DATA_ROOT_FOR_MULTIARCH=/data/march/docker BLDENV=${{ dist }} make -f Makefile.work sonic-slave-build | tee $tmpfile
+ DOCKER_DATA_ROOT_FOR_MULTIARCH=/data/march/docker BLDENV=${{ dist }} $(BUILD_OPTIONS) make -f Makefile.work sonic-slave-build | tee $tmpfile
SLAVE_BASE_TAG=$(grep "^Checking sonic-slave-base image:" $tmpfile | awk -F ':' '{print $3}')
SLAVE_TAG=$(grep "^Checking sonic-slave image:" $tmpfile | awk -F ':' '{print $3}')
diff --git a/.gitignore b/.gitignore
index d608aea9fa3b..ced7ef1651e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,6 +74,7 @@ platform/broadcom/sonic-platform-modules-dell/s6100/modules/dell_s6100_lpc.c
platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_ich.c
platform/broadcom/sonic-platform-modules-dell/z9100/modules/dell_mailbox.c
platform/broadcom/sonic-platform-modules-dell/z9264f/sonic_platform/ipmihelper.py
+platform/cisco-8000
# buildinfo
files/build/buildinfo
diff --git a/.gitmodules b/.gitmodules
index 0673278516c6..f1c3b9e4fc36 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -40,6 +40,9 @@
[submodule "src/sonic-platform-daemons"]
path = src/sonic-platform-daemons
url = https://github.com/Azure/sonic-platform-daemons
+[submodule "src/sonic-platform-pde"]
+ path = src/sonic-platform-pde
+ url = https://github.com/Azure/sonic-platform-pdk-pde
[submodule "src/sonic-frr/frr"]
path = src/sonic-frr/frr
url = https://github.com/Azure/sonic-frr.git
diff --git a/Makefile b/Makefile
index 2231e6d98231..3b8792bfb445 100644
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,29 @@
NOJESSIE ?= 1
NOSTRETCH ?= 0
+NOBUSTER ?= 0
+NOBULLSEYE ?= 1
+
+ifeq ($(NOJESSIE),0)
+BUILD_JESSIE=1
+endif
+
+ifeq ($(NOSTRETCH),0)
+BUILD_STRETCH=1
+endif
+
+ifeq ($(NOBUSTER),0)
+BUILD_BUSTER=1
+endif
+
+ifeq ($(NOBULLSEYE),0)
+BUILD_BULLSEYE=1
+endif
+
+PLATFORM_PATH := platform/$(if $(PLATFORM),$(PLATFORM),$(CONFIGURED_PLATFORM))
+PLATFORM_CHECKOUT := platform/checkout
+PLATFORM_CHECKOUT_FILE := $(PLATFORM_CHECKOUT)/$(PLATFORM).ini
+PLATFORM_CHECKOUT_CMD := $(shell if [ -f $(PLATFORM_CHECKOUT_FILE) ]; then PLATFORM_PATH=$(PLATFORM_PATH) j2 $(PLATFORM_CHECKOUT)/template.j2 $(PLATFORM_CHECKOUT_FILE); fi)
%::
@echo "+++ --- Making $@ --- +++"
@@ -11,7 +34,12 @@ endif
ifeq ($(NOSTRETCH), 0)
EXTRA_DOCKER_TARGETS=$(notdir $@) BLDENV=stretch make -f Makefile.work stretch
endif
+ifeq ($(NOBUSTER), 0)
BLDENV=buster make -f Makefile.work $@
+endif
+ifeq ($(NOBULLSEYE), 0)
+ BLDENV=bullseye make -f Makefile.work $@
+endif
jessie:
@echo "+++ Making $@ +++"
@@ -25,19 +53,38 @@ ifeq ($(NOSTRETCH), 0)
make -f Makefile.work stretch
endif
+buster:
+ @echo "+++ Making $@ +++"
+ifeq ($(NOBUSTER), 0)
+ make -f Makefile.work buster
+endif
+
init:
@echo "+++ Making $@ +++"
make -f Makefile.work $@
-clean configure reset showtag sonic-slave-build sonic-slave-bash :
+#
+# Function to invoke target $@ in Makefile.work with proper BLDENV
+#
+define make_work
@echo "+++ Making $@ +++"
-ifeq ($(NOJESSIE), 0)
- make -f Makefile.work $@
-endif
-ifeq ($(NOSTRETCH), 0)
- BLDENV=stretch make -f Makefile.work $@
-endif
- BLDENV=buster make -f Makefile.work $@
+ $(if $(BUILD_JESSIE),make -f Makefile.work $@,)
+ $(if $(BUILD_STRETCH),BLDENV=stretch make -f Makefile.work $@,)
+ $(if $(BUILD_BUSTER),BLDENV=buster make -f Makefile.work $@,)
+ $(if $(BUILD_BULLSEYE),BLDENV=bullseye make -f Makefile.work $@,)
+endef
+
+.PHONY: $(PLATFORM_PATH)
+
+$(PLATFORM_PATH):
+ @echo "+++ Cheking $@ +++"
+ $(PLATFORM_CHECKOUT_CMD)
+
+configure : $(PLATFORM_PATH)
+ $(call make_work, $@)
+
+clean reset showtag sonic-slave-build sonic-slave-bash :
+ $(call make_work, $@)
# Freeze the versions, see more detail options: scripts/versions_manager.py freeze -h
freeze:
diff --git a/Makefile.work b/Makefile.work
index 6a64c85fd0ce..4a59067434fd 100644
--- a/Makefile.work
+++ b/Makefile.work
@@ -92,7 +92,9 @@ ifeq ($(PLATFORM_ARCH),)
override PLATFORM_ARCH = $(CONFIGURED_ARCH)
endif
-ifeq ($(BLDENV), buster)
+ifeq ($(BLDENV), bullseye)
+SLAVE_DIR = sonic-slave-bullseye
+else ifeq ($(BLDENV), buster)
SLAVE_DIR = sonic-slave-buster
else ifeq ($(BLDENV), stretch)
SLAVE_DIR = sonic-slave-stretch
@@ -247,6 +249,7 @@ SONIC_BUILD_INSTRUCTION := make \
SONIC_IMAGE_VERSION=$(SONIC_IMAGE_VERSION) \
ENABLE_DHCP_GRAPH_SERVICE=$(ENABLE_DHCP_GRAPH_SERVICE) \
ENABLE_ZTP=$(ENABLE_ZTP) \
+ INCLUDE_PDE=$(INCLUDE_PDE) \
SHUTDOWN_BGP_ON_START=$(SHUTDOWN_BGP_ON_START) \
INCLUDE_KUBERNETES=$(INCLUDE_KUBERNETES) \
KUBERNETES_VERSION=$(KUBERNETES_VERSION) \
@@ -268,6 +271,7 @@ SONIC_BUILD_INSTRUCTION := make \
HTTPS_PROXY=$(https_proxy) \
NO_PROXY=$(no_proxy) \
SONIC_INCLUDE_SYSTEM_TELEMETRY=$(INCLUDE_SYSTEM_TELEMETRY) \
+ INCLUDE_DHCP_RELAY=$(INCLUDE_DHCP_RELAY) \
SONIC_INCLUDE_RESTAPI=$(INCLUDE_RESTAPI) \
TELEMETRY_WRITABLE=$(TELEMETRY_WRITABLE) \
EXTRA_DOCKER_TARGETS=$(EXTRA_DOCKER_TARGETS) \
diff --git a/README.md b/README.md
index 35ba10d70d9f..988424f9bac5 100644
--- a/README.md
+++ b/README.md
@@ -6,45 +6,45 @@
*master builds*:
-[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-all)
-[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-all)
-[![Centec](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-all/badge/icon?subject=Centec)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-all)
-[![Centec(arm64)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-arm64-all/badge/icon?subject=Centec(arm64))](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-arm64-all)
-[![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-all)
-[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-all)
-[![Marvell(armhf)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-armhf-all/badge/icon?subject=Marvell(armhf))](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-armhf-all)
-[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-all/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-all)
+[![Barefoot](https://dev.azure.com/mssonic/build/_apis/build/status/barefoot/Azure.sonic-buildimage.official.barefoot?branchName=master&label=Barefoot)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=146&branchName=master)
+[![Broadcom](https://dev.azure.com/mssonic/build/_apis/build/status/broadcom/Azure.sonic-buildimage.official.broadcom?branchName=master&label=Broadcom)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=138&branchName=master)
+[![Centec](https://dev.azure.com/mssonic/build/_apis/build/status/centec/Azure.sonic-buildimage.official.centec?branchName=master&label=Centec)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=143&branchName=master)
+[![Centec(arm64)](https://dev.azure.com/mssonic/build/_apis/build/status/centec/Azure.sonic-buildimage.official.centec-arm64?branchName=master&label=Centec-arm64)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=140&branchName=master)
+[![Innovium](https://dev.azure.com/mssonic/build/_apis/build/status/innovium/Azure.sonic-buildimage.official.innovium?branchName=master&label=Innovium)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=148&branchName=master)
+[![Mellanox](https://dev.azure.com/mssonic/build/_apis/build/status/mellanox/Azure.sonic-buildimage.official.mellanox?branchName=master&label=Mellanox)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=139&branchName=master)
+[![Marvell(armhf)](https://dev.azure.com/mssonic/build/_apis/build/status/marvell/Azure.sonic-buildimage.official.marvell-armhf?branchName=master&label=Marvell-armhf)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=141&branchName=master)
+[![Nephos](https://dev.azure.com/mssonic/build/_apis/build/status/nephos/Azure.sonic-buildimage.official.nephos?branchName=master&label=Nephos)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=149&branchName=master)
[![P4](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all/badge/icon?subject=P4)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/p4/job/buildimage-p4-all)
-[![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-image/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-image)
+[![VS](https://dev.azure.com/mssonic/build/_apis/build/status/vs/Azure.sonic-buildimage.official.vs?branchName=master&label=VS)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=142&branchName=master)
*202012 builds*:
-[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-202012/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-202012/)
-[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-202012/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-202012)
-[![Centec](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-202012/badge/icon?subject=Centec)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-202012)
-[![Centec(arm64)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-arm64-202012/badge/icon?subject=Centec(arm64))](https://sonic-jenkins.westus2.cloudapp.azure.com/job/centec/job/buildimage-centec-arm64-202012)
-[![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-202012/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-202012/)
-[![Marvell(armhf)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-armhf-202012/badge/icon?subject=Marvell(armhf))](https://sonic-jenkins.westus2.cloudapp.azure.com/job/marvell/job/buildimage-mrvl-armhf-202012)
-[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-202012/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-202012)
-[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-202012/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-202012)
-[![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-image-202012/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-image-202012)
+[![Barefoot](https://dev.azure.com/mssonic/build/_apis/build/status/barefoot/Azure.sonic-buildimage.official.barefoot?branchName=202012&label=Barefoot)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=146&branchName=202012)
+[![Broadcom](https://dev.azure.com/mssonic/build/_apis/build/status/broadcom/Azure.sonic-buildimage.official.broadcom?branchName=202012&label=Broadcom)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=138&branchName=202012)
+[![Centec](https://dev.azure.com/mssonic/build/_apis/build/status/centec/Azure.sonic-buildimage.official.centec?branchName=202012&label=Centec)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=143&branchName=202012)
+[![Centec(arm64)](https://dev.azure.com/mssonic/build/_apis/build/status/centec/Azure.sonic-buildimage.official.centec-arm64?branchName=202012&label=Centec-arm64)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=140&branchName=202012)
+[![Innovium](https://dev.azure.com/mssonic/build/_apis/build/status/innovium/Azure.sonic-buildimage.official.innovium?branchName=202012&label=Innovium)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=148&branchName=202012)
+[![Marvell(armhf)](https://dev.azure.com/mssonic/build/_apis/build/status/marvell/Azure.sonic-buildimage.official.marvell-armhf?branchName=202012&label=Marvell-armhf)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=141&branchName=202012)
+[![Mellanox](https://dev.azure.com/mssonic/build/_apis/build/status/mellanox/Azure.sonic-buildimage.official.mellanox?branchName=202012&label=Mellanox)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=139&branchName=202012)
+[![Nephos](https://dev.azure.com/mssonic/build/_apis/build/status/nephos/Azure.sonic-buildimage.official.nephos?branchName=202012&label=Nephos)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=149&branchName=202012)
+[![VS](https://dev.azure.com/mssonic/build/_apis/build/status/vs/Azure.sonic-buildimage.official.vs?branchName=202012&label=VS)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=142&branchName=202012)
*201911 builds*:
-[![Barefoot](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/badge/icon?subject=Barefoot)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/barefoot/job/buildimage-bf-201911/)
-[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201911/)
-[![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201911/)
-[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201911/)
-[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201911/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201911)
-[![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201911)
+[![Barefoot](https://dev.azure.com/mssonic/build/_apis/build/status/barefoot/Azure.sonic-buildimage.official.barefoot?branchName=201911&label=Barefoot)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=146&branchName=201911)
+[![Broadcom](https://dev.azure.com/mssonic/build/_apis/build/status/broadcom/Azure.sonic-buildimage.official.broadcom?branchName=201911&label=Broadcom)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=138&branchName=201911)
+[![Innovium](https://dev.azure.com/mssonic/build/_apis/build/status/innovium/Azure.sonic-buildimage.official.innovium?branchName=201911&label=Innovium)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=148&branchName=201911)
+[![Mellanox](https://dev.azure.com/mssonic/build/_apis/build/status/mellanox/Azure.sonic-buildimage.official.mellanox?branchName=201911&label=Mellanox)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=139&branchName=201911)
+[![Nephos](https://dev.azure.com/mssonic/build/_apis/build/status/nephos/Azure.sonic-buildimage.official.nephos?branchName=201911&label=Nephos)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=149&branchName=201911)
+[![VS](https://dev.azure.com/mssonic/build/_apis/build/status/vs/Azure.sonic-buildimage.official.vs?branchName=201911&label=VS)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=142&branchName=201911)
*201811 builds*:
-[![Broadcom](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/badge/icon?subject=Broadcom)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/broadcom/job/buildimage-brcm-201811/)
-[![Mellanox](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/badge/icon?subject=Mellanox)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/mellanox/job/buildimage-mlnx-201811/)
-[![Innovium](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/badge/icon?subject=Innovium)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/innovium/job/buildimage-invm-201811/)
-[![Nephos](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811/badge/icon?subject=Nephos)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/nephos/job/buildimage-nephos-201811)
-[![VS](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811/badge/icon?subject=VS)](https://sonic-jenkins.westus2.cloudapp.azure.com/job/vs/job/buildimage-vs-201811)
+[![Broadcom](https://dev.azure.com/mssonic/build/_apis/build/status/broadcom/Azure.sonic-buildimage.official.broadcom?branchName=201811&label=Broadcom)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=138&branchName=201811)
+[![Mellanox](https://dev.azure.com/mssonic/build/_apis/build/status/mellanox/Azure.sonic-buildimage.official.mellanox?branchName=201811&label=Mellanox)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=139&branchName=201811)
+[![Innovium](https://dev.azure.com/mssonic/build/_apis/build/status/innovium/Azure.sonic-buildimage.official.innovium?branchName=201811&label=Innovium)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=148&branchName=201811)
+[![Nephos](https://dev.azure.com/mssonic/build/_apis/build/status/nephos/Azure.sonic-buildimage.official.nephos?branchName=201811&label=Nephos)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=149&branchName=201811)
+[![VS](https://dev.azure.com/mssonic/build/_apis/build/status/vs/Azure.sonic-buildimage.official.vs?branchName=201811&label=VS)](https://dev.azure.com/mssonic/build/_build/latest?definitionId=142&branchName=201811)
*201807 builds*:
diff --git a/build_debian.sh b/build_debian.sh
index 71522271652c..267b46193465 100755
--- a/build_debian.sh
+++ b/build_debian.sh
@@ -237,7 +237,6 @@ then
sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubelet=${KUBERNETES_VERSION}-00
sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubectl=${KUBERNETES_VERSION}-00
sudo LANG=C chroot $FILESYSTEM_ROOT apt-get -y install kubeadm=${KUBERNETES_VERSION}-00
- # kubeadm package auto install kubelet & kubectl
else
echo '[INFO] Skipping Install kubernetes'
fi
diff --git a/device/accton/x86_64-accton_as4630_54te-r0/pmon_daemon_control.json b/device/accton/x86_64-accton_as4630_54te-r0/pmon_daemon_control.json
index 584a14b9d942..a3b204e20d8d 100644
--- a/device/accton/x86_64-accton_as4630_54te-r0/pmon_daemon_control.json
+++ b/device/accton/x86_64-accton_as4630_54te-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_as4630_54te-r0/sonic_platform/__init__.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/__init__.py
index a18a2a2d2a3b..cbd0cd4831e0 100644
--- a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/__init__.py
+++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/__init__.py
@@ -1,2 +1,2 @@
-__all__ = ['chassis', 'eeprom', 'platform', 'psu', 'sfp', 'thermal', 'fan']
+__all__ = [ "platform", "chassis", "sfp", "eeprom", "component", "psu", "thermal", "fan", "fan_drawer" ]
from . import platform
diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py
index d666e0c5bf86..7a54eee6f478 100644
--- a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py
+++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/chassis.py
@@ -27,6 +27,13 @@
REBOOT_CAUSE_FILE = "reboot-cause.txt"
PREV_REBOOT_CAUSE_FILE = "previous-reboot-cause.txt"
HOST_CHK_CMD = "docker > /dev/null 2>&1"
+SYSLED_FNODE = "/sys/class/leds/diag/brightness"
+SYSLED_MODES = {
+ "0" : "STATUS_LED_COLOR_OFF",
+ "1" : "STATUS_LED_COLOR_GREEN",
+ "2" : "STATUS_LED_COLOR_AMBER",
+ "5" : "STATUS_LED_COLOR_GREEN_BLINK"
+}
class Chassis(ChassisBase):
@@ -55,12 +62,11 @@ def __initialize_sfp(self):
self.sfp_module_initialized = True
def __initialize_fan(self):
- from sonic_platform.fan import Fan
- for fant_index in range(0, NUM_FAN_TRAY):
- for fan_index in range(0, NUM_FAN):
- fan = Fan(fant_index, fan_index)
- self._fan_list.append(fan)
-
+ from sonic_platform.fan_drawer import FanDrawer
+ for fant_index in range(NUM_FAN_TRAY):
+ fandrawer = FanDrawer(fant_index)
+ self._fan_drawer_list.append(fandrawer)
+ self._fan_list.extend(fandrawer._fan_list)
def __initialize_psu(self):
from sonic_platform.psu import Psu
for index in range(0, NUM_PSU):
@@ -192,3 +198,39 @@ def get_sfp(self, index):
sys.stderr.write("SFP index {} out of range (1-{})\n".format(
index, len(self._sfp_list)))
return sfp
+
+ def get_position_in_parent(self):
+ """
+ Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position
+ for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned
+ Returns:
+ integer: The 1-based relative physical position in parent device or -1 if cannot determine the position
+ """
+ return -1
+
+ def is_replaceable(self):
+ """
+ Indicate whether this device is replaceable.
+ Returns:
+ bool: True if it is replaceable.
+ """
+ return False
+
+
+ def initizalize_system_led(self):
+ return True
+
+ def get_status_led(self):
+ val = self._api_helper.read_txt_file(SYSLED_FNODE)
+ return SYSLED_MODES[val] if val in SYSLED_MODES else "UNKNOWN"
+
+ def set_status_led(self, color):
+ mode = None
+ for key, val in SYSLED_MODES.items():
+ if val == color:
+ mode = key
+ break
+ if mode is None:
+ return False
+ else:
+ return self._api_helper.write_txt_file(SYSLED_FNODE, mode)
diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan.py
index 663c343a75f6..8f48931244db 100644
--- a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan.py
+++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan.py
@@ -13,10 +13,10 @@
raise ImportError(str(e) + "- required module not found")
PSU_FAN_MAX_RPM = 26688
-
-CPLD_I2C_PATH = "/sys/bus/i2c/devices/3-0060/fan_"
-PSU_HWMON_I2C_PATH ="/sys/bus/i2c/devices/{}-00{}/"
-PSU_I2C_MAPPING = {
+SPEED_TOLERANCE = 15
+CPLD_FAN_I2C_PATH = "/sys/bus/i2c/devices/3-0060/fan_"
+I2C_PATH ="/sys/bus/i2c/devices/{}-00{}/"
+PSU_HWMON_I2C_MAPPING = {
0: {
"num": 10,
"addr": "58"
@@ -27,6 +27,20 @@
},
}
+PSU_CPLD_I2C_MAPPING = {
+ 0: {
+ "num": 10,
+ "addr": "50"
+ },
+ 1: {
+ "num": 11,
+ "addr": "51"
+ },
+}
+
+
+FAN_NAME_LIST = ["FAN-1F", "FAN-1R", "FAN-2F", "FAN-2R",
+ "FAN-3F", "FAN-3R"]
class Fan(FanBase):
"""Platform-specific Fan class"""
@@ -39,9 +53,14 @@ def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0):
if self.is_psu_fan:
self.psu_index = psu_index
- self.psu_i2c_num = PSU_I2C_MAPPING[self.psu_index]['num']
- self.psu_i2c_addr = PSU_I2C_MAPPING[self.psu_index]['addr']
- self.psu_hwmon_path = PSU_HWMON_I2C_PATH.format(
+ self.psu_i2c_num = PSU_HWMON_I2C_MAPPING[self.psu_index]['num']
+ self.psu_i2c_addr = PSU_HWMON_I2C_MAPPING[self.psu_index]['addr']
+ self.psu_hwmon_path = I2C_PATH.format(
+ self.psu_i2c_num, self.psu_i2c_addr)
+
+ self.psu_i2c_num = PSU_CPLD_I2C_MAPPING[self.psu_index]['num']
+ self.psu_i2c_addr = PSU_CPLD_I2C_MAPPING[self.psu_index]['addr']
+ self.psu_cpld_path = I2C_PATH.format(
self.psu_i2c_num, self.psu_i2c_addr)
FanBase.__init__(self)
@@ -57,10 +76,10 @@ def get_direction(self):
if not self.is_psu_fan:
- dir_str = "{}{}{}".format(CPLD_I2C_PATH, 'direction_', self.fan_tray_index)
+ dir_str = "{}{}{}".format(CPLD_FAN_I2C_PATH, 'direction_', self.fan_tray_index+1)
val=self._api_helper.read_txt_file(dir_str)
if val is not None:
- if val==0:#F2B
+ if int(val, 10)==0:#F2B
direction=self.FAN_DIRECTION_EXHAUST
else:
direction=self.FAN_DIRECTION_INTAKE
@@ -99,7 +118,7 @@ def get_speed(self):
else:
return 0
elif self.get_presence():
- speed_path = "{}{}".format(CPLD_I2C_PATH, 'duty_cycle_percentage')
+ speed_path = "{}{}".format(CPLD_FAN_I2C_PATH, 'duty_cycle_percentage')
speed=self._api_helper.read_txt_file(speed_path)
if speed is None:
return 0
@@ -116,7 +135,7 @@ def get_target_speed(self):
0 : when PWM mode is use
pwm : when pwm mode is not use
"""
- return False #Not supported
+ return self.get_speed()
def get_speed_tolerance(self):
"""
@@ -125,7 +144,7 @@ def get_speed_tolerance(self):
An integer, the percentage of variance from target speed which is
considered tolerable
"""
- return False #Not supported
+ return SPEED_TOLERANCE
def set_speed(self, speed):
"""
@@ -138,7 +157,7 @@ def set_speed(self, speed):
"""
if not self.is_psu_fan and self.get_presence():
- speed_path = "{}{}".format(CPLD_I2C_PATH, 'duty_cycle_percentage')
+ speed_path = "{}{}".format(CPLD_FAN_I2C_PATH, 'duty_cycle_percentage')
return self._api_helper.write_txt_file(speed_path, int(speed))
return False
@@ -154,18 +173,109 @@ def set_status_led(self, color):
"""
return False #Not supported
+ def get_status_led(self):
+ """
+ Gets the state of the fan status LED
+ Returns:
+ A string, one of the predefined STATUS_LED_COLOR_* strings above
+ """
+ status=self.get_presence()
+ if status is None:
+ return self.STATUS_LED_COLOR_OFF
+
+ return {
+ 1: self.STATUS_LED_COLOR_GREEN,
+ 0: self.STATUS_LED_COLOR_RED
+ }.get(status, self.STATUS_LED_COLOR_OFF)
+
+ def get_name(self):
+ """
+ Retrieves the name of the device
+ Returns:
+ string: The name of the device
+ """
+ fan_name = FAN_NAME_LIST[self.fan_tray_index*2 + self.fan_index] \
+ if not self.is_psu_fan \
+ else "PSU-{} FAN-{}".format(self.psu_index+1, self.fan_index+1)
+
+ return fan_name
+
def get_presence(self):
"""
Retrieves the presence of the FAN
Returns:
bool: True if FAN is present, False if not
"""
- present_path = "{}{}{}".format(CPLD_I2C_PATH, 'present_', self.fan_index+1)
+
+
+ if self.is_psu_fan:
+ present_path="{}{}".format(self.psu_cpld_path, 'psu_present')
+ else:
+ present_path = "{}{}{}".format(CPLD_FAN_I2C_PATH, 'present_', self.fan_tray_index+1)
+
val=self._api_helper.read_txt_file(present_path)
- if not self.is_psu_fan:
+ if val is not None:
+ return int(val, 10)==1
+ else:
+ return False
+
+ def get_status(self):
+ """
+ Retrieves the operational status of the device
+ Returns:
+ A boolean value, True if device is operating properly, False if not
+ """
+ if self.is_psu_fan:
+ psu_fan_path= "{}{}".format(self.psu_hwmon_path, 'psu_fan1_fault')
+ val=self._api_helper.read_txt_file(psu_fan_path)
if val is not None:
- return int(val, 10)==1
+ return int(val, 10)==0
else:
return False
else:
- return True
+ path = "{}{}{}".format(CPLD_FAN_I2C_PATH, 'fault_', self.fan_tray_index+1)
+ val=self._api_helper.read_txt_file(path)
+ if val is not None:
+ return int(val, 10)==0
+ else:
+ return False
+
+
+ def get_model(self):
+ """
+ Retrieves the model number (or part number) of the device
+ Returns:
+ string: Model/part number of device
+ """
+
+ return "N/A"
+
+ def get_serial(self):
+ """
+ Retrieves the serial number of the device
+ Returns:
+ string: Serial number of device
+ """
+ return "N/A"
+
+ def get_position_in_parent(self):
+ """
+ Retrieves 1-based relative physical position in parent device.
+ If the agent cannot determine the parent-relative position
+ for some reason, or if the associated value of
+ entPhysicalContainedIn is'0', then the value '-1' is returned
+ Returns:
+ integer: The 1-based relative physical position in parent device
+ or -1 if cannot determine the position
+ """
+ return (self.fan_tray_index+1) \
+ if not self.is_psu_fan else (self.psu_index+1)
+
+ def is_replaceable(self):
+ """
+ Indicate whether this device is replaceable.
+ Returns:
+ bool: True if it is replaceable.
+ """
+ return True if not self.is_psu_fan else False
+
diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan_drawer.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan_drawer.py
new file mode 100644
index 000000000000..e21163c106c1
--- /dev/null
+++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan_drawer.py
@@ -0,0 +1,90 @@
+########################################################################
+#
+# Module contains an implementation of SONiC Platform Base API and
+# provides the Fan-Drawers' information available in the platform.
+#
+########################################################################
+
+try:
+ from sonic_platform_base.fan_drawer_base import FanDrawerBase
+except ImportError as e:
+ raise ImportError(str(e) + "- required module not found")
+
+FANS_PER_FANTRAY = 2
+
+
+class FanDrawer(FanDrawerBase):
+ """Platform-specific Fan class"""
+
+ def __init__(self, fantray_index):
+
+ FanDrawerBase.__init__(self)
+ # FanTray is 0-based in platforms
+ self.fantrayindex = fantray_index
+ self.__initialize_fan_drawer()
+
+
+ def __initialize_fan_drawer(self):
+ from sonic_platform.fan import Fan
+ for i in range(FANS_PER_FANTRAY):
+ self._fan_list.append(Fan(self.fantrayindex, i))
+
+ def get_name(self):
+ """
+ Retrieves the fan drawer name
+ Returns:
+ string: The name of the device
+ """
+ return "FanTray{}".format(self.fantrayindex+1)
+
+ def get_presence(self):
+ """
+ Retrieves the presence of the device
+ Returns:
+ bool: True if device is present, False if not
+ """
+ return self._fan_list[0].get_presence()
+
+ def get_model(self):
+ """
+ Retrieves the model number (or part number) of the device
+ Returns:
+ string: Model/part number of device
+ """
+ return self._fan_list[0].get_model()
+
+ def get_serial(self):
+ """
+ Retrieves the serial number of the device
+ Returns:
+ string: Serial number of device
+ """
+ return self._fan_list[0].get_serial()
+
+ def get_status(self):
+ """
+ Retrieves the operational status of the device
+ Returns:
+ A boolean value, True if device is operating properly, False if not
+ """
+ return self._fan_list[0].get_status()
+
+ def get_position_in_parent(self):
+ """
+ Retrieves 1-based relative physical position in parent device.
+ If the agent cannot determine the parent-relative position
+ for some reason, or if the associated value of
+ entPhysicalContainedIn is'0', then the value '-1' is returned
+ Returns:
+ integer: The 1-based relative physical position in parent device
+ or -1 if cannot determine the position
+ """
+ return (self.fantrayindex+1)
+
+ def is_replaceable(self):
+ """
+ Indicate whether this device is replaceable.
+ Returns:
+ bool: True if it is replaceable.
+ """
+ return True
diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/helper.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/helper.py
index 4cd60ac90611..b124ca29f0df 100644
--- a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/helper.py
+++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/helper.py
@@ -51,7 +51,7 @@ def run_interactive_command(self, cmd):
def read_txt_file(self, file_path):
try:
- with open(file_path, 'r') as fd:
+ with open(file_path, 'r', errors='replace') as fd:
data = fd.read()
return data.strip()
except IOError:
diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/psu.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/psu.py
index 3413ab5779cc..8eab43891b39 100644
--- a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/psu.py
+++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/psu.py
@@ -139,8 +139,15 @@ def get_status_led(self):
Returns:
A string, one of the predefined STATUS_LED_COLOR_* strings above
"""
+ status=self.get_status()
+ if status is None:
+ return self.STATUS_LED_COLOR_OFF
+
+ return {
+ 1: self.STATUS_LED_COLOR_GREEN,
+ 0: self.STATUS_LED_COLOR_RED
+ }.get(status, self.STATUS_LED_COLOR_OFF)
- return False #Controlled by HW
def get_temperature(self):
"""
@@ -226,3 +233,45 @@ def get_status(self):
return int(val, 10) == 1
else:
return 0
+
+ def get_model(self):
+ """
+ Retrieves the model number (or part number) of the device
+ Returns:
+ string: Model/part number of device
+ """
+ model_path="{}{}".format(self.cpld_path, 'psu_model_name')
+ model=self._api_helper.read_txt_file(model_path)
+ if model is None:
+ return "N/A"
+
+ return model
+
+ def get_serial(self):
+ """
+ Retrieves the serial number of the device
+ Returns:
+ string: Serial number of device
+ """
+ serial_path="{}{}".format(self.cpld_path, 'psu_serial_number')
+ serial=self._api_helper.read_txt_file(serial_path)
+ if serial is None:
+ return "N/A"
+ return serial
+
+ def get_position_in_parent(self):
+ """
+ Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position
+ for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned
+ Returns:
+ integer: The 1-based relative physical position in parent device or -1 if cannot determine the position
+ """
+ return self.index+1
+
+ def is_replaceable(self):
+ """
+ Indicate whether this device is replaceable.
+ Returns:
+ bool: True if it is replaceable.
+ """
+ return True
diff --git a/device/accton/x86_64-accton_as4630_54te-r0/system_health_monitoring_config.json b/device/accton/x86_64-accton_as4630_54te-r0/system_health_monitoring_config.json
new file mode 100644
index 000000000000..91a29558b492
--- /dev/null
+++ b/device/accton/x86_64-accton_as4630_54te-r0/system_health_monitoring_config.json
@@ -0,0 +1,15 @@
+{
+ "services_to_ignore": [],
+ "devices_to_ignore": [
+ "asic",
+ "psu.temperature"
+
+ ],
+ "user_defined_checkers": [],
+ "polling_interval": 60,
+ "led_color": {
+ "fault": "STATUS_LED_COLOR_AMBER",
+ "normal": "STATUS_LED_COLOR_GREEN",
+ "booting": "STATUS_LED_COLOR_GREEN_BLINK"
+ }
+}
diff --git a/device/accton/x86_64-accton_as7326_56x-r0/custom_led.bin b/device/accton/x86_64-accton_as7326_56x-r0/custom_led.bin
index 8495c8216801..817b02a195e2 100755
Binary files a/device/accton/x86_64-accton_as7326_56x-r0/custom_led.bin and b/device/accton/x86_64-accton_as7326_56x-r0/custom_led.bin differ
diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers_defaults_t0.j2
index 38e34eb571e8..dc04b2265f33 100644
--- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers_defaults_t0.j2
+++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers_defaults_t0.j2
@@ -1,4 +1,4 @@
-{%- set default_cable = '300m' %}
+{%- set default_cable = '0m' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
diff --git a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers_defaults_t1.j2
index 38e34eb571e8..dc04b2265f33 100644
--- a/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers_defaults_t1.j2
+++ b/device/arista/x86_64-arista_7050_qx32/Arista-7050-QX32/buffers_defaults_t1.j2
@@ -1,4 +1,4 @@
-{%- set default_cable = '300m' %}
+{%- set default_cable = '0m' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers_defaults_t0.j2
index d93aa34893d6..3c0a68f1da88 100644
--- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers_defaults_t0.j2
+++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers_defaults_t0.j2
@@ -1,4 +1,4 @@
-{%- set default_cable = '300m' %}
+{%- set default_cable = '0m' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers_defaults_t1.j2
index d93aa34893d6..3c0a68f1da88 100644
--- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers_defaults_t1.j2
+++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX-32S-S4Q31/buffers_defaults_t1.j2
@@ -1,4 +1,4 @@
-{%- set default_cable = '300m' %}
+{%- set default_cable = '0m' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX32S-Q32/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX32S-Q32/buffers_defaults_t0.j2
index 38e34eb571e8..dc04b2265f33 100644
--- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX32S-Q32/buffers_defaults_t0.j2
+++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX32S-Q32/buffers_defaults_t0.j2
@@ -1,4 +1,4 @@
-{%- set default_cable = '300m' %}
+{%- set default_cable = '0m' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
diff --git a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX32S-Q32/buffers_defaults_t1.j2 b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX32S-Q32/buffers_defaults_t1.j2
index 38e34eb571e8..dc04b2265f33 100644
--- a/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX32S-Q32/buffers_defaults_t1.j2
+++ b/device/arista/x86_64-arista_7050_qx32s/Arista-7050QX32S-Q32/buffers_defaults_t1.j2
@@ -1,4 +1,4 @@
-{%- set default_cable = '300m' %}
+{%- set default_cable = '0m' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
diff --git a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t0.j2 b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t0.j2
index f5b7327e705d..2a328ac4806d 100644
--- a/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t0.j2
+++ b/device/arista/x86_64-arista_7050cx3_32s/Arista-7050CX3-32S-C32/buffers_defaults_t0.j2
@@ -10,7 +10,7 @@
{%- macro generate_buffer_pool_and_profiles() %}
"BUFFER_POOL": {
"ingress_lossless_pool": {
- "size": "32712448",
+ "size": "32732160",
"type": "ingress",
"mode": "dynamic",
"xoff": "1622016"
diff --git a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json
index 6ab72e55ab47..b78f75fbf284 100644
--- a/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json
+++ b/device/arista/x86_64-arista_7170_32c/Arista-7170-32C-C32/board_lane_map.json
@@ -5,7 +5,7 @@
{
"connector": 1,
"device_id": 0,
- "mac_block": 14,
+ "mac_block": 7,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -59,7 +59,7 @@
{
"connector": 2,
"device_id": 0,
- "mac_block": 12,
+ "mac_block": 6,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -113,7 +113,7 @@
{
"connector": 3,
"device_id": 0,
- "mac_block": 10,
+ "mac_block": 5,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -167,7 +167,7 @@
{
"connector": 4,
"device_id": 0,
- "mac_block": 8,
+ "mac_block": 4,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -221,7 +221,7 @@
{
"connector": 5,
"device_id": 0,
- "mac_block": 6,
+ "mac_block": 3,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -275,7 +275,7 @@
{
"connector": 6,
"device_id": 0,
- "mac_block": 4,
+ "mac_block": 2,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -329,7 +329,7 @@
{
"connector": 7,
"device_id": 0,
- "mac_block": 2,
+ "mac_block": 1,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -437,7 +437,7 @@
{
"connector": 9,
"device_id": 0,
- "mac_block": 62,
+ "mac_block": 31,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -491,7 +491,7 @@
{
"connector": 10,
"device_id": 0,
- "mac_block": 60,
+ "mac_block": 30,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -545,7 +545,7 @@
{
"connector": 11,
"device_id": 0,
- "mac_block": 58,
+ "mac_block": 29,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -599,7 +599,7 @@
{
"connector": 12,
"device_id": 0,
- "mac_block": 56,
+ "mac_block": 28,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -653,7 +653,7 @@
{
"connector": 13,
"device_id": 0,
- "mac_block": 54,
+ "mac_block": 27,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -707,7 +707,7 @@
{
"connector": 14,
"device_id": 0,
- "mac_block": 52,
+ "mac_block": 26,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -761,7 +761,7 @@
{
"connector": 15,
"device_id": 0,
- "mac_block": 50,
+ "mac_block": 25,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -815,7 +815,7 @@
{
"connector": 16,
"device_id": 0,
- "mac_block": 48,
+ "mac_block": 24,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -869,7 +869,7 @@
{
"connector": 17,
"device_id": 0,
- "mac_block": 46,
+ "mac_block": 23,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -923,7 +923,7 @@
{
"connector": 18,
"device_id": 0,
- "mac_block": 44,
+ "mac_block": 22,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -977,7 +977,7 @@
{
"connector": 19,
"device_id": 0,
- "mac_block": 42,
+ "mac_block": 21,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1031,7 +1031,7 @@
{
"connector": 20,
"device_id": 0,
- "mac_block": 40,
+ "mac_block": 20,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1085,7 +1085,7 @@
{
"connector": 21,
"device_id": 0,
- "mac_block": 38,
+ "mac_block": 19,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1139,7 +1139,7 @@
{
"connector": 22,
"device_id": 0,
- "mac_block": 36,
+ "mac_block": 18,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1193,7 +1193,7 @@
{
"connector": 23,
"device_id": 0,
- "mac_block": 34,
+ "mac_block": 17,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1247,7 +1247,7 @@
{
"connector": 24,
"device_id": 0,
- "mac_block": 32,
+ "mac_block": 16,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1301,7 +1301,7 @@
{
"connector": 25,
"device_id": 0,
- "mac_block": 30,
+ "mac_block": 15,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1355,7 +1355,7 @@
{
"connector": 26,
"device_id": 0,
- "mac_block": 28,
+ "mac_block": 14,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1409,7 +1409,7 @@
{
"connector": 27,
"device_id": 0,
- "mac_block": 26,
+ "mac_block": 13,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1463,7 +1463,7 @@
{
"connector": 28,
"device_id": 0,
- "mac_block": 24,
+ "mac_block": 12,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1517,7 +1517,7 @@
{
"connector": 29,
"device_id": 0,
- "mac_block": 22,
+ "mac_block": 11,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1571,7 +1571,7 @@
{
"connector": 30,
"device_id": 0,
- "mac_block": 20,
+ "mac_block": 10,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1625,7 +1625,7 @@
{
"connector": 31,
"device_id": 0,
- "mac_block": 18,
+ "mac_block": 9,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
@@ -1679,7 +1679,7 @@
{
"connector": 32,
"device_id": 0,
- "mac_block": 16,
+ "mac_block": 8,
"media_type": "copper",
"lane0": {
"mac_ch": 0,
diff --git a/device/arista/x86_64-arista_7170_32c/default_sku b/device/arista/x86_64-arista_7170_32c/default_sku
index 536bad44f086..e396ca3395f6 100644
--- a/device/arista/x86_64-arista_7170_32c/default_sku
+++ b/device/arista/x86_64-arista_7170_32c/default_sku
@@ -1 +1 @@
-Arista-7170-32CD-C32 t1
+Arista-7170-32C-C32 t1
diff --git a/device/arista/x86_64-arista_7170_32c/sensors.conf b/device/arista/x86_64-arista_7170_32c/sensors.conf
deleted file mode 120000
index 1ab9e0f47704..000000000000
--- a/device/arista/x86_64-arista_7170_32c/sensors.conf
+++ /dev/null
@@ -1 +0,0 @@
-../x86_64-arista_7170_64c/sensors.conf
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7170_32c/sensors.conf b/device/arista/x86_64-arista_7170_32c/sensors.conf
new file mode 100644
index 000000000000..d3de228da97a
--- /dev/null
+++ b/device/arista/x86_64-arista_7170_32c/sensors.conf
@@ -0,0 +1,57 @@
+# libsensors configuration file for DCS-7170-32C
+# ------------------------------------------------
+
+bus "i2c-6" "SCD 0000:06:00.0 SMBus master 0 bus 5"
+bus "i2c-7" "SCD 0000:06:00.0 SMBus master 0 bus 6"
+bus "i2c-8" "SCD 0000:06:00.0 SMBus master 0 bus 7"
+bus "i2c-81" "SCD 0000:ff:0b.3 SMBus master 0 bus 0"
+
+chip "max6658-i2c-8-4c"
+ label temp1 "Temp sensor near ASIC"
+
+ set temp1_max 100
+ set temp1_crit 110
+ set temp1_min -55
+
+ set temp2_max 100
+ set temp2_crit 110
+ set temp2_min -55
+ ignore temp2
+
+chip "pmbus-i2c-6-58"
+ label temp1 "PSU1 primary hotspot temp"
+ label temp2 "PSU1 inlet temp"
+ label temp3 "PSU1 exhaust temp"
+
+ # setting maximum and critical thresholds is not supported for this psu
+ # fault and warning limits defined internally by hardware
+
+ ignore fan2
+ ignore fan3
+
+chip "pmbus-i2c-7-58"
+ label temp1 "PSU2 primary hotspot temp"
+ label temp2 "PSU2 inlet temp"
+ label temp3 "PSU2 exhaust temp"
+
+ # setting maximum and critical thresholds is not supported for this psu
+ # fault and warning limits defined internally by hardware
+
+ ignore fan2
+ ignore fan3
+
+chip "max6658-i2c-81-4c"
+ label temp1 "Rear air temp1"
+ label temp2 "Rear air temp2"
+
+ set temp1_max 70
+ set temp1_crit 80
+ set temp1_min -55
+ set temp2_max 70
+ set temp2_crit 80
+ set temp2_min -55
+
+chip "lm73-i2c-8-4a"
+ label temp1 "Front air temp"
+
+ set temp1_max 65
diff --git a/device/arista/x86_64-arista_7170_32cd/sensors.conf b/device/arista/x86_64-arista_7170_32cd/sensors.conf
index 1ab9e0f47704..39485db7bba1 120000
--- a/device/arista/x86_64-arista_7170_32cd/sensors.conf
+++ b/device/arista/x86_64-arista_7170_32cd/sensors.conf
@@ -1 +1 @@
-../x86_64-arista_7170_64c/sensors.conf
\ No newline at end of file
+../x86_64-arista_7170_32c/sensors.conf
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-32D4 b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-32D4
new file mode 120000
index 000000000000..7546a1ba9e29
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-32D4
@@ -0,0 +1 @@
+Arista-7280CR3-C32D4
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/jr2-a7280cr3-32d4-32x100G+4x400G.config.bcm b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/jr2-a7280cr3-32d4-32x100G+4x400G.config.bcm
new file mode 100644
index 000000000000..003579a88692
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/jr2-a7280cr3-32d4-32x100G+4x400G.config.bcm
@@ -0,0 +1,753 @@
+soc_family.BCM8869X=BCM8869X
+
+dpp_db_path=/usr/share/bcm/db
+custom_feature_ucode_path=u_code_db2pem.txt
+system_headers_mode=1
+suppress_unknown_prop_warnings=1
+l4_protocols_load_balancing_enable=1
+fabric_logical_port_base=512
+trunk_group_max_members=128
+num_olp_tm_ports.BCM8869X=1
+
+ucode_port_0.BCM8869X=CPU.0:core_0.0
+ucode_port_200.BCM8869X=CPU.8:core_1.200
+ucode_port_201.BCM8869X=CPU.16:core_0.201
+ucode_port_202.BCM8869X=CPU.24:core_1.202
+ucode_port_203.BCM8869X=CPU.32:core_0.203
+
+port_init_speed_xe.BCM8869X=10000
+port_init_speed_xl.BCM8869X=40000
+port_init_speed_le.BCM8869X=50000
+port_init_speed_ce.BCM8869X=100000
+port_init_speed_cc.BCM8869X=200000
+port_init_speed_cd.BCM8869X=400000
+port_init_speed_il.BCM8869X=10312
+
+port_init_cl72=0
+
+serdes_tx_taps_1=pam4:-16:64:0:3:0:0
+serdes_tx_taps_2=pam4:-16:64:0:3:0:0
+serdes_tx_taps_3=pam4:-16:64:0:3:0:0
+serdes_tx_taps_4=pam4:-16:64:0:3:0:0
+serdes_tx_taps_5=pam4:-16:64:0:3:0:0
+serdes_tx_taps_6=pam4:-16:64:0:3:0:0
+serdes_tx_taps_7=pam4:-16:64:0:3:0:0
+serdes_tx_taps_8=pam4:-16:64:0:3:0:0
+serdes_tx_taps_9=pam4:-8:60:0:0:0:0
+serdes_tx_taps_10=pam4:-8:60:0:0:0:0
+serdes_tx_taps_11=pam4:-8:60:0:0:0:0
+serdes_tx_taps_12=pam4:-8:60:0:0:0:0
+serdes_tx_taps_13=pam4:-8:60:0:0:0:0
+serdes_tx_taps_14=pam4:-8:60:0:0:0:0
+serdes_tx_taps_15=pam4:-8:60:0:0:0:0
+serdes_tx_taps_16=pam4:-8:60:0:0:0:0
+serdes_tx_taps_17=pam4:-8:60:0:0:0:0
+serdes_tx_taps_18=pam4:-8:60:0:0:0:0
+serdes_tx_taps_19=pam4:-8:60:0:0:0:0
+serdes_tx_taps_20=pam4:-8:60:0:0:0:0
+serdes_tx_taps_21=pam4:-8:60:0:0:0:0
+serdes_tx_taps_22=pam4:-8:60:0:0:0:0
+serdes_tx_taps_23=pam4:-8:60:0:0:0:0
+serdes_tx_taps_24=pam4:-8:60:0:0:0:0
+serdes_tx_taps_25=pam4:-8:60:0:0:0:0
+serdes_tx_taps_26=pam4:-8:60:0:0:0:0
+serdes_tx_taps_27=pam4:-8:60:0:0:0:0
+serdes_tx_taps_28=pam4:-8:60:0:0:0:0
+serdes_tx_taps_29=pam4:-16:60:0:3:0:0
+serdes_tx_taps_30=pam4:-16:60:0:3:0:0
+serdes_tx_taps_31=pam4:-16:60:0:3:0:0
+serdes_tx_taps_32=pam4:-16:60:0:3:0:0
+serdes_tx_taps_33=pam4:-28:136:0:4:0:0
+serdes_tx_taps_34=pam4:-32:128:0:6:0:0
+serdes_tx_taps_35=pam4:-32:128:0:6:0:0
+serdes_tx_taps_36=pam4:-28:136:0:4:0:0
+
+ucode_port_100.BCM8869X=RCY_MIRROR.0:core_0.100
+ucode_port_101.BCM8869X=RCY_MIRROR.1:core_0.101
+ucode_port_102.BCM8869X=RCY_MIRROR.2:core_0.102
+ucode_port_103.BCM8869X=RCY_MIRROR.3:core_0.103
+ucode_port_104.BCM8869X=RCY_MIRROR.4:core_0.104
+ucode_port_105.BCM8869X=RCY_MIRROR.5:core_0.105
+ucode_port_106.BCM8869X=RCY_MIRROR.6:core_0.106
+ucode_port_107.BCM8869X=RCY_MIRROR.7:core_0.107
+ucode_port_108.BCM8869X=RCY_MIRROR.8:core_0.108
+ucode_port_109.BCM8869X=RCY_MIRROR.9:core_0.109
+ucode_port_110.BCM8869X=RCY_MIRROR.10:core_0.110
+ucode_port_111.BCM8869X=RCY_MIRROR.11:core_0.111
+ucode_port_112.BCM8869X=RCY_MIRROR.12:core_0.112
+ucode_port_113.BCM8869X=RCY_MIRROR.13:core_0.113
+ucode_port_114.BCM8869X=RCY_MIRROR.14:core_0.114
+ucode_port_115.BCM8869X=RCY_MIRROR.15:core_0.115
+ucode_port_116.BCM8869X=RCY_MIRROR.16:core_0.116
+ucode_port_117.BCM8869X=RCY_MIRROR.17:core_0.117
+ucode_port_118.BCM8869X=RCY_MIRROR.18:core_0.118
+ucode_port_119.BCM8869X=RCY_MIRROR.19:core_0.119
+ucode_port_120.BCM8869X=RCY_MIRROR.0:core_1.120
+ucode_port_121.BCM8869X=RCY_MIRROR.1:core_1.121
+ucode_port_122.BCM8869X=RCY_MIRROR.2:core_1.122
+ucode_port_123.BCM8869X=RCY_MIRROR.3:core_1.123
+ucode_port_124.BCM8869X=RCY_MIRROR.4:core_1.124
+ucode_port_125.BCM8869X=RCY_MIRROR.5:core_1.125
+ucode_port_126.BCM8869X=RCY_MIRROR.6:core_1.126
+ucode_port_127.BCM8869X=RCY_MIRROR.7:core_1.127
+ucode_port_128.BCM8869X=RCY_MIRROR.8:core_1.128
+ucode_port_129.BCM8869X=RCY_MIRROR.9:core_1.129
+ucode_port_130.BCM8869X=RCY_MIRROR.10:core_1.130
+ucode_port_131.BCM8869X=RCY_MIRROR.11:core_1.131
+ucode_port_132.BCM8869X=RCY_MIRROR.12:core_1.132
+ucode_port_133.BCM8869X=RCY_MIRROR.13:core_1.133
+ucode_port_134.BCM8869X=RCY_MIRROR.14:core_1.134
+ucode_port_135.BCM8869X=RCY_MIRROR.15:core_1.135
+ucode_port_136.BCM8869X=RCY_MIRROR.16:core_1.136
+ucode_port_137.BCM8869X=RCY_MIRROR.17:core_1.137
+ucode_port_138.BCM8869X=RCY_MIRROR.18:core_1.138
+ucode_port_139.BCM8869X=RCY_MIRROR.19:core_1.139
+
+port_priorities.BCM8869X=8
+
+ucode_port_240.BCM8869X=OLP:core_0.240
+
+sw_state_max_size.BCM8869X=750000000
+
+stable_location.BCM8869X=4
+stable_location.BCM8869X_ADAPTER=3
+
+stable_filename.BCM8869X_ADAPTER=warmboot_data_0
+stable_filename=/dev/shm/warmboot_data_0
+stable_filename.1=/dev/shm/warmboot_data_1
+stable_filename.2=/dev/shm/warmboot_data_2
+
+stable_size.BCM8869X=800000000
+
+tm_port_header_type_in_0.BCM8869X=INJECTED_2
+tm_port_header_type_out_0.BCM8869X=CPU
+
+tm_port_header_type_in_200.BCM8869X=INJECTED_2_PP
+tm_port_header_type_out_200.BCM8869X=ETH
+tm_port_header_type_in_201.BCM8869X=INJECTED_2_PP
+tm_port_header_type_out_201.BCM8869X=ETH
+tm_port_header_type_in_202.BCM8869X=INJECTED_2_PP
+tm_port_header_type_out_202.BCM8869X=ETH
+tm_port_header_type_in_203.BCM8869X=INJECTED_2_PP
+tm_port_header_type_out_203.BCM8869X=ETH
+
+sat_enable.BCM8869X=1
+tm_port_header_type_out_210.BCM8869X=CPU
+tm_port_header_type_in_210.BCM8869X=INJECTED_2
+
+tm_port_header_type_in_211.BCM8869X=INJECTED_2
+tm_port_header_type_out_211.BCM8869X=CPU
+tm_port_header_type_in_212.BCM8869X=INJECTED_2
+tm_port_header_type_out_212.BCM8869X=CPU
+
+tm_port_header_type_in_240.BCM8869X=INJECTED_2
+tm_port_header_type_out_240.BCM8869X=RAW
+
+dtm_flow_mapping_mode_region_64.BCM8869X=3
+dtm_flow_mapping_mode_region_65.BCM8869X=3
+dtm_flow_mapping_mode_region_66.BCM8869X=3
+dtm_flow_mapping_mode_region_67.BCM8869X=3
+dtm_flow_mapping_mode_region_68.BCM8869X=3
+dtm_flow_mapping_mode_region_69.BCM8869X=3
+dtm_flow_mapping_mode_region_70.BCM8869X=3
+dtm_flow_mapping_mode_region_71.BCM8869X=3
+dtm_flow_mapping_mode_region_72.BCM8869X=3
+dtm_flow_mapping_mode_region_73.BCM8869X=3
+dtm_flow_mapping_mode_region_74.BCM8869X=3
+dtm_flow_mapping_mode_region_75.BCM8869X=3
+dtm_flow_mapping_mode_region_76.BCM8869X=3
+dtm_flow_mapping_mode_region_77.BCM8869X=3
+dtm_flow_mapping_mode_region_78.BCM8869X=3
+dtm_flow_mapping_mode_region_79.BCM8869X=7
+dtm_flow_mapping_mode_region_80.BCM8869X=3
+dtm_flow_mapping_mode_region_81.BCM8869X=1
+dtm_flow_mapping_mode_region_82.BCM8869X=3
+dtm_flow_mapping_mode_region_83.BCM8869X=3
+dtm_flow_mapping_mode_region_84.BCM8869X=3
+dtm_flow_mapping_mode_region_85.BCM8869X=3
+dtm_flow_mapping_mode_region_86.BCM8869X=3
+dtm_flow_mapping_mode_region_87.BCM8869X=3
+dtm_flow_mapping_mode_region_88.BCM8869X=3
+dtm_flow_mapping_mode_region_89.BCM8869X=3
+dtm_flow_mapping_mode_region_90.BCM8869X=3
+dtm_flow_mapping_mode_region_91.BCM8869X=3
+dtm_flow_mapping_mode_region_92.BCM8869X=3
+dtm_flow_mapping_mode_region_93.BCM8869X=3
+dtm_flow_mapping_mode_region_94.BCM8869X=3
+
+dtm_flow_nof_remote_cores_region_1.BCM8869X=2
+dtm_flow_nof_remote_cores_region_2.BCM8869X=2
+dtm_flow_nof_remote_cores_region_3.BCM8869X=2
+dtm_flow_nof_remote_cores_region_4.BCM8869X=2
+dtm_flow_nof_remote_cores_region_5.BCM8869X=2
+dtm_flow_nof_remote_cores_region_6.BCM8869X=2
+dtm_flow_nof_remote_cores_region_7.BCM8869X=2
+dtm_flow_nof_remote_cores_region_8.BCM8869X=2
+dtm_flow_nof_remote_cores_region_9.BCM8869X=2
+dtm_flow_nof_remote_cores_region_10.BCM8869X=2
+dtm_flow_nof_remote_cores_region_11.BCM8869X=2
+dtm_flow_nof_remote_cores_region_12.BCM8869X=2
+dtm_flow_nof_remote_cores_region_13.BCM8869X=2
+dtm_flow_nof_remote_cores_region_14.BCM8869X=2
+dtm_flow_nof_remote_cores_region_15.BCM8869X=2
+dtm_flow_nof_remote_cores_region_16.BCM8869X=2
+dtm_flow_nof_remote_cores_region_17.BCM8869X=2
+dtm_flow_nof_remote_cores_region_18.BCM8869X=2
+dtm_flow_nof_remote_cores_region_19.BCM8869X=2
+dtm_flow_nof_remote_cores_region_20.BCM8869X=2
+dtm_flow_nof_remote_cores_region_21.BCM8869X=2
+dtm_flow_nof_remote_cores_region_22.BCM8869X=2
+dtm_flow_nof_remote_cores_region_23.BCM8869X=2
+dtm_flow_nof_remote_cores_region_24.BCM8869X=2
+dtm_flow_nof_remote_cores_region_25.BCM8869X=2
+dtm_flow_nof_remote_cores_region_26.BCM8869X=2
+dtm_flow_nof_remote_cores_region_27.BCM8869X=2
+dtm_flow_nof_remote_cores_region_28.BCM8869X=2
+dtm_flow_nof_remote_cores_region_29.BCM8869X=2
+dtm_flow_nof_remote_cores_region_30.BCM8869X=2
+dtm_flow_nof_remote_cores_region_31.BCM8869X=2
+dtm_flow_nof_remote_cores_region_32.BCM8869X=2
+dtm_flow_nof_remote_cores_region_33.BCM8869X=2
+dtm_flow_nof_remote_cores_region_34.BCM8869X=2
+dtm_flow_nof_remote_cores_region_35.BCM8869X=2
+dtm_flow_nof_remote_cores_region_36.BCM8869X=2
+dtm_flow_nof_remote_cores_region_37.BCM8869X=2
+dtm_flow_nof_remote_cores_region_38.BCM8869X=2
+dtm_flow_nof_remote_cores_region_39.BCM8869X=2
+dtm_flow_nof_remote_cores_region_40.BCM8869X=2
+dtm_flow_nof_remote_cores_region_41.BCM8869X=2
+dtm_flow_nof_remote_cores_region_42.BCM8869X=2
+dtm_flow_nof_remote_cores_region_43.BCM8869X=2
+dtm_flow_nof_remote_cores_region_44.BCM8869X=2
+dtm_flow_nof_remote_cores_region_45.BCM8869X=2
+dtm_flow_nof_remote_cores_region_46.BCM8869X=2
+dtm_flow_nof_remote_cores_region_47.BCM8869X=2
+dtm_flow_nof_remote_cores_region_48.BCM8869X=2
+dtm_flow_nof_remote_cores_region_49.BCM8869X=2
+dtm_flow_nof_remote_cores_region_50.BCM8869X=2
+dtm_flow_nof_remote_cores_region_51.BCM8869X=2
+dtm_flow_nof_remote_cores_region_52.BCM8869X=2
+dtm_flow_nof_remote_cores_region_53.BCM8869X=2
+dtm_flow_nof_remote_cores_region_54.BCM8869X=2
+dtm_flow_nof_remote_cores_region_55.BCM8869X=2
+dtm_flow_nof_remote_cores_region_56.BCM8869X=2
+dtm_flow_nof_remote_cores_region_57.BCM8869X=2
+dtm_flow_nof_remote_cores_region_58.BCM8869X=2
+dtm_flow_nof_remote_cores_region_59.BCM8869X=2
+dtm_flow_nof_remote_cores_region_60.BCM8869X=2
+
+mdb_profile.BCM8869X=l3-xl
+
+outlif_logical_to_physical_phase_map_1=S1
+outlif_logical_to_physical_phase_map_2=L1
+outlif_logical_to_physical_phase_map_3=XL
+outlif_logical_to_physical_phase_map_4=L2
+outlif_logical_to_physical_phase_map_5=M1
+outlif_logical_to_physical_phase_map_6=M2
+outlif_logical_to_physical_phase_map_7=M3
+outlif_logical_to_physical_phase_map_8=S2
+
+outlif_physical_phase_data_granularity_S1=60
+outlif_physical_phase_data_granularity_S2=60
+outlif_physical_phase_data_granularity_M1=60
+outlif_physical_phase_data_granularity_M2=60
+outlif_physical_phase_data_granularity_M3=60
+outlif_physical_phase_data_granularity_L1=60
+outlif_physical_phase_data_granularity_L2=60
+outlif_physical_phase_data_granularity_XL=60
+
+port_init_speed_fabric.BCM8869X=53125
+
+fabric_connect_mode.BCM8869X=SINGLE_FAP
+protocol_traps_mode.BCM8869X=IN_LIF
+
+schan_intr_enable.BCM8869X=0
+tdma_intr_enable.BCM8869X=0
+tslam_intr_enable.BCM8869X=0
+miim_intr_enable.BCM8869X=0
+schan_timeout_usec.BCM8869X=300000
+tdma_timeout_usec.BCM8869X=1000000
+tslam_timeout_usec.BCM8869X=1000000
+
+appl_enable_intr_init.BCM8869X=1
+polled_irq_mode.BCM8869X=1
+polled_irq_delay.BCM8869X=1000
+
+bcm_stat_interval.BCM8869X=1000
+
+mem_cache_enable_ecc.BCM8869X=1
+mem_cache_enable_parity.BCM8869X=1
+
+serdes_nif_clk_freq_in.BCM8869X_A0=2
+serdes_nif_clk_freq_out.BCM8869X_A0=1
+serdes_fabric_clk_freq_in.BCM8869X_A0=2
+serdes_fabric_clk_freq_out.BCM8869X_A0=1
+
+serdes_nif_clk_freq_in.BCM8869X=1
+serdes_nif_clk_freq_out.BCM8869X=bypass
+serdes_fabric_clk_freq_in.BCM8869X=1
+serdes_fabric_clk_freq_out.BCM8869X=bypass
+
+dram_phy_tune_mode_on_init.BCM8869X=RUN_TUNE
+
+dport_map_direct.BCM8869X=1
+
+pmf_sexem3_stage.BCM8869X=IPMF3
+
+lane_to_serdes_map_fabric_lane0.0=rx0:tx0
+lane_to_serdes_map_fabric_lane1.0=rx1:tx1
+lane_to_serdes_map_fabric_lane2.0=rx2:tx2
+lane_to_serdes_map_fabric_lane3.0=rx3:tx3
+lane_to_serdes_map_fabric_lane4.0=rx4:tx4
+lane_to_serdes_map_fabric_lane5.0=rx5:tx5
+lane_to_serdes_map_fabric_lane6.0=rx6:tx6
+lane_to_serdes_map_fabric_lane7.0=rx7:tx7
+lane_to_serdes_map_fabric_lane8.0=rx8:tx8
+lane_to_serdes_map_fabric_lane9.0=rx9:tx9
+lane_to_serdes_map_fabric_lane10.0=rx10:tx10
+lane_to_serdes_map_fabric_lane11.0=rx11:tx11
+lane_to_serdes_map_fabric_lane12.0=rx12:tx12
+lane_to_serdes_map_fabric_lane13.0=rx13:tx13
+lane_to_serdes_map_fabric_lane14.0=rx14:tx14
+lane_to_serdes_map_fabric_lane15.0=rx15:tx15
+lane_to_serdes_map_fabric_lane16.0=rx16:tx16
+lane_to_serdes_map_fabric_lane17.0=rx17:tx17
+lane_to_serdes_map_fabric_lane18.0=rx18:tx18
+lane_to_serdes_map_fabric_lane19.0=rx19:tx19
+lane_to_serdes_map_fabric_lane20.0=rx20:tx20
+lane_to_serdes_map_fabric_lane21.0=rx21:tx21
+lane_to_serdes_map_fabric_lane22.0=rx22:tx22
+lane_to_serdes_map_fabric_lane23.0=rx23:tx23
+lane_to_serdes_map_fabric_lane24.0=rx24:tx24
+lane_to_serdes_map_fabric_lane25.0=rx25:tx25
+lane_to_serdes_map_fabric_lane26.0=rx26:tx26
+lane_to_serdes_map_fabric_lane27.0=rx27:tx27
+lane_to_serdes_map_fabric_lane28.0=rx28:tx28
+lane_to_serdes_map_fabric_lane29.0=rx29:tx29
+lane_to_serdes_map_fabric_lane30.0=rx30:tx30
+lane_to_serdes_map_fabric_lane31.0=rx31:tx31
+lane_to_serdes_map_fabric_lane32.0=rx32:tx32
+lane_to_serdes_map_fabric_lane33.0=rx33:tx33
+lane_to_serdes_map_fabric_lane34.0=rx34:tx34
+lane_to_serdes_map_fabric_lane35.0=rx35:tx35
+lane_to_serdes_map_fabric_lane36.0=rx36:tx36
+lane_to_serdes_map_fabric_lane37.0=rx37:tx37
+lane_to_serdes_map_fabric_lane38.0=rx38:tx38
+lane_to_serdes_map_fabric_lane39.0=rx39:tx39
+lane_to_serdes_map_fabric_lane40.0=rx40:tx40
+lane_to_serdes_map_fabric_lane41.0=rx41:tx41
+lane_to_serdes_map_fabric_lane42.0=rx42:tx42
+lane_to_serdes_map_fabric_lane43.0=rx43:tx43
+lane_to_serdes_map_fabric_lane44.0=rx44:tx44
+lane_to_serdes_map_fabric_lane45.0=rx45:tx45
+lane_to_serdes_map_fabric_lane46.0=rx46:tx46
+lane_to_serdes_map_fabric_lane47.0=rx47:tx47
+lane_to_serdes_map_fabric_lane48.0=rx48:tx48
+lane_to_serdes_map_fabric_lane49.0=rx49:tx49
+lane_to_serdes_map_fabric_lane50.0=rx50:tx50
+lane_to_serdes_map_fabric_lane51.0=rx51:tx51
+lane_to_serdes_map_fabric_lane52.0=rx52:tx52
+lane_to_serdes_map_fabric_lane53.0=rx53:tx53
+lane_to_serdes_map_fabric_lane54.0=rx54:tx54
+lane_to_serdes_map_fabric_lane55.0=rx55:tx55
+lane_to_serdes_map_fabric_lane56.0=rx56:tx56
+lane_to_serdes_map_fabric_lane57.0=rx57:tx57
+lane_to_serdes_map_fabric_lane58.0=rx58:tx58
+lane_to_serdes_map_fabric_lane59.0=rx59:tx59
+lane_to_serdes_map_fabric_lane60.0=rx60:tx60
+lane_to_serdes_map_fabric_lane61.0=rx61:tx61
+lane_to_serdes_map_fabric_lane62.0=rx62:tx62
+lane_to_serdes_map_fabric_lane63.0=rx63:tx63
+lane_to_serdes_map_fabric_lane64.0=rx64:tx64
+lane_to_serdes_map_fabric_lane65.0=rx65:tx65
+lane_to_serdes_map_fabric_lane66.0=rx66:tx66
+lane_to_serdes_map_fabric_lane67.0=rx67:tx67
+lane_to_serdes_map_fabric_lane68.0=rx68:tx68
+lane_to_serdes_map_fabric_lane69.0=rx69:tx69
+lane_to_serdes_map_fabric_lane70.0=rx70:tx70
+lane_to_serdes_map_fabric_lane71.0=rx71:tx71
+lane_to_serdes_map_fabric_lane72.0=rx72:tx72
+lane_to_serdes_map_fabric_lane73.0=rx73:tx73
+lane_to_serdes_map_fabric_lane74.0=rx74:tx74
+lane_to_serdes_map_fabric_lane75.0=rx75:tx75
+lane_to_serdes_map_fabric_lane76.0=rx76:tx76
+lane_to_serdes_map_fabric_lane77.0=rx77:tx77
+lane_to_serdes_map_fabric_lane78.0=rx78:tx78
+lane_to_serdes_map_fabric_lane79.0=rx79:tx79
+lane_to_serdes_map_fabric_lane80.0=rx80:tx80
+lane_to_serdes_map_fabric_lane81.0=rx81:tx81
+lane_to_serdes_map_fabric_lane82.0=rx82:tx82
+lane_to_serdes_map_fabric_lane83.0=rx83:tx83
+lane_to_serdes_map_fabric_lane84.0=rx84:tx84
+lane_to_serdes_map_fabric_lane85.0=rx85:tx85
+lane_to_serdes_map_fabric_lane86.0=rx86:tx86
+lane_to_serdes_map_fabric_lane87.0=rx87:tx87
+lane_to_serdes_map_fabric_lane88.0=rx88:tx88
+lane_to_serdes_map_fabric_lane89.0=rx89:tx89
+lane_to_serdes_map_fabric_lane90.0=rx90:tx90
+lane_to_serdes_map_fabric_lane91.0=rx91:tx91
+lane_to_serdes_map_fabric_lane92.0=rx92:tx92
+lane_to_serdes_map_fabric_lane93.0=rx93:tx93
+lane_to_serdes_map_fabric_lane94.0=rx94:tx94
+lane_to_serdes_map_fabric_lane95.0=rx95:tx95
+lane_to_serdes_map_fabric_lane96.0=rx96:tx96
+lane_to_serdes_map_fabric_lane97.0=rx97:tx97
+lane_to_serdes_map_fabric_lane98.0=rx98:tx98
+lane_to_serdes_map_fabric_lane99.0=rx99:tx99
+lane_to_serdes_map_fabric_lane100.0=rx100:tx100
+lane_to_serdes_map_fabric_lane101.0=rx101:tx101
+lane_to_serdes_map_fabric_lane102.0=rx102:tx102
+lane_to_serdes_map_fabric_lane103.0=rx103:tx103
+lane_to_serdes_map_fabric_lane104.0=rx104:tx104
+lane_to_serdes_map_fabric_lane105.0=rx105:tx105
+lane_to_serdes_map_fabric_lane106.0=rx106:tx106
+lane_to_serdes_map_fabric_lane107.0=rx107:tx107
+lane_to_serdes_map_fabric_lane108.0=rx108:tx108
+lane_to_serdes_map_fabric_lane109.0=rx109:tx109
+lane_to_serdes_map_fabric_lane110.0=rx110:tx110
+lane_to_serdes_map_fabric_lane111.0=rx111:tx111
+
+lane_to_serdes_map_nif_lane0.0=rx5:tx7
+lane_to_serdes_map_nif_lane1.0=rx7:tx6
+lane_to_serdes_map_nif_lane2.0=rx4:tx5
+lane_to_serdes_map_nif_lane3.0=rx6:tx4
+lane_to_serdes_map_nif_lane4.0=rx0:tx0
+lane_to_serdes_map_nif_lane5.0=rx1:tx1
+lane_to_serdes_map_nif_lane6.0=rx2:tx3
+lane_to_serdes_map_nif_lane7.0=rx3:tx2
+lane_to_serdes_map_nif_lane8.0=rx13:tx15
+lane_to_serdes_map_nif_lane9.0=rx12:tx14
+lane_to_serdes_map_nif_lane10.0=rx15:tx13
+lane_to_serdes_map_nif_lane11.0=rx14:tx12
+lane_to_serdes_map_nif_lane12.0=rx10:tx10
+lane_to_serdes_map_nif_lane13.0=rx8:tx9
+lane_to_serdes_map_nif_lane14.0=rx9:tx11
+lane_to_serdes_map_nif_lane15.0=rx11:tx8
+lane_to_serdes_map_nif_lane16.0=rx23:tx23
+lane_to_serdes_map_nif_lane17.0=rx21:tx22
+lane_to_serdes_map_nif_lane18.0=rx22:tx21
+lane_to_serdes_map_nif_lane19.0=rx20:tx20
+lane_to_serdes_map_nif_lane20.0=rx16:tx18
+lane_to_serdes_map_nif_lane21.0=rx17:tx17
+lane_to_serdes_map_nif_lane22.0=rx18:tx16
+lane_to_serdes_map_nif_lane23.0=rx19:tx19
+lane_to_serdes_map_nif_lane24.0=rx31:tx31
+lane_to_serdes_map_nif_lane25.0=rx30:tx30
+lane_to_serdes_map_nif_lane26.0=rx29:tx29
+lane_to_serdes_map_nif_lane27.0=rx28:tx28
+lane_to_serdes_map_nif_lane28.0=rx24:tx26
+lane_to_serdes_map_nif_lane29.0=rx26:tx25
+lane_to_serdes_map_nif_lane30.0=rx25:tx24
+lane_to_serdes_map_nif_lane31.0=rx27:tx27
+lane_to_serdes_map_nif_lane32.0=rx38:tx34
+lane_to_serdes_map_nif_lane33.0=rx34:tx39
+lane_to_serdes_map_nif_lane34.0=rx39:tx33
+lane_to_serdes_map_nif_lane35.0=rx32:tx38
+lane_to_serdes_map_nif_lane36.0=rx36:tx35
+lane_to_serdes_map_nif_lane37.0=rx33:tx37
+lane_to_serdes_map_nif_lane38.0=rx37:tx32
+lane_to_serdes_map_nif_lane39.0=rx35:tx36
+lane_to_serdes_map_nif_lane40.0=rx46:tx41
+lane_to_serdes_map_nif_lane41.0=rx41:tx46
+lane_to_serdes_map_nif_lane42.0=rx45:tx42
+lane_to_serdes_map_nif_lane43.0=rx40:tx47
+lane_to_serdes_map_nif_lane44.0=rx47:tx40
+lane_to_serdes_map_nif_lane45.0=rx43:tx44
+lane_to_serdes_map_nif_lane46.0=rx44:tx43
+lane_to_serdes_map_nif_lane47.0=rx42:tx45
+lane_to_serdes_map_nif_lane48.0=rx55:tx55
+lane_to_serdes_map_nif_lane49.0=rx54:tx54
+lane_to_serdes_map_nif_lane50.0=rx53:tx53
+lane_to_serdes_map_nif_lane51.0=rx52:tx52
+lane_to_serdes_map_nif_lane52.0=rx48:tx48
+lane_to_serdes_map_nif_lane53.0=rx49:tx49
+lane_to_serdes_map_nif_lane54.0=rx50:tx50
+lane_to_serdes_map_nif_lane55.0=rx51:tx51
+lane_to_serdes_map_nif_lane56.0=rx60:tx60
+lane_to_serdes_map_nif_lane57.0=rx61:tx61
+lane_to_serdes_map_nif_lane58.0=rx62:tx63
+lane_to_serdes_map_nif_lane59.0=rx63:tx62
+lane_to_serdes_map_nif_lane60.0=rx58:tx59
+lane_to_serdes_map_nif_lane61.0=rx59:tx56
+lane_to_serdes_map_nif_lane62.0=rx57:tx58
+lane_to_serdes_map_nif_lane63.0=rx56:tx57
+lane_to_serdes_map_nif_lane64.0=rx68:tx69
+lane_to_serdes_map_nif_lane65.0=rx69:tx68
+lane_to_serdes_map_nif_lane66.0=rx70:tx71
+lane_to_serdes_map_nif_lane67.0=rx71:tx70
+lane_to_serdes_map_nif_lane68.0=rx67:tx64
+lane_to_serdes_map_nif_lane69.0=rx66:tx67
+lane_to_serdes_map_nif_lane70.0=rx65:tx65
+lane_to_serdes_map_nif_lane71.0=rx64:tx66
+lane_to_serdes_map_nif_lane72.0=rx78:tx76
+lane_to_serdes_map_nif_lane73.0=rx76:tx77
+lane_to_serdes_map_nif_lane74.0=rx79:tx78
+lane_to_serdes_map_nif_lane75.0=rx77:tx79
+lane_to_serdes_map_nif_lane76.0=rx75:tx72
+lane_to_serdes_map_nif_lane77.0=rx74:tx75
+lane_to_serdes_map_nif_lane78.0=rx73:tx73
+lane_to_serdes_map_nif_lane79.0=rx72:tx74
+lane_to_serdes_map_nif_lane80.0=rx83:tx84
+lane_to_serdes_map_nif_lane81.0=rx87:tx80
+lane_to_serdes_map_nif_lane82.0=rx82:tx85
+lane_to_serdes_map_nif_lane83.0=rx84:tx83
+lane_to_serdes_map_nif_lane84.0=rx80:tx86
+lane_to_serdes_map_nif_lane85.0=rx85:tx81
+lane_to_serdes_map_nif_lane86.0=rx81:tx87
+lane_to_serdes_map_nif_lane87.0=rx86:tx82
+lane_to_serdes_map_nif_lane88.0=rx90:tx93
+lane_to_serdes_map_nif_lane89.0=rx88:tx91
+lane_to_serdes_map_nif_lane90.0=rx91:tx92
+lane_to_serdes_map_nif_lane91.0=rx95:tx88
+lane_to_serdes_map_nif_lane92.0=rx94:tx95
+lane_to_serdes_map_nif_lane93.0=rx93:tx90
+lane_to_serdes_map_nif_lane94.0=rx89:tx94
+lane_to_serdes_map_nif_lane95.0=rx92:tx89
+
+phy_rx_polarity_flip_phy0=0
+phy_rx_polarity_flip_phy1=1
+phy_rx_polarity_flip_phy2=0
+phy_rx_polarity_flip_phy3=0
+phy_rx_polarity_flip_phy4=0
+phy_rx_polarity_flip_phy5=0
+phy_rx_polarity_flip_phy6=0
+phy_rx_polarity_flip_phy7=0
+phy_rx_polarity_flip_phy8=1
+phy_rx_polarity_flip_phy9=1
+phy_rx_polarity_flip_phy10=1
+phy_rx_polarity_flip_phy11=1
+phy_rx_polarity_flip_phy12=0
+phy_rx_polarity_flip_phy13=1
+phy_rx_polarity_flip_phy14=1
+phy_rx_polarity_flip_phy15=1
+phy_rx_polarity_flip_phy16=0
+phy_rx_polarity_flip_phy17=1
+phy_rx_polarity_flip_phy18=1
+phy_rx_polarity_flip_phy19=0
+phy_rx_polarity_flip_phy20=0
+phy_rx_polarity_flip_phy21=0
+phy_rx_polarity_flip_phy22=0
+phy_rx_polarity_flip_phy23=0
+phy_rx_polarity_flip_phy24=1
+phy_rx_polarity_flip_phy25=1
+phy_rx_polarity_flip_phy26=1
+phy_rx_polarity_flip_phy27=0
+phy_rx_polarity_flip_phy28=0
+phy_rx_polarity_flip_phy29=1
+phy_rx_polarity_flip_phy30=1
+phy_rx_polarity_flip_phy31=0
+phy_rx_polarity_flip_phy32=1
+phy_rx_polarity_flip_phy33=0
+phy_rx_polarity_flip_phy34=0
+phy_rx_polarity_flip_phy35=0
+phy_rx_polarity_flip_phy36=0
+phy_rx_polarity_flip_phy37=1
+phy_rx_polarity_flip_phy38=0
+phy_rx_polarity_flip_phy39=1
+
+phy_rx_polarity_flip_phy40=1
+phy_rx_polarity_flip_phy41=1
+phy_rx_polarity_flip_phy42=0
+phy_rx_polarity_flip_phy43=0
+phy_rx_polarity_flip_phy44=1
+phy_rx_polarity_flip_phy45=0
+phy_rx_polarity_flip_phy46=1
+phy_rx_polarity_flip_phy47=0
+
+phy_rx_polarity_flip_phy48=1
+phy_rx_polarity_flip_phy49=1
+phy_rx_polarity_flip_phy50=1
+phy_rx_polarity_flip_phy51=1
+phy_rx_polarity_flip_phy52=0
+phy_rx_polarity_flip_phy53=0
+phy_rx_polarity_flip_phy54=0
+phy_rx_polarity_flip_phy55=0
+phy_rx_polarity_flip_phy56=0
+phy_rx_polarity_flip_phy57=0
+phy_rx_polarity_flip_phy58=0
+phy_rx_polarity_flip_phy59=0
+phy_rx_polarity_flip_phy60=1
+phy_rx_polarity_flip_phy61=1
+phy_rx_polarity_flip_phy62=1
+phy_rx_polarity_flip_phy63=1
+phy_rx_polarity_flip_phy64=1
+phy_rx_polarity_flip_phy65=1
+phy_rx_polarity_flip_phy66=1
+phy_rx_polarity_flip_phy67=1
+phy_rx_polarity_flip_phy68=1
+phy_rx_polarity_flip_phy69=1
+phy_rx_polarity_flip_phy70=1
+phy_rx_polarity_flip_phy71=1
+phy_rx_polarity_flip_phy72=1
+phy_rx_polarity_flip_phy73=0
+phy_rx_polarity_flip_phy74=0
+phy_rx_polarity_flip_phy75=1
+phy_rx_polarity_flip_phy76=1
+phy_rx_polarity_flip_phy77=1
+phy_rx_polarity_flip_phy78=1
+phy_rx_polarity_flip_phy79=1
+
+phy_rx_polarity_flip_phy80=1
+phy_rx_polarity_flip_phy81=1
+phy_rx_polarity_flip_phy82=1
+phy_rx_polarity_flip_phy83=0
+phy_rx_polarity_flip_phy84=1
+phy_rx_polarity_flip_phy85=0
+phy_rx_polarity_flip_phy86=1
+phy_rx_polarity_flip_phy87=0
+
+phy_rx_polarity_flip_phy88=1
+phy_rx_polarity_flip_phy89=0
+phy_rx_polarity_flip_phy90=0
+phy_rx_polarity_flip_phy91=1
+phy_rx_polarity_flip_phy92=1
+phy_rx_polarity_flip_phy93=0
+phy_rx_polarity_flip_phy94=0
+phy_rx_polarity_flip_phy95=1
+
+phy_tx_polarity_flip_phy0=1
+phy_tx_polarity_flip_phy1=1
+phy_tx_polarity_flip_phy2=1
+phy_tx_polarity_flip_phy3=1
+phy_tx_polarity_flip_phy4=1
+phy_tx_polarity_flip_phy5=1
+phy_tx_polarity_flip_phy6=0
+phy_tx_polarity_flip_phy7=0
+phy_tx_polarity_flip_phy8=1
+phy_tx_polarity_flip_phy9=1
+phy_tx_polarity_flip_phy10=1
+phy_tx_polarity_flip_phy11=1
+phy_tx_polarity_flip_phy12=1
+phy_tx_polarity_flip_phy13=1
+phy_tx_polarity_flip_phy14=0
+phy_tx_polarity_flip_phy15=0
+phy_tx_polarity_flip_phy16=0
+phy_tx_polarity_flip_phy17=0
+phy_tx_polarity_flip_phy18=0
+phy_tx_polarity_flip_phy19=0
+phy_tx_polarity_flip_phy20=0
+phy_tx_polarity_flip_phy21=0
+phy_tx_polarity_flip_phy22=0
+phy_tx_polarity_flip_phy23=0
+phy_tx_polarity_flip_phy24=0
+phy_tx_polarity_flip_phy25=0
+phy_tx_polarity_flip_phy26=0
+phy_tx_polarity_flip_phy27=0
+phy_tx_polarity_flip_phy28=0
+phy_tx_polarity_flip_phy29=0
+phy_tx_polarity_flip_phy30=0
+phy_tx_polarity_flip_phy31=0
+phy_tx_polarity_flip_phy32=1
+phy_tx_polarity_flip_phy33=0
+phy_tx_polarity_flip_phy34=0
+phy_tx_polarity_flip_phy35=1
+phy_tx_polarity_flip_phy36=1
+phy_tx_polarity_flip_phy37=0
+phy_tx_polarity_flip_phy38=1
+phy_tx_polarity_flip_phy39=0
+
+phy_tx_polarity_flip_phy40=0
+phy_tx_polarity_flip_phy41=1
+phy_tx_polarity_flip_phy42=1
+phy_tx_polarity_flip_phy43=0
+phy_tx_polarity_flip_phy44=1
+phy_tx_polarity_flip_phy45=0
+phy_tx_polarity_flip_phy46=1
+phy_tx_polarity_flip_phy47=0
+
+phy_tx_polarity_flip_phy48=0
+phy_tx_polarity_flip_phy49=0
+phy_tx_polarity_flip_phy50=0
+phy_tx_polarity_flip_phy51=0
+phy_tx_polarity_flip_phy52=0
+phy_tx_polarity_flip_phy53=0
+phy_tx_polarity_flip_phy54=0
+phy_tx_polarity_flip_phy55=0
+phy_tx_polarity_flip_phy56=1
+phy_tx_polarity_flip_phy57=1
+phy_tx_polarity_flip_phy58=0
+phy_tx_polarity_flip_phy59=0
+phy_tx_polarity_flip_phy60=1
+phy_tx_polarity_flip_phy61=1
+phy_tx_polarity_flip_phy62=0
+phy_tx_polarity_flip_phy63=0
+phy_tx_polarity_flip_phy64=0
+phy_tx_polarity_flip_phy65=0
+phy_tx_polarity_flip_phy66=0
+phy_tx_polarity_flip_phy67=0
+phy_tx_polarity_flip_phy68=0
+phy_tx_polarity_flip_phy69=0
+phy_tx_polarity_flip_phy70=1
+phy_tx_polarity_flip_phy71=1
+phy_tx_polarity_flip_phy72=1
+phy_tx_polarity_flip_phy73=1
+phy_tx_polarity_flip_phy74=1
+phy_tx_polarity_flip_phy75=1
+phy_tx_polarity_flip_phy76=0
+phy_tx_polarity_flip_phy77=0
+phy_tx_polarity_flip_phy78=1
+phy_tx_polarity_flip_phy79=1
+
+phy_tx_polarity_flip_phy80=1
+phy_tx_polarity_flip_phy81=1
+phy_tx_polarity_flip_phy82=0
+phy_tx_polarity_flip_phy83=0
+phy_tx_polarity_flip_phy84=1
+phy_tx_polarity_flip_phy85=1
+phy_tx_polarity_flip_phy86=1
+phy_tx_polarity_flip_phy87=1
+
+phy_tx_polarity_flip_phy88=0
+phy_tx_polarity_flip_phy89=0
+phy_tx_polarity_flip_phy90=1
+phy_tx_polarity_flip_phy91=1
+phy_tx_polarity_flip_phy92=1
+phy_tx_polarity_flip_phy93=1
+phy_tx_polarity_flip_phy94=1
+phy_tx_polarity_flip_phy95=1
+
+ucode_port_1=CGE2_0:core_0.1
+ucode_port_2=CGE2_1:core_0.2
+ucode_port_3=CGE2_2:core_0.3
+ucode_port_4=CGE2_3:core_0.4
+ucode_port_5=CGE2_4:core_0.5
+ucode_port_6=CGE2_5:core_0.6
+ucode_port_7=CGE2_6:core_0.7
+ucode_port_8=CGE2_7:core_0.8
+ucode_port_9=CGE2_8:core_0.9
+ucode_port_10=CGE2_9:core_0.10
+ucode_port_11=CGE2_10:core_0.11
+ucode_port_12=CGE2_11:core_0.12
+ucode_port_13=CGE2_12:core_0.13
+ucode_port_14=CGE2_13:core_0.14
+ucode_port_15=CGE2_14:core_0.15
+ucode_port_16=CGE2_15:core_0.16
+ucode_port_17=CGE2_36:core_1.17
+ucode_port_18=CGE2_37:core_1.18
+ucode_port_19=CGE2_38:core_1.19
+ucode_port_20=CGE2_39:core_1.20
+ucode_port_21=CGE2_32:core_1.21
+ucode_port_22=CGE2_33:core_1.22
+ucode_port_23=CGE2_34:core_1.23
+ucode_port_24=CGE2_35:core_1.24
+ucode_port_25=CGE2_28:core_1.25
+ucode_port_26=CGE2_29:core_1.26
+ucode_port_27=CGE2_30:core_1.27
+ucode_port_28=CGE2_31:core_1.28
+ucode_port_29=CGE2_24:core_1.29
+ucode_port_30=CGE2_25:core_1.30
+ucode_port_31=CGE2_26:core_1.31
+ucode_port_32=CGE2_27:core_1.32
+
+ucode_port_33=CDGE4:core_0.33
+ucode_port_34=CDGE5:core_0.34
+ucode_port_35=CDGE11:core_1.35
+ucode_port_36=CDGE10:core_1.36
+
+rif_id_max=0x4000
+
+dma_desc_aggregator_chain_length_max.BCM8869X=1000
+dma_desc_aggregator_buff_size_kb.BCM8869X=100
+dma_desc_aggregator_timeout_usec.BCM8869X=1000
+dma_desc_aggregator_enable_specific_MDB_LPM.BCM8869X=1
+dma_desc_aggregator_enable_specific_MDB_FEC.BCM8869X=1
diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/port_config.ini b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/port_config.ini
new file mode 100644
index 000000000000..914fbbdf1652
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/port_config.ini
@@ -0,0 +1,37 @@
+# name lanes alias index speed
+Ethernet0 0,1 Ethernet1/1 1 100000
+Ethernet4 2,3 Ethernet2/1 2 100000
+Ethernet8 4,5 Ethernet3/1 3 100000
+Ethernet12 6,7 Ethernet4/1 4 100000
+Ethernet16 8,9 Ethernet5/1 5 100000
+Ethernet20 10,11 Ethernet6/1 6 100000
+Ethernet24 12,13 Ethernet7/1 7 100000
+Ethernet28 14,15 Ethernet8/1 8 100000
+Ethernet32 16,17 Ethernet9/1 9 100000
+Ethernet36 18,19 Ethernet10/1 10 100000
+Ethernet40 20,21 Ethernet11/1 11 100000
+Ethernet44 22,23 Ethernet12/1 12 100000
+Ethernet48 24,25 Ethernet13/1 13 100000
+Ethernet52 26,27 Ethernet14/1 14 100000
+Ethernet56 28,29 Ethernet15/1 15 100000
+Ethernet60 30,31 Ethernet16/1 16 100000
+Ethernet64 72,73 Ethernet17/1 17 100000
+Ethernet68 74,75 Ethernet18/1 18 100000
+Ethernet72 76,77 Ethernet19/1 19 100000
+Ethernet76 78,79 Ethernet20/1 20 100000
+Ethernet80 64,65 Ethernet21/1 21 100000
+Ethernet84 66,67 Ethernet22/1 22 100000
+Ethernet88 68,69 Ethernet23/1 23 100000
+Ethernet92 70,71 Ethernet24/1 24 100000
+Ethernet96 56,57 Ethernet25/1 25 100000
+Ethernet100 58,59 Ethernet26/1 26 100000
+Ethernet104 60,61 Ethernet27/1 27 100000
+Ethernet108 62,63 Ethernet28/1 28 100000
+Ethernet112 48,49 Ethernet29/1 29 100000
+Ethernet116 50,51 Ethernet30/1 30 100000
+Ethernet120 52,53 Ethernet31/1 31 100000
+Ethernet124 54,55 Ethernet32/1 32 100000
+Ethernet128 32,33,34,35,36,37,38,39 Ethernet33/1 33 400000
+Ethernet136 40,41,42,43,44,45,46,47 Ethernet34/1 34 400000
+Ethernet144 88,89,90,91,92,93,94,95 Ethernet35/1 35 400000
+Ethernet152 80,81,82,83,84,85,86,87 Ethernet36/1 36 400000
diff --git a/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/sai.profile b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/sai.profile
new file mode 100644
index 000000000000..991f232ceafe
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/sai.profile
@@ -0,0 +1,2 @@
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32d4-32x100G+4x400G.config.bcm
+SAI_NUM_ECMP_MEMBERS=64
diff --git a/device/arista/x86_64-arista_7280cr3_32d4/fancontrol b/device/arista/x86_64-arista_7280cr3_32d4/fancontrol
deleted file mode 120000
index 6a53b7541071..000000000000
--- a/device/arista/x86_64-arista_7280cr3_32d4/fancontrol
+++ /dev/null
@@ -1 +0,0 @@
-../x86_64-arista_7280cr3_32p4/fancontrol
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3_32d4/platform_env.conf b/device/arista/x86_64-arista_7280cr3_32d4/platform_env.conf
new file mode 120000
index 000000000000..063c1c7e7cf7
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3_32d4/platform_env.conf
@@ -0,0 +1 @@
+../x86_64-arista_7280cr3_32p4/platform_env.conf
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32D4 b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-32P4
similarity index 100%
rename from device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32D4
rename to device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-32P4
diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/jr2-a7280cr3-32p4-32x100G+4x400G.config.bcm b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/jr2-a7280cr3-32p4-32x100G+4x400G.config.bcm
new file mode 100644
index 000000000000..5b2bbbf89254
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/jr2-a7280cr3-32p4-32x100G+4x400G.config.bcm
@@ -0,0 +1,743 @@
+soc_family.BCM8869X=BCM8869X
+
+dpp_db_path=/usr/share/bcm/db
+custom_feature_ucode_path=u_code_db2pem.txt
+system_headers_mode=1
+suppress_unknown_prop_warnings=1
+l4_protocols_load_balancing_enable=1
+fabric_logical_port_base=512
+trunk_group_max_members=128
+num_olp_tm_ports.BCM8869X=1
+
+ucode_port_0.BCM8869X=CPU.0:core_0.0
+ucode_port_200.BCM8869X=CPU.8:core_1.200
+ucode_port_201.BCM8869X=CPU.16:core_0.201
+ucode_port_202.BCM8869X=CPU.24:core_1.202
+ucode_port_203.BCM8869X=CPU.32:core_0.203
+
+port_init_speed_xe.BCM8869X=10000
+port_init_speed_xl.BCM8869X=40000
+port_init_speed_le.BCM8869X=50000
+port_init_speed_ce.BCM8869X=100000
+port_init_speed_cc.BCM8869X=200000
+port_init_speed_cd.BCM8869X=400000
+port_init_speed_il.BCM8869X=10312
+
+port_init_cl72=0
+
+serdes_tx_taps_1=pam4:-16:64:0:3:0:0
+serdes_tx_taps_2=pam4:-16:64:0:3:0:0
+serdes_tx_taps_3=pam4:-16:64:0:3:0:0
+serdes_tx_taps_4=pam4:-16:64:0:3:0:0
+serdes_tx_taps_5=pam4:-16:64:0:3:0:0
+serdes_tx_taps_6=pam4:-16:64:0:3:0:0
+serdes_tx_taps_7=pam4:-16:64:0:3:0:0
+serdes_tx_taps_8=pam4:-16:64:0:3:0:0
+serdes_tx_taps_9=pam4:-8:60:0:0:0:0
+serdes_tx_taps_10=pam4:-8:60:0:0:0:0
+serdes_tx_taps_11=pam4:-8:60:0:0:0:0
+serdes_tx_taps_12=pam4:-8:60:0:0:0:0
+serdes_tx_taps_13=pam4:-8:60:0:0:0:0
+serdes_tx_taps_14=pam4:-8:60:0:0:0:0
+serdes_tx_taps_15=pam4:-8:60:0:0:0:0
+serdes_tx_taps_16=pam4:-8:60:0:0:0:0
+serdes_tx_taps_17=pam4:-8:60:0:0:0:0
+serdes_tx_taps_18=pam4:-8:60:0:0:0:0
+serdes_tx_taps_19=pam4:-8:60:0:0:0:0
+serdes_tx_taps_20=pam4:-8:60:0:0:0:0
+serdes_tx_taps_21=pam4:-8:60:0:0:0:0
+serdes_tx_taps_22=pam4:-8:60:0:0:0:0
+serdes_tx_taps_23=pam4:-8:60:0:0:0:0
+serdes_tx_taps_24=pam4:-8:60:0:0:0:0
+serdes_tx_taps_25=pam4:-8:60:0:0:0:0
+serdes_tx_taps_26=pam4:-8:60:0:0:0:0
+serdes_tx_taps_27=pam4:-8:60:0:0:0:0
+serdes_tx_taps_28=pam4:-8:60:0:0:0:0
+serdes_tx_taps_29=pam4:-16:60:0:3:0:0
+serdes_tx_taps_30=pam4:-16:60:0:3:0:0
+serdes_tx_taps_31=pam4:-16:60:0:3:0:0
+serdes_tx_taps_32=pam4:-16:60:0:3:0:0
+serdes_tx_taps_33=pam4:-12:136:-4:0:0:0
+serdes_tx_taps_34=pam4:-12:140:-8:4:0:0
+serdes_tx_taps_35=pam4:-12:124:-12:4:0:0
+serdes_tx_taps_36=pam4:-16:136:-8:4:0:0
+
+ucode_port_100.BCM8869X=RCY_MIRROR.0:core_0.100
+ucode_port_101.BCM8869X=RCY_MIRROR.1:core_0.101
+ucode_port_102.BCM8869X=RCY_MIRROR.2:core_0.102
+ucode_port_103.BCM8869X=RCY_MIRROR.3:core_0.103
+ucode_port_104.BCM8869X=RCY_MIRROR.4:core_0.104
+ucode_port_105.BCM8869X=RCY_MIRROR.5:core_0.105
+ucode_port_106.BCM8869X=RCY_MIRROR.6:core_0.106
+ucode_port_107.BCM8869X=RCY_MIRROR.7:core_0.107
+ucode_port_108.BCM8869X=RCY_MIRROR.8:core_0.108
+ucode_port_109.BCM8869X=RCY_MIRROR.9:core_0.109
+ucode_port_110.BCM8869X=RCY_MIRROR.10:core_0.110
+ucode_port_111.BCM8869X=RCY_MIRROR.11:core_0.111
+ucode_port_112.BCM8869X=RCY_MIRROR.12:core_0.112
+ucode_port_113.BCM8869X=RCY_MIRROR.13:core_0.113
+ucode_port_114.BCM8869X=RCY_MIRROR.14:core_0.114
+ucode_port_115.BCM8869X=RCY_MIRROR.15:core_0.115
+ucode_port_116.BCM8869X=RCY_MIRROR.16:core_0.116
+ucode_port_117.BCM8869X=RCY_MIRROR.17:core_0.117
+ucode_port_118.BCM8869X=RCY_MIRROR.18:core_0.118
+ucode_port_119.BCM8869X=RCY_MIRROR.19:core_0.119
+ucode_port_120.BCM8869X=RCY_MIRROR.0:core_1.120
+ucode_port_121.BCM8869X=RCY_MIRROR.1:core_1.121
+ucode_port_122.BCM8869X=RCY_MIRROR.2:core_1.122
+ucode_port_123.BCM8869X=RCY_MIRROR.3:core_1.123
+ucode_port_124.BCM8869X=RCY_MIRROR.4:core_1.124
+ucode_port_125.BCM8869X=RCY_MIRROR.5:core_1.125
+ucode_port_126.BCM8869X=RCY_MIRROR.6:core_1.126
+ucode_port_127.BCM8869X=RCY_MIRROR.7:core_1.127
+ucode_port_128.BCM8869X=RCY_MIRROR.8:core_1.128
+ucode_port_129.BCM8869X=RCY_MIRROR.9:core_1.129
+ucode_port_130.BCM8869X=RCY_MIRROR.10:core_1.130
+ucode_port_131.BCM8869X=RCY_MIRROR.11:core_1.131
+ucode_port_132.BCM8869X=RCY_MIRROR.12:core_1.132
+ucode_port_133.BCM8869X=RCY_MIRROR.13:core_1.133
+ucode_port_134.BCM8869X=RCY_MIRROR.14:core_1.134
+ucode_port_135.BCM8869X=RCY_MIRROR.15:core_1.135
+ucode_port_136.BCM8869X=RCY_MIRROR.16:core_1.136
+ucode_port_137.BCM8869X=RCY_MIRROR.17:core_1.137
+ucode_port_138.BCM8869X=RCY_MIRROR.18:core_1.138
+ucode_port_139.BCM8869X=RCY_MIRROR.19:core_1.139
+
+port_priorities.BCM8869X=8
+
+ucode_port_213.BCM8869X=OLP:core_0.213
+
+sw_state_max_size.BCM8869X=750000000
+
+stable_location.BCM8869X=4
+stable_location.BCM8869X_ADAPTER=3
+
+stable_filename.BCM8869X_ADAPTER=warmboot_data_0
+stable_filename=/dev/shm/warmboot_data_0
+stable_filename.1=/dev/shm/warmboot_data_1
+stable_filename.2=/dev/shm/warmboot_data_2
+
+stable_size.BCM8869X=800000000
+
+tm_port_header_type_in_0.BCM8869X=INJECTED_2
+tm_port_header_type_out_0.BCM8869X=CPU
+
+tm_port_header_type_in_200.BCM8869X=INJECTED_2_PP
+tm_port_header_type_out_200.BCM8869X=ETH
+tm_port_header_type_in_201.BCM8869X=INJECTED_2_PP
+tm_port_header_type_out_201.BCM8869X=ETH
+tm_port_header_type_in_202.BCM8869X=INJECTED_2_PP
+tm_port_header_type_out_202.BCM8869X=ETH
+tm_port_header_type_in_203.BCM8869X=INJECTED_2_PP
+tm_port_header_type_out_203.BCM8869X=ETH
+
+sat_enable.BCM8869X=1
+tm_port_header_type_out_210.BCM8869X=CPU
+tm_port_header_type_in_210.BCM8869X=INJECTED_2
+
+tm_port_header_type_in_211.BCM8869X=INJECTED_2
+tm_port_header_type_out_211.BCM8869X=CPU
+tm_port_header_type_in_212.BCM8869X=INJECTED_2
+tm_port_header_type_out_212.BCM8869X=CPU
+
+tm_port_header_type_in_213.BCM8869X=INJECTED_2
+tm_port_header_type_out_213.BCM8869X=RAW
+
+dtm_flow_mapping_mode_region_64.BCM8869X=3
+dtm_flow_mapping_mode_region_65.BCM8869X=3
+dtm_flow_mapping_mode_region_66.BCM8869X=3
+dtm_flow_mapping_mode_region_67.BCM8869X=3
+dtm_flow_mapping_mode_region_68.BCM8869X=3
+dtm_flow_mapping_mode_region_69.BCM8869X=3
+dtm_flow_mapping_mode_region_70.BCM8869X=3
+dtm_flow_mapping_mode_region_71.BCM8869X=3
+dtm_flow_mapping_mode_region_72.BCM8869X=3
+dtm_flow_mapping_mode_region_73.BCM8869X=3
+dtm_flow_mapping_mode_region_74.BCM8869X=3
+dtm_flow_mapping_mode_region_75.BCM8869X=3
+dtm_flow_mapping_mode_region_76.BCM8869X=3
+dtm_flow_mapping_mode_region_77.BCM8869X=3
+dtm_flow_mapping_mode_region_78.BCM8869X=3
+dtm_flow_mapping_mode_region_79.BCM8869X=7
+dtm_flow_mapping_mode_region_80.BCM8869X=3
+dtm_flow_mapping_mode_region_81.BCM8869X=1
+dtm_flow_mapping_mode_region_82.BCM8869X=3
+dtm_flow_mapping_mode_region_83.BCM8869X=3
+dtm_flow_mapping_mode_region_84.BCM8869X=3
+dtm_flow_mapping_mode_region_85.BCM8869X=3
+dtm_flow_mapping_mode_region_86.BCM8869X=3
+dtm_flow_mapping_mode_region_87.BCM8869X=3
+dtm_flow_mapping_mode_region_88.BCM8869X=3
+dtm_flow_mapping_mode_region_89.BCM8869X=3
+dtm_flow_mapping_mode_region_90.BCM8869X=3
+dtm_flow_mapping_mode_region_91.BCM8869X=3
+dtm_flow_mapping_mode_region_92.BCM8869X=3
+dtm_flow_mapping_mode_region_93.BCM8869X=3
+dtm_flow_mapping_mode_region_94.BCM8869X=3
+
+dtm_flow_nof_remote_cores_region_1.BCM8869X=2
+dtm_flow_nof_remote_cores_region_2.BCM8869X=2
+dtm_flow_nof_remote_cores_region_3.BCM8869X=2
+dtm_flow_nof_remote_cores_region_4.BCM8869X=2
+dtm_flow_nof_remote_cores_region_5.BCM8869X=2
+dtm_flow_nof_remote_cores_region_6.BCM8869X=2
+dtm_flow_nof_remote_cores_region_7.BCM8869X=2
+dtm_flow_nof_remote_cores_region_8.BCM8869X=2
+dtm_flow_nof_remote_cores_region_9.BCM8869X=2
+dtm_flow_nof_remote_cores_region_10.BCM8869X=2
+dtm_flow_nof_remote_cores_region_11.BCM8869X=2
+dtm_flow_nof_remote_cores_region_12.BCM8869X=2
+dtm_flow_nof_remote_cores_region_13.BCM8869X=2
+dtm_flow_nof_remote_cores_region_14.BCM8869X=2
+dtm_flow_nof_remote_cores_region_15.BCM8869X=2
+dtm_flow_nof_remote_cores_region_16.BCM8869X=2
+dtm_flow_nof_remote_cores_region_17.BCM8869X=2
+dtm_flow_nof_remote_cores_region_18.BCM8869X=2
+dtm_flow_nof_remote_cores_region_19.BCM8869X=2
+dtm_flow_nof_remote_cores_region_20.BCM8869X=2
+dtm_flow_nof_remote_cores_region_21.BCM8869X=2
+dtm_flow_nof_remote_cores_region_22.BCM8869X=2
+dtm_flow_nof_remote_cores_region_23.BCM8869X=2
+dtm_flow_nof_remote_cores_region_24.BCM8869X=2
+dtm_flow_nof_remote_cores_region_25.BCM8869X=2
+dtm_flow_nof_remote_cores_region_26.BCM8869X=2
+dtm_flow_nof_remote_cores_region_27.BCM8869X=2
+dtm_flow_nof_remote_cores_region_28.BCM8869X=2
+dtm_flow_nof_remote_cores_region_29.BCM8869X=2
+dtm_flow_nof_remote_cores_region_30.BCM8869X=2
+dtm_flow_nof_remote_cores_region_31.BCM8869X=2
+dtm_flow_nof_remote_cores_region_32.BCM8869X=2
+dtm_flow_nof_remote_cores_region_33.BCM8869X=2
+dtm_flow_nof_remote_cores_region_34.BCM8869X=2
+dtm_flow_nof_remote_cores_region_35.BCM8869X=2
+dtm_flow_nof_remote_cores_region_36.BCM8869X=2
+dtm_flow_nof_remote_cores_region_37.BCM8869X=2
+dtm_flow_nof_remote_cores_region_38.BCM8869X=2
+dtm_flow_nof_remote_cores_region_39.BCM8869X=2
+dtm_flow_nof_remote_cores_region_40.BCM8869X=2
+dtm_flow_nof_remote_cores_region_41.BCM8869X=2
+dtm_flow_nof_remote_cores_region_42.BCM8869X=2
+dtm_flow_nof_remote_cores_region_43.BCM8869X=2
+dtm_flow_nof_remote_cores_region_44.BCM8869X=2
+dtm_flow_nof_remote_cores_region_45.BCM8869X=2
+dtm_flow_nof_remote_cores_region_46.BCM8869X=2
+dtm_flow_nof_remote_cores_region_47.BCM8869X=2
+dtm_flow_nof_remote_cores_region_48.BCM8869X=2
+dtm_flow_nof_remote_cores_region_49.BCM8869X=2
+dtm_flow_nof_remote_cores_region_50.BCM8869X=2
+dtm_flow_nof_remote_cores_region_51.BCM8869X=2
+dtm_flow_nof_remote_cores_region_52.BCM8869X=2
+dtm_flow_nof_remote_cores_region_53.BCM8869X=2
+dtm_flow_nof_remote_cores_region_54.BCM8869X=2
+dtm_flow_nof_remote_cores_region_55.BCM8869X=2
+dtm_flow_nof_remote_cores_region_56.BCM8869X=2
+dtm_flow_nof_remote_cores_region_57.BCM8869X=2
+dtm_flow_nof_remote_cores_region_58.BCM8869X=2
+dtm_flow_nof_remote_cores_region_59.BCM8869X=2
+dtm_flow_nof_remote_cores_region_60.BCM8869X=2
+
+mdb_profile.BCM8869X=l3-xl
+
+outlif_logical_to_physical_phase_map_1=S1
+outlif_logical_to_physical_phase_map_2=L1
+outlif_logical_to_physical_phase_map_3=XL
+outlif_logical_to_physical_phase_map_4=L2
+outlif_logical_to_physical_phase_map_5=M1
+outlif_logical_to_physical_phase_map_6=M2
+outlif_logical_to_physical_phase_map_7=M3
+outlif_logical_to_physical_phase_map_8=S2
+
+outlif_physical_phase_data_granularity_S1=60
+outlif_physical_phase_data_granularity_S2=60
+outlif_physical_phase_data_granularity_M1=60
+outlif_physical_phase_data_granularity_M2=60
+outlif_physical_phase_data_granularity_M3=60
+outlif_physical_phase_data_granularity_L1=60
+outlif_physical_phase_data_granularity_L2=60
+outlif_physical_phase_data_granularity_XL=60
+
+port_init_speed_fabric.BCM8869X=53125
+
+fabric_connect_mode.BCM8869X=SINGLE_FAP
+protocol_traps_mode.BCM8869X=IN_LIF
+
+schan_intr_enable.BCM8869X=0
+tdma_intr_enable.BCM8869X=0
+tslam_intr_enable.BCM8869X=0
+miim_intr_enable.BCM8869X=0
+schan_timeout_usec.BCM8869X=300000
+tdma_timeout_usec.BCM8869X=1000000
+tslam_timeout_usec.BCM8869X=1000000
+
+appl_enable_intr_init.BCM8869X=1
+polled_irq_mode.BCM8869X=1
+polled_irq_delay.BCM8869X=1000
+
+bcm_stat_interval.BCM8869X=1000
+
+mem_cache_enable_ecc.BCM8869X=1
+mem_cache_enable_parity.BCM8869X=1
+
+serdes_nif_clk_freq_in.BCM8869X_A0=2
+serdes_nif_clk_freq_out.BCM8869X_A0=1
+serdes_fabric_clk_freq_in.BCM8869X_A0=2
+serdes_fabric_clk_freq_out.BCM8869X_A0=1
+
+serdes_nif_clk_freq_in.BCM8869X=1
+serdes_nif_clk_freq_out.BCM8869X=bypass
+serdes_fabric_clk_freq_in.BCM8869X=1
+serdes_fabric_clk_freq_out.BCM8869X=bypass
+
+dram_phy_tune_mode_on_init.BCM8869X=RUN_TUNE
+
+dport_map_direct.BCM8869X=1
+
+pmf_sexem3_stage.BCM8869X=IPMF3
+
+lane_to_serdes_map_fabric_lane0.0=rx0:tx0
+lane_to_serdes_map_fabric_lane1.0=rx1:tx1
+lane_to_serdes_map_fabric_lane2.0=rx2:tx2
+lane_to_serdes_map_fabric_lane3.0=rx3:tx3
+lane_to_serdes_map_fabric_lane4.0=rx4:tx4
+lane_to_serdes_map_fabric_lane5.0=rx5:tx5
+lane_to_serdes_map_fabric_lane6.0=rx6:tx6
+lane_to_serdes_map_fabric_lane7.0=rx7:tx7
+lane_to_serdes_map_fabric_lane8.0=rx8:tx8
+lane_to_serdes_map_fabric_lane9.0=rx9:tx9
+lane_to_serdes_map_fabric_lane10.0=rx10:tx10
+lane_to_serdes_map_fabric_lane11.0=rx11:tx11
+lane_to_serdes_map_fabric_lane12.0=rx12:tx12
+lane_to_serdes_map_fabric_lane13.0=rx13:tx13
+lane_to_serdes_map_fabric_lane14.0=rx14:tx14
+lane_to_serdes_map_fabric_lane15.0=rx15:tx15
+lane_to_serdes_map_fabric_lane16.0=rx16:tx16
+lane_to_serdes_map_fabric_lane17.0=rx17:tx17
+lane_to_serdes_map_fabric_lane18.0=rx18:tx18
+lane_to_serdes_map_fabric_lane19.0=rx19:tx19
+lane_to_serdes_map_fabric_lane20.0=rx20:tx20
+lane_to_serdes_map_fabric_lane21.0=rx21:tx21
+lane_to_serdes_map_fabric_lane22.0=rx22:tx22
+lane_to_serdes_map_fabric_lane23.0=rx23:tx23
+lane_to_serdes_map_fabric_lane24.0=rx24:tx24
+lane_to_serdes_map_fabric_lane25.0=rx25:tx25
+lane_to_serdes_map_fabric_lane26.0=rx26:tx26
+lane_to_serdes_map_fabric_lane27.0=rx27:tx27
+lane_to_serdes_map_fabric_lane28.0=rx28:tx28
+lane_to_serdes_map_fabric_lane29.0=rx29:tx29
+lane_to_serdes_map_fabric_lane30.0=rx30:tx30
+lane_to_serdes_map_fabric_lane31.0=rx31:tx31
+lane_to_serdes_map_fabric_lane32.0=rx32:tx32
+lane_to_serdes_map_fabric_lane33.0=rx33:tx33
+lane_to_serdes_map_fabric_lane34.0=rx34:tx34
+lane_to_serdes_map_fabric_lane35.0=rx35:tx35
+lane_to_serdes_map_fabric_lane36.0=rx36:tx36
+lane_to_serdes_map_fabric_lane37.0=rx37:tx37
+lane_to_serdes_map_fabric_lane38.0=rx38:tx38
+lane_to_serdes_map_fabric_lane39.0=rx39:tx39
+lane_to_serdes_map_fabric_lane40.0=rx40:tx40
+lane_to_serdes_map_fabric_lane41.0=rx41:tx41
+lane_to_serdes_map_fabric_lane42.0=rx42:tx42
+lane_to_serdes_map_fabric_lane43.0=rx43:tx43
+lane_to_serdes_map_fabric_lane44.0=rx44:tx44
+lane_to_serdes_map_fabric_lane45.0=rx45:tx45
+lane_to_serdes_map_fabric_lane46.0=rx46:tx46
+lane_to_serdes_map_fabric_lane47.0=rx47:tx47
+lane_to_serdes_map_fabric_lane48.0=rx48:tx48
+lane_to_serdes_map_fabric_lane49.0=rx49:tx49
+lane_to_serdes_map_fabric_lane50.0=rx50:tx50
+lane_to_serdes_map_fabric_lane51.0=rx51:tx51
+lane_to_serdes_map_fabric_lane52.0=rx52:tx52
+lane_to_serdes_map_fabric_lane53.0=rx53:tx53
+lane_to_serdes_map_fabric_lane54.0=rx54:tx54
+lane_to_serdes_map_fabric_lane55.0=rx55:tx55
+lane_to_serdes_map_fabric_lane56.0=rx56:tx56
+lane_to_serdes_map_fabric_lane57.0=rx57:tx57
+lane_to_serdes_map_fabric_lane58.0=rx58:tx58
+lane_to_serdes_map_fabric_lane59.0=rx59:tx59
+lane_to_serdes_map_fabric_lane60.0=rx60:tx60
+lane_to_serdes_map_fabric_lane61.0=rx61:tx61
+lane_to_serdes_map_fabric_lane62.0=rx62:tx62
+lane_to_serdes_map_fabric_lane63.0=rx63:tx63
+lane_to_serdes_map_fabric_lane64.0=rx64:tx64
+lane_to_serdes_map_fabric_lane65.0=rx65:tx65
+lane_to_serdes_map_fabric_lane66.0=rx66:tx66
+lane_to_serdes_map_fabric_lane67.0=rx67:tx67
+lane_to_serdes_map_fabric_lane68.0=rx68:tx68
+lane_to_serdes_map_fabric_lane69.0=rx69:tx69
+lane_to_serdes_map_fabric_lane70.0=rx70:tx70
+lane_to_serdes_map_fabric_lane71.0=rx71:tx71
+lane_to_serdes_map_fabric_lane72.0=rx72:tx72
+lane_to_serdes_map_fabric_lane73.0=rx73:tx73
+lane_to_serdes_map_fabric_lane74.0=rx74:tx74
+lane_to_serdes_map_fabric_lane75.0=rx75:tx75
+lane_to_serdes_map_fabric_lane76.0=rx76:tx76
+lane_to_serdes_map_fabric_lane77.0=rx77:tx77
+lane_to_serdes_map_fabric_lane78.0=rx78:tx78
+lane_to_serdes_map_fabric_lane79.0=rx79:tx79
+lane_to_serdes_map_fabric_lane80.0=rx80:tx80
+lane_to_serdes_map_fabric_lane81.0=rx81:tx81
+lane_to_serdes_map_fabric_lane82.0=rx82:tx82
+lane_to_serdes_map_fabric_lane83.0=rx83:tx83
+lane_to_serdes_map_fabric_lane84.0=rx84:tx84
+lane_to_serdes_map_fabric_lane85.0=rx85:tx85
+lane_to_serdes_map_fabric_lane86.0=rx86:tx86
+lane_to_serdes_map_fabric_lane87.0=rx87:tx87
+lane_to_serdes_map_fabric_lane88.0=rx88:tx88
+lane_to_serdes_map_fabric_lane89.0=rx89:tx89
+lane_to_serdes_map_fabric_lane90.0=rx90:tx90
+lane_to_serdes_map_fabric_lane91.0=rx91:tx91
+lane_to_serdes_map_fabric_lane92.0=rx92:tx92
+lane_to_serdes_map_fabric_lane93.0=rx93:tx93
+lane_to_serdes_map_fabric_lane94.0=rx94:tx94
+lane_to_serdes_map_fabric_lane95.0=rx95:tx95
+lane_to_serdes_map_fabric_lane96.0=rx96:tx96
+lane_to_serdes_map_fabric_lane97.0=rx97:tx97
+lane_to_serdes_map_fabric_lane98.0=rx98:tx98
+lane_to_serdes_map_fabric_lane99.0=rx99:tx99
+lane_to_serdes_map_fabric_lane100.0=rx100:tx100
+lane_to_serdes_map_fabric_lane101.0=rx101:tx101
+lane_to_serdes_map_fabric_lane102.0=rx102:tx102
+lane_to_serdes_map_fabric_lane103.0=rx103:tx103
+lane_to_serdes_map_fabric_lane104.0=rx104:tx104
+lane_to_serdes_map_fabric_lane105.0=rx105:tx105
+lane_to_serdes_map_fabric_lane106.0=rx106:tx106
+lane_to_serdes_map_fabric_lane107.0=rx107:tx107
+lane_to_serdes_map_fabric_lane108.0=rx108:tx108
+lane_to_serdes_map_fabric_lane109.0=rx109:tx109
+lane_to_serdes_map_fabric_lane110.0=rx110:tx110
+lane_to_serdes_map_fabric_lane111.0=rx111:tx111
+
+lane_to_serdes_map_nif_lane0.0=rx5:tx7
+lane_to_serdes_map_nif_lane1.0=rx7:tx6
+lane_to_serdes_map_nif_lane2.0=rx4:tx5
+lane_to_serdes_map_nif_lane3.0=rx6:tx4
+lane_to_serdes_map_nif_lane4.0=rx0:tx0
+lane_to_serdes_map_nif_lane5.0=rx1:tx1
+lane_to_serdes_map_nif_lane6.0=rx2:tx3
+lane_to_serdes_map_nif_lane7.0=rx3:tx2
+lane_to_serdes_map_nif_lane8.0=rx13:tx15
+lane_to_serdes_map_nif_lane9.0=rx12:tx14
+lane_to_serdes_map_nif_lane10.0=rx15:tx13
+lane_to_serdes_map_nif_lane11.0=rx14:tx12
+lane_to_serdes_map_nif_lane12.0=rx10:tx10
+lane_to_serdes_map_nif_lane13.0=rx8:tx9
+lane_to_serdes_map_nif_lane14.0=rx9:tx11
+lane_to_serdes_map_nif_lane15.0=rx11:tx8
+lane_to_serdes_map_nif_lane16.0=rx23:tx23
+lane_to_serdes_map_nif_lane17.0=rx21:tx22
+lane_to_serdes_map_nif_lane18.0=rx22:tx21
+lane_to_serdes_map_nif_lane19.0=rx20:tx20
+lane_to_serdes_map_nif_lane20.0=rx16:tx18
+lane_to_serdes_map_nif_lane21.0=rx17:tx17
+lane_to_serdes_map_nif_lane22.0=rx18:tx16
+lane_to_serdes_map_nif_lane23.0=rx19:tx19
+lane_to_serdes_map_nif_lane24.0=rx31:tx31
+lane_to_serdes_map_nif_lane25.0=rx30:tx30
+lane_to_serdes_map_nif_lane26.0=rx29:tx29
+lane_to_serdes_map_nif_lane27.0=rx28:tx28
+lane_to_serdes_map_nif_lane28.0=rx24:tx26
+lane_to_serdes_map_nif_lane29.0=rx26:tx25
+lane_to_serdes_map_nif_lane30.0=rx25:tx24
+lane_to_serdes_map_nif_lane31.0=rx27:tx27
+lane_to_serdes_map_nif_lane32.0=rx39:tx35
+lane_to_serdes_map_nif_lane33.0=rx38:tx36
+lane_to_serdes_map_nif_lane34.0=rx32:tx32
+lane_to_serdes_map_nif_lane35.0=rx37:tx37
+lane_to_serdes_map_nif_lane36.0=rx33:tx34
+lane_to_serdes_map_nif_lane37.0=rx34:tx38
+lane_to_serdes_map_nif_lane38.0=rx35:tx33
+lane_to_serdes_map_nif_lane39.0=rx36:tx39
+lane_to_serdes_map_nif_lane40.0=rx44:tx47
+lane_to_serdes_map_nif_lane41.0=rx43:tx41
+lane_to_serdes_map_nif_lane42.0=rx47:tx46
+lane_to_serdes_map_nif_lane43.0=rx42:tx42
+lane_to_serdes_map_nif_lane44.0=rx45:tx45
+lane_to_serdes_map_nif_lane45.0=rx41:tx40
+lane_to_serdes_map_nif_lane46.0=rx46:tx44
+lane_to_serdes_map_nif_lane47.0=rx40:tx43
+lane_to_serdes_map_nif_lane48.0=rx55:tx55
+lane_to_serdes_map_nif_lane49.0=rx54:tx54
+lane_to_serdes_map_nif_lane50.0=rx53:tx53
+lane_to_serdes_map_nif_lane51.0=rx52:tx52
+lane_to_serdes_map_nif_lane52.0=rx48:tx48
+lane_to_serdes_map_nif_lane53.0=rx49:tx49
+lane_to_serdes_map_nif_lane54.0=rx50:tx50
+lane_to_serdes_map_nif_lane55.0=rx51:tx51
+lane_to_serdes_map_nif_lane56.0=rx60:tx60
+lane_to_serdes_map_nif_lane57.0=rx61:tx61
+lane_to_serdes_map_nif_lane58.0=rx62:tx63
+lane_to_serdes_map_nif_lane59.0=rx63:tx62
+lane_to_serdes_map_nif_lane60.0=rx58:tx59
+lane_to_serdes_map_nif_lane61.0=rx59:tx56
+lane_to_serdes_map_nif_lane62.0=rx57:tx58
+lane_to_serdes_map_nif_lane63.0=rx56:tx57
+lane_to_serdes_map_nif_lane64.0=rx68:tx69
+lane_to_serdes_map_nif_lane65.0=rx69:tx68
+lane_to_serdes_map_nif_lane66.0=rx70:tx71
+lane_to_serdes_map_nif_lane67.0=rx71:tx70
+lane_to_serdes_map_nif_lane68.0=rx67:tx64
+lane_to_serdes_map_nif_lane69.0=rx66:tx67
+lane_to_serdes_map_nif_lane70.0=rx65:tx65
+lane_to_serdes_map_nif_lane71.0=rx64:tx66
+lane_to_serdes_map_nif_lane72.0=rx78:tx76
+lane_to_serdes_map_nif_lane73.0=rx76:tx77
+lane_to_serdes_map_nif_lane74.0=rx79:tx78
+lane_to_serdes_map_nif_lane75.0=rx77:tx79
+lane_to_serdes_map_nif_lane76.0=rx75:tx72
+lane_to_serdes_map_nif_lane77.0=rx74:tx75
+lane_to_serdes_map_nif_lane78.0=rx73:tx73
+lane_to_serdes_map_nif_lane79.0=rx72:tx74
+lane_to_serdes_map_nif_lane80.0=rx81:tx83
+lane_to_serdes_map_nif_lane81.0=rx85:tx84
+lane_to_serdes_map_nif_lane82.0=rx80:tx80
+lane_to_serdes_map_nif_lane83.0=rx86:tx85
+lane_to_serdes_map_nif_lane84.0=rx82:tx82
+lane_to_serdes_map_nif_lane85.0=rx87:tx86
+lane_to_serdes_map_nif_lane86.0=rx83:tx81
+lane_to_serdes_map_nif_lane87.0=rx84:tx87
+lane_to_serdes_map_nif_lane88.0=rx91:tx95
+lane_to_serdes_map_nif_lane89.0=rx90:tx89
+lane_to_serdes_map_nif_lane90.0=rx95:tx94
+lane_to_serdes_map_nif_lane91.0=rx89:tx90
+lane_to_serdes_map_nif_lane92.0=rx93:tx93
+lane_to_serdes_map_nif_lane93.0=rx94:tx88
+lane_to_serdes_map_nif_lane94.0=rx92:tx92
+lane_to_serdes_map_nif_lane95.0=rx88:tx91
+phy_rx_polarity_flip_phy0=0
+phy_rx_polarity_flip_phy1=1
+phy_rx_polarity_flip_phy2=0
+phy_rx_polarity_flip_phy3=0
+phy_rx_polarity_flip_phy4=0
+phy_rx_polarity_flip_phy5=0
+phy_rx_polarity_flip_phy6=0
+phy_rx_polarity_flip_phy7=0
+phy_rx_polarity_flip_phy8=1
+phy_rx_polarity_flip_phy9=1
+phy_rx_polarity_flip_phy10=1
+phy_rx_polarity_flip_phy11=1
+phy_rx_polarity_flip_phy12=0
+phy_rx_polarity_flip_phy13=1
+phy_rx_polarity_flip_phy14=1
+phy_rx_polarity_flip_phy15=1
+phy_rx_polarity_flip_phy16=0
+phy_rx_polarity_flip_phy17=1
+phy_rx_polarity_flip_phy18=1
+phy_rx_polarity_flip_phy19=0
+phy_rx_polarity_flip_phy20=0
+phy_rx_polarity_flip_phy21=0
+phy_rx_polarity_flip_phy22=0
+phy_rx_polarity_flip_phy23=0
+phy_rx_polarity_flip_phy24=1
+phy_rx_polarity_flip_phy25=1
+phy_rx_polarity_flip_phy26=1
+phy_rx_polarity_flip_phy27=0
+phy_rx_polarity_flip_phy28=0
+phy_rx_polarity_flip_phy29=1
+phy_rx_polarity_flip_phy30=1
+phy_rx_polarity_flip_phy31=0
+phy_rx_polarity_flip_phy32=0
+phy_rx_polarity_flip_phy33=1
+phy_rx_polarity_flip_phy34=1
+phy_rx_polarity_flip_phy35=0
+phy_rx_polarity_flip_phy36=0
+phy_rx_polarity_flip_phy37=0
+phy_rx_polarity_flip_phy38=1
+phy_rx_polarity_flip_phy39=0
+phy_rx_polarity_flip_phy40=1
+phy_rx_polarity_flip_phy41=1
+phy_rx_polarity_flip_phy42=0
+phy_rx_polarity_flip_phy43=0
+phy_rx_polarity_flip_phy44=1
+phy_rx_polarity_flip_phy45=1
+phy_rx_polarity_flip_phy46=0
+phy_rx_polarity_flip_phy47=0
+phy_rx_polarity_flip_phy48=1
+phy_rx_polarity_flip_phy49=1
+phy_rx_polarity_flip_phy50=1
+phy_rx_polarity_flip_phy51=1
+phy_rx_polarity_flip_phy52=0
+phy_rx_polarity_flip_phy53=0
+phy_rx_polarity_flip_phy54=0
+phy_rx_polarity_flip_phy55=0
+phy_rx_polarity_flip_phy56=0
+phy_rx_polarity_flip_phy57=0
+phy_rx_polarity_flip_phy58=0
+phy_rx_polarity_flip_phy59=0
+phy_rx_polarity_flip_phy60=1
+phy_rx_polarity_flip_phy61=1
+phy_rx_polarity_flip_phy62=1
+phy_rx_polarity_flip_phy63=1
+phy_rx_polarity_flip_phy64=1
+phy_rx_polarity_flip_phy65=1
+phy_rx_polarity_flip_phy66=1
+phy_rx_polarity_flip_phy67=1
+phy_rx_polarity_flip_phy68=1
+phy_rx_polarity_flip_phy69=1
+phy_rx_polarity_flip_phy70=1
+phy_rx_polarity_flip_phy71=1
+phy_rx_polarity_flip_phy72=1
+phy_rx_polarity_flip_phy73=0
+phy_rx_polarity_flip_phy74=0
+phy_rx_polarity_flip_phy75=1
+phy_rx_polarity_flip_phy76=1
+phy_rx_polarity_flip_phy77=1
+phy_rx_polarity_flip_phy78=1
+phy_rx_polarity_flip_phy79=1
+phy_rx_polarity_flip_phy80=0
+phy_rx_polarity_flip_phy81=0
+phy_rx_polarity_flip_phy82=1
+phy_rx_polarity_flip_phy83=1
+phy_rx_polarity_flip_phy84=1
+phy_rx_polarity_flip_phy85=0
+phy_rx_polarity_flip_phy86=1
+phy_rx_polarity_flip_phy87=1
+phy_rx_polarity_flip_phy88=0
+phy_rx_polarity_flip_phy89=0
+phy_rx_polarity_flip_phy90=1
+phy_rx_polarity_flip_phy91=1
+phy_rx_polarity_flip_phy92=0
+phy_rx_polarity_flip_phy93=1
+phy_rx_polarity_flip_phy94=0
+phy_rx_polarity_flip_phy95=0
+phy_tx_polarity_flip_phy0=1
+phy_tx_polarity_flip_phy1=1
+phy_tx_polarity_flip_phy2=1
+phy_tx_polarity_flip_phy3=1
+phy_tx_polarity_flip_phy4=1
+phy_tx_polarity_flip_phy5=1
+phy_tx_polarity_flip_phy6=0
+phy_tx_polarity_flip_phy7=0
+phy_tx_polarity_flip_phy8=1
+phy_tx_polarity_flip_phy9=1
+phy_tx_polarity_flip_phy10=1
+phy_tx_polarity_flip_phy11=1
+phy_tx_polarity_flip_phy12=1
+phy_tx_polarity_flip_phy13=1
+phy_tx_polarity_flip_phy14=0
+phy_tx_polarity_flip_phy15=0
+phy_tx_polarity_flip_phy16=0
+phy_tx_polarity_flip_phy17=0
+phy_tx_polarity_flip_phy18=0
+phy_tx_polarity_flip_phy19=0
+phy_tx_polarity_flip_phy20=0
+phy_tx_polarity_flip_phy21=0
+phy_tx_polarity_flip_phy22=0
+phy_tx_polarity_flip_phy23=0
+phy_tx_polarity_flip_phy24=0
+phy_tx_polarity_flip_phy25=0
+phy_tx_polarity_flip_phy26=0
+phy_tx_polarity_flip_phy27=0
+phy_tx_polarity_flip_phy28=0
+phy_tx_polarity_flip_phy29=0
+phy_tx_polarity_flip_phy30=0
+phy_tx_polarity_flip_phy31=0
+phy_tx_polarity_flip_phy32=0
+phy_tx_polarity_flip_phy33=0
+phy_tx_polarity_flip_phy34=1
+phy_tx_polarity_flip_phy35=1
+phy_tx_polarity_flip_phy36=1
+phy_tx_polarity_flip_phy37=0
+phy_tx_polarity_flip_phy38=0
+phy_tx_polarity_flip_phy39=1
+phy_tx_polarity_flip_phy40=1
+phy_tx_polarity_flip_phy41=1
+phy_tx_polarity_flip_phy42=0
+phy_tx_polarity_flip_phy43=1
+phy_tx_polarity_flip_phy44=1
+phy_tx_polarity_flip_phy45=1
+phy_tx_polarity_flip_phy46=0
+phy_tx_polarity_flip_phy47=0
+phy_tx_polarity_flip_phy48=0
+phy_tx_polarity_flip_phy49=0
+phy_tx_polarity_flip_phy50=0
+phy_tx_polarity_flip_phy51=0
+phy_tx_polarity_flip_phy52=0
+phy_tx_polarity_flip_phy53=0
+phy_tx_polarity_flip_phy54=0
+phy_tx_polarity_flip_phy55=0
+phy_tx_polarity_flip_phy56=1
+phy_tx_polarity_flip_phy57=1
+phy_tx_polarity_flip_phy58=0
+phy_tx_polarity_flip_phy59=0
+phy_tx_polarity_flip_phy60=1
+phy_tx_polarity_flip_phy61=1
+phy_tx_polarity_flip_phy62=0
+phy_tx_polarity_flip_phy63=0
+phy_tx_polarity_flip_phy64=0
+phy_tx_polarity_flip_phy65=0
+phy_tx_polarity_flip_phy66=0
+phy_tx_polarity_flip_phy67=0
+phy_tx_polarity_flip_phy68=0
+phy_tx_polarity_flip_phy69=0
+phy_tx_polarity_flip_phy70=1
+phy_tx_polarity_flip_phy71=1
+phy_tx_polarity_flip_phy72=1
+phy_tx_polarity_flip_phy73=1
+phy_tx_polarity_flip_phy74=1
+phy_tx_polarity_flip_phy75=1
+phy_tx_polarity_flip_phy76=0
+phy_tx_polarity_flip_phy77=0
+phy_tx_polarity_flip_phy78=1
+phy_tx_polarity_flip_phy79=1
+phy_tx_polarity_flip_phy80=0
+phy_tx_polarity_flip_phy81=1
+phy_tx_polarity_flip_phy82=1
+phy_tx_polarity_flip_phy83=1
+phy_tx_polarity_flip_phy84=1
+phy_tx_polarity_flip_phy85=0
+phy_tx_polarity_flip_phy86=0
+phy_tx_polarity_flip_phy87=1
+phy_tx_polarity_flip_phy88=1
+phy_tx_polarity_flip_phy89=0
+phy_tx_polarity_flip_phy90=0
+phy_tx_polarity_flip_phy91=1
+phy_tx_polarity_flip_phy92=1
+phy_tx_polarity_flip_phy93=1
+phy_tx_polarity_flip_phy94=0
+phy_tx_polarity_flip_phy95=0
+
+ucode_port_1=CGE2_0:core_0.1
+ucode_port_2=CGE2_1:core_0.2
+ucode_port_3=CGE2_2:core_0.3
+ucode_port_4=CGE2_3:core_0.4
+ucode_port_5=CGE2_4:core_0.5
+ucode_port_6=CGE2_5:core_0.6
+ucode_port_7=CGE2_6:core_0.7
+ucode_port_8=CGE2_7:core_0.8
+ucode_port_9=CGE2_8:core_0.9
+ucode_port_10=CGE2_9:core_0.10
+ucode_port_11=CGE2_10:core_0.11
+ucode_port_12=CGE2_11:core_0.12
+ucode_port_13=CGE2_12:core_0.13
+ucode_port_14=CGE2_13:core_0.14
+ucode_port_15=CGE2_14:core_0.15
+ucode_port_16=CGE2_15:core_0.16
+ucode_port_17=CGE2_36:core_1.17
+ucode_port_18=CGE2_37:core_1.18
+ucode_port_19=CGE2_38:core_1.19
+ucode_port_20=CGE2_39:core_1.20
+ucode_port_21=CGE2_32:core_1.21
+ucode_port_22=CGE2_33:core_1.22
+ucode_port_23=CGE2_34:core_1.23
+ucode_port_24=CGE2_35:core_1.24
+ucode_port_25=CGE2_28:core_1.25
+ucode_port_26=CGE2_29:core_1.26
+ucode_port_27=CGE2_30:core_1.27
+ucode_port_28=CGE2_31:core_1.28
+ucode_port_29=CGE2_24:core_1.29
+ucode_port_30=CGE2_25:core_1.30
+ucode_port_31=CGE2_26:core_1.31
+ucode_port_32=CGE2_27:core_1.32
+
+ucode_port_33=CDGE4:core_0.33
+ucode_port_34=CDGE5:core_0.34
+ucode_port_35=CDGE11:core_1.35
+ucode_port_36=CDGE10:core_1.36
+
+rif_id_max=0x4000
+
+dma_desc_aggregator_chain_length_max.BCM8869X=1000
+dma_desc_aggregator_buff_size_kb.BCM8869X=100
+dma_desc_aggregator_timeout_usec.BCM8869X=1000
+dma_desc_aggregator_enable_specific_MDB_LPM.BCM8869X=1
+dma_desc_aggregator_enable_specific_MDB_FEC.BCM8869X=1
diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/port_config.ini b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/port_config.ini
index 976eae864d55..914fbbdf1652 100644
--- a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/port_config.ini
+++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/port_config.ini
@@ -1,37 +1,37 @@
# name lanes alias index speed
-Ethernet0 1,2 Ethernet1/1 1 100000
-Ethernet4 3,4 Ethernet2/1 2 100000
-Ethernet8 5,6 Ethernet3/1 3 100000
-Ethernet12 7,8 Ethernet4/1 4 100000
-Ethernet16 9,10 Ethernet5/1 5 100000
-Ethernet20 11,12 Ethernet6/1 6 100000
-Ethernet24 13,14 Ethernet7/1 7 100000
-Ethernet28 15,16 Ethernet8/1 8 100000
-Ethernet32 17,18 Ethernet9/1 9 100000
-Ethernet36 19,20 Ethernet10/1 10 100000
-Ethernet40 21,22 Ethernet11/1 11 100000
-Ethernet44 23,24 Ethernet12/1 12 100000
-Ethernet48 25,26 Ethernet13/1 13 100000
-Ethernet52 27,28 Ethernet14/1 14 100000
-Ethernet56 29,30 Ethernet15/1 15 100000
-Ethernet60 31,32 Ethernet16/1 16 100000
-Ethernet64 73,74 Ethernet17/1 17 100000
-Ethernet68 75,76 Ethernet18/1 18 100000
-Ethernet72 77,78 Ethernet19/1 19 100000
-Ethernet76 79,80 Ethernet20/1 20 100000
-Ethernet80 65,66 Ethernet21/1 21 100000
-Ethernet84 67,68 Ethernet22/1 22 100000
-Ethernet88 69,70 Ethernet23/1 23 100000
-Ethernet92 71,72 Ethernet24/1 24 100000
-Ethernet96 57,58 Ethernet25/1 25 100000
-Ethernet100 59,60 Ethernet26/1 26 100000
-Ethernet104 61,62 Ethernet27/1 27 100000
-Ethernet108 63,64 Ethernet28/1 28 100000
-Ethernet112 49,50 Ethernet29/1 29 100000
-Ethernet116 51,52 Ethernet30/1 30 100000
-Ethernet120 53,54 Ethernet31/1 31 100000
-Ethernet124 55,56 Ethernet32/1 32 100000
-Ethernet128 33,34,35,36,37,38,39,40 Ethernet33/1 33 400000
-Ethernet132 41,42,43,44,45,46,47,48 Ethernet34/1 34 400000
-Ethernet136 89,90,91,92,93,94,95,96 Ethernet35/1 35 400000
-Ethernet140 81,82,83,84,85,86,87,88 Ethernet36/1 36 400000
+Ethernet0 0,1 Ethernet1/1 1 100000
+Ethernet4 2,3 Ethernet2/1 2 100000
+Ethernet8 4,5 Ethernet3/1 3 100000
+Ethernet12 6,7 Ethernet4/1 4 100000
+Ethernet16 8,9 Ethernet5/1 5 100000
+Ethernet20 10,11 Ethernet6/1 6 100000
+Ethernet24 12,13 Ethernet7/1 7 100000
+Ethernet28 14,15 Ethernet8/1 8 100000
+Ethernet32 16,17 Ethernet9/1 9 100000
+Ethernet36 18,19 Ethernet10/1 10 100000
+Ethernet40 20,21 Ethernet11/1 11 100000
+Ethernet44 22,23 Ethernet12/1 12 100000
+Ethernet48 24,25 Ethernet13/1 13 100000
+Ethernet52 26,27 Ethernet14/1 14 100000
+Ethernet56 28,29 Ethernet15/1 15 100000
+Ethernet60 30,31 Ethernet16/1 16 100000
+Ethernet64 72,73 Ethernet17/1 17 100000
+Ethernet68 74,75 Ethernet18/1 18 100000
+Ethernet72 76,77 Ethernet19/1 19 100000
+Ethernet76 78,79 Ethernet20/1 20 100000
+Ethernet80 64,65 Ethernet21/1 21 100000
+Ethernet84 66,67 Ethernet22/1 22 100000
+Ethernet88 68,69 Ethernet23/1 23 100000
+Ethernet92 70,71 Ethernet24/1 24 100000
+Ethernet96 56,57 Ethernet25/1 25 100000
+Ethernet100 58,59 Ethernet26/1 26 100000
+Ethernet104 60,61 Ethernet27/1 27 100000
+Ethernet108 62,63 Ethernet28/1 28 100000
+Ethernet112 48,49 Ethernet29/1 29 100000
+Ethernet116 50,51 Ethernet30/1 30 100000
+Ethernet120 52,53 Ethernet31/1 31 100000
+Ethernet124 54,55 Ethernet32/1 32 100000
+Ethernet128 32,33,34,35,36,37,38,39 Ethernet33/1 33 400000
+Ethernet136 40,41,42,43,44,45,46,47 Ethernet34/1 34 400000
+Ethernet144 88,89,90,91,92,93,94,95 Ethernet35/1 35 400000
+Ethernet152 80,81,82,83,84,85,86,87 Ethernet36/1 36 400000
diff --git a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/sai.profile b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/sai.profile
index e69de29bb2d1..c01315c9b3bd 100644
--- a/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/sai.profile
+++ b/device/arista/x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/sai.profile
@@ -0,0 +1,2 @@
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/jr2-a7280cr3-32p4-32x100G+4x400G.config.bcm
+SAI_NUM_ECMP_MEMBERS=64
diff --git a/device/arista/x86_64-arista_7280cr3_32p4/fancontrol b/device/arista/x86_64-arista_7280cr3_32p4/fancontrol
deleted file mode 100644
index 55a48e095084..000000000000
--- a/device/arista/x86_64-arista_7280cr3_32p4/fancontrol
+++ /dev/null
@@ -1,10 +0,0 @@
-INTERVAL=5
-DEVPATH=hwmon2=devices/pci0000:00/0000:00:09.0 hwmon3=devices/pci0000:00/0000:00:09.0/i2c-56/56-004c
-DEVNAME=hwmon2=scd_fan_p3 hwmon3=max6658
-FCTEMPS=hwmon2/pwm6=hwmon3/temp1_input hwmon2/pwm5=hwmon3/temp1_input hwmon2/pwm4=hwmon3/temp1_input hwmon2/pwm3=hwmon3/temp1_input hwmon2/pwm2=hwmon3/temp1_input hwmon2/pwm1=hwmon3/temp1_input
-FCFANS=hwmon2/pwm6=hwmon2/fan6_input hwmon2/pwm5=hwmon2/fan5_input hwmon2/pwm4=hwmon2/fan4_input hwmon2/pwm3=hwmon2/fan3_input hwmon2/pwm2=hwmon2/fan2_input hwmon2/pwm1=hwmon2/fan1_input
-MINTEMP=hwmon2/pwm6=50 hwmon2/pwm5=50 hwmon2/pwm4=50 hwmon2/pwm3=50 hwmon2/pwm2=50 hwmon2/pwm1=50
-MINPWM=hwmon2/pwm6=128 hwmon2/pwm5=128 hwmon2/pwm4=128 hwmon2/pwm3=128 hwmon2/pwm2=128 hwmon2/pwm1=128
-MAXTEMP=hwmon2/pwm6=60 hwmon2/pwm5=60 hwmon2/pwm4=60 hwmon2/pwm3=60 hwmon2/pwm2=60 hwmon2/pwm1=60
-MINSTART=hwmon2/pwm6=128 hwmon2/pwm5=128 hwmon2/pwm4=128 hwmon2/pwm3=128 hwmon2/pwm2=128 hwmon2/pwm1=128
-MINSTOP=hwmon2/pwm6=128 hwmon2/pwm5=128 hwmon2/pwm4=128 hwmon2/pwm3=128 hwmon2/pwm2=128 hwmon2/pwm1=128
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4 b/device/arista/x86_64-arista_7280cr3mk_32d4
deleted file mode 120000
index 50478132d933..000000000000
--- a/device/arista/x86_64-arista_7280cr3mk_32d4
+++ /dev/null
@@ -1 +0,0 @@
-x86_64-arista_7280cr3_32d4
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-32D4 b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-32D4
new file mode 120000
index 000000000000..7546a1ba9e29
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-32D4
@@ -0,0 +1 @@
+Arista-7280CR3-C32D4
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C32D4/jr2-a7280cr3-32d4-32x100G+4x400G.config.bcm b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C32D4/jr2-a7280cr3-32d4-32x100G+4x400G.config.bcm
new file mode 120000
index 000000000000..fd83a52e8c97
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C32D4/jr2-a7280cr3-32d4-32x100G+4x400G.config.bcm
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/jr2-a7280cr3-32d4-32x100G+4x400G.config.bcm
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C32D4/port_config.ini b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C32D4/port_config.ini
new file mode 120000
index 000000000000..99c576e4855d
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C32D4/port_config.ini
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/port_config.ini
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C32D4/sai.profile b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C32D4/sai.profile
new file mode 120000
index 000000000000..d73267e5ea33
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C32D4/sai.profile
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32d4/Arista-7280CR3-C32D4/sai.profile
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C40/jr2-a7280cr3-32d4-40x100G.config.bcm b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C40/jr2-a7280cr3-32d4-40x100G.config.bcm
new file mode 120000
index 000000000000..d5071872b2f2
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C40/jr2-a7280cr3-32d4-40x100G.config.bcm
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/jr2-a7280cr3-32d4-40x100G.config.bcm
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C40/port_config.ini b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C40/port_config.ini
new file mode 120000
index 000000000000..ced14126af62
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C40/port_config.ini
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/port_config.ini
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C40/sai.profile b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C40/sai.profile
new file mode 120000
index 000000000000..cecb98495c52
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/Arista-7280CR3-C40/sai.profile
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32d4/Arista-7280CR3-C40/sai.profile
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/default_sku b/device/arista/x86_64-arista_7280cr3mk_32d4/default_sku
new file mode 100644
index 000000000000..3fee2043ff9d
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/default_sku
@@ -0,0 +1 @@
+Arista-7280CR3-C40 t1
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/platform.json b/device/arista/x86_64-arista_7280cr3mk_32d4/platform.json
new file mode 120000
index 000000000000..d9bda8a07e5d
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/platform.json
@@ -0,0 +1 @@
+../x86_64-arista_7280cr3_32d4/platform.json
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/platform_env.conf b/device/arista/x86_64-arista_7280cr3mk_32d4/platform_env.conf
new file mode 120000
index 000000000000..857fa4808ece
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/platform_env.conf
@@ -0,0 +1 @@
+../x86_64-arista_7280cr3_32d4/platform_env.conf
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/platform_reboot b/device/arista/x86_64-arista_7280cr3mk_32d4/platform_reboot
new file mode 120000
index 000000000000..7f94a49e38b0
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/platform_reboot
@@ -0,0 +1 @@
+../x86_64-arista_common/platform_reboot
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/plugins b/device/arista/x86_64-arista_7280cr3mk_32d4/plugins
new file mode 120000
index 000000000000..5fbbf98a6284
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/plugins
@@ -0,0 +1 @@
+../x86_64-arista_common/plugins/
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/pmon_daemon_control.json b/device/arista/x86_64-arista_7280cr3mk_32d4/pmon_daemon_control.json
new file mode 120000
index 000000000000..51d5ab7b0059
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/pmon_daemon_control.json
@@ -0,0 +1 @@
+../x86_64-arista_common/pmon_daemon_control.json
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/sensors.conf b/device/arista/x86_64-arista_7280cr3mk_32d4/sensors.conf
new file mode 120000
index 000000000000..8f1d37726c7f
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/sensors.conf
@@ -0,0 +1 @@
+../x86_64-arista_7280cr3_32d4/sensors.conf
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/system_health_monitoring_config.json b/device/arista/x86_64-arista_7280cr3mk_32d4/system_health_monitoring_config.json
new file mode 120000
index 000000000000..1185f771fa8e
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/system_health_monitoring_config.json
@@ -0,0 +1 @@
+../x86_64-arista_common/system_health_monitoring_config.json
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32d4/thermal_policy.json b/device/arista/x86_64-arista_7280cr3mk_32d4/thermal_policy.json
new file mode 120000
index 000000000000..0991dc7f3638
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32d4/thermal_policy.json
@@ -0,0 +1 @@
+../x86_64-arista_common/thermal_policy.json
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4 b/device/arista/x86_64-arista_7280cr3mk_32p4
deleted file mode 120000
index d6e2ddbb64bd..000000000000
--- a/device/arista/x86_64-arista_7280cr3mk_32p4
+++ /dev/null
@@ -1 +0,0 @@
-x86_64-arista_7280cr3_32p4
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-32P4 b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-32P4
new file mode 120000
index 000000000000..cfdaca201c0a
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-32P4
@@ -0,0 +1 @@
+Arista-7280CR3-C32P4
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C32P4/jr2-a7280cr3-32p4-32x100G+4x400G.config.bcm b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C32P4/jr2-a7280cr3-32p4-32x100G+4x400G.config.bcm
new file mode 120000
index 000000000000..1961801d0409
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C32P4/jr2-a7280cr3-32p4-32x100G+4x400G.config.bcm
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/jr2-a7280cr3-32p4-32x100G+4x400G.config.bcm
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C32P4/port_config.ini b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C32P4/port_config.ini
new file mode 120000
index 000000000000..d86230e26917
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C32P4/port_config.ini
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/port_config.ini
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C32P4/sai.profile b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C32P4/sai.profile
new file mode 120000
index 000000000000..bdf32213dd14
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C32P4/sai.profile
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32p4/Arista-7280CR3-C32P4/sai.profile
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm
new file mode 120000
index 000000000000..327d3dc0d97b
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/jr2-a7280cr3-32p4-40x100G.config.bcm
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C40/port_config.ini b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C40/port_config.ini
new file mode 120000
index 000000000000..52285035456b
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C40/port_config.ini
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/port_config.ini
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C40/sai.profile b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C40/sai.profile
new file mode 120000
index 000000000000..55e35fe597c5
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/Arista-7280CR3-C40/sai.profile
@@ -0,0 +1 @@
+../../x86_64-arista_7280cr3_32p4/Arista-7280CR3-C40/sai.profile
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/default_sku b/device/arista/x86_64-arista_7280cr3mk_32p4/default_sku
new file mode 100644
index 000000000000..3fee2043ff9d
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/default_sku
@@ -0,0 +1 @@
+Arista-7280CR3-C40 t1
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/platform.json b/device/arista/x86_64-arista_7280cr3mk_32p4/platform.json
new file mode 120000
index 000000000000..4da1d04362f7
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/platform.json
@@ -0,0 +1 @@
+../x86_64-arista_7280cr3_32p4/platform.json
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/platform_env.conf b/device/arista/x86_64-arista_7280cr3mk_32p4/platform_env.conf
new file mode 120000
index 000000000000..063c1c7e7cf7
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/platform_env.conf
@@ -0,0 +1 @@
+../x86_64-arista_7280cr3_32p4/platform_env.conf
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/platform_reboot b/device/arista/x86_64-arista_7280cr3mk_32p4/platform_reboot
new file mode 120000
index 000000000000..7f94a49e38b0
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/platform_reboot
@@ -0,0 +1 @@
+../x86_64-arista_common/platform_reboot
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/plugins b/device/arista/x86_64-arista_7280cr3mk_32p4/plugins
new file mode 120000
index 000000000000..5fbbf98a6284
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/plugins
@@ -0,0 +1 @@
+../x86_64-arista_common/plugins/
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/pmon_daemon_control.json b/device/arista/x86_64-arista_7280cr3mk_32p4/pmon_daemon_control.json
new file mode 120000
index 000000000000..51d5ab7b0059
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/pmon_daemon_control.json
@@ -0,0 +1 @@
+../x86_64-arista_common/pmon_daemon_control.json
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/sensors.conf b/device/arista/x86_64-arista_7280cr3mk_32p4/sensors.conf
new file mode 120000
index 000000000000..0b3f7a039764
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/sensors.conf
@@ -0,0 +1 @@
+../x86_64-arista_7280cr3_32p4/sensors.conf
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/system_health_monitoring_config.json b/device/arista/x86_64-arista_7280cr3mk_32p4/system_health_monitoring_config.json
new file mode 120000
index 000000000000..1185f771fa8e
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/system_health_monitoring_config.json
@@ -0,0 +1 @@
+../x86_64-arista_common/system_health_monitoring_config.json
\ No newline at end of file
diff --git a/device/arista/x86_64-arista_7280cr3mk_32p4/thermal_policy.json b/device/arista/x86_64-arista_7280cr3mk_32p4/thermal_policy.json
new file mode 120000
index 000000000000..0991dc7f3638
--- /dev/null
+++ b/device/arista/x86_64-arista_7280cr3mk_32p4/thermal_policy.json
@@ -0,0 +1 @@
+../x86_64-arista_common/thermal_policy.json
\ No newline at end of file
diff --git a/device/celestica/x86_64-cel_e1031-r0/platform.json b/device/celestica/x86_64-cel_e1031-r0/platform.json
new file mode 100644
index 000000000000..26acaf4aee76
--- /dev/null
+++ b/device/celestica/x86_64-cel_e1031-r0/platform.json
@@ -0,0 +1,758 @@
+{
+ "chassis": {
+ "name": "Celestica-E1031-T48S4",
+ "components": [
+ {
+ "name": "SMC_CPLD"
+ },
+ {
+ "name": "MMC_CPLD"
+ },
+ {
+ "name": "BIOS"
+ }
+ ],
+ "fans": [
+ {
+ "name": "FAN-1"
+ },
+ {
+ "name": "FAN-2"
+ },
+ {
+ "name": "FAN-3"
+ }
+ ],
+ "fan_drawers": [
+ {
+ "name": "Drawer1",
+ "fans": [
+ {
+ "name": "FAN-1"
+ }
+ ]
+ },
+ {
+ "name": "Drawer2",
+ "fans": [
+ {
+ "name": "FAN-2"
+ }
+ ]
+ },
+ {
+ "name": "Drawer3",
+ "fans": [
+ {
+ "name": "FAN-3"
+ }
+ ]
+ }
+ ],
+ "psus": [
+ {
+ "name": "PSU-R",
+ "fans": [
+ {
+ "name": "PSU-1 FAN-1"
+ }
+ ]
+ },
+ {
+ "name": "PSU-L",
+ "fans": [
+ {
+ "name": "PSU-2 FAN-1"
+ }
+ ]
+ }
+ ],
+ "thermals": [
+ {
+ "name": "Inlet ambient sensor (Rear to Front)"
+ },
+ {
+ "name": "Helix shutdown sensor (Rear to Front)"
+ },
+ {
+ "name": "Inlet ambient sensor (Front to Rear, right)"
+ },
+ {
+ "name": "Helix shutdown sensor (Front to Rear)"
+ },
+ {
+ "name": "Inlet ambient sensor (Front to Rear, left)"
+ },
+ {
+ "name": "CPU errata sensor (Front to Rear)"
+ },
+ {
+ "name": "CPU errata sensor (Rear to Front)"
+ }
+ ],
+ "sfps": [
+ {
+ "name": "Ethernet54"
+ },
+ {
+ "name": "Ethernet0"
+ },
+ {
+ "name": "Ethernet1"
+ },
+ {
+ "name": "Ethernet2"
+ },
+ {
+ "name": "Ethernet3"
+ },
+ {
+ "name": "Ethernet4"
+ },
+ {
+ "name": "Ethernet5"
+ },
+ {
+ "name": "Ethernet6"
+ },
+ {
+ "name": "Ethernet7"
+ },
+ {
+ "name": "Ethernet8"
+ },
+ {
+ "name": "Ethernet9"
+ },
+ {
+ "name": "Ethernet10"
+ },
+ {
+ "name": "Ethernet11"
+ },
+ {
+ "name": "Ethernet12"
+ },
+ {
+ "name": "Ethernet13"
+ },
+ {
+ "name": "Ethernet14"
+ },
+ {
+ "name": "Ethernet15"
+ },
+ {
+ "name": "Ethernet16"
+ },
+ {
+ "name": "Ethernet17"
+ },
+ {
+ "name": "Ethernet18"
+ },
+ {
+ "name": "Ethernet19"
+ },
+ {
+ "name": "Ethernet20"
+ },
+ {
+ "name": "Ethernet21"
+ },
+ {
+ "name": "Ethernet22"
+ },
+ {
+ "name": "Ethernet23"
+ },
+ {
+ "name": "Ethernet24"
+ },
+ {
+ "name": "Ethernet25"
+ },
+ {
+ "name": "Ethernet26"
+ },
+ {
+ "name": "Ethernet27"
+ },
+ {
+ "name": "Ethernet28"
+ },
+ {
+ "name": "Ethernet29"
+ },
+ {
+ "name": "Ethernet30"
+ },
+ {
+ "name": "Ethernet31"
+ },
+ {
+ "name": "Ethernet32"
+ },
+ {
+ "name": "Ethernet33"
+ },
+ {
+ "name": "Ethernet34"
+ },
+ {
+ "name": "Ethernet35"
+ },
+ {
+ "name": "Ethernet36"
+ },
+ {
+ "name": "Ethernet37"
+ },
+ {
+ "name": "Ethernet38"
+ },
+ {
+ "name": "Ethernet39"
+ },
+ {
+ "name": "Ethernet40"
+ },
+ {
+ "name": "Ethernet41"
+ },
+ {
+ "name": "Ethernet42"
+ },
+ {
+ "name": "Ethernet43"
+ },
+ {
+ "name": "Ethernet44"
+ },
+ {
+ "name": "Ethernet45"
+ },
+ {
+ "name": "Ethernet46"
+ },
+ {
+ "name": "Ethernet47"
+ },
+ {
+ "name": "Ethernet48"
+ },
+ {
+ "name": "Ethernet49"
+ },
+ {
+ "name": "Ethernet50"
+ },
+ {
+ "name": "Ethernet51"
+ },
+ {
+ "name": "Ethernet52"
+ },
+ {
+ "name": "Ethernet53"
+ }
+ ]
+ },
+ "interfaces": {
+ "Ethernet0": {
+ "index": "1",
+ "lanes": "2",
+ "breakout_modes": {
+ "1x1G": [
+ "etp1"
+ ]
+ }
+ },
+ "Ethernet1": {
+ "index": "2",
+ "lanes": "1",
+ "breakout_modes": {
+ "1x1G": [
+ "etp2"
+ ]
+ }
+ },
+ "Ethernet2": {
+ "index": "3",
+ "lanes": "4",
+ "breakout_modes": {
+ "1x1G": [
+ "etp3"
+ ]
+ }
+ },
+ "Ethernet3": {
+ "index": "4",
+ "lanes": "3",
+ "breakout_modes": {
+ "1x1G": [
+ "etp4"
+ ]
+ }
+ },
+ "Ethernet4": {
+ "index": "5",
+ "lanes": "6",
+ "breakout_modes": {
+ "1x1G": [
+ "etp5"
+ ]
+ }
+ },
+ "Ethernet5": {
+ "index": "6",
+ "lanes": "5",
+ "breakout_modes": {
+ "1x1G": [
+ "etp6"
+ ]
+ }
+ },
+ "Ethernet6": {
+ "index": "7",
+ "lanes": "8",
+ "breakout_modes": {
+ "1x1G": [
+ "etp7"
+ ]
+ }
+ },
+ "Ethernet7": {
+ "index": "8",
+ "lanes": "7",
+ "breakout_modes": {
+ "1x1G": [
+ "etp8"
+ ]
+ }
+ },
+ "Ethernet8": {
+ "index": "9",
+ "lanes": "10",
+ "breakout_modes": {
+ "1x1G": [
+ "etp9"
+ ]
+ }
+ },
+ "Ethernet9": {
+ "index": "10",
+ "lanes": "9",
+ "breakout_modes": {
+ "1x1G": [
+ "etp10"
+ ]
+ }
+ },
+ "Ethernet10": {
+ "index": "11",
+ "lanes": "12",
+ "breakout_modes": {
+ "1x1G": [
+ "etp11"
+ ]
+ }
+ },
+ "Ethernet11": {
+ "index": "12",
+ "lanes": "11",
+ "breakout_modes": {
+ "1x1G": [
+ "etp12"
+ ]
+ }
+ },
+ "Ethernet12": {
+ "index": "13",
+ "lanes": "14",
+ "breakout_modes": {
+ "1x1G": [
+ "etp13"
+ ]
+ }
+ },
+ "Ethernet13": {
+ "index": "14",
+ "lanes": "13",
+ "breakout_modes": {
+ "1x1G": [
+ "etp14"
+ ]
+ }
+ },
+ "Ethernet14": {
+ "index": "15",
+ "lanes": "16",
+ "breakout_modes": {
+ "1x1G": [
+ "etp15"
+ ]
+ }
+ },
+ "Ethernet15": {
+ "index": "16",
+ "lanes": "15",
+ "breakout_modes": {
+ "1x1G": [
+ "etp16"
+ ]
+ }
+ },
+ "Ethernet16": {
+ "index": "17",
+ "lanes": "18",
+ "breakout_modes": {
+ "1x1G": [
+ "etp17"
+ ]
+ }
+ },
+ "Ethernet17": {
+ "index": "18",
+ "lanes": "17",
+ "breakout_modes": {
+ "1x1G": [
+ "etp18"
+ ]
+ }
+ },
+ "Ethernet18": {
+ "index": "19",
+ "lanes": "20",
+ "breakout_modes": {
+ "1x1G": [
+ "etp19"
+ ]
+ }
+ },
+ "Ethernet19": {
+ "index": "20",
+ "lanes": "19",
+ "breakout_modes": {
+ "1x1G": [
+ "etp20"
+ ]
+ }
+ },
+ "Ethernet20": {
+ "index": "21",
+ "lanes": "22",
+ "breakout_modes": {
+ "1x1G": [
+ "etp21"
+ ]
+ }
+ },
+ "Ethernet21": {
+ "index": "22",
+ "lanes": "21",
+ "breakout_modes": {
+ "1x1G": [
+ "etp22"
+ ]
+ }
+ },
+ "Ethernet22": {
+ "index": "23",
+ "lanes": "24",
+ "breakout_modes": {
+ "1x1G": [
+ "etp23"
+ ]
+ }
+ },
+ "Ethernet23": {
+ "index": "24",
+ "lanes": "23",
+ "breakout_modes": {
+ "1x1G": [
+ "etp24"
+ ]
+ }
+ },
+ "Ethernet24": {
+ "index": "25",
+ "lanes": "26",
+ "breakout_modes": {
+ "1x1G": [
+ "etp25"
+ ]
+ }
+ },
+ "Ethernet25": {
+ "index": "26",
+ "lanes": "25",
+ "breakout_modes": {
+ "1x1G": [
+ "etp26"
+ ]
+ }
+ },
+ "Ethernet26": {
+ "index": "27",
+ "lanes": "28",
+ "breakout_modes": {
+ "1x1G": [
+ "etp27"
+ ]
+ }
+ },
+ "Ethernet27": {
+ "index": "28",
+ "lanes": "27",
+ "breakout_modes": {
+ "1x1G": [
+ "etp28"
+ ]
+ }
+ },
+ "Ethernet28": {
+ "index": "29",
+ "lanes": "30",
+ "breakout_modes": {
+ "1x1G": [
+ "etp29"
+ ]
+ }
+ },
+ "Ethernet29": {
+ "index": "30",
+ "lanes": "29",
+ "breakout_modes": {
+ "1x1G": [
+ "etp30"
+ ]
+ }
+ },
+ "Ethernet30": {
+ "index": "31",
+ "lanes": "32",
+ "breakout_modes": {
+ "1x1G": [
+ "etp31"
+ ]
+ }
+ },
+ "Ethernet31": {
+ "index": "32",
+ "lanes": "31",
+ "breakout_modes": {
+ "1x1G": [
+ "etp32"
+ ]
+ }
+ },
+ "Ethernet32": {
+ "index": "33",
+ "lanes": "34",
+ "breakout_modes": {
+ "1x1G": [
+ "etp33"
+ ]
+ }
+ },
+ "Ethernet33": {
+ "index": "34",
+ "lanes": "33",
+ "breakout_modes": {
+ "1x1G": [
+ "etp34"
+ ]
+ }
+ },
+ "Ethernet34": {
+ "index": "35",
+ "lanes": "36",
+ "breakout_modes": {
+ "1x1G": [
+ "etp35"
+ ]
+ }
+ },
+ "Ethernet35": {
+ "index": "36",
+ "lanes": "35",
+ "breakout_modes": {
+ "1x1G": [
+ "etp36"
+ ]
+ }
+ },
+ "Ethernet36": {
+ "index": "37",
+ "lanes": "38",
+ "breakout_modes": {
+ "1x1G": [
+ "etp37"
+ ]
+ }
+ },
+ "Ethernet37": {
+ "index": "38",
+ "lanes": "37",
+ "breakout_modes": {
+ "1x1G": [
+ "etp38"
+ ]
+ }
+ },
+ "Ethernet38": {
+ "index": "39",
+ "lanes": "40",
+ "breakout_modes": {
+ "1x1G": [
+ "etp39"
+ ]
+ }
+ },
+ "Ethernet39": {
+ "index": "40",
+ "lanes": "39",
+ "breakout_modes": {
+ "1x1G": [
+ "etp40"
+ ]
+ }
+ },
+ "Ethernet40": {
+ "index": "41",
+ "lanes": "42",
+ "breakout_modes": {
+ "1x1G": [
+ "etp41"
+ ]
+ }
+ },
+ "Ethernet41": {
+ "index": "42",
+ "lanes": "41",
+ "breakout_modes": {
+ "1x1G": [
+ "etp42"
+ ]
+ }
+ },
+ "Ethernet42": {
+ "index": "43",
+ "lanes": "44",
+ "breakout_modes": {
+ "1x1G": [
+ "etp43"
+ ]
+ }
+ },
+ "Ethernet43": {
+ "index": "44",
+ "lanes": "43",
+ "breakout_modes": {
+ "1x1G": [
+ "etp44"
+ ]
+ }
+ },
+ "Ethernet44": {
+ "index": "45",
+ "lanes": "46",
+ "breakout_modes": {
+ "1x1G": [
+ "etp45"
+ ]
+ }
+ },
+ "Ethernet45": {
+ "index": "46",
+ "lanes": "45",
+ "breakout_modes": {
+ "1x1G": [
+ "etp46"
+ ]
+ }
+ },
+ "Ethernet46": {
+ "index": "47",
+ "lanes": "48",
+ "breakout_modes": {
+ "1x1G": [
+ "etp47"
+ ]
+ }
+ },
+ "Ethernet47": {
+ "index": "48",
+ "lanes": "47",
+ "breakout_modes": {
+ "1x1G": [
+ "etp48"
+ ]
+ }
+ },
+ "Ethernet48": {
+ "index": "49",
+ "lanes": "48",
+ "breakout_modes": {
+ "1x10G": [
+ "etp49"
+ ]
+ }
+ },
+ "Ethernet49": {
+ "index": "50",
+ "lanes": "53",
+ "breakout_modes": {
+ "1x10G": [
+ "etp50"
+ ]
+ }
+ },
+ "Ethernet50": {
+ "index": "51",
+ "lanes": "56",
+ "breakout_modes": {
+ "1x10G": [
+ "etp51"
+ ]
+ }
+ },
+ "Ethernet51": {
+ "index": "52",
+ "lanes": "55",
+ "breakout_modes": {
+ "1x10G": [
+ "etp52"
+ ]
+ }
+ },
+ "Ethernet52": {
+ "index": "53",
+ "lanes": "49",
+ "breakout_modes": {
+ "1x10G": [
+ "etp53"
+ ]
+ }
+ },
+ "Ethernet53": {
+ "index": "54,54,54,54",
+ "lanes": "57,58,59,60 ",
+ "breakout_modes": {
+ "1x10G": [
+ "etp54"
+ ]
+ }
+ },
+ "Ethernet54": {
+ "index": "55,55,55,55",
+ "lanes": "61,62,63,64",
+ "breakout_modes": {
+ "1x10G": [
+ "etp55"
+ ]
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/device/celestica/x86_64-cel_e1031-r0/platform_components.json b/device/celestica/x86_64-cel_e1031-r0/platform_components.json
new file mode 100644
index 000000000000..97e691f90084
--- /dev/null
+++ b/device/celestica/x86_64-cel_e1031-r0/platform_components.json
@@ -0,0 +1,11 @@
+{
+ "chassis": {
+ "Celestica-E1031-T48S4": {
+ "component": {
+ "BIOS": {},
+ "SMC_CPLD": {},
+ "MMC_CPLD": {}
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py
index d65f2cf3f54f..033d4668211f 100644
--- a/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py
+++ b/device/celestica/x86_64-cel_e1031-r0/plugins/sfputil.py
@@ -11,63 +11,17 @@ class SfpUtil(SfpUtilBase):
"""Platform-specific SfpUtil class"""
PORT_START = 1
- PORT_END = 52
+ PORT_END = 55
+ SFP_PORT_START = 49
+ SFP_PORT_END = 52
port_to_i2c_mapping = {
- 1: None,
- 2: None,
- 3: None,
- 4: None,
- 5: None,
- 6: None,
- 7: None,
- 8: None,
- 9: None,
- 10: None,
- 11: None,
- 12: None,
- 13: None,
- 14: None,
- 15: None,
- 16: None,
- 17: None,
- 18: None,
- 19: None,
- 20: None,
- 21: None,
- 22: None,
- 23: None,
- 24: None,
- 25: None,
- 26: None,
- 27: None,
- 28: None,
- 29: None,
- 30: None,
- 31: None,
- 32: None,
- 33: None,
- 34: None,
- 35: None,
- 36: None,
- 37: None,
- 38: None,
- 39: None,
- 40: None,
- 41: None,
- 42: None,
- 43: None,
- 44: None,
- 45: None,
- 46: None,
- 47: None,
- 48: None,
49: 15,
50: 14,
51: 17,
52: 16
}
_port_to_eeprom_mapping = {}
- _sfp_port = list(range(49, PORT_END + 1))
+ _sfp_port = list(range(SFP_PORT_START, SFP_PORT_END + 1))
@property
def port_start(self):
@@ -89,7 +43,7 @@ def __init__(self):
# Override port_to_eeprom_mapping for class initialization
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
for x in range(self.PORT_START, self.PORT_END + 1):
- port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x])
+ port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) if x in self._sfp_port else None
self.port_to_eeprom_mapping[x] = port_eeprom_path
SfpUtilBase.__init__(self)
@@ -103,7 +57,7 @@ def get_presence(self, port_num):
try:
with open(sfp_modabs_path, 'r') as port_status:
status = int(port_status.read(), 16)
- status = (status >> (port_num - 49)) & 1
+ status = (status >> (port_num - self.SFP_PORT_START)) & 1
except IOError:
return False
@@ -138,7 +92,8 @@ def get_transceiver_change_event(self, timeout=0):
for port_num in self._sfp_port:
change = (changes >> (port_num - 49)) & 1
if change == 1:
- port_dict[str(port_num)] = str(int(self.get_presence(port_num)))
+ port_dict[str(port_num)] = str(
+ int(self.get_presence(port_num)))
found_flag = 1
if not found_flag:
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py
index de7a246b43f8..cb442518f199 100644
--- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py
+++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py
@@ -6,25 +6,26 @@
#
#############################################################################
+
try:
- import sys
from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper
from sonic_platform_base.chassis_base import ChassisBase
+ from sonic_py_common import device_info
from .common import Common
from .event import SfpEvent
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
NUM_FAN_TRAY = 3
-NUM_FAN = 1
NUM_PSU = 2
NUM_THERMAL = 7
-NUM_SFP = 52
+NUM_SFP = 55
NUM_COMPONENT = 3
RESET_REGISTER = "0x112"
HOST_REBOOT_CAUSE_PATH = "/host/reboot-cause/previous-reboot-cause.txt"
PMON_REBOOT_CAUSE_PATH = "/usr/share/sonic/platform/api_files/reboot-cause/previous-reboot-cause.txt"
HOST_CHK_CMD = "docker > /dev/null 2>&1"
+STATUS_LED_PATH = "/sys/devices/platform/e1031.smc/master_led"
class Chassis(ChassisBase):
@@ -32,66 +33,63 @@ class Chassis(ChassisBase):
def __init__(self):
ChassisBase.__init__(self)
+
self._api_common = Common()
- self.sfp_module_initialized = False
- self.__initialize_eeprom()
- self.is_host = self._api_common.is_host()
+ self._is_host = self._api_common.is_host()
- if not self.is_host:
- self.__initialize_fan()
- self.__initialize_psu()
- self.__initialize_thermals()
- else:
- self.__initialize_components()
+ self.__initialize_eeprom()
+ self.__initialize_fan()
+ self.__initialize_psu()
+ self.__initialize_thermals()
+ self.__initialize_components()
- self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self.__is_host(
- ) else PMON_REBOOT_CAUSE_PATH
+ self.sfp_module_initialized = False
+ self._reboot_cause_path = HOST_REBOOT_CAUSE_PATH if self._is_host else PMON_REBOOT_CAUSE_PATH
def __initialize_sfp(self):
sfputil_helper = SfpUtilHelper()
port_config_file_path = device_info.get_path_to_port_config_file()
sfputil_helper.read_porttab_mappings(port_config_file_path, 0)
- from sonic_platform.sfp import Sfp
+ from .sfp import Sfp
for index in range(0, NUM_SFP):
- name_idx = 0 if index+1 == NUM_SFP else index+1
- sfp = Sfp(index, sfputil_helper.logical[name_idx])
+ sfp = Sfp(index, sfputil_helper.logical[index])
self._sfp_list.append(sfp)
self.sfp_module_initialized = True
def __initialize_psu(self):
- from sonic_platform.psu import Psu
+ from .psu import Psu
for index in range(0, NUM_PSU):
psu = Psu(index)
self._psu_list.append(psu)
def __initialize_fan(self):
- from sonic_platform.fan import Fan
- for fant_index in range(0, NUM_FAN_TRAY):
- for fan_index in range(0, NUM_FAN):
- fan = Fan(fant_index, fan_index)
- self._fan_list.append(fan)
+ from .fan_drawer import FanDrawer
+ for i in range(NUM_FAN_TRAY):
+ fandrawer = FanDrawer(i)
+ self._fan_drawer_list.append(fandrawer)
+ self._fan_list += fandrawer.get_all_fans()
def __initialize_thermals(self):
- from sonic_platform.thermal import Thermal
+ from .thermal import Thermal
airflow = self.__get_air_flow()
for index in range(0, NUM_THERMAL):
thermal = Thermal(index, airflow)
self._thermal_list.append(thermal)
def __initialize_eeprom(self):
- from sonic_platform.eeprom import Tlv
+ from .eeprom import Tlv
self._eeprom = Tlv()
def __initialize_components(self):
- from sonic_platform.component import Component
+ from .component import Component
for index in range(0, NUM_COMPONENT):
component = Component(index)
self._component_list.append(component)
def __get_air_flow(self):
air_flow_path = '/usr/share/sonic/device/{}/fan_airflow'.format(
- self._api_common.platform) if self.is_host else '/usr/share/sonic/platform/fan_airflow'
+ self._api_common.get_platform()) if self._is_host else '/usr/share/sonic/platform/fan_airflow'
air_flow = self._api_common.read_txt_file(air_flow_path)
return air_flow or 'B2F'
@@ -154,7 +152,6 @@ def get_reboot_cause(self):
else:
reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE
description = 'Unknown reason'
-
return (reboot_cause, description)
def get_watchdog(self):
@@ -247,8 +244,8 @@ def get_sfp(self, index):
# The index will start from 1
sfp = self._sfp_list[index-1]
except IndexError:
- sys.stderr.write("SFP index {} out of range (1-{})\n".format(
- index, len(self._sfp_list)))
+ print("SFP index {} out of range (1-{})\n".format(
+ index, len(self._sfp_list)))
return sfp
##############################################################
@@ -269,13 +266,13 @@ def get_name(self):
Returns:
string: The name of the device
"""
- return self._api_common.hwsku
+ return self._api_common.get_hwsku()
def get_presence(self):
"""
- Retrieves the presence of the PSU
+ Retrieves the presence of the Chassis
Returns:
- bool: True if PSU is present, False if not
+ bool: True if Chassis is present, False if not
"""
return True
@@ -303,3 +300,52 @@ def get_status(self):
"""
return True
+ def get_position_in_parent(self):
+ """
+ Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position
+ for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned
+ Returns:
+ integer: The 1-based relative physical position in parent device or -1 if cannot determine the position
+ """
+ return -1
+
+ def is_replaceable(self):
+ """
+ Indicate whether this device is replaceable.
+ Returns:
+ bool: True if it is replaceable.
+ """
+ return False
+
+ def set_status_led(self, color):
+ """
+ Sets the state of the PSU status LED
+ Args:
+ color: A string representing the color with which to set the PSU status LED
+ Note: Only support green and off
+ Returns:
+ bool: True if status LED state is set successfully, False if not
+ """
+
+ status_str = {
+ self.STATUS_LED_COLOR_GREEN: 'green',
+ self.STATUS_LED_COLOR_AMBER: 'amber',
+ self.STATUS_LED_COLOR_OFF: 'off'
+ }.get(color, 'off')
+
+ return self._api_common.write_txt_file(STATUS_LED_PATH, status_str)
+
+ def get_status_led(self):
+ """
+ Gets the state of the PSU status LED
+ Returns:
+ A string, one of the predefined STATUS_LED_COLOR_* strings above
+ """
+ status = self._api_common.read_txt_file(STATUS_LED_PATH)
+ status_str = {
+ 'on': self.STATUS_LED_COLOR_GREEN,
+ 'amber': self.STATUS_LED_COLOR_AMBER,
+ 'off': self.STATUS_LED_COLOR_OFF
+ }.get(status, None)
+
+ return status_str
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/common.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/common.py
index 84fcafd1bcf0..08e8fc41475c 100644
--- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/common.py
+++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/common.py
@@ -29,7 +29,18 @@ class Common:
def __init__(self, conf=None):
self._main_conf = conf
- (self.platform, self.hwsku) = device_info.get_platform_and_hwsku()
+ self.platform = None
+ self.hwsku = None
+
+ def get_platform(self):
+ (self.platform, self.hwsku) = device_info.get_platform_and_hwsku(
+ ) if not self.platform else (self.platform, self.hwsku)
+ return self.platform
+
+ def get_hwsku(self):
+ (self.platform, self.hwsku) = device_info.get_platform_and_hwsku(
+ ) if not self.hwsku else (self.platform, self.hwsku)
+ return self.hwsku
def run_command(self, command):
status = False
@@ -38,7 +49,7 @@ def run_command(self, command):
p = subprocess.Popen(
command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
raw_data, err = p.communicate()
- if err == '':
+ if p.returncode == 0:
status, output = True, raw_data.strip()
except Exception:
pass
@@ -152,10 +163,28 @@ def get_reg(self, path, reg_addr):
status, output = self.run_command(cmd)
return output if status else None
+ def set_reg(self, path, reg_addr, value):
+ cmd = "echo {0} {1} > {2}".format(reg_addr, value, path)
+ status, output = self.run_command(cmd)
+ return output if status else None
+
def read_txt_file(self, path):
- with open(path, 'r') as f:
- output = f.readline()
- return output.strip('\n')
+ try:
+ with open(path, 'r') as f:
+ output = f.readline()
+ return output.strip('\n')
+ except Exception:
+ pass
+ return ''
+
+ def read_one_line_file(self, file_path):
+ try:
+ with open(file_path, 'r') as fd:
+ data = fd.readline()
+ return data.strip()
+ except IOError:
+ pass
+ return ''
def write_txt_file(self, file_path, value):
try:
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py
index 8d2829f90c01..56fae35914ab 100644
--- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py
+++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py
@@ -6,12 +6,12 @@
#
#############################################################################
-import os.path
-import shutil
-import shlex
-import subprocess
try:
+ import os.path
+ import shutil
+ import shlex
+ import subprocess
from sonic_platform_base.component_base import ComponentBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
@@ -119,6 +119,29 @@ def get_firmware_version(self):
return fw_version
+ def get_available_firmware_version(self, image_path):
+ """
+ Retrieves the available firmware version of the component
+ Note: the firmware version will be read from image
+ Args:
+ image_path: A string, path to firmware image
+ Returns:
+ A string containing the available firmware version of the component
+ """
+ return "N/A"
+
+ def get_firmware_update_notification(self, image_path):
+ """
+ Retrieves a notification on what should be done in order to complete
+ the component firmware update
+ Args:
+ image_path: A string, path to firmware image
+ Returns:
+ A string containing the component firmware update notification if required.
+ By default 'None' value will be used, which indicates that no actions are required
+ """
+ return "None"
+
def install_firmware(self, image_path):
"""
Install firmware to module
@@ -139,5 +162,73 @@ def install_firmware(self, image_path):
install_command = "ispvm %s" % new_image_path
# elif self.name == "BIOS":
# install_command = "afulnx_64 %s /p /b /n /x /r" % image_path
-
return self.__run_command(install_command)
+
+ def update_firmware(self, image_path):
+ """
+ Updates firmware of the component
+ This API performs firmware update: it assumes firmware installation and loading in a single call.
+ In case platform component requires some extra steps (apart from calling Low Level Utility)
+ to load the installed firmware (e.g, reboot, power cycle, etc.) - this will be done automatically by API
+ Args:
+ image_path: A string, path to firmware image
+ Raises:
+ RuntimeError: update failed
+ """
+ return False
+
+ ##############################################################
+ ###################### Device methods ########################
+ ##############################################################
+
+ def get_presence(self):
+ """
+ Retrieves the presence of the FAN
+ Returns:
+ bool: True if FAN is present, False if not
+ """
+ return True
+
+ def get_model(self):
+ """
+ Retrieves the model number (or part number) of the device
+ Returns:
+ string: Model/part number of device
+ """
+ return 'N/A'
+
+ def get_serial(self):
+ """
+ Retrieves the serial number of the device
+ Returns:
+ string: Serial number of device
+ """
+ return 'N/A'
+
+ def get_status(self):
+ """
+ Retrieves the operational status of the device
+ Returns:
+ A boolean value, True if device is operating properly, False if not
+ """
+ return True
+
+ def get_position_in_parent(self):
+ """
+ Retrieves 1-based relative physical position in parent device.
+ If the agent cannot determine the parent-relative position
+ for some reason, or if the associated value of
+ entPhysicalContainedIn is'0', then the value '-1' is returned
+ Returns:
+ integer: The 1-based relative physical position in parent device
+ or -1 if cannot determine the position
+ """
+ return -1
+
+ def is_replaceable(self):
+ """
+ Indicate whether this device is replaceable.
+ Returns:
+ bool: True if it is replaceable.
+ """
+ return False
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py
index c31d29f2caef..dc43a4d7ddda 100644
--- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py
+++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/eeprom.py
@@ -17,13 +17,14 @@
else:
from cStringIO import StringIO
- from sonic_platform_base.sonic_eeprom import eeprom_dts
from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo
+ from sonic_platform_base.sonic_eeprom.eeprom_base import EepromDecoder
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
CACHE_ROOT = '/var/cache/sonic/decode-syseeprom'
CACHE_FILE = 'syseeprom_cache'
+NULL = 'N/A'
class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
@@ -32,8 +33,8 @@ class Tlv(eeprom_tlvinfo.TlvInfoDecoder):
def __init__(self):
self._eeprom_path = "/sys/class/i2c-adapter/i2c-2/2-0050/eeprom"
+ self._eeprom = None
super(Tlv, self).__init__(self._eeprom_path, 0, '', True)
- self._eeprom = self._load_eeprom()
def __parse_output(self, decode_output):
decode_output.replace('\0', '')
@@ -50,7 +51,7 @@ def __parse_output(self, decode_output):
value = match.group(3).rstrip('\0')
_eeprom_info_dict[idx] = value
- except Exception:
+ except BaseException:
pass
return _eeprom_info_dict
@@ -59,7 +60,7 @@ def _load_eeprom(self):
sys.stdout = StringIO()
try:
self.read_eeprom_db()
- except Exception:
+ except BaseException:
decode_output = sys.stdout.getvalue()
sys.stdout = original_stdout
return self.__parse_output(decode_output)
@@ -71,7 +72,7 @@ def _load_eeprom(self):
if not os.path.exists(CACHE_ROOT):
try:
os.makedirs(CACHE_ROOT)
- except Exception:
+ except BaseException:
pass
#
@@ -80,7 +81,7 @@ def _load_eeprom(self):
#
try:
self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE))
- except Exception:
+ except BaseException:
pass
e = self.read_eeprom()
@@ -89,7 +90,7 @@ def _load_eeprom(self):
try:
self.update_cache(e)
- except Exception:
+ except BaseException:
pass
self.decode_eeprom(e)
@@ -102,14 +103,98 @@ def _load_eeprom(self):
return self.__parse_output(decode_output)
+ def _valid_tlv(self, eeprom_data):
+ tlvinfo_type_codes_list = [
+ self._TLV_CODE_PRODUCT_NAME,
+ self._TLV_CODE_PART_NUMBER,
+ self._TLV_CODE_SERIAL_NUMBER,
+ self._TLV_CODE_MAC_BASE,
+ self._TLV_CODE_MANUF_DATE,
+ self._TLV_CODE_DEVICE_VERSION,
+ self._TLV_CODE_LABEL_REVISION,
+ self._TLV_CODE_PLATFORM_NAME,
+ self._TLV_CODE_ONIE_VERSION,
+ self._TLV_CODE_MAC_SIZE,
+ self._TLV_CODE_MANUF_NAME,
+ self._TLV_CODE_MANUF_COUNTRY,
+ self._TLV_CODE_VENDOR_NAME,
+ self._TLV_CODE_DIAG_VERSION,
+ self._TLV_CODE_SERVICE_TAG,
+ self._TLV_CODE_VENDOR_EXT,
+ self._TLV_CODE_CRC_32
+ ]
+
+ for code in tlvinfo_type_codes_list:
+ code_str = "0x{:X}".format(code)
+ eeprom_data[code_str] = eeprom_data.get(code_str, NULL)
+ return eeprom_data
+
def get_eeprom(self):
- return self._eeprom
+ self._eeprom = self._load_eeprom() if not self._eeprom else self._eeprom
+ return self._valid_tlv(self._eeprom)
+
+ def get_pn(self):
+ return self.get_eeprom()['0x22']
def get_serial(self):
- return self._eeprom.get('0x23', "Undefined.")
+ return self.get_eeprom()['0x23']
def get_mac(self):
- return self._eeprom.get('0x24', "Undefined.")
+ return self.get_eeprom()['0x24']
- def get_pn(self):
- return self._eeprom.get('0x21', "Undefined.")
+
+class DeviceEEPROM(eeprom_tlvinfo.TlvInfoDecoder):
+
+ def __init__(self, eeprom_path, device_format, start_offset):
+ # Decode device eeprom as per specified format
+ self.format = device_format
+ self.start_offset = start_offset
+
+ EepromDecoder.__init__(self, eeprom_path, self.format,
+ self.start_offset, '', True)
+ self._load_device_eeprom()
+
+ def _load_device_eeprom(self):
+ """
+ Reads the Fan/PSU EEPROM and interprets as per the specified format
+ """
+ self.serial_number = 'NA'
+ self.model_str = 'NA'
+
+ # device eeproms use proprietary format
+ try:
+ # Read Fan/PSU EEPROM as per the specified format.
+ self.eeprom_data = EepromDecoder.read_eeprom(self)
+ except Exception as e:
+ return
+
+ if self.eeprom_data[0] == 255:
+ return
+
+ (valid, data) = self._get_eeprom_field("Model")
+ if valid:
+ self.model_str = data.decode()
+
+ try:
+ (valid, data) = self._get_eeprom_field("Serial Number")
+ if valid:
+ self.serial_number = data.decode()
+ except Exception as e:
+ return
+
+ def _get_eeprom_field(self, field_name, decode=False):
+ """
+ For a field name specified in the EEPROM format, returns the
+ presence of the field and the value for the same.
+ """
+ field_start = 0
+ for field in self.format:
+ field_end = field_start + field[2]
+ if field[0] == field_name:
+ if decode:
+ return (True, self.eeprom_data[field_start:field_end].decode('ascii'))
+ else:
+ return (True, self.eeprom_data[field_start:field_end])
+ field_start = field_end
+
+ return (False, None)
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/event.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/event.py
index c8a487f383ea..332751386c7f 100644
--- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/event.py
+++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/event.py
@@ -1,7 +1,7 @@
try:
import time
import select
- from .helper import APIHelper
+ from .common import Common
from sonic_py_common.logger import Logger
except ImportError as e:
raise ImportError(repr(e) + " - required module not found")
@@ -16,12 +16,12 @@ class SfpEvent:
GPIO_SUS7 = '/sys/devices/platform/hlx-ich.0/sci_int_gpio_sus7'
def __init__(self, sfp_list):
- self._api_helper = APIHelper()
+ self._api_common = Common()
self._sfp_list = sfp_list
self._logger = Logger()
-
+
# clear interrupt
- self._api_helper.read_one_line_file(self.INT_PATH)
+ self._api_common.read_one_line_file(self.INT_PATH)
def get_sfp_event(self, timeout):
epoll = select.epoll()
@@ -37,7 +37,7 @@ def get_sfp_event(self, timeout):
events = epoll.poll(timeout=timeout_sec if timeout != 0 else -1)
if events:
# Read the QSFP ABS interrupt & status registers
- port_changes = self._api_helper.read_one_line_file(
+ port_changes = self._api_common.read_one_line_file(
self.INT_PATH)
changes = int(port_changes, 16)
for sfp in self._sfp_list:
@@ -48,7 +48,8 @@ def get_sfp_event(self, timeout):
if change == 1:
time.sleep(self.DELAY)
port_status = sfp.get_presence()
- port_dict[str(sfp.port_num)] = '1' if port_status else '0'
+ port_dict[str(sfp.port_num)
+ ] = '1' if port_status else '0'
return port_dict
except Exception as e:
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py
index c066cb9c33fc..90029ffce47e 100644
--- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py
+++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py
@@ -6,6 +6,7 @@
#
#############################################################################
+from __future__ import division
import math
import os.path
@@ -20,8 +21,10 @@
EMC2305_MAX_PWM = 255
EMC2305_FAN_PWM = "pwm{}"
EMC2305_FAN_TARGET = "fan{}_target"
+EMC2305_FAN_PWM_MODE = "pwm{}_enable"
EMC2305_FAN_INPUT = "pwm{}"
FAN_NAME_LIST = ["FAN-1", "FAN-2", "FAN-3"]
+FAN_SPEED_TOLERANCE = 10
PSU_FAN_MAX_RPM = 11000
PSU_HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
PSU_I2C_MAPPING = {
@@ -34,12 +37,16 @@
"addr": "5a"
},
}
+NULL_VAL = 'N/A'
class Fan(FanBase):
"""Platform-specific Fan class"""
def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0):
+ FanBase.__init__(self)
+
+ self._api_common = Common()
self.fan_index = fan_index
self.fan_tray_index = fan_tray_index
self.is_psu_fan = is_psu_fan
@@ -64,13 +71,10 @@ def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0):
self.fan_e1031_led = "fan{}_led"
self.fan_e1031_led_col_map = {
self.STATUS_LED_COLOR_GREEN: "green",
- self.STATUS_LED_COLOR_RED: "amber",
+ self.STATUS_LED_COLOR_AMBER: "amber",
self.STATUS_LED_COLOR_OFF: "off"
}
- self._api_common = Common()
- FanBase.__init__(self)
-
def __search_file_by_name(self, directory, file_name):
for dirpath, dirnames, files in os.walk(directory):
for name in files:
@@ -141,19 +145,26 @@ def get_target_speed(self):
0 : when PWM mode is use
pwm : when pwm mode is not use
"""
- target = 0
+ target = NULL_VAL
if not self.is_psu_fan:
chip = self.emc2305_chip_mapping[self.fan_index]
device = chip['device']
fan_index = chip['index_map']
- sysfs_path = "%s%s/%s" % (
- EMC2305_PATH, device, EMC2305_FAN_TARGET)
- sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
- raw = self._api_common.read_txt_file(sysfs_path).strip('\r\n')
+
+ enable_path = "%s%s/%s" % (
+ EMC2305_PATH, device, EMC2305_FAN_PWM_MODE)
+ enable = self._api_common.read_txt_file(
+ enable_path.format(fan_index[self.fan_tray_index]))
+
+ target_mode = EMC2305_FAN_TARGET if enable != "0" else EMC2305_FAN_PWM
+ target_path = "%s%s/%s" % (EMC2305_PATH, device,
+ target_mode.format(fan_index[self.fan_tray_index]))
+
+ raw = self._api_common.read_txt_file(target_path)
pwm = int(raw, 10) if raw else 0
target = math.ceil(float(pwm) * 100 / EMC2305_MAX_PWM)
- return target
+ return int(target)
def get_speed_tolerance(self):
"""
@@ -162,7 +173,7 @@ def get_speed_tolerance(self):
An integer, the percentage of variance from target speed which is
considered tolerable
"""
- return 10
+ return FAN_SPEED_TOLERANCE
def set_speed(self, speed):
"""
@@ -211,6 +222,28 @@ def set_status_led(self, color):
return set_status_led
+ def get_status_led(self):
+ """
+ Gets the state of the fan status LED
+ Returns:
+ A string, one of the predefined STATUS_LED_COLOR_* strings above
+ """
+ led = self.STATUS_LED_COLOR_GREEN
+ if not self.is_psu_fan:
+ fan_led_file = (FAN_PATH +
+ self.fan_e1031_led.format(self.fan_tray_index+1))
+
+ led = self._api_common.read_txt_file(fan_led_file)
+ return {
+ 'green': self.STATUS_LED_COLOR_GREEN,
+ 'off': self.STATUS_LED_COLOR_OFF,
+ 'amber': self.STATUS_LED_COLOR_AMBER
+ }.get(led, self.STATUS_LED_COLOR_OFF)
+
+ ##############################################################
+ ###################### Device methods ########################
+ ##############################################################
+
def get_name(self):
"""
Retrieves the name of the device
@@ -240,11 +273,7 @@ def get_model(self):
Returns:
string: Model/part number of device
"""
- if self.is_psu_fan:
- return NULL_VAL
-
- model = NULL_VAL
- return model
+ return NULL_VAL
def get_serial(self):
"""
@@ -252,11 +281,7 @@ def get_serial(self):
Returns:
string: Serial number of device
"""
- if self.is_psu_fan:
- return NULL_VAL
-
- serial = NULL_VAL
- return serial
+ return NULL_VAL
def get_status(self):
"""
@@ -269,7 +294,7 @@ def get_status(self):
fan_fault_sysfs_name = "fan1_fault"
fan_fault_sysfs_path = self.__search_file_by_name(
self.psu_hwmon_path, fan_fault_sysfs_name)
- status = self._api_common.read_txt_file(fan_fault_sysfs_path)
+ status = self._api_common.read_one_line_file(fan_fault_sysfs_path)
elif self.get_presence():
chip = self.emc2305_chip_mapping[self.fan_index]
@@ -278,7 +303,27 @@ def get_status(self):
sysfs_path = "%s%s/%s" % (
EMC2305_PATH, device, 'fan{}_fault')
sysfs_path = sysfs_path.format(fan_index[self.fan_tray_index])
- status = self._api_common.read_txt_file(sysfs_path)
+ status = self._api_common.read_one_line_file(sysfs_path)
return False if int(status) != 0 else True
+ def get_position_in_parent(self):
+ """
+ Retrieves 1-based relative physical position in parent device.
+ If the agent cannot determine the parent-relative position
+ for some reason, or if the associated value of
+ entPhysicalContainedIn is'0', then the value '-1' is returned
+ Returns:
+ integer: The 1-based relative physical position in parent device
+ or -1 if cannot determine the position
+ """
+ return (self.fan_tray_index*2 + self.fan_index + 1) \
+ if not self.is_psu_fan else (self.fan_index+1)
+
+ def is_replaceable(self):
+ """
+ Indicate whether this device is replaceable.
+ Returns:
+ bool: True if it is replaceable.
+ """
+ return True if not self.is_psu_fan else False
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan_drawer.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan_drawer.py
new file mode 100644
index 000000000000..fe12b0ab101e
--- /dev/null
+++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan_drawer.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+
+#############################################################################
+# Celestica
+#
+# Module contains an implementation of SONiC Platform Base API and
+# provides the the Fan-Drawers' information available in the platform
+#
+#############################################################################
+
+try:
+ from sonic_platform_base.fan_drawer_base import FanDrawerBase
+except ImportError as e:
+ raise ImportError(str(e) + "- required module not found")
+
+NUM_FAN = 1
+
+
+class FanDrawer(FanDrawerBase):
+ def __init__(self, fantray_index):
+ FanDrawerBase.__init__(self)
+ self._index = fantray_index + 1
+ self._init_fan(fantray_index)
+
+ def _init_fan(self, fantray_index):
+ from sonic_platform.fan import Fan
+ for index in range(NUM_FAN):
+ fan = Fan(fantray_index, index)
+ self._fan_list.append(fan)
+
+ def set_status_led(self, color):
+ """
+ Sets the state of the fan drawer status LED
+ Args:
+ color: A string representing the color with which to set the
+ fan drawer status LED
+ Returns:
+ bool: True if status LED state is set successfully, False if not
+ """
+ return self._fan_list[0].set_status_led(color)
+
+ def get_status_led(self, color=None):
+ """
+ Gets the state of the fan drawer LED
+ Returns:
+ A string, one of the predefined STATUS_LED_COLOR_* strings above
+ """
+ return self._fan_list[0].get_status_led()
+
+ ##############################################################
+ ###################### Device methods ########################
+ ##############################################################
+
+ def get_name(self):
+ """
+ Retrieves the name of the device
+ Returns:
+ string: The name of the device
+ """
+ return "Drawer{}".format(self._index)
+
+ def get_presence(self):
+ """
+ Retrieves the presence of the device
+ Returns:
+ bool: True if device is present, False if not
+ """
+ return self._fan_list[0].get_presence()
+
+ def get_model(self):
+ """
+ Retrieves the model number (or part number) of the device
+ Returns:
+ string: Model/part number of device
+ """
+ return self._fan_list[0].get_model()
+
+ def get_serial(self):
+ """
+ Retrieves the serial number of the device
+ Returns:
+ string: Serial number of device
+ """
+ return self._fan_list[0].get_serial()
+
+ def get_status(self):
+ """
+ Retrieves the operational status of the device
+ Returns:
+ A boolean value, True if device is operating properly, False if not
+ """
+ return self._fan_list[0].get_status()
+
+ def get_position_in_parent(self):
+ """
+ Retrieves 1-based relative physical position in parent device
+ Returns:
+ integer: The 1-based relative physical position in parent device
+ """
+ return self._index
+
+ def is_replaceable(self):
+ """
+ Indicate whether this device is replaceable.
+ Returns:
+ bool: True if it is replaceable.
+ """
+ return True
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/helper.py
deleted file mode 100644
index 75449ab55185..000000000000
--- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/helper.py
+++ /dev/null
@@ -1,133 +0,0 @@
-import os
-import struct
-import subprocess
-from mmap import *
-
-from sonic_py_common import device_info
-
-HOST_CHK_CMD = "docker > /dev/null 2>&1"
-EMPTY_STRING = ""
-
-
-class APIHelper():
-
- def __init__(self):
- (self.platform, self.hwsku) = device_info.get_platform_and_hwsku()
-
- def is_host(self):
- return os.system(HOST_CHK_CMD) == 0
-
- def pci_get_value(self, resource, offset):
- status = True
- result = ""
- try:
- fd = os.open(resource, os.O_RDWR)
- mm = mmap(fd, 0)
- mm.seek(int(offset))
- read_data_stream = mm.read(4)
- result = struct.unpack('I', read_data_stream)
- except Exception:
- status = False
- return status, result
-
- def run_command(self, cmd):
- status = True
- result = ""
- try:
- p = subprocess.Popen(
- cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- raw_data, err = p.communicate()
- if err == '':
- result = raw_data.strip()
- except Exception:
- status = False
- return status, result
-
- def run_interactive_command(self, cmd):
- try:
- os.system(cmd)
- except Exception:
- return False
- return True
-
- def read_txt_file(self, file_path):
- try:
- with open(file_path, 'r') as fd:
- data = fd.read()
- return data.strip()
- except IOError:
- pass
- return None
-
- def read_one_line_file(self, file_path):
- try:
- with open(file_path, 'r') as fd:
- data = fd.readline()
- return data.strip()
- except IOError:
- pass
- return None
-
- def write_txt_file(self, file_path, value):
- try:
- with open(file_path, 'w') as fd:
- fd.write(str(value))
- except Exception:
- return False
- return True
-
- def get_cpld_reg_value(self, getreg_path, register):
- cmd = "echo {1} > {0}; cat {0}".format(getreg_path, register)
- status, result = self.run_command(cmd)
- return result if status else None
-
- def ipmi_raw(self, netfn, cmd):
- status = True
- result = ""
- try:
- cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd))
- p = subprocess.Popen(
- cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- raw_data, err = p.communicate()
- if err == '':
- result = raw_data.strip()
- else:
- status = False
- except Exception:
- status = False
- return status, result
-
- def ipmi_fru_id(self, id, key=None):
- status = True
- result = ""
- try:
- cmd = "ipmitool fru print {}".format(str(
- id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key))
-
- p = subprocess.Popen(
- cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- raw_data, err = p.communicate()
- if err == '':
- result = raw_data.strip()
- else:
- status = False
- except Exception:
- status = False
- return status, result
-
- def ipmi_set_ss_thres(self, id, threshold_key, value):
- status = True
- result = ""
- try:
- cmd = "ipmitool sensor thresh '{}' {} {}".format(
- str(id), str(threshold_key), str(value))
- p = subprocess.Popen(
- cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- raw_data, err = p.communicate()
- if err == '':
- result = raw_data.strip()
- else:
- status = False
- except Exception:
- status = False
- return status, result
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py
index ccc63c8ac9ae..136010802233 100644
--- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py
+++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/psu.py
@@ -11,10 +11,13 @@
try:
from sonic_platform_base.psu_base import PsuBase
from sonic_platform.fan import Fan
+ from .common import Common
+ from .eeprom import DeviceEEPROM
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
FAN_E1031_SPEED_PATH = "/sys/class/hwmon/hwmon{}/fan1_input"
+PSU_E1031_STAT_PATH = "/sys/devices/platform/e1031.smc/"
HWMON_PATH = "/sys/bus/i2c/devices/i2c-{0}/{0}-00{1}/hwmon"
FAN_MAX_RPM = 11000
PSU_NAME_LIST = ["PSU-R", "PSU-L"]
@@ -22,13 +25,22 @@
PSU_I2C_MAPPING = {
0: {
"num": 13,
- "addr": "5b"
+ "addr": "5b",
+ "eeprom_addr": "53"
},
1: {
"num": 12,
- "addr": "5a"
+ "addr": "5a",
+ "eeprom_addr": "52"
},
}
+PSU_EEPROM_PATH = "/sys/bus/i2c/devices/{}-00{}/eeprom"
+PSU_EEPROM_FORMAT = [
+ ('Serial Number', 's', 16), ('burn', 'x', 16),
+ ('Model', 's', 16),
+ ('Part Number', 's', 16),
+]
+PSU_EEPROM_START_OFFSET = 48
class Psu(PsuBase):
@@ -36,32 +48,26 @@ class Psu(PsuBase):
def __init__(self, psu_index):
PsuBase.__init__(self)
+
+ self._api_common = Common()
self.index = psu_index
- self.psu_path = "/sys/devices/platform/e1031.smc/"
self.psu_presence = "psu{}_prs"
self.psu_oper_status = "psu{}_status"
self.i2c_num = PSU_I2C_MAPPING[self.index]["num"]
self.i2c_addr = PSU_I2C_MAPPING[self.index]["addr"]
self.hwmon_path = HWMON_PATH.format(self.i2c_num, self.i2c_addr)
+ self.eeprom_addr = PSU_EEPROM_PATH.format(
+ self.i2c_num, PSU_I2C_MAPPING[self.index]["eeprom_addr"])
+
for fan_index in range(0, PSU_NUM_FAN[self.index]):
fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index)
self._fan_list.append(fan)
- PsuBase.__init__(self)
- def __read_txt_file(self, file_path):
- try:
- with open(file_path, 'r') as fd:
- data = fd.read()
- return data.strip()
- except IOError:
- pass
- return ""
-
- def __search_file_by_contain(self, directory, search_str, file_start):
+ def _search_file_by_contain(self, directory, search_str, file_start):
for dirpath, dirnames, files in os.walk(directory):
for name in files:
file_path = os.path.join(dirpath, name)
- if name.startswith(file_start) and search_str in self.__read_txt_file(file_path):
+ if name.startswith(file_start) and search_str in self._api_common.read_txt_file(file_path):
return file_path
return None
@@ -76,7 +82,7 @@ def get_voltage(self):
voltage_name = "in{}_input"
voltage_label = "vout1"
- vout_label_path = self.__search_file_by_contain(
+ vout_label_path = self._search_file_by_contain(
self.hwmon_path, voltage_label, "in")
if vout_label_path:
dir_name = os.path.dirname(vout_label_path)
@@ -84,7 +90,7 @@ def get_voltage(self):
in_num = ''.join(list(filter(str.isdigit, basename)))
vout_path = os.path.join(
dir_name, voltage_name.format(in_num))
- vout_val = self.__read_txt_file(vout_path)
+ vout_val = self._api_common.read_txt_file(vout_path)
psu_voltage = float(vout_val) / 1000
return psu_voltage
@@ -99,7 +105,7 @@ def get_current(self):
current_name = "curr{}_input"
current_label = "iout1"
- curr_label_path = self.__search_file_by_contain(
+ curr_label_path = self._search_file_by_contain(
self.hwmon_path, current_label, "cur")
if curr_label_path:
dir_name = os.path.dirname(curr_label_path)
@@ -107,7 +113,7 @@ def get_current(self):
cur_num = ''.join(list(filter(str.isdigit, basename)))
cur_path = os.path.join(
dir_name, current_name.format(cur_num))
- cur_val = self.__read_txt_file(cur_path)
+ cur_val = self._api_common.read_txt_file(cur_path)
psu_current = float(cur_val) / 1000
return psu_current
@@ -122,7 +128,7 @@ def get_power(self):
current_name = "power{}_input"
current_label = "pout1"
- pw_label_path = self.__search_file_by_contain(
+ pw_label_path = self._search_file_by_contain(
self.hwmon_path, current_label, "power")
if pw_label_path:
dir_name = os.path.dirname(pw_label_path)
@@ -130,7 +136,7 @@ def get_power(self):
pw_num = ''.join(list(filter(str.isdigit, basename)))
pw_path = os.path.join(
dir_name, current_name.format(pw_num))
- pw_val = self.__read_txt_file(pw_path)
+ pw_val = self._api_common.read_txt_file(pw_path)
psu_power = float(pw_val) / 1000000
return psu_power
@@ -165,6 +171,10 @@ def get_status_led(self):
# Hardware not supported
return self.STATUS_LED_COLOR_OFF
+ ##############################################################
+ ###################### Device methods ########################
+ ##############################################################
+
def get_name(self):
"""
Retrieves the name of the device
@@ -180,8 +190,8 @@ def get_presence(self):
bool: True if PSU is present, False if not
"""
psu_location = ["R", "L"]
- presences_status = self.__read_txt_file(
- self.psu_path + self.psu_presence.format(psu_location[self.index])) or 0
+ presences_status = self._api_common.read_txt_file(
+ PSU_E1031_STAT_PATH + self.psu_presence.format(psu_location[self.index])) or 0
return int(presences_status) == 1
@@ -192,7 +202,153 @@ def get_status(self):
A boolean value, True if device is operating properly, False if not
"""
psu_location = ["R", "L"]
- power_status = self.__read_txt_file(
- self.psu_path + self.psu_oper_status.format(psu_location[self.index])) or 0
+ power_status = self._api_common.read_txt_file(
+ PSU_E1031_STAT_PATH + self.psu_oper_status.format(psu_location[self.index])) or 0
return int(power_status) == 1
+
+ def get_model(self):
+ """
+ Retrieves the model number (or part number) of the device
+ Returns:
+ string: Model/part number of device
+ """
+ self._eeprom = DeviceEEPROM(
+ self.eeprom_addr, PSU_EEPROM_FORMAT, PSU_EEPROM_START_OFFSET)
+ return self._eeprom.model_str
+
+ def get_serial(self):
+ """
+ Retrieves the serial number of the device
+ Returns:
+ string: Serial number of device
+ """
+ self._eeprom = DeviceEEPROM(
+ self.eeprom_addr, PSU_EEPROM_FORMAT, PSU_EEPROM_START_OFFSET)
+ return self._eeprom.serial_number
+
+ def get_position_in_parent(self):
+ """
+ Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position
+ for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned
+ Returns:
+ integer: The 1-based relative physical position in parent device or -1 if cannot determine the position
+ """
+ return -1
+
+ def is_replaceable(self):
+ """
+ Indicate whether this device is replaceable.
+ Returns:
+ bool: True if it is replaceable.
+ """
+ return True
+
+ def get_temperature(self):
+ """
+ Retrieves current temperature reading from PSU
+ Returns:
+ A float number of current temperature in Celsius up to nearest thousandth
+ of one degree Celsius, e.g. 30.125
+ there are three temp sensors , we choose one of them
+ """
+ psu_temperature = None
+ temperature_name = "temp{}_input"
+ temperature_label = "vout1"
+
+ vout_label_path = self._search_file_by_contain(
+ self.hwmon_path, temperature_label, "in")
+ if vout_label_path:
+ dir_name = os.path.dirname(vout_label_path)
+ basename = os.path.basename(vout_label_path)
+ in_num = ''.join(list(filter(str.isdigit, basename)))
+ temp_path = os.path.join(
+ dir_name, temperature_name.format(in_num))
+ vout_val = self._api_common.read_txt_file(temp_path)
+ psu_temperature = float(vout_val) / 1000
+
+ return psu_temperature
+
+ def get_temperature_high_threshold(self):
+ """
+ Retrieves the high threshold temperature of PSU
+ Returns:
+ A float number, the high threshold temperature of PSU in Celsius
+ up to nearest thousandth of one degree Celsius, e.g. 30.125
+ there are three temp sensors , we choose one of them
+ """
+ psu_temperature = None
+ temperature_name = "temp{}_max"
+ temperature_label = "vout1"
+
+ vout_label_path = self._search_file_by_contain(
+ self.hwmon_path, temperature_label, "in")
+ if vout_label_path:
+ dir_name = os.path.dirname(vout_label_path)
+ basename = os.path.basename(vout_label_path)
+ in_num = ''.join(list(filter(str.isdigit, basename)))
+ temp_path = os.path.join(
+ dir_name, temperature_name.format(in_num))
+ vout_val = self._api_common.read_txt_file(temp_path)
+ psu_temperature = float(vout_val) / 1000
+
+ return psu_temperature
+
+ def get_voltage_high_threshold(self):
+ """
+ Retrieves the high threshold PSU voltage output
+ Returns:
+ A float number, the high threshold output voltage in volts,
+ e.g. 12.1
+ """
+ psu_voltage = 12.6
+ voltage_name = "in{}_crit"
+ voltage_label = "vout1"
+
+ vout_label_path = self._search_file_by_contain(
+ self.hwmon_path, voltage_label, "in")
+ if vout_label_path:
+ dir_name = os.path.dirname(vout_label_path)
+ basename = os.path.basename(vout_label_path)
+ in_num = ''.join(list(filter(str.isdigit, basename)))
+ vout_path = os.path.join(
+ dir_name, voltage_name.format(in_num))
+ if os.path.exists(vout_path):
+ vout_val = self._api_common.read_txt_file(vout_path)
+ psu_voltage = float(vout_val) / 1000
+
+ return psu_voltage
+
+ def get_voltage_low_threshold(self):
+ """
+ Retrieves the low threshold PSU voltage output
+ Returns:
+ A float number, the low threshold output voltage in volts,
+ e.g. 12.1
+ """
+ psu_voltage = 11.4
+ voltage_name = "in{}_lcrit"
+ voltage_label = "vout1"
+
+ vout_label_path = self._search_file_by_contain(
+ self.hwmon_path, voltage_label, "in")
+ if vout_label_path:
+ dir_name = os.path.dirname(vout_label_path)
+ basename = os.path.basename(vout_label_path)
+ in_num = ''.join(list(filter(str.isdigit, basename)))
+ vout_path = os.path.join(
+ dir_name, voltage_name.format(in_num))
+ if os.path.exists(vout_path):
+ vout_val = self._api_common.read_txt_file(vout_path)
+ psu_voltage = float(vout_val) / 1000
+
+ return psu_voltage
+
+ def get_maximum_supplied_power(self):
+ """
+ Retrieves the maximum supplied power by PSU
+ Returns:
+ A float number, the maximum power output in Watts.
+ e.g. 1200.1
+ """
+ return 200.0
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py
index 91e5fec65ffc..157b06de1caf 100644
--- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py
+++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/sfp.py
@@ -6,23 +6,44 @@
#
#############################################################################
-import os
-import time
-from ctypes import create_string_buffer
-
try:
+ import time
+ from ctypes import create_string_buffer
from sonic_platform_base.sfp_base import SfpBase
- from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId
+ from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom
from sonic_platform_base.sonic_sfp.sff8472 import sffbase
+ from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId
+ from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom
+ from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId
+ from .common import Common
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
-INFO_OFFSET = 0
-DOM_OFFSET = 256
+INFO_OFFSET = 128
+DOM_OFFSET = 0
+# definitions of the offset and width for values in XCVR info eeprom
XCVR_INTFACE_BULK_OFFSET = 0
+XCVR_INTFACE_BULK_WIDTH_QSFP = 20
XCVR_INTFACE_BULK_WIDTH_SFP = 21
+XCVR_TYPE_OFFSET = 0
+XCVR_TYPE_WIDTH = 1
+XCVR_EXT_TYPE_OFFSET = 1
+XCVR_EXT_TYPE_WIDTH = 1
+XCVR_CONNECTOR_OFFSET = 2
+XCVR_CONNECTOR_WIDTH = 1
+XCVR_COMPLIANCE_CODE_OFFSET = 3
+XCVR_COMPLIANCE_CODE_WIDTH = 8
+XCVR_ENCODING_OFFSET = 11
+XCVR_ENCODING_WIDTH = 1
+XCVR_NBR_OFFSET = 12
+XCVR_NBR_WIDTH = 1
+XCVR_EXT_RATE_SEL_OFFSET = 13
+XCVR_EXT_RATE_SEL_WIDTH = 1
+XCVR_CABLE_LENGTH_OFFSET = 14
+XCVR_CABLE_LENGTH_WIDTH_QSFP = 5
+XCVR_CABLE_LENGTH_WIDTH_SFP = 6
XCVR_VENDOR_NAME_OFFSET = 20
XCVR_VENDOR_NAME_WIDTH = 16
XCVR_VENDOR_OUI_OFFSET = 37
@@ -30,30 +51,86 @@
XCVR_VENDOR_PN_OFFSET = 40
XCVR_VENDOR_PN_WIDTH = 16
XCVR_HW_REV_OFFSET = 56
+XCVR_HW_REV_WIDTH_OSFP = 2
+XCVR_HW_REV_WIDTH_QSFP = 2
XCVR_HW_REV_WIDTH_SFP = 4
XCVR_VENDOR_SN_OFFSET = 68
XCVR_VENDOR_SN_WIDTH = 16
XCVR_VENDOR_DATE_OFFSET = 84
XCVR_VENDOR_DATE_WIDTH = 8
XCVR_DOM_CAPABILITY_OFFSET = 92
-XCVR_DOM_CAPABILITY_WIDTH = 1
+XCVR_DOM_CAPABILITY_WIDTH = 2
+
+XCVR_INTERFACE_DATA_START = 0
+XCVR_INTERFACE_DATA_SIZE = 92
+
+QSFP_DOM_BULK_DATA_START = 22
+QSFP_DOM_BULK_DATA_SIZE = 36
+SFP_DOM_BULK_DATA_START = 96
+SFP_DOM_BULK_DATA_SIZE = 10
+
+# definitions of the offset for values in OSFP info eeprom
+OSFP_TYPE_OFFSET = 0
+OSFP_VENDOR_NAME_OFFSET = 129
+OSFP_VENDOR_PN_OFFSET = 148
+OSFP_HW_REV_OFFSET = 164
+OSFP_VENDOR_SN_OFFSET = 166
+
+# Offset for values in QSFP eeprom
+QSFP_DOM_REV_OFFSET = 1
+QSFP_DOM_REV_WIDTH = 1
+QSFP_TEMPE_OFFSET = 22
+QSFP_TEMPE_WIDTH = 2
+QSFP_VOLT_OFFSET = 26
+QSFP_VOLT_WIDTH = 2
+QSFP_VERSION_COMPLIANCE_OFFSET = 1
+QSFP_VERSION_COMPLIANCE_WIDTH = 2
+QSFP_CHANNL_MON_OFFSET = 34
+QSFP_CHANNL_MON_WIDTH = 16
+QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24
+QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86
+QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1
+QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3
+QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1
+QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4
+QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1
+QSFP_CONTROL_OFFSET = 86
+QSFP_CONTROL_WIDTH = 8
+QSFP_MODULE_MONITOR_OFFSET = 0
+QSFP_MODULE_MONITOR_WIDTH = 9
+QSFP_POWEROVERRIDE_OFFSET = 93
+QSFP_POWEROVERRIDE_WIDTH = 1
+QSFP_POWEROVERRIDE_BIT = 0
+QSFP_POWERSET_BIT = 1
+QSFP_OPTION_VALUE_OFFSET = 192
+QSFP_OPTION_VALUE_WIDTH = 4
+QSFP_MODULE_UPPER_PAGE3_START = 384
+QSFP_MODULE_THRESHOLD_OFFSET = 128
+QSFP_MODULE_THRESHOLD_WIDTH = 24
+QSFP_CHANNL_THRESHOLD_OFFSET = 176
+QSFP_CHANNL_THRESHOLD_WIDTH = 24
+
+SFP_MODULE_ADDRA2_OFFSET = 256
+SFP_MODULE_THRESHOLD_OFFSET = 0
+SFP_MODULE_THRESHOLD_WIDTH = 56
+SFP_CHANNL_THRESHOLD_OFFSET = 112
+SFP_CHANNL_THRESHOLD_WIDTH = 2
-# Offset for values in SFP eeprom
SFP_TEMPE_OFFSET = 96
SFP_TEMPE_WIDTH = 2
SFP_VOLT_OFFSET = 98
SFP_VOLT_WIDTH = 2
SFP_CHANNL_MON_OFFSET = 100
SFP_CHANNL_MON_WIDTH = 6
-SFP_MODULE_THRESHOLD_OFFSET = 0
-SFP_MODULE_THRESHOLD_WIDTH = 40
-SFP_CHANNL_THRESHOLD_OFFSET = 112
-SFP_CHANNL_THRESHOLD_WIDTH = 2
-SFP_STATUS_CONTROL_OFFSET = 110
-SFP_STATUS_CONTROL_WIDTH = 1
+SFP_CHANNL_STATUS_OFFSET = 110
+SFP_CHANNL_STATUS_WIDTH = 1
SFP_TX_DISABLE_HARD_BIT = 7
SFP_TX_DISABLE_SOFT_BIT = 6
+qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)',
+ 'Length OM2(m)', 'Length OM1(m)',
+ 'Length Cable Assembly(m)')
+
sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)',
'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)',
'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)')
@@ -64,44 +141,63 @@
'FibreChannelTechnology', 'SFP+CableTechnology',
'FibreChannelTransmissionMedia', 'FibreChannelSpeed')
+qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes',
+ 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes',
+ 'Fibre Channel link length/Transmitter Technology',
+ 'Fibre Channel transmission media', 'Fibre Channel Speed')
+
+SFP_TYPE = "SFP"
+QSFP_TYPE = "QSFP"
+OSFP_TYPE = "OSFP"
+ETP_TYPE = "ETP"
+
+SFP_PORT_START = 49
+SFP_PORT_END = 52
+
+PORT_START = 1
+PORT_END = 55
+
class Sfp(SfpBase):
"""Platform-specific Sfp class"""
- # Port number
- PORT_START = 1
- PORT_END = 52
+ # Port I2C number
port_to_i2c_mapping = {
49: 15,
50: 14,
51: 17,
52: 16
}
- _sfp_port = list(range(49, PORT_END + 1))
- PRS_PATH = "/sys/devices/platform/e1031.smc/SFP/sfp_modabs"
- PLATFORM_ROOT_PATH = '/usr/share/sonic/device'
- PMON_HWSKU_PATH = '/usr/share/sonic/hwsku'
- HOST_CHK_CMD = "docker > /dev/null 2>&1"
+ _sfp_port = list(range(SFP_PORT_START, SFP_PORT_END + 1))
- PLATFORM = "x86_64-cel_e1031-r0"
- HWSKU = "Celestica-E1031-T48S4"
+ PRS_PATH = "/sys/devices/platform/e1031.smc/SFP/sfp_modabs"
def __init__(self, sfp_index, sfp_name):
+ SfpBase.__init__(self)
+
+ # Init common function
+ self._api_common = Common()
+
# Init index
self.index = sfp_index
self.port_num = self.index + 1
+ # Init sfp data
+ self.sfp_type = self.__get_sfp_type()
+ self.name = sfp_name
+
# Init eeprom path
eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'
self.port_to_eeprom_mapping = {}
- for x in range(self.PORT_START, self.PORT_END + 1):
+ for x in range(PORT_START, PORT_END + 1):
if x not in self._sfp_port:
self.port_to_i2c_mapping[x] = None
self.port_to_eeprom_mapping[x] = eeprom_path.format(
self.port_to_i2c_mapping[x])
self.info_dict_keys = ['type', 'hardware_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier',
- 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui']
+ 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance',
+ 'vendor_date', 'vendor_oui', "application_advertisement", "type_abbrv_name"]
self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage',
'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power']
@@ -109,10 +205,12 @@ def __init__(self, sfp_index, sfp_name):
self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning',
'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning']
- self.name = sfp_name
- SfpBase.__init__(self)
+ self._dom_capability_detect()
- def _convert_string_to_num(self, value_str):
+ def __get_sfp_type(self):
+ return SFP_TYPE if self.port_num in self._sfp_port else ETP_TYPE
+
+ def __convert_string_to_num(self, value_str):
if "-inf" in value_str:
return 'N/A'
elif "Unknown" in value_str:
@@ -132,18 +230,6 @@ def _convert_string_to_num(self, value_str):
else:
return 'N/A'
- def __read_txt_file(self, file_path):
- try:
- with open(file_path, 'r') as fd:
- data = fd.read()
- return data.strip()
- except IOError:
- pass
- return ""
-
- def __is_host(self):
- return os.system(self.HOST_CHK_CMD) == 0
-
def __read_eeprom_specific_bytes(self, offset, num_bytes):
sysfsfile_eeprom = None
eeprom_raw = []
@@ -156,9 +242,13 @@ def __read_eeprom_specific_bytes(self, offset, num_bytes):
sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0)
sysfsfile_eeprom.seek(offset)
raw = sysfsfile_eeprom.read(num_bytes)
- for n in range(0, num_bytes):
- eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
- except Exception:
+ if isinstance(raw, str):
+ for n in range(0, num_bytes):
+ eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2)
+ else:
+ for n in range(0, num_bytes):
+ eeprom_raw[n] = hex(raw[n])[2:].zfill(2)
+ except BaseException:
pass
finally:
if sysfsfile_eeprom:
@@ -166,6 +256,106 @@ def __read_eeprom_specific_bytes(self, offset, num_bytes):
return eeprom_raw
+ def _dom_capability_detect(self):
+ if not self.get_presence():
+ self.dom_supported = False
+ self.dom_temp_supported = False
+ self.dom_volt_supported = False
+ self.dom_rx_power_supported = False
+ self.dom_tx_power_supported = False
+ self.calibration = 0
+ return
+
+ if self.sfp_type == "QSFP":
+ self.calibration = 1
+ sfpi_obj = sff8436InterfaceId()
+ if sfpi_obj is None:
+ self.dom_supported = False
+ offset = 128
+
+ # QSFP capability byte parse, through this byte can know whether it support tx_power or not.
+ # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436,
+ # need to add more code for determining the capability and version compliance
+ # in SFF-8636 dom capability definitions evolving with the versions.
+ qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes(
+ (offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH)
+ if qsfp_dom_capability_raw is not None:
+ qsfp_version_compliance_raw = self.__read_eeprom_specific_bytes(
+ QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH)
+ qsfp_version_compliance = int(
+ qsfp_version_compliance_raw[0], 16)
+ dom_capability = sfpi_obj.parse_dom_capability(
+ qsfp_dom_capability_raw, 0)
+ if qsfp_version_compliance >= 0x08:
+ self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On'
+ self.dom_volt_supported = dom_capability['data']['Voltage_support']['value'] == 'On'
+ self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On'
+ self.dom_tx_power_supported = dom_capability['data']['Tx_power_support']['value'] == 'On'
+ else:
+ self.dom_temp_supported = True
+ self.dom_volt_supported = True
+ self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On'
+ self.dom_tx_power_supported = True
+
+ self.dom_supported = True
+ self.calibration = 1
+ sfpd_obj = sff8436Dom()
+ if sfpd_obj is None:
+ return None
+ qsfp_option_value_raw = self.__read_eeprom_specific_bytes(
+ QSFP_OPTION_VALUE_OFFSET, QSFP_OPTION_VALUE_WIDTH)
+ if qsfp_option_value_raw is not None:
+ optional_capability = sfpd_obj.parse_option_params(
+ qsfp_option_value_raw, 0)
+ self.dom_tx_disable_supported = optional_capability[
+ 'data']['TxDisable']['value'] == 'On'
+ dom_status_indicator = sfpd_obj.parse_dom_status_indicator(
+ qsfp_version_compliance_raw, 1)
+ self.qsfp_page3_available = dom_status_indicator['data']['FlatMem']['value'] == 'Off'
+ else:
+ self.dom_supported = False
+ self.dom_temp_supported = False
+ self.dom_volt_supported = False
+ self.dom_rx_power_supported = False
+ self.dom_tx_power_supported = False
+ self.calibration = 0
+ self.qsfp_page3_available = False
+
+ elif self.sfp_type == "SFP":
+ sfpi_obj = sff8472InterfaceId()
+ if sfpi_obj is None:
+ return None
+ sfp_dom_capability_raw = self.__read_eeprom_specific_bytes(
+ XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH)
+ if sfp_dom_capability_raw is not None:
+ sfp_dom_capability = int(sfp_dom_capability_raw[0], 16)
+ self.dom_supported = (sfp_dom_capability & 0x40 != 0)
+ if self.dom_supported:
+ self.dom_temp_supported = True
+ self.dom_volt_supported = True
+ self.dom_rx_power_supported = True
+ self.dom_tx_power_supported = True
+ if sfp_dom_capability & 0x20 != 0:
+ self.calibration = 1
+ elif sfp_dom_capability & 0x10 != 0:
+ self.calibration = 2
+ else:
+ self.calibration = 0
+ else:
+ self.dom_temp_supported = False
+ self.dom_volt_supported = False
+ self.dom_rx_power_supported = False
+ self.dom_tx_power_supported = False
+ self.calibration = 0
+ self.dom_tx_disable_supported = (
+ int(sfp_dom_capability_raw[1], 16) & 0x40 != 0)
+ else:
+ self.dom_supported = False
+ self.dom_temp_supported = False
+ self.dom_volt_supported = False
+ self.dom_rx_power_supported = False
+ self.dom_tx_power_supported = False
+
def get_transceiver_info(self):
"""
Retrieves transceiver info of this SFP
@@ -189,85 +379,183 @@ def get_transceiver_info(self):
vendor_date |1*255VCHAR |vendor date
vendor_oui |1*255VCHAR |vendor OUI
========================================================================
- """
- # check present status
- sfpi_obj = sff8472InterfaceId()
- if not self.get_presence() or not sfpi_obj:
- return {}
-
- offset = INFO_OFFSET
-
- sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes(
- (offset + XCVR_INTFACE_BULK_OFFSET), XCVR_INTFACE_BULK_WIDTH_SFP)
- sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(
- sfp_interface_bulk_raw, 0)
-
- sfp_vendor_name_raw = self.__read_eeprom_specific_bytes(
- (offset + XCVR_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
- sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
- sfp_vendor_name_raw, 0)
-
- sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes(
- (offset + XCVR_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
- sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(
- sfp_vendor_pn_raw, 0)
-
- sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes(
- (offset + XCVR_HW_REV_OFFSET), XCVR_HW_REV_WIDTH_SFP)
- sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(
- sfp_vendor_rev_raw, 0)
-
- sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes(
- (offset + XCVR_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
- sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(
- sfp_vendor_sn_raw, 0)
-
- sfp_vendor_oui_raw = self.__read_eeprom_specific_bytes(
- (offset + XCVR_VENDOR_OUI_OFFSET), XCVR_VENDOR_OUI_WIDTH)
- if sfp_vendor_oui_raw is not None:
- sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(
- sfp_vendor_oui_raw, 0)
-
- sfp_vendor_date_raw = self.__read_eeprom_specific_bytes(
- (offset + XCVR_VENDOR_DATE_OFFSET), XCVR_VENDOR_DATE_WIDTH)
- sfp_vendor_date_data = sfpi_obj.parse_vendor_date(
- sfp_vendor_date_raw, 0)
-
+ """
+ compliance_code_dict = {}
transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A')
- compliance_code_dict = dict()
+ if not self.get_presence():
+ return transceiver_info_dict
+
+ # ToDo: OSFP tranceiver info parsing not fully supported.
+ # in inf8628.py lack of some memory map definition
+ # will be implemented when the inf8628 memory map ready
+ if self.sfp_type == OSFP_TYPE:
+ offset = 0
+ vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP
+
+ sfpi_obj = inf8628InterfaceId()
+ if sfpi_obj is None:
+ return None
+
+ sfp_type_raw = self.__read_eeprom_specific_bytes(
+ (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH)
+ if sfp_type_raw is not None:
+ sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0)
+ else:
+ return None
+
+ sfp_vendor_name_raw = self.__read_eeprom_specific_bytes(
+ (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH)
+ if sfp_vendor_name_raw is not None:
+ sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
+ sfp_vendor_name_raw, 0)
+ else:
+ return None
+
+ sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes(
+ (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH)
+ if sfp_vendor_pn_raw is not None:
+ sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(
+ sfp_vendor_pn_raw, 0)
+ else:
+ return None
+
+ sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes(
+ (offset + OSFP_HW_REV_OFFSET), vendor_rev_width)
+ if sfp_vendor_rev_raw is not None:
+ sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(
+ sfp_vendor_rev_raw, 0)
+ else:
+ return None
+
+ sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes(
+ (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH)
+ if sfp_vendor_sn_raw is not None:
+ sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(
+ sfp_vendor_sn_raw, 0)
+ else:
+ return None
+
+ transceiver_info_dict['type'] = sfp_type_data['data']['type']['value']
+ transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value']
+ transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value']
+ transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value']
+ transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value']
+ transceiver_info_dict['vendor_oui'] = 'N/A'
+ transceiver_info_dict['vendor_date'] = 'N/A'
+ transceiver_info_dict['connector'] = 'N/A'
+ transceiver_info_dict['encoding'] = 'N/A'
+ transceiver_info_dict['ext_identifier'] = 'N/A'
+ transceiver_info_dict['ext_rateselect_compliance'] = 'N/A'
+ transceiver_info_dict['cable_type'] = 'N/A'
+ transceiver_info_dict['cable_length'] = 'N/A'
+ transceiver_info_dict['specification_compliance'] = '{}'
+ transceiver_info_dict['nominal_bit_rate'] = 'N/A'
- if sfp_interface_bulk_data:
+ else:
+ if self.sfp_type == QSFP_TYPE:
+ offset = 128
+ vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP
+ # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP
+ interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP
+
+ sfpi_obj = sff8436InterfaceId()
+ if sfpi_obj is None:
+ print("Error: sfp_object open failed")
+ return None
+
+ else:
+ offset = 0
+ vendor_rev_width = XCVR_HW_REV_WIDTH_SFP
+ # cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP
+ interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP
+
+ sfpi_obj = sff8472InterfaceId()
+ if sfpi_obj is None:
+ print("Error: sfp_object open failed")
+ return None
+ sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes(
+ offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE)
+ if sfp_interface_bulk_raw is None:
+ return None
+
+ start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START
+ end = start + interface_info_bulk_width
+ sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk(
+ sfp_interface_bulk_raw[start: end], 0)
+
+ start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START
+ end = start + XCVR_VENDOR_NAME_WIDTH
+ sfp_vendor_name_data = sfpi_obj.parse_vendor_name(
+ sfp_interface_bulk_raw[start: end], 0)
+
+ start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START
+ end = start + XCVR_VENDOR_PN_WIDTH
+ sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn(
+ sfp_interface_bulk_raw[start: end], 0)
+
+ start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START
+ end = start + vendor_rev_width
+ sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev(
+ sfp_interface_bulk_raw[start: end], 0)
+
+ start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START
+ end = start + XCVR_VENDOR_SN_WIDTH
+ sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn(
+ sfp_interface_bulk_raw[start: end], 0)
+
+ start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START
+ end = start + XCVR_VENDOR_OUI_WIDTH
+ sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui(
+ sfp_interface_bulk_raw[start: end], 0)
+
+ start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START
+ end = start + XCVR_VENDOR_DATE_WIDTH
+ sfp_vendor_date_data = sfpi_obj.parse_vendor_date(
+ sfp_interface_bulk_raw[start: end], 0)
transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value']
+ transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value']
+ transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value']
+ transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value']
+ transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value']
+ transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value']
+ transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[
+ 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value']
transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value']
transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value']
transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value']
transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value']
transceiver_info_dict['type_abbrv_name'] = sfp_interface_bulk_data['data']['type_abbrv_name']['value']
- transceiver_info_dict['manufacturer'] = sfp_vendor_name_data[
- 'data']['Vendor Name']['value'] if sfp_vendor_name_data else 'N/A'
- transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] if sfp_vendor_pn_data else 'N/A'
- transceiver_info_dict['hardware_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] if sfp_vendor_rev_data else 'N/A'
- transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] if sfp_vendor_sn_data else 'N/A'
- transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] if sfp_vendor_oui_data else 'N/A'
- transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[
- 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] if sfp_vendor_date_data else 'N/A'
- transceiver_info_dict['cable_type'] = "Unknown"
- transceiver_info_dict['cable_length'] = "Unknown"
-
- for key in sfp_cable_length_tup:
- if key in sfp_interface_bulk_data['data']:
- transceiver_info_dict['cable_type'] = key
- transceiver_info_dict['cable_length'] = str(
- sfp_interface_bulk_data['data'][key]['value'])
-
- for key in sfp_compliance_code_tup:
- if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
- compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
- transceiver_info_dict['specification_compliance'] = str(
- compliance_code_dict)
- transceiver_info_dict['nominal_bit_rate'] = str(
- sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
+ if self.sfp_type == QSFP_TYPE:
+ for key in qsfp_cable_length_tup:
+ if key in sfp_interface_bulk_data['data']:
+ transceiver_info_dict['cable_type'] = key
+ transceiver_info_dict['cable_length'] = str(
+ sfp_interface_bulk_data['data'][key]['value'])
+
+ for key in qsfp_compliance_code_tup:
+ if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
+ compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
+ transceiver_info_dict['specification_compliance'] = str(
+ compliance_code_dict)
+
+ transceiver_info_dict['nominal_bit_rate'] = str(
+ sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value'])
+ else:
+ for key in sfp_cable_length_tup:
+ if key in sfp_interface_bulk_data['data']:
+ transceiver_info_dict['cable_type'] = key
+ transceiver_info_dict['cable_length'] = str(
+ sfp_interface_bulk_data['data'][key]['value'])
+
+ for key in sfp_compliance_code_tup:
+ if key in sfp_interface_bulk_data['data']['Specification compliance']['value']:
+ compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value']
+ transceiver_info_dict['specification_compliance'] = str(
+ compliance_code_dict)
+
+ transceiver_info_dict['nominal_bit_rate'] = str(
+ sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value'])
return transceiver_info_dict
@@ -296,44 +584,117 @@ def get_transceiver_bulk_status(self):
| |for example, tx2power stands for tx power of channel 2.
========================================================================
"""
- # check present status
- sfpd_obj = sff8472Dom()
- if not self.get_presence() or not sfpd_obj:
- return {}
+ transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A')
- eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
- sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
- cal_type = sfpi_obj.get_calibration_type()
- sfpd_obj._calibration_type = cal_type
+ if self.sfp_type == OSFP_TYPE:
+ pass
- offset = DOM_OFFSET
- transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A')
- dom_temperature_raw = self.__read_eeprom_specific_bytes(
- (offset + SFP_TEMPE_OFFSET), SFP_TEMPE_WIDTH)
+ elif self.sfp_type == QSFP_TYPE:
+ if not self.dom_supported:
+ return transceiver_dom_info_dict
+
+ offset = 0
+ sfpd_obj = sff8436Dom()
+ if sfpd_obj is None:
+ return transceiver_dom_info_dict
+
+ dom_data_raw = self.__read_eeprom_specific_bytes(
+ (offset + QSFP_DOM_BULK_DATA_START), QSFP_DOM_BULK_DATA_SIZE)
+ if dom_data_raw is None:
+ return transceiver_dom_info_dict
+
+ if self.dom_temp_supported:
+ start = QSFP_TEMPE_OFFSET - QSFP_DOM_BULK_DATA_START
+ end = start + QSFP_TEMPE_WIDTH
+ dom_temperature_data = sfpd_obj.parse_temperature(
+ dom_data_raw[start: end], 0)
+ temp = self.__convert_string_to_num(
+ dom_temperature_data['data']['Temperature']['value'])
+ if temp is not None:
+ transceiver_dom_info_dict['temperature'] = temp
+
+ if self.dom_volt_supported:
+ start = QSFP_VOLT_OFFSET - QSFP_DOM_BULK_DATA_START
+ end = start + QSFP_VOLT_WIDTH
+ dom_voltage_data = sfpd_obj.parse_voltage(
+ dom_data_raw[start: end], 0)
+ volt = self.__convert_string_to_num(
+ dom_voltage_data['data']['Vcc']['value'])
+ if volt is not None:
+ transceiver_dom_info_dict['voltage'] = volt
+
+ start = QSFP_CHANNL_MON_OFFSET - QSFP_DOM_BULK_DATA_START
+ end = start + QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH
+ dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power(
+ dom_data_raw[start: end], 0)
+
+ if self.dom_tx_power_supported:
+ transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['TX1Power']['value'])
+ transceiver_dom_info_dict['tx2power'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['TX2Power']['value'])
+ transceiver_dom_info_dict['tx3power'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['TX3Power']['value'])
+ transceiver_dom_info_dict['tx4power'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['TX4Power']['value'])
+
+ if self.dom_rx_power_supported:
+ transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['RX1Power']['value'])
+ transceiver_dom_info_dict['rx2power'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['RX2Power']['value'])
+ transceiver_dom_info_dict['rx3power'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['RX3Power']['value'])
+ transceiver_dom_info_dict['rx4power'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['RX4Power']['value'])
+
+ transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['TX1Bias']['value'])
+ transceiver_dom_info_dict['tx2bias'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['TX2Bias']['value'])
+ transceiver_dom_info_dict['tx3bias'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['TX3Bias']['value'])
+ transceiver_dom_info_dict['tx4bias'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['TX4Bias']['value'])
- if dom_temperature_raw is not None:
+ else:
+ if not self.dom_supported:
+ return transceiver_dom_info_dict
+
+ offset = 256
+ sfpd_obj = sff8472Dom()
+ if sfpd_obj is None:
+ return transceiver_dom_info_dict
+ sfpd_obj._calibration_type = self.calibration
+
+ dom_data_raw = self.__read_eeprom_specific_bytes(
+ (offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE)
+
+ start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START
+ end = start + SFP_TEMPE_WIDTH
dom_temperature_data = sfpd_obj.parse_temperature(
- dom_temperature_raw, 0)
- transceiver_dom_info_dict['temperature'] = dom_temperature_data['data']['Temperature']['value']
-
- dom_voltage_raw = self.__read_eeprom_specific_bytes(
- (offset + SFP_VOLT_OFFSET), SFP_VOLT_WIDTH)
- if dom_voltage_raw is not None:
- dom_voltage_data = sfpd_obj.parse_voltage(dom_voltage_raw, 0)
- transceiver_dom_info_dict['voltage'] = dom_voltage_data['data']['Vcc']['value']
-
- dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
- (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH)
- if dom_channel_monitor_raw is not None:
- dom_voltage_data = sfpd_obj.parse_channel_monitor_params(
- dom_channel_monitor_raw, 0)
- transceiver_dom_info_dict['tx1power'] = dom_voltage_data['data']['TXPower']['value']
- transceiver_dom_info_dict['rx1power'] = dom_voltage_data['data']['RXPower']['value']
- transceiver_dom_info_dict['tx1bias'] = dom_voltage_data['data']['TXBias']['value']
-
- for key in transceiver_dom_info_dict:
- transceiver_dom_info_dict[key] = self._convert_string_to_num(
- transceiver_dom_info_dict[key])
+ dom_data_raw[start: end], 0)
+
+ start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START
+ end = start + SFP_VOLT_WIDTH
+ dom_voltage_data = sfpd_obj.parse_voltage(
+ dom_data_raw[start: end], 0)
+
+ start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START
+ end = start + SFP_CHANNL_MON_WIDTH
+ dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params(
+ dom_data_raw[start: end], 0)
+
+ transceiver_dom_info_dict['temperature'] = self.__convert_string_to_num(
+ dom_temperature_data['data']['Temperature']['value'])
+ transceiver_dom_info_dict['voltage'] = self.__convert_string_to_num(
+ dom_voltage_data['data']['Vcc']['value'])
+ transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['RXPower']['value'])
+ transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['TXBias']['value'])
+ transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num(
+ dom_channel_monitor_data['data']['TXPower']['value'])
transceiver_dom_info_dict['rx_los'] = self.get_rx_los()
transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault()
@@ -372,26 +733,79 @@ def get_transceiver_threshold_info(self):
txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA.
========================================================================
"""
- # check present status
- sfpd_obj = sff8472Dom()
+ transceiver_dom_threshold_info_dict = dict.fromkeys(
+ self.threshold_dict_keys, 'N/A')
- if not self.get_presence() and not sfpd_obj:
- return {}
+ if self.sfp_type == OSFP_TYPE:
+ pass
- eeprom_ifraw = self.__read_eeprom_specific_bytes(0, DOM_OFFSET)
- sfpi_obj = sff8472InterfaceId(eeprom_ifraw)
- cal_type = sfpi_obj.get_calibration_type()
- sfpd_obj._calibration_type = cal_type
+ elif self.sfp_type == QSFP_TYPE:
+ if not self.dom_supported or not self.qsfp_page3_available:
+ return transceiver_dom_threshold_info_dict
- offset = DOM_OFFSET
- transceiver_dom_threshold_info_dict = dict.fromkeys(
- self.threshold_dict_keys, 'N/A')
- dom_module_threshold_raw = self.__read_eeprom_specific_bytes(
- (offset + SFP_MODULE_THRESHOLD_OFFSET), SFP_MODULE_THRESHOLD_WIDTH)
- if dom_module_threshold_raw is not None:
- dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(
+ # Dom Threshold data starts from offset 384
+ # Revert offset back to 0 once data is retrieved
+ offset = QSFP_MODULE_UPPER_PAGE3_START
+ sfpd_obj = sff8436Dom()
+ if sfpd_obj is None:
+ return transceiver_dom_threshold_info_dict
+
+ dom_module_threshold_raw = self.__read_eeprom_specific_bytes(
+ (offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH)
+ if dom_module_threshold_raw is None:
+ return transceiver_dom_threshold_info_dict
+
+ dom_module_threshold_data = sfpd_obj.parse_module_threshold_values(
dom_module_threshold_raw, 0)
+ dom_channel_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_THRESHOLD_OFFSET),
+ QSFP_CHANNL_THRESHOLD_WIDTH)
+ if dom_channel_threshold_raw is None:
+ return transceiver_dom_threshold_info_dict
+ dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values(
+ dom_channel_threshold_raw, 0)
+
+ # Threshold Data
+ transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value']
+ transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
+ transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value']
+ transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value']
+ transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value']
+ transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value']
+ transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value']
+ transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value']
+ transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value']
+ transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value']
+ transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value']
+ transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value']
+ transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value']
+ transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value']
+ transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value']
+ transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value']
+ transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value']
+ transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value']
+ transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value']
+ transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value']
+
+ else:
+ offset = SFP_MODULE_ADDRA2_OFFSET
+
+ if not self.dom_supported:
+ return transceiver_dom_threshold_info_dict
+
+ sfpd_obj = sff8472Dom(None, self.calibration)
+ if sfpd_obj is None:
+ return transceiver_dom_threshold_info_dict
+
+ dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET),
+ SFP_MODULE_THRESHOLD_WIDTH)
+ if dom_module_threshold_raw is not None:
+ dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold(
+ dom_module_threshold_raw, 0)
+ else:
+ return transceiver_dom_threshold_info_dict
+
+ # Threshold Data
transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value']
transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value']
transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value']
@@ -415,7 +829,7 @@ def get_transceiver_threshold_info(self):
transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value']
for key in transceiver_dom_threshold_info_dict:
- transceiver_dom_threshold_info_dict[key] = self._convert_string_to_num(
+ transceiver_dom_threshold_info_dict[key] = self.__convert_string_to_num(
transceiver_dom_threshold_info_dict[key])
return transceiver_dom_threshold_info_dict
@@ -437,11 +851,27 @@ def get_rx_los(self):
Note : RX LOS status is latched until a call to get_rx_los or a reset.
"""
rx_los = False
- status_control_raw = self.__read_eeprom_specific_bytes(
- SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
- if status_control_raw:
- data = int(status_control_raw[0], 16)
- rx_los = (sffbase().test_bit(data, 1) != 0)
+ if self.sfp_type == OSFP_TYPE:
+ return False
+
+ elif self.sfp_type == QSFP_TYPE:
+ offset = 0
+ dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+ (offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH)
+ if dom_channel_monitor_raw is not None:
+ rx_los_data = int(dom_channel_monitor_raw[0], 16)
+ rx1_los = (rx_los_data & 0x01 != 0)
+ rx2_los = (rx_los_data & 0x02 != 0)
+ rx3_los = (rx_los_data & 0x04 != 0)
+ rx4_los = (rx_los_data & 0x08 != 0)
+ rx_los = (rx1_los and rx2_los and rx3_los and rx4_los)
+ else:
+ offset = 256
+ dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+ (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH)
+ if dom_channel_monitor_raw is not None:
+ rx_los_data = int(dom_channel_monitor_raw[0], 16)
+ rx_los = (rx_los_data & 0x02 != 0)
return rx_los
@@ -452,14 +882,32 @@ def get_tx_fault(self):
A Boolean, True if SFP has TX fault, False if not
Note : TX fault status is lached until a call to get_tx_fault or a reset.
"""
- tx_fault = False
- status_control_raw = self.__read_eeprom_specific_bytes(
- SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
- if status_control_raw:
- data = int(status_control_raw[0], 16)
- tx_fault = (sffbase().test_bit(data, 2) != 0)
+ tx4_fault = False
+
+ if self.sfp_type == OSFP_TYPE or not self.dom_supported:
+ return False
+
+ elif self.sfp_type == QSFP_TYPE:
+ offset = 0
+ dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+ (offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH)
+ if dom_channel_monitor_raw is not None:
+ tx_fault_data = int(dom_channel_monitor_raw[0], 16)
+ tx1_fault = (tx_fault_data & 0x01 != 0)
+ tx2_fault = (tx_fault_data & 0x02 != 0)
+ tx3_fault = (tx_fault_data & 0x04 != 0)
+ tx4_fault = (tx_fault_data & 0x08 != 0)
+ tx4_fault = (
+ tx1_fault and tx2_fault and tx3_fault and tx4_fault)
+ else:
+ offset = 256
+ dom_channel_monitor_raw = self.__read_eeprom_specific_bytes(
+ (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH)
+ if dom_channel_monitor_raw is not None:
+ tx_fault_data = int(dom_channel_monitor_raw[0], 16)
+ tx4_fault = (tx_fault_data & 0x04 != 0)
- return tx_fault
+ return tx4_fault
def get_tx_disable(self):
"""
@@ -469,7 +917,7 @@ def get_tx_disable(self):
"""
tx_disable = False
status_control_raw = self.__read_eeprom_specific_bytes(
- SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
+ SFP_CHANNL_STATUS_OFFSET, SFP_CHANNL_STATUS_WIDTH)
if status_control_raw:
data = int(status_control_raw[0], 16)
tx_disable_hard = (sffbase().test_bit(
@@ -516,8 +964,8 @@ def get_temperature(self):
Returns:
An integer number of current temperature in Celsius
"""
- transceiver_dom_info_dict = self.get_transceiver_bulk_status()
- return transceiver_dom_info_dict.get("temperature", "N/A")
+ transceiver_bulk_status = self.get_transceiver_bulk_status()
+ return transceiver_bulk_status.get("temperature", "N/A")
def get_voltage(self):
"""
@@ -525,8 +973,8 @@ def get_voltage(self):
Returns:
An integer number of supply voltage in mV
"""
- transceiver_dom_info_dict = self.get_transceiver_bulk_status()
- return transceiver_dom_info_dict.get("voltage", "N/A")
+ transceiver_bulk_status = self.get_transceiver_bulk_status()
+ return transceiver_bulk_status.get("voltage", "N/A")
def get_tx_bias(self):
"""
@@ -584,7 +1032,7 @@ def tx_disable(self, tx_disable):
"""
sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num]
status_control_raw = self.__read_eeprom_specific_bytes(
- SFP_STATUS_CONTROL_OFFSET, SFP_STATUS_CONTROL_WIDTH)
+ SFP_CHANNL_STATUS_OFFSET, SFP_CHANNL_STATUS_WIDTH)
if status_control_raw is not None:
# Set bit 6 for Soft TX Disable Select
# 01000000 = 64 and 10111111 = 191
@@ -598,10 +1046,9 @@ def tx_disable(self, tx_disable):
buffer = create_string_buffer(1)
buffer[0] = chr(tx_disable_ctl)
# Write to eeprom
- sysfsfile_eeprom.seek(SFP_STATUS_CONTROL_OFFSET)
+ sysfsfile_eeprom.seek(SFP_CHANNL_STATUS_OFFSET)
sysfsfile_eeprom.write(buffer[0])
except Exception:
- #print("Error: unable to open file: %s" % str(e))
return False
finally:
if sysfsfile_eeprom:
@@ -656,6 +1103,10 @@ def set_power_override(self, power_override, power_set):
# SFP doesn't support this feature
return False
+ ##############################################################
+ ###################### Device methods ########################
+ ##############################################################
+
def get_name(self):
"""
Retrieves the name of the device
@@ -700,3 +1151,26 @@ def get_serial(self):
"""
transceiver_dom_info_dict = self.get_transceiver_info()
return transceiver_dom_info_dict.get("serial", "N/A")
+
+ def get_status(self):
+ """
+ Retrieves the operational status of the device
+ Returns:
+ A boolean value, True if device is operating properly, False if not
+ """
+ return self.get_presence() and not self.get_reset_status()
+
+ def get_position_in_parent(self):
+ """
+ Returns:
+ Temp return 0
+ """
+ return 0
+
+ def is_replaceable(self):
+ """
+ Retrieves if replaceable
+ Returns:
+ A boolean value, True if replaceable
+ """
+ return True
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py
index 2235b4c6572a..d224281a5935 100644
--- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py
+++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/thermal.py
@@ -93,7 +93,6 @@
class Thermal(ThermalBase):
"""Platform-specific Thermal class"""
- THERMAL_NAME_LIST = []
MAINBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-11/11-001a/hwmon/hwmon2"
CPUBOARD_SS_PATH = "/sys/class/i2c-adapter/i2c-3/3-001a/hwmon/hwmon1"
SS_CONFIG_PATH = "/usr/share/sonic/device/x86_64-cel_e1031-r0/sensors.conf"
@@ -110,9 +109,12 @@ def __init__(self, thermal_index, airflow):
self.name = self.get_name()
self.postion = self._thermal_info["postion"]
+ self.minimum_thermal = self.get_temperature()
+ self.maximum_thermal = self.get_temperature()
def _get_hwmon_path(self):
- hwmon_path = os.path.join(I2C_ADAPTER_PATH, self._thermal_info["i2c_path"])
+ hwmon_path = os.path.join(
+ I2C_ADAPTER_PATH, self._thermal_info["i2c_path"])
hwmon_dir = os.listdir(hwmon_path)[0]
return os.path.join(hwmon_path, hwmon_dir)
@@ -126,6 +128,17 @@ def _set_threshold(self, file_name, temperature):
temp_file_path = os.path.join(self._hwmon_path, file_name)
return self._api_common.write_txt_file(temp_file_path, str(temperature))
+ def _get_threshold(self, file_name):
+ temp_file_path = os.path.join(self._hwmon_path, file_name)
+ data = self._api_common.read_txt_file(temp_file_path)
+ if data:
+ try:
+ threshold = float(data)
+ return round(threshold/1000, 3)
+ except Exception:
+ pass
+ return None
+
def get_temperature(self):
"""
Retrieves current temperature reading from thermal
@@ -144,7 +157,8 @@ def get_high_threshold(self):
up to nearest thousandth of one degree Celsius, e.g. 30.125
"""
max_crit_key = '{}_max'.format(self._airflow)
- return self._thermal_info.get(max_crit_key, None)
+ high_threshold_file = "temp{}_max".format(self._ss_index)
+ return self._get_threshold(high_threshold_file) or self._thermal_info.get(max_crit_key, None)
def get_low_threshold(self):
"""
@@ -153,7 +167,7 @@ def get_low_threshold(self):
A float number, the low threshold temperature of thermal in Celsius
up to nearest thousandth of one degree Celsius, e.g. 30.125
"""
- return 0.0
+ return 0.001
def set_high_threshold(self, temperature):
"""
@@ -166,8 +180,8 @@ def set_high_threshold(self, temperature):
"""
temp_file = "temp{}_max".format(self._ss_index)
is_set = self._set_threshold(temp_file, int(temperature*1000))
- file_set = False
- if is_set:
+ file_set = True
+ if is_set and self._api_common.is_host():
try:
with open(self.SS_CONFIG_PATH, 'r+') as f:
content = f.readlines()
@@ -215,7 +229,35 @@ def get_low_critical_threshold(self):
A float number, the low critical threshold temperature of thermal in Celsius
up to nearest thousandth of one degree Celsius, e.g. 30.125
"""
- return 0.0
+ return 0.001
+
+ def get_minimum_recorded(self):
+ """
+ Retrieves the minimum recorded temperature of thermal
+ Returns:
+ A float number, the minimum recorded temperature of thermal in Celsius
+ up to nearest thousandth of one degree Celsius, e.g. 30.125
+ """
+ tmp = self.get_temperature()
+ if tmp < self.minimum_thermal:
+ self.minimum_thermal = tmp
+ return self.minimum_thermal
+
+ def get_maximum_recorded(self):
+ """
+ Retrieves the maximum recorded temperature of thermal
+ Returns:
+ A float number, the maximum recorded temperature of thermal in Celsius
+ up to nearest thousandth of one degree Celsius, e.g. 30.125
+ """
+ tmp = self.get_temperature()
+ if tmp > self.maximum_thermal:
+ self.maximum_thermal = tmp
+ return self.maximum_thermal
+
+ ##############################################################
+ ###################### Device methods ########################
+ ##############################################################
def get_name(self):
"""
@@ -267,3 +309,21 @@ def get_status(self):
raw_txt = self._api_common.read_txt_file(fault_file_path)
return int(raw_txt) == 0
+
+ def is_replaceable(self):
+ """
+ Retrieves whether thermal module is replaceable
+ Returns:
+ A boolean value, True if replaceable, False if not
+ """
+ return False
+
+ def get_position_in_parent(self):
+ """
+ Retrieves the thermal position information
+ Returns:
+ A int value, 0 represent ASIC thermal, 1 represent CPU thermal info
+ """
+ if self.postion == "cpu":
+ return 1
+ return 0
diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/watchdog.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/watchdog.py
index 62f325655cac..93898bd646a4 100644
--- a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/watchdog.py
+++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/watchdog.py
@@ -4,114 +4,107 @@
# Watchdog contains an implementation of SONiC Platform Base API
#
#############################################################################
-import fcntl
-import os
-import array
try:
+ import os
+ import time
from sonic_platform_base.watchdog_base import WatchdogBase
+ from .common import Common
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
-""" ioctl constants """
-IO_WRITE = 0x40000000
-IO_READ = 0x80000000
-IO_READ_WRITE = 0xC0000000
-IO_SIZE_INT = 0x00040000
-IO_SIZE_40 = 0x00280000
-IO_TYPE_WATCHDOG = ord('W') << 8
-
-WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG
-WDR_40 = IO_READ | IO_SIZE_40 | IO_TYPE_WATCHDOG
-WDWR_INT = IO_READ_WRITE | IO_SIZE_INT | IO_TYPE_WATCHDOG
-
-""" Watchdog ioctl commands """
-WDIOC_GETSUPPORT = 0 | WDR_40
-WDIOC_GETSTATUS = 1 | WDR_INT
-WDIOC_GETBOOTSTATUS = 2 | WDR_INT
-WDIOC_GETTEMP = 3 | WDR_INT
-WDIOC_SETOPTIONS = 4 | WDR_INT
-WDIOC_KEEPALIVE = 5 | WDR_INT
-WDIOC_SETTIMEOUT = 6 | WDWR_INT
-WDIOC_GETTIMEOUT = 7 | WDR_INT
-WDIOC_SETPRETIMEOUT = 8 | WDWR_INT
-WDIOC_GETPRETIMEOUT = 9 | WDR_INT
-WDIOC_GETTIMELEFT = 10 | WDR_INT
-
-""" Watchdog status constants """
-WDIOS_DISABLECARD = 0x0001
-WDIOS_ENABLECARD = 0x0002
+PLATFORM_CPLD_PATH = '/sys/devices/platform/e1031.smc/'
+SETREG_FILE = 'setreg'
+GETREG_FILE = 'getreg'
WDT_COMMON_ERROR = -1
-WD_MAIN_IDENTITY = "iTCO_wdt"
-WDT_SYSFS_PATH = "/sys/class/watchdog/"
+MMC_VERSION_REG = "0x100"
+
+# watchdog infomation for cpld v06
+V06_MMC_VERSION = 0x05
+V06_WDT_WIDTH = '0x110'
+V06_WDT_WIDTH_SELECTOR = {
+ 30: '0x1',
+ 60: '0x2',
+ 180: '0x3'
+}
+
+V06_CPLD_WDT_INFO = {
+ 'wdt_en_reg': '0x111',
+ 'wdt_en_cmd': '0x0',
+ 'wdt_dis_cmd': '0x1'
+}
+
+# watchdog infomation
+WDT_TIMER_L_BIT_REG = '0x117'
+WDT_TIMER_M_BIT_REG = '0x118'
+WDT_TIMER_H_BIT_REG = '0x119'
+WDT_KEEP_ALVIVE_REG = '0x11a'
+
+CPLD_WDT_INFO = {
+ 'wdt_en_reg': '0x116',
+ 'wdt_en_cmd': '0x1',
+ 'wdt_dis_cmd': '0x0'
+}
class Watchdog(WatchdogBase):
def __init__(self):
- WatchdogBase.__init__(self)
+ # Init api_common
+ self._api_common = Common()
+
+ # Init cpld reg path
+ self.setreg_path = os.path.join(PLATFORM_CPLD_PATH, SETREG_FILE)
+ self.getreg_path = os.path.join(PLATFORM_CPLD_PATH, GETREG_FILE)
+
+ self.mmc_v = self._get_mmc_version()
+ self.cpld_info = V06_CPLD_WDT_INFO if self.mmc_v <= V06_MMC_VERSION else CPLD_WDT_INFO
- self.watchdog, self.wdt_main_dev_name = self._get_wdt()
- self.status_path = "/sys/class/watchdog/%s/status" % self.wdt_main_dev_name
- self.state_path = "/sys/class/watchdog/%s/state" % self.wdt_main_dev_name
- self.timeout_path = "/sys/class/watchdog/%s/timeout" % self.wdt_main_dev_name
# Set default value
self._disable()
self.armed = False
- self.timeout = self._gettimeout(self.timeout_path)
+ self.timeout = 0
- def _is_wd_main(self, dev):
- """
- Checks watchdog identity
- """
- identity = self._read_file(
- "{}/{}/identity".format(WDT_SYSFS_PATH, dev))
- return identity == WD_MAIN_IDENTITY
+ def _get_mmc_version(self):
+ hex_str_v = self._api_common.get_reg(self.getreg_path, MMC_VERSION_REG)
+ return int(hex_str_v, 16)
- def _get_wdt(self):
- """
- Retrieves watchdog device
- """
- wdt_main_dev_list = [dev for dev in os.listdir(
- "/dev/") if dev.startswith("watchdog") and self._is_wd_main(dev)]
- if not wdt_main_dev_list:
- return None
- wdt_main_dev_name = wdt_main_dev_list[0]
- watchdog_device_path = "/dev/{}".format(wdt_main_dev_name)
- watchdog = os.open(watchdog_device_path, os.O_RDWR)
- return watchdog, wdt_main_dev_name
+ def _get_level_hex(self, sub_hex):
+ sub_hex_str = sub_hex.replace("x", "0")
+ return hex(int(sub_hex_str, 16))
- def _read_file(self, file_path):
- """
- Read text file
- """
- try:
- with open(file_path, "r") as fd:
- txt = fd.read()
- except IOError:
- return WDT_COMMON_ERROR
- return txt.strip()
+ def _seconds_to_lmh_hex(self, seconds):
+ ms = seconds*1000 # calculate timeout in ms format
+ hex_str = hex(ms)
+ l = self._get_level_hex(hex_str[-2:])
+ m = self._get_level_hex(hex_str[-4:-2])
+ h = self._get_level_hex(hex_str[-6:-4])
+ return (l, m, h)
def _enable(self):
"""
Turn on the watchdog timer
"""
- req = array.array('h', [WDIOS_ENABLECARD])
- fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
+ return self._api_common.set_reg(self.setreg_path, self.cpld_info['wdt_en_reg'], self.cpld_info['wdt_en_cmd'])
def _disable(self):
"""
Turn off the watchdog timer
"""
- req = array.array('h', [WDIOS_DISABLECARD])
- fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False)
+ return self._api_common.set_reg(self.setreg_path, self.cpld_info['wdt_en_reg'], self.cpld_info['wdt_dis_cmd'])
def _keepalive(self):
"""
Keep alive watchdog timer
"""
- fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE)
+ if self.mmc_v <= V06_MMC_VERSION:
+ self._disable()
+ self._enable()
+
+ else:
+ self._api_common.set_reg(
+ self.setreg_path, WDT_KEEP_ALVIVE_REG, self.cpld_info['wdt_en_cmd'])
def _settimeout(self, seconds):
"""
@@ -119,29 +112,23 @@ def _settimeout(self, seconds):
@param seconds - timeout in seconds
@return is the actual set timeout
"""
- req = array.array('I', [seconds])
- fcntl.ioctl(self.watchdog, WDIOC_SETTIMEOUT, req, True)
- return int(req[0])
- def _gettimeout(self, timeout_path):
- """
- Get watchdog timeout
- @return watchdog timeout
- """
- req = array.array('I', [0])
- fcntl.ioctl(self.watchdog, WDIOC_GETTIMEOUT, req, True)
+ if self.mmc_v <= V06_MMC_VERSION:
+ timeout_hex = V06_WDT_WIDTH_SELECTOR.get(seconds, '0x2')
+ seconds = 60 if timeout_hex == '0x2' else seconds
+ self._api_common.set_reg(
+ self.setreg_path, V06_WDT_WIDTH, timeout_hex)
- return int(req[0])
+ else:
+ (l, m, h) = self._seconds_to_lmh_hex(seconds)
+ self._api_common.set_reg(
+ self.setreg_path, WDT_TIMER_H_BIT_REG, h) # set high bit
+ self._api_common.set_reg(
+ self.setreg_path, WDT_TIMER_M_BIT_REG, m) # set med bit
+ self._api_common.set_reg(
+ self.setreg_path, WDT_TIMER_L_BIT_REG, l) # set low bit
- def _gettimeleft(self):
- """
- Get time left before watchdog timer expires
- @return time left in seconds
- """
- req = array.array('I', [0])
- fcntl.ioctl(self.watchdog, WDIOC_GETTIMELEFT, req, True)
-
- return int(req[0])
+ return seconds
#################################################################
@@ -157,22 +144,25 @@ def arm(self, seconds):
An integer specifying the *actual* number of seconds the watchdog
was armed with. On failure returns -1.
"""
-
ret = WDT_COMMON_ERROR
- if seconds < 0:
+
+ if seconds < 0 or seconds > 180:
return ret
try:
if self.timeout != seconds:
self.timeout = self._settimeout(seconds)
+
if self.armed:
self._keepalive()
else:
self._enable()
self.armed = True
+
ret = self.timeout
+ self.arm_timestamp = time.time()
except IOError as e:
- pass
+ print("Error: unable to enable wdt due to : {}".format(e))
return ret
@@ -183,14 +173,12 @@ def disarm(self):
A boolean, True if watchdog is disarmed successfully, False if not
"""
disarmed = False
- if self.is_armed():
- try:
- self._disable()
- self.armed = False
- disarmed = True
- except IOError:
- pass
-
+ try:
+ self._disable()
+ self.armed = False
+ disarmed = True
+ except IOError as e:
+ print("Error: unable to disable wdt due to : {}".format(e))
return disarmed
def is_armed(self):
@@ -199,7 +187,6 @@ def is_armed(self):
Returns:
A boolean, True if watchdog is armed, False if not
"""
-
return self.armed
def get_remaining_time(self):
@@ -214,16 +201,6 @@ def get_remaining_time(self):
timeleft = WDT_COMMON_ERROR
if self.armed:
- try:
- timeleft = self._gettimeleft()
- except IOError:
- pass
+ timeleft = int(self.timeout - (time.time() - self.arm_timestamp))
return timeleft
-
- def __del__(self):
- """
- Close watchdog
- """
-
- os.close(self.watchdog)
diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_def.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_def.j2
index 38e34eb571e8..dc04b2265f33 100644
--- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_def.j2
+++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_def.j2
@@ -1,4 +1,4 @@
-{%- set default_cable = '300m' %}
+{%- set default_cable = '0m' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_t0.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_t0.j2
index 38e34eb571e8..dc04b2265f33 100644
--- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_t0.j2
+++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_t0.j2
@@ -1,4 +1,4 @@
-{%- set default_cable = '300m' %}
+{%- set default_cable = '0m' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_t1.j2 b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_t1.j2
index 38e34eb571e8..dc04b2265f33 100644
--- a/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_t1.j2
+++ b/device/dell/x86_64-dell_s6000_s1220-r0/Force10-S6000/buffers_defaults_t1.j2
@@ -1,4 +1,4 @@
-{%- set default_cable = '300m' %}
+{%- set default_cable = '0m' %}
{%- macro generate_port_lists(PORT_ALL) %}
{# Generate list of ports #}
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2
index 3369e2cc5e4d..0eacb5840e7e 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t0.j2
@@ -23,13 +23,11 @@
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "static",
"static_th":"32575488"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2
index a1fa90d39779..7cf5c623ec8e 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C32/buffers_defaults_t1.j2
@@ -23,13 +23,11 @@
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "static",
"static_th":"32575488"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2
index 3369e2cc5e4d..0eacb5840e7e 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t0.j2
@@ -23,13 +23,11 @@
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "static",
"static_th":"32575488"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2
index 3a8e9a92261a..f39aacca6121 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-C8D48/buffers_defaults_t1.j2
@@ -23,13 +23,11 @@
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "static",
"static_th":"32575488"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t0.j2
index 3369e2cc5e4d..0eacb5840e7e 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t0.j2
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t0.j2
@@ -23,13 +23,11 @@
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "static",
"static_th":"32575488"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2
index a1fa90d39779..7cf5c623ec8e 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/buffers_defaults_t1.j2
@@ -23,13 +23,11 @@
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "static",
"static_th":"32575488"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/port_config.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/port_config.ini
index 55c8fb3dcf64..2b24bea93107 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/port_config.ini
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-100G/port_config.ini
@@ -31,5 +31,5 @@ Ethernet112 113,114,115,116 hundredGigE1/29 29 100000
Ethernet116 117,118,119,120 hundredGigE1/30 30 100000
Ethernet120 121,122,123,124 hundredGigE1/31 31 100000
Ethernet124 125,126,127,128 hundredGigE1/32 32 100000
-Ethernet128 128 tenGigE1/33 33 10000
-Ethernet129 129 tenGigE1/34 34 10000
+Ethernet128 129 tenGigE1/33 33 10000
+Ethernet129 128 tenGigE1/34 34 10000
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t0.j2
index 3369e2cc5e4d..0eacb5840e7e 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t0.j2
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t0.j2
@@ -23,13 +23,11 @@
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "static",
"static_th":"32575488"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2
index a1fa90d39779..7cf5c623ec8e 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/buffers_defaults_t1.j2
@@ -23,13 +23,11 @@
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "static",
"static_th":"32575488"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/port_config.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/port_config.ini
index 726427759c08..c38b0e9b6f84 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/port_config.ini
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-10G/port_config.ini
@@ -103,5 +103,5 @@ Ethernet112 113,114,115,116 hundredGigE1/29 29 100000
Ethernet116 117,118,119,120 hundredGigE1/30 30 100000
Ethernet120 121,122,123,124 hundredGigE1/31 31 100000
Ethernet124 125,126,127,128 hundredGigE1/32 32 100000
-Ethernet128 128 tenGigE1/33 33 10000
-Ethernet129 129 tenGigE1/34 34 10000
+Ethernet128 129 tenGigE1/33 33 10000
+Ethernet129 128 tenGigE1/34 34 10000
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t0.j2
index 3369e2cc5e4d..0eacb5840e7e 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t0.j2
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t0.j2
@@ -23,13 +23,11 @@
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "static",
"static_th":"32575488"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2
index a1fa90d39779..7cf5c623ec8e 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/buffers_defaults_t1.j2
@@ -23,13 +23,11 @@
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "static",
"static_th":"32575488"
},
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"0",
- "mode": "dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/port_config.ini b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/port_config.ini
index 7366a95cf8b8..e78fafdc24e0 100644
--- a/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/port_config.ini
+++ b/device/dell/x86_64-dellemc_s5232f_c3538-r0/DellEMC-S5232f-P-25G/port_config.ini
@@ -103,5 +103,5 @@ Ethernet112 113,114,115,116 hundredGigE1/29 29 100000
Ethernet116 117,118,119,120 hundredGigE1/30 30 100000
Ethernet120 121,122,123,124 hundredGigE1/31 31 100000
Ethernet124 125,126,127,128 hundredGigE1/32 32 100000
-Ethernet128 128 tenGigE1/33 33 10000
-Ethernet129 129 tenGigE1/34 34 10000
+Ethernet128 129 tenGigE1/33 33 10000
+Ethernet129 128 tenGigE1/34 34 10000
diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2
index d538ab1f650f..832a60eda6c5 100644
--- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2
+++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C64/buffers_defaults_t1.j2
@@ -36,7 +36,6 @@
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"1518",
- "mode":"dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2
index cbbae78d7596..a1761da29bb3 100644
--- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2
+++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-C8D112/buffers_defaults_t0.j2
@@ -43,7 +43,6 @@
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"1518",
- "mode":"dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2
index 96c99e5800e9..6934f631d1b0 100644
--- a/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2
+++ b/device/dell/x86_64-dellemc_z9264f_c3538-r0/DellEMC-Z9264f-Q64/buffers_defaults_t0.j2
@@ -36,7 +36,6 @@
"egress_lossy_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
"size":"1518",
- "mode":"dynamic",
"dynamic_th":"3"
}
},
diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t0.j2
index 29bb64904e6c..5ecbe788e3ab 100644
--- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t0.j2
+++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t0.j2
@@ -26,13 +26,13 @@
{%- macro generate_buffer_pool_and_profiles() %}
"BUFFER_POOL": {
"ingress_lossless_pool": {
- "size": "66800476",
+ "size": "66394076",
"type": "ingress",
"mode": "dynamic",
"xoff": "8644128"
},
"egress_lossless_pool": {
- "size": "66800476",
+ "size": "55921148",
"type": "egress",
"mode": "static"
}
@@ -41,7 +41,7 @@
"ingress_lossy_profile": {
"pool":"[BUFFER_POOL|ingress_lossless_pool]",
"size":"0",
- "static_th":"66800476"
+ "static_th":"66394076"
},
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t1.j2
index 29bb64904e6c..5ecbe788e3ab 100644
--- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t1.j2
+++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/buffers_defaults_t1.j2
@@ -26,13 +26,13 @@
{%- macro generate_buffer_pool_and_profiles() %}
"BUFFER_POOL": {
"ingress_lossless_pool": {
- "size": "66800476",
+ "size": "66394076",
"type": "ingress",
"mode": "dynamic",
"xoff": "8644128"
},
"egress_lossless_pool": {
- "size": "66800476",
+ "size": "55921148",
"type": "egress",
"mode": "static"
}
@@ -41,7 +41,7 @@
"ingress_lossy_profile": {
"pool":"[BUFFER_POOL|ingress_lossless_pool]",
"size":"0",
- "static_th":"66800476"
+ "static_th":"66394076"
},
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/th3-z9332f-16x400G-64x100G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/th3-z9332f-16x400G-64x100G.config.bcm
index caab3df1ef78..1a41367d9410 100644
--- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/th3-z9332f-16x400G-64x100G.config.bcm
+++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-M-O16C64/th3-z9332f-16x400G-64x100G.config.bcm
@@ -31,7 +31,6 @@ max_vp_lags.0=0
tdma_intr_enable=1
tdma_timeout_usec.0=5000000
parity_correction.0=1
-mmu_lossless.0=0
bcm_num_cos=10
default_cpu_tx_queue=7
pktdma_poll_mode_channel_bitmap=1
diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2
index 94a40d257f6c..7254e841d8b4 100644
--- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2
+++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t0.j2
@@ -10,13 +10,13 @@
{%- macro generate_buffer_pool_and_profiles() %}
"BUFFER_POOL": {
"ingress_lossless_pool": {
- "size": "66435732",
+ "size": "66394076",
"type": "ingress",
"mode": "dynamic",
- "xoff": "27400374"
+ "xoff": "27200352"
},
"egress_lossless_pool": {
- "size": "66435732",
+ "size": "38462204",
"type": "egress",
"mode": "static"
}
@@ -25,7 +25,7 @@
"ingress_lossy_profile": {
"pool":"[BUFFER_POOL|ingress_lossless_pool]",
"size":"0",
- "static_th":"66435732"
+ "static_th":"66394076"
},
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2 b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2
index 94a40d257f6c..7254e841d8b4 100644
--- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2
+++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/buffers_defaults_t1.j2
@@ -10,13 +10,13 @@
{%- macro generate_buffer_pool_and_profiles() %}
"BUFFER_POOL": {
"ingress_lossless_pool": {
- "size": "66435732",
+ "size": "66394076",
"type": "ingress",
"mode": "dynamic",
- "xoff": "27400374"
+ "xoff": "27200352"
},
"egress_lossless_pool": {
- "size": "66435732",
+ "size": "38462204",
"type": "egress",
"mode": "static"
}
@@ -25,7 +25,7 @@
"ingress_lossy_profile": {
"pool":"[BUFFER_POOL|ingress_lossless_pool]",
"size":"0",
- "static_th":"66435732"
+ "static_th":"66394076"
},
"egress_lossless_profile": {
"pool":"[BUFFER_POOL|egress_lossless_pool]",
diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm
index 1376e610b220..a189a8b1731f 100644
--- a/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm
+++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/DellEMC-Z9332f-O32/th3-z9332f-32x400G.config.bcm
@@ -31,7 +31,6 @@ max_vp_lags.0=0
tdma_intr_enable=1
tdma_timeout_usec.0=5000000
parity_correction.0=1
-mmu_lossless.0=0
bcm_num_cos=10
default_cpu_tx_queue=7
pktdma_poll_mode_channel_bitmap=1
diff --git a/device/dell/x86_64-dellemc_z9332f_d1508-r0/pcie.yaml b/device/dell/x86_64-dellemc_z9332f_d1508-r0/pcie.yaml
new file mode 100644
index 000000000000..fbd2549082a6
--- /dev/null
+++ b/device/dell/x86_64-dellemc_z9332f_d1508-r0/pcie.yaml
@@ -0,0 +1,28 @@
+- bus: '00'
+ dev: '03'
+ fn: '0'
+ id: 6f08
+ name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI
+ Express Root Port 3 (rev 03)'
+- bus: '00'
+ dev: 1c
+ fn: '0'
+ id: 8c10
+ name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express
+ Root Port #1 (rev d5)'
+- bus: '00'
+ dev: 1f
+ fn: '2'
+ id: 8c02
+ name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port
+ SATA Controller 1 [AHCI mode] (rev 05)'
+- bus: '05'
+ dev: '00'
+ fn: '0'
+ id: b980
+ name: 'Ethernet controller: Broadcom Limited Device b980 (rev 11)'
+- bus: 09
+ dev: '00'
+ fn: '0'
+ id: '7021'
+ name: 'Memory controller: Xilinx Corporation Device 7021'
diff --git a/device/mellanox/x86_64-mlnx_msn2010-r0/platform.json b/device/mellanox/x86_64-mlnx_msn2010-r0/platform.json
index f4d5b7bcbfad..1e8fe747f906 100644
--- a/device/mellanox/x86_64-mlnx_msn2010-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn2010-r0/platform.json
@@ -380,7 +380,7 @@
"lanes": "72,73,74,75",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp19"],
- "2x50G[40G,25G,10G]": ["etp19a", "etp19b"],
+ "2x50G[25G,10G]": ["etp19a", "etp19b"],
"4x25G[10G]": ["etp19a", "etp19b", "etp19c", "etp19d"]
}
},
@@ -389,7 +389,7 @@
"lanes": "76,77,78,79",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp20"],
- "2x50G[40G,25G,10G]": ["etp20a", "etp20b"],
+ "2x50G[25G,10G]": ["etp20a", "etp20b"],
"4x25G[10G]": ["etp20a", "etp20b", "etp20c", "etp20d"]
}
},
@@ -398,7 +398,7 @@
"lanes": "80,81,82,83",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp21"],
- "2x50G[40G,25G,10G]": ["etp21a", "etp21b"],
+ "2x50G[25G,10G]": ["etp21a", "etp21b"],
"4x25G[10G]": ["etp21a", "etp21b", "etp21c", "etp21d"]
}
},
@@ -407,7 +407,7 @@
"lanes": "84,85,86,87",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp22"],
- "2x50G[40G,25G,10G]": ["etp22a", "etp22b"],
+ "2x50G[25G,10G]": ["etp22a", "etp22b"],
"4x25G[10G]": ["etp22a", "etp22b", "etp22c", "etp22d"]
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn2410-r0/platform.json b/device/mellanox/x86_64-mlnx_msn2410-r0/platform.json
index 10ac34581492..6ed5a3a84aa8 100644
--- a/device/mellanox/x86_64-mlnx_msn2410-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn2410-r0/platform.json
@@ -909,7 +909,7 @@
"lanes": "192,193,194,195",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp49"],
- "2x50G[40G,25G,10G]": ["etp49a", "etp49b"]
+ "2x50G[25G,10G]": ["etp49a", "etp49b"]
}
},
"Ethernet196": {
@@ -917,7 +917,7 @@
"lanes": "196,197,198,199",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp50"],
- "2x50G[40G,25G,10G]": ["etp50a", "etp50b"]
+ "2x50G[25G,10G]": ["etp50a", "etp50b"]
}
},
"Ethernet200": {
@@ -925,7 +925,7 @@
"lanes": "200,201,202,203",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp51"],
- "2x50G[40G,25G,10G]": ["etp51a", "etp51b"]
+ "2x50G[25G,10G]": ["etp51a", "etp51b"]
}
},
"Ethernet204": {
@@ -933,7 +933,7 @@
"lanes": "204,205,206,207",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp52"],
- "2x50G[40G,25G,10G]": ["etp52a", "etp52b"]
+ "2x50G[25G,10G]": ["etp52a", "etp52b"]
}
},
"Ethernet208": {
@@ -941,7 +941,7 @@
"lanes": "208,209,210,211",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp53"],
- "2x50G[40G,25G,10G]": ["etp53a", "etp53b"]
+ "2x50G[25G,10G]": ["etp53a", "etp53b"]
}
},
"Ethernet212": {
@@ -949,7 +949,7 @@
"lanes": "212,213,214,215",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp54"],
- "2x50G[40G,25G,10G]": ["etp54a", "etp54b"]
+ "2x50G[25G,10G]": ["etp54a", "etp54b"]
}
},
"Ethernet216": {
@@ -957,7 +957,7 @@
"lanes": "216,217,218,219",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp55"],
- "2x50G[40G,25G,10G]": ["etp55a", "etp55b"]
+ "2x50G[25G,10G]": ["etp55a", "etp55b"]
}
},
"Ethernet220": {
@@ -965,7 +965,7 @@
"lanes": "220,221,222,223",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp56"],
- "2x50G[40G,25G,10G]": ["etp56a", "etp56b"]
+ "2x50G[25G,10G]": ["etp56a", "etp56b"]
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/hwsku.json b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/hwsku.json
index 8d3ad0dc0310..b7e75bb1044e 100644
--- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/hwsku.json
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-C28D8/hwsku.json
@@ -85,28 +85,28 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet112": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet114": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet116": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet118": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet120": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet122": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet124": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet126": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D40C8S8/hwsku.json b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D40C8S8/hwsku.json
index 26e4bda87738..1ac7b9e06324 100644
--- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D40C8S8/hwsku.json
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D40C8S8/hwsku.json
@@ -31,16 +31,16 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet16": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet18": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet20": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet22": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet24": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -55,76 +55,76 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet40": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet42": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet44": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet46": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet48": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet50": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet52": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet54": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet56": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet58": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet60": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet62": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet64": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet66": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet68": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet70": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet72": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet74": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet76": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet78": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet80": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet82": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet84": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet86": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet88": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -139,40 +139,40 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet104": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet106": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet108": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet110": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet112": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet114": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet116": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet118": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet120": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet122": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet124": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet126": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
}
}
}
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/hwsku.json b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/hwsku.json
index 0e846d9b3874..cf86472b543d 100644
--- a/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/hwsku.json
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/Mellanox-SN2700-D48C8/hwsku.json
@@ -1,40 +1,40 @@
{
"interfaces": {
"Ethernet0": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet2": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet4": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet6": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet8": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet10": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet12": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet14": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet16": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet18": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet20": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet22": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet24": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -49,76 +49,76 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet40": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet42": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet44": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet46": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet48": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet50": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet52": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet54": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet56": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet58": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet60": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet62": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet64": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet66": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet68": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet70": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet72": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet74": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet76": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet78": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet80": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet82": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet84": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet86": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet88": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -133,40 +133,40 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet104": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet106": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet108": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet110": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet112": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet114": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet116": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet118": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet120": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet122": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet124": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet126": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json b/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json
index 09445f7fe9b8..063a211e785c 100644
--- a/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn2700-r0/platform.json
@@ -381,7 +381,7 @@
"lanes": "0,1,2,3",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp1"],
- "2x50G[40G,25G,10G]": ["etp1a", "etp1b"]
+ "2x50G[25G,10G]": ["etp1a", "etp1b"]
}
},
"Ethernet4": {
@@ -389,7 +389,7 @@
"lanes": "4,5,6,7",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp2"],
- "2x50G[40G,25G,10G]": ["etp2a", "etp2b"]
+ "2x50G[25G,10G]": ["etp2a", "etp2b"]
}
},
"Ethernet8": {
@@ -397,7 +397,7 @@
"lanes": "8,9,10,11",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp3"],
- "2x50G[40G,25G,10G]": ["etp3a", "etp3b"]
+ "2x50G[25G,10G]": ["etp3a", "etp3b"]
}
},
"Ethernet12": {
@@ -405,7 +405,7 @@
"lanes": "12,13,14,15",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp4"],
- "2x50G[40G,25G,10G]": ["etp4a", "etp4b"]
+ "2x50G[25G,10G]": ["etp4a", "etp4b"]
}
},
"Ethernet16": {
@@ -413,7 +413,7 @@
"lanes": "16,17,18,19",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp5"],
- "2x50G[40G,25G,10G]": ["etp5a", "etp5b"]
+ "2x50G[25G,10G]": ["etp5a", "etp5b"]
}
},
"Ethernet20": {
@@ -421,7 +421,7 @@
"lanes": "20,21,22,23",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp6"],
- "2x50G[40G,25G,10G]": ["etp6a", "etp6b"]
+ "2x50G[25G,10G]": ["etp6a", "etp6b"]
}
},
"Ethernet24": {
@@ -429,7 +429,7 @@
"lanes": "24,25,26,27",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp7"],
- "2x50G[40G,25G,10G]": ["etp7a", "etp7b"]
+ "2x50G[25G,10G]": ["etp7a", "etp7b"]
}
},
"Ethernet28": {
@@ -437,7 +437,7 @@
"lanes": "28,29,30,31",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp8"],
- "2x50G[40G,25G,10G]": ["etp8a", "etp8b"]
+ "2x50G[25G,10G]": ["etp8a", "etp8b"]
}
},
"Ethernet32": {
@@ -445,7 +445,7 @@
"lanes": "32,33,34,35",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp9"],
- "2x50G[40G,25G,10G]": ["etp9a", "etp9b"]
+ "2x50G[25G,10G]": ["etp9a", "etp9b"]
}
},
"Ethernet36": {
@@ -453,7 +453,7 @@
"lanes": "36,37,38,39",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp10"],
- "2x50G[40G,25G,10G]": ["etp10a", "etp10b"]
+ "2x50G[25G,10G]": ["etp10a", "etp10b"]
}
},
"Ethernet40": {
@@ -461,7 +461,7 @@
"lanes": "40,41,42,43",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp11"],
- "2x50G[40G,25G,10G]": ["etp11a", "etp11b"]
+ "2x50G[25G,10G]": ["etp11a", "etp11b"]
}
},
"Ethernet44": {
@@ -469,7 +469,7 @@
"lanes": "44,45,46,47",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp12"],
- "2x50G[40G,25G,10G]": ["etp12a", "etp12b"]
+ "2x50G[25G,10G]": ["etp12a", "etp12b"]
}
},
"Ethernet48": {
@@ -477,7 +477,7 @@
"lanes": "48,49,50,51",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp13"],
- "2x50G[40G,25G,10G]": ["etp13a", "etp13b"]
+ "2x50G[25G,10G]": ["etp13a", "etp13b"]
}
},
"Ethernet52": {
@@ -485,7 +485,7 @@
"lanes": "52,53,54,55",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp14"],
- "2x50G[40G,25G,10G]": ["etp14a", "etp14b"]
+ "2x50G[25G,10G]": ["etp14a", "etp14b"]
}
},
"Ethernet56": {
@@ -493,7 +493,7 @@
"lanes": "56,57,58,59",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp15"],
- "2x50G[40G,25G,10G]": ["etp15a", "etp15b"]
+ "2x50G[25G,10G]": ["etp15a", "etp15b"]
}
},
"Ethernet60": {
@@ -501,7 +501,7 @@
"lanes": "60,61,62,63",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp16"],
- "2x50G[40G,25G,10G]": ["etp16a", "etp16b"]
+ "2x50G[25G,10G]": ["etp16a", "etp16b"]
}
},
"Ethernet64": {
@@ -509,7 +509,7 @@
"lanes": "64,65,66,67",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp17"],
- "2x50G[40G,25G,10G]": ["etp17a", "etp17b"]
+ "2x50G[25G,10G]": ["etp17a", "etp17b"]
}
},
"Ethernet68": {
@@ -517,7 +517,7 @@
"lanes": "68,69,70,71",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp18"],
- "2x50G[40G,25G,10G]": ["etp18a", "etp18b"]
+ "2x50G[25G,10G]": ["etp18a", "etp18b"]
}
},
"Ethernet72": {
@@ -525,7 +525,7 @@
"lanes": "72,73,74,75",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp19"],
- "2x50G[40G,25G,10G]": ["etp19a", "etp19b"]
+ "2x50G[25G,10G]": ["etp19a", "etp19b"]
}
},
"Ethernet76": {
@@ -533,7 +533,7 @@
"lanes": "76,77,78,79",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp20"],
- "2x50G[40G,25G,10G]": ["etp20a", "etp20b"]
+ "2x50G[25G,10G]": ["etp20a", "etp20b"]
}
},
"Ethernet80": {
@@ -541,7 +541,7 @@
"lanes": "80,81,82,83",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp21"],
- "2x50G[40G,25G,10G]": ["etp21a", "etp21b"]
+ "2x50G[25G,10G]": ["etp21a", "etp21b"]
}
},
"Ethernet84": {
@@ -549,7 +549,7 @@
"lanes": "84,85,86,87",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp22"],
- "2x50G[40G,25G,10G]": ["etp22a", "etp22b"]
+ "2x50G[25G,10G]": ["etp22a", "etp22b"]
}
},
"Ethernet88": {
@@ -557,7 +557,7 @@
"lanes": "88,89,90,91",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp23"],
- "2x50G[40G,25G,10G]": ["etp23a", "etp23b"]
+ "2x50G[25G,10G]": ["etp23a", "etp23b"]
}
},
"Ethernet92": {
@@ -565,7 +565,7 @@
"lanes": "92,93,94,95",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp24"],
- "2x50G[40G,25G,10G]": ["etp24a", "etp24b"]
+ "2x50G[25G,10G]": ["etp24a", "etp24b"]
}
},
"Ethernet96": {
@@ -573,7 +573,7 @@
"lanes": "96,97,98,99",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp25"],
- "2x50G[40G,25G,10G]": ["etp25a", "etp25b"]
+ "2x50G[25G,10G]": ["etp25a", "etp25b"]
}
},
"Ethernet100": {
@@ -581,7 +581,7 @@
"lanes": "100,101,102,103",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp26"],
- "2x50G[40G,25G,10G]": ["etp26a", "etp26b"]
+ "2x50G[25G,10G]": ["etp26a", "etp26b"]
}
},
"Ethernet104": {
@@ -589,7 +589,7 @@
"lanes": "104,105,106,107",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp27"],
- "2x50G[40G,25G,10G]": ["etp27a", "etp27b"]
+ "2x50G[25G,10G]": ["etp27a", "etp27b"]
}
},
"Ethernet108": {
@@ -597,7 +597,7 @@
"lanes": "108,109,110,111",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp28"],
- "2x50G[40G,25G,10G]": ["etp28a", "etp28b"]
+ "2x50G[25G,10G]": ["etp28a", "etp28b"]
}
},
"Ethernet112": {
@@ -605,7 +605,7 @@
"lanes": "112,113,114,115",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp29"],
- "2x50G[40G,25G,10G]": ["etp29a", "etp29b"]
+ "2x50G[25G,10G]": ["etp29a", "etp29b"]
}
},
"Ethernet116": {
@@ -613,7 +613,7 @@
"lanes": "116,117,118,119",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp30"],
- "2x50G[40G,25G,10G]": ["etp30a", "etp30b"]
+ "2x50G[25G,10G]": ["etp30a", "etp30b"]
}
},
"Ethernet120": {
@@ -621,7 +621,7 @@
"lanes": "120,121,122,123",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp31"],
- "2x50G[40G,25G,10G]": ["etp31a", "etp31b"]
+ "2x50G[25G,10G]": ["etp31a", "etp31b"]
}
},
"Ethernet124": {
@@ -629,7 +629,7 @@
"lanes": "124,125,126,127",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp32"],
- "2x50G[40G,25G,10G]": ["etp32a", "etp32b"]
+ "2x50G[25G,10G]": ["etp32a", "etp32b"]
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn2740-r0/platform.json b/device/mellanox/x86_64-mlnx_msn2740-r0/platform.json
index e7847ee28582..387742f4e3a0 100644
--- a/device/mellanox/x86_64-mlnx_msn2740-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn2740-r0/platform.json
@@ -369,7 +369,7 @@
"lanes": "0,1,2,3",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp1"],
- "2x50G[40G,25G,10G]": ["etp1a", "etp1b"]
+ "2x50G[25G,10G]": ["etp1a", "etp1b"]
}
},
"Ethernet4": {
@@ -377,7 +377,7 @@
"lanes": "4,5,6,7",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp2"],
- "2x50G[40G,25G,10G]": ["etp2a", "etp2b"]
+ "2x50G[25G,10G]": ["etp2a", "etp2b"]
}
},
"Ethernet8": {
@@ -385,7 +385,7 @@
"lanes": "8,9,10,11",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp3"],
- "2x50G[40G,25G,10G]": ["etp3a", "etp3b"]
+ "2x50G[25G,10G]": ["etp3a", "etp3b"]
}
},
"Ethernet12": {
@@ -393,7 +393,7 @@
"lanes": "12,13,14,15",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp4"],
- "2x50G[40G,25G,10G]": ["etp4a", "etp4b"]
+ "2x50G[25G,10G]": ["etp4a", "etp4b"]
}
},
"Ethernet16": {
@@ -401,7 +401,7 @@
"lanes": "16,17,18,19",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp5"],
- "2x50G[40G,25G,10G]": ["etp5a", "etp5b"]
+ "2x50G[25G,10G]": ["etp5a", "etp5b"]
}
},
"Ethernet20": {
@@ -409,7 +409,7 @@
"lanes": "20,21,22,23",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp6"],
- "2x50G[40G,25G,10G]": ["etp6a", "etp6b"]
+ "2x50G[25G,10G]": ["etp6a", "etp6b"]
}
},
"Ethernet24": {
@@ -417,7 +417,7 @@
"lanes": "24,25,26,27",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp7"],
- "2x50G[40G,25G,10G]": ["etp7a", "etp7b"]
+ "2x50G[25G,10G]": ["etp7a", "etp7b"]
}
},
"Ethernet28": {
@@ -425,7 +425,7 @@
"lanes": "28,29,30,31",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp8"],
- "2x50G[40G,25G,10G]": ["etp8a", "etp8b"]
+ "2x50G[25G,10G]": ["etp8a", "etp8b"]
}
},
"Ethernet32": {
@@ -433,7 +433,7 @@
"lanes": "32,33,34,35",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp9"],
- "2x50G[40G,25G,10G]": ["etp9a", "etp9b"]
+ "2x50G[25G,10G]": ["etp9a", "etp9b"]
}
},
"Ethernet36": {
@@ -441,7 +441,7 @@
"lanes": "36,37,38,39",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp10"],
- "2x50G[40G,25G,10G]": ["etp10a", "etp10b"]
+ "2x50G[25G,10G]": ["etp10a", "etp10b"]
}
},
"Ethernet40": {
@@ -449,7 +449,7 @@
"lanes": "40,41,42,43",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp11"],
- "2x50G[40G,25G,10G]": ["etp11a", "etp11b"]
+ "2x50G[25G,10G]": ["etp11a", "etp11b"]
}
},
"Ethernet44": {
@@ -457,7 +457,7 @@
"lanes": "44,45,46,47",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp12"],
- "2x50G[40G,25G,10G]": ["etp12a", "etp12b"]
+ "2x50G[25G,10G]": ["etp12a", "etp12b"]
}
},
"Ethernet48": {
@@ -465,7 +465,7 @@
"lanes": "48,49,50,51",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp13"],
- "2x50G[40G,25G,10G]": ["etp13a", "etp13b"]
+ "2x50G[25G,10G]": ["etp13a", "etp13b"]
}
},
"Ethernet52": {
@@ -473,7 +473,7 @@
"lanes": "52,53,54,55",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp14"],
- "2x50G[40G,25G,10G]": ["etp14a", "etp14b"]
+ "2x50G[25G,10G]": ["etp14a", "etp14b"]
}
},
"Ethernet56": {
@@ -481,7 +481,7 @@
"lanes": "56,57,58,59",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp15"],
- "2x50G[40G,25G,10G]": ["etp15a", "etp15b"]
+ "2x50G[25G,10G]": ["etp15a", "etp15b"]
}
},
"Ethernet60": {
@@ -489,7 +489,7 @@
"lanes": "60,61,62,63",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp16"],
- "2x50G[40G,25G,10G]": ["etp16a", "etp16b"]
+ "2x50G[25G,10G]": ["etp16a", "etp16b"]
}
},
"Ethernet64": {
@@ -497,7 +497,7 @@
"lanes": "64,65,66,67",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp17"],
- "2x50G[40G,25G,10G]": ["etp17a", "etp17b"]
+ "2x50G[25G,10G]": ["etp17a", "etp17b"]
}
},
"Ethernet68": {
@@ -505,7 +505,7 @@
"lanes": "68,69,70,71",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp18"],
- "2x50G[40G,25G,10G]": ["etp18a", "etp18b"]
+ "2x50G[25G,10G]": ["etp18a", "etp18b"]
}
},
"Ethernet72": {
@@ -513,7 +513,7 @@
"lanes": "72,73,74,75",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp19"],
- "2x50G[40G,25G,10G]": ["etp19a", "etp19b"]
+ "2x50G[25G,10G]": ["etp19a", "etp19b"]
}
},
"Ethernet76": {
@@ -521,7 +521,7 @@
"lanes": "76,77,78,79",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp20"],
- "2x50G[40G,25G,10G]": ["etp20a", "etp20b"]
+ "2x50G[25G,10G]": ["etp20a", "etp20b"]
}
},
"Ethernet80": {
@@ -529,7 +529,7 @@
"lanes": "80,81,82,83",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp21"],
- "2x50G[40G,25G,10G]": ["etp21a", "etp21b"]
+ "2x50G[25G,10G]": ["etp21a", "etp21b"]
}
},
"Ethernet84": {
@@ -537,7 +537,7 @@
"lanes": "84,85,86,87",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp22"],
- "2x50G[40G,25G,10G]": ["etp22a", "etp22b"]
+ "2x50G[25G,10G]": ["etp22a", "etp22b"]
}
},
"Ethernet88": {
@@ -545,7 +545,7 @@
"lanes": "88,89,90,91",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp23"],
- "2x50G[40G,25G,10G]": ["etp23a", "etp23b"]
+ "2x50G[25G,10G]": ["etp23a", "etp23b"]
}
},
"Ethernet92": {
@@ -553,7 +553,7 @@
"lanes": "92,93,94,95",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp24"],
- "2x50G[40G,25G,10G]": ["etp24a", "etp24b"]
+ "2x50G[25G,10G]": ["etp24a", "etp24b"]
}
},
"Ethernet96": {
@@ -561,7 +561,7 @@
"lanes": "96,97,98,99",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp25"],
- "2x50G[40G,25G,10G]": ["etp25a", "etp25b"]
+ "2x50G[25G,10G]": ["etp25a", "etp25b"]
}
},
"Ethernet100": {
@@ -569,7 +569,7 @@
"lanes": "100,101,102,103",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp26"],
- "2x50G[40G,25G,10G]": ["etp26a", "etp26b"]
+ "2x50G[25G,10G]": ["etp26a", "etp26b"]
}
},
"Ethernet104": {
@@ -577,7 +577,7 @@
"lanes": "104,105,106,107",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp27"],
- "2x50G[40G,25G,10G]": ["etp27a", "etp27b"]
+ "2x50G[25G,10G]": ["etp27a", "etp27b"]
}
},
"Ethernet108": {
@@ -585,7 +585,7 @@
"lanes": "108,109,110,111",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp28"],
- "2x50G[40G,25G,10G]": ["etp28a", "etp28b"]
+ "2x50G[25G,10G]": ["etp28a", "etp28b"]
}
},
"Ethernet112": {
@@ -593,7 +593,7 @@
"lanes": "112,113,114,115",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp29"],
- "2x50G[40G,25G,10G]": ["etp29a", "etp29b"]
+ "2x50G[25G,10G]": ["etp29a", "etp29b"]
}
},
"Ethernet116": {
@@ -601,7 +601,7 @@
"lanes": "116,117,118,119",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp30"],
- "2x50G[40G,25G,10G]": ["etp30a", "etp30b"]
+ "2x50G[25G,10G]": ["etp30a", "etp30b"]
}
},
"Ethernet120": {
@@ -609,7 +609,7 @@
"lanes": "120,121,122,123",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp31"],
- "2x50G[40G,25G,10G]": ["etp31a", "etp31b"]
+ "2x50G[25G,10G]": ["etp31a", "etp31b"]
}
},
"Ethernet124": {
@@ -617,7 +617,7 @@
"lanes": "124,125,126,127",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp32"],
- "2x50G[40G,25G,10G]": ["etp32a", "etp32b"]
+ "2x50G[25G,10G]": ["etp32a", "etp32b"]
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn3420-r0/platform.json b/device/mellanox/x86_64-mlnx_msn3420-r0/platform.json
index 415d7de70ebb..b2848ae909d8 100644
--- a/device/mellanox/x86_64-mlnx_msn3420-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn3420-r0/platform.json
@@ -955,7 +955,7 @@
"lanes": "192,193,194,195",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp49"],
- "2x50G[40G,25G,10G,1G]": ["etp49a", "etp49b"],
+ "2x50G[25G,10G,1G]": ["etp49a", "etp49b"],
"4x25G[10G,1G]": ["etp49a", "etp49b", "etp49c", "etp49d"]
}
},
@@ -964,7 +964,7 @@
"lanes": "196,197,198,199",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp50"],
- "2x50G[40G,25G,10G,1G]": ["etp50a", "etp50b"],
+ "2x50G[25G,10G,1G]": ["etp50a", "etp50b"],
"4x25G[10G,1G]": ["etp50a", "etp50b", "etp50c", "etp50d"]
}
},
@@ -973,7 +973,7 @@
"lanes": "200,201,202,203",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp51"],
- "2x50G[40G,25G,10G,1G]": ["etp51a", "etp51b"],
+ "2x50G[25G,10G,1G]": ["etp51a", "etp51b"],
"4x25G[10G,1G]": ["etp51a", "etp51b", "etp51c", "etp51d"]
}
},
@@ -982,7 +982,7 @@
"lanes": "204,205,206,207",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp52"],
- "2x50G[40G,25G,10G,1G]": ["etp52a", "etp52b"],
+ "2x50G[25G,10G,1G]": ["etp52a", "etp52b"],
"4x25G[10G,1G]": ["etp52a", "etp52b", "etp52c", "etp52d"]
}
},
@@ -991,7 +991,7 @@
"lanes": "208,209,210,211",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp53"],
- "2x50G[40G,25G,10G,1G]": ["etp53a", "etp53b"],
+ "2x50G[25G,10G,1G]": ["etp53a", "etp53b"],
"4x25G[10G,1G]": ["etp53a", "etp53b", "etp53c", "etp53d"]
}
},
@@ -1000,7 +1000,7 @@
"lanes": "212,213,214,215",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp54"],
- "2x50G[40G,25G,10G,1G]": ["etp54a", "etp54b"],
+ "2x50G[25G,10G,1G]": ["etp54a", "etp54b"],
"4x25G[10G,1G]": ["etp54a", "etp54b", "etp54c", "etp54d"]
}
},
@@ -1009,7 +1009,7 @@
"lanes": "216,217,218,219",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp55"],
- "2x50G[40G,25G,10G,1G]": ["etp55a", "etp55b"],
+ "2x50G[25G,10G,1G]": ["etp55a", "etp55b"],
"4x25G[10G,1G]": ["etp55a", "etp55b", "etp55c", "etp55d"]
}
},
@@ -1018,7 +1018,7 @@
"lanes": "220,221,222,223",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp56"],
- "2x50G[40G,25G,10G,1G]": ["etp56a", "etp56b"],
+ "2x50G[25G,10G,1G]": ["etp56a", "etp56b"],
"4x25G[10G,1G]": ["etp56a", "etp56b", "etp56c", "etp56d"]
}
},
@@ -1027,7 +1027,7 @@
"lanes": "224,225,226,227",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp57"],
- "2x50G[40G,25G,10G,1G]": ["etp57a", "etp57b"],
+ "2x50G[25G,10G,1G]": ["etp57a", "etp57b"],
"4x25G[10G,1G]": ["etp57a", "etp57b", "etp57c", "etp57d"]
}
},
@@ -1036,7 +1036,7 @@
"lanes": "228,229,230,231",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp58"],
- "2x50G[40G,25G,10G,1G]": ["etp58a", "etp58b"],
+ "2x50G[25G,10G,1G]": ["etp58a", "etp58b"],
"4x25G[10G,1G]": ["etp58a", "etp58b", "etp58c", "etp58d"]
}
},
@@ -1045,7 +1045,7 @@
"lanes": "232,233,234,235",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp59"],
- "2x50G[40G,25G,10G,1G]": ["etp59a", "etp59b"],
+ "2x50G[25G,10G,1G]": ["etp59a", "etp59b"],
"4x25G[10G,1G]": ["etp59a", "etp59b", "etp59c", "etp59d"]
}
},
@@ -1054,7 +1054,7 @@
"lanes": "236,237,238,239",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp60"],
- "2x50G[40G,25G,10G,1G]": ["etp60a", "etp60b"],
+ "2x50G[25G,10G,1G]": ["etp60a", "etp60b"],
"4x25G[10G,1G]": ["etp60a", "etp60b", "etp60c", "etp60d"]
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn3700-r0/platform.json b/device/mellanox/x86_64-mlnx_msn3700-r0/platform.json
index ffb0d93cd37c..df6deb892b4b 100644
--- a/device/mellanox/x86_64-mlnx_msn3700-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn3700-r0/platform.json
@@ -412,8 +412,8 @@
"lanes": "0,1,2,3",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp1"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp1a", "etp1b"],
- "4x50G[40G,25G,10G,1G]": ["etp1a", "etp1b", "etp1c", "etp1d"]
+ "2x100G[50G,25G,10G,1G]": ["etp1a", "etp1b"],
+ "4x50G[25G,10G,1G]": ["etp1a", "etp1b", "etp1c", "etp1d"]
}
},
"Ethernet4": {
@@ -421,8 +421,8 @@
"lanes": "4,5,6,7",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp2"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp2a", "etp2b"],
- "4x50G[40G,25G,10G,1G]": ["etp2a", "etp2b", "etp2c", "etp2d"]
+ "2x100G[50G,25G,10G,1G]": ["etp2a", "etp2b"],
+ "4x50G[25G,10G,1G]": ["etp2a", "etp2b", "etp2c", "etp2d"]
}
},
"Ethernet8": {
@@ -430,8 +430,8 @@
"lanes": "8,9,10,11",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp3"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp3a", "etp3b"],
- "4x50G[40G,25G,10G,1G]": ["etp3a", "etp3b", "etp3c", "etp3d"]
+ "2x100G[50G,25G,10G,1G]": ["etp3a", "etp3b"],
+ "4x50G[25G,10G,1G]": ["etp3a", "etp3b", "etp3c", "etp3d"]
}
},
"Ethernet12": {
@@ -439,8 +439,8 @@
"lanes": "12,13,14,15",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp4"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp4a", "etp4b"],
- "4x50G[40G,25G,10G,1G]": ["etp4a", "etp4b", "etp4c", "etp4d"]
+ "2x100G[50G,25G,10G,1G]": ["etp4a", "etp4b"],
+ "4x50G[25G,10G,1G]": ["etp4a", "etp4b", "etp4c", "etp4d"]
}
},
"Ethernet16": {
@@ -448,8 +448,8 @@
"lanes": "16,17,18,19",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp5"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp5a", "etp5b"],
- "4x50G[40G,25G,10G,1G]": ["etp5a", "etp5b", "etp5c", "etp5d"]
+ "2x100G[50G,25G,10G,1G]": ["etp5a", "etp5b"],
+ "4x50G[25G,10G,1G]": ["etp5a", "etp5b", "etp5c", "etp5d"]
}
},
"Ethernet20": {
@@ -457,8 +457,8 @@
"lanes": "20,21,22,23",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp6"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp6a", "etp6b"],
- "4x50G[40G,25G,10G,1G]": ["etp6a", "etp6b", "etp6c", "etp6d"]
+ "2x100G[50G,25G,10G,1G]": ["etp6a", "etp6b"],
+ "4x50G[25G,10G,1G]": ["etp6a", "etp6b", "etp6c", "etp6d"]
}
},
"Ethernet24": {
@@ -466,8 +466,8 @@
"lanes": "24,25,26,27",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp7"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp7a", "etp7b"],
- "4x50G[40G,25G,10G,1G]": ["etp7a", "etp7b", "etp7c", "etp7d"]
+ "2x100G[50G,25G,10G,1G]": ["etp7a", "etp7b"],
+ "4x50G[25G,10G,1G]": ["etp7a", "etp7b", "etp7c", "etp7d"]
}
},
"Ethernet28": {
@@ -475,8 +475,8 @@
"lanes": "28,29,30,31",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp8"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp8a", "etp8b"],
- "4x50G[40G,25G,10G,1G]": ["etp8a", "etp8b", "etp8c", "etp8d"]
+ "2x100G[50G,25G,10G,1G]": ["etp8a", "etp8b"],
+ "4x50G[25G,10G,1G]": ["etp8a", "etp8b", "etp8c", "etp8d"]
}
},
"Ethernet32": {
@@ -484,8 +484,8 @@
"lanes": "32,33,34,35",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp9"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp9a", "etp9b"],
- "4x50G[40G,25G,10G,1G]": ["etp9a", "etp9b", "etp9c", "etp9d"]
+ "2x100G[50G,25G,10G,1G]": ["etp9a", "etp9b"],
+ "4x50G[25G,10G,1G]": ["etp9a", "etp9b", "etp9c", "etp9d"]
}
},
"Ethernet36": {
@@ -493,8 +493,8 @@
"lanes": "36,37,38,39",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp10"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp10a", "etp10b"],
- "4x50G[40G,25G,10G,1G]": ["etp10a", "etp10b", "etp10c", "etp10d"]
+ "2x100G[50G,25G,10G,1G]": ["etp10a", "etp10b"],
+ "4x50G[25G,10G,1G]": ["etp10a", "etp10b", "etp10c", "etp10d"]
}
},
"Ethernet40": {
@@ -502,8 +502,8 @@
"lanes": "40,41,42,43",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp11"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp11a", "etp11b"],
- "4x50G[40G,25G,10G,1G]": ["etp11a", "etp11b", "etp11c", "etp11d"]
+ "2x100G[50G,25G,10G,1G]": ["etp11a", "etp11b"],
+ "4x50G[25G,10G,1G]": ["etp11a", "etp11b", "etp11c", "etp11d"]
}
},
"Ethernet44": {
@@ -511,8 +511,8 @@
"lanes": "44,45,46,47",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp12"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp12a", "etp12b"],
- "4x50G[40G,25G,10G,1G]": ["etp12a", "etp12b", "etp12c", "etp12d"]
+ "2x100G[50G,25G,10G,1G]": ["etp12a", "etp12b"],
+ "4x50G[25G,10G,1G]": ["etp12a", "etp12b", "etp12c", "etp12d"]
}
},
"Ethernet48": {
@@ -520,8 +520,8 @@
"lanes": "48,49,50,51",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp13"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp13a", "etp13b"],
- "4x50G[40G,25G,10G,1G]": ["etp13a", "etp13b", "etp13c", "etp13d"]
+ "2x100G[50G,25G,10G,1G]": ["etp13a", "etp13b"],
+ "4x50G[25G,10G,1G]": ["etp13a", "etp13b", "etp13c", "etp13d"]
}
},
"Ethernet52": {
@@ -529,8 +529,8 @@
"lanes": "52,53,54,55",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp14"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp14a", "etp14b"],
- "4x50G[40G,25G,10G,1G]": ["etp14a", "etp14b", "etp14c", "etp14d"]
+ "2x100G[50G,25G,10G,1G]": ["etp14a", "etp14b"],
+ "4x50G[25G,10G,1G]": ["etp14a", "etp14b", "etp14c", "etp14d"]
}
},
"Ethernet56": {
@@ -538,8 +538,8 @@
"lanes": "56,57,58,59",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp15"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp15a", "etp15b"],
- "4x50G[40G,25G,10G,1G]": ["etp15a", "etp15b", "etp15c", "etp15d"]
+ "2x100G[50G,25G,10G,1G]": ["etp15a", "etp15b"],
+ "4x50G[25G,10G,1G]": ["etp15a", "etp15b", "etp15c", "etp15d"]
}
},
"Ethernet60": {
@@ -547,8 +547,8 @@
"lanes": "60,61,62,63",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp16"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp16a", "etp16b"],
- "4x50G[40G,25G,10G,1G]": ["etp16a", "etp16b", "etp16c", "etp16d"]
+ "2x100G[50G,25G,10G,1G]": ["etp16a", "etp16b"],
+ "4x50G[25G,10G,1G]": ["etp16a", "etp16b", "etp16c", "etp16d"]
}
},
"Ethernet64": {
@@ -556,8 +556,8 @@
"lanes": "64,65,66,67",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp17"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp17a", "etp17b"],
- "4x50G[40G,25G,10G,1G]": ["etp17a", "etp17b", "etp17c", "etp17d"]
+ "2x100G[50G,25G,10G,1G]": ["etp17a", "etp17b"],
+ "4x50G[25G,10G,1G]": ["etp17a", "etp17b", "etp17c", "etp17d"]
}
},
"Ethernet68": {
@@ -565,8 +565,8 @@
"lanes": "68,69,70,71",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp18"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp18a", "etp18b"],
- "4x50G[40G,25G,10G,1G]": ["etp18a", "etp18b", "etp18c", "etp18d"]
+ "2x100G[50G,25G,10G,1G]": ["etp18a", "etp18b"],
+ "4x50G[25G,10G,1G]": ["etp18a", "etp18b", "etp18c", "etp18d"]
}
},
"Ethernet72": {
@@ -574,8 +574,8 @@
"lanes": "72,73,74,75",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp19"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp19a", "etp19b"],
- "4x50G[40G,25G,10G,1G]": ["etp19a", "etp19b", "etp19c", "etp19d"]
+ "2x100G[50G,25G,10G,1G]": ["etp19a", "etp19b"],
+ "4x50G[25G,10G,1G]": ["etp19a", "etp19b", "etp19c", "etp19d"]
}
},
"Ethernet76": {
@@ -583,8 +583,8 @@
"lanes": "76,77,78,79",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp20"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp20a", "etp20b"],
- "4x50G[40G,25G,10G,1G]": ["etp20a", "etp20b", "etp20c", "etp20d"]
+ "2x100G[50G,25G,10G,1G]": ["etp20a", "etp20b"],
+ "4x50G[25G,10G,1G]": ["etp20a", "etp20b", "etp20c", "etp20d"]
}
},
"Ethernet80": {
@@ -592,8 +592,8 @@
"lanes": "80,81,82,83",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp21"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp21a", "etp21b"],
- "4x50G[40G,25G,10G,1G]": ["etp21a", "etp21b", "etp21c", "etp21d"]
+ "2x100G[50G,25G,10G,1G]": ["etp21a", "etp21b"],
+ "4x50G[25G,10G,1G]": ["etp21a", "etp21b", "etp21c", "etp21d"]
}
},
"Ethernet84": {
@@ -601,8 +601,8 @@
"lanes": "84,85,86,87",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp22"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp22a", "etp22b"],
- "4x50G[40G,25G,10G,1G]": ["etp22a", "etp22b", "etp22c", "etp22d"]
+ "2x100G[50G,25G,10G,1G]": ["etp22a", "etp22b"],
+ "4x50G[25G,10G,1G]": ["etp22a", "etp22b", "etp22c", "etp22d"]
}
},
"Ethernet88": {
@@ -610,8 +610,8 @@
"lanes": "88,89,90,91",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp23"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp23a", "etp23b"],
- "4x50G[40G,25G,10G,1G]": ["etp23a", "etp23b", "etp23c", "etp23d"]
+ "2x100G[50G,25G,10G,1G]": ["etp23a", "etp23b"],
+ "4x50G[25G,10G,1G]": ["etp23a", "etp23b", "etp23c", "etp23d"]
}
},
"Ethernet92": {
@@ -619,8 +619,8 @@
"lanes": "92,93,94,95",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp24"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp24a", "etp24b"],
- "4x50G[40G,25G,10G,1G]": ["etp24a", "etp24b", "etp24c", "etp24d"]
+ "2x100G[50G,25G,10G,1G]": ["etp24a", "etp24b"],
+ "4x50G[25G,10G,1G]": ["etp24a", "etp24b", "etp24c", "etp24d"]
}
},
"Ethernet96": {
@@ -628,8 +628,8 @@
"lanes": "96,97,98,99",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp25"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp25a", "etp25b"],
- "4x50G[40G,25G,10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"]
+ "2x100G[50G,25G,10G,1G]": ["etp25a", "etp25b"],
+ "4x50G[25G,10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"]
}
},
"Ethernet100": {
@@ -637,8 +637,8 @@
"lanes": "100,101,102,103",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp26"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp26a", "etp26b"],
- "4x50G[40G,25G,10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"]
+ "2x100G[50G,25G,10G,1G]": ["etp26a", "etp26b"],
+ "4x50G[25G,10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"]
}
},
"Ethernet104": {
@@ -646,8 +646,8 @@
"lanes": "104,105,106,107",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp27"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp27a", "etp27b"],
- "4x50G[40G,25G,10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"]
+ "2x100G[50G,25G,10G,1G]": ["etp27a", "etp27b"],
+ "4x50G[25G,10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"]
}
},
"Ethernet108": {
@@ -655,8 +655,8 @@
"lanes": "108,109,110,111",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp28"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp28a", "etp28b"],
- "4x50G[40G,25G,10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"]
+ "2x100G[50G,25G,10G,1G]": ["etp28a", "etp28b"],
+ "4x50G[25G,10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"]
}
},
"Ethernet112": {
@@ -664,8 +664,8 @@
"lanes": "112,113,114,115",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp29"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp29a", "etp29b"],
- "4x50G[40G,25G,10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"]
+ "2x100G[50G,25G,10G,1G]": ["etp29a", "etp29b"],
+ "4x50G[25G,10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"]
}
},
"Ethernet116": {
@@ -673,8 +673,8 @@
"lanes": "116,117,118,119",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp30"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp30a", "etp30b"],
- "4x50G[40G,25G,10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"]
+ "2x100G[50G,25G,10G,1G]": ["etp30a", "etp30b"],
+ "4x50G[25G,10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"]
}
},
"Ethernet120": {
@@ -682,8 +682,8 @@
"lanes": "120,121,122,123",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp31"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp31a", "etp31b"],
- "4x50G[40G,25G,10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"]
+ "2x100G[50G,25G,10G,1G]": ["etp31a", "etp31b"],
+ "4x50G[25G,10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"]
}
},
"Ethernet124": {
@@ -691,8 +691,8 @@
"lanes": "124,125,126,127",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp32"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp32a", "etp32b"],
- "4x50G[40G,25G,10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"]
+ "2x100G[50G,25G,10G,1G]": ["etp32a", "etp32b"],
+ "4x50G[25G,10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"]
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform.json b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform.json
index 821b8204e730..3eafd31ca3b4 100644
--- a/device/mellanox/x86_64-mlnx_msn3700c-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn3700c-r0/platform.json
@@ -384,7 +384,7 @@
"lanes": "0,1,2,3",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp1"],
- "2x50G[40G,25G,10G,1G]": ["etp1a", "etp1b"],
+ "2x50G[25G,10G,1G]": ["etp1a", "etp1b"],
"4x25G[10G,1G]": ["etp1a", "etp1b", "etp1c", "etp1d"]
}
},
@@ -393,7 +393,7 @@
"lanes": "4,5,6,7",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp2"],
- "2x50G[40G,25G,10G,1G]": ["etp2a", "etp2b"],
+ "2x50G[25G,10G,1G]": ["etp2a", "etp2b"],
"4x25G[10G,1G]": ["etp2a", "etp2b", "etp2c", "etp2d"]
}
},
@@ -402,7 +402,7 @@
"lanes": "8,9,10,11",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp3"],
- "2x50G[40G,25G,10G,1G]": ["etp3a", "etp3b"],
+ "2x50G[25G,10G,1G]": ["etp3a", "etp3b"],
"4x25G[10G,1G]": ["etp3a", "etp3b", "etp3c", "etp3d"]
}
},
@@ -411,7 +411,7 @@
"lanes": "12,13,14,15",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp4"],
- "2x50G[40G,25G,10G,1G]": ["etp4a", "etp4b"],
+ "2x50G[25G,10G,1G]": ["etp4a", "etp4b"],
"4x25G[10G,1G]": ["etp4a", "etp4b", "etp4c", "etp4d"]
}
},
@@ -420,7 +420,7 @@
"lanes": "16,17,18,19",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp5"],
- "2x50G[40G,25G,10G,1G]": ["etp5a", "etp5b"],
+ "2x50G[25G,10G,1G]": ["etp5a", "etp5b"],
"4x25G[10G,1G]": ["etp5a", "etp5b", "etp5c", "etp5d"]
}
},
@@ -429,7 +429,7 @@
"lanes": "20,21,22,23",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp6"],
- "2x50G[40G,25G,10G,1G]": ["etp6a", "etp6b"],
+ "2x50G[25G,10G,1G]": ["etp6a", "etp6b"],
"4x25G[10G,1G]": ["etp6a", "etp6b", "etp6c", "etp6d"]
}
},
@@ -438,7 +438,7 @@
"lanes": "24,25,26,27",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp7"],
- "2x50G[40G,25G,10G,1G]": ["etp7a", "etp7b"],
+ "2x50G[25G,10G,1G]": ["etp7a", "etp7b"],
"4x25G[10G,1G]": ["etp7a", "etp7b", "etp7c", "etp7d"]
}
},
@@ -447,7 +447,7 @@
"lanes": "28,29,30,31",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp8"],
- "2x50G[40G,25G,10G,1G]": ["etp8a", "etp8b"],
+ "2x50G[25G,10G,1G]": ["etp8a", "etp8b"],
"4x25G[10G,1G]": ["etp8a", "etp8b", "etp8c", "etp8d"]
}
},
@@ -456,7 +456,7 @@
"lanes": "32,33,34,35",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp9"],
- "2x50G[40G,25G,10G,1G]": ["etp9a", "etp9b"],
+ "2x50G[25G,10G,1G]": ["etp9a", "etp9b"],
"4x25G[10G,1G]": ["etp9a", "etp9b", "etp9c", "etp9d"]
}
},
@@ -465,7 +465,7 @@
"lanes": "36,37,38,39",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp10"],
- "2x50G[40G,25G,10G,1G]": ["etp10a", "etp10b"],
+ "2x50G[25G,10G,1G]": ["etp10a", "etp10b"],
"4x25G[10G,1G]": ["etp10a", "etp10b", "etp10c", "etp10d"]
}
},
@@ -474,7 +474,7 @@
"lanes": "40,41,42,43",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp11"],
- "2x50G[40G,25G,10G,1G]": ["etp11a", "etp11b"],
+ "2x50G[25G,10G,1G]": ["etp11a", "etp11b"],
"4x25G[10G,1G]": ["etp11a", "etp11b", "etp11c", "etp11d"]
}
},
@@ -483,7 +483,7 @@
"lanes": "44,45,46,47",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp12"],
- "2x50G[40G,25G,10G,1G]": ["etp12a", "etp12b"],
+ "2x50G[25G,10G,1G]": ["etp12a", "etp12b"],
"4x25G[10G,1G]": ["etp12a", "etp12b", "etp12c", "etp12d"]
}
},
@@ -492,7 +492,7 @@
"lanes": "48,49,50,51",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp13"],
- "2x50G[40G,25G,10G,1G]": ["etp13a", "etp13b"],
+ "2x50G[25G,10G,1G]": ["etp13a", "etp13b"],
"4x25G[10G,1G]": ["etp13a", "etp13b", "etp13c", "etp13d"]
}
},
@@ -501,7 +501,7 @@
"lanes": "52,53,54,55",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp14"],
- "2x50G[40G,25G,10G,1G]": ["etp14a", "etp14b"],
+ "2x50G[25G,10G,1G]": ["etp14a", "etp14b"],
"4x25G[10G,1G]": ["etp14a", "etp14b", "etp14c", "etp14d"]
}
},
@@ -510,7 +510,7 @@
"lanes": "56,57,58,59",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp15"],
- "2x50G[40G,25G,10G,1G]": ["etp15a", "etp15b"],
+ "2x50G[25G,10G,1G]": ["etp15a", "etp15b"],
"4x25G[10G,1G]": ["etp15a", "etp15b", "etp15c", "etp15d"]
}
},
@@ -519,7 +519,7 @@
"lanes": "60,61,62,63",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp16"],
- "2x50G[40G,25G,10G,1G]": ["etp16a", "etp16b"],
+ "2x50G[25G,10G,1G]": ["etp16a", "etp16b"],
"4x25G[10G,1G]": ["etp16a", "etp16b", "etp16c", "etp16d"]
}
},
@@ -528,7 +528,7 @@
"lanes": "64,65,66,67",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp17"],
- "2x50G[40G,25G,10G,1G]": ["etp17a", "etp17b"],
+ "2x50G[25G,10G,1G]": ["etp17a", "etp17b"],
"4x25G[10G,1G]": ["etp17a", "etp17b", "etp17c", "etp17d"]
}
},
@@ -537,7 +537,7 @@
"lanes": "68,69,70,71",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp18"],
- "2x50G[40G,25G,10G,1G]": ["etp18a", "etp18b"],
+ "2x50G[25G,10G,1G]": ["etp18a", "etp18b"],
"4x25G[10G,1G]": ["etp18a", "etp18b", "etp18c", "etp18d"]
}
},
@@ -546,7 +546,7 @@
"lanes": "72,73,74,75",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp19"],
- "2x50G[40G,25G,10G,1G]": ["etp19a", "etp19b"],
+ "2x50G[25G,10G,1G]": ["etp19a", "etp19b"],
"4x25G[10G,1G]": ["etp19a", "etp19b", "etp19c", "etp19d"]
}
},
@@ -555,7 +555,7 @@
"lanes": "76,77,78,79",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp20"],
- "2x50G[40G,25G,10G,1G]": ["etp20a", "etp20b"],
+ "2x50G[25G,10G,1G]": ["etp20a", "etp20b"],
"4x25G[10G,1G]": ["etp20a", "etp20b", "etp20c", "etp20d"]
}
},
@@ -564,7 +564,7 @@
"lanes": "80,81,82,83",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp21"],
- "2x50G[40G,25G,10G,1G]": ["etp21a", "etp21b"],
+ "2x50G[25G,10G,1G]": ["etp21a", "etp21b"],
"4x25G[10G,1G]": ["etp21a", "etp21b", "etp21c", "etp21d"]
}
},
@@ -573,7 +573,7 @@
"lanes": "84,85,86,87",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp22"],
- "2x50G[40G,25G,10G,1G]": ["etp22a", "etp22b"],
+ "2x50G[25G,10G,1G]": ["etp22a", "etp22b"],
"4x25G[10G,1G]": ["etp22a", "etp22b", "etp22c", "etp22d"]
}
},
@@ -582,7 +582,7 @@
"lanes": "88,89,90,91",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp23"],
- "2x50G[40G,25G,10G,1G]": ["etp23a", "etp23b"],
+ "2x50G[25G,10G,1G]": ["etp23a", "etp23b"],
"4x25G[10G,1G]": ["etp23a", "etp23b", "etp23c", "etp23d"]
}
},
@@ -591,7 +591,7 @@
"lanes": "92,93,94,95",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp24"],
- "2x50G[40G,25G,10G,1G]": ["etp24a", "etp24b"],
+ "2x50G[25G,10G,1G]": ["etp24a", "etp24b"],
"4x25G[10G,1G]": ["etp24a", "etp24b", "etp24c", "etp24d"]
}
},
@@ -600,7 +600,7 @@
"lanes": "96,97,98,99",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp25"],
- "2x50G[40G,25G,10G,1G]": ["etp25a", "etp25b"],
+ "2x50G[25G,10G,1G]": ["etp25a", "etp25b"],
"4x25G[10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"]
}
},
@@ -609,7 +609,7 @@
"lanes": "100,101,102,103",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp26"],
- "2x50G[40G,25G,10G,1G]": ["etp26a", "etp26b"],
+ "2x50G[25G,10G,1G]": ["etp26a", "etp26b"],
"4x25G[10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"]
}
},
@@ -618,7 +618,7 @@
"lanes": "104,105,106,107",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp27"],
- "2x50G[40G,25G,10G,1G]": ["etp27a", "etp27b"],
+ "2x50G[25G,10G,1G]": ["etp27a", "etp27b"],
"4x25G[10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"]
}
},
@@ -627,7 +627,7 @@
"lanes": "108,109,110,111",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp28"],
- "2x50G[40G,25G,10G,1G]": ["etp28a", "etp28b"],
+ "2x50G[25G,10G,1G]": ["etp28a", "etp28b"],
"4x25G[10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"]
}
},
@@ -636,7 +636,7 @@
"lanes": "112,113,114,115",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp29"],
- "2x50G[40G,25G,10G,1G]": ["etp29a", "etp29b"],
+ "2x50G[25G,10G,1G]": ["etp29a", "etp29b"],
"4x25G[10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"]
}
},
@@ -645,7 +645,7 @@
"lanes": "116,117,118,119",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp30"],
- "2x50G[40G,25G,10G,1G]": ["etp30a", "etp30b"],
+ "2x50G[25G,10G,1G]": ["etp30a", "etp30b"],
"4x25G[10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"]
}
},
@@ -654,7 +654,7 @@
"lanes": "120,121,122,123",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp31"],
- "2x50G[40G,25G,10G,1G]": ["etp31a", "etp31b"],
+ "2x50G[25G,10G,1G]": ["etp31a", "etp31b"],
"4x25G[10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"]
}
},
@@ -663,7 +663,7 @@
"lanes": "124,125,126,127",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp32"],
- "2x50G[40G,25G,10G,1G]": ["etp32a", "etp32b"],
+ "2x50G[25G,10G,1G]": ["etp32a", "etp32b"],
"4x25G[10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"]
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/hwsku.json b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/hwsku.json
index 5901836014fe..5bc784192c84 100644
--- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/hwsku.json
+++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D112C8/hwsku.json
@@ -1,148 +1,148 @@
{
"interfaces": {
"Ethernet0": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet2": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet4": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet6": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet8": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet10": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet12": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet14": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet16": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet18": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet20": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet22": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet24": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet26": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet28": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet30": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet32": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet34": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet36": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet38": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet40": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet42": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet44": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet46": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet48": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet50": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet52": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet54": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet56": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet58": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet60": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet62": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet64": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet66": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet68": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet70": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet72": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet74": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet76": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet78": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet80": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet82": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet84": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet86": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet88": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet90": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet92": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet94": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet96": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -151,16 +151,16 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet104": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet106": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet108": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet110": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet112": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -169,16 +169,16 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet120": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet122": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet124": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet126": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet128": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -187,16 +187,16 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet136": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet138": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet140": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet142": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet144": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -205,160 +205,160 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet152": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet154": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet156": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet158": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet160": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet162": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet164": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet166": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet168": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet170": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet172": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet174": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet176": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet178": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet180": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet182": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet184": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet186": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet188": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet190": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet192": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet194": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet196": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet198": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet200": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet202": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet204": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet206": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet208": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet210": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet212": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet214": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet216": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet218": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet220": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet222": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet224": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet226": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet228": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet230": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet232": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet234": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet236": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet238": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet240": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet242": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet244": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet246": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet248": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet250": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet252": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet254": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/hwsku.json b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/hwsku.json
index 1c76295f197d..04826b7f557c 100644
--- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/hwsku.json
+++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D24C52/hwsku.json
@@ -25,28 +25,28 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet32": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet34": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet36": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet38": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet40": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet42": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet44": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet46": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet48": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -91,16 +91,16 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet104": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet106": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet108": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet110": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet112": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -151,28 +151,28 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet176": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet178": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet180": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet182": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet184": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet186": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet188": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet190": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet192": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -211,16 +211,16 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet240": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet242": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet244": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet246": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet248": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C49S1/hwsku.json b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C49S1/hwsku.json
index 4e047d0cefa4..83c69052a64c 100644
--- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C49S1/hwsku.json
+++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C49S1/hwsku.json
@@ -25,28 +25,28 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet32": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet34": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet36": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet38": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet40": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet42": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet44": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet46": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet48": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -91,16 +91,16 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet104": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet106": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet108": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet110": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet112": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -142,10 +142,10 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet164": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet166": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet168": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -154,28 +154,28 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet176": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet178": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet180": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet182": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet184": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet186": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet188": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet190": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet192": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -214,22 +214,22 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet240": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet242": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet244": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet246": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet248": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet250": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet252": {
"default_brkout_mode": "1x10G[100G,50G,40G,25G]"
diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/hwsku.json b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/hwsku.json
index fd7584babec5..f7334a858bf1 100644
--- a/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/hwsku.json
+++ b/device/mellanox/x86_64-mlnx_msn3800-r0/Mellanox-SN3800-D28C50/hwsku.json
@@ -25,28 +25,28 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet32": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet34": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet36": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet38": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet40": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet42": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet44": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet46": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet48": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -91,16 +91,16 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet104": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet106": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet108": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet110": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet112": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -151,28 +151,28 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet176": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet178": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet180": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet182": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet184": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet186": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet188": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet190": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet192": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
@@ -211,28 +211,28 @@
"default_brkout_mode": "1x100G[50G,40G,25G,10G]"
},
"Ethernet240": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet242": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet244": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet246": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet248": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet250": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet252": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
},
"Ethernet254": {
- "default_brkout_mode": "2x50G[40G,25G,10G]"
+ "default_brkout_mode": "2x50G[25G,10G]"
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn3800-r0/platform.json b/device/mellanox/x86_64-mlnx_msn3800-r0/platform.json
index 3c458e4e1cea..db273059482c 100644
--- a/device/mellanox/x86_64-mlnx_msn3800-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn3800-r0/platform.json
@@ -725,7 +725,7 @@
"lanes": "0,1,2,3",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp1"],
- "2x50G[40G,25G,10G]": ["etp1a", "etp1b"]
+ "2x50G[25G,10G]": ["etp1a", "etp1b"]
}
},
"Ethernet4": {
@@ -733,7 +733,7 @@
"lanes": "4,5,6,7",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp2"],
- "2x50G[40G,25G,10G]": ["etp2a", "etp2b"]
+ "2x50G[25G,10G]": ["etp2a", "etp2b"]
}
},
"Ethernet8": {
@@ -741,7 +741,7 @@
"lanes": "8,9,10,11",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp3"],
- "2x50G[40G,25G,10G]": ["etp3a", "etp3b"]
+ "2x50G[25G,10G]": ["etp3a", "etp3b"]
}
},
"Ethernet12": {
@@ -749,7 +749,7 @@
"lanes": "12,13,14,15",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp4"],
- "2x50G[40G,25G,10G]": ["etp4a", "etp4b"]
+ "2x50G[25G,10G]": ["etp4a", "etp4b"]
}
},
"Ethernet16": {
@@ -757,7 +757,7 @@
"lanes": "16,17,18,19",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp5"],
- "2x50G[40G,25G,10G]": ["etp5a", "etp5b"]
+ "2x50G[25G,10G]": ["etp5a", "etp5b"]
}
},
"Ethernet20": {
@@ -765,7 +765,7 @@
"lanes": "20,21,22,23",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp6"],
- "2x50G[40G,25G,10G]": ["etp6a", "etp6b"]
+ "2x50G[25G,10G]": ["etp6a", "etp6b"]
}
},
"Ethernet24": {
@@ -773,7 +773,7 @@
"lanes": "24,25,26,27",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp7"],
- "2x50G[40G,25G,10G]": ["etp7a", "etp7b"]
+ "2x50G[25G,10G]": ["etp7a", "etp7b"]
}
},
"Ethernet28": {
@@ -781,7 +781,7 @@
"lanes": "28,29,30,31",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp8"],
- "2x50G[40G,25G,10G]": ["etp8a", "etp8b"]
+ "2x50G[25G,10G]": ["etp8a", "etp8b"]
}
},
"Ethernet32": {
@@ -789,7 +789,7 @@
"lanes": "32,33,34,35",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp9"],
- "2x50G[40G,25G,10G]": ["etp9a", "etp9b"]
+ "2x50G[25G,10G]": ["etp9a", "etp9b"]
}
},
"Ethernet36": {
@@ -797,7 +797,7 @@
"lanes": "36,37,38,39",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp10"],
- "2x50G[40G,25G,10G]": ["etp10a", "etp10b"]
+ "2x50G[25G,10G]": ["etp10a", "etp10b"]
}
},
"Ethernet40": {
@@ -805,7 +805,7 @@
"lanes": "40,41,42,43",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp11"],
- "2x50G[40G,25G,10G]": ["etp11a", "etp11b"]
+ "2x50G[25G,10G]": ["etp11a", "etp11b"]
}
},
"Ethernet44": {
@@ -813,7 +813,7 @@
"lanes": "44,45,46,47",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp12"],
- "2x50G[40G,25G,10G]": ["etp12a", "etp12b"]
+ "2x50G[25G,10G]": ["etp12a", "etp12b"]
}
},
"Ethernet48": {
@@ -821,7 +821,7 @@
"lanes": "48,49,50,51",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp13"],
- "2x50G[40G,25G,10G]": ["etp13a", "etp13b"]
+ "2x50G[25G,10G]": ["etp13a", "etp13b"]
}
},
"Ethernet52": {
@@ -829,7 +829,7 @@
"lanes": "52,53,54,55",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp14"],
- "2x50G[40G,25G,10G]": ["etp14a", "etp14b"]
+ "2x50G[25G,10G]": ["etp14a", "etp14b"]
}
},
"Ethernet56": {
@@ -837,7 +837,7 @@
"lanes": "56,57,58,59",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp15"],
- "2x50G[40G,25G,10G]": ["etp15a", "etp15b"]
+ "2x50G[25G,10G]": ["etp15a", "etp15b"]
}
},
"Ethernet60": {
@@ -845,7 +845,7 @@
"lanes": "60,61,62,63",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp16"],
- "2x50G[40G,25G,10G]": ["etp16a", "etp16b"]
+ "2x50G[25G,10G]": ["etp16a", "etp16b"]
}
},
"Ethernet64": {
@@ -853,7 +853,7 @@
"lanes": "64,65,66,67",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp17"],
- "2x50G[40G,25G,10G]": ["etp17a", "etp17b"]
+ "2x50G[25G,10G]": ["etp17a", "etp17b"]
}
},
"Ethernet68": {
@@ -861,7 +861,7 @@
"lanes": "68,69,70,71",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp18"],
- "2x50G[40G,25G,10G]": ["etp18a", "etp18b"]
+ "2x50G[25G,10G]": ["etp18a", "etp18b"]
}
},
"Ethernet72": {
@@ -869,7 +869,7 @@
"lanes": "72,73,74,75",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp19"],
- "2x50G[40G,25G,10G]": ["etp19a", "etp19b"]
+ "2x50G[25G,10G]": ["etp19a", "etp19b"]
}
},
"Ethernet76": {
@@ -877,7 +877,7 @@
"lanes": "76,77,78,79",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp20"],
- "2x50G[40G,25G,10G]": ["etp20a", "etp20b"]
+ "2x50G[25G,10G]": ["etp20a", "etp20b"]
}
},
"Ethernet80": {
@@ -885,7 +885,7 @@
"lanes": "80,81,82,83",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp21"],
- "2x50G[40G,25G,10G]": ["etp21a", "etp21b"]
+ "2x50G[25G,10G]": ["etp21a", "etp21b"]
}
},
"Ethernet84": {
@@ -893,7 +893,7 @@
"lanes": "84,85,86,87",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp22"],
- "2x50G[40G,25G,10G]": ["etp22a", "etp22b"]
+ "2x50G[25G,10G]": ["etp22a", "etp22b"]
}
},
"Ethernet88": {
@@ -901,7 +901,7 @@
"lanes": "88,89,90,91",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp23"],
- "2x50G[40G,25G,10G]": ["etp23a", "etp23b"]
+ "2x50G[25G,10G]": ["etp23a", "etp23b"]
}
},
"Ethernet92": {
@@ -909,7 +909,7 @@
"lanes": "92,93,94,95",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp24"],
- "2x50G[40G,25G,10G]": ["etp24a", "etp24b"]
+ "2x50G[25G,10G]": ["etp24a", "etp24b"]
}
},
"Ethernet96": {
@@ -917,7 +917,7 @@
"lanes": "96,97,98,99",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp25"],
- "2x50G[40G,25G,10G]": ["etp25a", "etp25b"]
+ "2x50G[25G,10G]": ["etp25a", "etp25b"]
}
},
"Ethernet100": {
@@ -925,7 +925,7 @@
"lanes": "100,101,102,103",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp26"],
- "2x50G[40G,25G,10G]": ["etp26a", "etp26b"]
+ "2x50G[25G,10G]": ["etp26a", "etp26b"]
}
},
"Ethernet104": {
@@ -933,7 +933,7 @@
"lanes": "104,105,106,107",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp27"],
- "2x50G[40G,25G,10G]": ["etp27a", "etp27b"]
+ "2x50G[25G,10G]": ["etp27a", "etp27b"]
}
},
"Ethernet108": {
@@ -941,7 +941,7 @@
"lanes": "108,109,110,111",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp28"],
- "2x50G[40G,25G,10G]": ["etp28a", "etp28b"]
+ "2x50G[25G,10G]": ["etp28a", "etp28b"]
}
},
"Ethernet112": {
@@ -949,7 +949,7 @@
"lanes": "112,113,114,115",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp29"],
- "2x50G[40G,25G,10G]": ["etp29a", "etp29b"]
+ "2x50G[25G,10G]": ["etp29a", "etp29b"]
}
},
"Ethernet116": {
@@ -957,7 +957,7 @@
"lanes": "116,117,118,119",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp30"],
- "2x50G[40G,25G,10G]": ["etp30a", "etp30b"]
+ "2x50G[25G,10G]": ["etp30a", "etp30b"]
}
},
"Ethernet120": {
@@ -965,7 +965,7 @@
"lanes": "120,121,122,123",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp31"],
- "2x50G[40G,25G,10G]": ["etp31a", "etp31b"]
+ "2x50G[25G,10G]": ["etp31a", "etp31b"]
}
},
"Ethernet124": {
@@ -973,7 +973,7 @@
"lanes": "124,125,126,127",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp32"],
- "2x50G[40G,25G,10G]": ["etp32a", "etp32b"]
+ "2x50G[25G,10G]": ["etp32a", "etp32b"]
}
},
"Ethernet128": {
@@ -981,7 +981,7 @@
"lanes": "128,129,130,131",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp33"],
- "2x50G[40G,25G,10G]": ["etp33a", "etp33b"]
+ "2x50G[25G,10G]": ["etp33a", "etp33b"]
}
},
"Ethernet132": {
@@ -989,7 +989,7 @@
"lanes": "132,133,134,135",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp34"],
- "2x50G[40G,25G,10G]": ["etp34a", "etp34b"]
+ "2x50G[25G,10G]": ["etp34a", "etp34b"]
}
},
"Ethernet136": {
@@ -997,7 +997,7 @@
"lanes": "136,137,138,139",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp35"],
- "2x50G[40G,25G,10G]": ["etp35a", "etp35b"]
+ "2x50G[25G,10G]": ["etp35a", "etp35b"]
}
},
"Ethernet140": {
@@ -1005,7 +1005,7 @@
"lanes": "140,141,142,143",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp36"],
- "2x50G[40G,25G,10G]": ["etp36a", "etp36b"]
+ "2x50G[25G,10G]": ["etp36a", "etp36b"]
}
},
"Ethernet144": {
@@ -1013,7 +1013,7 @@
"lanes": "144,145,146,147",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp37"],
- "2x50G[40G,25G,10G]": ["etp37a", "etp37b"]
+ "2x50G[25G,10G]": ["etp37a", "etp37b"]
}
},
"Ethernet148": {
@@ -1021,7 +1021,7 @@
"lanes": "148,149,150,151",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp38"],
- "2x50G[40G,25G,10G]": ["etp38a", "etp38b"]
+ "2x50G[25G,10G]": ["etp38a", "etp38b"]
}
},
"Ethernet152": {
@@ -1029,7 +1029,7 @@
"lanes": "152,153,154,155",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp39"],
- "2x50G[40G,25G,10G]": ["etp39a", "etp39b"]
+ "2x50G[25G,10G]": ["etp39a", "etp39b"]
}
},
"Ethernet156": {
@@ -1037,7 +1037,7 @@
"lanes": "156,157,158,159",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp40"],
- "2x50G[40G,25G,10G]": ["etp40a", "etp40b"]
+ "2x50G[25G,10G]": ["etp40a", "etp40b"]
}
},
"Ethernet160": {
@@ -1045,7 +1045,7 @@
"lanes": "160,161,162,163",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp41"],
- "2x50G[40G,25G,10G]": ["etp41a", "etp41b"]
+ "2x50G[25G,10G]": ["etp41a", "etp41b"]
}
},
"Ethernet164": {
@@ -1053,7 +1053,7 @@
"lanes": "164,165,166,167",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp42"],
- "2x50G[40G,25G,10G]": ["etp42a", "etp42b"]
+ "2x50G[25G,10G]": ["etp42a", "etp42b"]
}
},
"Ethernet168": {
@@ -1061,7 +1061,7 @@
"lanes": "168,169,170,171",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp43"],
- "2x50G[40G,25G,10G]": ["etp43a", "etp43b"]
+ "2x50G[25G,10G]": ["etp43a", "etp43b"]
}
},
"Ethernet172": {
@@ -1069,7 +1069,7 @@
"lanes": "172,173,174,175",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp44"],
- "2x50G[40G,25G,10G]": ["etp44a", "etp44b"]
+ "2x50G[25G,10G]": ["etp44a", "etp44b"]
}
},
"Ethernet176": {
@@ -1077,7 +1077,7 @@
"lanes": "176,177,178,179",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp45"],
- "2x50G[40G,25G,10G]": ["etp45a", "etp45b"]
+ "2x50G[25G,10G]": ["etp45a", "etp45b"]
}
},
"Ethernet180": {
@@ -1085,7 +1085,7 @@
"lanes": "180,181,182,183",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp46"],
- "2x50G[40G,25G,10G]": ["etp46a", "etp46b"]
+ "2x50G[25G,10G]": ["etp46a", "etp46b"]
}
},
"Ethernet184": {
@@ -1093,7 +1093,7 @@
"lanes": "184,185,186,187",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp47"],
- "2x50G[40G,25G,10G]": ["etp47a", "etp47b"]
+ "2x50G[25G,10G]": ["etp47a", "etp47b"]
}
},
"Ethernet188": {
@@ -1101,7 +1101,7 @@
"lanes": "188,189,190,191",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp48"],
- "2x50G[40G,25G,10G]": ["etp48a", "etp48b"]
+ "2x50G[25G,10G]": ["etp48a", "etp48b"]
}
},
"Ethernet192": {
@@ -1109,7 +1109,7 @@
"lanes": "192,193,194,195",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp49"],
- "2x50G[40G,25G,10G]": ["etp49a", "etp49b"]
+ "2x50G[25G,10G]": ["etp49a", "etp49b"]
}
},
"Ethernet196": {
@@ -1117,7 +1117,7 @@
"lanes": "196,197,198,199",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp50"],
- "2x50G[40G,25G,10G]": ["etp50a", "etp50b"]
+ "2x50G[25G,10G]": ["etp50a", "etp50b"]
}
},
"Ethernet200": {
@@ -1125,7 +1125,7 @@
"lanes": "200,201,202,203",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp51"],
- "2x50G[40G,25G,10G]": ["etp51a", "etp51b"]
+ "2x50G[25G,10G]": ["etp51a", "etp51b"]
}
},
"Ethernet204": {
@@ -1133,7 +1133,7 @@
"lanes": "204,205,206,207",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp52"],
- "2x50G[40G,25G,10G]": ["etp52a", "etp52b"]
+ "2x50G[25G,10G]": ["etp52a", "etp52b"]
}
},
"Ethernet208": {
@@ -1141,7 +1141,7 @@
"lanes": "208,209,210,211",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp53"],
- "2x50G[40G,25G,10G]": ["etp53a", "etp53b"]
+ "2x50G[25G,10G]": ["etp53a", "etp53b"]
}
},
"Ethernet212": {
@@ -1149,7 +1149,7 @@
"lanes": "212,213,214,215",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp54"],
- "2x50G[40G,25G,10G]": ["etp54a", "etp54b"]
+ "2x50G[25G,10G]": ["etp54a", "etp54b"]
}
},
"Ethernet216": {
@@ -1157,7 +1157,7 @@
"lanes": "216,217,218,219",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp55"],
- "2x50G[40G,25G,10G]": ["etp55a", "etp55b"]
+ "2x50G[25G,10G]": ["etp55a", "etp55b"]
}
},
"Ethernet220": {
@@ -1165,7 +1165,7 @@
"lanes": "220,221,222,223",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp56"],
- "2x50G[40G,25G,10G]": ["etp56a", "etp56b"]
+ "2x50G[25G,10G]": ["etp56a", "etp56b"]
}
},
"Ethernet224": {
@@ -1173,7 +1173,7 @@
"lanes": "224,225,226,227",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp57"],
- "2x50G[40G,25G,10G]": ["etp57a", "etp57b"]
+ "2x50G[25G,10G]": ["etp57a", "etp57b"]
}
},
"Ethernet228": {
@@ -1181,7 +1181,7 @@
"lanes": "228,229,230,231",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp58"],
- "2x50G[40G,25G,10G]": ["etp58a", "etp58b"]
+ "2x50G[25G,10G]": ["etp58a", "etp58b"]
}
},
"Ethernet232": {
@@ -1189,7 +1189,7 @@
"lanes": "232,233,234,235",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp59"],
- "2x50G[40G,25G,10G]": ["etp59a", "etp59b"]
+ "2x50G[25G,10G]": ["etp59a", "etp59b"]
}
},
"Ethernet236": {
@@ -1197,7 +1197,7 @@
"lanes": "236,237,238,239",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp60"],
- "2x50G[40G,25G,10G]": ["etp60a", "etp60b"]
+ "2x50G[25G,10G]": ["etp60a", "etp60b"]
}
},
"Ethernet240": {
@@ -1205,7 +1205,7 @@
"lanes": "240,241,242,243",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp61"],
- "2x50G[40G,25G,10G]": ["etp61a", "etp61b"]
+ "2x50G[25G,10G]": ["etp61a", "etp61b"]
}
},
"Ethernet244": {
@@ -1213,7 +1213,7 @@
"lanes": "244,245,246,247",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp62"],
- "2x50G[40G,25G,10G]": ["etp62a", "etp62b"]
+ "2x50G[25G,10G]": ["etp62a", "etp62b"]
}
},
"Ethernet248": {
@@ -1221,7 +1221,7 @@
"lanes": "248,249,250,251",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp63"],
- "2x50G[40G,25G,10G]": ["etp63a", "etp63b"]
+ "2x50G[25G,10G]": ["etp63a", "etp63b"]
}
},
"Ethernet252": {
@@ -1229,7 +1229,7 @@
"lanes": "252,253,254,255",
"breakout_modes": {
"1x100G[50G,40G,25G,10G]": ["etp64"],
- "2x50G[40G,25G,10G]": ["etp64a", "etp64b"]
+ "2x50G[25G,10G]": ["etp64a", "etp64b"]
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn4410-r0/platform.json b/device/mellanox/x86_64-mlnx_msn4410-r0/platform.json
index 61df8efaedbe..75722fd0d5e3 100644
--- a/device/mellanox/x86_64-mlnx_msn4410-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn4410-r0/platform.json
@@ -412,7 +412,7 @@
"lanes": "0,1,2,3",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp1"],
- "2x50G[40G,25G,10G,1G]": ["etp1a", "etp1b"],
+ "2x50G[25G,10G,1G]": ["etp1a", "etp1b"],
"4x25G[10G,1G]": ["etp1a", "etp1b", "etp1c", "etp1d"]
}
},
@@ -421,7 +421,7 @@
"lanes": "8,9,10,11",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp2"],
- "2x50G[40G,25G,10G,1G]": ["etp2a", "etp2b"],
+ "2x50G[25G,10G,1G]": ["etp2a", "etp2b"],
"4x25G[10G,1G]": ["etp2a", "etp2b", "etp2c", "etp2d"]
}
},
@@ -430,7 +430,7 @@
"lanes": "16,17,18,19",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp3"],
- "2x50G[40G,25G,10G,1G]": ["etp3a", "etp3b"],
+ "2x50G[25G,10G,1G]": ["etp3a", "etp3b"],
"4x25G[10G,1G]": ["etp3a", "etp3b", "etp3c", "etp3d"]
}
},
@@ -439,7 +439,7 @@
"lanes": "24,25,26,27",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp4"],
- "2x50G[40G,25G,10G,1G]": ["etp4a", "etp4b"],
+ "2x50G[25G,10G,1G]": ["etp4a", "etp4b"],
"4x25G[10G,1G]": ["etp4a", "etp4b", "etp4c", "etp4d"]
}
},
@@ -448,7 +448,7 @@
"lanes": "32,33,34,35",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp5"],
- "2x50G[40G,25G,10G,1G]": ["etp5a", "etp5b"],
+ "2x50G[25G,10G,1G]": ["etp5a", "etp5b"],
"4x25G[10G,1G]": ["etp5a", "etp5b", "etp5c", "etp5d"]
}
},
@@ -457,7 +457,7 @@
"lanes": "40,41,42,43",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp6"],
- "2x50G[40G,25G,10G,1G]": ["etp6a", "etp6b"],
+ "2x50G[25G,10G,1G]": ["etp6a", "etp6b"],
"4x25G[10G,1G]": ["etp6a", "etp6b", "etp6c", "etp6d"]
}
},
@@ -466,7 +466,7 @@
"lanes": "48,49,50,51",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp7"],
- "2x50G[40G,25G,10G,1G]": ["etp7a", "etp7b"],
+ "2x50G[25G,10G,1G]": ["etp7a", "etp7b"],
"4x25G[10G,1G]": ["etp7a", "etp7b", "etp7c", "etp7d"]
}
},
@@ -475,7 +475,7 @@
"lanes": "56,57,58,59",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp8"],
- "2x50G[40G,25G,10G,1G]": ["etp8a", "etp8b"],
+ "2x50G[25G,10G,1G]": ["etp8a", "etp8b"],
"4x25G[10G,1G]": ["etp8a", "etp8b", "etp8c", "etp8d"]
}
},
@@ -484,7 +484,7 @@
"lanes": "64,65,66,67",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp9"],
- "2x50G[40G,25G,10G,1G]": ["etp9a", "etp9b"],
+ "2x50G[25G,10G,1G]": ["etp9a", "etp9b"],
"4x25G[10G,1G]": ["etp9a", "etp9b", "etp9c", "etp9d"]
}
},
@@ -493,7 +493,7 @@
"lanes": "72,73,74,75",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp10"],
- "2x50G[40G,25G,10G,1G]": ["etp10a", "etp10b"],
+ "2x50G[25G,10G,1G]": ["etp10a", "etp10b"],
"4x25G[10G,1G]": ["etp10a", "etp10b", "etp10c", "etp10d"]
}
},
@@ -502,7 +502,7 @@
"lanes": "80,81,82,83",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp11"],
- "2x50G[40G,25G,10G,1G]": ["etp11a", "etp11b"],
+ "2x50G[25G,10G,1G]": ["etp11a", "etp11b"],
"4x25G[10G,1G]": ["etp11a", "etp11b", "etp11c", "etp11d"]
}
},
@@ -511,7 +511,7 @@
"lanes": "88,89,90,91",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp12"],
- "2x50G[40G,25G,10G,1G]": ["etp12a", "etp12b"],
+ "2x50G[25G,10G,1G]": ["etp12a", "etp12b"],
"4x25G[10G,1G]": ["etp12a", "etp12b", "etp12c", "etp12d"]
}
},
@@ -520,7 +520,7 @@
"lanes": "96,97,98,99",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp13"],
- "2x50G[40G,25G,10G,1G]": ["etp13a", "etp13b"],
+ "2x50G[25G,10G,1G]": ["etp13a", "etp13b"],
"4x25G[10G,1G]": ["etp13a", "etp13b", "etp13c", "etp13d"]
}
},
@@ -529,7 +529,7 @@
"lanes": "104,105,106,107",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp14"],
- "2x50G[40G,25G,10G,1G]": ["etp14a", "etp14b"],
+ "2x50G[25G,10G,1G]": ["etp14a", "etp14b"],
"4x25G[10G,1G]": ["etp14a", "etp14b", "etp14c", "etp14d"]
}
},
@@ -538,7 +538,7 @@
"lanes": "112,113,114,115",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp15"],
- "2x50G[40G,25G,10G,1G]": ["etp15a", "etp15b"],
+ "2x50G[25G,10G,1G]": ["etp15a", "etp15b"],
"4x25G[10G,1G]": ["etp15a", "etp15b", "etp15c", "etp15d"]
}
},
@@ -547,7 +547,7 @@
"lanes": "120,121,122,123",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp16"],
- "2x50G[40G,25G,10G,1G]": ["etp16a", "etp16b"],
+ "2x50G[25G,10G,1G]": ["etp16a", "etp16b"],
"4x25G[10G,1G]": ["etp16a", "etp16b", "etp16c", "etp16d"]
}
},
@@ -556,7 +556,7 @@
"lanes": "128,129,130,131",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp17"],
- "2x50G[40G,25G,10G,1G]": ["etp17a", "etp17b"],
+ "2x50G[25G,10G,1G]": ["etp17a", "etp17b"],
"4x25G[10G,1G]": ["etp17a", "etp17b", "etp17c", "etp17d"]
}
},
@@ -565,7 +565,7 @@
"lanes": "136,137,138,139",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp18"],
- "2x50G[40G,25G,10G,1G]": ["etp18a", "etp18b"],
+ "2x50G[25G,10G,1G]": ["etp18a", "etp18b"],
"4x25G[10G,1G]": ["etp18a", "etp18b", "etp18c", "etp18d"]
}
},
@@ -574,7 +574,7 @@
"lanes": "144,145,146,147",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp19"],
- "2x50G[40G,25G,10G,1G]": ["etp19a", "etp19b"],
+ "2x50G[25G,10G,1G]": ["etp19a", "etp19b"],
"4x25G[10G,1G]": ["etp19a", "etp19b", "etp19c", "etp19d"]
}
},
@@ -583,7 +583,7 @@
"lanes": "152,153,154,155",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp20"],
- "2x50G[40G,25G,10G,1G]": ["etp20a", "etp20b"],
+ "2x50G[25G,10G,1G]": ["etp20a", "etp20b"],
"4x25G[10G,1G]": ["etp20a", "etp20b", "etp20c", "etp20d"]
}
},
@@ -592,7 +592,7 @@
"lanes": "160,161,162,163",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp21"],
- "2x50G[40G,25G,10G,1G]": ["etp21a", "etp21b"],
+ "2x50G[25G,10G,1G]": ["etp21a", "etp21b"],
"4x25G[10G,1G]": ["etp21a", "etp21b", "etp21c", "etp21d"]
}
},
@@ -601,7 +601,7 @@
"lanes": "168,169,170,171",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp22"],
- "2x50G[40G,25G,10G,1G]": ["etp22a", "etp22b"],
+ "2x50G[25G,10G,1G]": ["etp22a", "etp22b"],
"4x25G[10G,1G]": ["etp22a", "etp22b", "etp22c", "etp22d"]
}
},
@@ -610,7 +610,7 @@
"lanes": "176,177,178,179",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp23"],
- "2x50G[40G,25G,10G,1G]": ["etp23a", "etp23b"],
+ "2x50G[25G,10G,1G]": ["etp23a", "etp23b"],
"4x25G[10G,1G]": ["etp23a", "etp23b", "etp23c", "etp23d"]
}
},
@@ -619,7 +619,7 @@
"lanes": "184,185,186,187",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp24"],
- "2x50G[40G,25G,10G,1G]": ["etp24a", "etp24b"],
+ "2x50G[25G,10G,1G]": ["etp24a", "etp24b"],
"4x25G[10G,1G]": ["etp24a", "etp24b", "etp24c", "etp24d"]
}
},
@@ -628,8 +628,8 @@
"lanes": "192,193,194,195,196,197,198,199",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp25"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp25a", "etp25b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp25a", "etp25b"],
+ "4x100G[50G,25G,10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"]
}
},
"Ethernet200": {
@@ -637,8 +637,8 @@
"lanes": "200,201,202,203,204,205,206,207",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp26"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp26a", "etp26b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp26a", "etp26b"],
+ "4x100G[50G,25G,10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"]
}
},
"Ethernet208": {
@@ -646,8 +646,8 @@
"lanes": "208,209,210,211,212,213,214,215",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp27"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp27a", "etp27b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp27a", "etp27b"],
+ "4x100G[50G,25G,10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"]
}
},
"Ethernet216": {
@@ -655,8 +655,8 @@
"lanes": "216,217,218,219,220,221,222,223",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp28"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp28a", "etp28b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp28a", "etp28b"],
+ "4x100G[50G,25G,10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"]
}
},
"Ethernet224": {
@@ -664,8 +664,8 @@
"lanes": "224,225,226,227,228,229,230,231",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp29"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp29a", "etp29b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp29a", "etp29b"],
+ "4x100G[50G,25G,10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"]
}
},
"Ethernet232": {
@@ -673,8 +673,8 @@
"lanes": "232,233,234,235,236,237,238,239",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp30"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp30a", "etp30b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp30a", "etp30b"],
+ "4x100G[50G,25G,10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"]
}
},
"Ethernet240": {
@@ -682,8 +682,8 @@
"lanes": "240,241,242,243,244,245,246,247",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp31"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp31a", "etp31b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp31a", "etp31b"],
+ "4x100G[50G,25G,10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"]
}
},
"Ethernet248": {
@@ -691,8 +691,8 @@
"lanes": "248,249,250,251,252,253,254,255",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp32"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp32a", "etp32b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp32a", "etp32b"],
+ "4x100G[50G,25G,10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"]
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn4600-r0/ACS-MSN4600/hwsku.json b/device/mellanox/x86_64-mlnx_msn4600-r0/ACS-MSN4600/hwsku.json
index ff0cda3b54d3..7353bb967dab 100644
--- a/device/mellanox/x86_64-mlnx_msn4600-r0/ACS-MSN4600/hwsku.json
+++ b/device/mellanox/x86_64-mlnx_msn4600-r0/ACS-MSN4600/hwsku.json
@@ -3,194 +3,194 @@
"Ethernet0": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet8": {
+ "Ethernet4": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet16": {
+ "Ethernet8": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet24": {
+ "Ethernet12": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet32": {
+ "Ethernet16": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet40": {
+ "Ethernet20": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet48": {
+ "Ethernet24": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet56": {
+ "Ethernet28": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet64": {
+ "Ethernet32": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet72": {
+ "Ethernet36": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet80": {
+ "Ethernet40": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet88": {
+ "Ethernet44": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet96": {
+ "Ethernet48": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet104": {
+ "Ethernet52": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet112": {
+ "Ethernet56": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet120": {
+ "Ethernet60": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet128": {
+ "Ethernet64": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet136": {
+ "Ethernet68": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet144": {
+ "Ethernet72": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet152": {
+ "Ethernet76": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet160": {
+ "Ethernet80": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet168": {
+ "Ethernet84": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet176": {
+ "Ethernet88": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet184": {
+ "Ethernet92": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet192": {
+ "Ethernet96": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet200": {
+ "Ethernet100": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet208": {
+ "Ethernet104": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet216": {
+ "Ethernet108": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet224": {
+ "Ethernet112": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet232": {
+ "Ethernet116": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet240": {
+ "Ethernet120": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet248": {
+ "Ethernet124": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet256": {
+ "Ethernet128": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet264": {
+ "Ethernet132": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet272": {
+ "Ethernet136": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet280": {
+ "Ethernet140": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet288": {
+ "Ethernet144": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet296": {
+ "Ethernet148": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet304": {
+ "Ethernet152": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet312": {
+ "Ethernet156": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet320": {
+ "Ethernet160": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet328": {
+ "Ethernet164": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet336": {
+ "Ethernet168": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet344": {
+ "Ethernet172": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet352": {
+ "Ethernet176": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet360": {
+ "Ethernet180": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet368": {
+ "Ethernet184": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet376": {
+ "Ethernet188": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet384": {
+ "Ethernet192": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet392": {
+ "Ethernet196": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet400": {
+ "Ethernet200": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet408": {
+ "Ethernet204": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet416": {
+ "Ethernet208": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet424": {
+ "Ethernet212": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet432": {
+ "Ethernet216": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet440": {
+ "Ethernet220": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet448": {
+ "Ethernet224": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet456": {
+ "Ethernet228": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet464": {
+ "Ethernet232": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet472": {
+ "Ethernet236": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet480": {
+ "Ethernet240": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet488": {
+ "Ethernet244": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
},
- "Ethernet496": {
+ "Ethernet248": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
- },
- "Ethernet504": {
+ },
+ "Ethernet252": {
"default_brkout_mode": "1x200G[100G,50G,40G,25G,10G,1G]"
- }
+ }
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn4600-r0/ACS-MSN4600/port_config.ini b/device/mellanox/x86_64-mlnx_msn4600-r0/ACS-MSN4600/port_config.ini
index a1ecf9aa3266..2e6212ef692c 100644
--- a/device/mellanox/x86_64-mlnx_msn4600-r0/ACS-MSN4600/port_config.ini
+++ b/device/mellanox/x86_64-mlnx_msn4600-r0/ACS-MSN4600/port_config.ini
@@ -1,65 +1,65 @@
# name lanes alias index
Ethernet0 0,1,2,3 etp1 1
-Ethernet8 8,9,10,11 etp2 2
-Ethernet16 16,17,18,19 etp3 3
-Ethernet24 24,25,26,27 etp4 4
-Ethernet32 32,33,34,35 etp5 5
-Ethernet40 40,41,42,43 etp6 6
-Ethernet48 48,49,50,51 etp7 7
-Ethernet56 56,57,58,59 etp8 8
-Ethernet64 64,65,66,67 etp9 9
-Ethernet72 72,73,74,75 etp10 10
-Ethernet80 80,81,82,83 etp11 11
-Ethernet88 88,89,90,91 etp12 12
-Ethernet96 96,97,98,99 etp13 13
-Ethernet104 104,105,106,107 etp14 14
-Ethernet112 112,113,114,115 etp15 15
-Ethernet120 120,121,122,123 etp16 16
-Ethernet128 128,129,130,131 etp17 17
-Ethernet136 136,137,138,139 etp18 18
-Ethernet144 144,145,146,147 etp19 19
-Ethernet152 152,153,154,155 etp20 20
-Ethernet160 160,161,162,163 etp21 21
-Ethernet168 168,169,170,171 etp22 22
-Ethernet176 176,177,178,179 etp23 23
-Ethernet184 184,185,186,187 etp24 24
-Ethernet192 192,193,194,195 etp25 25
-Ethernet200 200,201,202,203 etp26 26
-Ethernet208 208,209,210,211 etp27 27
-Ethernet216 216,217,218,219 etp28 28
-Ethernet224 224,225,226,227 etp29 29
-Ethernet232 232,233,234,235 etp30 30
-Ethernet240 240,241,242,243 etp31 31
-Ethernet248 248,249,250,251 etp32 32
-Ethernet256 256,257,258,259 etp33 33
-Ethernet264 264,265,266,267 etp34 34
-Ethernet272 272,273,274,275 etp35 35
-Ethernet280 280,281,282,283 etp36 36
-Ethernet288 288,289,290,291 etp37 37
-Ethernet296 296,297,298,299 etp38 38
-Ethernet304 304,305,306,307 etp39 39
-Ethernet312 312,313,314,315 etp40 40
-Ethernet320 320,321,322,323 etp41 41
-Ethernet328 328,329,330,331 etp42 42
-Ethernet336 336,337,338,339 etp43 43
-Ethernet344 344,345,346,347 etp44 44
-Ethernet352 352,353,354,355 etp45 45
-Ethernet360 360,361,362,363 etp46 46
-Ethernet368 368,369,370,371 etp47 47
-Ethernet376 376,377,378,379 etp48 48
-Ethernet384 384,385,386,387 etp49 49
-Ethernet392 392,393,394,395 etp50 50
-Ethernet400 400,401,402,403 etp51 51
-Ethernet408 408,409,410,411 etp52 52
-Ethernet416 416,417,418,419 etp53 53
-Ethernet424 424,425,426,427 etp54 54
-Ethernet432 432,433,434,435 etp55 55
-Ethernet440 440,441,442,443 etp56 56
-Ethernet448 448,449,450,451 etp57 57
-Ethernet456 456,457,458,459 etp58 58
-Ethernet464 464,465,466,467 etp59 59
-Ethernet472 472,473,474,475 etp60 60
-Ethernet480 480,481,482,483 etp61 61
-Ethernet488 488,489,490,491 etp62 62
-Ethernet496 496,497,498,499 etp63 63
-Ethernet504 504,505,506,507 etp64 64
+Ethernet4 8,9,10,11 etp2 2
+Ethernet8 16,17,18,19 etp3 3
+Ethernet12 24,25,26,27 etp4 4
+Ethernet16 32,33,34,35 etp5 5
+Ethernet20 40,41,42,43 etp6 6
+Ethernet24 48,49,50,51 etp7 7
+Ethernet28 56,57,58,59 etp8 8
+Ethernet32 64,65,66,67 etp9 9
+Ethernet36 72,73,74,75 etp10 10
+Ethernet40 80,81,82,83 etp11 11
+Ethernet44 88,89,90,91 etp12 12
+Ethernet48 96,97,98,99 etp13 13
+Ethernet52 104,105,106,107 etp14 14
+Ethernet56 112,113,114,115 etp15 15
+Ethernet60 120,121,122,123 etp16 16
+Ethernet64 128,129,130,131 etp17 17
+Ethernet68 136,137,138,139 etp18 18
+Ethernet72 144,145,146,147 etp19 19
+Ethernet76 152,153,154,155 etp20 20
+Ethernet80 160,161,162,163 etp21 21
+Ethernet84 168,169,170,171 etp22 22
+Ethernet88 176,177,178,179 etp23 23
+Ethernet92 184,185,186,187 etp24 24
+Ethernet96 192,193,194,195 etp25 25
+Ethernet100 200,201,202,203 etp26 26
+Ethernet104 208,209,210,211 etp27 27
+Ethernet108 216,217,218,219 etp28 28
+Ethernet112 224,225,226,227 etp29 29
+Ethernet116 232,233,234,235 etp30 30
+Ethernet120 240,241,242,243 etp31 31
+Ethernet124 248,249,250,251 etp32 32
+Ethernet128 256,257,258,259 etp33 33
+Ethernet132 264,265,266,267 etp34 34
+Ethernet136 272,273,274,275 etp35 35
+Ethernet140 280,281,282,283 etp36 36
+Ethernet144 288,289,290,291 etp37 37
+Ethernet148 296,297,298,299 etp38 38
+Ethernet152 304,305,306,307 etp39 39
+Ethernet156 312,313,314,315 etp40 40
+Ethernet160 320,321,322,323 etp41 41
+Ethernet164 328,329,330,331 etp42 42
+Ethernet168 336,337,338,339 etp43 43
+Ethernet172 344,345,346,347 etp44 44
+Ethernet176 352,353,354,355 etp45 45
+Ethernet180 360,361,362,363 etp46 46
+Ethernet184 368,369,370,371 etp47 47
+Ethernet188 376,377,378,379 etp48 48
+Ethernet192 384,385,386,387 etp49 49
+Ethernet196 392,393,394,395 etp50 50
+Ethernet200 400,401,402,403 etp51 51
+Ethernet204 408,409,410,411 etp52 52
+Ethernet208 416,417,418,419 etp53 53
+Ethernet212 424,425,426,427 etp54 54
+Ethernet216 432,433,434,435 etp55 55
+Ethernet220 440,441,442,443 etp56 56
+Ethernet224 448,449,450,451 etp57 57
+Ethernet228 456,457,458,459 etp58 58
+Ethernet232 464,465,466,467 etp59 59
+Ethernet236 472,473,474,475 etp60 60
+Ethernet240 480,481,482,483 etp61 61
+Ethernet244 488,489,490,491 etp62 62
+Ethernet248 496,497,498,499 etp63 63
+Ethernet252 504,505,506,507 etp64 64
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn4600-r0/platform.json b/device/mellanox/x86_64-mlnx_msn4600-r0/platform.json
index 033b58cb81af..a16b210d90ed 100644
--- a/device/mellanox/x86_64-mlnx_msn4600-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn4600-r0/platform.json
@@ -626,574 +626,574 @@
"lanes": "0,1,2,3",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp1"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp1a", "etp1b"],
- "4x50G[40G,25G,10G,1G]": ["etp1a", "etp1b", "etp1c", "etp1d"]
+ "2x100G[50G,25G,10G,1G]": ["etp1a", "etp1b"],
+ "4x50G[25G,10G,1G]": ["etp1a", "etp1b", "etp1c", "etp1d"]
}
},
- "Ethernet8": {
+ "Ethernet4": {
"index": "2,2,2,2",
"lanes": "8,9,10,11",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp2"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp2a", "etp2b"],
- "4x50G[40G,25G,10G,1G]": ["etp2a", "etp2b", "etp2c", "etp2d"]
+ "2x100G[50G,25G,10G,1G]": ["etp2a", "etp2b"],
+ "4x50G[25G,10G,1G]": ["etp2a", "etp2b", "etp2c", "etp2d"]
}
},
- "Ethernet16": {
+ "Ethernet8": {
"index": "3,3,3,3",
"lanes": "16,17,18,19",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp3"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp3a", "etp3b"],
- "4x50G[40G,25G,10G,1G]": ["etp3a", "etp3b", "etp3c", "etp3d"]
+ "2x100G[50G,25G,10G,1G]": ["etp3a", "etp3b"],
+ "4x50G[25G,10G,1G]": ["etp3a", "etp3b", "etp3c", "etp3d"]
}
},
- "Ethernet24": {
+ "Ethernet12": {
"index": "4,4,4,4",
"lanes": "24,25,26,27",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp4"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp4a", "etp4b"],
- "4x50G[40G,25G,10G,1G]": ["etp4a", "etp4b", "etp4c", "etp4d"]
+ "2x100G[50G,25G,10G,1G]": ["etp4a", "etp4b"],
+ "4x50G[25G,10G,1G]": ["etp4a", "etp4b", "etp4c", "etp4d"]
}
},
- "Ethernet32": {
+ "Ethernet16": {
"index": "5,5,5,5",
"lanes": "32,33,34,35",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp5"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp5a", "etp5b"],
- "4x50G[40G,25G,10G,1G]": ["etp5a", "etp5b", "etp5c", "etp5d"]
+ "2x100G[50G,25G,10G,1G]": ["etp5a", "etp5b"],
+ "4x50G[25G,10G,1G]": ["etp5a", "etp5b", "etp5c", "etp5d"]
}
},
- "Ethernet40": {
+ "Ethernet20": {
"index": "6,6,6,6",
"lanes": "40,41,42,43",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp6"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp6a", "etp6b"],
- "4x50G[40G,25G,10G,1G]": ["etp6a", "etp6b", "etp6c", "etp6d"]
+ "2x100G[50G,25G,10G,1G]": ["etp6a", "etp6b"],
+ "4x50G[25G,10G,1G]": ["etp6a", "etp6b", "etp6c", "etp6d"]
}
},
- "Ethernet48": {
+ "Ethernet24": {
"index": "7,7,7,7",
"lanes": "48,49,50,51",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp7"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp7a", "etp7b"],
- "4x50G[40G,25G,10G,1G]": ["etp7a", "etp7b", "etp7c", "etp7d"]
+ "2x100G[50G,25G,10G,1G]": ["etp7a", "etp7b"],
+ "4x50G[25G,10G,1G]": ["etp7a", "etp7b", "etp7c", "etp7d"]
}
},
- "Ethernet56": {
+ "Ethernet28": {
"index": "8,8,8,8",
"lanes": "56,57,58,59",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp8"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp8a", "etp8b"],
- "4x50G[40G,25G,10G,1G]": ["etp8a", "etp8b", "etp8c", "etp8d"]
+ "2x100G[50G,25G,10G,1G]": ["etp8a", "etp8b"],
+ "4x50G[25G,10G,1G]": ["etp8a", "etp8b", "etp8c", "etp8d"]
}
},
- "Ethernet64": {
+ "Ethernet32": {
"index": "9,9,9,9",
"lanes": "64,65,66,67",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp9"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp9a", "etp9b"],
- "4x50G[40G,25G,10G,1G]": ["etp9a", "etp9b", "etp9c", "etp9d"]
+ "2x100G[50G,25G,10G,1G]": ["etp9a", "etp9b"],
+ "4x50G[25G,10G,1G]": ["etp9a", "etp9b", "etp9c", "etp9d"]
}
},
- "Ethernet72": {
+ "Ethernet36": {
"index": "10,10,10,10",
"lanes": "72,73,74,75",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp10"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp10a", "etp10b"],
- "4x50G[40G,25G,10G,1G]": ["etp10a", "etp10b", "etp10c", "etp10d"]
+ "2x100G[50G,25G,10G,1G]": ["etp10a", "etp10b"],
+ "4x50G[25G,10G,1G]": ["etp10a", "etp10b", "etp10c", "etp10d"]
}
},
- "Ethernet80": {
+ "Ethernet40": {
"index": "11,11,11,11",
"lanes": "80,81,82,83",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp11"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp11a", "etp11b"],
- "4x50G[40G,25G,10G,1G]": ["etp11a", "etp11b", "etp11c", "etp11d"]
+ "2x100G[50G,25G,10G,1G]": ["etp11a", "etp11b"],
+ "4x50G[25G,10G,1G]": ["etp11a", "etp11b", "etp11c", "etp11d"]
}
},
- "Ethernet88": {
+ "Ethernet44": {
"index": "12,12,12,12",
"lanes": "88,89,90,91",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp12"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp12a", "etp12b"],
- "4x50G[40G,25G,10G,1G]": ["etp12a", "etp12b", "etp12c", "etp12d"]
+ "2x100G[50G,25G,10G,1G]": ["etp12a", "etp12b"],
+ "4x50G[25G,10G,1G]": ["etp12a", "etp12b", "etp12c", "etp12d"]
}
},
- "Ethernet96": {
+ "Ethernet48": {
"index": "13,13,13,13",
"lanes": "96,97,98,99",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp13"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp13a", "etp13b"],
- "4x50G[40G,25G,10G,1G]": ["etp13a", "etp13b", "etp13c", "etp13d"]
+ "2x100G[50G,25G,10G,1G]": ["etp13a", "etp13b"],
+ "4x50G[25G,10G,1G]": ["etp13a", "etp13b", "etp13c", "etp13d"]
}
},
- "Ethernet104": {
+ "Ethernet52": {
"index": "14,14,14,14",
"lanes": "104,105,106,107",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp14"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp14a", "etp14b"],
- "4x50G[40G,25G,10G,1G]": ["etp14a", "etp14b", "etp14c", "etp14d"]
+ "2x100G[50G,25G,10G,1G]": ["etp14a", "etp14b"],
+ "4x50G[25G,10G,1G]": ["etp14a", "etp14b", "etp14c", "etp14d"]
}
},
- "Ethernet112": {
+ "Ethernet56": {
"index": "15,15,15,15",
"lanes": "112,113,114,115",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp15"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp15a", "etp15b"],
- "4x50G[40G,25G,10G,1G]": ["etp15a", "etp15b", "etp15c", "etp15d"]
+ "2x100G[50G,25G,10G,1G]": ["etp15a", "etp15b"],
+ "4x50G[25G,10G,1G]": ["etp15a", "etp15b", "etp15c", "etp15d"]
}
},
- "Ethernet120": {
+ "Ethernet60": {
"index": "16,16,16,16",
"lanes": "120,121,122,123",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp16"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp16a", "etp16b"],
- "4x50G[40G,25G,10G,1G]": ["etp16a", "etp16b", "etp16c", "etp16d"]
+ "2x100G[50G,25G,10G,1G]": ["etp16a", "etp16b"],
+ "4x50G[25G,10G,1G]": ["etp16a", "etp16b", "etp16c", "etp16d"]
}
},
- "Ethernet128": {
+ "Ethernet64": {
"index": "17,17,17,17",
"lanes": "128,129,130,131",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp17"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp17a", "etp17b"],
- "4x50G[40G,25G,10G,1G]": ["etp17a", "etp17b", "etp17c", "etp17d"]
+ "2x100G[50G,25G,10G,1G]": ["etp17a", "etp17b"],
+ "4x50G[25G,10G,1G]": ["etp17a", "etp17b", "etp17c", "etp17d"]
}
},
- "Ethernet136": {
+ "Ethernet68": {
"index": "18,18,18,18",
"lanes": "136,137,138,139",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp18"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp18a", "etp18b"],
- "4x50G[40G,25G,10G,1G]": ["etp18a", "etp18b", "etp18c", "etp18d"]
+ "2x100G[50G,25G,10G,1G]": ["etp18a", "etp18b"],
+ "4x50G[25G,10G,1G]": ["etp18a", "etp18b", "etp18c", "etp18d"]
}
},
- "Ethernet144": {
+ "Ethernet72": {
"index": "19,19,19,19",
"lanes": "144,145,146,147",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp19"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp19a", "etp19b"],
- "4x50G[40G,25G,10G,1G]": ["etp19a", "etp19b", "etp19c", "etp19d"]
+ "2x100G[50G,25G,10G,1G]": ["etp19a", "etp19b"],
+ "4x50G[25G,10G,1G]": ["etp19a", "etp19b", "etp19c", "etp19d"]
}
},
- "Ethernet152": {
+ "Ethernet76": {
"index": "20,20,20,20",
"lanes": "152,153,154,155",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp20"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp20a", "etp20b"],
- "4x50G[40G,25G,10G,1G]": ["etp20a", "etp20b", "etp20c", "etp20d"]
+ "2x100G[50G,25G,10G,1G]": ["etp20a", "etp20b"],
+ "4x50G[25G,10G,1G]": ["etp20a", "etp20b", "etp20c", "etp20d"]
}
},
- "Ethernet160": {
+ "Ethernet80": {
"index": "21,21,21,21",
"lanes": "160,161,162,163",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp21"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp21a", "etp21b"],
- "4x50G[40G,25G,10G,1G]": ["etp21a", "etp21b", "etp21c", "etp21d"]
+ "2x100G[50G,25G,10G,1G]": ["etp21a", "etp21b"],
+ "4x50G[25G,10G,1G]": ["etp21a", "etp21b", "etp21c", "etp21d"]
}
},
- "Ethernet168": {
+ "Ethernet84": {
"index": "22,22,22,22",
"lanes": "168,169,170,171",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp22"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp22a", "etp22b"],
- "4x50G[40G,25G,10G,1G]": ["etp22a", "etp22b", "etp22c", "etp22d"]
+ "2x100G[50G,25G,10G,1G]": ["etp22a", "etp22b"],
+ "4x50G[25G,10G,1G]": ["etp22a", "etp22b", "etp22c", "etp22d"]
}
},
- "Ethernet176": {
+ "Ethernet88": {
"index": "23,23,23,23",
"lanes": "176,177,178,179",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp23"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp23a", "etp23b"],
- "4x50G[40G,25G,10G,1G]": ["etp23a", "etp23b", "etp23c", "etp23d"]
+ "2x100G[50G,25G,10G,1G]": ["etp23a", "etp23b"],
+ "4x50G[25G,10G,1G]": ["etp23a", "etp23b", "etp23c", "etp23d"]
}
},
- "Ethernet184": {
+ "Ethernet92": {
"index": "24,24,24,24",
"lanes": "184,185,186,187",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp24"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp24a", "etp24b"],
- "4x50G[40G,25G,10G,1G]": ["etp24a", "etp24b", "etp24c", "etp24d"]
+ "2x100G[50G,25G,10G,1G]": ["etp24a", "etp24b"],
+ "4x50G[25G,10G,1G]": ["etp24a", "etp24b", "etp24c", "etp24d"]
}
},
- "Ethernet192": {
+ "Ethernet96": {
"index": "25,25,25,25",
"lanes": "192,193,194,195",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp25"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp25a", "etp25b"],
- "4x50G[40G,25G,10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"]
+ "2x100G[50G,25G,10G,1G]": ["etp25a", "etp25b"],
+ "4x50G[25G,10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"]
}
},
- "Ethernet200": {
+ "Ethernet100": {
"index": "26,26,26,26",
"lanes": "200,201,202,203",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp26"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp26a", "etp26b"],
- "4x50G[40G,25G,10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"]
+ "2x100G[50G,25G,10G,1G]": ["etp26a", "etp26b"],
+ "4x50G[25G,10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"]
}
},
- "Ethernet208": {
+ "Ethernet104": {
"index": "27,27,27,27",
"lanes": "208,209,210,211",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp27"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp27a", "etp27b"],
- "4x50G[40G,25G,10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"]
+ "2x100G[50G,25G,10G,1G]": ["etp27a", "etp27b"],
+ "4x50G[25G,10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"]
}
},
- "Ethernet216": {
+ "Ethernet108": {
"index": "28,28,28,28",
"lanes": "216,217,218,219",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp28"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp28a", "etp28b"],
- "4x50G[40G,25G,10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"]
+ "2x100G[50G,25G,10G,1G]": ["etp28a", "etp28b"],
+ "4x50G[25G,10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"]
}
},
- "Ethernet224": {
+ "Ethernet112": {
"index": "29,29,29,29",
"lanes": "224,225,226,227",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp29"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp29a", "etp29b"],
- "4x50G[40G,25G,10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"]
+ "2x100G[50G,25G,10G,1G]": ["etp29a", "etp29b"],
+ "4x50G[25G,10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"]
} },
- "Ethernet232": {
+ "Ethernet116": {
"index": "30,30,30,30",
"lanes": "232,233,234,235",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp30"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp30a", "etp30b"],
- "4x50G[40G,25G,10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"]
+ "2x100G[50G,25G,10G,1G]": ["etp30a", "etp30b"],
+ "4x50G[25G,10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"]
}
},
- "Ethernet240": {
+ "Ethernet120": {
"index": "31,31,31,31",
"lanes": "240,241,242,243",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp31"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp31a", "etp31b"],
- "4x50G[40G,25G,10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"]
+ "2x100G[50G,25G,10G,1G]": ["etp31a", "etp31b"],
+ "4x50G[25G,10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"]
}
},
- "Ethernet248": {
+ "Ethernet124": {
"index": "32,32,32,32",
"lanes": "248,249,250,251",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp32"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp32a", "etp32b"],
- "4x50G[40G,25G,10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"]
+ "2x100G[50G,25G,10G,1G]": ["etp32a", "etp32b"],
+ "4x50G[25G,10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"]
}
},
- "Ethernet256": {
+ "Ethernet128": {
"index": "33,33,33,33",
"lanes": "256,257,258,259",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp33"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp33a", "etp33b"],
- "4x50G[40G,25G,10G,1G]": ["etp33a", "etp33b", "etp33c", "etp33d"]
+ "2x100G[50G,25G,10G,1G]": ["etp33a", "etp33b"],
+ "4x50G[25G,10G,1G]": ["etp33a", "etp33b", "etp33c", "etp33d"]
}
},
- "Ethernet264": {
+ "Ethernet132": {
"index": "34,34,34,34",
"lanes": "264,265,266,267",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp34"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp34a", "etp34b"],
- "4x50G[40G,25G,10G,1G]": ["etp34a", "etp34b", "etp34c", "etp34d"]
+ "2x100G[50G,25G,10G,1G]": ["etp34a", "etp34b"],
+ "4x50G[25G,10G,1G]": ["etp34a", "etp34b", "etp34c", "etp34d"]
}
},
- "Ethernet272": {
+ "Ethernet136": {
"index": "35,35,35,35",
"lanes": "272,273,274,275",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp35"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp35a", "etp35b"],
- "4x50G[40G,25G,10G,1G]": ["etp35a", "etp35b", "etp35c", "etp35d"]
+ "2x100G[50G,25G,10G,1G]": ["etp35a", "etp35b"],
+ "4x50G[25G,10G,1G]": ["etp35a", "etp35b", "etp35c", "etp35d"]
}
},
- "Ethernet280": {
+ "Ethernet140": {
"index": "36,36,36,36",
"lanes": "280,281,282,283",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp36"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp36a", "etp36b"],
- "4x50G[40G,25G,10G,1G]": ["etp36a", "etp36b", "etp36c", "etp36d"]
+ "2x100G[50G,25G,10G,1G]": ["etp36a", "etp36b"],
+ "4x50G[25G,10G,1G]": ["etp36a", "etp36b", "etp36c", "etp36d"]
}
},
- "Ethernet288": {
+ "Ethernet144": {
"index": "37,37,37,37",
"lanes": "288,289,290,291",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp37"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp37a", "etp37b"],
- "4x50G[40G,25G,10G,1G]": ["etp37a", "etp37b", "etp37c", "etp37d"]
+ "2x100G[50G,25G,10G,1G]": ["etp37a", "etp37b"],
+ "4x50G[25G,10G,1G]": ["etp37a", "etp37b", "etp37c", "etp37d"]
}
},
- "Ethernet296": {
+ "Ethernet148": {
"index": "38,38,38,38",
"lanes": "296,297,298,299",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp38"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp38a", "etp38b"],
- "4x50G[40G,25G,10G,1G]": ["etp38a", "etp38b", "etp38c", "etp38d"]
+ "2x100G[50G,25G,10G,1G]": ["etp38a", "etp38b"],
+ "4x50G[25G,10G,1G]": ["etp38a", "etp38b", "etp38c", "etp38d"]
}
},
- "Ethernet304": {
+ "Ethernet152": {
"index": "39,39,39,39",
"lanes": "304,305,306,307",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp39"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp39a", "etp39b"],
- "4x50G[40G,25G,10G,1G]": ["etp39a", "etp39b", "etp39c", "etp39d"]
+ "2x100G[50G,25G,10G,1G]": ["etp39a", "etp39b"],
+ "4x50G[25G,10G,1G]": ["etp39a", "etp39b", "etp39c", "etp39d"]
}
},
- "Ethernet312": {
+ "Ethernet156": {
"index": "40,40,40,40",
"lanes": "312,313,314,315",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp40"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp40a", "etp40b"],
- "4x50G[40G,25G,10G,1G]": ["etp40a", "etp40b", "etp40c", "etp40d"]
+ "2x100G[50G,25G,10G,1G]": ["etp40a", "etp40b"],
+ "4x50G[25G,10G,1G]": ["etp40a", "etp40b", "etp40c", "etp40d"]
}
},
- "Ethernet320": {
+ "Ethernet160": {
"index": "41,41,41,41",
"lanes": "320,321,322,323",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp41"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp41a", "etp41b"],
- "4x50G[40G,25G,10G,1G]": ["etp41a", "etp41b", "etp41c", "etp41d"]
+ "2x100G[50G,25G,10G,1G]": ["etp41a", "etp41b"],
+ "4x50G[25G,10G,1G]": ["etp41a", "etp41b", "etp41c", "etp41d"]
}
},
- "Ethernet328": {
+ "Ethernet164": {
"index": "42,42,42,42",
"lanes": "328,329,330,331",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp42"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp42a", "etp42b"],
- "4x50G[40G,25G,10G,1G]": ["etp42a", "etp42b", "etp42c", "etp42d"]
+ "2x100G[50G,25G,10G,1G]": ["etp42a", "etp42b"],
+ "4x50G[25G,10G,1G]": ["etp42a", "etp42b", "etp42c", "etp42d"]
}
},
- "Ethernet336": {
+ "Ethernet168": {
"index": "43,43,43,43",
"lanes": "336,337,338,339",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp43"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp43a", "etp43b"],
- "4x50G[40G,25G,10G,1G]": ["etp43a", "etp43b", "etp43c", "etp43d"]
+ "2x100G[50G,25G,10G,1G]": ["etp43a", "etp43b"],
+ "4x50G[25G,10G,1G]": ["etp43a", "etp43b", "etp43c", "etp43d"]
}
},
- "Ethernet344": {
+ "Ethernet172": {
"index": "44,44,44,44",
"lanes": "344,345,346,347",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp44"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp44a", "etp44b"],
- "4x50G[40G,25G,10G,1G]": ["etp44a", "etp44b", "etp44c", "etp44d"]
+ "2x100G[50G,25G,10G,1G]": ["etp44a", "etp44b"],
+ "4x50G[25G,10G,1G]": ["etp44a", "etp44b", "etp44c", "etp44d"]
}
},
- "Ethernet352": {
+ "Ethernet176": {
"index": "45,45,45,45",
"lanes": "352,353,354,355",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp45"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp45a", "etp45b"],
- "4x50G[40G,25G,10G,1G]": ["etp45a", "etp45b", "etp45c", "etp45d"]
+ "2x100G[50G,25G,10G,1G]": ["etp45a", "etp45b"],
+ "4x50G[25G,10G,1G]": ["etp45a", "etp45b", "etp45c", "etp45d"]
}
},
- "Ethernet360": {
+ "Ethernet180": {
"index": "46,46,46,46",
"lanes": "360,361,362,363",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp46"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp46a", "etp46b"],
- "4x50G[40G,25G,10G,1G]": ["etp46a", "etp46b", "etp46c", "etp46d"]
+ "2x100G[50G,25G,10G,1G]": ["etp46a", "etp46b"],
+ "4x50G[25G,10G,1G]": ["etp46a", "etp46b", "etp46c", "etp46d"]
}
},
- "Ethernet368": {
+ "Ethernet184": {
"index": "47,47,47,47",
"lanes": "368,369,370,371",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp47"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp47a", "etp47b"],
- "4x50G[40G,25G,10G,1G]": ["etp47a", "etp47b", "etp47c", "etp47d"]
+ "2x100G[50G,25G,10G,1G]": ["etp47a", "etp47b"],
+ "4x50G[25G,10G,1G]": ["etp47a", "etp47b", "etp47c", "etp47d"]
}
},
- "Ethernet376": {
+ "Ethernet188": {
"index": "48,48,48,48",
"lanes": "376,377,378,379",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp48"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp48a", "etp48b"],
- "4x50G[40G,25G,10G,1G]": ["etp48a", "etp48b", "etp48c", "etp48d"]
+ "2x100G[50G,25G,10G,1G]": ["etp48a", "etp48b"],
+ "4x50G[25G,10G,1G]": ["etp48a", "etp48b", "etp48c", "etp48d"]
}
},
- "Ethernet384": {
+ "Ethernet192": {
"index": "49,49,49,49",
"lanes": "384,385,386,387",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp49"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp49a", "etp49b"],
- "4x50G[40G,25G,10G,1G]": ["etp49a", "etp49b", "etp49c", "etp49d"]
+ "2x100G[50G,25G,10G,1G]": ["etp49a", "etp49b"],
+ "4x50G[25G,10G,1G]": ["etp49a", "etp49b", "etp49c", "etp49d"]
}
},
- "Ethernet392": {
+ "Ethernet196": {
"index": "50,50,50,50",
"lanes": "392,393,394,395",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp50"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp50a", "etp50b"],
- "4x50G[40G,25G,10G,1G]": ["etp50a", "etp50b", "etp50c", "etp50d"]
+ "2x100G[50G,25G,10G,1G]": ["etp50a", "etp50b"],
+ "4x50G[25G,10G,1G]": ["etp50a", "etp50b", "etp50c", "etp50d"]
}
},
- "Ethernet400": {
+ "Ethernet200": {
"index": "51,51,51,51",
"lanes": "400,401,402,403",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp51"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp51a", "etp51b"],
- "4x50G[40G,25G,10G,1G]": ["etp51a", "etp51b", "etp51c", "etp51d"]
+ "2x100G[50G,25G,10G,1G]": ["etp51a", "etp51b"],
+ "4x50G[25G,10G,1G]": ["etp51a", "etp51b", "etp51c", "etp51d"]
}
},
- "Ethernet408": {
+ "Ethernet204": {
"index": "52,52,52,52",
"lanes": "408,409,410,411",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp52"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp52a", "etp52b"],
- "4x50G[40G,25G,10G,1G]": ["etp52a", "etp52b", "etp52c", "etp52d"]
+ "2x100G[50G,25G,10G,1G]": ["etp52a", "etp52b"],
+ "4x50G[25G,10G,1G]": ["etp52a", "etp52b", "etp52c", "etp52d"]
}
},
- "Ethernet416": {
+ "Ethernet208": {
"index": "53,53,53,53",
"lanes": "416,417,418,419",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp53"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp53a", "etp53b"],
- "4x50G[40G,25G,10G,1G]": ["etp53a", "etp53b", "etp53c", "etp53d"]
+ "2x100G[50G,25G,10G,1G]": ["etp53a", "etp53b"],
+ "4x50G[25G,10G,1G]": ["etp53a", "etp53b", "etp53c", "etp53d"]
}
},
- "Ethernet424": {
+ "Ethernet212": {
"index": "54,54,54,54",
"lanes": "424,425,426,427",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp54"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp54a", "etp54b"],
- "4x50G[40G,25G,10G,1G]": ["etp54a", "etp54b", "etp54c", "etp54d"]
+ "2x100G[50G,25G,10G,1G]": ["etp54a", "etp54b"],
+ "4x50G[25G,10G,1G]": ["etp54a", "etp54b", "etp54c", "etp54d"]
}
},
- "Ethernet432": {
+ "Ethernet216": {
"index": "55,55,55,55",
"lanes": "432,433,434,435",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp55"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp55a", "etp55b"],
- "4x50G[40G,25G,10G,1G]": ["etp55a", "etp55b", "etp55c", "etp55d"]
+ "2x100G[50G,25G,10G,1G]": ["etp55a", "etp55b"],
+ "4x50G[25G,10G,1G]": ["etp55a", "etp55b", "etp55c", "etp55d"]
}
},
- "Ethernet440": {
+ "Ethernet220": {
"index": "56,56,56,56",
"lanes": "440,441,442,443",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp56"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp56a", "etp56b"],
- "4x50G[40G,25G,10G,1G]": ["etp56a", "etp56b", "etp56c", "etp56d"]
+ "2x100G[50G,25G,10G,1G]": ["etp56a", "etp56b"],
+ "4x50G[25G,10G,1G]": ["etp56a", "etp56b", "etp56c", "etp56d"]
}
},
- "Ethernet448": {
+ "Ethernet224": {
"index": "57,57,57,57",
"lanes": "448,449,450,451",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp57"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp57a", "etp57b"],
- "4x50G[40G,25G,10G,1G]": ["etp57a", "etp57b", "etp57c", "etp57d"]
+ "2x100G[50G,25G,10G,1G]": ["etp57a", "etp57b"],
+ "4x50G[25G,10G,1G]": ["etp57a", "etp57b", "etp57c", "etp57d"]
}
},
- "Ethernet456": {
+ "Ethernet228": {
"index": "58,58,58,58",
"lanes": "456,457,458,459",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp58"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp58a", "etp58b"],
- "4x50G[40G,25G,10G,1G]": ["etp58a", "etp58b", "etp58c", "etp58d"]
+ "2x100G[50G,25G,10G,1G]": ["etp58a", "etp58b"],
+ "4x50G[25G,10G,1G]": ["etp58a", "etp58b", "etp58c", "etp58d"]
}
},
- "Ethernet464": {
+ "Ethernet232": {
"index": "59,59,59,59",
"lanes": "464,465,466,467",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp59"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp59a", "etp59b"],
- "4x50G[40G,25G,10G,1G]": ["etp59a", "etp59b", "etp59c", "etp59d"]
+ "2x100G[50G,25G,10G,1G]": ["etp59a", "etp59b"],
+ "4x50G[25G,10G,1G]": ["etp59a", "etp59b", "etp59c", "etp59d"]
}
},
- "Ethernet472": {
+ "Ethernet236": {
"index": "60,60,60,60",
"lanes": "472,473,474,475",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp60"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp60a", "etp60b"],
- "4x50G[40G,25G,10G,1G]": ["etp60a", "etp60b", "etp60c", "etp60d"]
+ "2x100G[50G,25G,10G,1G]": ["etp60a", "etp60b"],
+ "4x50G[25G,10G,1G]": ["etp60a", "etp60b", "etp60c", "etp60d"]
}
},
- "Ethernet480": {
+ "Ethernet240": {
"index": "61,61,61,61",
"lanes": "480,481,482,483",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp61"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp61a", "etp61b"],
- "4x50G[40G,25G,10G,1G]": ["etp61a", "etp61b", "etp61c", "etp61d"]
+ "2x100G[50G,25G,10G,1G]": ["etp61a", "etp61b"],
+ "4x50G[25G,10G,1G]": ["etp61a", "etp61b", "etp61c", "etp61d"]
}
},
- "Ethernet488": {
+ "Ethernet244": {
"index": "62,62,62,62",
"lanes": "488,489,490,491",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp62"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp62a", "etp62b"],
- "4x50G[40G,25G,10G,1G]": ["etp62a", "etp62b", "etp62c", "etp62d"]
+ "2x100G[50G,25G,10G,1G]": ["etp62a", "etp62b"],
+ "4x50G[25G,10G,1G]": ["etp62a", "etp62b", "etp62c", "etp62d"]
}
},
- "Ethernet496": {
+ "Ethernet248": {
"index": "63,63,63,63",
"lanes": "496,497,498,499",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp63"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp63a", "etp63b"],
- "4x50G[40G,25G,10G,1G]": ["etp63a", "etp63b", "etp63c", "etp63d"]
+ "2x100G[50G,25G,10G,1G]": ["etp63a", "etp63b"],
+ "4x50G[25G,10G,1G]": ["etp63a", "etp63b", "etp63c", "etp63d"]
}
},
- "Ethernet504": {
+ "Ethernet252": {
"index": "64,64,64,64",
"lanes": "504,505,506,507",
"breakout_modes": {
"1x200G[100G,50G,40G,25G,10G,1G]": ["etp64"],
- "2x100G[50G,40G,25G,10G,1G]": ["etp64a", "etp64b"],
- "4x50G[40G,25G,10G,1G]": ["etp64a", "etp64b", "etp64c", "etp64d"]
+ "2x100G[50G,25G,10G,1G]": ["etp64a", "etp64b"],
+ "4x50G[25G,10G,1G]": ["etp64a", "etp64b", "etp64c", "etp64d"]
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/hwsku.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/hwsku.json
index b73944cba7a0..8be2a839d6e4 100644
--- a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/hwsku.json
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/hwsku.json
@@ -2,195 +2,195 @@
"interfaces": {
"Ethernet0": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet8": {
+ },
+ "Ethernet4": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet16": {
+ },
+ "Ethernet8": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet24": {
+ },
+ "Ethernet12": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet32": {
+ },
+ "Ethernet16": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet40": {
+ },
+ "Ethernet20": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet48": {
+ },
+ "Ethernet24": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet56": {
+ },
+ "Ethernet28": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet64": {
+ },
+ "Ethernet32": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet72": {
+ },
+ "Ethernet36": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet80": {
+ },
+ "Ethernet40": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet88": {
+ },
+ "Ethernet44": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet96": {
+ },
+ "Ethernet48": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet104": {
+ },
+ "Ethernet52": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet112": {
+ },
+ "Ethernet56": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet120": {
+ },
+ "Ethernet60": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet128": {
+ },
+ "Ethernet64": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet136": {
+ },
+ "Ethernet68": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet144": {
+ },
+ "Ethernet72": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet152": {
+ },
+ "Ethernet76": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet160": {
+ },
+ "Ethernet80": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet168": {
+ },
+ "Ethernet84": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet176": {
+ },
+ "Ethernet88": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet184": {
+ },
+ "Ethernet92": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet192": {
+ },
+ "Ethernet96": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet200": {
+ },
+ "Ethernet100": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet208": {
+ },
+ "Ethernet104": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet216": {
+ },
+ "Ethernet108": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet224": {
+ },
+ "Ethernet112": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet232": {
+ },
+ "Ethernet116": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet240": {
+ },
+ "Ethernet120": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet248": {
+ },
+ "Ethernet124": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet256": {
+ },
+ "Ethernet128": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet264": {
+ },
+ "Ethernet132": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet272": {
+ },
+ "Ethernet136": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet280": {
+ },
+ "Ethernet140": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet288": {
+ },
+ "Ethernet144": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet296": {
+ },
+ "Ethernet148": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet304": {
+ },
+ "Ethernet152": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet312": {
+ },
+ "Ethernet156": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet320": {
+ },
+ "Ethernet160": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet328": {
+ },
+ "Ethernet164": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet336": {
+ },
+ "Ethernet168": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet344": {
+ },
+ "Ethernet172": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet352": {
+ },
+ "Ethernet176": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet360": {
+ },
+ "Ethernet180": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet368": {
+ },
+ "Ethernet184": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet376": {
+ },
+ "Ethernet188": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet384": {
+ },
+ "Ethernet192": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet392": {
+ },
+ "Ethernet196": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet400": {
+ },
+ "Ethernet200": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet408": {
+ },
+ "Ethernet204": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet416": {
+ },
+ "Ethernet208": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet424": {
+ },
+ "Ethernet212": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet432": {
+ },
+ "Ethernet216": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet440": {
+ },
+ "Ethernet220": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet448": {
+ },
+ "Ethernet224": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet456": {
+ },
+ "Ethernet228": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet464": {
+ },
+ "Ethernet232": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet472": {
+ },
+ "Ethernet236": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet480": {
+ },
+ "Ethernet240": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet488": {
+ },
+ "Ethernet244": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet496": {
+ },
+ "Ethernet248": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet504": {
+ },
+ "Ethernet252": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
}
}
-}
\ No newline at end of file
+}
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini
index a1ecf9aa3266..2e6212ef692c 100644
--- a/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/ACS-MSN4600C/port_config.ini
@@ -1,65 +1,65 @@
# name lanes alias index
Ethernet0 0,1,2,3 etp1 1
-Ethernet8 8,9,10,11 etp2 2
-Ethernet16 16,17,18,19 etp3 3
-Ethernet24 24,25,26,27 etp4 4
-Ethernet32 32,33,34,35 etp5 5
-Ethernet40 40,41,42,43 etp6 6
-Ethernet48 48,49,50,51 etp7 7
-Ethernet56 56,57,58,59 etp8 8
-Ethernet64 64,65,66,67 etp9 9
-Ethernet72 72,73,74,75 etp10 10
-Ethernet80 80,81,82,83 etp11 11
-Ethernet88 88,89,90,91 etp12 12
-Ethernet96 96,97,98,99 etp13 13
-Ethernet104 104,105,106,107 etp14 14
-Ethernet112 112,113,114,115 etp15 15
-Ethernet120 120,121,122,123 etp16 16
-Ethernet128 128,129,130,131 etp17 17
-Ethernet136 136,137,138,139 etp18 18
-Ethernet144 144,145,146,147 etp19 19
-Ethernet152 152,153,154,155 etp20 20
-Ethernet160 160,161,162,163 etp21 21
-Ethernet168 168,169,170,171 etp22 22
-Ethernet176 176,177,178,179 etp23 23
-Ethernet184 184,185,186,187 etp24 24
-Ethernet192 192,193,194,195 etp25 25
-Ethernet200 200,201,202,203 etp26 26
-Ethernet208 208,209,210,211 etp27 27
-Ethernet216 216,217,218,219 etp28 28
-Ethernet224 224,225,226,227 etp29 29
-Ethernet232 232,233,234,235 etp30 30
-Ethernet240 240,241,242,243 etp31 31
-Ethernet248 248,249,250,251 etp32 32
-Ethernet256 256,257,258,259 etp33 33
-Ethernet264 264,265,266,267 etp34 34
-Ethernet272 272,273,274,275 etp35 35
-Ethernet280 280,281,282,283 etp36 36
-Ethernet288 288,289,290,291 etp37 37
-Ethernet296 296,297,298,299 etp38 38
-Ethernet304 304,305,306,307 etp39 39
-Ethernet312 312,313,314,315 etp40 40
-Ethernet320 320,321,322,323 etp41 41
-Ethernet328 328,329,330,331 etp42 42
-Ethernet336 336,337,338,339 etp43 43
-Ethernet344 344,345,346,347 etp44 44
-Ethernet352 352,353,354,355 etp45 45
-Ethernet360 360,361,362,363 etp46 46
-Ethernet368 368,369,370,371 etp47 47
-Ethernet376 376,377,378,379 etp48 48
-Ethernet384 384,385,386,387 etp49 49
-Ethernet392 392,393,394,395 etp50 50
-Ethernet400 400,401,402,403 etp51 51
-Ethernet408 408,409,410,411 etp52 52
-Ethernet416 416,417,418,419 etp53 53
-Ethernet424 424,425,426,427 etp54 54
-Ethernet432 432,433,434,435 etp55 55
-Ethernet440 440,441,442,443 etp56 56
-Ethernet448 448,449,450,451 etp57 57
-Ethernet456 456,457,458,459 etp58 58
-Ethernet464 464,465,466,467 etp59 59
-Ethernet472 472,473,474,475 etp60 60
-Ethernet480 480,481,482,483 etp61 61
-Ethernet488 488,489,490,491 etp62 62
-Ethernet496 496,497,498,499 etp63 63
-Ethernet504 504,505,506,507 etp64 64
+Ethernet4 8,9,10,11 etp2 2
+Ethernet8 16,17,18,19 etp3 3
+Ethernet12 24,25,26,27 etp4 4
+Ethernet16 32,33,34,35 etp5 5
+Ethernet20 40,41,42,43 etp6 6
+Ethernet24 48,49,50,51 etp7 7
+Ethernet28 56,57,58,59 etp8 8
+Ethernet32 64,65,66,67 etp9 9
+Ethernet36 72,73,74,75 etp10 10
+Ethernet40 80,81,82,83 etp11 11
+Ethernet44 88,89,90,91 etp12 12
+Ethernet48 96,97,98,99 etp13 13
+Ethernet52 104,105,106,107 etp14 14
+Ethernet56 112,113,114,115 etp15 15
+Ethernet60 120,121,122,123 etp16 16
+Ethernet64 128,129,130,131 etp17 17
+Ethernet68 136,137,138,139 etp18 18
+Ethernet72 144,145,146,147 etp19 19
+Ethernet76 152,153,154,155 etp20 20
+Ethernet80 160,161,162,163 etp21 21
+Ethernet84 168,169,170,171 etp22 22
+Ethernet88 176,177,178,179 etp23 23
+Ethernet92 184,185,186,187 etp24 24
+Ethernet96 192,193,194,195 etp25 25
+Ethernet100 200,201,202,203 etp26 26
+Ethernet104 208,209,210,211 etp27 27
+Ethernet108 216,217,218,219 etp28 28
+Ethernet112 224,225,226,227 etp29 29
+Ethernet116 232,233,234,235 etp30 30
+Ethernet120 240,241,242,243 etp31 31
+Ethernet124 248,249,250,251 etp32 32
+Ethernet128 256,257,258,259 etp33 33
+Ethernet132 264,265,266,267 etp34 34
+Ethernet136 272,273,274,275 etp35 35
+Ethernet140 280,281,282,283 etp36 36
+Ethernet144 288,289,290,291 etp37 37
+Ethernet148 296,297,298,299 etp38 38
+Ethernet152 304,305,306,307 etp39 39
+Ethernet156 312,313,314,315 etp40 40
+Ethernet160 320,321,322,323 etp41 41
+Ethernet164 328,329,330,331 etp42 42
+Ethernet168 336,337,338,339 etp43 43
+Ethernet172 344,345,346,347 etp44 44
+Ethernet176 352,353,354,355 etp45 45
+Ethernet180 360,361,362,363 etp46 46
+Ethernet184 368,369,370,371 etp47 47
+Ethernet188 376,377,378,379 etp48 48
+Ethernet192 384,385,386,387 etp49 49
+Ethernet196 392,393,394,395 etp50 50
+Ethernet200 400,401,402,403 etp51 51
+Ethernet204 408,409,410,411 etp52 52
+Ethernet208 416,417,418,419 etp53 53
+Ethernet212 424,425,426,427 etp54 54
+Ethernet216 432,433,434,435 etp55 55
+Ethernet220 440,441,442,443 etp56 56
+Ethernet224 448,449,450,451 etp57 57
+Ethernet228 456,457,458,459 etp58 58
+Ethernet232 464,465,466,467 etp59 59
+Ethernet236 472,473,474,475 etp60 60
+Ethernet240 480,481,482,483 etp61 61
+Ethernet244 488,489,490,491 etp62 62
+Ethernet248 496,497,498,499 etp63 63
+Ethernet252 504,505,506,507 etp64 64
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/buffers_defaults_t0.j2
index 03b1f23d94b6..c6ec42948ec6 100644
--- a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/buffers_defaults_t0.j2
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/buffers_defaults_t0.j2
@@ -1,7 +1,7 @@
{% set default_cable = '5m' %}
{% set ingress_lossless_pool_size = '53379072' %}
-{% set ingress_lossy_pool_size = '1540096' %}
-{% set egress_lossless_pool_size = '60817408' %}
+{% set ingress_lossless_xoff_size = '1540096' %}
+{% set egress_lossless_pool_size = '60817392' %}
{% set egress_lossy_pool_size = '53379072' %}
{%- macro generate_port_lists(PORT_ALL) %}
@@ -16,13 +16,7 @@
"ingress_lossless_pool": {
{%- if dynamic_mode is not defined %}
"size": "{{ ingress_lossless_pool_size }}",
- {%- endif %}
- "type": "ingress",
- "mode": "dynamic"
- },
- "ingress_lossy_pool": {
- {%- if dynamic_mode is not defined %}
- "size": "{{ ingress_lossy_pool_size }}",
+ "xoff": "{{ ingress_lossless_xoff_size }}",
{%- endif %}
"type": "ingress",
"mode": "dynamic"
@@ -47,7 +41,7 @@
"dynamic_th":"7"
},
"ingress_lossy_profile": {
- "pool":"[BUFFER_POOL|ingress_lossy_pool]",
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
"size":"0",
"dynamic_th":"3"
},
@@ -73,7 +67,7 @@
"BUFFER_PORT_INGRESS_PROFILE_LIST": {
{% for port in port_names.split(',') %}
"{{ port }}": {
- "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]"
+ "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]"
}{% if not loop.last %},{% endif %}
{% endfor %}
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/buffers_defaults_t1.j2
index 432f125d6cb5..cbe3511a8311 100644
--- a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/buffers_defaults_t1.j2
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/buffers_defaults_t1.j2
@@ -1,7 +1,7 @@
{% set default_cable = '5m' %}
{% set ingress_lossless_pool_size = '52723712' %}
-{% set ingress_lossless_pool_xoff = '2195456' %}
-{% set egress_lossless_pool_size = '60817408' %}
+{% set ingress_lossless_xoff_size = '2195456' %}
+{% set egress_lossless_pool_size = '60817392' %}
{% set egress_lossy_pool_size = '52723712' %}
{%- macro generate_port_lists(PORT_ALL) %}
@@ -16,13 +16,7 @@
"ingress_lossless_pool": {
{%- if dynamic_mode is not defined %}
"size": "{{ ingress_lossless_pool_size }}",
- {%- endif %}
- "type": "ingress",
- "mode": "dynamic"
- },
- "ingress_lossy_pool": {
- {%- if dynamic_mode is not defined %}
- "size": "{{ ingress_lossy_pool_size }}",
+ "xoff": "{{ ingress_lossless_xoff_size }}",
{%- endif %}
"type": "ingress",
"mode": "dynamic"
@@ -47,7 +41,7 @@
"dynamic_th":"7"
},
"ingress_lossy_profile": {
- "pool":"[BUFFER_POOL|ingress_lossy_pool]",
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
"size":"0",
"dynamic_th":"3"
},
@@ -73,7 +67,7 @@
"BUFFER_PORT_INGRESS_PROFILE_LIST": {
{% for port in port_names.split(',') %}
"{{ port }}": {
- "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile],[BUFFER_PROFILE|ingress_lossy_profile]"
+ "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]"
}{% if not loop.last %},{% endif %}
{% endfor %}
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/hwsku.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/hwsku.json
index b73944cba7a0..8be2a839d6e4 100644
--- a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/hwsku.json
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-C64/hwsku.json
@@ -2,195 +2,195 @@
"interfaces": {
"Ethernet0": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet8": {
+ },
+ "Ethernet4": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet16": {
+ },
+ "Ethernet8": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet24": {
+ },
+ "Ethernet12": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet32": {
+ },
+ "Ethernet16": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet40": {
+ },
+ "Ethernet20": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet48": {
+ },
+ "Ethernet24": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet56": {
+ },
+ "Ethernet28": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet64": {
+ },
+ "Ethernet32": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet72": {
+ },
+ "Ethernet36": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet80": {
+ },
+ "Ethernet40": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet88": {
+ },
+ "Ethernet44": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet96": {
+ },
+ "Ethernet48": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet104": {
+ },
+ "Ethernet52": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet112": {
+ },
+ "Ethernet56": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet120": {
+ },
+ "Ethernet60": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet128": {
+ },
+ "Ethernet64": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet136": {
+ },
+ "Ethernet68": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet144": {
+ },
+ "Ethernet72": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet152": {
+ },
+ "Ethernet76": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet160": {
+ },
+ "Ethernet80": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet168": {
+ },
+ "Ethernet84": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet176": {
+ },
+ "Ethernet88": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet184": {
+ },
+ "Ethernet92": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet192": {
+ },
+ "Ethernet96": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet200": {
+ },
+ "Ethernet100": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet208": {
+ },
+ "Ethernet104": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet216": {
+ },
+ "Ethernet108": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet224": {
+ },
+ "Ethernet112": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet232": {
+ },
+ "Ethernet116": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet240": {
+ },
+ "Ethernet120": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet248": {
+ },
+ "Ethernet124": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet256": {
+ },
+ "Ethernet128": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet264": {
+ },
+ "Ethernet132": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet272": {
+ },
+ "Ethernet136": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet280": {
+ },
+ "Ethernet140": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet288": {
+ },
+ "Ethernet144": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet296": {
+ },
+ "Ethernet148": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet304": {
+ },
+ "Ethernet152": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet312": {
+ },
+ "Ethernet156": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet320": {
+ },
+ "Ethernet160": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet328": {
+ },
+ "Ethernet164": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet336": {
+ },
+ "Ethernet168": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet344": {
+ },
+ "Ethernet172": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet352": {
+ },
+ "Ethernet176": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet360": {
+ },
+ "Ethernet180": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet368": {
+ },
+ "Ethernet184": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet376": {
+ },
+ "Ethernet188": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet384": {
+ },
+ "Ethernet192": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet392": {
+ },
+ "Ethernet196": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet400": {
+ },
+ "Ethernet200": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet408": {
+ },
+ "Ethernet204": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet416": {
+ },
+ "Ethernet208": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet424": {
+ },
+ "Ethernet212": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet432": {
+ },
+ "Ethernet216": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet440": {
+ },
+ "Ethernet220": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet448": {
+ },
+ "Ethernet224": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet456": {
+ },
+ "Ethernet228": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet464": {
+ },
+ "Ethernet232": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet472": {
+ },
+ "Ethernet236": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet480": {
+ },
+ "Ethernet240": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet488": {
+ },
+ "Ethernet244": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet496": {
+ },
+ "Ethernet248": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
- },
- "Ethernet504": {
+ },
+ "Ethernet252": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
}
}
-}
\ No newline at end of file
+}
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/hwsku.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/hwsku.json
index 03af6221121b..cbba15ff738f 100644
--- a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/hwsku.json
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/hwsku.json
@@ -1,364 +1,364 @@
{
"interfaces": {
"Ethernet0": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
"Ethernet2": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet8": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
- },
- "Ethernet10": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet4": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet16": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet6": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet18": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet8": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet24": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet10": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet26": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet12": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet32": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet14": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet34": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet16": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet40": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet18": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet42": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet20": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet48": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet22": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet50": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet24": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet56": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet26": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet58": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet28": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet64": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet30": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet66": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet32": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet72": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet34": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet74": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet36": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet80": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet38": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet82": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet40": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet88": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet42": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet90": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet44": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet96": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet46": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet98": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet48": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet104": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet50": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet106": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet52": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet112": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet54": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet114": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet56": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet120": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet58": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet122": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet60": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet128": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet62": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet130": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet64": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet136": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet66": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet138": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet68": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet144": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet70": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet146": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet72": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet152": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet74": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet154": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet76": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet160": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet78": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet162": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet80": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet168": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet82": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet170": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet84": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet176": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet86": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet178": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet88": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet184": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet90": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet186": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet92": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet94": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet192": {
+ "Ethernet96": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
},
- "Ethernet200": {
+ "Ethernet100": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
},
- "Ethernet208": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet104": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet210": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet106": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet216": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet108": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet218": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet110": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet224": {
+ "Ethernet112": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
},
- "Ethernet232": {
+ "Ethernet116": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
},
- "Ethernet240": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet120": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet242": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet122": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet248": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet124": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet250": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet126": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet256": {
+ "Ethernet128": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
},
- "Ethernet264": {
+ "Ethernet132": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
},
- "Ethernet272": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet136": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet274": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet138": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet280": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet140": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet282": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet142": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet288": {
+ "Ethernet144": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
},
- "Ethernet296": {
+ "Ethernet148": {
"default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
},
- "Ethernet304": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
- },
- "Ethernet306": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet152": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet312": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet154": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet314": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet156": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet320": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet158": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet322": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet160": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet328": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet162": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet330": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet164": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet336": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet166": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet338": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet168": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet344": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet170": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet346": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet172": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet352": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet174": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet176": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet354": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet178": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet360": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet180": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet362": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet182": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet368": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet184": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet370": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet186": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet376": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet188": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet378": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet190": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet384": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet192": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet386": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet194": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet392": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet196": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet394": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet198": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet400": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet200": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet402": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet202": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet408": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet204": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet410": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet206": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet416": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet208": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet418": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet210": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet424": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet212": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet426": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet214": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet432": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet216": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet434": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet218": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet440": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet220": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet442": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet222": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet448": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet224": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet450": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet226": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet456": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet228": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet458": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet230": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet464": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet232": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet466": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet234": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet472": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet236": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet474": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet238": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet480": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet240": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet482": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet242": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet488": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet244": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet490": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet246": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet496": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet248": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet498": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet250": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet504": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet252": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
},
- "Ethernet506": {
- "default_brkout_mode": "2x50G[40G,25G,10G,1G]"
+ "Ethernet254": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
}
}
-}
\ No newline at end of file
+}
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/port_config.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/port_config.ini
index 27d933d886fa..be2c7d9255ca 100644
--- a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/port_config.ini
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D112C8/port_config.ini
@@ -1,121 +1,121 @@
# name lanes alias index speed fec
Ethernet0 0,1 etp1a 1 50000 none
Ethernet2 2,3 etp1b 1 50000 none
-Ethernet8 8,9 etp2a 2 50000 none
-Ethernet10 10,11 etp2b 2 50000 none
-Ethernet16 16,17 etp3a 3 50000 none
-Ethernet18 18,19 etp3b 3 50000 none
-Ethernet24 24,25 etp4a 4 50000 none
-Ethernet26 26,27 etp4b 4 50000 none
-Ethernet32 32,33 etp5a 5 50000 none
-Ethernet34 34,35 etp5b 5 50000 none
-Ethernet40 40,41 etp6a 6 50000 none
-Ethernet42 42,43 etp6b 6 50000 none
-Ethernet48 48,49 etp7a 7 50000 none
-Ethernet50 50,51 etp7b 7 50000 none
-Ethernet56 56,57 etp8a 8 50000 none
-Ethernet58 58,59 etp8b 8 50000 none
-Ethernet64 64,65 etp9a 9 50000 none
-Ethernet66 66,67 etp9b 9 50000 none
-Ethernet72 72,73 etp10a 10 50000 none
-Ethernet74 74,75 etp10b 10 50000 none
-Ethernet80 80,81 etp11a 11 50000 none
-Ethernet82 82,83 etp11b 11 50000 none
-Ethernet88 88,89 etp12a 12 50000 none
-Ethernet90 90,91 etp12b 12 50000 none
-Ethernet96 96,97 etp13a 13 50000 none
-Ethernet98 98,99 etp13b 13 50000 none
-Ethernet104 104,105 etp14a 14 50000 none
-Ethernet106 106,107 etp14b 14 50000 none
-Ethernet112 112,113 etp15a 15 50000 none
-Ethernet114 114,115 etp15b 15 50000 none
-Ethernet120 120,121 etp16a 16 50000 none
-Ethernet122 122,123 etp16b 16 50000 none
-Ethernet128 128,129 etp17a 17 50000 none
-Ethernet130 130,131 etp17b 17 50000 none
-Ethernet136 136,137 etp18a 18 50000 none
-Ethernet138 138,139 etp18b 18 50000 none
-Ethernet144 144,145 etp19a 19 50000 none
-Ethernet146 146,147 etp19b 19 50000 none
-Ethernet152 152,153 etp20a 20 50000 none
-Ethernet154 154,155 etp20b 20 50000 none
-Ethernet160 160,161 etp21a 21 50000 none
-Ethernet162 162,163 etp21b 21 50000 none
-Ethernet168 168,169 etp22a 22 50000 none
-Ethernet170 170,171 etp22b 22 50000 none
-Ethernet176 176,177 etp23a 23 50000 none
-Ethernet178 178,179 etp23b 23 50000 none
-Ethernet184 184,185 etp24a 24 50000 none
-Ethernet186 186,187 etp24b 24 50000 none
-Ethernet192 192,193,194,195 etp25 25 100000 rs
-Ethernet200 200,201,202,203 etp26 26 100000 rs
-Ethernet208 208,209 etp27a 27 50000 none
-Ethernet210 210,211 etp27b 27 50000 none
-Ethernet216 216,217 etp28a 28 50000 none
-Ethernet218 218,219 etp28b 28 50000 none
-Ethernet224 224,225,226,227 etp29 29 100000 rs
-Ethernet232 232,233,234,235 etp30 30 100000 rs
-Ethernet240 240,241 etp31a 31 50000 none
-Ethernet242 242,243 etp31b 31 50000 none
-Ethernet248 248,249 etp32a 32 50000 none
-Ethernet250 250,251 etp32b 32 50000 none
-Ethernet256 256,257,258,259 etp33 33 100000 rs
-Ethernet264 264,265,266,267 etp34 34 100000 rs
-Ethernet272 272,273 etp35a 35 50000 none
-Ethernet274 274,275 etp35b 35 50000 none
-Ethernet280 280,281 etp36a 36 50000 none
-Ethernet282 282,283 etp36b 36 50000 none
-Ethernet288 288,289,290,291 etp37 37 100000 rs
-Ethernet296 296,297,298,299 etp38 38 100000 rs
-Ethernet304 304,305 etp39a 39 50000 none
-Ethernet306 306,307 etp39b 39 50000 none
-Ethernet312 312,313 etp40a 40 50000 none
-Ethernet314 314,315 etp40b 40 50000 none
-Ethernet320 320,321 etp41a 41 50000 none
-Ethernet322 322,323 etp41b 41 50000 none
-Ethernet328 328,329 etp42a 42 50000 none
-Ethernet330 330,331 etp42b 42 50000 none
-Ethernet336 336,337 etp43a 43 50000 none
-Ethernet338 338,339 etp43b 43 50000 none
-Ethernet344 344,345 etp44a 44 50000 none
-Ethernet346 346,347 etp44b 44 50000 none
-Ethernet352 352,353 etp45a 45 50000 none
-Ethernet354 354,355 etp45b 45 50000 none
-Ethernet360 360,361 etp46a 46 50000 none
-Ethernet362 362,363 etp46b 46 50000 none
-Ethernet368 368,369 etp47a 47 50000 none
-Ethernet370 370,371 etp47b 47 50000 none
-Ethernet376 376,377 etp48a 48 50000 none
-Ethernet378 378,379 etp48b 48 50000 none
-Ethernet384 384,385 etp49a 49 50000 none
-Ethernet386 386,387 etp49b 49 50000 none
-Ethernet392 392,393 etp50a 50 50000 none
-Ethernet394 394,395 etp50b 50 50000 none
-Ethernet400 400,401 etp51a 51 50000 none
-Ethernet402 402,403 etp51b 51 50000 none
-Ethernet408 408,409 etp52a 52 50000 none
-Ethernet410 410,411 etp52b 52 50000 none
-Ethernet416 416,417 etp53a 53 50000 none
-Ethernet418 418,419 etp53b 53 50000 none
-Ethernet424 424,425 etp54a 54 50000 none
-Ethernet426 426,427 etp54b 54 50000 none
-Ethernet432 432,433 etp55a 55 50000 none
-Ethernet434 434,435 etp55b 55 50000 none
-Ethernet440 440,441 etp56a 56 50000 none
-Ethernet442 442,443 etp56b 56 50000 none
-Ethernet448 448,449 etp57a 57 50000 none
-Ethernet450 450,451 etp57b 57 50000 none
-Ethernet456 456,457 etp58a 58 50000 none
-Ethernet458 458,459 etp58b 58 50000 none
-Ethernet464 464,465 etp59a 59 50000 none
-Ethernet466 466,467 etp59b 59 50000 none
-Ethernet472 472,473 etp60a 60 50000 none
-Ethernet474 474,475 etp60b 60 50000 none
-Ethernet480 480,481 etp61a 61 50000 none
-Ethernet482 482,483 etp61b 61 50000 none
-Ethernet488 488,489 etp62a 62 50000 none
-Ethernet490 490,491 etp62b 62 50000 none
-Ethernet496 496,497 etp63a 63 50000 none
-Ethernet498 498,499 etp63b 63 50000 none
-Ethernet504 504,505 etp64a 64 50000 none
-Ethernet506 506,507 etp64b 64 50000 none
+Ethernet4 8,9 etp2a 2 50000 none
+Ethernet6 10,11 etp2b 2 50000 none
+Ethernet8 16,17 etp3a 3 50000 none
+Ethernet10 18,19 etp3b 3 50000 none
+Ethernet12 24,25 etp4a 4 50000 none
+Ethernet14 26,27 etp4b 4 50000 none
+Ethernet16 32,33 etp5a 5 50000 none
+Ethernet18 34,35 etp5b 5 50000 none
+Ethernet20 40,41 etp6a 6 50000 none
+Ethernet22 42,43 etp6b 6 50000 none
+Ethernet24 48,49 etp7a 7 50000 none
+Ethernet26 50,51 etp7b 7 50000 none
+Ethernet28 56,57 etp8a 8 50000 none
+Ethernet30 58,59 etp8b 8 50000 none
+Ethernet32 64,65 etp9a 9 50000 none
+Ethernet34 66,67 etp9b 9 50000 none
+Ethernet36 72,73 etp10a 10 50000 none
+Ethernet38 74,75 etp10b 10 50000 none
+Ethernet40 80,81 etp11a 11 50000 none
+Ethernet42 82,83 etp11b 11 50000 none
+Ethernet44 88,89 etp12a 12 50000 none
+Ethernet46 90,91 etp12b 12 50000 none
+Ethernet48 96,97 etp13a 13 50000 none
+Ethernet50 98,99 etp13b 13 50000 none
+Ethernet52 104,105 etp14a 14 50000 none
+Ethernet54 106,107 etp14b 14 50000 none
+Ethernet56 112,113 etp15a 15 50000 none
+Ethernet58 114,115 etp15b 15 50000 none
+Ethernet60 120,121 etp16a 16 50000 none
+Ethernet62 122,123 etp16b 16 50000 none
+Ethernet64 128,129 etp17a 17 50000 none
+Ethernet66 130,131 etp17b 17 50000 none
+Ethernet68 136,137 etp18a 18 50000 none
+Ethernet70 138,139 etp18b 18 50000 none
+Ethernet72 144,145 etp19a 19 50000 none
+Ethernet74 146,147 etp19b 19 50000 none
+Ethernet76 152,153 etp20a 20 50000 none
+Ethernet78 154,155 etp20b 20 50000 none
+Ethernet80 160,161 etp21a 21 50000 none
+Ethernet82 162,163 etp21b 21 50000 none
+Ethernet84 168,169 etp22a 22 50000 none
+Ethernet86 170,171 etp22b 22 50000 none
+Ethernet88 176,177 etp23a 23 50000 none
+Ethernet90 178,179 etp23b 23 50000 none
+Ethernet92 184,185 etp24a 24 50000 none
+Ethernet94 186,187 etp24b 24 50000 none
+Ethernet96 192,193,194,195 etp25 25 100000 rs
+Ethernet100 200,201,202,203 etp26 26 100000 rs
+Ethernet104 208,209 etp27a 27 50000 none
+Ethernet106 210,211 etp27b 27 50000 none
+Ethernet108 216,217 etp28a 28 50000 none
+Ethernet110 218,219 etp28b 28 50000 none
+Ethernet112 224,225,226,227 etp29 29 100000 rs
+Ethernet116 232,233,234,235 etp30 30 100000 rs
+Ethernet120 240,241 etp31a 31 50000 none
+Ethernet122 242,243 etp31b 31 50000 none
+Ethernet124 248,249 etp32a 32 50000 none
+Ethernet126 250,251 etp32b 32 50000 none
+Ethernet128 256,257,258,259 etp33 33 100000 rs
+Ethernet132 264,265,266,267 etp34 34 100000 rs
+Ethernet136 272,273 etp35a 35 50000 none
+Ethernet138 274,275 etp35b 35 50000 none
+Ethernet140 280,281 etp36a 36 50000 none
+Ethernet142 282,283 etp36b 36 50000 none
+Ethernet144 288,289,290,291 etp37 37 100000 rs
+Ethernet148 296,297,298,299 etp38 38 100000 rs
+Ethernet152 304,305 etp39a 39 50000 none
+Ethernet154 306,307 etp39b 39 50000 none
+Ethernet156 312,313 etp40a 40 50000 none
+Ethernet158 314,315 etp40b 40 50000 none
+Ethernet160 320,321 etp41a 41 50000 none
+Ethernet162 322,323 etp41b 41 50000 none
+Ethernet164 328,329 etp42a 42 50000 none
+Ethernet166 330,331 etp42b 42 50000 none
+Ethernet168 336,337 etp43a 43 50000 none
+Ethernet170 338,339 etp43b 43 50000 none
+Ethernet172 344,345 etp44a 44 50000 none
+Ethernet174 346,347 etp44b 44 50000 none
+Ethernet176 352,353 etp45a 45 50000 none
+Ethernet178 354,355 etp45b 45 50000 none
+Ethernet180 360,361 etp46a 46 50000 none
+Ethernet182 362,363 etp46b 46 50000 none
+Ethernet184 368,369 etp47a 47 50000 none
+Ethernet186 370,371 etp47b 47 50000 none
+Ethernet188 376,377 etp48a 48 50000 none
+Ethernet190 378,379 etp48b 48 50000 none
+Ethernet192 384,385 etp49a 49 50000 none
+Ethernet194 386,387 etp49b 49 50000 none
+Ethernet196 392,393 etp50a 50 50000 none
+Ethernet198 394,395 etp50b 50 50000 none
+Ethernet200 400,401 etp51a 51 50000 none
+Ethernet202 402,403 etp51b 51 50000 none
+Ethernet204 408,409 etp52a 52 50000 none
+Ethernet206 410,411 etp52b 52 50000 none
+Ethernet208 416,417 etp53a 53 50000 none
+Ethernet210 418,419 etp53b 53 50000 none
+Ethernet212 424,425 etp54a 54 50000 none
+Ethernet214 426,427 etp54b 54 50000 none
+Ethernet216 432,433 etp55a 55 50000 none
+Ethernet218 434,435 etp55b 55 50000 none
+Ethernet220 440,441 etp56a 56 50000 none
+Ethernet222 442,443 etp56b 56 50000 none
+Ethernet224 448,449 etp57a 57 50000 none
+Ethernet226 450,451 etp57b 57 50000 none
+Ethernet228 456,457 etp58a 58 50000 none
+Ethernet230 458,459 etp58b 58 50000 none
+Ethernet232 464,465 etp59a 59 50000 none
+Ethernet234 466,467 etp59b 59 50000 none
+Ethernet236 472,473 etp60a 60 50000 none
+Ethernet238 474,475 etp60b 60 50000 none
+Ethernet240 480,481 etp61a 61 50000 none
+Ethernet242 482,483 etp61b 61 50000 none
+Ethernet244 488,489 etp62a 62 50000 none
+Ethernet246 490,491 etp62b 62 50000 none
+Ethernet248 496,497 etp63a 63 50000 none
+Ethernet250 498,499 etp63b 63 50000 none
+Ethernet252 504,505 etp64a 64 50000 none
+Ethernet254 506,507 etp64b 64 50000 none
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers.json.j2
new file mode 120000
index 000000000000..117d740b0f5b
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers.json.j2
@@ -0,0 +1 @@
+../ACS-MSN4600C/buffers.json.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers_defaults_t0.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers_defaults_t0.j2
new file mode 100644
index 000000000000..e3a39b9dc79b
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers_defaults_t0.j2
@@ -0,0 +1,104 @@
+{% set default_cable = '5m' %}
+{% set ingress_lossless_pool_size = '50995200' %}
+{% set ingress_lossless_xoff_size = '1810432' %}
+{% set egress_lossless_pool_size = '60817392' %}
+{% set egress_lossy_pool_size = '50995200' %}
+
+{%- macro generate_port_lists(PORT_ALL) %}
+ {# Generate list of ports #}
+ {%- for port_idx in range(0, 32) %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %}
+ {%- endfor %}
+{%- endmacro %}
+
+{%- macro generate_buffer_pool_and_profiles() %}
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ {%- if dynamic_mode is not defined %}
+ "size": "{{ ingress_lossless_pool_size }}",
+ "xoff": "{{ ingress_lossless_xoff_size }}",
+ {%- endif %}
+ "type": "ingress",
+ "mode": "dynamic"
+ },
+ "egress_lossless_pool": {
+ "size": "{{ egress_lossless_pool_size }}",
+ "type": "egress",
+ "mode": "dynamic"
+ },
+ "egress_lossy_pool": {
+ {%- if dynamic_mode is not defined %}
+ "size": "{{ egress_lossy_pool_size }}",
+ {%- endif %}
+ "type": "egress",
+ "mode": "dynamic"
+ }
+ },
+ "BUFFER_PROFILE": {
+ "ingress_lossless_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"7"
+ },
+ "ingress_lossy_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ },
+ "egress_lossless_profile": {
+ "pool":"[BUFFER_POOL|egress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"7"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"9216",
+ "dynamic_th":"7"
+ },
+ "q_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ }
+ },
+{%- endmacro %}
+
+{%- macro generate_profile_lists(port_names) %}
+ "BUFFER_PORT_INGRESS_PROFILE_LIST": {
+{% for port in port_names.split(',') %}
+ "{{ port }}": {
+ "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]"
+ }{% if not loop.last %},{% endif %}
+
+{% endfor %}
+ },
+ "BUFFER_PORT_EGRESS_PROFILE_LIST": {
+{% for port in port_names.split(',') %}
+ "{{ port }}": {
+ "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]"
+ }{% if not loop.last %},{% endif %}
+
+{% endfor %}
+ }
+{%- endmacro %}
+
+{%- macro generate_queue_buffers(port_names) %}
+ "BUFFER_QUEUE": {
+{% for port in port_names.split(',') %}
+ "{{ port }}|3-4": {
+ "profile" : "[BUFFER_PROFILE|egress_lossless_profile]"
+ },
+{% endfor %}
+{% for port in port_names.split(',') %}
+ "{{ port }}|0-2": {
+ "profile" : "[BUFFER_PROFILE|q_lossy_profile]"
+ },
+{% endfor %}
+{% for port in port_names.split(',') %}
+ "{{ port }}|5-6": {
+ "profile" : "[BUFFER_PROFILE|q_lossy_profile]"
+ }{% if not loop.last %},{% endif %}
+
+{% endfor %}
+ }
+{%- endmacro %}
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers_defaults_t1.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers_defaults_t1.j2
new file mode 100644
index 000000000000..149d810c983b
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers_defaults_t1.j2
@@ -0,0 +1,104 @@
+{% set default_cable = '5m' %}
+{% set ingress_lossless_pool_size = '50143232' %}
+{% set ingress_lossless_xoff_size = '2662400' %}
+{% set egress_lossless_pool_size = '60817392' %}
+{% set egress_lossy_pool_size = '50143232' %}
+
+{%- macro generate_port_lists(PORT_ALL) %}
+ {# Generate list of ports #}
+ {%- for port_idx in range(0, 32) %}
+ {%- if PORT_ALL.append("Ethernet%d" % (port_idx)) %}{%- endif %}
+ {%- endfor %}
+{%- endmacro %}
+
+{%- macro generate_buffer_pool_and_profiles() %}
+ "BUFFER_POOL": {
+ "ingress_lossless_pool": {
+ {%- if dynamic_mode is not defined %}
+ "size": "{{ ingress_lossless_pool_size }}",
+ "xoff": "{{ ingress_lossless_xoff_size }}",
+ {%- endif %}
+ "type": "ingress",
+ "mode": "dynamic"
+ },
+ "egress_lossless_pool": {
+ "size": "{{ egress_lossless_pool_size }}",
+ "type": "egress",
+ "mode": "dynamic"
+ },
+ "egress_lossy_pool": {
+ {%- if dynamic_mode is not defined %}
+ "size": "{{ egress_lossy_pool_size }}",
+ {%- endif %}
+ "type": "egress",
+ "mode": "dynamic"
+ }
+ },
+ "BUFFER_PROFILE": {
+ "ingress_lossless_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"7"
+ },
+ "ingress_lossy_profile": {
+ "pool":"[BUFFER_POOL|ingress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ },
+ "egress_lossless_profile": {
+ "pool":"[BUFFER_POOL|egress_lossless_pool]",
+ "size":"0",
+ "dynamic_th":"7"
+ },
+ "egress_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"9216",
+ "dynamic_th":"7"
+ },
+ "q_lossy_profile": {
+ "pool":"[BUFFER_POOL|egress_lossy_pool]",
+ "size":"0",
+ "dynamic_th":"3"
+ }
+ },
+{%- endmacro %}
+
+{%- macro generate_profile_lists(port_names) %}
+ "BUFFER_PORT_INGRESS_PROFILE_LIST": {
+{% for port in port_names.split(',') %}
+ "{{ port }}": {
+ "profile_list" : "[BUFFER_PROFILE|ingress_lossless_profile]"
+ }{% if not loop.last %},{% endif %}
+
+{% endfor %}
+ },
+ "BUFFER_PORT_EGRESS_PROFILE_LIST": {
+{% for port in port_names.split(',') %}
+ "{{ port }}": {
+ "profile_list" : "[BUFFER_PROFILE|egress_lossless_profile],[BUFFER_PROFILE|egress_lossy_profile]"
+ }{% if not loop.last %},{% endif %}
+
+{% endfor %}
+ }
+{%- endmacro %}
+
+{%- macro generate_queue_buffers(port_names) %}
+ "BUFFER_QUEUE": {
+{% for port in port_names.split(',') %}
+ "{{ port }}|3-4": {
+ "profile" : "[BUFFER_PROFILE|egress_lossless_profile]"
+ },
+{% endfor %}
+{% for port in port_names.split(',') %}
+ "{{ port }}|0-2": {
+ "profile" : "[BUFFER_PROFILE|q_lossy_profile]"
+ },
+{% endfor %}
+{% for port in port_names.split(',') %}
+ "{{ port }}|5-6": {
+ "profile" : "[BUFFER_PROFILE|q_lossy_profile]"
+ }{% if not loop.last %},{% endif %}
+
+{% endfor %}
+ }
+{%- endmacro %}
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers_dynamic.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers_dynamic.json.j2
new file mode 120000
index 000000000000..8c4117c66214
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/buffers_dynamic.json.j2
@@ -0,0 +1 @@
+../../x86_64-mlnx_msn2700-r0/ACS-MSN2700/buffers_dynamic.json.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/hwsku.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/hwsku.json
new file mode 100644
index 000000000000..9ecb1b45bfd1
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/hwsku.json
@@ -0,0 +1,268 @@
+{
+ "interfaces": {
+ "Ethernet0": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet2": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet4": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet6": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet8": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet10": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet12": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet14": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet16": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet18": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet20": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet22": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet24": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet26": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet28": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet30": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet32": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet34": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet36": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet38": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet40": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet44": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet48": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet50": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet52": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet54": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet56": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet60": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet64": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet68": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet72": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet76": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet80": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet84": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet88": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet92": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet96": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet100": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet104": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet108": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet112": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet116": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet120": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet124": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet128": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet132": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet136": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet140": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet144": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet148": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet152": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet156": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet160": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet164": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet168": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet172": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet176": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet180": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet184": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet188": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet192": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet194": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet196": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet198": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet200": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet204": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet208": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet210": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet212": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet214": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet216": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet220": {
+ "default_brkout_mode": "1x100G[50G,40G,25G,10G,1G]"
+ },
+ "Ethernet224": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet226": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet228": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet230": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet232": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet234": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet236": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet238": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet240": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet242": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet244": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet246": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet248": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet250": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet252": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ },
+ "Ethernet254": {
+ "default_brkout_mode": "2x50G[25G,10G,1G]"
+ }
+ }
+}
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/pg_profile_lookup.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/pg_profile_lookup.ini
new file mode 120000
index 000000000000..49745268908f
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/pg_profile_lookup.ini
@@ -0,0 +1 @@
+../Mellanox-SN4600C-D112C8/pg_profile_lookup.ini
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/port_config.ini b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/port_config.ini
new file mode 100644
index 000000000000..f98cd3b232fa
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/port_config.ini
@@ -0,0 +1,89 @@
+# name lanes alias index speed
+Ethernet0 0,1 etp1a 1 50000
+Ethernet2 2,3 etp1b 1 50000
+Ethernet4 8,9 etp2a 2 50000
+Ethernet6 10,11 etp2b 2 50000
+Ethernet8 16,17 etp3a 3 50000
+Ethernet10 18,19 etp3b 3 50000
+Ethernet12 24,25 etp4a 4 50000
+Ethernet14 26,27 etp4b 4 50000
+Ethernet16 32,33 etp5a 5 50000
+Ethernet18 34,35 etp5b 5 50000
+Ethernet20 40,41 etp6a 6 50000
+Ethernet22 42,43 etp6b 6 50000
+Ethernet24 48,49 etp7a 7 50000
+Ethernet26 50,51 etp7b 7 50000
+Ethernet28 56,57 etp8a 8 50000
+Ethernet30 58,59 etp8b 8 50000
+Ethernet32 64,65 etp9a 9 50000
+Ethernet34 66,67 etp9b 9 50000
+Ethernet36 72,73 etp10a 10 50000
+Ethernet38 74,75 etp10b 10 50000
+Ethernet40 80,81,82,83 etp11 11 100000
+Ethernet44 88,89,90,91 etp12 12 100000
+Ethernet48 96,97 etp13a 13 50000
+Ethernet50 98,99 etp13b 13 50000
+Ethernet52 104,105 etp14a 14 50000
+Ethernet54 106,107 etp14b 14 50000
+Ethernet56 112,113,114,115 etp15 15 100000
+Ethernet60 120,121,122,123 etp16 16 100000
+Ethernet64 128,129,130,131 etp17 17 100000
+Ethernet68 136,137,138,139 etp18 18 100000
+Ethernet72 144,145,146,147 etp19 19 100000
+Ethernet76 152,153,154,155 etp20 20 100000
+Ethernet80 160,161,162,163 etp21 21 100000
+Ethernet84 168,169,170,171 etp22 22 100000
+Ethernet88 176,177,178,179 etp23 23 100000
+Ethernet92 184,185,186,187 etp24 24 100000
+Ethernet96 192,193,194,195 etp25 25 100000
+Ethernet100 200,201,202,203 etp26 26 100000
+Ethernet104 208,209,210,211 etp27 27 100000
+Ethernet108 216,217,218,219 etp28 28 100000
+Ethernet112 224,225,226,227 etp29 29 100000
+Ethernet116 232,233,234,235 etp30 30 100000
+Ethernet120 240,241,242,243 etp31 31 100000
+Ethernet124 248,249,250,251 etp32 32 100000
+Ethernet128 256,257,258,259 etp33 33 100000
+Ethernet132 264,265,266,267 etp34 34 100000
+Ethernet136 272,273,274,275 etp35 35 100000
+Ethernet140 280,281,282,283 etp36 36 100000
+Ethernet144 288,289,290,291 etp37 37 100000
+Ethernet148 296,297,298,299 etp38 38 100000
+Ethernet152 304,305,306,307 etp39 39 100000
+Ethernet156 312,313,314,315 etp40 40 100000
+Ethernet160 320,321,322,323 etp41 41 100000
+Ethernet164 328,329,330,331 etp42 42 100000
+Ethernet168 336,337,338,339 etp43 43 100000
+Ethernet172 344,345,346,347 etp44 44 100000
+Ethernet176 352,353,354,355 etp45 45 100000
+Ethernet180 360,361,362,363 etp46 46 100000
+Ethernet184 368,369,370,371 etp47 47 100000
+Ethernet188 376,377,378,379 etp48 48 100000
+Ethernet192 384,385 etp49a 49 50000
+Ethernet194 386,387 etp49b 49 50000
+Ethernet196 392,393 etp50a 50 50000
+Ethernet198 394,395 etp50b 50 50000
+Ethernet200 400,401,402,403 etp51 51 100000
+Ethernet204 408,409,410,411 etp52 52 100000
+Ethernet208 416,417 etp53a 53 50000
+Ethernet210 418,419 etp53b 53 50000
+Ethernet212 424,425 etp54a 54 50000
+Ethernet214 426,427 etp54b 54 50000
+Ethernet216 432,433,434,435 etp55 55 100000
+Ethernet220 440,441,442,443 etp56 56 100000
+Ethernet224 448,449 etp57a 57 50000
+Ethernet226 450,451 etp57b 57 50000
+Ethernet228 456,457 etp58a 58 50000
+Ethernet230 458,459 etp58b 58 50000
+Ethernet232 464,465 etp59a 59 50000
+Ethernet234 466,467 etp59b 59 50000
+Ethernet236 472,473 etp60a 60 50000
+Ethernet238 474,475 etp60b 60 50000
+Ethernet240 480,481 etp61a 61 50000
+Ethernet242 482,483 etp61b 61 50000
+Ethernet244 488,489 etp62a 62 50000
+Ethernet246 490,491 etp62b 62 50000
+Ethernet248 496,497 etp63a 63 50000
+Ethernet250 498,499 etp63b 63 50000
+Ethernet252 504,505 etp64a 64 50000
+Ethernet254 506,507 etp64b 64 50000
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/qos.json.j2 b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/qos.json.j2
new file mode 120000
index 000000000000..05394016a129
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/qos.json.j2
@@ -0,0 +1 @@
+../ACS-MSN4600C/qos.json.j2
\ No newline at end of file
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/sai.profile b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/sai.profile
new file mode 100644
index 000000000000..8719655c1ccc
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/sai.profile
@@ -0,0 +1,4 @@
+SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/sai_4600c_48x50g_40x100g.xml
+SAI_DUMP_STORE_PATH=/var/log/mellanox/sdk-dumps
+SAI_DUMP_STORE_AMOUNT=10
+SAI_VXLAN_SRCPORT_RANGE_ENABLE=1
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/sai_4600c_48x50g_40x100g.xml b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/sai_4600c_48x50g_40x100g.xml
new file mode 100644
index 000000000000..bc26a518c08a
--- /dev/null
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/Mellanox-SN4600C-D48C40/sai_4600c_48x50g_40x100g.xml
@@ -0,0 +1,494 @@
+
+
+
+
+
+ 00:02:03:04:05:80
+
+
+ 1
+
+
+ 64
+
+
+
+
+ 105
+ 2
+ 4
+ 0
+
+
+ 1
+
+
+ 384
+
+
+ 107
+ 2
+ 4
+ 1
+ 1
+ 384
+
+
+ 109
+ 2
+ 4
+ 2
+ 1
+ 384
+
+
+ 111
+ 2
+ 4
+ 3
+ 1
+ 384
+
+
+ 97
+ 2
+ 4
+ 4
+ 1
+ 384
+
+
+ 99
+ 2
+ 4
+ 5
+ 1
+ 384
+
+
+ 101
+ 2
+ 4
+ 6
+ 1
+ 384
+
+
+ 103
+ 2
+ 4
+ 7
+ 1
+ 384
+
+
+ 121
+ 2
+ 4
+ 8
+ 1
+ 384
+
+
+ 123
+ 2
+ 4
+ 9
+ 1
+ 384
+
+
+ 125
+ 4
+ 10
+ 0
+ 1536
+
+
+ 127
+ 4
+ 11
+ 0
+ 1536
+
+
+ 113
+ 2
+ 4
+ 12
+ 1
+ 384
+
+
+ 115
+ 2
+ 4
+ 13
+ 1
+ 384
+
+
+ 117
+ 4
+ 14
+ 0
+ 1536
+
+
+ 119
+ 4
+ 15
+ 0
+ 1536
+
+
+ 89
+ 4
+ 16
+ 0
+ 1536
+
+
+ 91
+ 4
+ 17
+ 0
+ 1536
+
+
+ 93
+ 4
+ 18
+ 0
+ 1536
+
+
+ 95
+ 4
+ 19
+ 0
+ 1536
+
+
+ 81
+ 4
+ 20
+ 0
+ 1536
+
+
+ 83
+ 4
+ 21
+ 0
+ 1536
+
+
+ 85
+ 4
+ 22
+ 0
+ 1536
+
+
+ 87
+ 4
+ 23
+ 0
+ 1536
+
+
+ 73
+ 4
+ 24
+ 0
+ 1536
+
+
+ 75
+ 4
+ 25
+ 0
+ 1536
+
+
+ 77
+ 4
+ 26
+ 0
+ 1536
+
+
+ 79
+ 4
+ 27
+ 0
+ 1536
+
+
+ 65
+ 4
+ 28
+ 0
+ 1536
+
+
+ 67
+ 4
+ 29
+ 0
+ 1536
+
+
+ 69
+ 4
+ 30
+ 0
+ 1536
+
+
+ 71
+ 4
+ 31
+ 0
+ 1536
+
+
+ 5
+ 4
+ 32
+ 0
+ 1536
+
+
+ 7
+ 4
+ 33
+ 0
+ 1536
+
+
+ 1
+ 4
+ 34
+ 0
+ 1536
+
+
+ 3
+ 4
+ 35
+ 0
+ 1536
+
+
+ 13
+ 4
+ 36
+ 0
+ 1536
+
+
+ 15
+ 4
+ 37
+ 0
+ 1536
+
+
+ 9
+ 4
+ 38
+ 0
+ 1536
+
+
+ 11
+ 4
+ 39
+ 0
+ 1536
+
+
+ 21
+ 4
+ 40
+ 0
+ 1536
+
+
+ 23
+ 4
+ 41
+ 0
+ 1536
+
+
+ 17
+ 4
+ 42
+ 0
+ 1536
+
+
+ 19
+ 4
+ 43
+ 0
+ 1536
+
+
+ 29
+ 4
+ 44
+ 0
+ 1536
+
+
+ 31
+ 4
+ 45
+ 0
+ 1536
+
+
+ 25
+ 4
+ 46
+ 0
+ 1536
+
+
+ 27
+ 4
+ 47
+ 0
+ 1536
+
+
+ 53
+ 2
+ 4
+ 48
+ 1
+ 384
+
+
+ 55
+ 2
+ 4
+ 49
+ 1
+ 384
+
+
+ 49
+ 4
+ 50
+ 0
+ 1536
+
+
+ 51
+ 4
+ 51
+ 0
+ 1536
+
+
+ 61
+ 2
+ 4
+ 52
+ 1
+ 384
+
+
+ 63
+ 2
+ 4
+ 53
+ 1
+ 384
+
+
+ 57
+ 4
+ 54
+ 0
+ 1536
+
+
+ 59
+ 4
+ 55
+ 0
+ 1536
+
+
+ 37
+ 2
+ 4
+ 56
+ 1
+ 384
+
+
+ 39
+ 2
+ 4
+ 57
+ 1
+ 384
+
+
+ 33
+ 2
+ 4
+ 58
+ 1
+ 384
+
+
+ 35
+ 2
+ 4
+ 59
+ 1
+ 384
+
+
+ 45
+ 2
+ 4
+ 60
+ 1
+ 384
+
+
+ 47
+ 2
+ 4
+ 61
+ 1
+ 384
+
+
+ 41
+ 2
+ 4
+ 62
+ 1
+ 384
+
+
+ 43
+ 2
+ 4
+ 63
+ 1
+ 384
+
+
+
+
diff --git a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform.json b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform.json
index 691be91ab49b..ab22b4fd18da 100644
--- a/device/mellanox/x86_64-mlnx_msn4600c-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn4600c-r0/platform.json
@@ -620,511 +620,511 @@
"lanes": "0,1,2,3",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp1"],
- "2x50G[40G,25G,10G,1G]": ["etp1a", "etp1b"]
+ "2x50G[25G,10G,1G]": ["etp1a", "etp1b"]
}
},
- "Ethernet8": {
+ "Ethernet4": {
"index": "2,2,2,2",
"lanes": "8,9,10,11",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp2"],
- "2x50G[40G,25G,10G,1G]": ["etp2a", "etp2b"]
+ "2x50G[25G,10G,1G]": ["etp2a", "etp2b"]
}
},
- "Ethernet16": {
+ "Ethernet8": {
"index": "3,3,3,3",
"lanes": "16,17,18,19",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp3"],
- "2x50G[40G,25G,10G,1G]": ["etp3a", "etp3b"]
+ "2x50G[25G,10G,1G]": ["etp3a", "etp3b"]
}
},
- "Ethernet24": {
+ "Ethernet12": {
"index": "4,4,4,4",
"lanes": "24,25,26,27",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp4"],
- "2x50G[40G,25G,10G,1G]": ["etp4a", "etp4b"]
+ "2x50G[25G,10G,1G]": ["etp4a", "etp4b"]
}
},
- "Ethernet32": {
+ "Ethernet16": {
"index": "5,5,5,5",
"lanes": "32,33,34,35",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp5"],
- "2x50G[40G,25G,10G,1G]": ["etp5a", "etp5b"]
+ "2x50G[25G,10G,1G]": ["etp5a", "etp5b"]
}
},
- "Ethernet40": {
+ "Ethernet20": {
"index": "6,6,6,6",
"lanes": "40,41,42,43",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp6"],
- "2x50G[40G,25G,10G,1G]": ["etp6a", "etp6b"]
+ "2x50G[25G,10G,1G]": ["etp6a", "etp6b"]
}
},
- "Ethernet48": {
+ "Ethernet24": {
"index": "7,7,7,7",
"lanes": "48,49,50,51",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp7"],
- "2x50G[40G,25G,10G,1G]": ["etp7a", "etp7b"]
+ "2x50G[25G,10G,1G]": ["etp7a", "etp7b"]
}
},
- "Ethernet56": {
+ "Ethernet28": {
"index": "8,8,8,8",
"lanes": "56,57,58,59",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp8"],
- "2x50G[40G,25G,10G,1G]": ["etp8a", "etp8b"]
+ "2x50G[25G,10G,1G]": ["etp8a", "etp8b"]
}
},
- "Ethernet64": {
+ "Ethernet32": {
"index": "9,9,9,9",
"lanes": "64,65,66,67",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp9"],
- "2x50G[40G,25G,10G,1G]": ["etp9a", "etp9b"]
+ "2x50G[25G,10G,1G]": ["etp9a", "etp9b"]
}
},
- "Ethernet72": {
+ "Ethernet36": {
"index": "10,10,10,10",
"lanes": "72,73,74,75",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp10"],
- "2x50G[40G,25G,10G,1G]": ["etp10a", "etp10b"]
+ "2x50G[25G,10G,1G]": ["etp10a", "etp10b"]
}
},
- "Ethernet80": {
+ "Ethernet40": {
"index": "11,11,11,11",
"lanes": "80,81,82,83",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp11"],
- "2x50G[40G,25G,10G,1G]": ["etp11a", "etp11b"]
+ "2x50G[25G,10G,1G]": ["etp11a", "etp11b"]
}
},
- "Ethernet88": {
+ "Ethernet44": {
"index": "12,12,12,12",
"lanes": "88,89,90,91",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp12"],
- "2x50G[40G,25G,10G,1G]": ["etp12a", "etp12b"]
+ "2x50G[25G,10G,1G]": ["etp12a", "etp12b"]
}
},
- "Ethernet96": {
+ "Ethernet48": {
"index": "13,13,13,13",
"lanes": "96,97,98,99",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp13"],
- "2x50G[40G,25G,10G,1G]": ["etp13a", "etp13b"]
+ "2x50G[25G,10G,1G]": ["etp13a", "etp13b"]
}
},
- "Ethernet104": {
+ "Ethernet52": {
"index": "14,14,14,14",
"lanes": "104,105,106,107",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp14"],
- "2x50G[40G,25G,10G,1G]": ["etp14a", "etp14b"]
+ "2x50G[25G,10G,1G]": ["etp14a", "etp14b"]
}
},
- "Ethernet112": {
+ "Ethernet56": {
"index": "15,15,15,15",
"lanes": "112,113,114,115",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp15"],
- "2x50G[40G,25G,10G,1G]": ["etp15a", "etp15b"]
+ "2x50G[25G,10G,1G]": ["etp15a", "etp15b"]
}
},
- "Ethernet120": {
+ "Ethernet60": {
"index": "16,16,16,16",
"lanes": "120,121,122,123",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp16"],
- "2x50G[40G,25G,10G,1G]": ["etp16a", "etp16b"]
+ "2x50G[25G,10G,1G]": ["etp16a", "etp16b"]
}
},
- "Ethernet128": {
+ "Ethernet64": {
"index": "17,17,17,17",
"lanes": "128,129,130,131",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp17"],
- "2x50G[40G,25G,10G,1G]": ["etp17a", "etp17b"]
+ "2x50G[25G,10G,1G]": ["etp17a", "etp17b"]
}
},
- "Ethernet136": {
+ "Ethernet68": {
"index": "18,18,18,18",
"lanes": "136,137,138,139",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp18"],
- "2x50G[40G,25G,10G,1G]": ["etp18a", "etp18b"]
+ "2x50G[25G,10G,1G]": ["etp18a", "etp18b"]
}
},
- "Ethernet144": {
+ "Ethernet72": {
"index": "19,19,19,19",
"lanes": "144,145,146,147",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp19"],
- "2x50G[40G,25G,10G,1G]": ["etp19a", "etp19b"]
+ "2x50G[25G,10G,1G]": ["etp19a", "etp19b"]
}
},
- "Ethernet152": {
+ "Ethernet76": {
"index": "20,20,20,20",
"lanes": "152,153,154,155",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp20"],
- "2x50G[40G,25G,10G,1G]": ["etp20a", "etp20b"]
+ "2x50G[25G,10G,1G]": ["etp20a", "etp20b"]
}
},
- "Ethernet160": {
+ "Ethernet80": {
"index": "21,21,21,21",
"lanes": "160,161,162,163",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp21"],
- "2x50G[40G,25G,10G,1G]": ["etp21a", "etp21b"]
+ "2x50G[25G,10G,1G]": ["etp21a", "etp21b"]
}
},
- "Ethernet168": {
+ "Ethernet84": {
"index": "22,22,22,22",
"lanes": "168,169,170,171",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp22"],
- "2x50G[40G,25G,10G,1G]": ["etp22a", "etp22b"]
+ "2x50G[25G,10G,1G]": ["etp22a", "etp22b"]
}
},
- "Ethernet176": {
+ "Ethernet88": {
"index": "23,23,23,23",
"lanes": "176,177,178,179",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp23"],
- "2x50G[40G,25G,10G,1G]": ["etp23a", "etp23b"]
+ "2x50G[25G,10G,1G]": ["etp23a", "etp23b"]
}
},
- "Ethernet184": {
+ "Ethernet92": {
"index": "24,24,24,24",
"lanes": "184,185,186,187",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp24"],
- "2x50G[40G,25G,10G,1G]": ["etp24a", "etp24b"]
+ "2x50G[25G,10G,1G]": ["etp24a", "etp24b"]
}
},
- "Ethernet192": {
+ "Ethernet96": {
"index": "25,25,25,25",
"lanes": "192,193,194,195",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp25"],
- "2x50G[40G,25G,10G,1G]": ["etp25a", "etp25b"]
+ "2x50G[25G,10G,1G]": ["etp25a", "etp25b"]
}
},
- "Ethernet200": {
+ "Ethernet100": {
"index": "26,26,26,26",
"lanes": "200,201,202,203",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp26"],
- "2x50G[40G,25G,10G,1G]": ["etp26a", "etp26b"]
+ "2x50G[25G,10G,1G]": ["etp26a", "etp26b"]
}
},
- "Ethernet208": {
+ "Ethernet104": {
"index": "27,27,27,27",
"lanes": "208,209,210,211",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp27"],
- "2x50G[40G,25G,10G,1G]": ["etp27a", "etp27b"]
+ "2x50G[25G,10G,1G]": ["etp27a", "etp27b"]
}
},
- "Ethernet216": {
+ "Ethernet108": {
"index": "28,28,28,28",
"lanes": "216,217,218,219",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp28"],
- "2x50G[40G,25G,10G,1G]": ["etp28a", "etp28b"]
+ "2x50G[25G,10G,1G]": ["etp28a", "etp28b"]
}
},
- "Ethernet224": {
+ "Ethernet112": {
"index": "29,29,29,29",
"lanes": "224,225,226,227",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp29"],
- "2x50G[40G,25G,10G,1G]": ["etp29a", "etp29b"]
+ "2x50G[25G,10G,1G]": ["etp29a", "etp29b"]
}
},
- "Ethernet232": {
+ "Ethernet116": {
"index": "30,30,30,30",
"lanes": "232,233,234,235",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp30"],
- "2x50G[40G,25G,10G,1G]": ["etp30a", "etp30b"]
+ "2x50G[25G,10G,1G]": ["etp30a", "etp30b"]
}
},
- "Ethernet240": {
+ "Ethernet120": {
"index": "31,31,31,31",
"lanes": "240,241,242,243",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp31"],
- "2x50G[40G,25G,10G,1G]": ["etp31a", "etp31b"]
+ "2x50G[25G,10G,1G]": ["etp31a", "etp31b"]
}
},
- "Ethernet248": {
+ "Ethernet124": {
"index": "32,32,32,32",
"lanes": "248,249,250,251",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp32"],
- "2x50G[40G,25G,10G,1G]": ["etp32a", "etp32b"]
+ "2x50G[25G,10G,1G]": ["etp32a", "etp32b"]
}
},
- "Ethernet256": {
+ "Ethernet128": {
"index": "33,33,33,33",
"lanes": "256,257,258,259",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp33"],
- "2x50G[40G,25G,10G,1G]": ["etp33a", "etp33b"]
+ "2x50G[25G,10G,1G]": ["etp33a", "etp33b"]
}
},
- "Ethernet264": {
+ "Ethernet132": {
"index": "34,34,34,34",
"lanes": "264,265,266,267",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp34"],
- "2x50G[40G,25G,10G,1G]": ["etp34a", "etp34b"]
+ "2x50G[25G,10G,1G]": ["etp34a", "etp34b"]
}
},
- "Ethernet272": {
+ "Ethernet136": {
"index": "35,35,35,35",
"lanes": "272,273,274,275",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp35"],
- "2x50G[40G,25G,10G,1G]": ["etp35a", "etp35b"]
+ "2x50G[25G,10G,1G]": ["etp35a", "etp35b"]
}
},
- "Ethernet280": {
+ "Ethernet140": {
"index": "36,36,36,36",
"lanes": "280,281,282,283",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp36"],
- "2x50G[40G,25G,10G,1G]": ["etp36a", "etp36b"]
+ "2x50G[25G,10G,1G]": ["etp36a", "etp36b"]
}
},
- "Ethernet288": {
+ "Ethernet144": {
"index": "37,37,37,37",
"lanes": "288,289,290,291",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp37"],
- "2x50G[40G,25G,10G,1G]": ["etp37a", "etp37b"]
+ "2x50G[25G,10G,1G]": ["etp37a", "etp37b"]
}
},
- "Ethernet296": {
+ "Ethernet148": {
"index": "38,38,38,38",
"lanes": "296,297,298,299",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp38"],
- "2x50G[40G,25G,10G,1G]": ["etp38a", "etp38b"]
+ "2x50G[25G,10G,1G]": ["etp38a", "etp38b"]
}
},
- "Ethernet304": {
+ "Ethernet152": {
"index": "39,39,39,39",
"lanes": "304,305,306,307",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp39"],
- "2x50G[40G,25G,10G,1G]": ["etp39a", "etp39b"]
+ "2x50G[25G,10G,1G]": ["etp39a", "etp39b"]
}
},
- "Ethernet312": {
+ "Ethernet156": {
"index": "40,40,40,40",
"lanes": "312,313,314,315",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp40"],
- "2x50G[40G,25G,10G,1G]": ["etp40a", "etp40b"]
+ "2x50G[25G,10G,1G]": ["etp40a", "etp40b"]
}
},
- "Ethernet320": {
+ "Ethernet160": {
"index": "41,41,41,41",
"lanes": "320,321,322,323",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp41"],
- "2x50G[40G,25G,10G,1G]": ["etp42a", "etp42b"]
+ "2x50G[25G,10G,1G]": ["etp42a", "etp42b"]
}
},
- "Ethernet328": {
+ "Ethernet164": {
"index": "42,42,42,42",
"lanes": "328,329,330,331",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp42"],
- "2x50G[40G,25G,10G,1G]": ["etp42a", "etp42b"]
+ "2x50G[25G,10G,1G]": ["etp42a", "etp42b"]
}
},
- "Ethernet336": {
+ "Ethernet168": {
"index": "43,43,43,43",
"lanes": "336,337,338,339",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp43"],
- "2x50G[40G,25G,10G,1G]": ["etp43a", "etp43b"]
+ "2x50G[25G,10G,1G]": ["etp43a", "etp43b"]
}
},
- "Ethernet344": {
+ "Ethernet172": {
"index": "44,44,44,44",
"lanes": "344,345,346,347",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp44"],
- "2x50G[40G,25G,10G,1G]": ["etp44a", "etp44b"]
+ "2x50G[25G,10G,1G]": ["etp44a", "etp44b"]
}
},
- "Ethernet352": {
+ "Ethernet176": {
"index": "45,45,45,45",
"lanes": "352,353,354,355",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp45"],
- "2x50G[40G,25G,10G,1G]": ["etp45a", "etp45b"]
+ "2x50G[25G,10G,1G]": ["etp45a", "etp45b"]
}
},
- "Ethernet360": {
+ "Ethernet180": {
"index": "46,46,46,46",
"lanes": "360,361,362,363",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp46"],
- "2x50G[40G,25G,10G,1G]": ["etp46a", "etp46b"]
+ "2x50G[25G,10G,1G]": ["etp46a", "etp46b"]
}
},
- "Ethernet368": {
+ "Ethernet184": {
"index": "47,47,47,47",
"lanes": "368,369,370,371",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp47"],
- "2x50G[40G,25G,10G,1G]": ["etp47a", "etp47b"]
+ "2x50G[25G,10G,1G]": ["etp47a", "etp47b"]
}
},
- "Ethernet376": {
+ "Ethernet188": {
"index": "48,48,48,48",
"lanes": "376,377,378,379",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp48"],
- "2x50G[40G,25G,10G,1G]": ["etp48a", "etp48b"]
+ "2x50G[25G,10G,1G]": ["etp48a", "etp48b"]
}
},
- "Ethernet384": {
+ "Ethernet192": {
"index": "49,49,49,49",
"lanes": "384,385,386,387",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp49"],
- "2x50G[40G,25G,10G,1G]": ["etp49a", "etp49b"]
+ "2x50G[25G,10G,1G]": ["etp49a", "etp49b"]
}
},
- "Ethernet392": {
+ "Ethernet196": {
"index": "50,50,50,50",
"lanes": "392,393,394,395",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp50"],
- "2x50G[40G,25G,10G,1G]": ["etp50a", "etp50b"]
+ "2x50G[25G,10G,1G]": ["etp50a", "etp50b"]
}
},
- "Ethernet400": {
+ "Ethernet200": {
"index": "51,51,51,51",
"lanes": "400,401,402,403",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp51"],
- "2x50G[40G,25G,10G,1G]": ["etp51a", "etp51b"]
+ "2x50G[25G,10G,1G]": ["etp51a", "etp51b"]
}
},
- "Ethernet408": {
+ "Ethernet204": {
"index": "52,52,52,52",
"lanes": "408,409,410,411",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp52"],
- "2x50G[40G,25G,10G,1G]": ["etp52a", "etp52b"]
+ "2x50G[25G,10G,1G]": ["etp52a", "etp52b"]
}
},
- "Ethernet416": {
+ "Ethernet208": {
"index": "53,53,53,53",
"lanes": "416,417,418,419",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp53"],
- "2x50G[40G,25G,10G,1G]": ["etp53a", "etp53b"]
+ "2x50G[25G,10G,1G]": ["etp53a", "etp53b"]
}
},
- "Ethernet424": {
+ "Ethernet212": {
"index": "54,54,54,54",
"lanes": "424,425,426,427",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp54"],
- "2x50G[40G,25G,10G,1G]": ["etp54a", "etp54b"]
+ "2x50G[25G,10G,1G]": ["etp54a", "etp54b"]
}
},
- "Ethernet432": {
+ "Ethernet216": {
"index": "55,55,55,55",
"lanes": "432,433,434,435",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp55"],
- "2x50G[40G,25G,10G,1G]": ["etp55a", "etp55b"]
+ "2x50G[25G,10G,1G]": ["etp55a", "etp55b"]
}
},
- "Ethernet440": {
+ "Ethernet220": {
"index": "56,56,56,56",
"lanes": "440,441,442,443",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp56"],
- "2x50G[40G,25G,10G,1G]": ["etp56a", "etp56b"]
+ "2x50G[25G,10G,1G]": ["etp56a", "etp56b"]
}
},
- "Ethernet448": {
+ "Ethernet224": {
"index": "57,57,57,57",
"lanes": "448,449,450,451",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp57"],
- "2x50G[40G,25G,10G,1G]": ["etp57a", "etp57b"]
+ "2x50G[25G,10G,1G]": ["etp57a", "etp57b"]
}
},
- "Ethernet456": {
+ "Ethernet228": {
"index": "58,58,58,58",
"lanes": "456,457,458,459",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp58"],
- "2x50G[40G,25G,10G,1G]": ["etp58a", "etp58b"]
+ "2x50G[25G,10G,1G]": ["etp58a", "etp58b"]
}
},
- "Ethernet464": {
+ "Ethernet232": {
"index": "59,59,59,59",
"lanes": "464,465,466,467",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp59"],
- "2x50G[40G,25G,10G,1G]": ["etp59a", "etp59b"]
+ "2x50G[25G,10G,1G]": ["etp59a", "etp59b"]
}
},
- "Ethernet472": {
+ "Ethernet236": {
"index": "60,60,60,60",
"lanes": "472,473,474,475",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp60"],
- "2x50G[40G,25G,10G,1G]": ["etp60a", "etp60b"]
+ "2x50G[25G,10G,1G]": ["etp60a", "etp60b"]
}
},
- "Ethernet480": {
+ "Ethernet240": {
"index": "61,61,61,61",
"lanes": "480,481,482,483",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp61"],
- "2x50G[40G,25G,10G,1G]": ["etp61a", "etp61b"]
+ "2x50G[25G,10G,1G]": ["etp61a", "etp61b"]
}
},
- "Ethernet488": {
+ "Ethernet244": {
"index": "62,62,62,62",
"lanes": "488,489,490,491",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp62"],
- "2x50G[40G,25G,10G,1G]": ["etp62a", "etp62b"]
+ "2x50G[25G,10G,1G]": ["etp62a", "etp62b"]
}
},
- "Ethernet496": {
+ "Ethernet248": {
"index": "63,63,63,63",
"lanes": "496,497,498,499",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp63"],
- "2x50G[40G,25G,10G,1G]": ["etp63a", "etp63b"]
+ "2x50G[25G,10G,1G]": ["etp63a", "etp63b"]
}
},
- "Ethernet504": {
+ "Ethernet252": {
"index": "64,64,64,64",
"lanes": "504,505,506,507",
"breakout_modes": {
"1x100G[50G,40G,25G,10G,1G]": ["etp64"],
- "2x50G[40G,25G,10G,1G]": ["etp64a", "etp64b"]
+ "2x50G[25G,10G,1G]": ["etp64a", "etp64b"]
}
}
}
diff --git a/device/mellanox/x86_64-mlnx_msn4700-r0/platform.json b/device/mellanox/x86_64-mlnx_msn4700-r0/platform.json
index 9f0391fa35ec..88b5045afadc 100644
--- a/device/mellanox/x86_64-mlnx_msn4700-r0/platform.json
+++ b/device/mellanox/x86_64-mlnx_msn4700-r0/platform.json
@@ -412,8 +412,8 @@
"lanes": "0,1,2,3,4,5,6,7",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp1"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp1a", "etp1b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp1a", "etp1b", "etp1c", "etp1d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp1a", "etp1b"],
+ "4x100G[50G,25G,10G,1G]": ["etp1a", "etp1b", "etp1c", "etp1d"]
}
},
"Ethernet8": {
@@ -421,8 +421,8 @@
"lanes": "8,9,10,11,12,13,14,15",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp2"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp2a", "etp2b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp2a", "etp2b", "etp2c", "etp2d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp2a", "etp2b"],
+ "4x100G[50G,25G,10G,1G]": ["etp2a", "etp2b", "etp2c", "etp2d"]
}
},
"Ethernet16": {
@@ -430,8 +430,8 @@
"lanes": "16,17,18,19,20,21,22,23",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp3"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp3a", "etp3b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp3a", "etp3b", "etp3c", "etp3d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp3a", "etp3b"],
+ "4x100G[50G,25G,10G,1G]": ["etp3a", "etp3b", "etp3c", "etp3d"]
}
},
"Ethernet24": {
@@ -439,8 +439,8 @@
"lanes": "24,25,26,27,28,29,30,31",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp4"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp4a", "etp4b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp4a", "etp4b", "etp4c", "etp4d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp4a", "etp4b"],
+ "4x100G[50G,25G,10G,1G]": ["etp4a", "etp4b", "etp4c", "etp4d"]
}
},
"Ethernet32": {
@@ -448,8 +448,8 @@
"lanes": "32,33,34,35,36,37,38,39",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp5"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp5a", "etp5b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp5a", "etp5b", "etp5c", "etp5d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp5a", "etp5b"],
+ "4x100G[50G,25G,10G,1G]": ["etp5a", "etp5b", "etp5c", "etp5d"]
}
},
"Ethernet40": {
@@ -457,8 +457,8 @@
"lanes": "40,41,42,43,44,45,46,47",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp6"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp6a", "etp6b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp6a", "etp6b", "etp6c", "etp6d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp6a", "etp6b"],
+ "4x100G[50G,25G,10G,1G]": ["etp6a", "etp6b", "etp6c", "etp6d"]
}
},
"Ethernet48": {
@@ -466,8 +466,8 @@
"lanes": "48,49,50,51,52,53,54,55",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp7"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp7a", "etp7b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp7a", "etp7b", "etp7c", "etp7d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp7a", "etp7b"],
+ "4x100G[50G,25G,10G,1G]": ["etp7a", "etp7b", "etp7c", "etp7d"]
}
},
"Ethernet56": {
@@ -475,8 +475,8 @@
"lanes": "56,57,58,59,60,61,62,63",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp8"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp8a", "etp8b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp8a", "etp8b", "etp8c", "etp8d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp8a", "etp8b"],
+ "4x100G[50G,25G,10G,1G]": ["etp8a", "etp8b", "etp8c", "etp8d"]
}
},
"Ethernet64": {
@@ -484,8 +484,8 @@
"lanes": "64,65,66,67,68,69,70,71",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp9"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp9a", "etp9b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp9a", "etp9b", "etp9c", "etp9d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp9a", "etp9b"],
+ "4x100G[50G,25G,10G,1G]": ["etp9a", "etp9b", "etp9c", "etp9d"]
}
},
"Ethernet72": {
@@ -493,8 +493,8 @@
"lanes": "72,73,74,75,76,77,78,79",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp10"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp10a", "etp10b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp10a", "etp10b", "etp10c", "etp10d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp10a", "etp10b"],
+ "4x100G[50G,25G,10G,1G]": ["etp10a", "etp10b", "etp10c", "etp10d"]
}
},
"Ethernet80": {
@@ -502,8 +502,8 @@
"lanes": "80,81,82,83,84,85,86,87",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp11"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp11a", "etp11b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp11a", "etp11b", "etp11c", "etp11d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp11a", "etp11b"],
+ "4x100G[50G,25G,10G,1G]": ["etp11a", "etp11b", "etp11c", "etp11d"]
}
},
"Ethernet88": {
@@ -511,8 +511,8 @@
"lanes": "88,89,90,91,92,93,94,95",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp12"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp12a", "etp12b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp12a", "etp12b", "etp12c", "etp12d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp12a", "etp12b"],
+ "4x100G[50G,25G,10G,1G]": ["etp12a", "etp12b", "etp12c", "etp12d"]
}
},
"Ethernet96": {
@@ -520,8 +520,8 @@
"lanes": "96,97,98,99,100,101,102,103",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp13"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp13a", "etp13b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp13a", "etp13b", "etp13c", "etp13d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp13a", "etp13b"],
+ "4x100G[50G,25G,10G,1G]": ["etp13a", "etp13b", "etp13c", "etp13d"]
}
},
"Ethernet104": {
@@ -529,8 +529,8 @@
"lanes": "104,105,106,107,108,109,110,111",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp14"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp14a", "etp14b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp14a", "etp14b", "etp14c", "etp14d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp14a", "etp14b"],
+ "4x100G[50G,25G,10G,1G]": ["etp14a", "etp14b", "etp14c", "etp14d"]
}
},
"Ethernet112": {
@@ -538,8 +538,8 @@
"lanes": "112,113,114,115,116,117,118,119",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp15"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp15a", "etp15b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp15a", "etp15b", "etp15c", "etp15d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp15a", "etp15b"],
+ "4x100G[50G,25G,10G,1G]": ["etp15a", "etp15b", "etp15c", "etp15d"]
}
},
"Ethernet120": {
@@ -547,8 +547,8 @@
"lanes": "120,121,122,123,124,125,126,127",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp16"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp16a", "etp16b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp16a", "etp16b", "etp16c", "etp16d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp16a", "etp16b"],
+ "4x100G[50G,25G,10G,1G]": ["etp16a", "etp16b", "etp16c", "etp16d"]
}
},
"Ethernet128": {
@@ -556,8 +556,8 @@
"lanes": "128,129,130,131,132,133,134,135",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp17"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp17a", "etp17b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp17a", "etp17b", "etp17c", "etp17d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp17a", "etp17b"],
+ "4x100G[50G,25G,10G,1G]": ["etp17a", "etp17b", "etp17c", "etp17d"]
}
},
"Ethernet136": {
@@ -565,8 +565,8 @@
"lanes": "136,137,138,139,140,141,142,143",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp18"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp18a", "etp18b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp18a", "etp18b", "etp18c", "etp18d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp18a", "etp18b"],
+ "4x100G[50G,25G,10G,1G]": ["etp18a", "etp18b", "etp18c", "etp18d"]
}
},
"Ethernet144": {
@@ -574,8 +574,8 @@
"lanes": "144,145,146,147,148,149,150,151",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp19"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp19a", "etp19b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp19a", "etp19b", "etp19c", "etp19d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp19a", "etp19b"],
+ "4x100G[50G,25G,10G,1G]": ["etp19a", "etp19b", "etp19c", "etp19d"]
}
},
"Ethernet152": {
@@ -583,8 +583,8 @@
"lanes": "152,153,154,155,156,157,158,159",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp20"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp20a", "etp20b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp20a", "etp20b", "etp20c", "etp20d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp20a", "etp20b"],
+ "4x100G[50G,25G,10G,1G]": ["etp20a", "etp20b", "etp20c", "etp20d"]
}
},
"Ethernet160": {
@@ -592,8 +592,8 @@
"lanes": "160,161,162,163,164,165,166,167",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp21"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp21a", "etp21b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp21a", "etp21b", "etp21c", "etp21d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp21a", "etp21b"],
+ "4x100G[50G,25G,10G,1G]": ["etp21a", "etp21b", "etp21c", "etp21d"]
}
},
"Ethernet168": {
@@ -601,8 +601,8 @@
"lanes": "168,169,170,171,172,173,174,175",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp22"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp22a", "etp22b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp22a", "etp22b", "etp22c", "etp22d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp22a", "etp22b"],
+ "4x100G[50G,25G,10G,1G]": ["etp22a", "etp22b", "etp22c", "etp22d"]
}
},
"Ethernet176": {
@@ -610,8 +610,8 @@
"lanes": "176,177,178,179,180,181,182,183",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp23"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp23a", "etp23b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp23a", "etp23b", "etp23c", "etp23d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp23a", "etp23b"],
+ "4x100G[50G,25G,10G,1G]": ["etp23a", "etp23b", "etp23c", "etp23d"]
}
},
"Ethernet184": {
@@ -619,8 +619,8 @@
"lanes": "184,185,186,187,188,189,190,191",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp24"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp24a", "etp24b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp24a", "etp24b", "etp24c", "etp24d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp24a", "etp24b"],
+ "4x100G[50G,25G,10G,1G]": ["etp24a", "etp24b", "etp24c", "etp24d"]
}
},
"Ethernet192": {
@@ -628,8 +628,8 @@
"lanes": "192,193,194,195,196,197,198,199",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp25"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp25a", "etp25b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp25a", "etp25b"],
+ "4x100G[50G,25G,10G,1G]": ["etp25a", "etp25b", "etp25c", "etp25d"]
}
},
"Ethernet200": {
@@ -637,8 +637,8 @@
"lanes": "200,201,202,203,204,205,206,207",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp26"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp26a", "etp26b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp26a", "etp26b"],
+ "4x100G[50G,25G,10G,1G]": ["etp26a", "etp26b", "etp26c", "etp26d"]
}
},
"Ethernet208": {
@@ -646,8 +646,8 @@
"lanes": "208,209,210,211,212,213,214,215",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp27"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp27a", "etp27b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp27a", "etp27b"],
+ "4x100G[50G,25G,10G,1G]": ["etp27a", "etp27b", "etp27c", "etp27d"]
}
},
"Ethernet216": {
@@ -655,8 +655,8 @@
"lanes": "216,217,218,219,220,221,222,223",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp28"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp28a", "etp28b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp28a", "etp28b"],
+ "4x100G[50G,25G,10G,1G]": ["etp28a", "etp28b", "etp28c", "etp28d"]
}
},
"Ethernet224": {
@@ -664,8 +664,8 @@
"lanes": "224,225,226,227,228,229,230,231",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp29"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp29a", "etp29b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp29a", "etp29b"],
+ "4x100G[50G,25G,10G,1G]": ["etp29a", "etp29b", "etp29c", "etp29d"]
}
},
"Ethernet232": {
@@ -673,8 +673,8 @@
"lanes": "232,233,234,235,236,237,238,239",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp30"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp30a", "etp30b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp30a", "etp30b"],
+ "4x100G[50G,25G,10G,1G]": ["etp30a", "etp30b", "etp30c", "etp30d"]
}
},
"Ethernet240": {
@@ -682,8 +682,8 @@
"lanes": "240,241,242,243,244,245,246,247",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp31"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp31a", "etp31b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp31a", "etp31b"],
+ "4x100G[50G,25G,10G,1G]": ["etp31a", "etp31b", "etp31c", "etp31d"]
}
},
"Ethernet248": {
@@ -691,8 +691,8 @@
"lanes": "248,249,250,251,252,253,254,255",
"breakout_modes": {
"1x400G[200G,100G,50G,40G,25G,10G,1G]": ["etp32"],
- "2x200G[100G,50G,40G,25G,10G,1G]": ["etp32a", "etp32b"],
- "4x100G[50G,40G,25G,10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"]
+ "2x200G[100G,50G,25G,10G,1G]": ["etp32a", "etp32b"],
+ "4x100G[50G,25G,10G,1G]": ["etp32a", "etp32b", "etp32c", "etp32d"]
}
}
}
diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/0/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/0/context_config.json
deleted file mode 100644
index bf8d2f497567..000000000000
--- a/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/0/context_config.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "CONTEXTS": [
- {
- "guid" : 0,
- "name" : "syncd0",
- "dbAsic" : "ASIC_DB",
- "dbCounters" : "COUNTERS_DB",
- "dbFlex": "FLEX_COUNTER_DB",
- "dbState" : "STATE_DB",
- "zmq_enable": false,
- "zmq_endpoint": "tcp://127.0.0.1:5555",
- "zmq_ntf_endpoint": "tcp://127.0.0.1:5556",
- "switches": [
- {
- "index" : 0,
- "hwinfo" : "0"
- }
- ]
- }
- ]
-}
diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/1/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/1/context_config.json
deleted file mode 100644
index 0dcc997c9259..000000000000
--- a/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/1/context_config.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "CONTEXTS": [
- {
- "guid" : 0,
- "name" : "syncd1",
- "dbAsic" : "ASIC_DB",
- "dbCounters" : "COUNTERS_DB",
- "dbFlex": "FLEX_COUNTER_DB",
- "dbState" : "STATE_DB",
- "zmq_enable": false,
- "zmq_endpoint": "tcp://127.0.0.1:5555",
- "zmq_ntf_endpoint": "tcp://127.0.0.1:5556",
- "switches": [
- {
- "index" : 0,
- "hwinfo" : "1"
- }
- ]
- }
- ]
-}
diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/2/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/2/context_config.json
deleted file mode 100644
index e4541b0c7b90..000000000000
--- a/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/2/context_config.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "CONTEXTS": [
- {
- "guid" : 0,
- "name" : "syncd2",
- "dbAsic" : "ASIC_DB",
- "dbCounters" : "COUNTERS_DB",
- "dbFlex": "FLEX_COUNTER_DB",
- "dbState" : "STATE_DB",
- "zmq_enable": false,
- "zmq_endpoint": "tcp://127.0.0.1:5555",
- "zmq_ntf_endpoint": "tcp://127.0.0.1:5556",
- "switches": [
- {
- "index" : 0,
- "hwinfo" : "2"
- }
- ]
- }
- ]
-}
diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/3/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/3/context_config.json
deleted file mode 100644
index e32691dc1f35..000000000000
--- a/device/virtual/x86_64-kvm_x86_64-r0/msft_four_asic_vs/3/context_config.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "CONTEXTS": [
- {
- "guid" : 0,
- "name" : "syncd3",
- "dbAsic" : "ASIC_DB",
- "dbCounters" : "COUNTERS_DB",
- "dbFlex": "FLEX_COUNTER_DB",
- "dbState" : "STATE_DB",
- "zmq_enable": false,
- "zmq_endpoint": "tcp://127.0.0.1:5555",
- "zmq_ntf_endpoint": "tcp://127.0.0.1:5556",
- "switches": [
- {
- "index" : 0,
- "hwinfo" : "3"
- }
- ]
- }
- ]
-}
diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/context_config.json
deleted file mode 100644
index bf8d2f497567..000000000000
--- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/0/context_config.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "CONTEXTS": [
- {
- "guid" : 0,
- "name" : "syncd0",
- "dbAsic" : "ASIC_DB",
- "dbCounters" : "COUNTERS_DB",
- "dbFlex": "FLEX_COUNTER_DB",
- "dbState" : "STATE_DB",
- "zmq_enable": false,
- "zmq_endpoint": "tcp://127.0.0.1:5555",
- "zmq_ntf_endpoint": "tcp://127.0.0.1:5556",
- "switches": [
- {
- "index" : 0,
- "hwinfo" : "0"
- }
- ]
- }
- ]
-}
diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/context_config.json
deleted file mode 100644
index 0dcc997c9259..000000000000
--- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/1/context_config.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "CONTEXTS": [
- {
- "guid" : 0,
- "name" : "syncd1",
- "dbAsic" : "ASIC_DB",
- "dbCounters" : "COUNTERS_DB",
- "dbFlex": "FLEX_COUNTER_DB",
- "dbState" : "STATE_DB",
- "zmq_enable": false,
- "zmq_endpoint": "tcp://127.0.0.1:5555",
- "zmq_ntf_endpoint": "tcp://127.0.0.1:5556",
- "switches": [
- {
- "index" : 0,
- "hwinfo" : "1"
- }
- ]
- }
- ]
-}
diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/context_config.json
deleted file mode 100644
index e4541b0c7b90..000000000000
--- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/2/context_config.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "CONTEXTS": [
- {
- "guid" : 0,
- "name" : "syncd2",
- "dbAsic" : "ASIC_DB",
- "dbCounters" : "COUNTERS_DB",
- "dbFlex": "FLEX_COUNTER_DB",
- "dbState" : "STATE_DB",
- "zmq_enable": false,
- "zmq_endpoint": "tcp://127.0.0.1:5555",
- "zmq_ntf_endpoint": "tcp://127.0.0.1:5556",
- "switches": [
- {
- "index" : 0,
- "hwinfo" : "2"
- }
- ]
- }
- ]
-}
diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/context_config.json
deleted file mode 100644
index e32691dc1f35..000000000000
--- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/3/context_config.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "CONTEXTS": [
- {
- "guid" : 0,
- "name" : "syncd3",
- "dbAsic" : "ASIC_DB",
- "dbCounters" : "COUNTERS_DB",
- "dbFlex": "FLEX_COUNTER_DB",
- "dbState" : "STATE_DB",
- "zmq_enable": false,
- "zmq_endpoint": "tcp://127.0.0.1:5555",
- "zmq_ntf_endpoint": "tcp://127.0.0.1:5556",
- "switches": [
- {
- "index" : 0,
- "hwinfo" : "3"
- }
- ]
- }
- ]
-}
diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/context_config.json
deleted file mode 100644
index 6517d0469314..000000000000
--- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/4/context_config.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "CONTEXTS": [
- {
- "guid" : 0,
- "name" : "syncd4",
- "dbAsic" : "ASIC_DB",
- "dbCounters" : "COUNTERS_DB",
- "dbFlex": "FLEX_COUNTER_DB",
- "dbState" : "STATE_DB",
- "zmq_enable": false,
- "zmq_endpoint": "tcp://127.0.0.1:5555",
- "zmq_ntf_endpoint": "tcp://127.0.0.1:5556",
- "switches": [
- {
- "index" : 0,
- "hwinfo" : "4"
- }
- ]
- }
- ]
-}
diff --git a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/context_config.json b/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/context_config.json
deleted file mode 100644
index 2aa18004ea31..000000000000
--- a/device/virtual/x86_64-kvm_x86_64-r0/msft_multi_asic_vs/5/context_config.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "CONTEXTS": [
- {
- "guid" : 0,
- "name" : "syncd5",
- "dbAsic" : "ASIC_DB",
- "dbCounters" : "COUNTERS_DB",
- "dbFlex": "FLEX_COUNTER_DB",
- "dbState" : "STATE_DB",
- "zmq_enable": false,
- "zmq_endpoint": "tcp://127.0.0.1:5555",
- "zmq_ntf_endpoint": "tcp://127.0.0.1:5556",
- "switches": [
- {
- "index" : 0,
- "hwinfo" : "5"
- }
- ]
- }
- ]
-}
diff --git a/dockers/docker-dhcp-relay/Dockerfile.j2 b/dockers/docker-dhcp-relay/Dockerfile.j2
index 1100aa510742..a08e74145fe1 100644
--- a/dockers/docker-dhcp-relay/Dockerfile.j2
+++ b/dockers/docker-dhcp-relay/Dockerfile.j2
@@ -30,7 +30,9 @@ RUN apt-get clean -y && \
COPY ["docker_init.sh", "start.sh", "/usr/bin/"]
COPY ["docker-dhcp-relay.supervisord.conf.j2", "port-name-alias-map.txt.j2", "wait_for_intf.sh.j2", "/usr/share/sonic/templates/"]
+COPY ["dhcp-relay.programs.j2", "dhcpv4-relay.agents.j2", "dhcpv6-relay.agents.j2", "dhcpv6-relay.monitors.j2", "/usr/share/sonic/templates/"]
COPY ["files/supervisor-proc-exit-listener", "/usr/bin"]
COPY ["critical_processes", "/etc/supervisor"]
+COPY ["cli", "/cli/"]
ENTRYPOINT ["/usr/bin/docker_init.sh"]
diff --git a/dockers/docker-dhcp-relay/cli-plugin-tests/conftest.py b/dockers/docker-dhcp-relay/cli-plugin-tests/conftest.py
new file mode 100644
index 000000000000..4eb79edd0b60
--- /dev/null
+++ b/dockers/docker-dhcp-relay/cli-plugin-tests/conftest.py
@@ -0,0 +1,27 @@
+import pytest
+import mock_tables # lgtm [py/unused-import]
+from unittest import mock
+
+@pytest.fixture()
+def mock_cfgdb():
+ cfgdb = mock.Mock()
+ CONFIG = {
+ 'VLAN': {
+ 'Vlan1000': {
+ 'dhcp_servers': ['192.0.0.1']
+ }
+ }
+ }
+
+ def get_entry(table, key):
+ return CONFIG[table][key]
+
+ def set_entry(table, key, data):
+ CONFIG[table].setdefault(key, {})
+ CONFIG[table][key] = data
+
+ cfgdb.get_entry = mock.Mock(side_effect=get_entry)
+ cfgdb.set_entry = mock.Mock(side_effect=set_entry)
+
+ yield cfgdb
+
diff --git a/dockers/docker-dhcp-relay/cli-plugin-tests/mock_tables.py b/dockers/docker-dhcp-relay/cli-plugin-tests/mock_tables.py
new file mode 100644
index 000000000000..650d2cf489e1
--- /dev/null
+++ b/dockers/docker-dhcp-relay/cli-plugin-tests/mock_tables.py
@@ -0,0 +1,154 @@
+# MONKEY PATCH!!!
+import json
+import os
+from unittest import mock
+
+import mockredis
+import redis
+import swsssdk
+from sonic_py_common import multi_asic
+from swsssdk import SonicDBConfig, SonicV2Connector, ConfigDBConnector, ConfigDBPipeConnector
+from swsscommon import swsscommon
+
+
+topo = None
+dedicated_dbs = {}
+
+def clean_up_config():
+ # Set SonicDBConfig variables to initial state
+ # so that it can be loaded with single or multiple
+ # namespaces before the test begins.
+ SonicDBConfig._sonic_db_config = {}
+ SonicDBConfig._sonic_db_global_config_init = False
+ SonicDBConfig._sonic_db_config_init = False
+
+def load_namespace_config():
+ # To support multi asic testing
+ # SonicDBConfig load_sonic_global_db_config
+ # is invoked to load multiple namespaces
+ clean_up_config()
+ SonicDBConfig.load_sonic_global_db_config(
+ global_db_file_path=os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), 'database_global.json'))
+
+def load_database_config():
+ # Load local database_config.json for single namespace test scenario
+ clean_up_config()
+ SonicDBConfig.load_sonic_db_config(
+ sonic_db_file_path=os.path.join(
+ os.path.dirname(os.path.abspath(__file__)), 'database_config.json'))
+
+
+_old_connect_SonicV2Connector = SonicV2Connector.connect
+
+def connect_SonicV2Connector(self, db_name, retry_on=True):
+ # add topo to kwargs for testing different topology
+ self.dbintf.redis_kwargs['topo'] = topo
+ # add the namespace to kwargs for testing multi asic
+ self.dbintf.redis_kwargs['namespace'] = self.namespace
+ # Mock DB filename for unit-test
+ global dedicated_dbs
+ if dedicated_dbs and dedicated_dbs.get(db_name):
+ self.dbintf.redis_kwargs['db_name'] = dedicated_dbs[db_name]
+ else:
+ self.dbintf.redis_kwargs['db_name'] = db_name
+ self.dbintf.redis_kwargs['decode_responses'] = True
+ _old_connect_SonicV2Connector(self, db_name, retry_on)
+
+def _subscribe_keyspace_notification(self, db_name, client):
+ pass
+
+
+def config_set(self, *args):
+ pass
+
+
+class MockPubSub:
+ def get_message(self):
+ return None
+
+ def psubscribe(self, *args, **kwargs):
+ pass
+
+ def __call__(self, *args, **kwargs):
+ return self
+
+ def listen(self):
+ return []
+
+ def punsubscribe(self, *args, **kwargs):
+ pass
+
+ def clear(self):
+ pass
+
+INPUT_DIR = os.path.dirname(os.path.abspath(__file__))
+
+
+class SwssSyncClient(mockredis.MockRedis):
+ def __init__(self, *args, **kwargs):
+ super(SwssSyncClient, self).__init__(strict=True, *args, **kwargs)
+ # Namespace is added in kwargs specifically for unit-test
+ # to identify the file path to load the db json files.
+ topo = kwargs.pop('topo')
+ namespace = kwargs.pop('namespace')
+ db_name = kwargs.pop('db_name')
+ self.decode_responses = kwargs.pop('decode_responses', False) == True
+ fname = db_name.lower() + ".json"
+ self.pubsub = MockPubSub()
+
+ if namespace is not None and namespace is not multi_asic.DEFAULT_NAMESPACE:
+ fname = os.path.join(INPUT_DIR, namespace, fname)
+ elif topo is not None:
+ fname = os.path.join(INPUT_DIR, topo, fname)
+ else:
+ fname = os.path.join(INPUT_DIR, fname)
+
+ if os.path.exists(fname):
+ with open(fname) as f:
+ js = json.load(f)
+ for k, v in js.items():
+ if 'expireat' in v and 'ttl' in v and 'type' in v and 'value' in v:
+ # database is in redis-dump format
+ if v['type'] == 'hash':
+ # ignore other types for now since sonic has hset keys only in the db
+ for attr, value in v['value'].items():
+ self.hset(k, attr, value)
+ else:
+ for attr, value in v.items():
+ self.hset(k, attr, value)
+
+ # Patch mockredis/mockredis/client.py
+ # The offical implementation assume decode_responses=False
+ # Here we detect the option and decode after doing encode
+ def _encode(self, value):
+ "Return a bytestring representation of the value. Taken from redis-py connection.py"
+
+ value = super(SwssSyncClient, self)._encode(value)
+
+ if self.decode_responses:
+ return value.decode('utf-8')
+
+ # Patch mockredis/mockredis/client.py
+ # The official implementation will filter out keys with a slash '/'
+ # ref: https://github.com/locationlabs/mockredis/blob/master/mockredis/client.py
+ def keys(self, pattern='*'):
+ """Emulate keys."""
+ import fnmatch
+ import re
+
+ # Make regex out of glob styled pattern.
+ regex = fnmatch.translate(pattern)
+ regex = re.compile(regex)
+
+ # Find every key that matches the pattern
+ return [key for key in self.redis if regex.match(key)]
+
+
+swsssdk.interface.DBInterface._subscribe_keyspace_notification = _subscribe_keyspace_notification
+mockredis.MockRedis.config_set = config_set
+redis.StrictRedis = SwssSyncClient
+SonicV2Connector.connect = connect_SonicV2Connector
+swsscommon.SonicV2Connector = SonicV2Connector
+swsscommon.ConfigDBConnector = ConfigDBConnector
+swsscommon.ConfigDBPipeConnector = ConfigDBPipeConnector
diff --git a/dockers/docker-dhcp-relay/cli-plugin-tests/pytest.ini b/dockers/docker-dhcp-relay/cli-plugin-tests/pytest.ini
new file mode 100644
index 000000000000..b960c46f4109
--- /dev/null
+++ b/dockers/docker-dhcp-relay/cli-plugin-tests/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+addopts = --cov-config=.coveragerc --cov --cov-report html --cov-report term --cov-report xml --junitxml=test-results.xml -vv
+
diff --git a/dockers/docker-dhcp-relay/cli-plugin-tests/test_config_dhcp_relay.py b/dockers/docker-dhcp-relay/cli-plugin-tests/test_config_dhcp_relay.py
new file mode 100644
index 000000000000..8a47f6994b80
--- /dev/null
+++ b/dockers/docker-dhcp-relay/cli-plugin-tests/test_config_dhcp_relay.py
@@ -0,0 +1,141 @@
+import os
+import sys
+import traceback
+from unittest import mock
+
+from click.testing import CliRunner
+
+from utilities_common.db import Db
+
+import pytest
+
+sys.path.append('../cli/config/plugins/')
+import dhcp_relay
+
+config_vlan_add_dhcp_relay_output="""\
+Added DHCP relay destination address 192.0.0.100 to Vlan1000
+Restarting DHCP relay service...
+"""
+
+config_vlan_del_dhcp_relay_output="""\
+Removed DHCP relay destination address 192.0.0.100 from Vlan1000
+Restarting DHCP relay service...
+"""
+
+class TestConfigVlanDhcpRelay(object):
+ def test_plugin_registration(self):
+ cli = mock.MagicMock()
+ dhcp_relay.register(cli)
+ cli.commands['vlan'].add_command.assert_called_once_with(dhcp_relay.vlan_dhcp_relay)
+
+ def test_config_vlan_add_dhcp_relay_with_nonexist_vlanid(self):
+ runner = CliRunner()
+
+ with mock.patch('utilities_common.cli.run_command') as mock_run_command:
+ result = runner.invoke(dhcp_relay.vlan_dhcp_relay.commands["add"],
+ ["1001", "192.0.0.100"])
+ print(result.exit_code)
+ print(result.output)
+ # traceback.print_tb(result.exc_info[2])
+ assert result.exit_code != 0
+ assert "Error: Vlan1001 doesn't exist" in result.output
+ assert mock_run_command.call_count == 0
+
+ def test_config_vlan_add_dhcp_relay_with_invalid_vlanid(self):
+ runner = CliRunner()
+
+ with mock.patch('utilities_common.cli.run_command') as mock_run_command:
+ result = runner.invoke(dhcp_relay.vlan_dhcp_relay.commands["add"],
+ ["4096", "192.0.0.100"])
+ print(result.exit_code)
+ print(result.output)
+ # traceback.print_tb(result.exc_info[2])
+ assert result.exit_code != 0
+ assert "Error: Vlan4096 doesn't exist" in result.output
+ assert mock_run_command.call_count == 0
+
+ def test_config_vlan_add_dhcp_relay_with_invalid_ip(self):
+ runner = CliRunner()
+
+ with mock.patch('utilities_common.cli.run_command') as mock_run_command:
+ result = runner.invoke(dhcp_relay.vlan_dhcp_relay.commands["add"],
+ ["1000", "192.0.0.1000"])
+ print(result.exit_code)
+ print(result.output)
+ # traceback.print_tb(result.exc_info[2])
+ assert result.exit_code != 0
+ assert "Error: 192.0.0.1000 is invalid IP address" in result.output
+ assert mock_run_command.call_count == 0
+
+ def test_config_vlan_add_dhcp_relay_with_exist_ip(self, mock_cfgdb):
+ runner = CliRunner()
+ db = Db()
+ db.cfgdb = mock_cfgdb
+
+ with mock.patch('utilities_common.cli.run_command') as mock_run_command:
+ result = runner.invoke(dhcp_relay.vlan_dhcp_relay.commands["add"],
+ ["1000", "192.0.0.1"], obj=db)
+ print(result.exit_code)
+ print(result.output)
+ assert result.exit_code == 0
+ assert "192.0.0.1 is already a DHCP relay destination for Vlan1000" in result.output
+ assert mock_run_command.call_count == 0
+
+ def test_config_vlan_add_del_dhcp_relay_dest(self, mock_cfgdb):
+ runner = CliRunner()
+ db = Db()
+ db.cfgdb = mock_cfgdb
+
+ # add new relay dest
+ with mock.patch("utilities_common.cli.run_command") as mock_run_command:
+ result = runner.invoke(dhcp_relay.vlan_dhcp_relay.commands["add"],
+ ["1000", "192.0.0.100"], obj=db)
+ print(result.exit_code)
+ print(result.output)
+ assert result.exit_code == 0
+ assert result.output == config_vlan_add_dhcp_relay_output
+ assert mock_run_command.call_count == 3
+ db.cfgdb.set_entry.assert_called_once_with('VLAN', 'Vlan1000', {'dhcp_servers': ['192.0.0.1', '192.0.0.100']})
+
+ db.cfgdb.set_entry.reset_mock()
+
+ # del relay dest
+ with mock.patch("utilities_common.cli.run_command") as mock_run_command:
+ result = runner.invoke(dhcp_relay.vlan_dhcp_relay.commands["del"],
+ ["1000", "192.0.0.100"], obj=db)
+ print(result.exit_code)
+ print(result.output)
+ assert result.exit_code == 0
+ assert result.output == config_vlan_del_dhcp_relay_output
+ assert mock_run_command.call_count == 3
+ db.cfgdb.set_entry.assert_called_once_with('VLAN', 'Vlan1000', {'dhcp_servers': ['192.0.0.1']})
+
+ def test_config_vlan_remove_nonexist_dhcp_relay_dest(self, mock_cfgdb):
+ runner = CliRunner()
+ db = Db()
+ db.cfgdb = mock_cfgdb
+
+ with mock.patch('utilities_common.cli.run_command') as mock_run_command:
+ result = runner.invoke(dhcp_relay.vlan_dhcp_relay.commands["del"],
+ ["1000", "192.0.0.100"], obj=db)
+ print(result.exit_code)
+ print(result.output)
+ # traceback.print_tb(result.exc_info[2])
+ assert result.exit_code != 0
+ assert "Error: 192.0.0.100 is not a DHCP relay destination for Vlan1000" in result.output
+ assert mock_run_command.call_count == 0
+
+ def test_config_vlan_remove_dhcp_relay_dest_with_nonexist_vlanid(self, mock_cfgdb):
+ runner = CliRunner()
+ db = Db()
+ db.cfgdb = mock_cfgdb
+
+ with mock.patch('utilities_common.cli.run_command') as mock_run_command:
+ result = runner.invoke(dhcp_relay.vlan_dhcp_relay.commands["del"],
+ ["1001", "192.0.0.1"], obj=Db)
+ print(result.exit_code)
+ print(result.output)
+ # traceback.print_tb(result.exc_info[2])
+ assert result.exit_code != 0
+ assert "Error: Vlan1001 doesn't exist" in result.output
+ assert mock_run_command.call_count == 0
diff --git a/dockers/docker-dhcp-relay/cli-plugin-tests/test_show_dhcp_relay.py b/dockers/docker-dhcp-relay/cli-plugin-tests/test_show_dhcp_relay.py
new file mode 100644
index 000000000000..b8219fcc6ad3
--- /dev/null
+++ b/dockers/docker-dhcp-relay/cli-plugin-tests/test_show_dhcp_relay.py
@@ -0,0 +1,28 @@
+import os
+import sys
+import traceback
+from unittest import mock
+
+from click.testing import CliRunner
+
+import show.vlan as vlan
+from utilities_common.db import Db
+
+sys.path.insert(0, '../cli/show/plugins/')
+import show_dhcp_relay
+
+
+class TestVlanDhcpRelay(object):
+ def test_plugin_registration(self):
+ cli = mock.MagicMock()
+ show_dhcp_relay.register(cli)
+ assert 'DHCP Helper Address' in dict(vlan.VlanBrief.COLUMNS)
+
+ def test_dhcp_relay_column_output(self):
+ ctx = (
+ ({'Vlan100': {'dhcp_servers': ['192.0.0.1', '192.168.0.2']}}, {}, {}),
+ (),
+ )
+ assert show_dhcp_relay.get_dhcp_helper_address(ctx, 'Vlan100') == '192.0.0.1\n192.168.0.2'
+
+
diff --git a/dockers/docker-dhcp-relay/cli/config/plugins/dhcp_relay.py b/dockers/docker-dhcp-relay/cli/config/plugins/dhcp_relay.py
new file mode 100644
index 000000000000..e3cdd8304654
--- /dev/null
+++ b/dockers/docker-dhcp-relay/cli/config/plugins/dhcp_relay.py
@@ -0,0 +1,84 @@
+import click
+import utilities_common.cli as clicommon
+
+@click.group(cls=clicommon.AbbreviationGroup, name='dhcp_relay')
+def vlan_dhcp_relay():
+ pass
+
+@vlan_dhcp_relay.command('add')
+@click.argument('vid', metavar='', required=True, type=int)
+@click.argument('dhcp_relay_destination_ip', metavar='', required=True)
+@clicommon.pass_db
+def add_vlan_dhcp_relay_destination(db, vid, dhcp_relay_destination_ip):
+ """ Add a destination IP address to the VLAN's DHCP relay """
+
+ ctx = click.get_current_context()
+
+ if not clicommon.is_ipaddress(dhcp_relay_destination_ip):
+ ctx.fail('{} is invalid IP address'.format(dhcp_relay_destination_ip))
+
+ vlan_name = 'Vlan{}'.format(vid)
+ vlan = db.cfgdb.get_entry('VLAN', vlan_name)
+ if len(vlan) == 0:
+ ctx.fail("{} doesn't exist".format(vlan_name))
+
+ dhcp_relay_dests = vlan.get('dhcp_servers', [])
+ if dhcp_relay_destination_ip in dhcp_relay_dests:
+ click.echo("{} is already a DHCP relay destination for {}".format(dhcp_relay_destination_ip, vlan_name))
+ return
+
+ dhcp_relay_dests.append(dhcp_relay_destination_ip)
+ vlan['dhcp_servers'] = dhcp_relay_dests
+ db.cfgdb.set_entry('VLAN', vlan_name, vlan)
+ click.echo("Added DHCP relay destination address {} to {}".format(dhcp_relay_destination_ip, vlan_name))
+ try:
+ click.echo("Restarting DHCP relay service...")
+ clicommon.run_command("systemctl stop dhcp_relay", display_cmd=False)
+ clicommon.run_command("systemctl reset-failed dhcp_relay", display_cmd=False)
+ clicommon.run_command("systemctl start dhcp_relay", display_cmd=False)
+ except SystemExit as e:
+ ctx.fail("Restart service dhcp_relay failed with error {}".format(e))
+
+@vlan_dhcp_relay.command('del')
+@click.argument('vid', metavar='', required=True, type=int)
+@click.argument('dhcp_relay_destination_ip', metavar='', required=True)
+@clicommon.pass_db
+def del_vlan_dhcp_relay_destination(db, vid, dhcp_relay_destination_ip):
+ """ Remove a destination IP address from the VLAN's DHCP relay """
+
+ ctx = click.get_current_context()
+
+ if not clicommon.is_ipaddress(dhcp_relay_destination_ip):
+ ctx.fail('{} is invalid IP address'.format(dhcp_relay_destination_ip))
+
+ vlan_name = 'Vlan{}'.format(vid)
+ vlan = db.cfgdb.get_entry('VLAN', vlan_name)
+ if len(vlan) == 0:
+ ctx.fail("{} doesn't exist".format(vlan_name))
+
+ dhcp_relay_dests = vlan.get('dhcp_servers', [])
+ if not dhcp_relay_destination_ip in dhcp_relay_dests:
+ ctx.fail("{} is not a DHCP relay destination for {}".format(dhcp_relay_destination_ip, vlan_name))
+
+ dhcp_relay_dests.remove(dhcp_relay_destination_ip)
+ if len(dhcp_relay_dests) == 0:
+ del vlan['dhcp_servers']
+ else:
+ vlan['dhcp_servers'] = dhcp_relay_dests
+ db.cfgdb.set_entry('VLAN', vlan_name, vlan)
+ click.echo("Removed DHCP relay destination address {} from {}".format(dhcp_relay_destination_ip, vlan_name))
+ try:
+ click.echo("Restarting DHCP relay service...")
+ clicommon.run_command("systemctl stop dhcp_relay", display_cmd=False)
+ clicommon.run_command("systemctl reset-failed dhcp_relay", display_cmd=False)
+ clicommon.run_command("systemctl start dhcp_relay", display_cmd=False)
+ except SystemExit as e:
+ ctx.fail("Restart service dhcp_relay failed with error {}".format(e))
+
+
+def register(cli):
+ cli.commands['vlan'].add_command(vlan_dhcp_relay)
+
+
+if __name__ == '__main__':
+ vlan_dhcp_relay()
diff --git a/dockers/docker-dhcp-relay/cli/show/plugins/show_dhcp_relay.py b/dockers/docker-dhcp-relay/cli/show/plugins/show_dhcp_relay.py
new file mode 100644
index 000000000000..ae8c453e45f3
--- /dev/null
+++ b/dockers/docker-dhcp-relay/cli/show/plugins/show_dhcp_relay.py
@@ -0,0 +1,20 @@
+from natsort import natsorted
+import show.vlan as vlan
+
+def get_dhcp_helper_address(ctx, vlan):
+ cfg, _ = ctx
+ vlan_dhcp_helper_data, _, _ = cfg
+ vlan_config = vlan_dhcp_helper_data.get(vlan)
+ if not vlan_config:
+ return ""
+
+ dhcp_helpers = vlan_config.get('dhcp_servers', [])
+
+ return '\n'.join(natsorted(dhcp_helpers))
+
+
+vlan.VlanBrief.register_column('DHCP Helper Address', get_dhcp_helper_address)
+
+
+def register(cli):
+ pass
diff --git a/dockers/docker-dhcp-relay/dhcp-relay.programs.j2 b/dockers/docker-dhcp-relay/dhcp-relay.programs.j2
new file mode 100644
index 000000000000..d6c0d805a4cc
--- /dev/null
+++ b/dockers/docker-dhcp-relay/dhcp-relay.programs.j2
@@ -0,0 +1,17 @@
+[group:isc-dhcp-relay]
+programs=
+{%- set add_preceding_comma = { 'flag': False } %}
+{% for vlan_name in VLAN_INTERFACE %}
+{# Append DHCPv4 agents #}
+{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
+{% if add_preceding_comma.flag %},{% endif %}
+{% set _dummy = add_preceding_comma.update({'flag': True}) %}
+isc-dhcpv4-relay-{{ vlan_name }}
+{%- endif %}
+{# Append DHCPv6 agents #}
+{% if VLAN and vlan_name in VLAN and 'dhcpv6_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcpv6_servers']|length > 0 %}
+{% if add_preceding_comma.flag %},{% endif %}
+{% set _dummy = add_preceding_comma.update({'flag': True}) %}
+isc-dhcpv6-relay-{{ vlan_name }}
+{%- endif %}
+{% endfor %}
diff --git a/dockers/docker-dhcp-relay/dhcpv4-relay.agents.j2 b/dockers/docker-dhcp-relay/dhcpv4-relay.agents.j2
new file mode 100644
index 000000000000..bf756ff63817
--- /dev/null
+++ b/dockers/docker-dhcp-relay/dhcpv4-relay.agents.j2
@@ -0,0 +1,40 @@
+{# Append DHCPv4 agents #}
+{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
+{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
+{% if dhcp_server | ipv4 %}
+{% set _dummy = relay_for_ipv4.update({'flag': True}) %}
+{% endif %}
+{% endfor %}
+{% if relay_for_ipv4.flag %}
+{% set _dummy = relay_for_ipv4.update({'flag': False}) %}
+[program:isc-dhcpv4-relay-{{ vlan_name }}]
+{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #}
+command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id {{ vlan_name }}
+{#- Dual ToR Option #}
+{% if 'subtype' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['subtype'] == 'DualToR' %} -U Loopback0 -dt{% endif -%}
+{#- si option to use intf addr in relay #}
+{% if DEVICE_METADATA['localhost']['deployment_id'] == '8' %} -si{% endif -%}
+{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #}
+{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %}
+{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%}
+{% endfor %}
+{% for (name, prefix) in INTERFACE|pfx_filter %}
+{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
+{% endfor %}
+{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
+{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
+{% endfor %}
+{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
+{%- if dhcp_server | ipv4 %} {{ dhcp_server }}{% endif -%}
+{% endfor %}
+
+priority=3
+autostart=false
+autorestart=false
+stdout_logfile=syslog
+stderr_logfile=syslog
+dependent_startup=true
+dependent_startup_wait_for=start:exited
+
+{% endif %}
+{% endif %}
diff --git a/dockers/docker-dhcp-relay/dhcpv6-relay.agents.j2 b/dockers/docker-dhcp-relay/dhcpv6-relay.agents.j2
new file mode 100644
index 000000000000..2d95b383c093
--- /dev/null
+++ b/dockers/docker-dhcp-relay/dhcpv6-relay.agents.j2
@@ -0,0 +1,37 @@
+{# Append DHCPv6 agents #}
+{% if VLAN and vlan_name in VLAN and 'dhcpv6_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcpv6_servers']|length > 0 %}
+{% for dhcpv6_server in VLAN[vlan_name]['dhcpv6_servers'] %}
+{% if dhcpv6_server | ipv6 %}
+{% set _dummy = relay_for_ipv6.update({'flag': True}) %}
+{% endif %}
+{% endfor %}
+{% if relay_for_ipv6.flag %}
+{% set _dummy = relay_for_ipv6.update({'flag': False}) %}
+[program:isc-dhcpv6-relay-{{ vlan_name }}]
+{# We treat this VLAN as a downstream interface (-l), as we only want to listen for requests #}
+command=/usr/sbin/dhcrelay -d -6 --name-alias-map-file /tmp/port-name-alias-map.txt -l {{ vlan_name }}
+{#- We treat all other interfaces as upstream interfaces (-u), as we only want to listen for replies #}
+{%- for dhcpv6_server in VLAN[vlan_name]['dhcpv6_servers'] %}
+{%- if dhcpv6_server | ipv6 %}
+{%- for (name, prefix) in VLAN_INTERFACE|pfx_filter %}
+{%- if prefix | ipv6 and name != vlan_name %} -u {{ dhcpv6_server }}%%{{ name }} {% endif -%}
+{% endfor %}
+{% for (name, prefix) in INTERFACE|pfx_filter %}
+{% if prefix | ipv6 %} -u {{ dhcpv6_server }}%%{{ name }} {% endif -%}
+{% endfor %}
+{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
+{% if prefix | ipv6 %} -u {{ dhcpv6_server }}%%{{ name }} {% endif -%}
+{% endfor %}
+{% endif -%}
+{% endfor %}
+
+priority=3
+autostart=false
+autorestart=false
+stdout_logfile=syslog
+stderr_logfile=syslog
+dependent_startup=true
+dependent_startup_wait_for=start:exited
+
+{% endif %}
+{% endif %}
diff --git a/dockers/docker-dhcp-relay/dhcpv6-relay.monitors.j2 b/dockers/docker-dhcp-relay/dhcpv6-relay.monitors.j2
new file mode 100644
index 000000000000..8bb9e5ad8136
--- /dev/null
+++ b/dockers/docker-dhcp-relay/dhcpv6-relay.monitors.j2
@@ -0,0 +1,79 @@
+[group:dhcpmon]
+programs=
+{%- set add_preceding_comma = { 'flag': False } %}
+{% set monitor_instance = { 'flag': False } %}
+{% for vlan_name in VLAN_INTERFACE %}
+{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
+{% set _dummy = monitor_instance.update({'flag': True}) %}
+{%- endif %}
+{% if VLAN and vlan_name in VLAN and 'dhcpv6_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcpv6_servers']|length > 0 %}
+{% set _dummy = monitor_instance.update({'flag': True}) %}
+{%- endif %}
+{% if monitor_instance.flag %}
+{% if add_preceding_comma.flag %},{% endif %}
+{% set _dummy = add_preceding_comma.update({'flag': True}) %}
+dhcpmon-{{ vlan_name }}
+{%- set _dummy = monitor_instance.update({'flag': False}) %}
+{%- endif %}
+{% endfor %}
+
+
+{# Create a program entry for each DHCP MONitor instance #}
+{% set relay_for_ipv4 = { 'flag': False } %}
+{% set relay_for_ipv6 = { 'flag': False } %}
+{% for vlan_name in VLAN_INTERFACE %}
+{# Check DHCPv4 agents #}
+{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
+{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
+{% if dhcp_server | ipv4 %}
+{% set _dummy = relay_for_ipv4.update({'flag': True}) %}
+{% endif %}
+{% endfor %}
+{% endif %}
+{# Check DHCPv6 agents #}
+{% if VLAN and vlan_name in VLAN and 'dhcpv6_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcpv6_servers']|length > 0 %}
+{% for dhcpv6_server in VLAN[vlan_name]['dhcpv6_servers'] %}
+{% if dhcpv6_server | ipv6 %}
+{% set _dummy = relay_for_ipv6.update({'flag': True}) %}
+{% endif %}
+{% endfor %}
+{% endif %}
+{% if relay_for_ipv4.flag or relay_for_ipv6.flag %}
+[program:dhcpmon-{{ vlan_name }}]
+{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #}
+command=/usr/sbin/dhcpmon -id {{ vlan_name }}
+{#- Dual ToR Option #}
+{% if 'subtype' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['subtype'] == 'DualToR' %} -u Loopback0{% endif -%}
+{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #}
+{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %}
+{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%}
+{% endfor %}
+{% for (name, prefix) in INTERFACE|pfx_filter %}
+{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
+{% endfor %}
+{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
+{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
+{% endfor %}
+{% if MGMT_INTERFACE %}
+{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %}
+{% if prefix | ipv4 %} -im {{ name }}{% endif -%}
+{% endfor %}
+{% endif %}
+{% if relay_for_ipv4.flag %} -4{% endif %}
+{% if relay_for_ipv6.flag %} -6{% endif %}
+
+priority=4
+autostart=false
+autorestart=false
+stdout_logfile=syslog
+stderr_logfile=syslog
+dependent_startup=true
+dependent_startup_wait_for=
+{%- if relay_for_ipv4.flag %}isc-dhcpv4-relay-{{ vlan_name }}:running {% endif %}
+{% if relay_for_ipv6.flag %}isc-dhcpv6-relay-{{ vlan_name }}:running{% endif %}
+
+
+{% set _dummy = relay_for_ipv4.update({'flag': False}) %}
+{% set _dummy = relay_for_ipv6.update({'flag': False}) %}
+{% endif %}
+{% endfor %}
diff --git a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2
index a1811226a885..664e1f36c05e 100644
--- a/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2
+++ b/dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2
@@ -42,125 +42,29 @@ dependent_startup_wait_for=rsyslogd:running
{# If our configuration has VLANs... #}
{% if VLAN_INTERFACE %}
{# Count how many VLANs require a DHCP relay agent... #}
-{% set num_relays = { 'count': 0 } %}
+{% set ipv4_num_relays = { 'count': 0 } %}
+{% set ipv6_num_relays = { 'count': 0 } %}
{% for vlan_name in VLAN_INTERFACE %}
{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
-{% set _dummy = num_relays.update({'count': num_relays.count + 1}) %}
+{% set _dummy = ipv4_num_relays.update({'count': ipv4_num_relays.count + 1}) %}
+{% endif %}
+{% if VLAN and vlan_name in VLAN and 'dhcpv6_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcpv6_servers']|length > 0 %}
+{% set _dummy = ipv6_num_relays.update({'count': ipv6_num_relays.count + 1}) %}
{% endif %}
{% endfor %}
{# If one or more of the VLANs require a DHCP relay agent... #}
-{% if num_relays.count > 0 %}
-[group:isc-dhcp-relay]
-programs=
-{%- set add_preceding_comma = { 'flag': False } %}
-{% for vlan_name in VLAN_INTERFACE %}
-{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
-{% if add_preceding_comma.flag %},{% endif %}
-{% set _dummy = add_preceding_comma.update({'flag': True}) %}
-isc-dhcp-relay-{{ vlan_name }}
-{%- endif %}
-{% endfor %}
+{% if ipv4_num_relays.count > 0 or ipv6_num_relays.count > 0 %}
+{% include 'dhcp-relay.programs.j2' %}
{# Create a program entry for each DHCP relay agent instance #}
{% set relay_for_ipv4 = { 'flag': False } %}
+{% set relay_for_ipv6 = { 'flag': False } %}
{% for vlan_name in VLAN_INTERFACE %}
-{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
-{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
-{% if dhcp_server | ipv4 %}
-{% set _dummy = relay_for_ipv4.update({'flag': True}) %}
-{% endif %}
-{% endfor %}
-{% if relay_for_ipv4.flag %}
-{% set _dummy = relay_for_ipv4.update({'flag': False}) %}
-[program:isc-dhcp-relay-{{ vlan_name }}]
-{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #}
-command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id {{ vlan_name }}
-{#- Dual ToR Option #}
-{% if 'subtype' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['subtype'] == 'DualToR' %} -U Loopback0 -dt{% endif -%}
-{#- si option to use intf addr in relay #}
-{% if DEVICE_METADATA['localhost']['deployment_id'] == '8' %} -si{% endif -%}
-{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #}
-{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %}
-{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%}
-{% endfor %}
-{% for (name, prefix) in INTERFACE|pfx_filter %}
-{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
-{% endfor %}
-{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
-{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
-{% endfor %}
-{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
-{%- if dhcp_server | ipv4 %} {{ dhcp_server }}{% endif -%}
-{% endfor %}
-
-priority=3
-autostart=false
-autorestart=false
-stdout_logfile=syslog
-stderr_logfile=syslog
-dependent_startup=true
-dependent_startup_wait_for=start:exited
-
-{% endif %}
-{% endif %}
-{% endfor %}
-
-[group:dhcpmon]
-programs=
-{%- set add_preceding_comma = { 'flag': False } %}
-{% for vlan_name in VLAN_INTERFACE %}
-{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
-{% if add_preceding_comma.flag %},{% endif %}
-{% set _dummy = add_preceding_comma.update({'flag': True}) %}
-dhcpmon-{{ vlan_name }}
-{%- endif %}
-{% endfor %}
-
-
-{# Create a program entry for each DHCP MONitor instance #}
-{% set relay_for_ipv4 = { 'flag': False } %}
-{% for vlan_name in VLAN_INTERFACE %}
-{% if VLAN and vlan_name in VLAN and 'dhcp_servers' in VLAN[vlan_name] and VLAN[vlan_name]['dhcp_servers']|length > 0 %}
-{% for dhcp_server in VLAN[vlan_name]['dhcp_servers'] %}
-{% if dhcp_server | ipv4 %}
-{% set _dummy = relay_for_ipv4.update({'flag': True}) %}
-{% endif %}
-{% endfor %}
-{% if relay_for_ipv4.flag %}
-{% set _dummy = relay_for_ipv4.update({'flag': False}) %}
-[program:dhcpmon-{{ vlan_name }}]
-{# We treat this VLAN as a downstream interface (-id), as we only want to listen for requests #}
-command=/usr/sbin/dhcpmon -id {{ vlan_name }}
-{#- Dual ToR Option #}
-{% if 'subtype' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['subtype'] == 'DualToR' %} -u Loopback0{% endif -%}
-{#- We treat all other interfaces as upstream interfaces (-iu), as we only want to listen for replies #}
-{% for (name, prefix) in VLAN_INTERFACE|pfx_filter %}
-{% if prefix | ipv4 and name != vlan_name %} -iu {{ name }}{% endif -%}
-{% endfor %}
-{% for (name, prefix) in INTERFACE|pfx_filter %}
-{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
-{% endfor %}
-{% for (name, prefix) in PORTCHANNEL_INTERFACE|pfx_filter %}
-{% if prefix | ipv4 %} -iu {{ name }}{% endif -%}
-{% endfor %}
-{% if MGMT_INTERFACE %}
-{% for (name, prefix) in MGMT_INTERFACE|pfx_filter %}
-{% if prefix | ipv4 %} -im {{ name }}{% endif -%}
-{% endfor %}
-{% endif %}
-
-priority=4
-autostart=false
-autorestart=false
-stdout_logfile=syslog
-stderr_logfile=syslog
-dependent_startup=true
-dependent_startup_wait_for=isc-dhcp-relay-{{ vlan_name }}:running
-
-{% endif %}
-{% endif %}
+{% include 'dhcpv4-relay.agents.j2' %}
+{% include 'dhcpv6-relay.agents.j2' %}
{% endfor %}
+{% include 'dhcpv6-relay.monitors.j2' %}
{% endif %}
{% endif %}
diff --git a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2 b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2
index 88c4836373cd..7d6bc4ef04ae 100644
--- a/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2
+++ b/dockers/docker-fpm-frr/frr/bgpd/bgpd.main.conf.j2
@@ -31,6 +31,9 @@ ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq {{ loop.index * 5 }} permit {{ prefi
{% endfor %}
!
{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' or DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %}
+{% set multi_asic = True %}
+{% endif %}
+{% if multi_asic is defined or DEVICE_METADATA['localhost']['switch_type'] == 'voq' %}
route-map HIDE_INTERNAL permit 10
set community no-export
{% if constants.bgp.peers is defined and constants.bgp.peers.internal is defined and constants.bgp.peers.internal.community is defined %}
@@ -38,7 +41,6 @@ route-map HIDE_INTERNAL permit 10
route-map HIDE_INTERNAL permit 20
set community {{ constants.bgp.peers.internal.community }} additive
{% endif %}
-{% set multi_asic = True %}
!
{% endif %}
!
@@ -57,10 +59,11 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
bgp graceful-restart restart-time {{ constants.bgp.graceful_restart.restart_time | default(240) }}
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time {{ constants.bgp.graceful_restart.select_defer_time | default(45) }}
{% endif %}
!
{# set router-id #}
-{% if DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' %}
+{% if DEVICE_METADATA['localhost']['sub_role'] == 'BackEnd' or DEVICE_METADATA['localhost']['switch_type'] == 'voq' %}
bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}
{% else %}
bgp router-id {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}
@@ -68,7 +71,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
!
{# advertise loopback #}
network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/32
-{% if multi_asic is defined %}
+{% if multi_asic is defined or DEVICE_METADATA['localhost']['switch_type'] == 'voq' %}
network {{ get_ipv4_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/32 route-map HIDE_INTERNAL
{% endif %}
!
@@ -77,7 +80,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback0") | ip }}/64
exit-address-family
{% endif %}
-{% if multi_asic is defined %}
+{% if multi_asic is defined or DEVICE_METADATA['localhost']['switch_type'] == 'voq'%}
{% if get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") != 'None' %}
address-family ipv6
network {{ get_ipv6_loopback_address(LOOPBACK_INTERFACE, "Loopback4096") | ip }}/128 route-map HIDE_INTERNAL
@@ -99,7 +102,7 @@ router bgp {{ DEVICE_METADATA['localhost']['bgp_asn'] }}
{% endblock vlan_advertisement %}
!
!
-{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' %}
+{% if DEVICE_METADATA['localhost']['sub_role'] == 'FrontEnd' or DEVICE_METADATA['localhost']['switch_type'] == 'voq' %}
address-family ipv4
redistribute connected route-map HIDE_INTERNAL
exit-address-family
diff --git a/dockers/docker-orchagent/Dockerfile.j2 b/dockers/docker-orchagent/Dockerfile.j2
index 27c8598a1d13..2a927b5f2b69 100755
--- a/dockers/docker-orchagent/Dockerfile.j2
+++ b/dockers/docker-orchagent/Dockerfile.j2
@@ -24,9 +24,11 @@ RUN apt-get update && \
python3-dev
{% if ( CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" ) %}
-# Fix for gcc/python not found in arm docker
+# Fix for gcc/python/iputils-ping not found in arm docker
RUN apt-get install -f -y python2.7 python2.7-dev
-RUN apt-get install -y gcc-8
+RUN apt-get install -y \
+ gcc-8 \
+ iputils-ping
{% endif %}
{% if CONFIGURED_ARCH == "armhf" %}
RUN ln -s -f /usr/bin/gcc-8 /usr/bin/arm-linux-gnueabihf-gcc
diff --git a/dockers/docker-pde/Dockerfile.j2 b/dockers/docker-pde/Dockerfile.j2
new file mode 100644
index 000000000000..0711e563c259
--- /dev/null
+++ b/dockers/docker-pde/Dockerfile.j2
@@ -0,0 +1,95 @@
+FROM {{ docker_pde_load_image }}
+
+ARG docker_container_name
+ENV PYTHONPATH=/usr/share/sonic/platform
+
+RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf
+
+# Make apt-get non-interactive
+ENV DEBIAN_FRONTEND=noninteractive
+
+{% if ARTIFACTORY_URL is defined and ARTIFACTORY_URL|length -%}
+# Insert Artifactory URL references
+COPY ["files/03_stretch_af.list", "/etc/apt/sources.list.d/"]
+{%- endif %}
+
+# Update apt's cache of available packages
+RUN apt-get update && apt-get install -y ipmitool telnet busybox kmod libpcap-dev
+
+# Packages for benchmark tool - nench.sh
+RUN apt-get install -y bzip2 curl ioping openssl bc sysstat
+
+# Packages for PDDF
+
+RUN apt-get install -y python-jsonschema
+
+RUN pip3 install pytest pexpect
+
+{% if docker_pde_debs.strip() -%}
+# Copy locally-built Debian package dependencies
+COPY \
+{% for deb in docker_pde_debs.split(' ') -%}
+debs/{{ deb }}{{' '}}
+{%- endfor -%}
+/debs/
+
+# Install locally-built Debian packages and implicitly install their dependencies
+RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; }{%- for deb in docker_pde_debs.split(' ') %}; \
+dpkg_apt /debs/{{ deb }}
+{%- endfor %}
+{%- endif %}
+
+{% if docker_pde_pydebs.strip() -%}
+# Copy locally-built Debian package dependencies
+COPY \
+{% for deb in docker_pde_pydebs.split(' ') -%}
+python-debs/{{ deb }}{{' '}}
+{%- endfor -%}
+/debs/
+
+# Install locally-built Debian packages and implicitly install their dependencies
+{%- for deb in docker_pde_pydebs.split(' ') %}
+RUN dpkg_apt() { [ -f $1 ] && { dpkg -i $1 || apt-get -y install -f; } || return 1; }; dpkg_apt /debs/{{ deb }}
+{%- endfor %}
+{%- endif %}
+
+{% if docker_pde_whls.strip() -%}
+# Copy locally-built Python wheel dependencies
+COPY \
+{% for whl in docker_pde_whls.split(' ') -%}
+python-wheels/{{ whl }}{{' '}}
+{%- endfor -%}
+/python-wheels/
+
+# Install locally-built Python wheel dependencies
+
+RUN pip3 install \
+
+
+{% for whl in docker_pde_whls.split(' ') -%}
+/python-wheels/{{ whl }}{{' '}}
+{%- endfor %}
+{% endif %}
+
+{% if ARTIFACTORY_URL is defined and ARTIFACTORY_URL|length -%}
+# Remove Artifactory URL references
+RUN rm -f /etc/apt/sources.list.d/03_stretch_af.list && apt-get update
+{%- endif %}
+
+# Clean up
+RUN apt-get clean -y; \
+ apt-get autoclean -y; \
+ apt-get autoremove -y
+RUN rm -rf /debs ~/.cache
+
+RUN mkdir -p /home/pde
+
+COPY ["bench.sh", "/usr/bin/"]
+COPY ["stress-sfp-i2c.py", "/home/pde"]
+COPY ["supervisord.conf", "/etc/supervisor/conf.d/"]
+COPY ["syseeprom.py", "/usr/bin/"]
+COPY ["docker_init.sh", "/usr/bin/"]
+COPY ["cancun_files/cancun_4.5.0/*", "cancun_files/cancun_6.6.1/*", "cancun_files/cancun_4.3.0/*", "/usr/lib/cancun/"]
+COPY ["syncd_init_common.sh", "/usr/bin/"]
+
+ENTRYPOINT ["/usr/bin/docker_init.sh"]
diff --git a/dockers/docker-pde/base_image_files/pde-bench b/dockers/docker-pde/base_image_files/pde-bench
new file mode 100644
index 000000000000..dc22635ba900
--- /dev/null
+++ b/dockers/docker-pde/base_image_files/pde-bench
@@ -0,0 +1,37 @@
+#!/bin/bash
+
+CSV=/tmp/bench.csv
+
+# Make sure only root can run our script
+if [ "$(id -u)" != "0" ]; then
+ echo "This script must be run as root" 1>&2
+ exit 1
+fi
+
+# Start PDE if it's deactivated
+if [ $(docker ps | grep -c pde) -eq 0 ]; then
+ pde.sh start
+fi
+
+# Allow 5 seconds for PDE to be coming up
+for t in $(seq 1 5)
+do
+ if [ $(docker ps | grep -c pde) -gt 0 ]; then
+ break
+ fi
+ sleep 1
+done
+if [ $(docker ps | grep -c pde) -eq 0 ]; then
+ echo "docker-pde is not alive, existing ..."
+ exit 1
+fi
+
+# Launch the benchmark test suite
+docker exec -it pde /usr/bin/bench.sh
+echo "$(docker exec -it pde cat ${CSV})" > ${CSV}
+
+echo ""
+echo "CSV Report: ${CSV}"
+echo "-----------------------------------------------------------------------"
+echo "$(cat ${CSV})"
+echo "-----------------------------------------------------------------------"
diff --git a/dockers/docker-pde/base_image_files/pde-bench-knet b/dockers/docker-pde/base_image_files/pde-bench-knet
new file mode 100644
index 000000000000..cc75962eff35
--- /dev/null
+++ b/dockers/docker-pde/base_image_files/pde-bench-knet
@@ -0,0 +1,326 @@
+#!/bin/bash
+
+PLATF_DIR=/usr/share/sonic/platform
+HWSKU_DIR=/usr/share/sonic/hwsku
+PORT=Ethernet0
+LANE=1
+SPEED=0
+BCMPORT=ce0
+DURATION=5
+
+PPS_128=0
+BPS_128=0
+PPS_256=0
+BPS_256=0
+PPS_512=0
+BPS_512=0
+PPS_1024=0
+BPS_1024=0
+PPS_2048=0
+BPS_2048=0
+PPS_4096=0
+BPS_4096=0
+PPS_8192=0
+BPS_8192=0
+PPS_9000=0
+BPS_9000=0
+
+# SWSS is mandatory for KNET benchmark
+sudo systemctl start swss
+for t in $(seq 1 15)
+do
+ if [ $(docker ps | grep -c swss) -gt 0 ]; then
+ break
+ fi
+ sleep 1
+done
+if [ $(docker ps | grep -c swss) -eq 0 ]; then
+ echo "ERR: docker-swss is not alive, existing ..."
+ exit 1
+fi
+
+# Find out the PLATFORM and HWSKU
+if [ ! -d ${PLATF_DIR} ]; then
+ name=$(grep 'onie_platform=' /host/machine.conf | cut -d '=' -f 2)
+ PLATF_DIR=/usr/share/sonic/device/${name}
+fi
+
+if [ ! -d ${HWSKU_DIR} ]; then
+ name=$(head -1 ${PLATF_DIR}/default_sku | awk '{print $1}')
+ HWSKU_DIR=${PLATF_DIR}/${name}
+fi
+
+echo "PLATFORM='${PLATF_DIR}'"
+echo "HWSKU='${HWSKU_DIR}'"
+
+# Determine the target port for KNET benchmark
+while IFS= read -r line; do
+ line=$(echo ${line} | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
+ if [[ ${line} = \#* ]]; then
+ continue
+ fi
+ port=$(echo ${line} | awk '{print $1}')
+ lane=$(echo ${line} | awk '{print $2}' | cut -d ',' -f 1)
+ speed=$(echo ${line} | awk '{print $5}')
+ if [ -z "${speed}" ]; then
+ continue
+ fi
+ if [ ${speed} -gt ${SPEED} ]; then
+ PORT=${port}
+ LANE=${lane}
+ SPEED=${speed}
+ fi
+done < ${HWSKU_DIR}/port_config.ini
+
+echo "PORT=${PORT}"
+echo "LANE=${LANE}"
+echo "SPEED=${SPEED}"
+
+# Find out the name of the corresponding bcm port
+TEMP=$(mktemp)
+bcmcmd 'show pmap' | grep ${LANE} > ${TEMP}
+while IFS= read -r line; do
+ line=$(echo ${line} | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
+ if [ $(echo ${line} | awk '{print $4}') -eq ${LANE} ]; then
+ BCMPORT=$(echo ${line} | awk '{print $1}')
+ break
+ fi
+done < ${TEMP}
+rm -f ${TEMP}
+
+echo "BCMPORT=${BCMPORT}"
+
+# SWSS: Update the LLDP rate limit
+TEMP=$(mktemp)
+rm -f ${TEMP}.*
+docker cp swss:/etc/swss/config.d/00-copp.config.json ${TEMP}.old
+if [ ! -f ${TEMP}.old ]; then
+ echo "Unable to get 00-copp.config.json from docker-swss"
+fi
+
+lldp=0
+while IFS= read -r line
+do
+ if [ $(echo $line | grep -c -E '\"COPP_TABLE:') -gt 0 ]; then
+ lldp=0
+ fi
+ if [ $(echo $line | grep -c -E 'trap_ids.*,lldp') -gt 0 ]; then
+ lldp=1
+ fi
+ if [ $lldp -gt 0 ]; then
+ if [ $(echo $line | grep -c -E '.*\"cir\"') -gt 0 ]; then
+ echo "${line%:*}:\"30000\"," >> ${TEMP}.new
+ lldp=$(expr $lldp + 1)
+ continue
+ fi
+ if [ $(echo $line | grep -c -E '.*\"cbs\"') -gt 0 ]; then
+ echo "${line%:*}:\"30000\"," >> ${TEMP}.new
+ lldp=$(expr $lldp + 1)
+ continue
+ fi
+ fi
+ echo "$line" >> ${TEMP}.new
+done < "${TEMP}.old"
+
+csum1=$(md5sum ${TEMP}.old | cut -d ' ' -f 1)
+csum2=$(md5sum ${TEMP}.new | cut -d ' ' -f 1)
+if [ "${csum1}" != "${csum2}" ]; then
+ docker cp ${TEMP}.new swss:/etc/swss/config.d/00-copp.config.json
+ sudo config copp rx-rate 100000
+ sudo config save -y
+ sudo config reload -y
+fi
+
+# Disable ZTP
+sudo config ztp disable -y > /dev/null 2>&1
+
+# Enable the target port for benchmarking
+echo "Allow 15 seconds for ${PORT} getting ready"
+
+for tick in $(seq 1 15); do
+ if [ -d /sys/class/net/${PORT} ]; then
+ break
+ fi
+ sleep 1
+done
+sudo config interface startup ${PORT} > /dev/null 2>&1
+
+# Enable MAC loopback mode to the target port
+bcmcmd "port ${BCMPORT} lb=mac" > /dev/null 2>&1
+
+# Get started with the loopback benchmark test
+#
+
+# 128B
+P1=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B1=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+if [ $(docker ps | grep -c pde) -gt 0 ]; then
+ docker exec -it pde /usr/local/bin/pktsend ${PORT} ${DURATION} 128
+else
+ /usr/local/bin/pktsend ${PORT} ${DURATION} 128
+fi
+P2=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B2=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+NUM=$(expr ${P2} - ${P1})
+PPS=$(expr ${NUM} / ${DURATION})
+NUM=$(expr ${B2} - ${B1})
+BPS=$(expr ${NUM} / ${DURATION})
+BPS=$(expr ${BPS} / 1000000)
+BPS=$(expr ${BPS} \* 8)
+echo "PPS=${PPS}, BPS=${BPS}Mbps"
+PPS_128=${PPS}
+BPS_128=${BPS}
+
+# 256B
+P1=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B1=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+if [ $(docker ps | grep -c pde) -gt 0 ]; then
+ docker exec -it pde /usr/local/bin/pktsend ${PORT} ${DURATION} 256
+else
+ /usr/local/bin/pktsend ${PORT} ${DURATION} 256
+fi
+P2=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B2=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+NUM=$(expr ${P2} - ${P1})
+PPS=$(expr ${NUM} / ${DURATION})
+NUM=$(expr ${B2} - ${B1})
+BPS=$(expr ${NUM} / ${DURATION})
+BPS=$(expr ${BPS} / 1000000)
+BPS=$(expr ${BPS} \* 8)
+echo "PPS=${PPS}, BPS=${BPS}Mbps"
+PPS_256=${PPS}
+BPS_256=${BPS}
+
+# 512B
+P1=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B1=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+if [ $(docker ps | grep -c pde) -gt 0 ]; then
+ docker exec -it pde /usr/local/bin/pktsend ${PORT} ${DURATION} 512
+else
+ /usr/local/bin/pktsend ${PORT} ${DURATION} 512
+fi
+P2=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B2=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+NUM=$(expr ${P2} - ${P1})
+PPS=$(expr ${NUM} / ${DURATION})
+NUM=$(expr ${B2} - ${B1})
+BPS=$(expr ${NUM} / ${DURATION})
+BPS=$(expr ${BPS} / 1000000)
+BPS=$(expr ${BPS} \* 8)
+echo "PPS=${PPS}, BPS=${BPS}Mbps"
+PPS_512=${PPS}
+BPS_512=${BPS}
+
+# 1024B
+P1=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B1=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+if [ $(docker ps | grep -c pde) -gt 0 ]; then
+ docker exec -it pde /usr/local/bin/pktsend ${PORT} ${DURATION} 1024
+else
+ /usr/local/bin/pktsend ${PORT} ${DURATION} 1024
+fi
+P2=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B2=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+NUM=$(expr ${P2} - ${P1})
+PPS=$(expr ${NUM} / ${DURATION})
+NUM=$(expr ${B2} - ${B1})
+BPS=$(expr ${NUM} / ${DURATION})
+BPS=$(expr ${BPS} / 1000000)
+BPS=$(expr ${BPS} \* 8)
+echo "PPS=${PPS}, BPS=${BPS}Mbps"
+PPS_1024=${PPS}
+BPS_1024=${BPS}
+
+# 2048B
+P1=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B1=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+if [ $(docker ps | grep -c pde) -gt 0 ]; then
+ docker exec -it pde /usr/local/bin/pktsend ${PORT} ${DURATION} 2048
+else
+ /usr/local/bin/pktsend ${PORT} ${DURATION} 2048
+fi
+P2=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B2=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+NUM=$(expr ${P2} - ${P1})
+PPS=$(expr ${NUM} / ${DURATION})
+NUM=$(expr ${B2} - ${B1})
+BPS=$(expr ${NUM} / ${DURATION})
+BPS=$(expr ${BPS} / 1000000)
+BPS=$(expr ${BPS} \* 8)
+echo "PPS=${PPS}, BPS=${BPS}Mbps"
+PPS_2048=${PPS}
+BPS_2048=${BPS}
+
+# 4096B
+P1=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B1=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+if [ $(docker ps | grep -c pde) -gt 0 ]; then
+ docker exec -it pde /usr/local/bin/pktsend ${PORT} ${DURATION} 4096
+else
+ /usr/local/bin/pktsend ${PORT} ${DURATION} 4096
+fi
+P2=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B2=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+NUM=$(expr ${P2} - ${P1})
+PPS=$(expr ${NUM} / ${DURATION})
+NUM=$(expr ${B2} - ${B1})
+BPS=$(expr ${NUM} / ${DURATION})
+BPS=$(expr ${BPS} / 1000000)
+BPS=$(expr ${BPS} \* 8)
+echo "PPS=${PPS}, BPS=${BPS}Mbps"
+PPS_4096=${PPS}
+BPS_4096=${BPS}
+
+# 8192B
+P1=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B1=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+if [ $(docker ps | grep -c pde) -gt 0 ]; then
+ docker exec -it pde /usr/local/bin/pktsend ${PORT} ${DURATION} 8192
+else
+ /usr/local/bin/pktsend ${PORT} ${DURATION} 8192
+fi
+P2=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B2=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+NUM=$(expr ${P2} - ${P1})
+PPS=$(expr ${NUM} / ${DURATION})
+NUM=$(expr ${B2} - ${B1})
+BPS=$(expr ${NUM} / ${DURATION})
+BPS=$(expr ${BPS} / 1000000)
+BPS=$(expr ${BPS} \* 8)
+echo "PPS=${PPS}, BPS=${BPS}Mbps"
+PPS_8192=${PPS}
+BPS_8192=${BPS}
+
+# 9000B
+P1=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B1=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+if [ $(docker ps | grep -c pde) -gt 0 ]; then
+ docker exec -it pde /usr/local/bin/pktsend ${PORT} ${DURATION} 9000
+else
+ /usr/local/bin/pktsend ${PORT} ${DURATION} 9000
+fi
+P2=$(cat /sys/class/net/${PORT}/statistics/rx_packets)
+B2=$(cat /sys/class/net/${PORT}/statistics/rx_bytes)
+NUM=$(expr ${P2} - ${P1})
+PPS=$(expr ${NUM} / ${DURATION})
+NUM=$(expr ${B2} - ${B1})
+BPS=$(expr ${NUM} / ${DURATION})
+BPS=$(expr ${BPS} / 1000000)
+BPS=$(expr ${BPS} \* 8)
+echo "PPS=${PPS}, BPS=${BPS}Mbps"
+PPS_9000=${PPS}
+BPS_9000=${BPS}
+
+# Disable MAC loopback mode to the target port
+bcmcmd "port ${BCMPORT} lb=none" > /dev/null 2>&1
+
+# Generate the final report
+echo "payload size,loopback pps(Pkt/s),loopback Mbps(Mbit/s)"
+echo "128B,${PPS_128},${BPS_128}"
+echo "256B,${PPS_256},${BPS_256}"
+echo "512B,${PPS_512},${BPS_512}"
+echo "1024B,${PPS_1024},${BPS_1024}"
+echo "2048B,${PPS_2048},${BPS_2048}"
+echo "4096B,${PPS_4096},${BPS_4096}"
+echo "8192B,${PPS_8192},${BPS_8192}"
+echo "9000B,${PPS_9000},${BPS_9000}"
diff --git a/dockers/docker-pde/base_image_files/pde-stress b/dockers/docker-pde/base_image_files/pde-stress
new file mode 100644
index 000000000000..4ee4752a8b1e
--- /dev/null
+++ b/dockers/docker-pde/base_image_files/pde-stress
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# Make sure only root can run our script
+if [ "$(id -u)" != "0" ]; then
+ echo "This script must be run as root" 1>&2
+ exit 1
+fi
+
+# Start PDE if it's deactivated
+if [ $(docker ps | grep -c pde) -eq 0 ]; then
+ pde.sh start
+fi
+
+# Allow 5 seconds for PDE to be coming up
+for t in $(seq 1 5)
+do
+ if [ $(docker ps | grep -c pde) -gt 0 ]; then
+ break
+ fi
+done
+if [ $(docker ps | grep -c pde) -eq 0 ]; then
+ echo "docker-pde is not alive, existing ..."
+ exit 1
+fi
+
+# Now launch the PDE stress test
+docker exec -it pde /home/pde/stress-sfp-i2c.py $*
diff --git a/dockers/docker-pde/base_image_files/pde-test b/dockers/docker-pde/base_image_files/pde-test
new file mode 100644
index 000000000000..046a9f067480
--- /dev/null
+++ b/dockers/docker-pde/base_image_files/pde-test
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+# Make sure only root can run our script
+if [ "$(id -u)" != "0" ]; then
+ echo "This script must be run as root" 1>&2
+ exit 1
+fi
+
+# Make sure SWSS is deactivated
+if [ $(docker ps | grep -c swss) -ne 0 ]; then
+ systemctl stop swss
+ sleep 3
+fi
+
+# Start PDE if it's deactivated
+if [ $(docker ps | grep -c pde) -eq 0 ]; then
+ pde.sh start
+fi
+
+# Allow 5 seconds for PDE to be coming up
+for t in $(seq 1 5)
+do
+ if [ $(docker ps | grep -c pde) -gt 0 ]; then
+ break
+ fi
+done
+if [ $(docker ps | grep -c pde) -eq 0 ]; then
+ echo "docker-pde is not alive, existing ..."
+ exit 1
+fi
+
+usage()
+{
+ echo "usage: $0 "
+ exit 1
+}
+
+if [ $# -lt 1 ]
+then
+ usage
+fi
+
+case $1 in
+-h | help)
+ usage
+ ;;
+-l | ls | list)
+ docker exec -it -w /usr/local/sonic_pde_tests pde ls
+ exit 0
+ ;;
+*)
+ ;;
+esac
+
+# Now launch the PDE pytest
+docker exec -it -w /usr/local/sonic_pde_tests pde pytest $*
+
+# Reactivate the SWSS
+systemctl start swss
diff --git a/dockers/docker-pde/bench.sh b/dockers/docker-pde/bench.sh
new file mode 100644
index 000000000000..2a0951490918
--- /dev/null
+++ b/dockers/docker-pde/bench.sh
@@ -0,0 +1,140 @@
+#!/bin/bash
+
+CSV=/tmp/bench.csv
+
+TST_FREQ=2000
+TST_CORE=4
+TST_RAMSZ=8
+TST_DISKSZ=14
+TST_SHA=10
+TST_BZ2=30
+TST_AES=5
+TST_DISKRD=180
+TST_DISKWR=30
+
+cpu_benchmark()
+{
+ export TIMEFORMAT='%1R'
+ (time dd if=/dev/zero bs=1M count=500 2> /dev/null | \
+ "$@" > /dev/null ) 2>&1
+}
+
+# Platform Info
+PLATFORM=$(grep 'onie_platform=' /host/machine.conf | cut -d '=' -f 2)
+echo "Platform: ${PLATFORM}"
+
+if [ -d /usr/share/sonic/platform ]; then
+ HWSKU=$(head -1 /usr/share/sonic/platform/default_sku | awk '{print $1}')
+else
+ HWSKU=$(head -1 /usr/share/sonic/device/${PLATFORM}/default_sku | awk '{print $1}')
+fi
+echo "HWSKU: ${HWSKU}"
+
+REVISION=$(syseeprom.py 0x27)
+echo "Revision: ${REVISION}"
+
+# Basic Info
+CPU_NAME=$(awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | cut -d '@' -f 1 | sed 's/^[ \t]*//;s/[ \t]*$//')
+echo "CPU NAME: ${CPU_NAME}"
+
+if [ $(lscpu | grep -c 'CPU max MHz') -gt 0 ]; then
+ CPU_FREQ=$(lscpu | grep 'CPU max MHz' | cut -d ':' -f 2 | cut -d '.' -f 1 | sed 's/^[[:space:]]*//')
+else
+ CPU_FREQ=$(lscpu | grep 'CPU MHz' | cut -d ':' -f 2 | cut -d '.' -f 1 | sed 's/^[[:space:]]*//')
+fi
+echo -n "CPU FREQ: ${CPU_FREQ} MHz ........"
+if [ ${CPU_FREQ} -ge ${TST_FREQ} ]; then
+ echo "pass"
+else
+ echo "FAIL"
+fi
+
+CPU_CORE=$(awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo)
+echo -n "CPU CORE: ${CPU_CORE} ..............."
+if [ ${CPU_CORE} -ge ${TST_CORE} ]; then
+ echo "pass"
+else
+ echo "FAIL"
+fi
+
+RAM_SIZE=$(grep MemTotal /proc/meminfo | awk '{print $2}')
+RAM_SIZE=$(expr ${RAM_SIZE} / 1024) # MB
+RAM_SIZE=$(expr ${RAM_SIZE} + 1023)
+RAM_SIZE=$(expr ${RAM_SIZE} / 1024) # GB
+echo -n "RAM SIZE: ${RAM_SIZE} GB ..........."
+if [ ${RAM_SIZE} -ge ${TST_RAMSZ} ]; then
+ echo "pass"
+else
+ echo "FAIL"
+fi
+
+DISK_SIZE=$(lsblk -d | grep disk | head -1 | awk '{print $4}' | cut -d 'G' -f 1)
+echo -n "DISK: ${DISK_SIZE} GB ..........."
+if [ $(expr ${DISK_SIZE} \>= ${TST_DISKSZ}) -eq 1 ]; then
+ echo "pass"
+else
+ echo "FAIL"
+fi
+
+# CPU tests
+SHA_TIME=$(cpu_benchmark sha256sum)
+echo -n "SHA256: ${SHA_TIME} sec ........."
+if [ $(echo "${SHA_TIME} <= ${TST_SHA}" | bc) -eq 1 ]; then
+ echo "pass"
+else
+ echo "FAIL"
+fi
+
+BZ2_TIME=$(cpu_benchmark bzip2)
+echo -n "BZIP2: ${BZ2_TIME} sec ........."
+if [ $(echo "${BZ2_TIME} <= ${TST_BZ2}" | bc) -eq 1 ]; then
+ echo "pass"
+else
+ echo "FAIL"
+fi
+
+AES_TIME=$(cpu_benchmark openssl enc -e -aes-256-cbc -pass pass:12345678 | sed '/^\*\*\* WARNING : deprecated key derivation used\.$/d;/^Using -iter or -pbkdf2 would be better\.$/d')
+echo -n "AES256: ${AES_TIME} sec ........."
+if [ $(echo "${AES_TIME} <= ${TST_AES}" | bc) -eq 1 ]; then
+ echo "pass"
+else
+ echo "FAIL"
+fi
+
+# Disk tests
+DISK_RD=$(ioping -DRL -w 5 ./ | tail -n 2 | head -n 1 | cut -d ',' -f 4 | awk '{print $1}')
+echo -n "DISK READ: ${DISK_RD} MB/s ......"
+if [ $(echo "${DISK_RD} >= ${TST_DISKRD}" | bc) -eq 1 ]; then
+ echo "pass"
+else
+ echo "FAIL"
+fi
+
+rm -f dummy.bin
+DISK_WR=$(dd if=/dev/zero of=dummy.bin bs=64k count=16k conv=fdatasync 2>&1 | tail -1 | awk '{print $10}')
+rm -f dummy.bin
+echo -n "DISK WRITE: ${DISK_WR} MB/s ......."
+if [ $(echo "${DISK_WR} >= ${TST_DISKWR}" | bc) -eq 1 ]; then
+ echo "pass"
+else
+ echo "FAIL"
+fi
+
+# Report
+rm -f ${CSV}
+echo "Platform,HwSKU,Revision,Processor,CPU cores,Frequency(MHz),RAM(G),Disk(G),SHA256(s),bzip2(s),AES(s),sequential read(MiB/s),sequential write(MiB/s)," >> ${CSV}
+
+echo -n "${PLATFORM}," >> ${CSV}
+echo -n "${HWSKU}," >> ${CSV}
+echo -n "${REVISION}," >> ${CSV}
+echo -n "${CPU_NAME}," >> ${CSV}
+echo -n "${CPU_CORE}," >> ${CSV}
+echo -n "${CPU_FREQ}," >> ${CSV}
+echo -n "${RAM_SIZE}," >> ${CSV}
+echo -n "${DISK_SIZE}," >> ${CSV}
+echo -n "${SHA_TIME}," >> ${CSV}
+echo -n "${BZ2_TIME}," >> ${CSV}
+echo -n "${AES_TIME}," >> ${CSV}
+echo -n "${DISK_RD}," >> ${CSV}
+echo -n "${DISK_WR}," >> ${CSV}
+echo "" >> ${CSV}
diff --git a/dockers/docker-pde/docker_init.sh b/dockers/docker-pde/docker_init.sh
new file mode 100644
index 000000000000..f8e45e99d98d
--- /dev/null
+++ b/dockers/docker-pde/docker_init.sh
@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+set -x
+
+start_bcm()
+{
+ [ -e /dev/linux-bcm-knet ] || mknod /dev/linux-bcm-knet c 122 0
+ [ -e /dev/linux-user-bde ] || mknod /dev/linux-user-bde c 126 0
+ [ -e /dev/linux-kernel-bde ] || mknod /dev/linux-kernel-bde c 127 0
+}
+
+PLATFORM_DIR=/usr/share/sonic/platform
+HWSKU_DIR=/usr/share/sonic/hwsku
+
+mkdir -p /etc/sai.d/
+
+if [ -f $HWSKU_DIR/sai.profile ]; then
+ cp $HWSKU_DIR/sai.profile /etc/sai.d/sai.profile
+fi
+
+. /usr/bin/syncd_init_common.sh
+config_syncd
+
+# If the sonic-platform package is not installed, try to install it
+pip show sonic-platform > /dev/null 2>&1
+if [ $? -ne 0 ]; then
+ SONIC_PLATFORM_WHEEL="/usr/share/sonic/platform/sonic_platform-1.0-py2-none-any.whl"
+ echo "sonic-platform package not installed, attempting to install..."
+ if [ -e ${SONIC_PLATFORM_WHEEL} ]; then
+ pip install ${SONIC_PLATFORM_WHEEL}
+ if [ $? -eq 0 ]; then
+ echo "Successfully installed ${SONIC_PLATFORM_WHEEL}"
+ else
+ echo "Error: Failed to install ${SONIC_PLATFORM_WHEEL}"
+ fi
+ else
+ echo "Error: Unable to locate ${SONIC_PLATFORM_WHEEL}"
+ fi
+fi
+
+start_bcm
+
+exec /usr/bin/supervisord
diff --git a/dockers/docker-pde/stress-sfp-i2c.py b/dockers/docker-pde/stress-sfp-i2c.py
new file mode 100644
index 000000000000..cd595c52ec5c
--- /dev/null
+++ b/dockers/docker-pde/stress-sfp-i2c.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python
+
+try:
+ import sys
+ import time
+ import imp
+ from natsort import natsorted
+except ImportError as e:
+ raise ImportError("%s - required module not found" % str(e))
+
+HWSKU_PATH = "/usr/share/sonic/hwsku"
+PLATFORM_PATH = "/usr/share/sonic/platform"
+
+PLATFORM_SPECIFIC_MODULE_NAME = 'sfputil'
+PLATFORM_SPECIFIC_CLASS_NAME = 'SfpUtil'
+
+XCVR_EEPROM_TYPE_UNKNOWN = 0
+XCVR_EEPROM_TYPE_SFP = 1
+XCVR_EEPROM_TYPE_QSFP = 2
+XCVR_EEPROM_TYPE_QSFPDD = 3
+XCVR_EEPROM_TYPE_OSFP = XCVR_EEPROM_TYPE_QSFPDD
+
+OSFP_TYPE_ID = "18"
+
+# Global platform-specific sfputil class instance
+platform_sfputil = None
+
+# Global port dictionaries
+port_dict = None
+
+# Loads platform specific sfputil module from source
+def load_platform_sfputil():
+ global platform_sfputil
+
+ if platform_sfputil is not None:
+ return
+
+ try:
+ module_file = "/".join([PLATFORM_PATH, "plugins", PLATFORM_SPECIFIC_MODULE_NAME + ".py"])
+ module = imp.load_source(PLATFORM_SPECIFIC_MODULE_NAME, module_file)
+ except IOError, e:
+ print("Failed to load platform module '%s': %s" % (PLATFORM_SPECIFIC_MODULE_NAME, str(e)), True)
+
+ assert module is not None
+
+ try:
+ platform_sfputil_class = getattr(module, PLATFORM_SPECIFIC_CLASS_NAME)
+ platform_sfputil = platform_sfputil_class()
+ except AttributeError, e:
+ print("Failed to instantiate '%s' class: %s" % (PLATFORM_SPECIFIC_CLASS_NAME, str(e)), True)
+
+ assert platform_sfputil is not None
+ return
+
+# Loads platform port dictionaries
+def load_platform_portdict():
+ global port_dict
+
+ if port_dict is not None:
+ return
+
+ port_dict = {}
+ idx = 0
+ file = open(HWSKU_PATH + "/port_config.ini", "r")
+ line = file.readline()
+ while line is not None and len(line) > 0:
+ line = line.strip()
+ if line.startswith("#"):
+ line = file.readline()
+ continue
+ list = line.split()
+ if len(list) >= 4:
+ idx = int(list[3])
+ port_dict[list[0]] = { "index": str(idx) }
+ idx += 1
+ line = file.readline()
+
+ return port_dict
+
+def get_sfp_eeprom_type(port, data):
+ type = XCVR_EEPROM_TYPE_UNKNOWN
+
+ if (port in platform_sfputil.osfp_ports) or (port in platform_sfputil.qsfp_ports):
+ if data is None:
+ return type
+
+ if data[0] in OSFP_TYPE_ID:
+ code = 0
+ for i in range(128, 222):
+ code += int(data[i], 16)
+ if (code & 0xff) == int(data[222], 16):
+ type = XCVR_EEPROM_TYPE_OSFP
+ else:
+ type = XCVR_EEPROM_TYPE_QSFP
+ else:
+ type = XCVR_EEPROM_TYPE_QSFP
+ else:
+ type = XCVR_EEPROM_TYPE_SFP
+
+ return type
+
+# Test for SFP EEPROM
+def stress_sfp_i2c_one():
+ load_platform_sfputil()
+ load_platform_portdict()
+ num_sfp = 0
+ for intf in natsorted(port_dict.keys()):
+ port = int(port_dict[intf]['index'])
+ if not platform_sfputil._is_valid_port(port):
+ continue
+ if platform_sfputil.get_presence(port):
+ num_sfp += 1
+
+ assert num_sfp >= 2, "2 or more SFP modules should be attached for this test"
+
+ for intf in natsorted(port_dict.keys()):
+ port = int(port_dict[intf]['index'])
+ if not platform_sfputil._is_valid_port(port):
+ continue
+ if not platform_sfputil.get_presence(port):
+ continue
+
+ data = platform_sfputil.get_eeprom_raw(port, 256)
+ assert data is not None, "SFP{}: unable to read EEPROM".format(port)
+
+ code = 0
+ type = get_sfp_eeprom_type(port, data)
+ if type == XCVR_EEPROM_TYPE_QSFPDD:
+ for i in range(128, 222):
+ code += int(data[i], 16)
+ assert (code & 0xff) == int(data[222], 16), "{}: check code error".format(intf)
+ elif type == XCVR_EEPROM_TYPE_QSFP:
+ for i in range(128, 191):
+ code += int(data[i], 16)
+ assert (code & 0xff) == int(data[191], 16), "{}: check code error".format(intf)
+ else:
+ for i in range(0, 63):
+ code += int(data[i], 16)
+ assert (code & 0xff) == int(data[63], 16), "{}: check code error".format(intf)
+
+def stress_sfp_i2c(sec=180):
+ print("Initiating {} seconds SFP I2C stress test...".format(sec))
+ timeout = time.time() + sec
+ while timeout >= time.time():
+ stress_sfp_i2c_one()
+ sys.stdout.write("#")
+ sys.stdout.flush()
+ print("\nPASS")
+
+if __name__ == '__main__':
+ sec = 180
+ if len(sys.argv) >= 2:
+ sec = int(sys.argv[1])
+ stress_sfp_i2c(sec)
diff --git a/dockers/docker-pde/supervisord.conf b/dockers/docker-pde/supervisord.conf
new file mode 100644
index 000000000000..58a32d833163
--- /dev/null
+++ b/dockers/docker-pde/supervisord.conf
@@ -0,0 +1,12 @@
+[supervisord]
+logfile_maxbytes=1MB
+logfile_backups=2
+nodaemon=true
+
+[program:rsyslogd]
+command=/bin/bash -c "rm -f /var/run/rsyslogd.pid && /usr/sbin/rsyslogd -n"
+priority=1
+autostart=true
+autorestart=false
+stdout_logfile=syslog
+stderr_logfile=syslog
diff --git a/dockers/docker-pde/syseeprom.py b/dockers/docker-pde/syseeprom.py
new file mode 100644
index 000000000000..5f536128837a
--- /dev/null
+++ b/dockers/docker-pde/syseeprom.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+
+import sys
+import imp
+
+PLATFORM_SPECIFIC_MODULE_NAME = "eeprom"
+PLATFORM_SPECIFIC_CLASS_NAME = "board"
+
+platform_eeprom = None
+platform_eeprom_data = None
+
+# Returns path to platform and hwsku
+def get_path_to_platform_and_hwsku():
+ platform_path = '/usr/share/sonic/platform'
+ hwsku_path = '/usr/share/sonic/hwsku'
+ return (platform_path, hwsku_path)
+
+# Loads platform specific psuutil module from source
+def load_platform_util(module_name, class_name):
+ platform_util = None
+
+ # Get path to platform and hwsku
+ (platform_path, hwsku_path) = get_path_to_platform_and_hwsku()
+
+ try:
+ module_file = "/".join([platform_path, "plugins", module_name + ".py"])
+ module = imp.load_source(module_name, module_file)
+ except IOError, e:
+ assert False, ("Failed to load platform module '%s': %s" % (module_name, str(e)))
+
+ try:
+ platform_util_class = getattr(module, class_name)
+ # board class of eeprom requires 4 paramerters, need special treatment here.
+ platform_util = platform_util_class('','','','')
+ except AttributeError, e:
+ assert False, ("Failed to instantiate '%s' class: %s" % (class_name, str(e)))
+
+ return platform_util
+
+def init_platform_eeprom():
+ global platform_eeprom
+ global platform_eeprom_data
+
+ if platform_eeprom is None:
+ platform_eeprom = load_platform_util(PLATFORM_SPECIFIC_MODULE_NAME, \
+ PLATFORM_SPECIFIC_CLASS_NAME)
+ if platform_eeprom_data is None:
+ platform_eeprom_data = platform_eeprom.read_eeprom()
+
+ return platform_eeprom_data
+
+def main():
+ e = init_platform_eeprom()
+ c = platform_eeprom._TLV_CODE_PLATFORM_NAME
+ if len(sys.argv) > 1:
+ c = int(sys.argv[1], 0)
+ v, t = platform_eeprom.get_tlv_field(e, c)
+ if v:
+ print(t[2])
+ else:
+ print("Unknown")
+
+if __name__ == '__main__':
+ main()
+
diff --git a/dockers/docker-platform-monitor/Dockerfile.j2 b/dockers/docker-platform-monitor/Dockerfile.j2
index fe2c3c290a2b..d8988b8f6ebe 100755
--- a/dockers/docker-platform-monitor/Dockerfile.j2
+++ b/dockers/docker-platform-monitor/Dockerfile.j2
@@ -22,10 +22,10 @@ RUN apt-get update && \
rrdtool \
python-smbus \
python3-smbus \
- ethtool \
dmidecode \
i2c-tools \
psmisc \
+ python3-jsonschema \
libpci3
# TODO: Remove these lines once we no longer need Python 2
diff --git a/dockers/docker-platform-monitor/critical_processes b/dockers/docker-platform-monitor/critical_processes
index 3165d13ecdbc..e69de29bb2d1 100644
--- a/dockers/docker-platform-monitor/critical_processes
+++ b/dockers/docker-platform-monitor/critical_processes
@@ -1,3 +0,0 @@
-program:ledd
-program:xcvrd
-program:psud
diff --git a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2 b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2
index 90b6d5dfe733..b7eca4103ef2 100644
--- a/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2
+++ b/dockers/docker-platform-monitor/docker-pmon.supervisord.conf.j2
@@ -33,10 +33,10 @@ dependent_startup=true
command=/usr/local/bin/chassisd
priority=3
autostart=false
-autorestart=false
+autorestart=unexpected
stdout_logfile=syslog
stderr_logfile=syslog
-startsecs=0
+startsecs=10
dependent_startup=true
dependent_startup_wait_for=rsyslogd:running
{% endif %}
@@ -45,10 +45,10 @@ dependent_startup_wait_for=rsyslogd:running
command=/usr/local/bin/chassis_db_init
priority=3
autostart=false
-autorestart=false
+autorestart=unexpected
stdout_logfile=syslog
stderr_logfile=syslog
-startsecs=0
+startsecs=10
dependent_startup=true
dependent_startup_wait_for=rsyslogd:running
@@ -83,10 +83,10 @@ dependent_startup_wait_for=rsyslogd:running
command={% if API_VERSION == 3 and 'ledd' not in python2_daemons %}python3 {% else %} python2 {% endif %}/usr/local/bin/ledd
priority=5
autostart=false
-autorestart=false
+autorestart=unexpected
stdout_logfile=syslog
stderr_logfile=syslog
-startsecs=0
+startsecs=10
dependent_startup=true
dependent_startup_wait_for=rsyslogd:running
{% endif %}
@@ -100,10 +100,10 @@ command={% if API_VERSION == 3 and 'xcvrd' not in python2_daemons %}python3 {% e
{% endif %}
priority=6
autostart=false
-autorestart=false
+autorestart=unexpected
stdout_logfile=syslog
stderr_logfile=syslog
-startsecs=0
+startsecs=10
dependent_startup=true
dependent_startup_wait_for=rsyslogd:running
{% endif %}
@@ -113,10 +113,10 @@ dependent_startup_wait_for=rsyslogd:running
command={% if API_VERSION == 3 and 'psud' not in python2_daemons %}python3 {% else %} python2 {% endif %}/usr/local/bin/psud
priority=7
autostart=false
-autorestart=false
+autorestart=unexpected
stdout_logfile=syslog
stderr_logfile=syslog
-startsecs=0
+startsecs=10
dependent_startup=true
dependent_startup_wait_for=rsyslogd:running
{% endif %}
diff --git a/dockers/docker-sonic-mgmt/Dockerfile.j2 b/dockers/docker-sonic-mgmt/Dockerfile.j2
index 5f880dda7d9a..23007ffb9a86 100644
--- a/dockers/docker-sonic-mgmt/Dockerfile.j2
+++ b/dockers/docker-sonic-mgmt/Dockerfile.j2
@@ -70,6 +70,7 @@ RUN pip install cffi==1.10.0 \
tabulate \
textfsm \
virtualenv \
+ retry \
&& git clone https://github.com/p4lang/scapy-vxlan.git \
&& cd scapy-vxlan \
&& python setup.py install \
diff --git a/dockers/docker-sonic-restapi/supervisord.conf b/dockers/docker-sonic-restapi/supervisord.conf
index 4286a6dd3ec3..a873ba03d7da 100644
--- a/dockers/docker-sonic-restapi/supervisord.conf
+++ b/dockers/docker-sonic-restapi/supervisord.conf
@@ -43,7 +43,7 @@ dependent_startup_wait_for=rsyslogd:running
command=/usr/bin/restapi.sh
priority=1
autostart=false
-autorestart=true
+autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
diff --git a/dockers/docker-teamd/supervisord.conf b/dockers/docker-teamd/supervisord.conf
index 1c0d498c10b8..db6a8cfb9a5a 100644
--- a/dockers/docker-teamd/supervisord.conf
+++ b/dockers/docker-teamd/supervisord.conf
@@ -44,6 +44,7 @@ command=/usr/bin/teammgrd
priority=3
autostart=false
autorestart=false
+stopwaitsecs=60
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
diff --git a/files/Aboot/boot0.j2 b/files/Aboot/boot0.j2
index 408b05b5dd7a..bb8bd6587581 100644
--- a/files/Aboot/boot0.j2
+++ b/files/Aboot/boot0.j2
@@ -117,7 +117,8 @@ clean_flash() {
[ $f != "old_config" ] &&
[ $f != "minigraph.xml" ] &&
[ $f != "snmp.yml" ] &&
- [ $f != "acl.json" ]
+ [ $f != "acl.json" ] &&
+ [ $f != "port_config.json" ]
then
rm -rf "$target_path/$f"
fi
diff --git a/files/build_templates/docker_image_ctl.j2 b/files/build_templates/docker_image_ctl.j2
index e4dd02826e63..915279dfba94 100644
--- a/files/build_templates/docker_image_ctl.j2
+++ b/files/build_templates/docker_image_ctl.j2
@@ -93,6 +93,16 @@ function preStartAction()
docker cp /tmp/dump.rdb database$DEV:/var/lib/redis/
fi
fi
+{%- elif docker_container_name == "pde" %}
+ if [[ $(/bin/systemctl status swss | grep -c running) -gt 0 ]]; then
+ echo "Stopping SWSS before starting PDE"
+ systemctl stop swss
+ fi
+
+ if [[ $(/bin/systemctl status watchdog-control.service | grep -c running) -gt 0 ]]; then
+ echo "Stopping watchdog-control.service before starting PDE"
+ systemctl stop watchdog-control.service
+ fi
{%- elif docker_container_name == "snmp" %}
$SONIC_DB_CLI STATE_DB HSET 'DEVICE_METADATA|localhost' chassis_serial_number $(decode-syseeprom -s)
{%- else %}
@@ -404,6 +414,9 @@ start() {
-v /var/run/docker-syncd$DEV:/var/run/sswsyncd \
{%- endif %}
{%- endif %}
+{%- if docker_container_name == "pmon" %}
+ -v /usr/share/sonic/firmware:/usr/share/sonic/firmware:rw \
+{%- endif %}
{%- if docker_container_name == "swss" %}
-e ASIC_VENDOR=$ASIC_VENDOR \
{%- endif -%}
diff --git a/files/build_templates/gbsyncd-credo.service.j2 b/files/build_templates/gbsyncd-credo.service.j2
new file mode 120000
index 000000000000..69f613b0d892
--- /dev/null
+++ b/files/build_templates/gbsyncd-credo.service.j2
@@ -0,0 +1 @@
+gbsyncd.service.j2
\ No newline at end of file
diff --git a/files/build_templates/gbsyncd.service.j2 b/files/build_templates/gbsyncd.service.j2
index b33dfea6b00d..732d9c893367 100644
--- a/files/build_templates/gbsyncd.service.j2
+++ b/files/build_templates/gbsyncd.service.j2
@@ -1,5 +1,5 @@
[Unit]
-Description=gbsyncd service
+Description={{docker_container_name}} service
Requires=database.service updategraph.service
ConditionPathExists=!/usr/share/sonic/hwsku/gearbox_config.json
After=database.service updategraph.service
@@ -12,6 +12,8 @@ Before=ntp-config.service
[Service]
User=root
Environment=sonic_asic_platform={{ sonic_asic_platform }}
+Environment=gbsyncd_platform={{ docker_container_name }}
+ExecCondition=/usr/bin/gbsyncd-platform.sh
ExecStartPre=/usr/local/bin/gbsyncd.sh start
ExecStart=/usr/local/bin/gbsyncd.sh wait
ExecStop=/usr/local/bin/gbsyncd.sh stop
diff --git a/files/build_templates/init_cfg.json.j2 b/files/build_templates/init_cfg.json.j2
index 76f769431058..6e0d75518f60 100644
--- a/files/build_templates/init_cfg.json.j2
+++ b/files/build_templates/init_cfg.json.j2
@@ -21,7 +21,6 @@
},
{%- set features = [("bgp", "enabled", false, "enabled"),
("database", "always_enabled", false, "always_enabled"),
- ("dhcp_relay", "enabled", false, "enabled"),
("lldp", "enabled", false, "enabled"),
("pmon", "enabled", false, "enabled"),
("radv", "enabled", false, "enabled"),
@@ -29,6 +28,7 @@
("swss", "enabled", false, "enabled"),
("syncd", "enabled", false, "enabled"),
("teamd", "enabled", false, "enabled")] %}
+{% do features.append(("dhcp_relay", "{% if not (DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined and DEVICE_METADATA['localhost']['type'] != 'ToRRouter') %}enabled{% else %}disabled{% endif %}", false, "enabled")) %}
{%- if sonic_asic_platform == "vs" %}{% do features.append(("gbsyncd", "enabled", false, "enabled")) %}{% endif %}
{%- if include_iccpd == "y" %}{% do features.append(("iccpd", "disabled", false, "enabled")) %}{% endif %}
{%- if include_mgmt_framework == "y" %}{% do features.append(("mgmt-framework", "enabled", true, "enabled")) %}{% endif %}
@@ -47,7 +47,7 @@
"has_per_asic_scope": {% if feature + '@.service' in installer_services.split(' ') %}true{% else %}false{% endif %},
"auto_restart": "{{autorestart}}",
{%- if include_kubernetes == "y" %}
-{%- if feature in ["dhcp_relay", "lldp", "pmon", "radv", "snmp", "telemetry"] %}
+{%- if feature in ["lldp", "pmon", "radv", "snmp", "telemetry"] %}
"set_owner": "kube", {% else %}
"set_owner": "local", {% endif %} {% endif %}
"high_mem_alert": "disabled"
diff --git a/files/build_templates/manifest.json.j2 b/files/build_templates/manifest.json.j2
index 5b09e1d987bc..9f3e872d2e65 100644
--- a/files/build_templates/manifest.json.j2
+++ b/files/build_templates/manifest.json.j2
@@ -12,7 +12,15 @@
"before": {{ before.split()|json if before is defined else [] }},
"dependent-of": {{ dependent_of.split()|json if dependent_of is defined else [] }},
"asic-service": {{ asic_service }},
- "host-service": {{ host_service }}
+ "host-service": {{ host_service }},
+ "warm-shutdown": {
+ "after": {{ warm_shutdown_after.split()|json if warm_shutdown_after is defined else [] }},
+ "before": {{ warm_shutdown_before.split()|json if warm_shutdown_before is defined else [] }}
+ },
+ "fast-shutdown": {
+ "after": {{ fast_shutdown_after.split()|json if fast_shutdown_after is defined else [] }},
+ "before": {{ fast_shutdown_before.split()|json if fast_shutdown_before is defined else [] }}
+ }
},
"container": {
"privileged": {{ privileged if privileged else 'false' }},
diff --git a/files/build_templates/packages.json.j2 b/files/build_templates/packages.json.j2
index 3c0d1034031a..3c44abb70a2b 100644
--- a/files/build_templates/packages.json.j2
+++ b/files/build_templates/packages.json.j2
@@ -1,6 +1,12 @@
+{%- set docker_installation_targets = [] -%}
+{%- for docker_installation_target in installer_images.strip().split() -%}
+{%- set pkgname, docker_build_path, machine, image = docker_installation_target.split('|') -%}
+{%- if not machine or (machine and machine == target_machine) -%}
+{%- set _ = docker_installation_targets.append((pkgname, image)) -%}
+{%- endif -%}
+{%- endfor -%}
{
-{% for docker_installation_target in installer_images.strip().split() -%}
-{% set pkgname, docker_build_path, image = docker_installation_target.split('|') -%}
+{% for pkgname, image in docker_installation_targets -%}
{% set imagefilepath = image.split(':')|first -%}
{% set imageversion = image.split(':')|last -%}
{% set imagefilename = imagefilepath.split('/')|last -%}
diff --git a/files/build_templates/pde.service.j2 b/files/build_templates/pde.service.j2
new file mode 100644
index 000000000000..f053b57ad576
--- /dev/null
+++ b/files/build_templates/pde.service.j2
@@ -0,0 +1,22 @@
+[Unit]
+Description=PDE container
+{% if sonic_asic_platform == 'broadcom' %}
+Requires=opennsl-modules.service
+ConditionPathExists=!/usr/bin/swss.sh
+{% endif %}
+
+After=updategraph.service
+{% if sonic_asic_platform == 'broadcom' %}
+After=opennsl-modules.service
+{% endif %}
+
+Before=
+
+[Service]
+User={{ sonicadmin_user }}
+ExecStartPre=/usr/bin/{{ docker_container_name }}.sh start
+ExecStart=/usr/bin/{{ docker_container_name }}.sh wait
+ExecStop=/usr/bin/{{ docker_container_name }}.sh stop
+
+[Install]
+WantedBy=multi-user.target
diff --git a/files/build_templates/per_namespace/lldp.service.j2 b/files/build_templates/per_namespace/lldp.service.j2
index 1854bc0ca097..02ab99dca463 100644
--- a/files/build_templates/per_namespace/lldp.service.j2
+++ b/files/build_templates/per_namespace/lldp.service.j2
@@ -16,9 +16,9 @@ StartLimitBurst=3
[Service]
User={{ sonicadmin_user }}
-ExecStartPre=/usr/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %}
-ExecStart=/usr/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %}
-ExecStop=/usr/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %}
+ExecStartPre=/usr/local/bin/{{docker_container_name}}.sh start{% if multi_instance == 'true' %} %i{% endif %}
+ExecStart=/usr/local/bin/{{docker_container_name}}.sh wait{% if multi_instance == 'true' %} %i{% endif %}
+ExecStop=/usr/local/bin/{{docker_container_name}}.sh stop{% if multi_instance == 'true' %} %i{% endif %}
RestartSec=30
[Install]
diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2
index 36bc0e121286..48186caf642e 100644
--- a/files/build_templates/sonic_debian_extension.j2
+++ b/files/build_templates/sonic_debian_extension.j2
@@ -50,6 +50,7 @@ FILESYSTEM_ROOT_USR_SHARE="$FILESYSTEM_ROOT_USR/share"
FILESYSTEM_ROOT_USR_SHARE_SONIC="$FILESYSTEM_ROOT_USR_SHARE/sonic"
FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS="$FILESYSTEM_ROOT_USR_SHARE_SONIC/scripts"
FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES="$FILESYSTEM_ROOT_USR_SHARE_SONIC/templates"
+FILESYSTEM_ROOT_USR_SHARE_SONIC_FIRMWARE="$FILESYSTEM_ROOT_USR_SHARE_SONIC/firmware"
FILESYSTEM_ROOT_ETC="$FILESYSTEM_ROOT/etc"
FILESYSTEM_ROOT_ETC_SONIC="$FILESYSTEM_ROOT_ETC/sonic"
@@ -92,6 +93,7 @@ sudo mkdir -p $FILESYSTEM_ROOT/etc/sonic/
sudo mkdir -p $FILESYSTEM_ROOT/etc/modprobe.d/
sudo mkdir -p $FILESYSTEM_ROOT/var/cache/sonic/
sudo mkdir -p $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/
+sudo mkdir -p $FILESYSTEM_ROOT_USR_SHARE_SONIC_FIRMWARE/
# This is needed for Stretch and might not be needed for Buster where Linux create this directory by default.
# Keeping it generic. It should not harm anyways.
sudo mkdir -p $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM
@@ -114,6 +116,9 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in
python-dev \
python3-dev
+# Install j2cli for handling jinja template
+sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install "j2cli==0.3.10"
+
# Install Python client for Redis
sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip2 install "redis==3.5.3"
sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install "redis==3.5.3"
@@ -448,6 +453,10 @@ sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install azure-
sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip3 install watchdog==0.10.3
{% if include_kubernetes == "y" %}
+# Point to kubelet to /etc/resolv.conf
+#
+echo 'KUBELET_EXTRA_ARGS="--resolv-conf=/etc/resolv.conf"' | sudo tee -a $FILESYSTEM_ROOT/etc/default/kubelet
+
# Copy Flannel conf file into sonic-templates
#
sudo cp $BUILD_TEMPLATES/kube_cni.10-flannel.conflist $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/
@@ -468,6 +477,25 @@ sudo cp ${files_path}/container_startup.py ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCR
sudo chmod a+x ${FILESYSTEM_ROOT_USR_SHARE_SONIC_SCRIPTS}/container_startup.py
# Config file used by container mgmt scripts/service
+fl="${files_path}/remote_ctr.config.json"
+use_k8s_as_http_proxy=$(python3 -c 'import json
+with open("'${fl}'", "r") as s:
+ d=json.load(s);print(d.get("use_k8s_as_http_proxy", ""))
+')
+if [ "${use_k8s_as_http_proxy}" == "y" ]; then
+ # create proxy files for docker using private IP which will
+ # be later directed to k8s master upon config
+ PROXY_INFO="${kube_docker_proxy}"
+ cat < /dev/null
+[Service]
+Environment="HTTP_PROXY=${PROXY_INFO}"
+EOT
+ cat < /dev/null
+[Service]
+Environment="HTTPS_PROXY=${PROXY_INFO}"
+EOT
+fi
+
sudo cp ${files_path}/remote_ctr.config.json ${FILESYSTEM_ROOT_ETC_SONIC}/
# Remote container management service files
@@ -667,11 +695,18 @@ fi
SONIC_PACKAGE_MANAGER_FOLDER="/var/lib/sonic-package-manager/"
sudo mkdir -p $FILESYSTEM_ROOT/$SONIC_PACKAGE_MANAGER_FOLDER
-j2 $BUILD_TEMPLATES/packages.json.j2 | sudo tee $FILESYSTEM_ROOT/$SONIC_PACKAGE_MANAGER_FOLDER/packages.json
+target_machine="$TARGET_MACHINE" j2 $BUILD_TEMPLATES/packages.json.j2 | sudo tee $FILESYSTEM_ROOT/$SONIC_PACKAGE_MANAGER_FOLDER/packages.json
+if [ "${PIPESTATUS[0]}" != "0" ]; then
+ echo "Failed to generate packages.json" >&2
+ exit 1
+fi
# Copy docker_image_ctl.j2 for SONiC Package Manager
sudo cp $BUILD_TEMPLATES/docker_image_ctl.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/docker_image_ctl.j2
+# Generate shutdown order
+sudo LANG=C chroot $FILESYSTEM_ROOT /usr/local/bin/generate_shutdown_order.py
+
{% if include_kubernetes == "y" %}
## Pull in kubernetes docker images
echo "pulling universal k8s images ..."
@@ -754,14 +789,18 @@ sudo LANG=C chroot $FILESYSTEM_ROOT fuser -km /sys || true
sudo LANG=C chroot $FILESYSTEM_ROOT umount -lf /sys
{% endif %}
-# Copy service scripts (swss, syncd, bgp, teamd, radv)
+# Copy service scripts (swss, syncd, bgp, teamd, lldp, radv)
sudo LANG=C cp $SCRIPTS_DIR/swss.sh $FILESYSTEM_ROOT/usr/local/bin/swss.sh
sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh
sudo LANG=C cp $SCRIPTS_DIR/syncd_common.sh $FILESYSTEM_ROOT/usr/local/bin/syncd_common.sh
sudo LANG=C cp $SCRIPTS_DIR/gbsyncd.sh $FILESYSTEM_ROOT/usr/local/bin/gbsyncd.sh
+sudo LANG=C cp $SCRIPTS_DIR/gbsyncd-platform.sh $FILESYSTEM_ROOT/usr/bin/gbsyncd-platform.sh
sudo LANG=C cp $SCRIPTS_DIR/bgp.sh $FILESYSTEM_ROOT/usr/local/bin/bgp.sh
sudo LANG=C cp $SCRIPTS_DIR/teamd.sh $FILESYSTEM_ROOT/usr/local/bin/teamd.sh
+sudo LANG=C cp $SCRIPTS_DIR/lldp.sh $FILESYSTEM_ROOT/usr/local/bin/lldp.sh
sudo LANG=C cp $SCRIPTS_DIR/radv.sh $FILESYSTEM_ROOT/usr/local/bin/radv.sh
+sudo LANG=C cp $SCRIPTS_DIR/asic_status.sh $FILESYSTEM_ROOT/usr/local/bin/asic_status.sh
+sudo LANG=C cp $SCRIPTS_DIR/asic_status.py $FILESYSTEM_ROOT/usr/local/bin/asic_status.py
# Copy sonic-netns-exec script
sudo LANG=C cp $SCRIPTS_DIR/sonic-netns-exec $FILESYSTEM_ROOT/usr/bin/sonic-netns-exec
diff --git a/files/image_config/config-setup/config-setup b/files/image_config/config-setup/config-setup
index aacbdff00035..b151437b9e25 100755
--- a/files/image_config/config-setup/config-setup
+++ b/files/image_config/config-setup/config-setup
@@ -305,7 +305,7 @@ check_all_config_db_present()
do_config_migration()
{
# Identify list of files to migrate
- copy_list="minigraph.xml snmp.yml acl.json frr telemetry"
+ copy_list="minigraph.xml snmp.yml acl.json port_config.json frr telemetry"
# Migrate all configuration files from old to new
copy_config_files_and_directories $copy_list
diff --git a/files/image_config/copp/copp_cfg.j2 b/files/image_config/copp/copp_cfg.j2
index 61f051f43de8..481051cba611 100755
--- a/files/image_config/copp/copp_cfg.j2
+++ b/files/image_config/copp/copp_cfg.j2
@@ -79,12 +79,10 @@
"trap_ids": "lldp",
"trap_group": "queue4_group3"
},
-{% if not (DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined and DEVICE_METADATA['localhost']['type'] != "ToRRouter") %}
- "dhcp": {
+ "dhcp_relay": {
"trap_ids": "dhcp,dhcpv6",
"trap_group": "queue4_group3"
},
-{% endif %}
"udld": {
"trap_ids": "udld",
"trap_group": "queue4_group3"
diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local
index b299f9fe2bba..b63caef0f4a5 100755
--- a/files/image_config/platform/rc.local
+++ b/files/image_config/platform/rc.local
@@ -120,6 +120,8 @@ migrate_nos_configuration()
MG_FILE=$NOS_DIR/minigraph.xml
ACL_GZFILE=$NOS_DIR/acl.json.gz.base64.txt
ACL_FILE=$NOS_DIR/acl.json
+ PORT_CONFIG_GZFILE=$NOS_DIR/port_config.json.gz.base64.txt
+ PORT_CONFIG_FILE=$NOS_DIR/port_config.json
SNMP_FILE=$NOS_DIR/snmp.yml
mkdir -p $NOS_DIR
@@ -131,11 +133,13 @@ migrate_nos_configuration()
# decode & unzip minigraph.xml.gz.base64.txt
[ -f $MG_GZFILE ] && /usr/bin/base64 -d $MG_GZFILE | /bin/gunzip > $MG_FILE
[ -f $ACL_GZFILE ] && /usr/bin/base64 -d $ACL_GZFILE | /bin/gunzip > $ACL_FILE
+ [ -f $PORT_CONFIG_GZFILE ] && /usr/bin/base64 -d $PORT_CONFIG_GZFILE | /bin/gunzip > $PORT_CONFIG_FILE
# Copy relevant files
nos_migration_import $NOS_DIR/mgmt_interface.cfg /host/migration
nos_migration_import $MG_FILE /host/migration
nos_migration_import $ACL_FILE /host/migration
+ nos_migration_import $PORT_CONFIG_FILE /host/migration
nos_migration_import $SNMP_FILE /host/migration
if [ "$sonic_fast_reboot" == true ]; then
@@ -243,12 +247,14 @@ if [ -f $FIRST_BOOT_FILE ]; then
mkdir -p /etc/sonic/old_config
mv /host/minigraph.xml /etc/sonic/old_config/
[ -f /host/acl.json ] && mv /host/acl.json /etc/sonic/old_config/
+ [ -f /host/port_config.json ] && mv /host/port_config.json /etc/sonic/old_config/
[ -f /host/snmp.yml ] && mv /host/snmp.yml /etc/sonic/old_config/
touch /tmp/pending_config_migration
elif [ -n "$migration" ] && [ -f /host/migration/minigraph.xml ]; then
mkdir -p /etc/sonic/old_config
mv /host/migration/minigraph.xml /etc/sonic/old_config/
[ -f /host/migration/acl.json ] && mv /host/migration/acl.json /etc/sonic/old_config/
+ [ -f /host/migration/port_config.json ] && mv /host/migration/port_config.json /etc/sonic/old_config/
[ -f /host/migration/snmp.yml ] && mv /host/migration/snmp.yml /etc/sonic/old_config/
touch /tmp/pending_config_migration
[ -f /etc/sonic/updategraph.conf ] && sed -i -e "s/enabled=false/enabled=true/g" /etc/sonic/updategraph.conf
diff --git a/files/image_config/secureboot/allowlist_paths.conf b/files/image_config/secureboot/allowlist_paths.conf
index f1021f5c13e9..80b176178c7f 100644
--- a/files/image_config/secureboot/allowlist_paths.conf
+++ b/files/image_config/secureboot/allowlist_paths.conf
@@ -25,6 +25,7 @@ etc/sonic/acl.json
etc/sonic/config_db.json
etc/sonic/minigraph.xml
etc/sonic/old_config/.*
+etc/sonic/port_config.json
etc/sonic/snmp.yml
etc/sonic/sonic-environment
etc/sonic/updategraph.conf
diff --git a/files/image_config/warmboot-finalizer/finalize-warmboot.sh b/files/image_config/warmboot-finalizer/finalize-warmboot.sh
index 172fd95ab2e9..2649e51b0d21 100755
--- a/files/image_config/warmboot-finalizer/finalize-warmboot.sh
+++ b/files/image_config/warmboot-finalizer/finalize-warmboot.sh
@@ -11,6 +11,13 @@ declare -A RECONCILE_COMPONENTS=( \
["bgp"]="bgp" \
["nat"]="natsyncd" \
)
+
+for reconcile_file in $(find /etc/sonic/ -iname '*_reconcile' -type f); do
+ file_basename=$(basename $reconcile_file)
+ docker_container_name=${file_basename%_reconcile}
+ RECONCILE_COMPONENTS[$docker_container_name]=$(cat $reconcile_file)
+done
+
EXP_STATE="reconciled"
ASSISTANT_SCRIPT="/usr/local/bin/neighbor_advertiser"
diff --git a/files/scripts/asic_status.py b/files/scripts/asic_status.py
new file mode 100755
index 000000000000..bed21de412fa
--- /dev/null
+++ b/files/scripts/asic_status.py
@@ -0,0 +1,78 @@
+#!/usr/bin/env python3
+
+"""
+ bootstrap-asic
+"""
+try:
+ import re
+ import sys
+ from sonic_py_common import daemon_base
+ from swsscommon import swsscommon
+ from sonic_py_common import multi_asic
+ from sonic_py_common.logger import Logger
+except ImportError as e:
+ raise ImportError(str(e) + " - required module not found")
+
+#
+# Constants ====================================================================
+#
+SYSLOG_IDENTIFIER = 'asic_status.py'
+CHASSIS_ASIC_INFO_TABLE = 'CHASSIS_ASIC_TABLE'
+SELECT_TIMEOUT_MSECS = 5000
+
+def main():
+ logger = Logger(SYSLOG_IDENTIFIER)
+ logger.set_min_log_priority_info()
+
+ if len(sys.argv) != 3:
+ raise Exception('Pass service and valid asic-id as arguments')
+
+ service = sys.argv[1]
+ args_asic_id = sys.argv[2]
+
+ # Get num asics
+ num_asics = multi_asic.get_num_asics()
+ if num_asics == 0:
+ logger.log_error('Detected no asics on this platform for service {}'.format(service))
+ sys.exit(1)
+
+ # Connect to STATE_DB and subscribe to chassis-module table notifications
+ state_db = daemon_base.db_connect("CHASSIS_STATE_DB")
+
+ sel = swsscommon.Select()
+ sst = swsscommon.SubscriberStateTable(state_db, CHASSIS_ASIC_INFO_TABLE)
+ sel.addSelectable(sst)
+
+ while True:
+ (state, c) = sel.select(SELECT_TIMEOUT_MSECS)
+ if state == swsscommon.Select.TIMEOUT:
+ continue
+ if state != swsscommon.Select.OBJECT:
+ continue
+
+ (asic_key, asic_op, asic_fvp) = sst.pop()
+ asic_id=re.search(r'\d+$', asic_key)
+ global_asic_id = asic_id.group(0)
+
+ if asic_op == 'SET':
+ asic_fvs = dict(asic_fvp)
+ asic_name = asic_fvs.get('name')
+ if asic_name is None:
+ logger.log_info('Unable to get asic_name for asic{}'.format(global_asic_id))
+ continue
+
+ if asic_name.startswith('FABRIC-CARD') is False:
+ logger.log_info('Skipping module with asic_name {} for asic{}'.format(asic_name, global_asic_id))
+ continue
+
+ if (global_asic_id == args_asic_id):
+ logger.log_info('Detected asic{} is online'.format(global_asic_id))
+ sys.exit(0)
+ elif asic_op == 'DEL':
+ logger.log_info('Detected asic{} is offline'.format(global_asic_id))
+ sys.exit(1)
+ else:
+ continue
+
+if __name__ == "__main__":
+ main()
diff --git a/files/scripts/asic_status.sh b/files/scripts/asic_status.sh
new file mode 100755
index 000000000000..e3140eda5986
--- /dev/null
+++ b/files/scripts/asic_status.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+
+is_chassis_supervisor() {
+ if [ -f /etc/sonic/chassisdb.conf ]; then
+ true
+ return
+ fi
+ false
+ return
+}
+
+check_asic_status() {
+ # Ignore services that are not started in namespace.
+ if [[ -z $DEV ]]; then
+ return 0
+ fi
+
+ # For chassis supervisor, wait for asic to be online
+ /usr/local/bin/asic_status.py $SERVICE $DEV
+ if [[ $? = 0 ]]; then
+ debug "$SERVICE successfully detected asic $DEV..."
+ return 0
+ fi
+ debug "$SERVICE failed to detect asic $DEV..."
+ return 1
+}
diff --git a/files/scripts/gbsyncd-platform.sh b/files/scripts/gbsyncd-platform.sh
new file mode 100755
index 000000000000..cb83e0e39e5e
--- /dev/null
+++ b/files/scripts/gbsyncd-platform.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+# Check the gbsyncd platform defined on the device matching the service,
+# or otherwise skip starting the service
+
+SERVICE="$gbsyncd_platform"
+PLATFORM=${PLATFORM:-`sonic-cfggen -H -v DEVICE_METADATA.localhost.platform`}
+DEVPATH="/usr/share/sonic/device"
+CONFIGFILE="${DEVPATH}/${PLATFORM}/gbsyncd.ini"
+
+if [ ! -f "$CONFIGFILE" ]; then
+ if [ gbsyncd = "$SERVICE" ]; then
+ exit 0
+ fi
+ exit 1
+fi
+
+while IFS="=" read -r key value; do
+ case "$key" in
+ platform)
+ if [ "$value" = "$SERVICE" ]; then
+ exit 0
+ fi
+ ;;
+ esac
+done < "$CONFIGFILE"
+
+exit 1
diff --git a/files/scripts/gbsyncd.sh b/files/scripts/gbsyncd.sh
index 996fbf8cdf31..512ceed2d747 100755
--- a/files/scripts/gbsyncd.sh
+++ b/files/scripts/gbsyncd.sh
@@ -21,10 +21,10 @@ function stopplatform2() {
OP=$1
DEV=$2
-SERVICE="gbsyncd"
+SERVICE="$gbsyncd_platform"
PEER="swss"
-DEBUGLOG="/tmp/swss-gbsyncd-debug$DEV.log"
-LOCKFILE="/tmp/swss-gbsyncd-lock$DEV"
+DEBUGLOG="/tmp/swss-$SERVICE-debug$DEV.log"
+LOCKFILE="/tmp/swss-$SERVICE-lock$DEV"
NAMESPACE_PREFIX="asic"
if [ "$DEV" ]; then
NET_NS="$NAMESPACE_PREFIX$DEV" #name of the network namespace
diff --git a/files/scripts/lldp.sh b/files/scripts/lldp.sh
new file mode 100755
index 000000000000..a87df21141d2
--- /dev/null
+++ b/files/scripts/lldp.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+. /usr/local/bin/asic_status.sh
+
+function debug()
+{
+ /usr/bin/logger $1
+ /bin/echo `date` "- $1" >> ${DEBUGLOG}
+}
+
+start() {
+ debug "Starting ${SERVICE}$DEV service..."
+
+ # On supervisor card, skip starting asic related services here. In wait(),
+ # wait until the asic is detected by pmon and published via database.
+ if ! is_chassis_supervisor; then
+ # start service docker
+ /usr/bin/${SERVICE}.sh start $DEV
+ debug "Started ${SERVICE}$DEV service..."
+ fi
+}
+
+wait() {
+ # On supervisor card, wait for asic to be online before starting the docker.
+ if is_chassis_supervisor; then
+ check_asic_status
+ ASIC_STATUS=$?
+
+ # start service docker
+ if [[ $ASIC_STATUS == 0 ]]; then
+ /usr/bin/${SERVICE}.sh start $DEV
+ debug "Started ${SERVICE}$DEV service..."
+ fi
+ fi
+
+ /usr/bin/${SERVICE}.sh wait $DEV
+}
+
+stop() {
+ debug "Stopping ${SERVICE}$DEV service..."
+
+ /usr/bin/${SERVICE}.sh stop $DEV
+ debug "Stopped ${SERVICE}$DEV service..."
+}
+
+DEV=$2
+
+SERVICE="lldp"
+DEBUGLOG="/tmp/lldp-debug$DEV.log"
+
+case "$1" in
+ start|wait|stop)
+ $1
+ ;;
+ *)
+ echo "Usage: $0 {start|wait|stop}"
+ exit 1
+ ;;
+esac
diff --git a/files/scripts/swss.sh b/files/scripts/swss.sh
index 730d75bea2c1..298f5e21b656 100755
--- a/files/scripts/swss.sh
+++ b/files/scripts/swss.sh
@@ -1,6 +1,6 @@
#!/bin/bash
-DEPENDENT="radv dhcp_relay"
+DEPENDENT="radv"
MULTI_INST_DEPENDENT="teamd"
# Update dependent list based on other packages requirements
@@ -12,6 +12,8 @@ if [[ -f /etc/sonic/${SERVICE}_multi_inst_dependent ]]; then
MULTI_INST_DEPENDENT="${MULTI_INST_DEPENDENT} cat /etc/sonic/${SERVICE}_multi_inst_dependent"
fi
+. /usr/local/bin/asic_status.sh
+
function debug()
{
/usr/bin/logger $1
@@ -158,15 +160,31 @@ start() {
clean_up_tables STATE_DB "'PORT_TABLE*', 'MGMT_PORT_TABLE*', 'VLAN_TABLE*', 'VLAN_MEMBER_TABLE*', 'LAG_TABLE*', 'LAG_MEMBER_TABLE*', 'INTERFACE_TABLE*', 'MIRROR_SESSION*', 'VRF_TABLE*', 'FDB_TABLE*', 'FG_ROUTE_TABLE*', 'BUFFER_POOL*', 'BUFFER_PROFILE*', 'MUX_CABLE_TABLE*'"
fi
- # start service docker
- /usr/bin/${SERVICE}.sh start $DEV
- debug "Started ${SERVICE}$DEV service..."
+ # On supervisor card, skip starting asic related services here. In wait(),
+ # wait until the asic is detected by pmon and published via database.
+ if ! is_chassis_supervisor; then
+ # start service docker
+ /usr/bin/${SERVICE}.sh start $DEV
+ debug "Started ${SERVICE}$DEV service..."
+ fi
# Unlock has to happen before reaching out to peer service
unlock_service_state_change
}
wait() {
+ # On supervisor card, wait for asic to be online before starting the docker.
+ if is_chassis_supervisor; then
+ check_asic_status
+ ASIC_STATUS=$?
+
+ # start service docker
+ if [[ $ASIC_STATUS == 0 ]]; then
+ /usr/bin/${SERVICE}.sh start $DEV
+ debug "Started ${SERVICE}$DEV service..."
+ fi
+ fi
+
start_peer_and_dependent_services
# Allow some time for peer container to start
diff --git a/files/scripts/syncd_common.sh b/files/scripts/syncd_common.sh
index 0e9fc8ac2d7a..3bb7c9fe6b6e 100755
--- a/files/scripts/syncd_common.sh
+++ b/files/scripts/syncd_common.sh
@@ -11,6 +11,8 @@
# For examples of these, see gbsyncd.sh and syncd.sh.
#
+. /usr/local/bin/asic_status.sh
+
function debug()
{
/usr/bin/logger $1
@@ -104,14 +106,30 @@ start() {
startplatform
- # start service docker
- /usr/bin/${SERVICE}.sh start $DEV
- debug "Started ${SERVICE} service..."
+ # On supervisor card, skip starting asic related services here. In wait(),
+ # wait until the asic is detected by pmon and published via database.
+ if ! is_chassis_supervisor; then
+ # start service docker
+ /usr/bin/${SERVICE}.sh start $DEV
+ debug "Started ${SERVICE}$DEV service..."
+ fi
unlock_service_state_change
}
wait() {
+ # On supervisor card, wait for asic to be online before starting the docker.
+ if is_chassis_supervisor; then
+ check_asic_status
+ ASIC_STATUS=$?
+
+ # start service docker
+ if [[ $ASIC_STATUS == 0 ]]; then
+ /usr/bin/${SERVICE}.sh start $DEV
+ debug "Started ${SERVICE}$DEV service..."
+ fi
+ fi
+
waitplatform
/usr/bin/${SERVICE}.sh wait $DEV
diff --git a/files/scripts/teamd.sh b/files/scripts/teamd.sh
index 626bb5186ca0..c72048dccc93 100755
--- a/files/scripts/teamd.sh
+++ b/files/scripts/teamd.sh
@@ -1,5 +1,7 @@
#!/bin/bash
+. /usr/local/bin/asic_status.sh
+
function debug()
{
/usr/bin/logger $1
@@ -48,12 +50,28 @@ start() {
debug "Warm boot flag: ${SERVICE}$DEV ${WARM_BOOT}."
debug "Fast boot flag: ${SERVICE}$DEV ${Fast_BOOT}."
- # start service docker
- /usr/bin/${SERVICE}.sh start $DEV
- debug "Started ${SERVICE}$DEV service..."
+ # On supervisor card, skip starting asic related services here. In wait(),
+ # wait until the asic is detected by pmon and published via database.
+ if ! is_chassis_supervisor; then
+ # start service docker
+ /usr/bin/${SERVICE}.sh start $DEV
+ debug "Started ${SERVICE}$DEV service..."
+ fi
}
wait() {
+ # On supervisor card, wait for asic to be online before starting the docker.
+ if is_chassis_supervisor; then
+ check_asic_status
+ ASIC_STATUS=$?
+
+ # start service docker
+ if [[ $ASIC_STATUS == 0 ]]; then
+ /usr/bin/${SERVICE}.sh start $DEV
+ debug "Started ${SERVICE}$DEV service..."
+ fi
+ fi
+
/usr/bin/${SERVICE}.sh wait $DEV
}
diff --git a/platform/barefoot/sonic-platform-modules-arista b/platform/barefoot/sonic-platform-modules-arista
index 700b1e448fbc..6e8ccd3379d5 160000
--- a/platform/barefoot/sonic-platform-modules-arista
+++ b/platform/barefoot/sonic-platform-modules-arista
@@ -1 +1 @@
-Subproject commit 700b1e448fbcb3d9d083f0fbff08416aa1237185
+Subproject commit 6e8ccd3379d5e89f4e80b11391818e648d928d94
diff --git a/platform/broadcom/docker-pde.dep b/platform/broadcom/docker-pde.dep
new file mode 100644
index 000000000000..bc7eb8225808
--- /dev/null
+++ b/platform/broadcom/docker-pde.dep
@@ -0,0 +1,12 @@
+
+DPATH := $($(DOCKER_PDE)_PATH)
+DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/docker-pde.mk platform/broadcom/docker-pde.dep
+DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
+DEP_FILES += $(SONIC_COMMON_DOCKER_FILES_LIST)
+DEP_FILES += $(shell git ls-files $(DPATH))
+
+$(DOCKER_PDE)_CACHE_MODE := GIT_CONTENT_SHA
+$(DOCKER_PDE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
+$(DOCKER_PDE)_DEP_FILES := $(DEP_FILES)
+
+$(eval $(call add_dbg_docker,$(DOCKER_PDE),$(DOCKER_PDE_DBG)))
diff --git a/platform/broadcom/docker-pde.mk b/platform/broadcom/docker-pde.mk
new file mode 100644
index 000000000000..56d810467498
--- /dev/null
+++ b/platform/broadcom/docker-pde.mk
@@ -0,0 +1,49 @@
+# Docker image for SONiC Platform Development Environment (PDE)
+
+ifeq ($(INCLUDE_PDE), y)
+DOCKER_PDE_STEM = docker-pde
+DOCKER_PDE = $(DOCKER_PDE_STEM).gz
+DOCKER_PDE_DBG = $(DOCKER_PDE_STEM)-$(DBG_IMAGE_MARK).gz
+$(DOCKER_PDE)_PATH = $(DOCKERS_PATH)/$(DOCKER_PDE_STEM)
+$(DOCKER_PDE)_DEPENDS += $(PYTHON_NETIFACES)
+$(DOCKER_PDE)_DEPENDS += $(SONIC_PLATFORM_PDE) $(BRCM_SAI)
+
+$(DOCKER_PDE_RDEPENDS += $(PYTHON_NETIFACES)
+$(DOCKER_PDE)_PYTHON_DEBS += $(SONIC_UTILS)
+$(DOCKER_PDE)_PYTHON_WHEELS += $(SONIC_PLATFORM_COMMON_PY3)
+
+ifeq ($(PDDF_SUPPORT), y)
+$(DOCKER_PDE)_PYTHON_WHEELS += $(PDDF_PLATFORM_API_BASE_PY3)
+endif
+$(DOCKER_PDE)_PYTHON_WHEELS += $(SONIC_DAEMON_BASE_PY3)
+$(DOCKER_PDE)_DBG_DEPENDS = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_DEPENDS)
+$(DOCKER_PDE)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_IMAGE_PACKAGES)
+$(DOCKER_PDE)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BUSTER)
+
+SONIC_DOCKER_IMAGES += $(DOCKER_PDE)
+SONIC_BUSTER_DOCKERS += $(DOCKER_PDE)
+SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_PDE)
+SONIC_BUSTER_DBG_DOCKERS += $(DOCKER_PDE_DBG)
+SONIC_DOCKER_DBG_IMAGES += $(DOCKER_PDE_DBG)
+SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_PDE_DBG)
+
+$(DOCKER_PDE)_CONTAINER_NAME = pde
+$(DOCKER_PDE)_RUN_OPT += --net=host --privileged -t
+$(DOCKER_PDE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
+$(DOCKER_PDE)_RUN_OPT += -v /host/machine.conf:/host/machine.conf:ro
+$(DOCKER_PDE)_RUN_OPT += -v /usr/lib/python2.7/dist-packages:/usr/share/sonic/classes:ro
+
+$(DOCKER_PDE)_RUN_OPT += -v /usr/local/lib/python3.7/dist-packages/utilities_common:/usr/local/lib/python3.7/dist-packages/utilities_common:ro
+$(DOCKER_PDE)_RUN_OPT += -v /var/log/syslog:/var/log/syslog:ro
+$(DOCKER_PDE)_RUN_OPT += -v /lib/modules:/lib/modules:ro
+$(DOCKER_PDE)_RUN_OPT += -v /boot:/boot:ro
+$(DOCKER_PDE)_RUN_OPT += -v /var/log/ramfs:/var/log/ramfs:ro
+$(DOCKER_PDE)_RUN_OPT += -v /usr/share/sonic/device/x86_64-broadcom_common:/usr/share/sonic/device/x86_64-broadcom_common:ro
+$(DOCKER_PDE)_RUN_OPT += -v /usr/share/sonic/device/pddf:/usr/share/sonic/device/pddf:ro
+
+$(DOCKER_PDE)_BASE_IMAGE_FILES += pde-test:/usr/local/bin/pde-test
+$(DOCKER_PDE)_BASE_IMAGE_FILES += pde-bench:/usr/local/bin/pde-bench
+$(DOCKER_PDE)_BASE_IMAGE_FILES += pde-stress:/usr/local/bin/pde-stress
+$(DOCKER_PDE)_BASE_IMAGE_FILES += pde-bench-knet:/usr/local/bin/pde-bench-knet
+
+endif
diff --git a/platform/broadcom/one-pde-image.dep b/platform/broadcom/one-pde-image.dep
deleted file mode 100644
index 2abc8cad736f..000000000000
--- a/platform/broadcom/one-pde-image.dep
+++ /dev/null
@@ -1,2 +0,0 @@
-#DPKG FRK
-$(SONIC_ONE_PDE_IMAGE)_CACHE_MODE := none
diff --git a/platform/broadcom/rules.dep b/platform/broadcom/rules.dep
index fd9407aeb049..abd96f672e73 100644
--- a/platform/broadcom/rules.dep
+++ b/platform/broadcom/rules.dep
@@ -17,10 +17,14 @@ include $(PLATFORM_PATH)/platform-modules-brcm-xlr-gts.dep
include $(PLATFORM_PATH)/docker-syncd-brcm.dep
include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.dep
include $(PLATFORM_PATH)/docker-saiserver-brcm.dep
+ifeq ($(INCLUDE_PDE), y)
+include $(PLATFORM_PATH)/docker-pde.dep
+include $(PLATFORM_PATH)/sonic-pde-tests.dep
+endif
include $(PLATFORM_PATH)/one-image.dep
-include $(PLATFORM_PATH)/one-pde-image.dep
include $(PLATFORM_PATH)/raw-image.dep
include $(PLATFORM_PATH)/one-aboot.dep
include $(PLATFORM_PATH)/libsaithrift-dev.dep
include $(PLATFORM_PATH)/docker-syncd-brcm-dnx.dep
include $(PLATFORM_PATH)/docker-syncd-brcm-dnx-rpc.dep
+include $(PLATFORM_PATH)/../components/docker-gbsyncd-credo.dep
diff --git a/platform/broadcom/rules.mk b/platform/broadcom/rules.mk
index f7fb22a07442..031cd60150b8 100644
--- a/platform/broadcom/rules.mk
+++ b/platform/broadcom/rules.mk
@@ -17,12 +17,17 @@ include $(PLATFORM_PATH)/platform-modules-ragile.mk
include $(PLATFORM_PATH)/docker-syncd-brcm.mk
include $(PLATFORM_PATH)/docker-syncd-brcm-rpc.mk
include $(PLATFORM_PATH)/docker-saiserver-brcm.mk
+ifeq ($(INCLUDE_PDE), y)
+include $(PLATFORM_PATH)/docker-pde.mk
+include $(PLATFORM_PATH)/sonic-pde-tests.mk
+endif
include $(PLATFORM_PATH)/one-image.mk
include $(PLATFORM_PATH)/raw-image.mk
include $(PLATFORM_PATH)/one-aboot.mk
include $(PLATFORM_PATH)/libsaithrift-dev.mk
include $(PLATFORM_PATH)/docker-syncd-brcm-dnx.mk
include $(PLATFORM_PATH)/docker-syncd-brcm-dnx-rpc.mk
+include $(PLATFORM_PATH)/../components/docker-gbsyncd-credo.mk
BCMCMD = bcmcmd
$(BCMCMD)_URL = "https://sonicstorage.blob.core.windows.net/packages/20190307/bcmcmd?sv=2015-04-05&sr=b&sig=sUdbU7oVbh5exbXXHVL5TDFBTWDDBASHeJ8Cp0B0TIc%3D&se=2038-05-06T22%3A34%3A19Z&sp=r"
diff --git a/platform/broadcom/sai-modules.mk b/platform/broadcom/sai-modules.mk
index 0a21aa503670..cb33b9b46ffe 100644
--- a/platform/broadcom/sai-modules.mk
+++ b/platform/broadcom/sai-modules.mk
@@ -1,6 +1,6 @@
# Broadcom SAI modules
-BRCM_OPENNSL_KERNEL_VERSION = 5.0.0.1
+BRCM_OPENNSL_KERNEL_VERSION = 5.0.0.4
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 = 5.0.0.1
+BRCM_DNX_OPENNSL_KERNEL_VERSION = 5.0.0.4
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 065aca8291e5..e4f36385a83a 100644
--- a/platform/broadcom/sai.mk
+++ b/platform/broadcom/sai.mk
@@ -1,12 +1,12 @@
-BRCM_SAI = libsaibcm_5.0.0.1_amd64.deb
-$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/5.0/master/libsaibcm_5.0.0.1_amd64.deb?sv=2015-04-05&sr=b&sig=FXHu5ggw8zfUdvi0UScTHMAP0X3br0vTM4f2U2brQWo%3D&se=2029-08-15T01%3A20%3A19Z&sp=r"
-BRCM_SAI_DEV = libsaibcm-dev_5.0.0.1_amd64.deb
+BRCM_SAI = libsaibcm_5.0.0.6-1_amd64.deb
+$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/5.0/master/libsaibcm_5.0.0.6-1_amd64.deb?sv=2015-04-05&sr=b&sig=HA%2FwgMr%2BHnb6zzFCQDfO1WF%2Bf6PBSmIzH13728LTNz4%3D&se=2035-03-31T20%3A45%3A36Z&sp=r"
+BRCM_SAI_DEV = libsaibcm-dev_5.0.0.6-1_amd64.deb
$(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV)))
-$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/5.0/master/libsaibcm-dev_5.0.0.1_amd64.deb?sv=2015-04-05&sr=b&sig=C48%2BIViiA5KAq4ubDkXSehylTQgiIc7ZD47eo4roBYI%3D&se=2029-08-15T01%3A21%3A14Z&sp=r"
+$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/5.0/master/libsaibcm-dev_5.0.0.6-1_amd64.deb?sv=2015-04-05&sr=b&sig=z634%2BUk14EY5VjEE4tjhvDSP2hiK8s1EJAxjvidl44I%3D&se=2035-03-31T20%3A46%3A17Z&sp=r"
# SAI module for DNX Asic family
-BRCM_DNX_SAI = libsaibcm_dnx_5.0.0.1_amd64.deb
-$(BRCM_DNX_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/5.0/master/libsaibcm_dnx_5.0.0.1_amd64.deb?sv=2015-04-05&sr=b&sig=iUW4ZSz43oeOSe21%2BFaNTG1phTr6qgAfeeEN2mCXBWU%3D&se=2035-01-17T05%3A15%3A51Z&sp=r"
+BRCM_DNX_SAI = libsaibcm_dnx_5.0.0.6-1_amd64.deb
+$(BRCM_DNX_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/5.0/master/libsaibcm_dnx_5.0.0.6-1_amd64.deb?sv=2015-04-05&sr=b&sig=mDcpzWUcTSzNBM6vPPYNuMQ6D%2BTKQAC9k%2Fv0%2Bnz3L%2BM%3D&se=2035-03-31T20%3A46%3A44Z&sp=r"
SONIC_ONLINE_DEBS += $(BRCM_SAI)
SONIC_ONLINE_DEBS += $(BRCM_DNX_SAI)
diff --git a/platform/broadcom/saibcm-modules-dnx b/platform/broadcom/saibcm-modules-dnx
index c2359f831c28..70d0ce29b1cf 160000
--- a/platform/broadcom/saibcm-modules-dnx
+++ b/platform/broadcom/saibcm-modules-dnx
@@ -1 +1 @@
-Subproject commit c2359f831c285aa2dca221bf271b9c93607651da
+Subproject commit 70d0ce29b1cffce381b55e263649a18e9219f13b
diff --git a/platform/broadcom/saibcm-modules/debian/changelog b/platform/broadcom/saibcm-modules/debian/changelog
index 65d514931992..58468e30e799 100644
--- a/platform/broadcom/saibcm-modules/debian/changelog
+++ b/platform/broadcom/saibcm-modules/debian/changelog
@@ -1,3 +1,9 @@
+opennsl (5.0.0.4) unstable; urgency=medium
+
+ * Update to Broadcom SAI 5.0.0.4
+
+ -- Judy Joseph Fri, 12 July 2021 18:36:38 +0000
+
opennsl (5.0.0.1) unstable; urgency=medium
* Update to Broadcom SAI 5.0.0.1
diff --git a/platform/broadcom/saibcm-modules/make/Make.config b/platform/broadcom/saibcm-modules/make/Make.config
index 17c4c7f66fc3..f5b04b0cdf9e 100644
--- a/platform/broadcom/saibcm-modules/make/Make.config
+++ b/platform/broadcom/saibcm-modules/make/Make.config
@@ -172,7 +172,7 @@ CFLAGS += ${INCFLAGS}
CXXFLAGS += ${INCFLAGS}
CPPFLAGS += ${INCFLAGS}
-CFLAGS += -DSAI_FIXUP -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=1024
+CFLAGS += -DSAI_FIXUP -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=1025 -UKCOM_NETIF_MAX -DKCOM_NETIF_MAX=1056
# Flag to enable multi instance support
CFLAGS += -DBCM_INSTANCE_SUPPORT
diff --git a/platform/broadcom/sonic-pde-tests.dep b/platform/broadcom/sonic-pde-tests.dep
new file mode 100644
index 000000000000..2aaef7dc23f6
--- /dev/null
+++ b/platform/broadcom/sonic-pde-tests.dep
@@ -0,0 +1,10 @@
+SPATH := $($(SONIC_PLATFORM_PDE)_SRC_PATH)
+DEP_FILES := $(SONIC_COMMON_FILES_LIST) platform/broadcom/sonic-pde-tests.mk platform/broadcom/sonic-pde-tests.dep
+DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
+SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files))
+
+$(SONIC_PLATFORM_PDE)_CACHE_MODE := GIT_CONTENT_SHA
+$(SONIC_PLATFORM_PDE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
+$(SONIC_PLATFORM_PDE)_DEP_FILES := $(DEP_FILES)
+$(SONIC_PLATFORM_PDE)_SMDEP_FILES := $(SMDEP_FILES)
+$(SONIC_PLATFORM_PDE)_SMDEP_PATHS := $(SPATH)
diff --git a/platform/broadcom/sonic-pde-tests.mk b/platform/broadcom/sonic-pde-tests.mk
new file mode 100644
index 000000000000..a7482625c87e
--- /dev/null
+++ b/platform/broadcom/sonic-pde-tests.mk
@@ -0,0 +1,7 @@
+# sonic pde package
+
+SONIC_PLATFORM_PDE = sonic-platform-pde_1.0_amd64.deb
+$(SONIC_PLATFORM_PDE)_SRC_PATH = $(SRC_PATH)/sonic-platform-pde
+$(SONIC_PLATFORM_PDE)_DEPENDS += $(BRCM_SAI) $(BRCM_SAI_DEV) $(SWIG)
+
+SONIC_DPKG_DEBS += $(SONIC_PLATFORM_PDE)
diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-psu.c b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-psu.c
index 798a5656410e..3d197210e35f 100755
--- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-psu.c
+++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/modules/x86-64-accton-as4630-54pe-psu.c
@@ -35,7 +35,7 @@
#include
#define MAX_MODEL_NAME 20
-#define MAX_SERIAL_NUMBER 18
+#define MAX_SERIAL_NUMBER 19
static ssize_t show_status(struct device *dev, struct device_attribute *da, char *buf);
static ssize_t show_string(struct device *dev, struct device_attribute *da, char *buf);
@@ -90,8 +90,7 @@ static ssize_t show_status(struct device *dev, struct device_attribute *da,
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct as4630_54pe_psu_data *data = as4630_54pe_psu_update_device(dev);
u8 status = 0;
-
- //printk("data->status=0x%x, attr->index=%d,data->index=%d \n", data->status, attr->index, data->index);
+
if (attr->index == PSU_PRESENT) {
if(data->index==0)
status = !( (data->status >> 5) & 0x1);
@@ -267,7 +266,6 @@ static struct as4630_54pe_psu_data *as4630_54pe_psu_update_device(struct device
/* Read psu status */
status = as4630_54pe_cpld_read(0x60, 0x22);
- //printk("status=0x%x in %s\n", status, __FUNCTION__);
if (status < 0) {
dev_dbg(&client->dev, "cpld reg 0x60 err %d\n", status);
}
@@ -286,21 +284,36 @@ static struct as4630_54pe_psu_data *as4630_54pe_psu_update_device(struct device
if (status < 0) {
data->model_name[0] = '\0';
dev_dbg(&client->dev, "unable to read model name from (0x%x)\n", client->addr);
- printk("unable to read model name from (0x%x)\n", client->addr);
}
- else {
+ else if(!strncmp(data->model_name, "YPEB1200", strlen("YPEB1200")))
+ {
+ if (data->model_name[9]=='A' && data->model_name[10]=='M')
+ {
+ data->model_name[8]='A';
+ data->model_name[9]='M';
+ data->model_name[strlen("YPEB1200AM")]='\0';
+ }
+ else
+ data->model_name[strlen("YPEB1200")]='\0';
+ }
+ else
+ {
data->model_name[ARRAY_SIZE(data->model_name)-1] = '\0';
-
}
- /* Read from offset 0x2e ~ 0x3d (16 bytes) */
+ /* Read from offset 0x35 ~ 0x46 (18 bytes) */
status = as4630_54pe_psu_read_block(client, 0x35,data->serial_number, MAX_SERIAL_NUMBER);
if (status < 0)
{
data->serial_number[0] = '\0';
- dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x2e)\n", client->addr);
- printk("unable to read model name from (0x%x) offset(0x2e)\n", client->addr);
+ dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x35)\n", client->addr);
+ }
+ if (!strncmp(data->model_name, "YPEB1200AM", strlen("YPEB1200AM"))) /*for YPEB1200AM, SN length=18*/
+ {
+ data->serial_number[MAX_SERIAL_NUMBER-1]='\0';
}
- data->serial_number[MAX_SERIAL_NUMBER-1]='\0';
+ else
+ data->serial_number[MAX_SERIAL_NUMBER-2]='\0';
+
}
data->last_updated = jiffies;
diff --git a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py
index 4039119288a0..80dfd497c2d9 100755
--- a/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py
+++ b/platform/broadcom/sonic-platform-modules-accton/as4630-54pe/utils/accton_as4630_54pe_util.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2016 Accton Networks, Inc.
#
@@ -24,16 +24,11 @@
command:
install : install drivers and generate related sysfs nodes
clean : uninstall drivers and remove related sysfs nodes
- show : show all systen status
- sff : dump SFP eeprom
- set : change board setting with fan|led|sfp
"""
-
-import commands
+import subprocess
import getopt
import sys
import logging
-import re
import time
PROJECT_NAME = 'as4630_54pe'
@@ -42,34 +37,9 @@
DEBUG = False
args = []
ALL_DEVICE = {}
-DEVICE_NO = {'led':5, 'fan1':1, 'fan2':1,'fan3':1,'fan4':1,'fan5':1,'thermal':3, 'psu':2, 'sfp':54}
-
-
-led_prefix ='/sys/devices/platform/as4630_54pe_led/leds/accton_'+PROJECT_NAME+'_led::'
-fan_prefix ='/sys/devices/platform/as4630_54pe_'
-hwmon_types = {'led': ['diag','fan','loc','psu1','psu2'],
- 'fan1': ['fan'],
- 'fan2': ['fan'],
- 'fan3': ['fan'],
- 'fan4': ['fan'],
- 'fan5': ['fan'],
- }
-hwmon_nodes = {'led': ['brightness'] ,
- 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'],
- 'fan2': ['fan_duty_cycle_percentage','fan2_fault', 'fan2_speed_rpm', 'fan2_direction', 'fanr2_fault', 'fanr2_speed_rpm'],
- 'fan3': ['fan_duty_cycle_percentage','fan3_fault', 'fan3_speed_rpm', 'fan3_direction', 'fanr3_fault', 'fanr3_speed_rpm'],
- 'fan4': ['fan4_duty_cycle_percentage','fan4_fault', 'fan4_speed_rpm', 'fan4_direction', 'fanr4_fault', 'fanr4_speed_rpm'],
- 'fan5': ['fan_duty_cycle_percentage','fan5_fault', 'fan5_speed_rpm', 'fan5_direction', 'fanr5_fault', 'fanr5_speed_rpm'],
- }
-hwmon_prefix ={'led': led_prefix,
- 'fan1': fan_prefix,
- 'fan2': fan_prefix,
- 'fan3': fan_prefix,
- 'fan4': fan_prefix,
- 'fan5': fan_prefix,
- }
i2c_prefix = '/sys/bus/i2c/devices/'
+'''
i2c_bus = {'fan': ['54-0066'],
'thermal': ['54-004c', '55-0048','55-0049', '55-004a', '55-004b'] ,
'psu': ['49-0050','50-0053'],
@@ -78,7 +48,7 @@
'thermal': ['hwmon/hwmon*/temp1_input'] ,
'psu': ['psu_present ', 'psu_power_good'] ,
'sfp': ['module_present_ ', 'module_tx_disable_']}
-
+'''
sfp_map = [18, 19, 20, 21, 22, 23]
mknod =[
@@ -118,8 +88,8 @@
if DEBUG == True:
- print sys.argv[0]
- print 'ARGV :', sys.argv[1:]
+ print(sys.argv[0])
+ print('ARGV :', sys.argv[1:])
def main():
@@ -135,9 +105,9 @@ def main():
'force',
])
if DEBUG == True:
- print options
- print args
- print len(sys.argv)
+ print(options)
+ print(args)
+ print(len(sys.argv))
for opt, arg in options:
if opt in ('-h', '--help'):
@@ -148,29 +118,13 @@ def main():
elif opt in ('-f', '--force'):
FORCE = 1
else:
- print "TEST"
+ print("TEST")
logging.info('no option')
for arg in args:
if arg == 'install':
do_install()
elif arg == 'clean':
- do_uninstall()
- elif arg == 'show':
- device_traversal()
- elif arg == 'sff':
- if len(args)!=2:
- show_eeprom_help()
- elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']:
- show_eeprom_help()
- else:
- show_eeprom(args[1])
- return
- elif arg == 'set':
- if len(args)<3:
- show_set_help()
- else:
- set_device(args[1:])
- return
+ do_uninstall()
else:
show_help()
@@ -178,35 +132,22 @@ def main():
return 0
def show_help():
- print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}
- sys.exit(0)
-
-def show_set_help():
- cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
- print cmd +" [led|sfp|fan]"
- print " use \""+ cmd + " led 0-4 \" to set led color"
- print " use \""+ cmd + " fan 0-100\" to set fan duty percetage"
- print " use \""+ cmd + " sfp 1-32 {0|1}\" to set sfp# tx_disable"
- sys.exit(0)
-
-def show_eeprom_help():
- cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
- print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom"
+ print( __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]})
sys.exit(0)
def my_log(txt):
if DEBUG == True:
- print "[ACCTON DBG]: "+txt
+ print("[ACCTON DBG]: ",txt)
return
def log_os_system(cmd, show):
logging.info('Run :'+cmd)
status = 1
output = ""
- status, output = commands.getstatusoutput(cmd)
- my_log (cmd +"with result:" + str(status))
- my_log ("cmd:" + cmd)
- my_log (" output:"+output)
+ status, output = subprocess.getstatusoutput(cmd)
+ my_log (cmd +" with result:" + str(status))
+ #my_log ("cmd:" + cmd)
+ #my_log (" output:"+output)
if status:
logging.info('Failed :'+cmd)
if show:
@@ -252,6 +193,8 @@ def driver_install():
if FORCE == 0:
return status
+ print("Done driver_install")
+
return 0
def driver_uninstall():
@@ -259,7 +202,7 @@ def driver_uninstall():
for i in range(0,len(kos)):
rm = kos[-(i+1)].replace("modprobe", "modprobe -rq")
lst = rm.split(" ")
- print "lst=%s"%lst
+
if len(lst) > 3:
del(lst[3])
rm = " ".join(lst)
@@ -279,10 +222,10 @@ def device_install():
status, output = log_os_system(mknod[i], 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
- print("Check SFP")
+
for i in range(0,len(sfp_map)):
if(i < 4):
opt='optoe2'
@@ -290,16 +233,18 @@ def device_install():
opt='optoe1'
status, output =log_os_system("echo " + str(opt) + " 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
status, output =log_os_system("echo port"+str(i+49) + " > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-0050/port_name", 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
-
+
+ print("Done device_install")
+
return
def device_uninstall():
@@ -315,7 +260,7 @@ def device_uninstall():
target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
status, output =log_os_system("echo 0x50 > "+ target, 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
@@ -328,7 +273,7 @@ def device_uninstall():
temp[-1] = temp[-1].replace('new_device', 'delete_device')
status, output = log_os_system(" ".join(temp), 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
@@ -338,7 +283,7 @@ def system_ready():
if driver_inserted() == False:
return False
if not device_exist():
- print "not device_exist()"
+ print("not device_exist()")
return False
return True
@@ -349,14 +294,14 @@ def do_install():
if FORCE == 0:
return status
else:
- print PROJECT_NAME.upper()+" drivers detected...."
+ print(PROJECT_NAME.upper()+" drivers detected....")
if not device_exist():
status = device_install()
if status:
if FORCE == 0:
return status
else:
- print PROJECT_NAME.upper()+" devices detected...."
+ print(PROJECT_NAME.upper()+" devices detected....")
for i in range(len(cpld_set)):
status, output = log_os_system(cpld_set[i], 1)
@@ -367,18 +312,18 @@ def do_install():
def do_uninstall():
if not device_exist():
- print PROJECT_NAME.upper() +" has no device installed...."
+ print(PROJECT_NAME.upper()+" has no device installed....")
else:
- print "Removing device...."
+ print("Removing device....")
status = device_uninstall()
if status:
if FORCE == 0:
return status
if driver_inserted()== False :
- print PROJECT_NAME.upper() +" has no driver installed...."
+ print(PROJECT_NAME.upper()+" has no driver installed....")
else:
- print "Removing installed driver...."
+ print("Removing installed driver....")
status = driver_uninstall()
if status:
if FORCE == 0:
@@ -386,184 +331,6 @@ def do_uninstall():
return
-def devices_info():
- global DEVICE_NO
- global ALL_DEVICE
- global i2c_bus, hwmon_types
- for key in DEVICE_NO:
- ALL_DEVICE[key]= {}
- for i in range(0,DEVICE_NO[key]):
- ALL_DEVICE[key][key+str(i+1)] = []
-
- for key in i2c_bus:
- buses = i2c_bus[key]
- nodes = i2c_nodes[key]
- for i in range(0,len(buses)):
- for j in range(0,len(nodes)):
- if 'fan' == key:
- for k in range(0,DEVICE_NO[key]):
- node = key+str(k+1)
- path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
- elif 'sfp' == key:
- for k in range(0,DEVICE_NO[key]):
- node = key+str(k+1)
- path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
- else:
- node = key+str(i+1)
- path = i2c_prefix+ buses[i]+"/"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
-
- for key in hwmon_types:
- itypes = hwmon_types[key]
- nodes = hwmon_nodes[key]
- for i in range(0,len(itypes)):
- for j in range(0,len(nodes)):
- node = key+"_"+itypes[i]
- path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][ key+str(i+1)].append(path)
-
- #show dict all in the order
- if DEBUG == True:
- for i in sorted(ALL_DEVICE.keys()):
- print(i+": ")
- for j in sorted(ALL_DEVICE[i].keys()):
- print(" "+j)
- for k in (ALL_DEVICE[i][j]):
- print(" "+" "+k)
- return
-
-def show_eeprom(index):
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- if len(ALL_DEVICE)==0:
- devices_info()
- node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
- node = node.replace(node.split("/")[-1], 'eeprom')
- # check if got hexdump command in current environment
- ret, log = log_os_system("which hexdump", 0)
- ret, log2 = log_os_system("which busybox hexdump", 0)
- if len(log):
- hex_cmd = 'hexdump'
- elif len(log2):
- hex_cmd = ' busybox hexdump'
- else:
- log = 'Failed : no hexdump cmd!!'
- logging.info(log)
- print log
- return 1
- print "node=%s"%node
- print node + ":"
- ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1)
- if ret==0:
- print log
- else:
- print "**********device no found**********"
- return
-
-def set_device(args):
- global DEVICE_NO
- global ALL_DEVICE
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- if len(ALL_DEVICE)==0:
- devices_info()
-
- if args[0]=='led':
- if int(args[1])>4:
- show_set_help()
- return
- #print ALL_DEVICE['led']
- for i in range(0,len(ALL_DEVICE['led'])):
- for k in (ALL_DEVICE['led']['led'+str(i+1)]):
- ret, log = log_os_system("echo "+args[1]+" >"+k, 1)
- if ret:
- return ret
- elif args[0]=='fan':
- if int(args[1])>100:
- show_set_help()
- return
- #print ALL_DEVICE['fan']
- #fan1~6 is all fine, all fan share same setting
- node = ALL_DEVICE['fan1'] ['fan11'][0]
- node = node.replace(node.split("/")[-1], 'fan1_duty_cycle_percentage')
- ret, log = log_os_system("cat "+ node, 1)
- if ret==0:
- print ("Previous fan duty: " + log.strip() +"%")
- ret, log = log_os_system("echo "+args[1]+" >"+node, 1)
- if ret==0:
- print ("Current fan duty: " + args[1] +"%")
- return ret
- elif args[0]=='sfp':
- if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
- show_set_help()
- return
- if len(args)<2:
- show_set_help()
- return
-
- if int(args[2])>1:
- show_set_help()
- return
-
- #print ALL_DEVICE[args[0]]
- for i in range(0,len(ALL_DEVICE[args[0]])):
- for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
- if j.find('tx_disable')!= -1:
- ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
- if ret:
- return ret
-
- return
-
-#get digits inside a string.
-#Ex: 31 for "sfp31"
-def get_value(input):
- digit = re.findall('\d+', input)
- return int(digit[0])
-
-def device_traversal():
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- if len(ALL_DEVICE)==0:
- devices_info()
- for i in sorted(ALL_DEVICE.keys()):
- print("============================================")
- print(i.upper()+": ")
- print("============================================")
-
- for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
- print " "+j+":",
- for k in (ALL_DEVICE[i][j]):
- ret, log = log_os_system("cat "+k, 0)
- func = k.split("/")[-1].strip()
- func = re.sub(j+'_','',func,1)
- func = re.sub(i.lower()+'_','',func,1)
- if ret==0:
- print func+"="+log+" ",
- else:
- print func+"="+"X"+" ",
- print
- print("----------------------------------------------------------------")
-
-
- print
- return
-
def device_exist():
ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0)
ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0)
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/sonic_platform/chassis.py
index 99fb3b569a2c..feb1fbdb5620 100644
--- a/platform/broadcom/sonic-platform-modules-accton/as7326-56x/sonic_platform/chassis.py
+++ b/platform/broadcom/sonic-platform-modules-accton/as7326-56x/sonic_platform/chassis.py
@@ -7,6 +7,7 @@
#############################################################################
try:
+ import sys
import time
from sonic_platform_pddf_base.pddf_chassis import PddfChassis
except ImportError as e:
@@ -38,7 +39,7 @@ def get_change_event(self, timeout=2000):
bitmap = 0
for i in range(58):
- modpres = self.get_sfp(i).get_presence()
+ modpres = self.get_sfp(i+1).get_presence()
if modpres:
bitmap = bitmap | (1 << i)
@@ -59,3 +60,26 @@ def get_change_event(self, timeout=2000):
return True, change_dict
else:
return True, change_dict
+
+ def get_sfp(self, index):
+ """
+ Retrieves sfp represented by (1-based) index
+
+ Args:
+ index: An integer, the index (1-based) of the sfp to retrieve.
+ The index should be the sequence of a physical port in a chassis,
+ starting from 1.
+ For example, 1 for Ethernet0, 2 for Ethernet4 and so on.
+
+ Returns:
+ An object derived from SfpBase representing the specified sfp
+ """
+ sfp = None
+
+ try:
+ # The index will start from 1
+ sfp = self._sfp_list[index-1]
+ except IndexError:
+ sys.stderr.write("SFP index {} out of range (1-{})\n".format(
+ index, len(self._sfp_list)))
+ return sfp
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/sonic_platform/chassis.py
index 713cf6831ac0..8ff20a760562 100644
--- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/sonic_platform/chassis.py
+++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/sonic_platform/chassis.py
@@ -7,6 +7,7 @@
#############################################################################
try:
+ import sys
import time
from sonic_platform_pddf_base.pddf_chassis import PddfChassis
except ImportError as e:
@@ -38,7 +39,7 @@ def get_change_event(self, timeout=2000):
bitmap = 0
for i in range(34):
- modpres = self.get_sfp(i).get_presence()
+ modpres = self.get_sfp(i+1).get_presence()
if modpres:
bitmap = bitmap | (1 << i)
@@ -59,3 +60,27 @@ def get_change_event(self, timeout=2000):
return True, change_dict
else:
return True, change_dict
+
+
+ def get_sfp(self, index):
+ """
+ Retrieves sfp represented by (1-based) index
+
+ Args:
+ index: An integer, the index (1-based) of the sfp to retrieve.
+ The index should be the sequence of a physical port in a chassis,
+ starting from 1.
+ For example, 1 for Ethernet0, 2 for Ethernet4 and so on.
+
+ Returns:
+ An object derived from SfpBase representing the specified sfp
+ """
+ sfp = None
+
+ try:
+ # The index will start from 1
+ sfp = self._sfp_list[index-1]
+ except IndexError:
+ sys.stderr.write("SFP index {} out of range (1-{})\n".format(
+ index, len(self._sfp_list)))
+ return sfp
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py
index a6aa855174be..b6d3c02935e0 100755
--- a/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py
+++ b/platform/broadcom/sonic-platform-modules-accton/as7726-32x/utils/accton_as7726_32x_util.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2016 Accton Networks, Inc.
#
@@ -25,12 +25,8 @@
command:
install : install drivers and generate related sysfs nodes
clean : uninstall drivers and remove related sysfs nodes
- show : show all systen status
- sff : dump SFP eeprom
- set : change board setting with fan|led|sfp
"""
-
-import commands
+import subprocess
import getopt
import sys
import logging
@@ -43,34 +39,9 @@
DEBUG = False
args = []
ALL_DEVICE = {}
-DEVICE_NO = {'led':5, 'fan1':1, 'fan2':1,'fan3':1,'fan4':1,'fan5':1,'thermal':3, 'psu':2, 'sfp':54}
-
-
-led_prefix ='/sys/devices/platform/as7716_32x_led/leds/accton_'+PROJECT_NAME+'_led::'
-fan_prefix ='/sys/devices/platform/as7716_32x_'
-hwmon_types = {'led': ['diag','fan','loc','psu1','psu2'],
- 'fan1': ['fan'],
- 'fan2': ['fan'],
- 'fan3': ['fan'],
- 'fan4': ['fan'],
- 'fan5': ['fan'],
- }
-hwmon_nodes = {'led': ['brightness'] ,
- 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'],
- 'fan2': ['fan_duty_cycle_percentage','fan2_fault', 'fan2_speed_rpm', 'fan2_direction', 'fanr2_fault', 'fanr2_speed_rpm'],
- 'fan3': ['fan_duty_cycle_percentage','fan3_fault', 'fan3_speed_rpm', 'fan3_direction', 'fanr3_fault', 'fanr3_speed_rpm'],
- 'fan4': ['fan4_duty_cycle_percentage','fan4_fault', 'fan4_speed_rpm', 'fan4_direction', 'fanr4_fault', 'fanr4_speed_rpm'],
- 'fan5': ['fan_duty_cycle_percentage','fan5_fault', 'fan5_speed_rpm', 'fan5_direction', 'fanr5_fault', 'fanr5_speed_rpm'],
- }
-hwmon_prefix ={'led': led_prefix,
- 'fan1': fan_prefix,
- 'fan2': fan_prefix,
- 'fan3': fan_prefix,
- 'fan4': fan_prefix,
- 'fan5': fan_prefix,
- }
i2c_prefix = '/sys/bus/i2c/devices/'
+'''
i2c_bus = {'fan': ['54-0066'],
'thermal': ['54-004c', '55-0048','55-0049', '55-004a', '55-004b'] ,
'psu': ['49-0050','50-0053'],
@@ -79,7 +50,7 @@
'thermal': ['hwmon/hwmon*/temp1_input'] ,
'psu': ['psu_present ', 'psu_power_good'] ,
'sfp': ['module_present_ ', 'module_tx_disable_']}
-
+'''
sfp_map = [21, 22, 23, 24, 26, 25, 28, 27,
17, 18, 19, 20, 29, 30, 31, 32,
33, 34, 35, 36, 45, 46, 47, 48,
@@ -129,8 +100,8 @@
if DEBUG == True:
- print sys.argv[0]
- print 'ARGV :', sys.argv[1:]
+ print(sys.argv[0])
+ print('ARGV :', sys.argv[1:])
def main():
@@ -146,9 +117,9 @@ def main():
'force',
])
if DEBUG == True:
- print options
- print args
- print len(sys.argv)
+ print(options)
+ print(args)
+ print(len(sys.argv))
for opt, arg in options:
if opt in ('-h', '--help'):
@@ -165,22 +136,6 @@ def main():
do_install()
elif arg == 'clean':
do_uninstall()
- elif arg == 'show':
- device_traversal()
- elif arg == 'sff':
- if len(args)!=2:
- show_eeprom_help()
- elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']:
- show_eeprom_help()
- else:
- show_eeprom(args[1])
- return
- elif arg == 'set':
- if len(args)<3:
- show_set_help()
- else:
- set_device(args[1:])
- return
else:
show_help()
@@ -188,33 +143,20 @@ def main():
return 0
def show_help():
- print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}
- sys.exit(0)
-
-def show_set_help():
- cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
- print cmd +" [led|sfp|fan]"
- print " use \""+ cmd + " led 0-4 \" to set led color"
- print " use \""+ cmd + " fan 0-100\" to set fan duty percetage"
- print " use \""+ cmd + " sfp 1-32 {0|1}\" to set sfp# tx_disable"
- sys.exit(0)
-
-def show_eeprom_help():
- cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
- print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom"
+ print( __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]})
sys.exit(0)
def dis_i2c_ir3570a(addr):
cmd = "i2cset -y 0 0x%x 0xE5 0x01" % addr
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
cmd = "i2cset -y 0 0x%x 0x12 0x02" % addr
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
return status
def ir3570_check():
cmd = "i2cdump -y 0 0x42 s 0x9a"
try:
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
lines = output.split('\n')
hn = re.findall(r'\w+', lines[-1])
version = int(hn[1], 16)
@@ -223,24 +165,24 @@ def ir3570_check():
else:
ret = 0
except Exception as e:
- print "Error on ir3570_check() e:" + str(e)
+ print( "Error on ir3570_check() e:" + str(e))
return -1
return ret
def my_log(txt):
if DEBUG == True:
- print "[ACCTON DBG]: "+txt
+ print("[ACCTON DBG]: ",txt)
return
def log_os_system(cmd, show):
logging.info('Run :'+cmd)
status = 1
output = ""
- status, output = commands.getstatusoutput(cmd)
- my_log (cmd +"with result:" + str(status))
- my_log ("cmd:" + cmd)
- my_log (" output:"+output)
+ status, output = subprocess.getstatusoutput(cmd)
+ my_log (cmd +" with result:" + str(status))
+ #my_log ("cmd:" + cmd)
+ #my_log (" output:"+output)
if status:
logging.info('Failed :'+cmd)
if show:
@@ -285,6 +227,8 @@ def driver_install():
if status:
if FORCE == 0:
return status
+
+ print("Done driver_install")
#status=cpld_reset_mac()
return 0
@@ -294,7 +238,7 @@ def driver_uninstall():
for i in range(0,len(kos)):
rm = kos[-(i+1)].replace("modprobe", "modprobe -rq")
lst = rm.split(" ")
- print "lst=%s"%lst
+
if len(lst) > 3:
del(lst[3])
rm = " ".join(lst)
@@ -314,21 +258,24 @@ def device_install():
status, output = log_os_system(mknod[i], 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
-
+
for i in range(0,len(sfp_map)):
status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
status, output =log_os_system("echo port"+str(i)+" > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-0050/port_name", 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
+
+ print("Done device_install")
+
return
def device_uninstall():
@@ -344,7 +291,7 @@ def device_uninstall():
target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
status, output =log_os_system("echo 0x50 > "+ target, 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
@@ -357,7 +304,7 @@ def device_uninstall():
temp[-1] = temp[-1].replace('new_device', 'delete_device')
status, output = log_os_system(" ".join(temp), 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
@@ -367,7 +314,7 @@ def system_ready():
if driver_inserted() == False:
return False
if not device_exist():
- print "not device_exist()"
+ print("not device_exist()")
return False
return True
@@ -378,7 +325,7 @@ def do_install():
if FORCE == 0:
return status
else:
- print PROJECT_NAME.upper()+" drivers detected...."
+ print(PROJECT_NAME.upper()+" drivers detected....")
ir3570_check()
@@ -388,23 +335,23 @@ def do_install():
if FORCE == 0:
return status
else:
- print PROJECT_NAME.upper()+" devices detected...."
+ print(PROJECT_NAME.upper()+" devices detected....")
return
def do_uninstall():
if not device_exist():
- print PROJECT_NAME.upper() +" has no device installed...."
+ print(PROJECT_NAME.upper()+" has no device installed....")
else:
- print "Removing device...."
+ print("Removing device....")
status = device_uninstall()
if status:
if FORCE == 0:
return status
if driver_inserted()== False :
- print PROJECT_NAME.upper() +" has no driver installed...."
+ print(PROJECT_NAME.upper()+" has no driver installed....")
else:
- print "Removing installed driver...."
+ print("Removing installed driver....")
status = driver_uninstall()
if status:
if FORCE == 0:
@@ -412,184 +359,6 @@ def do_uninstall():
return
-def devices_info():
- global DEVICE_NO
- global ALL_DEVICE
- global i2c_bus, hwmon_types
- for key in DEVICE_NO:
- ALL_DEVICE[key]= {}
- for i in range(0,DEVICE_NO[key]):
- ALL_DEVICE[key][key+str(i+1)] = []
-
- for key in i2c_bus:
- buses = i2c_bus[key]
- nodes = i2c_nodes[key]
- for i in range(0,len(buses)):
- for j in range(0,len(nodes)):
- if 'fan' == key:
- for k in range(0,DEVICE_NO[key]):
- node = key+str(k+1)
- path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
- elif 'sfp' == key:
- for k in range(0,DEVICE_NO[key]):
- node = key+str(k+1)
- path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
- else:
- node = key+str(i+1)
- path = i2c_prefix+ buses[i]+"/"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
-
- for key in hwmon_types:
- itypes = hwmon_types[key]
- nodes = hwmon_nodes[key]
- for i in range(0,len(itypes)):
- for j in range(0,len(nodes)):
- node = key+"_"+itypes[i]
- path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][ key+str(i+1)].append(path)
-
- #show dict all in the order
- if DEBUG == True:
- for i in sorted(ALL_DEVICE.keys()):
- print(i+": ")
- for j in sorted(ALL_DEVICE[i].keys()):
- print(" "+j)
- for k in (ALL_DEVICE[i][j]):
- print(" "+" "+k)
- return
-
-def show_eeprom(index):
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- if len(ALL_DEVICE)==0:
- devices_info()
- node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
- node = node.replace(node.split("/")[-1], 'eeprom')
- # check if got hexdump command in current environment
- ret, log = log_os_system("which hexdump", 0)
- ret, log2 = log_os_system("which busybox hexdump", 0)
- if len(log):
- hex_cmd = 'hexdump'
- elif len(log2):
- hex_cmd = ' busybox hexdump'
- else:
- log = 'Failed : no hexdump cmd!!'
- logging.info(log)
- print log
- return 1
- print "node=%s"%node
- print node + ":"
- ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1)
- if ret==0:
- print log
- else:
- print "**********device no found**********"
- return
-
-def set_device(args):
- global DEVICE_NO
- global ALL_DEVICE
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- if len(ALL_DEVICE)==0:
- devices_info()
-
- if args[0]=='led':
- if int(args[1])>4:
- show_set_help()
- return
- #print ALL_DEVICE['led']
- for i in range(0,len(ALL_DEVICE['led'])):
- for k in (ALL_DEVICE['led']['led'+str(i+1)]):
- ret, log = log_os_system("echo "+args[1]+" >"+k, 1)
- if ret:
- return ret
- elif args[0]=='fan':
- if int(args[1])>100:
- show_set_help()
- return
- #print ALL_DEVICE['fan']
- #fan1~6 is all fine, all fan share same setting
- node = ALL_DEVICE['fan1'] ['fan11'][0]
- node = node.replace(node.split("/")[-1], 'fan1_duty_cycle_percentage')
- ret, log = log_os_system("cat "+ node, 1)
- if ret==0:
- print ("Previous fan duty: " + log.strip() +"%")
- ret, log = log_os_system("echo "+args[1]+" >"+node, 1)
- if ret==0:
- print ("Current fan duty: " + args[1] +"%")
- return ret
- elif args[0]=='sfp':
- if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
- show_set_help()
- return
- if len(args)<2:
- show_set_help()
- return
-
- if int(args[2])>1:
- show_set_help()
- return
-
- #print ALL_DEVICE[args[0]]
- for i in range(0,len(ALL_DEVICE[args[0]])):
- for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
- if j.find('tx_disable')!= -1:
- ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
- if ret:
- return ret
-
- return
-
-#get digits inside a string.
-#Ex: 31 for "sfp31"
-def get_value(input):
- digit = re.findall('\d+', input)
- return int(digit[0])
-
-def device_traversal():
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- if len(ALL_DEVICE)==0:
- devices_info()
- for i in sorted(ALL_DEVICE.keys()):
- print("============================================")
- print(i.upper()+": ")
- print("============================================")
-
- for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
- print " "+j+":",
- for k in (ALL_DEVICE[i][j]):
- ret, log = log_os_system("cat "+k, 0)
- func = k.split("/")[-1].strip()
- func = re.sub(j+'_','',func,1)
- func = re.sub(i.lower()+'_','',func,1)
- if ret==0:
- print func+"="+log+" ",
- else:
- print func+"="+"X"+" ",
- print
- print("----------------------------------------------------------------")
-
-
- print
- return
-
def device_exist():
ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0)
ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0)
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/sonic_platform/chassis.py
index 12c7dbacb16b..c597c0d8bb1c 100644
--- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/sonic_platform/chassis.py
+++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/sonic_platform/chassis.py
@@ -7,6 +7,7 @@
#############################################################################
try:
+ import sys
import time
from sonic_platform_pddf_base.pddf_chassis import PddfChassis
except ImportError as e:
@@ -38,7 +39,7 @@ def get_change_event(self, timeout=2000):
bitmap = 0
for i in range(64):
- modpres = self.get_sfp(i).get_presence()
+ modpres = self.get_sfp(i+1).get_presence()
if modpres:
bitmap = bitmap | (1 << i)
@@ -59,3 +60,27 @@ def get_change_event(self, timeout=2000):
return True, change_dict
else:
return True, change_dict
+
+
+ def get_sfp(self, index):
+ """
+ Retrieves sfp represented by (1-based) index
+
+ Args:
+ index: An integer, the index (1-based) of the sfp to retrieve.
+ The index should be the sequence of a physical port in a chassis,
+ starting from 1.
+ For example, 1 for Ethernet0, 2 for Ethernet4 and so on.
+
+ Returns:
+ An object derived from SfpBase representing the specified sfp
+ """
+ sfp = None
+
+ try:
+ # The index will start from 1
+ sfp = self._sfp_list[index-1]
+ except IndexError:
+ sys.stderr.write("SFP index {} out of range (1-{})\n".format(
+ index, len(self._sfp_list)))
+ return sfp
diff --git a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py
index 3aae150dad5c..0d3a47b8ba76 100755
--- a/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py
+++ b/platform/broadcom/sonic-platform-modules-accton/as7816-64x/utils/accton_as7816_util.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2016 Accton Networks, Inc.
#
@@ -17,25 +17,21 @@
"""
Usage: %(scriptName)s [options] command object
-
options:
-h | --help : this help message
-d | --debug : run with debug mode
- -f | --force : ignore error during installation or clean
+ -f | --force : ignore error during installation or clean
command:
install : install drivers and generate related sysfs nodes
clean : uninstall drivers and remove related sysfs nodes
- show : show all systen status
- sff : dump SFP eeprom
- set : change board setting with fan|led|sfp
"""
-
-import commands
+import subprocess
import getopt
import sys
import logging
import re
import time
+import os
@@ -45,15 +41,15 @@
DEBUG = False
args = []
ALL_DEVICE = {}
-DEVICE_NO = {'led':5, 'fan':4,'thermal':6, 'psu':2, 'sfp':64}
+
FORCE = 0
#logging.basicConfig(filename= PROJECT_NAME+'.log', filemode='w',level=logging.DEBUG)
#logging.basicConfig(level=logging.INFO)
if DEBUG == True:
- print sys.argv[0]
- print 'ARGV :', sys.argv[1:]
+ print(sys.argv[0])
+ print('ARGV :', sys.argv[1:] )
def main():
@@ -68,71 +64,48 @@ def main():
'debug',
'force',
])
- if DEBUG == True:
- print options
- print args
- print len(sys.argv)
-
+ if DEBUG == True:
+ print(options)
+ print(args)
+ print(len(sys.argv))
+
for opt, arg in options:
if opt in ('-h', '--help'):
show_help()
- elif opt in ('-d', '--debug'):
+ elif opt in ('-d', '--debug'):
DEBUG = True
logging.basicConfig(level=logging.INFO)
- elif opt in ('-f', '--force'):
+ elif opt in ('-f', '--force'):
FORCE = 1
else:
- logging.info('no option')
- for arg in args:
+ logging.info('no option')
+ for arg in args:
if arg == 'install':
- do_install()
+ do_install()
elif arg == 'clean':
- do_uninstall()
- elif arg == 'show':
- device_traversal()
- elif arg == 'sff':
- if len(args)!=2:
- show_eeprom_help()
- elif int(args[1]) ==0 or int(args[1]) > DEVICE_NO['sfp']:
- show_eeprom_help()
- else:
- show_eeprom(args[1])
- return
- elif arg == 'set':
- if len(args)<3:
- show_set_help()
- else:
- set_device(args[1:])
- return
+ do_uninstall()
else:
show_help()
-
-
- return 0
-
+
+
+ return 0
+
def show_help():
- print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}
+ print( __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]})
sys.exit(0)
-def show_set_help():
- cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
- print cmd +" [led|sfp|fan]"
- print " use \""+ cmd + " led 0-4 \" to set led color"
- print " use \""+ cmd + " fan 0-100\" to set fan duty percetage"
- print " use \""+ cmd + " sfp 1-64 {0|1}\" to set sfp# tx_disable"
- sys.exit(0)
-
+
def dis_i2c_ir3570a(addr):
cmd = "i2cset -y 0 0x%x 0xE5 0x01" % addr
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
cmd = "i2cset -y 0 0x%x 0x12 0x02" % addr
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
return status
def ir3570_check():
cmd = "i2cdump -y 0 0x42 s 0x9a"
try:
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
lines = output.split('\n')
hn = re.findall(r'\w+', lines[-1])
version = int(hn[1], 16)
@@ -141,23 +114,18 @@ def ir3570_check():
else:
ret = 0
except Exception as e:
- print "Error on ir3570_check() e:" + str(e)
+ print("Error on ir3570_check() e:" + str(e))
return -1
return ret
-def show_eeprom_help():
- cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
- print " use \""+ cmd + " 1-64 \" to dump sfp# eeprom"
- sys.exit(0)
-
def my_log(txt):
if DEBUG == True:
- print "[ROY]"+txt
+ print("[ROY]"+txt)
return
def log_os_system(cmd, show):
logging.info('Run :'+cmd)
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
my_log (cmd +"with result:" + str(status))
my_log (" output:"+output)
if status:
@@ -195,6 +163,9 @@ def driver_install():
if status:
if FORCE == 0:
return status
+
+ print("Done driver_install")
+
return 0
def driver_uninstall():
@@ -216,12 +187,9 @@ def driver_uninstall():
return status
return 0
-led_prefix ='/sys/class/leds/'+PROJECT_NAME+'_led::'
-hwmon_types = {'led': ['diag','fan','loc','psu1','psu2']}
-hwmon_nodes = {'led': ['brightness'] }
-hwmon_prefix ={'led': led_prefix}
i2c_prefix = '/sys/bus/i2c/devices/'
+'''
i2c_bus = {'fan': ['17-0068'] ,
'thermal': ['18-0048','18-0049', '18-004a' , '18-004b', '17-004d', '17-004e'] ,
'psu': ['10-0053','9-0050'],
@@ -230,12 +198,14 @@ def driver_uninstall():
'thermal': ['hwmon/hwmon*/temp1_input'] ,
'psu': ['psu_present', 'psu_power_good'] ,
'sfp': ['module_present']}
-
+'''
+
sfp_map = [37,38,39,40,42,41,44,43,33,34,35,36,45,46,47,48,49,50,51,52,
61,62,63,64,53,54,55,56,57,58,59,60,69,70,71,72,77,78,79,80,65,
66,67,68,73,74,75,76,85,86,87,88,31,32,29,30,81,82,83,84,25,26,
27,28]
+
mknod =[
'echo pca9548 0x77 > /sys/bus/i2c/devices/i2c-0/new_device',
'echo pca9548 0x71 > /sys/bus/i2c/devices/i2c-1/new_device',
@@ -278,7 +248,7 @@ def device_install():
status, output = log_os_system(mknod[i], 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
@@ -286,9 +256,12 @@ def device_install():
path = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device"
status, output =log_os_system("echo optoe1 0x50 > " + path, 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
+
+ print("Done device_install")
+
return
def device_uninstall():
@@ -300,7 +273,7 @@ def device_uninstall():
target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
status, output =log_os_system("echo 0x50 > "+ target, 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
@@ -313,7 +286,7 @@ def device_uninstall():
temp[-1] = temp[-1].replace('new_device', 'delete_device')
status, output = log_os_system(" ".join(temp), 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
@@ -327,43 +300,43 @@ def system_ready():
return True
def do_install():
- print "Checking system...."
+ print("Checking system....")
if driver_check() == False:
- print "No driver, installing...."
+ print("No driver, installing....")
status = driver_install()
if status:
if FORCE == 0:
return status
else:
- print PROJECT_NAME.upper()+" drivers detected...."
+ print(PROJECT_NAME.upper()+" drivers detected....")
ir3570_check()
if not device_exist():
- print "No device, installing...."
+ print("No device, installing....")
status = device_install()
if status:
if FORCE == 0:
return status
else:
- print PROJECT_NAME.upper()+" devices detected...."
+ print(PROJECT_NAME.upper()+" devices detected....")
return
def do_uninstall():
- print "Checking system...."
+ print("Checking system....")
if not device_exist():
- print PROJECT_NAME.upper() +" has no device installed...."
+ print(PROJECT_NAME.upper() +" has no device installed....")
else:
- print "Removing device...."
+ print("Removing device....")
status = device_uninstall()
if status:
if FORCE == 0:
return status
if driver_check()== False :
- print PROJECT_NAME.upper() +" has no driver installed...."
+ print(PROJECT_NAME.upper() +" has no driver installed....")
else:
- print "Removing installed driver...."
+ print("Removing installed driver....")
status = driver_uninstall()
if status:
if FORCE == 0:
@@ -371,184 +344,6 @@ def do_uninstall():
return
-def devices_info():
- global DEVICE_NO
- global ALL_DEVICE
- global i2c_bus, hwmon_types
- for key in DEVICE_NO:
- ALL_DEVICE[key]= {}
- for i in range(0,DEVICE_NO[key]):
- ALL_DEVICE[key][key+str(i+1)] = []
-
- for key in i2c_bus:
- buses = i2c_bus[key]
- nodes = i2c_nodes[key]
- for i in range(0,len(buses)):
- for j in range(0,len(nodes)):
- if 'fan' == key:
- for k in range(0,DEVICE_NO[key]):
- node = key+str(k+1)
- path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
- elif 'sfp' == key:
- for k in range(0,DEVICE_NO[key]):
- node = key+str(k+1)
- fmt = i2c_prefix+"19-0060/{0}_{1}"
- path = fmt.format(nodes[j], k+1)
-
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
- else:
- node = key+str(i+1)
- path = i2c_prefix+ buses[i]+"/"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
-
- for key in hwmon_types:
- itypes = hwmon_types[key]
- nodes = hwmon_nodes[key]
- for i in range(0,len(itypes)):
- for j in range(0,len(nodes)):
- node = key+"_"+itypes[i]
- path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][ key+str(i+1)].append(path)
-
- #show dict all in the order
- if DEBUG == True:
- for i in sorted(ALL_DEVICE.keys()):
- print(i+": ")
- for j in sorted(ALL_DEVICE[i].keys()):
- print(" "+j)
- for k in (ALL_DEVICE[i][j]):
- print(" "+" "+k)
- return
-
-def show_eeprom(index):
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- i = int(index)-1
- node = i2c_prefix+ str(sfp_map[i])+ i2c_bus['sfp'][0]+"/"+ 'eeprom'
- # check if got hexdump command in current environment
- ret, log = log_os_system("which hexdump", 0)
- ret, log2 = log_os_system("which busybox hexdump", 0)
- if len(log):
- hex_cmd = 'hexdump'
- elif len(log2):
- hex_cmd = ' busybox hexdump'
- else:
- log = 'Failed : no hexdump cmd!!'
- logging.info(log)
- print log
- return 1
-
- print node + ":"
- ret, log = log_os_system(hex_cmd +" -C "+node, 1)
- if ret==0:
- print log
- else:
- print "**********device no found**********"
- return
-
-def set_device(args):
- global DEVICE_NO
- global ALL_DEVICE
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- if len(ALL_DEVICE)==0:
- devices_info()
-
- if args[0]=='led':
- if int(args[1])>4:
- show_set_help()
- return
- #print ALL_DEVICE['led']
- for i in range(0,len(ALL_DEVICE['led'])):
- for k in (ALL_DEVICE['led']['led'+str(i+1)]):
- ret, log = log_os_system("echo "+args[1]+" >"+k, 1)
- if ret:
- return ret
- elif args[0]=='fan':
- if int(args[1])>100:
- show_set_help()
- return
- #print ALL_DEVICE['fan']
- #fan1~6 is all fine, all fan share same setting
- node = ALL_DEVICE['fan'] ['fan1'][0]
- node = node.replace(node.split("/")[-1], 'fan_duty_cycle_percentage')
- ret, log = log_os_system("cat "+ node, 1)
- if ret==0:
- print ("Previous fan duty: " + log.strip() +"%")
- ret, log = log_os_system("echo "+args[1]+" >"+node, 1)
- if ret==0:
- print ("Current fan duty: " + args[1] +"%")
- return ret
- elif args[0]=='sfp':
- if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
- show_set_help()
- return
- if len(args)<2:
- show_set_help()
- return
-
- if int(args[2])>1:
- show_set_help()
- return
-
- #print ALL_DEVICE[args[0]]
- for i in range(0,len(ALL_DEVICE[args[0]])):
- for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
- if j.find('tx_disable')!= -1:
- ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
- if ret:
- return ret
-
- return
-
-#get digits inside a string.
-#Ex: 31 for "sfp31"
-def get_value(input):
- digit = re.findall('\d+', input)
- return int(digit[0])
-
-def device_traversal():
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- if len(ALL_DEVICE)==0:
- devices_info()
- for i in sorted(ALL_DEVICE.keys()):
- print("============================================")
- print(i.upper()+": ")
- print("============================================")
-
- for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
- print " "+j+":",
- for k in (ALL_DEVICE[i][j]):
- ret, log = log_os_system("cat "+k, 0)
- func = k.split("/")[-1].strip()
- func = re.sub(j+'_','',func,1)
- func = re.sub(i.lower()+'_','',func,1)
- if ret==0:
- print func+"="+log+" ",
- else:
- print func+"="+"X"+" ",
- print
- print("----------------------------------------------------------------")
-
-
- print
- return
-
def device_exist():
ret1, log = log_os_system("ls "+i2c_prefix+"*0076", 0)
ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0)
diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/pddf_custom_psu.c b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/pddf_custom_psu.c
index 714286187a91..9c4dd7f66131 100644
--- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/pddf_custom_psu.c
+++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/modules/pddf_custom_psu.c
@@ -13,6 +13,95 @@
ssize_t pddf_show_custom_psu_v_out(struct device *dev, struct device_attribute *da, char *buf);
extern PSU_SYSFS_ATTR_DATA access_psu_v_out;
+ssize_t pddf_get_custom_psu_model_name(struct device *dev, struct device_attribute *da, char *buf);
+ssize_t pddf_get_custom_psu_serial_num(struct device *dev, struct device_attribute *da, char *buf);
+extern PSU_SYSFS_ATTR_DATA access_psu_model_name;
+extern PSU_SYSFS_ATTR_DATA access_psu_serial_num;
+
+#define MAX_MODEL_NAME 16
+#define MAX_SERIAL_NUMBER 19
+
+enum psu_type {
+ PSU_TYPE_AC_110V,
+ PSU_TYPE_DC_48V,
+ PSU_TYPE_DC_12V,
+ PSU_TYPE_AC_ACBEL_FSF019,
+ PSU_TYPE_AC_ACBEL_FSH082,
+ PSU_TYPE_YESM1300
+
+};
+
+struct model_name_info {
+ enum psu_type type;
+ u8 offset;
+ u8 length;
+ u8 chk_length;
+ char* model_name;
+};
+
+struct serial_number_info {
+ enum psu_type type;
+ u8 offset;
+ u8 length;
+ u8 chk_length;
+ char* serial_number;
+};
+
+struct model_name_info models[] = {
+{PSU_TYPE_AC_110V, 0x20, 8, 8, "YM-2651Y"},
+{PSU_TYPE_DC_48V, 0x20, 8, 8, "YM-2651V"},
+{PSU_TYPE_DC_12V, 0x00, 11, 11, "PSU-12V-750"},
+{PSU_TYPE_AC_ACBEL_FSF019, 0x15, 10, 7, "FSF019-"},
+{PSU_TYPE_AC_ACBEL_FSH082, 0x20, 10, 7, "FSH082-"},
+{PSU_TYPE_YESM1300, 0x20, 11, 8, "YESM1300"},
+
+};
+
+struct serial_number_info serials[] = {
+{PSU_TYPE_AC_110V, 0x2e, 18, 18, "YM-2651Y"},
+{PSU_TYPE_DC_48V, 0x2e, 18, 18, "YM-2651V"},
+{PSU_TYPE_DC_12V, 0x2e, 18, 18, "PSU-12V-750"},
+{PSU_TYPE_AC_ACBEL_FSF019, 0x2e, 16, 16, "FSF019-"},
+{PSU_TYPE_AC_ACBEL_FSH082, 0x35, 18, 18, "FSH082-"},
+{PSU_TYPE_YESM1300, 0x35, 20, 19, "YESM1300"},
+
+};
+
+struct pddf_psu_data {
+ char model_name[MAX_MODEL_NAME+1];
+ char serial_number[MAX_SERIAL_NUMBER+1];
+};
+
+
+static int pddf_psu_read_block(struct i2c_client *client, u8 command, u8 *data,
+ int data_len)
+{
+ int result = 0;
+ int retry_count = 10;
+
+ while (retry_count) {
+ retry_count--;
+
+ result = i2c_smbus_read_i2c_block_data(client, command, data_len, data);
+
+ if (unlikely(result < 0)) {
+ msleep(10);
+ continue;
+ }
+
+ if (unlikely(result != data_len)) {
+ result = -EIO;
+ msleep(10);
+ continue;
+ }
+
+ result = 0;
+ break;
+ }
+
+ return result;
+}
+
static int two_complement_to_int(u16 data, u8 valid_bit, int mask)
{
@@ -90,7 +179,7 @@ ssize_t pddf_show_custom_psu_v_out(struct device *dev, struct device_attribute *
exponent = two_complement_to_int(vout_mode & 0x1f, 5, 0x1f);
else
{
- printk(KERN_ERR "%s: Only support linear mode for vout mode\n", __func__);
+ /*printk(KERN_ERR "%s: Only support linear mode for vout mode\n", __func__);*/
exponent = 0;
}
mantissa = value;
@@ -100,13 +189,117 @@ ssize_t pddf_show_custom_psu_v_out(struct device *dev, struct device_attribute *
return sprintf(buf, "%d\n", (mantissa * multiplier) / (1 << -exponent));
}
+ssize_t pddf_get_custom_psu_serial_num(struct device *dev, struct device_attribute *da, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct pddf_psu_data data;
+ int i, status;
+
+ for (i = 0; i < ARRAY_SIZE(models); i++) {
+ memset(data.serial_number, 0, sizeof(data.serial_number));
+
+ status = pddf_psu_read_block(client, models[i].offset,
+ data.model_name, models[i].length);
+ if (status < 0) {
+ data.model_name[0] = '\0';
+ dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x%x)\n",
+ client->addr, models[i].offset);
+ return status;
+ }
+ else {
+ data.model_name[models[i].length] = '\0';
+ }
+
+ /* Determine if the model name is known, if not, read next index
+ */
+
+ if (strncmp(data.model_name, models[i].model_name, models[i].chk_length) == 0) {
+ status = pddf_psu_read_block(client, serials[i].offset,
+ data.serial_number, serials[i].length);
+
+ if (status < 0) {
+ data.serial_number[0] = '\0';
+ dev_dbg(&client->dev, "unable to read serial num from (0x%x) offset(0x%x)\n",
+ client->addr, serials[i].offset);
+ return status;
+ }
+ else {
+ data.serial_number[serials[i].length] = '\0';
+ return sprintf(buf, "%s\n", data.serial_number);
+ }
+
+ return 0;
+ }
+ else {
+ data.serial_number[0] = '\0';
+ }
+ }
+
+ return -ENODATA;
+
+
+}
+
+ssize_t pddf_get_custom_psu_model_name(struct device *dev, struct device_attribute *da, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct pddf_psu_data data;
+ int i, status;
+
+ for (i = 0; i < ARRAY_SIZE(models); i++) {
+ memset(data.model_name, 0, sizeof(data.model_name));
+
+ status = pddf_psu_read_block(client, models[i].offset,
+ data.model_name, models[i].length);
+ if (status < 0) {
+ data.model_name[0] = '\0';
+ dev_dbg(&client->dev, "unable to read model name from (0x%x) offset(0x%x)\n",
+ client->addr, models[i].offset);
+ return status;
+ }
+ else {
+ data.model_name[models[i].length] = '\0';
+ }
+
+ /* Determine if the model name is known, if not, read next index
+ */
+ if (strncmp(data.model_name, models[i].model_name, models[i].chk_length) == 0) {
+ if (models[i].type==PSU_TYPE_YESM1300)
+ {
+ if (data.model_name[9]=='A' && data.model_name[10]=='M')
+ {
+ data.model_name[8]='A';
+ data.model_name[9]='M';
+ data.model_name[strlen("YESM1300AM")]='\0';
+ }
+ else
+ data.model_name[strlen("YESM1300")]='\0';
+ }
+
+ return sprintf(buf, "%s\n", data.model_name);
+ }
+ else {
+ data.model_name[0] = '\0';
+ }
+ }
+
+ return -ENODATA;
+
+}
+
static int __init pddf_custom_psu_init(void)
{
access_psu_v_out.show = pddf_show_custom_psu_v_out;
access_psu_v_out.do_get = NULL;
- printk(KERN_ERR "pddf_custom_psu_init\n");
+
+ access_psu_serial_num.show = pddf_get_custom_psu_serial_num;
+ access_psu_serial_num.do_get = NULL;
+
+ access_psu_model_name.show = pddf_get_custom_psu_model_name;
+ access_psu_model_name.do_get = NULL;
+
return 0;
}
diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/sonic_platform/chassis.py
index 713cf6831ac0..8ff20a760562 100644
--- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/sonic_platform/chassis.py
+++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/sonic_platform/chassis.py
@@ -7,6 +7,7 @@
#############################################################################
try:
+ import sys
import time
from sonic_platform_pddf_base.pddf_chassis import PddfChassis
except ImportError as e:
@@ -38,7 +39,7 @@ def get_change_event(self, timeout=2000):
bitmap = 0
for i in range(34):
- modpres = self.get_sfp(i).get_presence()
+ modpres = self.get_sfp(i+1).get_presence()
if modpres:
bitmap = bitmap | (1 << i)
@@ -59,3 +60,27 @@ def get_change_event(self, timeout=2000):
return True, change_dict
else:
return True, change_dict
+
+
+ def get_sfp(self, index):
+ """
+ Retrieves sfp represented by (1-based) index
+
+ Args:
+ index: An integer, the index (1-based) of the sfp to retrieve.
+ The index should be the sequence of a physical port in a chassis,
+ starting from 1.
+ For example, 1 for Ethernet0, 2 for Ethernet4 and so on.
+
+ Returns:
+ An object derived from SfpBase representing the specified sfp
+ """
+ sfp = None
+
+ try:
+ # The index will start from 1
+ sfp = self._sfp_list[index-1]
+ except IndexError:
+ sys.stderr.write("SFP index {} out of range (1-{})\n".format(
+ index, len(self._sfp_list)))
+ return sfp
diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py
index 49a99aa777a3..1cc35e577b8d 100755
--- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py
+++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_monitor.py
@@ -21,8 +21,7 @@
try:
import commands
- import getopt
- import sys
+ import getopt, sys
import logging
import logging.config
import logging.handlers
diff --git a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py
index 898fcaa0f0d3..8eabc233fb2d 100755
--- a/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py
+++ b/platform/broadcom/sonic-platform-modules-accton/as9716-32d/utils/accton_as9716_32d_util.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
#
# Copyright (C) 2016 Accton Networks, Inc.
#
@@ -25,12 +25,8 @@
command:
install : install drivers and generate related sysfs nodes
clean : uninstall drivers and remove related sysfs nodes
- show : show all systen status
- sff : dump SFP eeprom
- set : change board setting with fan|led|sfp
"""
-
-import commands
+import subprocess
import getopt
import sys
import logging
@@ -43,35 +39,9 @@
DEBUG = False
args = []
ALL_DEVICE = {}
-DEVICE_NO = {'led':5, 'fan1':1, 'fan2':1,'fan3':1,'fan4':1,'fan5':1,'thermal':3, 'psu':2, 'sfp':34}
-
-
-led_prefix ='/sys/devices/platform/as9716_32d_led/leds/accton_'+PROJECT_NAME+'_led::'
-fan_prefix ='/sys/devices/platform/as9716_32d_'
-hwmon_types = {'led': ['diag','fan','loc','psu1','psu2'],
- 'fan1': ['fan'],
- 'fan2': ['fan'],
- 'fan3': ['fan'],
- 'fan4': ['fan'],
- 'fan5': ['fan'],
- }
-hwmon_nodes = {'led': ['brightness'] ,
- 'fan1': ['fan_duty_cycle_percentage', 'fan1_fault', 'fan1_speed_rpm', 'fan1_direction', 'fanr1_fault', 'fanr1_speed_rpm'],
- 'fan2': ['fan_duty_cycle_percentage','fan2_fault', 'fan2_speed_rpm', 'fan2_direction', 'fanr2_fault', 'fanr2_speed_rpm'],
- 'fan3': ['fan_duty_cycle_percentage','fan3_fault', 'fan3_speed_rpm', 'fan3_direction', 'fanr3_fault', 'fanr3_speed_rpm'],
- 'fan4': ['fan_duty_cycle_percentage','fan4_fault', 'fan4_speed_rpm', 'fan4_direction', 'fanr4_fault', 'fanr4_speed_rpm'],
- 'fan5': ['fan_duty_cycle_percentage','fan5_fault', 'fan5_speed_rpm', 'fan5_direction', 'fanr5_fault', 'fanr5_speed_rpm'],
- 'fan6': ['fan_duty_cycle_percentage','fan6_fault', 'fan6_speed_rpm', 'fan6_direction', 'fanr5_fault', 'fanr5_speed_rpm'],
- }
-hwmon_prefix ={'led': led_prefix,
- 'fan1': fan_prefix,
- 'fan2': fan_prefix,
- 'fan3': fan_prefix,
- 'fan4': fan_prefix,
- 'fan5': fan_prefix,
- }
i2c_prefix = '/sys/bus/i2c/devices/'
+'''
i2c_bus = {'fan': ['54-0066'],
'thermal': ['18-0048', '18-0049','18-004a', '18-004b', '18-004c', '18-004e', '18-004f'] ,
'psu': ['9-0058', '10-0059'],
@@ -80,6 +50,7 @@
'thermal': ['hwmon/hwmon*/temp1_input'] ,
'psu': ['psu_present ', 'psu_power_good'] ,
'sfp': ['module_present_ ', 'module_tx_disable_']}
+'''
sfp_map = [25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40,
@@ -135,8 +106,8 @@
if DEBUG == True:
- print sys.argv[0]
- print 'ARGV :', sys.argv[1:]
+ print(sys.argv[0])
+ print('ARGV :', sys.argv[1:])
def main():
@@ -152,9 +123,9 @@ def main():
'force',
])
if DEBUG == True:
- print options
- print args
- print len(sys.argv)
+ print(options)
+ print(args)
+ print(len(sys.argv))
for opt, arg in options:
if opt in ('-h', '--help'):
@@ -171,22 +142,6 @@ def main():
do_install()
elif arg == 'clean':
do_uninstall()
- elif arg == 'show':
- device_traversal()
- elif arg == 'sff':
- if len(args)!=2:
- show_eeprom_help()
- elif int(args[1]) > DEVICE_NO['sfp'] -1:
- show_eeprom_help()
- else:
- show_eeprom(args[1])
- return
- elif arg == 'set':
- if len(args)<3:
- show_set_help()
- else:
- set_device(args[1:])
- return
else:
show_help()
@@ -194,28 +149,20 @@ def main():
return 0
def show_help():
- print __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]}
- sys.exit(0)
-
-def show_set_help():
- cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
- print cmd +" [led|sfp|fan]"
- print " use \""+ cmd + " led 0-4 \" to set led color"
- print " use \""+ cmd + " fan 0-100\" to set fan duty percetage"
- print " use \""+ cmd + " sfp 1-32 {0|1}\" to set sfp# tx_disable"
+ print( __doc__ % {'scriptName' : sys.argv[0].split("/")[-1]})
sys.exit(0)
def dis_i2c_ir3570a(addr):
cmd = "i2cset -y 0 0x%x 0xE5 0x01" % addr
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
cmd = "i2cset -y 0 0x%x 0x12 0x02" % addr
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
return status
def ir3570_check():
cmd = "i2cdump -y 0 0x42 s 0x9a"
try:
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
lines = output.split('\n')
hn = re.findall(r'\w+', lines[-1])
version = int(hn[1], 16)
@@ -224,29 +171,24 @@ def ir3570_check():
else:
ret = 0
except Exception as e:
- print "Error on ir3570_check() e:" + str(e)
+ print( "Error on ir3570_check() e:" + str(e))
return -1
return ret
-def show_eeprom_help():
- cmd = sys.argv[0].split("/")[-1]+ " " + args[0]
- print " use \""+ cmd + " 1-32 \" to dump sfp# eeprom"
- sys.exit(0)
-
def my_log(txt):
if DEBUG == True:
- print "[ACCTON DBG]: "+txt
+ print("[ACCTON DBG]: "+txt)
return
def log_os_system(cmd, show):
logging.info('Run :'+cmd)
status = 1
output = ""
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
my_log (cmd +"with result:" + str(status))
- my_log ("cmd:" + cmd)
- my_log (" output:"+output)
+ #my_log ("cmd:" + cmd)
+ #my_log (" output:"+output)
if status:
logging.info('Failed :'+cmd)
if show:
@@ -285,6 +227,7 @@ def driver_install():
if FORCE == 0:
return status
log_os_system(cpld_reset_stop, 1)
+ print("Done driver_install")
return 0
def driver_uninstall():
@@ -292,7 +235,7 @@ def driver_uninstall():
for i in range(0,len(kos)):
rm = kos[-(i+1)].replace("modprobe", "modprobe -rq")
lst = rm.split(" ")
- print "lst=%s"%lst
+
if len(lst) > 3:
del(lst[3])
rm = " ".join(lst)
@@ -304,7 +247,7 @@ def driver_uninstall():
def eeprom_check():
cmd = "i2cget -y -f 0 0x57"
- status, output = commands.getstatusoutput(cmd)
+ status, output = subprocess.getstatusoutput(cmd)
return status
def device_install():
@@ -315,10 +258,10 @@ def device_install():
#for pca954x need times to built new i2c buses
if mknod[i].find('pca954') != -1:
time.sleep(2)
- print "init i2c device instance"
+ #print("init i2c device instance")
status, output = log_os_system(mknod[i], 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
@@ -331,14 +274,17 @@ def device_install():
for i in range(0,len(sfp_map)):
status, output =log_os_system("echo optoe1 0x50 > /sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/new_device", 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
status, output =log_os_system("echo port"+str(i)+" > /sys/bus/i2c/devices/"+str(sfp_map[i])+"-0050/port_name", 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
+
+ print("Done device_install")
+
return
def device_uninstall():
@@ -354,7 +300,7 @@ def device_uninstall():
target = "/sys/bus/i2c/devices/i2c-"+str(sfp_map[i])+"/delete_device"
status, output =log_os_system("echo 0x50 > "+ target, 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
@@ -367,7 +313,7 @@ def device_uninstall():
temp[-1] = temp[-1].replace('new_device', 'delete_device')
status, output = log_os_system(" ".join(temp), 1)
if status:
- print output
+ print(output)
if FORCE == 0:
return status
@@ -388,7 +334,7 @@ def system_ready():
if driver_inserted() == False:
return False
if not device_exist():
- print "not device_exist()"
+ print("not device_exist()")
return False
return True
@@ -399,7 +345,7 @@ def do_install():
if FORCE == 0:
return status
else:
- print PROJECT_NAME.upper()+" drivers detected...."
+ print(PROJECT_NAME.upper()+" drivers detected....")
ir3570_check()
@@ -409,23 +355,23 @@ def do_install():
if FORCE == 0:
return status
else:
- print PROJECT_NAME.upper()+" devices detected...."
+ print(PROJECT_NAME.upper()+" devices detected....")
return
def do_uninstall():
if not device_exist():
- print PROJECT_NAME.upper() +" has no device installed...."
+ print(PROJECT_NAME.upper()+" has no device installed....")
else:
- print "Removing device...."
+ print("Removing device....")
status = device_uninstall()
if status:
if FORCE == 0:
return status
if driver_inserted()== False :
- print PROJECT_NAME.upper() +" has no driver installed...."
+ print(PROJECT_NAME.upper()+" has no driver installed....")
else:
- print "Removing installed driver...."
+ print("Removing installed driver....")
status = driver_uninstall()
if status:
if FORCE == 0:
@@ -433,186 +379,6 @@ def do_uninstall():
return
-def devices_info():
- global DEVICE_NO
- global ALL_DEVICE
- global i2c_bus, hwmon_types
- for key in DEVICE_NO:
- ALL_DEVICE[key]= {}
- for i in range(0,DEVICE_NO[key]):
- ALL_DEVICE[key][key+str(i+1)] = []
-
- for key in i2c_bus:
- buses = i2c_bus[key]
- nodes = i2c_nodes[key]
- for i in range(0,len(buses)):
- for j in range(0,len(nodes)):
- if 'fan' == key:
- for k in range(0,DEVICE_NO[key]):
- node = key+str(k+1)
- path = i2c_prefix+ buses[i]+"/fan"+str(k+1)+"_"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
- elif 'sfp' == key:
- for k in range(0,DEVICE_NO[key]):
- node = key+str(k+1)
- path = i2c_prefix+ str(sfp_map[k])+ buses[i]+"/"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
- else:
- node = key+str(i+1)
- path = i2c_prefix+ buses[i]+"/"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][node].append(path)
-
- for key in hwmon_types:
- itypes = hwmon_types[key]
- nodes = hwmon_nodes[key]
- for i in range(0,len(itypes)):
- for j in range(0,len(nodes)):
- node = key+"_"+itypes[i]
- path = hwmon_prefix[key]+ itypes[i]+"/"+ nodes[j]
- my_log(node+": "+ path)
- ALL_DEVICE[key][ key+str(i+1)].append(path)
-
- #show dict all in the order
- if DEBUG == True:
- for i in sorted(ALL_DEVICE.keys()):
- print(i+": ")
- for j in sorted(ALL_DEVICE[i].keys()):
- print(" "+j)
- for k in (ALL_DEVICE[i][j]):
- print(" "+" "+k)
- return
-
-def show_eeprom(index):
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- #if len(ALL_DEVICE)==0:
- # devices_info()
- #node = ALL_DEVICE['sfp'] ['sfp'+str(index)][0]
- #node = node.replace(node.split("/")[-1], 'eeprom')
- node= "/sys/bus/i2c/devices/"+str(sfp_map[int(index)])+"-0050" + "/eeprom"
- # check if got hexdump command in current environment
- ret, log = log_os_system("which hexdump", 0)
- ret, log2 = log_os_system("which busybox hexdump", 0)
- if len(log):
- hex_cmd = 'hexdump'
- elif len(log2):
- hex_cmd = ' busybox hexdump'
- else:
- log = 'Failed : no hexdump cmd!!'
- logging.info(log)
- print log
- return 1
- print "node=%s"%node
- #print node + ":"
- #ret, log = log_os_system("cat "+node+"| "+hex_cmd+" -C", 1)
- ret, log = log_os_system(hex_cmd+" -C " + node, 1)
- if ret==0:
- print log
- else:
- print "**********device no found**********"
- return
-
-def set_device(args):
- global DEVICE_NO
- global ALL_DEVICE
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- if len(ALL_DEVICE)==0:
- devices_info()
-
- if args[0]=='led':
- if int(args[1])>4:
- show_set_help()
- return
- #print ALL_DEVICE['led']
- for i in range(0,len(ALL_DEVICE['led'])):
- for k in (ALL_DEVICE['led']['led'+str(i+1)]):
- ret, log = log_os_system("echo "+args[1]+" >"+k, 1)
- if ret:
- return ret
- elif args[0]=='fan':
- if int(args[1])>100:
- show_set_help()
- return
- #print ALL_DEVICE['fan']
- #fan1~6 is all fine, all fan share same setting
- node = ALL_DEVICE['fan1'] ['fan11'][0]
- node = node.replace(node.split("/")[-1], 'fan1_duty_cycle_percentage')
- ret, log = log_os_system("cat "+ node, 1)
- if ret==0:
- print ("Previous fan duty: " + log.strip() +"%")
- ret, log = log_os_system("echo "+args[1]+" >"+node, 1)
- if ret==0:
- print ("Current fan duty: " + args[1] +"%")
- return ret
- elif args[0]=='sfp':
- if int(args[1])> DEVICE_NO[args[0]] or int(args[1])==0:
- show_set_help()
- return
- if len(args)<2:
- show_set_help()
- return
-
- if int(args[2])>1:
- show_set_help()
- return
-
- #print ALL_DEVICE[args[0]]
- for i in range(0,len(ALL_DEVICE[args[0]])):
- for j in ALL_DEVICE[args[0]][args[0]+str(args[1])]:
- if j.find('tx_disable')!= -1:
- ret, log = log_os_system("echo "+args[2]+" >"+ j, 1)
- if ret:
- return ret
-
- return
-
-#get digits inside a string.
-#Ex: 31 for "sfp31"
-def get_value(input):
- digit = re.findall('\d+', input)
- return int(digit[0])
-
-def device_traversal():
- if system_ready()==False:
- print("System's not ready.")
- print("Please install first!")
- return
-
- if len(ALL_DEVICE)==0:
- devices_info()
- for i in sorted(ALL_DEVICE.keys()):
- print("============================================")
- print(i.upper()+": ")
- print("============================================")
-
- for j in sorted(ALL_DEVICE[i].keys(), key=get_value):
- print " "+j+":",
- for k in (ALL_DEVICE[i][j]):
- ret, log = log_os_system("cat "+k, 0)
- func = k.split("/")[-1].strip()
- func = re.sub(j+'_','',func,1)
- func = re.sub(i.lower()+'_','',func,1)
- if ret==0:
- print func+"="+log+" ",
- else:
- print func+"="+"X"+" ",
- print
- print("----------------------------------------------------------------")
-
-
- print
- return
-
def device_exist():
ret1, log = log_os_system("ls "+i2c_prefix+"*0077", 0)
ret2, log = log_os_system("ls "+i2c_prefix+"i2c-2", 0)
diff --git a/platform/broadcom/sonic-platform-modules-arista b/platform/broadcom/sonic-platform-modules-arista
index 700b1e448fbc..6e8ccd3379d5 160000
--- a/platform/broadcom/sonic-platform-modules-arista
+++ b/platform/broadcom/sonic-platform-modules-arista
@@ -1 +1 @@
-Subproject commit 700b1e448fbcb3d9d083f0fbff08416aa1237185
+Subproject commit 6e8ccd3379d5e89f4e80b11391818e648d928d94
diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init
index 5c73be6ee50c..07a6542109b5 100644
--- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init
+++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init
@@ -53,12 +53,11 @@ start)
echo max6699 0x1a > /sys/bus/i2c/devices/i2c-3/new_device
echo max6699 0x1a > /sys/bus/i2c/devices/i2c-11/new_device
- ## TODO: fix dps200 driver cause kernel panic issue
- # https://github.com/Azure/sonic-buildimage/issues/6602
-
# Attach PSUs
- # echo dps200 0x5a > /sys/bus/i2c/devices/i2c-12/new_device
- # echo dps200 0x5b > /sys/bus/i2c/devices/i2c-13/new_device
+ echo dps200 0x5a > /sys/bus/i2c/devices/i2c-12/new_device
+ echo 24c02 0x52 > /sys/bus/i2c/devices/i2c-12/new_device
+ echo dps200 0x5b > /sys/bus/i2c/devices/i2c-13/new_device
+ echo 24c02 0x53 > /sys/bus/i2c/devices/i2c-13/new_device
# Attach fans
echo emc2305 0x4d > /sys/bus/i2c/devices/i2c-23/new_device
diff --git a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install
index ae73bf82f58c..1f1b7609b760 100644
--- a/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install
+++ b/platform/broadcom/sonic-platform-modules-dell/debian/platform-modules-s6100.install
@@ -10,6 +10,7 @@ s6100/scripts/platform_reboot_override usr/share/sonic/device/x86_64-dell_s6100_
s6100/scripts/fast-reboot_plugin usr/share/sonic/device/x86_64-dell_s6100_c2538-r0
s6100/scripts/track_reboot_reason.sh usr/share/sonic/device/x86_64-dell_s6100_c2538-r0
s6100/scripts/warm-reboot_plugin usr/share/sonic/device/x86_64-dell_s6100_c2538-r0
+s6100/scripts/reboot_plugin usr/share/sonic/device/x86_64-dell_s6100_c2538-r0
s6100/scripts/ssd-fw-upgrade usr/share/sonic/device/x86_64-dell_s6100_c2538-r0
s6100/scripts/override.conf /etc/systemd/system/systemd-reboot.service.d
common/dell_lpc_mon.sh usr/local/bin
@@ -25,5 +26,6 @@ s6100/systemd/platform-modules-s6100.service etc/systemd/system
s6100/systemd/s6100-lpc-monitor.service etc/systemd/system
s6100/systemd/s6100-reboot-cause.service etc/systemd/system
s6100/systemd/s6100-i2c-enumerate.service etc/systemd/system
+s6100/scripts/s6100_serial_getty_monitor etc/monit/conf.d
common/fw-updater usr/local/bin
common/onie_mode_set usr/local/bin
diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin
index e32747c7fed5..683dcc6733ae 100755
--- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin
+++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/fast-reboot_plugin
@@ -4,4 +4,8 @@ if [[ -d /sys/devices/platform/SMF.512/hwmon/ ]]; then
cd /sys/devices/platform/SMF.512/hwmon/*
echo 0xcc > mb_poweron_reason
fi
+
+io_rd_wr.py --set --val 40 --offset 0x131
+io_rd_wr.py --set --val 06 --offset 210; io_rd_wr.py --set --val 0B --offset 211; io_rd_wr.py --set --val aa --offset 213
+
/usr/local/bin/s6100_i2c_enumeration.sh deinit & > /dev/null
diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override
index dc681104dac1..b47382a38b4b 100755
--- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override
+++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/platform_reboot_override
@@ -7,8 +7,8 @@ PORT_RES = '/dev/port'
def log_software_reboot():
- # Run plugin script which will track the cli triggered reboot, fastboot, warmboot
- res = subprocess.check_output(['/usr/share/sonic/device/x86_64-dell_s6100_c2538-r0/fast-reboot_plugin'])
+ # Run plugin script which will track the cli triggered reboot
+ res = subprocess.check_output(['/usr/share/sonic/device/x86_64-dell_s6100_c2538-r0/reboot_plugin'])
return
def ssd_hdparm_upgrade():
diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/reboot_plugin b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/reboot_plugin
new file mode 100755
index 000000000000..4ccfecdfe2af
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/reboot_plugin
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+if [[ -d /sys/devices/platform/SMF.512/hwmon/ ]]; then
+ cd /sys/devices/platform/SMF.512/hwmon/*
+ echo 0xcc > mb_poweron_reason
+fi
+
+/usr/local/bin/s6100_i2c_enumeration.sh deinit & > /dev/null
diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh
index 62a8c1a2812f..5c7c2308c1f0 100755
--- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh
+++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_platform.sh
@@ -52,6 +52,7 @@ if [[ "$1" == "init" ]]; then
fi
install_python_api_package
+ monit reload
elif [[ "$1" == "deinit" ]]; then
/usr/local/bin/s6100_i2c_enumeration.sh deinit
diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_serial_getty_monitor b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_serial_getty_monitor
new file mode 100644
index 000000000000..1b5d0c90db37
--- /dev/null
+++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/s6100_serial_getty_monitor
@@ -0,0 +1,4 @@
+#Dell S6100 serial getty monitor
+check process serial-getty matching "ttyS"
+start program = "/bin/systemctl start serial-getty@ttyS1.service"
+stop program = "/bin/systemctl stop serial-getty@ttyS1.service"
diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh
index 775c0c8d05f2..691b63a4a7e9 100755
--- a/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh
+++ b/platform/broadcom/sonic-platform-modules-dell/s6100/scripts/track_reboot_reason.sh
@@ -131,7 +131,29 @@ _is_unknown_reset(){
mb_poweron_reason=$(cat $MAILBOX_POWERON_REASON)
echo "Unknown POR: $curr_poweron_reason RST: $curr_reset_reason MBR: $mb_poweron_reason" > $REBOOT_CAUSE_FILE
fi
-
+
+}
+
+_is_software_reboot(){
+ SMF_STATUS=`io_rd_wr.py --set --val 06 --offset 210; io_rd_wr.py --set --val 0B --offset 211; io_rd_wr.py --get --offset 212`
+ SMF_STATUS=$(echo "$SMF_STATUS" | awk '{print $NF}')
+
+ CPLD_STATUS=`io_rd_wr.py --get --offset 0x131`
+ CPLD_STATUS=$(echo "$CPLD_STATUS" | awk '{print $NF}')
+
+ if [[ $SMF_STATUS == "aa" ]]; then
+ if [[ $CPLD_STATUS != "40" ]]; then
+ # Cold reset happened; Resetting the registers
+ io_rd_wr.py --set --val ff --offset 0x131
+ io_rd_wr.py --set --val 06 --offset 210; io_rd_wr.py --set --val 0B --offset 211; io_rd_wr.py --set --val ff --offset 213
+ echo 0x88 > $MAILBOX_POWERON_REASON
+ else
+ io_rd_wr.py --set --val 06 --offset 210; io_rd_wr.py --set --val 0B --offset 211; io_rd_wr.py --set --val ff --offset 213
+ echo 0xaa > $MAILBOX_POWERON_REASON
+ fi
+ else
+ echo 0xaa > $MAILBOX_POWERON_REASON
+ fi
}
update_mailbox_register(){
@@ -162,7 +184,7 @@ update_mailbox_register(){
&& [[ $SMF_FPGA_VERSION_MAJOR -ge 1 ]] && [[ $SMF_FPGA_VERSION_MINOR -ge 4 ]]; then
if [[ $reason = "cc" ]]; then
- echo 0xaa > $MAILBOX_POWERON_REASON
+ _is_software_reboot
elif [[ $SMF_RESET = "11" ]]; then
echo 0xee > $MAILBOX_POWERON_REASON
elif [[ $SMF_RESET = "33" ]]; then
@@ -185,7 +207,7 @@ update_mailbox_register(){
elif [[ $is_wd_reboot = 1 ]] && [[ $reason != "cc" ]]; then
echo 0xdd > $MAILBOX_POWERON_REASON
elif [[ $reason = "cc" ]]; then
- echo 0xaa > $MAILBOX_POWERON_REASON
+ _is_software_reboot
else
_is_unknown_reset $is_thermal_reboot
echo 0x99 > $MAILBOX_POWERON_REASON
diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py
index 4527f6947321..7f07739e7df0 100755
--- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py
+++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py
@@ -99,6 +99,7 @@ def __init__(self):
def _get_reboot_reason_smf_register(self):
# In S6100, mb_poweron_reason register will
# Returns 0xaa or 0xcc on software reload
+ # Returns 0x88 on cold-reboot happened during software reload
# Returns 0xff or 0xbb on power-cycle
# Returns 0xdd on Watchdog
# Returns 0xee on Thermal Shutdown
@@ -257,6 +258,8 @@ def get_reboot_cause(self):
return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None)
elif ((smf_mb_reg_reason == 0xaa) or (smf_mb_reg_reason == 0xcc)):
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None)
+ elif (smf_mb_reg_reason == 0x88):
+ return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "CPU Reset")
elif (smf_mb_reg_reason == 0xdd):
return (ChassisBase.REBOOT_CAUSE_WATCHDOG, None)
elif (smf_mb_reg_reason == 0xee):
diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/component.py
index 8b7ae004e8a4..01bcdeffe688 100644
--- a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/component.py
+++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/component.py
@@ -70,12 +70,12 @@ class Component(ComponentBase):
],
['Switch CPLD 1',
- 'Used for managing QSFP28/SFP port transceivers ',
+ 'Used for managing QSFP-DD/QSFP28/SFP port transceivers ',
get_cpld1_version
],
['Switch CPLD 2',
- 'Used for managing QSFP28/SFP port transceivers',
+ 'Used for managing QSFP-DD/QSFP28/SFP port transceivers',
get_cpld2_version
]
diff --git a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/sfp.py
index 0dcb6da49514..4fe4b261cad0 100644
--- a/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/sfp.py
+++ b/platform/broadcom/sonic-platform-modules-dell/z9332f/sonic_platform/sfp.py
@@ -1073,8 +1073,13 @@ def get_tx_bias(self):
try:
offset = QSFP_DD_PAGE17
if self.sfp_type == 'QSFP_DD':
- if self.qsfp_dd_DomInfo is None or not self.qsfp_dd_txbias_supported:
+ if self.qsfp_dd_DomInfo is None:
return None
+ if not self.qsfp_dd_txbias_supported:
+ for lane in range(0, 8):
+ tx_bias_list.append("N/A")
+ return tx_bias_list
+
tx_bias_data_raw = self._read_eeprom_bytes(self.eeprom_path, offset + QSFP_DD_TXBIAS_OFFSET, QSFP_DD_TXBIAS_WIDTH)
tx_bias_data = self.qsfp_dd_DomInfo.parse_dom_tx_bias(tx_bias_data_raw, 0)
@@ -1093,8 +1098,6 @@ def get_tx_bias(self):
if tx_bias_data is not None:
tx1_bias = self._strip_unit_from_str(tx_bias_data['data']['TXBias']['value'])
tx_bias_list.append(tx1_bias)
- else:
- tx_bias_list.append(0.0)
except (TypeError, ValueError):
return None
@@ -1107,8 +1110,12 @@ def get_rx_power(self):
rx_power_list = []
try:
if self.sfp_type == 'QSFP_DD':
- if self.qsfp_dd_DomInfo is None or not self.qsfp_dd_rxpower_supported:
+ if self.qsfp_dd_DomInfo is None:
return None
+ if not self.qsfp_dd_rxpower_supported:
+ for lane in range(0, 8):
+ rx_power_list.append("N/A")
+ return rx_power_list
offset = QSFP_DD_PAGE17
rx_power_data_raw = self._read_eeprom_bytes(self.eeprom_path, offset + QSFP_DD_RXPOWER_OFFSET, QSFP_DD_TXPOWER_WIDTH)
@@ -1128,9 +1135,7 @@ def get_rx_power(self):
rx_power_data = self._get_eeprom_data('ChannelMonitor')
if rx_power_data is not None:
rx1_pw = self._strip_unit_from_str(rx_power_data['data']['RXPower']['value'])
- else:
- rx1_pw = 0.0
- rx_power_list.append(rx1_pw)
+ rx_power_list.append(rx1_pw)
except (TypeError, ValueError):
return None
return rx_power_list
@@ -1142,8 +1147,12 @@ def get_tx_power(self):
tx_power_list = []
try:
if self.sfp_type == 'QSFP_DD':
- if self.qsfp_dd_DomInfo is None or not self.qsfp_dd_txpower_supported:
+ if self.qsfp_dd_DomInfo is None:
return None
+ if not self.qsfp_dd_txpower_supported:
+ for lane in range(0, 8):
+ tx_power_list.append("N/A")
+ return tx_power_list
offset = QSFP_DD_PAGE17
tx_power_data_raw = self._read_eeprom_bytes(self.eeprom_path, offset + QSFP_DD_TXPOWER_OFFSET,
@@ -1177,9 +1186,7 @@ def get_tx_power(self):
channel_monitor_data = self._get_eeprom_data('ChannelMonitor')
if channel_monitor_data is not None:
tx1_pw = self._strip_unit_from_str(channel_monitor_data['data']['TXPower']['value'])
- else:
- tx1_pw = 0.0
- tx_power_list.append(tx1_pw)
+ tx_power_list.append(tx1_pw)
except (TypeError, ValueError):
return None
return tx_power_list
@@ -1212,6 +1219,8 @@ def reset(self):
# Convert our register value back to a hex string and write back
self.pci_set_value(self.BASE_RES_PATH, reg_value, port_offset)
+ else:
+ return False
except ValueError:
return False
return True
diff --git a/platform/checkout/cisco-8000.ini b/platform/checkout/cisco-8000.ini
new file mode 100644
index 000000000000..a8a76e1d4a0e
--- /dev/null
+++ b/platform/checkout/cisco-8000.ini
@@ -0,0 +1,3 @@
+[module]
+repo=git@github.com:Cisco-8000-sonic/platform-cisco-8000.git
+ref=v0.1
diff --git a/platform/checkout/template.j2 b/platform/checkout/template.j2
new file mode 100644
index 000000000000..17b8f00c8902
--- /dev/null
+++ b/platform/checkout/template.j2
@@ -0,0 +1,11 @@
+{% set path = env('PLATFORM_PATH') %}
+if [ ! -d {{ path }} ]; then git clone {{ module.repo }} {{ path }}; fi;
+if [ -d {{ path }}/.git ]; then cd {{ path }} &&
+
+{% if module.ref is defined %}
+git checkout {{ module.ref }} && git submodule update --init --recursive;
+{% else %}
+git submodule update --init --recursive;
+{% endif %}
+
+else echo "{{ path }}/.git not found"; exit 1; fi
diff --git a/platform/components/docker-gbsyncd-credo.dep b/platform/components/docker-gbsyncd-credo.dep
new file mode 100644
index 000000000000..00551e0ac855
--- /dev/null
+++ b/platform/components/docker-gbsyncd-credo.dep
@@ -0,0 +1,12 @@
+DPATH := $($(DOCKER_GBSYNCD_BASE)_PATH)
+DEP_FILES := $(SONIC_COMMON_FILES_LIST)
+DEP_FILES += platform/components/docker-gbsyncd-credo.mk
+DEP_FILES += platform/components/docker-gbsyncd-credo.dep
+DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
+DEP_FILES += $(shell git ls-files $(DPATH))
+
+$(DOCKER_GBSYNCD_BASE)_CACHE_MODE := GIT_CONTENT_SHA
+$(DOCKER_GBSYNCD_BASE)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
+$(DOCKER_GBSYNCD_BASE)_DEP_FILES := $(DEP_FILES)
+
+$(eval $(call add_dbg_docker,$(DOCKER_GBSYNCD_BASE),$(DOCKER_GBSYNCD_BASE_DBG)))
diff --git a/platform/components/docker-gbsyncd-credo.mk b/platform/components/docker-gbsyncd-credo.mk
new file mode 100644
index 000000000000..a1231d846355
--- /dev/null
+++ b/platform/components/docker-gbsyncd-credo.mk
@@ -0,0 +1,14 @@
+DOCKER_GBSYNCD_PLATFORM_CODE = credo
+
+LIBSAI_CREDO = libsaicredo_0.5.1-alpha.2_amd64.deb
+$(LIBSAI_CREDO)_URL =
+LIBSAI_CREDO_OWL = libsaicredo-owl_0.5.1-alpha.2_amd64.deb
+$(LIBSAI_CREDO_OWL)_URL =
+
+ifneq ($($(LIBSAI_CREDO)_URL),)
+include $(PLATFORM_PATH)/../template/docker-gbsyncd-base.mk
+$(DOCKER_GBSYNCD_BASE)_CONTAINER_NAME = gbsyncd-$(DOCKER_GBSYNCD_PLATFORM_CODE)
+$(DOCKER_GBSYNCD_BASE)_PATH = $(PLATFORM_PATH)/../components/docker-gbsyncd-$(DOCKER_GBSYNCD_PLATFORM_CODE)
+SONIC_ONLINE_DEBS += $(LIBSAI_CREDO) $(LIBSAI_CREDO_OWL)
+$(DOCKER_GBSYNCD_BASE)_DEPENDS += $(SYNCD) $(LIBSAI_CREDO) $(LIBSAI_CREDO_OWL)
+endif
diff --git a/platform/components/docker-gbsyncd-credo/Dockerfile.j2 b/platform/components/docker-gbsyncd-credo/Dockerfile.j2
new file mode 100644
index 000000000000..f82ea0e6c77d
--- /dev/null
+++ b/platform/components/docker-gbsyncd-credo/Dockerfile.j2
@@ -0,0 +1,40 @@
+FROM docker-config-engine-buster
+
+ARG docker_container_name
+RUN [ -f /etc/rsyslog.conf ] && sed -ri "s/%syslogtag%/$docker_container_name#%syslogtag%/;" /etc/rsyslog.conf
+
+## Make apt-get non-interactive
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update
+
+RUN apt-get install -f -y iproute2 libcap2-bin libprotobuf-dev
+
+COPY \
+{% for deb in docker_gbsyncd_credo_debs.split(' ') -%}
+{% if 'libsaibcm' not in deb -%}
+debs/{{ deb }}{{' '}}
+{%- endif %}
+{%- endfor -%}
+debs/
+
+RUN dpkg -i \
+{% for deb in docker_gbsyncd_credo_debs.split(' ') -%}
+{% if 'libsaibcm' not in deb -%}
+debs/{{ deb }}{{' '}}
+{%- endif %}
+{%- endfor %}
+
+COPY ["docker-init.sh", "/usr/bin/"]
+COPY ["start.sh", "/usr/bin/"]
+
+COPY ["critical_processes.j2", "/usr/share/sonic/templates"]
+COPY ["supervisord.conf.j2", "/usr/share/sonic/templates"]
+
+COPY ["files/supervisor-proc-exit-listener", "/usr/bin"]
+
+## Clean up
+RUN apt-get clean -y; apt-get autoclean -y; apt-get autoremove -y
+RUN rm -rf /debs
+
+ENTRYPOINT ["/usr/bin/docker-init.sh"]
diff --git a/platform/components/docker-gbsyncd-credo/critical_processes.j2 b/platform/components/docker-gbsyncd-credo/critical_processes.j2
new file mode 100644
index 000000000000..bdd6903c5690
--- /dev/null
+++ b/platform/components/docker-gbsyncd-credo/critical_processes.j2
@@ -0,0 +1 @@
+program:syncd
diff --git a/platform/components/docker-gbsyncd-credo/docker-init.sh b/platform/components/docker-gbsyncd-credo/docker-init.sh
new file mode 100755
index 000000000000..93a1b931dfad
--- /dev/null
+++ b/platform/components/docker-gbsyncd-credo/docker-init.sh
@@ -0,0 +1,16 @@
+#! /bin/sh
+
+GB_CONFIG=/usr/share/sonic/hwsku/gearbox_config.json
+
+if [ ! -f $GB_CONFIG ]; then
+ exit 0
+fi
+
+CFGGEN_ARG="-j $GB_CONFIG"
+
+mkdir -p /etc/supervisor/conf.d/
+
+sonic-cfggen $CFGGEN_ARG -t /usr/share/sonic/templates/supervisord.conf.j2 > /etc/supervisor/conf.d/supervisord.conf
+sonic-cfggen $CFGGEN_ARG -t /usr/share/sonic/templates/critical_processes.j2 > /etc/supervisor/critical_processes
+
+exec /usr/local/bin/supervisord
diff --git a/platform/components/docker-gbsyncd-credo/start.sh b/platform/components/docker-gbsyncd-credo/start.sh
new file mode 100755
index 000000000000..ac7de02dcdca
--- /dev/null
+++ b/platform/components/docker-gbsyncd-credo/start.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env bash
+
+HWSKU_DIR=/usr/share/sonic/hwsku
+
+mkdir -p /etc/sai.d/
+
+# Create/Copy the psai.profile to /etc/sai.d/psai.profile
+if [ -f $HWSKU_DIR/psai.profile.j2 ]; then
+ sonic-cfggen -d -t $HWSKU_DIR/psai.profile.j2 > /etc/sai.d/psai.profile
+else
+ if [ -f $HWSKU_DIR/psai.profile ]; then
+ cp $HWSKU_DIR/psai.profile /etc/sai.d/psai.profile
+ fi
+fi
diff --git a/platform/components/docker-gbsyncd-credo/supervisord.conf.j2 b/platform/components/docker-gbsyncd-credo/supervisord.conf.j2
new file mode 100644
index 000000000000..6f12053ce236
--- /dev/null
+++ b/platform/components/docker-gbsyncd-credo/supervisord.conf.j2
@@ -0,0 +1,43 @@
+[supervisord]
+logfile_maxbytes=1MB
+logfile_backups=2
+nodaemon=true
+
+[eventlistener:dependent-startup]
+command=python3 -m supervisord_dependent_startup
+autostart=true
+autorestart=unexpected
+startretries=0
+exitcodes=0,3
+events=PROCESS_STATE
+
+[program:rsyslogd]
+command=/usr/sbin/rsyslogd -n -iNONE
+priority=1
+autostart=false
+autorestart=unexpected
+stdout_logfile=syslog
+stderr_logfile=syslog
+dependent_startup=true
+
+[program:start]
+command=/usr/bin/start.sh
+priority=2
+autostart=false
+autorestart=false
+startsecs=0
+stdout_logfile=syslog
+stderr_logfile=syslog
+dependent_startup=true
+dependent_startup_wait_for=rsyslogd:running
+
+[program:syncd]
+environment=CREDO_DEVICE_PATH=/usr/lib
+command=/usr/bin/syncd -s -p /etc/sai.d/psai.profile -x /usr/share/sonic/hwsku/context_config.json -g 1
+priority=3
+autostart=false
+autorestart=false
+stdout_logfile=syslog
+stderr_logfile=syslog
+dependent_startup=true
+dependent_startup_wait_for=start:exited
diff --git a/platform/mellanox/fw.mk b/platform/mellanox/fw.mk
index f22bb7e9f3ed..0b8768b4755f 100644
--- a/platform/mellanox/fw.mk
+++ b/platform/mellanox/fw.mk
@@ -11,17 +11,17 @@ else
FW_FROM_URL = n
endif
-MLNX_SPC_FW_VERSION = 13.2008.3216
+MLNX_SPC_FW_VERSION = 13.2008.3224
MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa
$(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH)
$(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE)
-MLNX_SPC2_FW_VERSION = 29.2008.3216
+MLNX_SPC2_FW_VERSION = 29.2008.3224
MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa
$(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH)
$(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE)
-MLNX_SPC3_FW_VERSION = 30.2008.3216
+MLNX_SPC3_FW_VERSION = 30.2008.3224
MLNX_SPC3_FW_FILE = fw-SPC3-rel-$(subst .,_,$(MLNX_SPC3_FW_VERSION))-EVB.mfa
$(MLNX_SPC3_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH)
$(MLNX_SPC3_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC3_FW_FILE)
diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py
index da6b70f7890e..3bc169843a39 100644
--- a/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py
+++ b/platform/mellanox/mlnx-platform-api/sonic_platform/eeprom.py
@@ -7,9 +7,10 @@
#############################################################################
import os
import time
+import subprocess
from sonic_py_common.logger import Logger
-
+from sonic_py_common.device_info import get_platform, get_path_to_platform_dir
try:
from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo
except ImportError as e:
@@ -25,6 +26,16 @@
#
EEPROM_SYMLINK = "/var/run/hw-management/eeprom/vpd_info"
+platform_name = get_platform()
+if 'simx' in platform_name:
+ platform_path = get_path_to_platform_dir()
+
+ if not os.path.exists(EEPROM_SYMLINK):
+ if not os.path.exists(os.path.dirname(EEPROM_SYMLINK)):
+ os.makedirs(os.path.dirname(EEPROM_SYMLINK))
+
+ subprocess.check_call(['/usr/bin/xxd', '-r', '-p', 'syseeprom.hex', EEPROM_SYMLINK], cwd=platform_path)
+
class Eeprom(eeprom_tlvinfo.TlvInfoDecoder):
RETRIES = 3
diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/pcie.py b/platform/mellanox/mlnx-platform-api/sonic_platform/pcie.py
new file mode 100644
index 000000000000..96d590e5e2e3
--- /dev/null
+++ b/platform/mellanox/mlnx-platform-api/sonic_platform/pcie.py
@@ -0,0 +1,69 @@
+########################################################################
+#
+# Copyright (C) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
+#
+# Module contains a platform specific implementation of SONiC Platform
+# Base PCIe class
+#
+########################################################################
+import os
+import re
+
+try:
+ from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil
+except ImportError as e:
+ raise ImportError(str(e) + "- required module not found")
+
+SYSFS_PCI_DEVICE_PATH = '/sys/bus/pci/devices/'
+
+
+class Pcie(PcieUtil):
+ # check the current PCIe device with config file and return the result
+ # use bus from _device_id_to_bus_map instead of from yaml file
+ def get_pcie_check(self):
+ self.load_config_file()
+ for item_conf in self.confInfo:
+ id_conf = item_conf["id"]
+ dev_conf = item_conf["dev"]
+ fn_conf = item_conf["fn"]
+ bus_conf = self._device_id_to_bus_map.get(str(id_conf))
+ if bus_conf and self.check_pcie_sysfs(bus=int(bus_conf, base=16), device=int(dev_conf, base=16),
+ func=int(fn_conf, base=16)):
+ item_conf["result"] = "Passed"
+ else:
+ item_conf["result"] = "Failed"
+ return self.confInfo
+
+ # Create
+ def _create_device_id_to_bus_map(self):
+ self._device_id_to_bus_map = {}
+ self.load_config_file()
+ device_folders = os.listdir(SYSFS_PCI_DEVICE_PATH)
+ for folder in device_folders:
+ # For each folder in the sysfs tree we check if it matches the normal PCIe device folder pattern,
+ # If match we add the device id from the device file and the bus from the folder name to the map
+ #
+ # Example for device folder name: 0000:ff:0b.1
+ #
+ # The folder name is built from:
+ # 4 hex digit of domain
+ # colon ':'
+ # 2 hex digit of bus - this is what we are looking for
+ # colon ':'
+ # 2 hex digit of id
+ # dot '.'
+ # 1 digit of fn
+ pattern_for_device_folder = re.search('....:(..):..\..', folder)
+ if pattern_for_device_folder:
+ bus = pattern_for_device_folder.group(1)
+ with open(os.path.join('/sys/bus/pci/devices', folder, 'device'), 'r') as device_file:
+ # The 'device' file contain an hex repesantaion of the id key in the yaml file.
+ # Example of the file contact:
+ # 0x6fe2
+ # We will strip the new line character, and remove the 0x prefix that is not needed.
+ device_id = device_file.read().strip().replace('0x', '')
+ self._device_id_to_bus_map[device_id] = bus
+
+ def __init__(self, platform_path):
+ PcieUtil.__init__(self, platform_path)
+ self._create_device_id_to_bus_map()
diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py
index 60e4dcbc99e2..6e18d1fbd854 100644
--- a/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py
+++ b/platform/mellanox/mlnx-platform-api/sonic_platform/platform.py
@@ -7,6 +7,7 @@
try:
from sonic_platform_base.platform_base import PlatformBase
from sonic_platform.chassis import Chassis
+ from sonic_py_common.device_info import get_platform
from . import utils
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
@@ -15,11 +16,13 @@ class Platform(PlatformBase):
def __init__(self):
PlatformBase.__init__(self)
self._chassis = Chassis()
- self._chassis.initialize_psu()
self._chassis.initialize_eeprom()
- if utils.is_host():
- self._chassis.initialize_components()
- self._chassis.initizalize_system_led()
- else:
- self._chassis.initialize_fan()
- self._chassis.initialize_thermals()
+ platform_name = get_platform()
+ if "simx" not in platform_name:
+ self._chassis.initialize_psu()
+ if utils.is_host():
+ self._chassis.initialize_components()
+ self._chassis.initizalize_system_led()
+ else:
+ self._chassis.initialize_fan()
+ self._chassis.initialize_thermals()
diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/watchdog.py b/platform/mellanox/mlnx-platform-api/sonic_platform/watchdog.py
index 06780627d52e..0737b0446671 100644
--- a/platform/mellanox/mlnx-platform-api/sonic_platform/watchdog.py
+++ b/platform/mellanox/mlnx-platform-api/sonic_platform/watchdog.py
@@ -275,6 +275,9 @@ def get_watchdog():
if device.startswith("watchdog") and is_mlnx_wd_main(device):
watchdog_main_device_name = device
+ if watchdog_main_device_name is None:
+ return None
+
watchdog_device_path = "/dev/{}".format(watchdog_main_device_name)
watchdog = None
diff --git a/platform/mellanox/mlnx-sai.mk b/platform/mellanox/mlnx-sai.mk
index 49d2fdb14b7f..7929b8c75181 100644
--- a/platform/mellanox/mlnx-sai.mk
+++ b/platform/mellanox/mlnx-sai.mk
@@ -1,6 +1,6 @@
# Mellanox SAI
-MLNX_SAI_VERSION = SAIRel1.19.0
+MLNX_SAI_VERSION = SAIRel1.19.1
export MLNX_SAI_VERSION
diff --git a/platform/mellanox/mlnx-sai/SAI-Implementation b/platform/mellanox/mlnx-sai/SAI-Implementation
index a2ec007c52bb..be35fa45f163 160000
--- a/platform/mellanox/mlnx-sai/SAI-Implementation
+++ b/platform/mellanox/mlnx-sai/SAI-Implementation
@@ -1 +1 @@
-Subproject commit a2ec007c52bb5ebc2eeaa8b73375a2e3e967391a
+Subproject commit be35fa45f163f6e1a36368f1776dc5fc745fc845
diff --git a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers
index 0354f2b1733c..3a0e3a26de2e 160000
--- a/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers
+++ b/platform/mellanox/sdk-src/sx-kernel/Switch-SDK-drivers
@@ -1 +1 @@
-Subproject commit 0354f2b1733cadc15443d12ed107e80725eccd47
+Subproject commit 3a0e3a26de2e1384b7ed216dc4cd842b36655e27
diff --git a/platform/mellanox/sdk.mk b/platform/mellanox/sdk.mk
index 9690d2d06ea6..67f8ab3fced9 100644
--- a/platform/mellanox/sdk.mk
+++ b/platform/mellanox/sdk.mk
@@ -1,6 +1,6 @@
MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/
MLNX_SDK_PKG_BASE_PATH = $(MLNX_SDK_BASE_PATH)/$(BLDENV)/
-MLNX_SDK_VERSION = 4.4.3216
+MLNX_SDK_VERSION = 4.4.3222
MLNX_SDK_ISSU_VERSION = 101
MLNX_SDK_DEB_VERSION = $(subst -,.,$(subst _,.,$(MLNX_SDK_VERSION)))
diff --git a/platform/template/docker-gbsyncd-base.mk b/platform/template/docker-gbsyncd-base.mk
index aa4f574141b2..579f76381010 100644
--- a/platform/template/docker-gbsyncd-base.mk
+++ b/platform/template/docker-gbsyncd-base.mk
@@ -27,4 +27,3 @@ $(DOCKER_GBSYNCD_BASE)_CONTAINER_NAME = gbsyncd
$(DOCKER_GBSYNCD_BASE)_RUN_OPT += --net=host --privileged -t
$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /host/machine.conf:/etc/machine.conf
$(DOCKER_GBSYNCD_BASE)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
-
diff --git a/rules/config b/rules/config
index 3af8e706e0f7..9c77aee1f0c0 100644
--- a/rules/config
+++ b/rules/config
@@ -51,6 +51,8 @@ DEFAULT_PASSWORD = YourPaSsWoRd
# ENABLE_ZTP - installs Zero Touch Provisioning support.
# ENABLE_ZTP = y
+# INCLUDE_PDE - Enable platform development enviroment
+# INCLUDE_PDE = y
# SHUTDOWN_BGP_ON_START - if set to y all bgp sessions will be in admin down state when
# bgp service starts.
# SHUTDOWN_BGP_ON_START = y
@@ -139,24 +141,30 @@ INCLUDE_RESTAPI = n
# INCLUDE_NAT - build docker-nat for nat support
INCLUDE_NAT = y
+# INCLUDE_DHCP_RELAY - build and install dhcp-relay package
+INCLUDE_DHCP_RELAY = y
+
# TELEMETRY_WRITABLE - Enable write/config operations via the gNMI interface.
# Uncomment to enable:
# TELEMETRY_WRITABLE = y
+
+# INCLUDE_MACSEC - build docker-macsec for macsec support
+INCLUDE_MACSEC = y
+
# INCLUDE_KUBERNETES - if set to y kubernetes packages are installed to be able to
# run as worker node in kubernetes cluster.
INCLUDE_KUBERNETES = n
-# INCLUDE_MACSEC - build docker-macsec for macsec support
-INCLUDE_MACSEC = y
+KUBE_DOCKER_PROXY = http://172.16.1.1:3128/
# KUBERNETES_VERSION - Set to the required version.
# K8s_GCR_IO_PAUSE_VERSION - Version of k8s universal pause container image
# These are Used *only* when INCLUDE_KUBERNETES=y
# NOTE: As a worker node it has to run version compatible to kubernetes master.
#
-KUBERNETES_VERSION = 1.18.6
-KUBERNETES_CNI_VERSION = 0.8.6
-K8s_GCR_IO_PAUSE_VERSION = 3.2
+KUBERNETES_VERSION = 1.21.1
+KUBERNETES_CNI_VERSION = 0.8.7
+K8s_GCR_IO_PAUSE_VERSION = 3.4.1
# SONIC_ENABLE_IMAGE_SIGNATURE - enable image signature
# To not use the auto-generated self-signed certificate, the required files to sign the image as below:
@@ -185,7 +193,6 @@ SONIC_VERSION_CONTROL_COMPONENTS ?= none
# SONiC docker registry
#
-# Uncomment below line to enable pulling sonic-slave docker from registry
-# ENABLE_DOCKER_BASE_PULL = y
-REGISTRY_PORT=443
-REGISTRY_SERVER=sonicdev-microsoft.azurecr.io
+# Set the env variable ENABLE_DOCKER_BASE_PULL = y to enable pulling sonic-slave docker from registry
+REGISTRY_PORT ?= 443
+REGISTRY_SERVER ?= sonicdev-microsoft.azurecr.io
diff --git a/rules/docker-dhcp-relay.mk b/rules/docker-dhcp-relay.mk
index a4cb3573e462..a8b33c5bc74c 100644
--- a/rules/docker-dhcp-relay.mk
+++ b/rules/docker-dhcp-relay.mk
@@ -15,17 +15,43 @@ $(DOCKER_DHCP_RELAY)_DBG_IMAGE_PACKAGES = $($(DOCKER_CONFIG_ENGINE_BUSTER)_DBG_I
$(DOCKER_DHCP_RELAY)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BUSTER)
+$(DOCKER_DHCP_RELAY)_INSTALL_PYTHON_WHEELS = $(SONIC_UTILITIES_PY3)
+$(DOCKER_DHCP_RELAY)_INSTALL_DEBS = $(PYTHON3_SWSSCOMMON)
+
$(DOCKER_DHCP_RELAY)_VERSION = 1.0.0
$(DOCKER_DHCP_RELAY)_PACKAGE_NAME = dhcp-relay
+$(DOCKER_DHCP_RELAY)_PACKAGE_DEPENDS = database^1.0.0
-SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY)
-SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY)
+$(DOCKER_DHCP_RELAY)_SERVICE_REQUIRES = updategraph
+$(DOCKER_DHCP_RELAY)_SERVICE_AFTER = swss syncd teamd
+$(DOCKER_DHCP_RELAY)_SERVICE_BEFORE = ntp-config
+$(DOCKER_DHCP_RELAY)_SERVICE_DEPENDENT_OF = swss
+SONIC_DOCKER_IMAGES += $(DOCKER_DHCP_RELAY)
SONIC_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG)
-SONIC_INSTALL_DOCKER_DBG_IMAGES += $(DOCKER_DHCP_RELAY_DBG)
+
+ifeq ($(INCLUDE_KUBERNETES),y)
+$(DOCKER_DHCP_RELAY)_DEFAULT_FEATURE_OWNER = kube
+endif
+
+$(DOCKER_DHCP_RELAY)_DEFAULT_FEATURE_STATE_ENABLED = y
+
+ifeq ($(INCLUDE_DHCP_RELAY),y)
+ifeq ($(INSTALL_DEBUG_TOOLS),y)
+SONIC_PACKAGES_LOCAL += $(DOCKER_DHCP_RELAY_DBG)
+else
+SONIC_PACKAGES_LOCAL += $(DOCKER_DHCP_RELAY)
+endif
+endif
$(DOCKER_DHCP_RELAY)_CONTAINER_NAME = dhcp_relay
-$(DOCKER_DHCP_RELAY)_RUN_OPT += --privileged -t
-$(DOCKER_DHCP_RELAY)_RUN_OPT += -v /etc/sonic:/etc/sonic:ro
-$(DOCKER_DHCP_RELAY)_RUN_OPT += -v /usr/share/sonic/scripts:/usr/share/sonic/scripts:ro
+$(DOCKER_DHCP_RELAY)_CONTAINER_PRIVILEGED = true
+$(DOCKER_DHCP_RELAY)_CONTAINER_VOLUMES += /etc/sonic:/etc/sonic:ro
+$(DOCKER_DHCP_RELAY)_CONTAINER_VOLUMES += /usr/share/sonic/scripts:/usr/share/sonic/scripts:ro
+$(DOCKER_DHCP_RELAY)_CONTAINER_TMPFS += /tmp/
+$(DOCKER_DHCP_RELAY)_CONTAINER_TMPFS += /var/tmp/
+
+$(DOCKER_DHCP_RELAY)_CLI_CONFIG_PLUGIN = /cli/config/plugins/dhcp_relay.py
+$(DOCKER_DHCP_RELAY)_CLI_SHOW_PLUGIN = /cli/show/plugins/show_dhcp_relay.py
+
$(DOCKER_DHCP_RELAY)_FILES += $(SUPERVISOR_PROC_EXIT_LISTENER_SCRIPT)
diff --git a/rules/docker-fpm-frr.mk b/rules/docker-fpm-frr.mk
index d7b38405cb7c..37c3a62f1855 100644
--- a/rules/docker-fpm-frr.mk
+++ b/rules/docker-fpm-frr.mk
@@ -18,6 +18,10 @@ $(DOCKER_FPM_FRR)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER)
$(DOCKER_FPM_FRR)_VERSION = 1.0.0
$(DOCKER_FPM_FRR)_PACKAGE_NAME = fpm-frr
+$(DOCKER_FPM_FRR)_WARM_SHUTDOWN_BEFORE = swss
+$(DOCKER_FPM_FRR)_WARM_SHUTDOWN_AFTER = radv
+$(DOCKER_FPM_FRR)_FAST_SHUTDOWN_BEFORE = swss
+$(DOCKER_FPM_FRR)_FAST_SHUTDOWN_AFTER = radv
SONIC_DOCKER_IMAGES += $(DOCKER_FPM_FRR)
diff --git a/rules/docker-lldp.mk b/rules/docker-lldp.mk
index f2432ab6335f..2c3d41a46d1a 100644
--- a/rules/docker-lldp.mk
+++ b/rules/docker-lldp.mk
@@ -18,6 +18,8 @@ $(DOCKER_LLDP)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER)
$(DOCKER_LLDP)_VERSION = 1.0.0
$(DOCKER_LLDP)_PACKAGE_NAME = lldp
+$(DOCKER_LLDP)_WARM_SHUTDOWN_BEFORE = swss
+$(DOCKER_LLDP)_FAST_SHUTDOWN_BEFORE = swss
SONIC_DOCKER_IMAGES += $(DOCKER_LLDP)
SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_LLDP)
diff --git a/rules/docker-nat.mk b/rules/docker-nat.mk
index 6c958bb8ecfa..b5ead85d1919 100644
--- a/rules/docker-nat.mk
+++ b/rules/docker-nat.mk
@@ -15,6 +15,8 @@ $(DOCKER_NAT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER)
$(DOCKER_NAT)_VERSION = 1.0.0
$(DOCKER_NAT)_PACKAGE_NAME = nat
+$(DOCKER_NAT)_WARM_SHUTDOWN_BEFORE = swss
+$(DOCKER_NAT)_FAST_SHUTDOWN_BEFORE = swss
ifeq ($(INCLUDE_NAT), y)
SONIC_DOCKER_IMAGES += $(DOCKER_NAT)
diff --git a/rules/docker-orchagent.mk b/rules/docker-orchagent.mk
index f545a64cb98e..3273b675905d 100644
--- a/rules/docker-orchagent.mk
+++ b/rules/docker-orchagent.mk
@@ -19,6 +19,8 @@ $(DOCKER_ORCHAGENT)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER)
$(DOCKER_ORCHAGENT)_VERSION = 1.0.0
$(DOCKER_ORCHAGENT)_PACKAGE_NAME = swss
+$(DOCKER_ORCHAGENT)_WARM_SHUTDOWN_BEFORE = syncd
+$(DOCKER_ORCHAGENT)_FAST_SHUTDOWN_BEFORE = syncd
SONIC_DOCKER_IMAGES += $(DOCKER_ORCHAGENT)
SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ORCHAGENT)
diff --git a/rules/docker-router-advertiser.mk b/rules/docker-router-advertiser.mk
index 083c83dbb649..14c896d820ae 100644
--- a/rules/docker-router-advertiser.mk
+++ b/rules/docker-router-advertiser.mk
@@ -15,6 +15,8 @@ $(DOCKER_ROUTER_ADVERTISER)_LOAD_DOCKERS = $(DOCKER_CONFIG_ENGINE_BUSTER)
$(DOCKER_ROUTER_ADVERTISER)_VERSION = 1.0.0
$(DOCKER_ROUTER_ADVERTISER)_PACKAGE_NAME = radv
+$(DOCKER_ROUTER_ADVERTISER)_WARM_SHUTDOWN_BEFORE = swss
+$(DOCKER_ROUTER_ADVERTISER)_FAST_SHUTDOWN_BEFORE = swss
SONIC_DOCKER_IMAGES += $(DOCKER_ROUTER_ADVERTISER)
SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_ROUTER_ADVERTISER)
diff --git a/rules/docker-sflow.mk b/rules/docker-sflow.mk
index 7291e5d216bb..5762dd869ac7 100644
--- a/rules/docker-sflow.mk
+++ b/rules/docker-sflow.mk
@@ -15,6 +15,8 @@ $(DOCKER_SFLOW)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER)
$(DOCKER_SFLOW)_VERSION = 1.0.0
$(DOCKER_SFLOW)_PACKAGE_NAME = sflow
+$(DOCKER_SFLOW)_WARM_SHUTDOWN_BEFORE = swss
+$(DOCKER_SFLOW)_FAST_SHUTDOWN_BEFORE = swss
SONIC_DOCKER_IMAGES += $(DOCKER_SFLOW)
ifeq ($(INCLUDE_SFLOW), y)
diff --git a/rules/docker-teamd.mk b/rules/docker-teamd.mk
index c6955bea5ca3..9135c45aea3e 100644
--- a/rules/docker-teamd.mk
+++ b/rules/docker-teamd.mk
@@ -17,6 +17,9 @@ $(DOCKER_TEAMD)_LOAD_DOCKERS += $(DOCKER_CONFIG_ENGINE_BUSTER)
$(DOCKER_TEAMD)_VERSION = 1.0.0
$(DOCKER_TEAMD)_PACKAGE_NAME = teamd
+$(DOCKER_TEAMD)_WARM_SHUTDOWN_BEFORE = syncd
+$(DOCKER_TEAMD)_WARM_SHUTDOWN_AFTER = swss
+$(DOCKER_TEAMD)_FAST_SHUTDOWN_BEFORE = swss
SONIC_DOCKER_IMAGES += $(DOCKER_TEAMD)
SONIC_INSTALL_DOCKER_IMAGES += $(DOCKER_TEAMD)
diff --git a/rules/functions b/rules/functions
index 84f548218a6d..5873b2db1b87 100644
--- a/rules/functions
+++ b/rules/functions
@@ -187,6 +187,10 @@ define generate_manifest
$(eval export after=$($(1).gz_SERVICE_AFTER))
$(eval export before=$($(1).gz_SERVICE_BEFORE))
$(eval export dependent_of=$($(1).gz_SERVICE_DEPENDENT_OF))
+ $(eval export warm_shutdown_after=$($*.gz_WARM_SHUTDOWN_AFTER))
+ $(eval export warm_shutdown_before=$($*.gz_WARM_SHUTDOWN_BEFORE))
+ $(eval export fast_shutdown_after=$($*.gz_FAST_SHUTDOWN_AFTER))
+ $(eval export fast_shutdown_before=$($*.gz_FAST_SHUTDOWN_BEFORE))
$(eval export privileged=$($(1).gz_CONTAINER_PRIVILEGED))
$(eval export volumes=$($(1).gz_CONTAINER_VOLUMES))
$(eval export tmpfs=$($(1).gz_CONTAINER_TMPFS))
diff --git a/rules/sonic-config.dep b/rules/sonic-config.dep
index 794d76b28496..ae8569326eea 100644
--- a/rules/sonic-config.dep
+++ b/rules/sonic-config.dep
@@ -4,7 +4,7 @@ SPATH := $($(SONIC_CONFIG_ENGINE_PY2)_SRC_PATH)
DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/sonic-config.mk rules/sonic-config.dep
DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST)
DEP_FILES += $(shell git ls-files $(SPATH))
-DEP_FILES += files/image_config/interfaces/interfaces.j2 dockers/docker-orchagent/ports.json.j2 dockers/docker-dhcp-relay/wait_for_intf.sh.j2 dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 dockers/docker-lldp/lldpd.conf.j2 dockers/docker-orchagent/ipinip.json.j2 device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/qos.json.j2 files/build_templates/qos_config.j2 device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/qos.json.j2 dockers/docker-orchagent/switch.json.j2 files/image_config/constants/constants.yml
+DEP_FILES += files/image_config/interfaces/interfaces.j2 dockers/docker-orchagent/ports.json.j2 dockers/docker-dhcp-relay/wait_for_intf.sh.j2 dockers/docker-dhcp-relay/docker-dhcp-relay.supervisord.conf.j2 dockers/docker-lldp/lldpd.conf.j2 dockers/docker-orchagent/ipinip.json.j2 $(wildcard device/arista/x86_64-arista_7050_qx32s/Arista-7050-QX-32S/*.j2 device/dell/x86_64-dell_s6100_c2538-r0/Force10-S6100/*.j2) files/build_templates/qos_config.j2 dockers/docker-orchagent/switch.json.j2 files/image_config/constants/constants.yml
$(SONIC_CONFIG_ENGINE_PY2)_CACHE_MODE := GIT_CONTENT_SHA
$(SONIC_CONFIG_ENGINE_PY2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST)
diff --git a/rules/system-health.mk b/rules/system-health.mk
index bafc09daa70f..00cd48858d32 100644
--- a/rules/system-health.mk
+++ b/rules/system-health.mk
@@ -3,7 +3,7 @@
SYSTEM_HEALTH = system_health-1.0-py3-none-any.whl
$(SYSTEM_HEALTH)_SRC_PATH = $(SRC_PATH)/system-health
$(SYSTEM_HEALTH)_PYTHON_VERSION = 3
-$(SYSTEM_HEALTH)_DEPENDS = $(SONIC_PY_COMMON_PY3) $(SWSSSDK_PY3) $(SONIC_CONFIG_ENGINE_PY3)
+$(SYSTEM_HEALTH)_DEPENDS = $(SONIC_PY_COMMON_PY3) $(SONIC_CONFIG_ENGINE_PY3)
SONIC_PYTHON_WHEELS += $(SYSTEM_HEALTH)
export system_health_py3_wheel_path="$(addprefix $(PYTHON_WHEELS_PATH)/,$(SYSTEM_HEALTH))"
diff --git a/scripts/docker_version_control.sh b/scripts/docker_version_control.sh
new file mode 100755
index 000000000000..41e536f08073
--- /dev/null
+++ b/scripts/docker_version_control.sh
@@ -0,0 +1,42 @@
+# This script is for reproducible build.
+# Reproducible build for docker enabled: Before build docker image, this script will change image:tag to image:sha256 in DOCKERFILE.
+# And record image sha256 to a target file.
+#!/bin/bash
+
+IMAGENAME=$1
+DOCKERFILE=$2
+ARCH=$3
+DOCKERFILE_TARGE=$4
+DISTRO=$5
+
+version_file=files/build/versions/default/versions-docker
+new_version_file=target/versions/default/versions-docker
+mkdir -p target/versions/default
+
+. src/sonic-build-hooks/buildinfo/config/buildinfo.config
+
+image_tag=`grep "^FROM " $DOCKERFILE | awk '{print$2}'`
+image=`echo $image_tag | cut -f1 -d:`
+tag=`echo $image_tag | cut -f2 -d:`
+
+# if docker image not in white list, exit
+if [[ "$IMAGENAME" != sonic-slave-* ]] && [[ "$IMAGENAME" != docker-base* ]];then
+ exit 0
+fi
+
+if [[ ",$SONIC_VERSION_CONTROL_COMPONENTS," == *,all,* ]] || [[ ",$SONIC_VERSION_CONTROL_COMPONENTS," == *,docker,* ]]; then
+ if [ -f $version_file ];then
+ hash_value=`grep "${ARCH}:${image_tag}" $version_file | awk -F== '{print$2}'`
+ fi
+ if [ -z $hash_value ];then
+ hash_value=unknown
+ fi
+ oldimage=${image_tag//\//\\/}
+ newimage="${oldimage}@$hash_value"
+ sed -i "s/$oldimage/$newimage/" $DOCKERFILE
+else
+ hash_value=`docker pull $image_tag | grep Digest | awk '{print$2}'`
+fi
+if [[ "$hash_value" != "unknown" ]];then
+ echo -e "${ARCH}:${image_tag}==$hash_value" >> $new_version_file
+fi
diff --git a/scripts/prepare_docker_buildinfo.sh b/scripts/prepare_docker_buildinfo.sh
index aa3aaaa4bed5..d2b2c57185d1 100755
--- a/scripts/prepare_docker_buildinfo.sh
+++ b/scripts/prepare_docker_buildinfo.sh
@@ -22,7 +22,10 @@ if [ -z "$DISTRO" ]; then
[ -z "$DISTRO" ] && DISTRO=jessie
fi
-DOCKERFILE_PRE_SCRIPT='# Auto-Generated for buildinfo
+# add script for reproducible build. using sha256 instead of tag for docker base image.
+scripts/docker_version_control.sh $@
+
+DOCKERFILE_PRE_SCRIPT='# Auto-Generated for buildinfo
COPY ["buildinfo", "/usr/local/share/buildinfo"]
RUN dpkg -i /usr/local/share/buildinfo/sonic-build-hooks_1.0_all.deb
RUN pre_run_buildinfo'
diff --git a/scripts/versions_manager.py b/scripts/versions_manager.py
index a59d85dd8a96..3a46aaafe229 100755
--- a/scripts/versions_manager.py
+++ b/scripts/versions_manager.py
@@ -374,10 +374,12 @@ def __init__(self, target_path="./target", source_path='.'):
def load_from_target(self):
dockers_path = os.path.join(self.target_path, 'versions/dockers')
build_path = os.path.join(self.target_path, 'versions/build')
+ default_path = os.path.join(self.target_path, 'versions/default')
modules = {}
self.modules = modules
file_paths = glob.glob(dockers_path + '/*')
file_paths += glob.glob(build_path + '/build-*')
+ file_paths += glob.glob(default_path)
file_paths.append(os.path.join(self.target_path, 'versions/host-image'))
file_paths.append(os.path.join(self.target_path, 'versions/host-base-image'))
for file_path in file_paths:
diff --git a/slave.mk b/slave.mk
index eb3f099103db..6f751c36a943 100644
--- a/slave.mk
+++ b/slave.mk
@@ -39,6 +39,8 @@ STRETCH_DEBS_PATH = $(TARGET_PATH)/debs/stretch
STRETCH_FILES_PATH = $(TARGET_PATH)/files/stretch
BUSTER_DEBS_PATH = $(TARGET_PATH)/debs/buster
BUSTER_FILES_PATH = $(TARGET_PATH)/files/buster
+BULLSEYE_DEBS_PATH = $(TARGET_PATH)/debs/bullseye
+BULLSEYE_FILES_PATH = $(TARGET_PATH)/files/bullseye
DBG_IMAGE_MARK = dbg
DBG_SRC_ARCHIVE_FILE = $(TARGET_PATH)/sonic_src.tar.gz
DPKG_ADMINDIR_PATH = /sonic/dpkg
@@ -49,7 +51,11 @@ CONFIGURED_ARCH := $(shell [ -f .arch ] && cat .arch || echo amd64)
ifeq ($(PLATFORM_ARCH),)
override PLATFORM_ARCH = $(CONFIGURED_ARCH)
endif
+ifeq ($(BLDENV),bullseye)
+IMAGE_DISTRO := bullseye
+else
IMAGE_DISTRO := buster
+endif
IMAGE_DISTRO_DEBS_PATH = $(TARGET_PATH)/debs/$(IMAGE_DISTRO)
IMAGE_DISTRO_FILES_PATH = $(TARGET_PATH)/files/$(IMAGE_DISTRO)
@@ -79,10 +85,12 @@ configure :
@mkdir -p $(JESSIE_DEBS_PATH)
@mkdir -p $(STRETCH_DEBS_PATH)
@mkdir -p $(BUSTER_DEBS_PATH)
+ @mkdir -p $(BULLSEYE_DEBS_PATH)
@mkdir -p $(FILES_PATH)
@mkdir -p $(JESSIE_FILES_PATH)
@mkdir -p $(STRETCH_FILES_PATH)
@mkdir -p $(BUSTER_FILES_PATH)
+ @mkdir -p $(BULLSEYE_FILES_PATH)
@mkdir -p $(PYTHON_DEBS_PATH)
@mkdir -p $(PYTHON_WHEELS_PATH)
@mkdir -p $(DPKG_ADMINDIR_PATH)
@@ -241,6 +249,7 @@ $(info "HTTP_PROXY" : "$(HTTP_PROXY)")
$(info "HTTPS_PROXY" : "$(HTTPS_PROXY)")
$(info "NO_PROXY" : "$(NO_PROXY)")
$(info "ENABLE_ZTP" : "$(ENABLE_ZTP)")
+$(info "INCLUDE_PDE" : "$(INCLUDE_PDE)")
$(info "SONIC_DEBUGGING_ON" : "$(SONIC_DEBUGGING_ON)")
$(info "SONIC_PROFILING_ON" : "$(SONIC_PROFILING_ON)")
$(info "KERNEL_PROCURE_METHOD" : "$(KERNEL_PROCURE_METHOD)")
@@ -256,11 +265,13 @@ $(info "ENABLE_HOST_SERVICE_ON_START" : "$(ENABLE_HOST_SERVICE_ON_START)")
$(info "INCLUDE_RESTAPI" : "$(INCLUDE_RESTAPI)")
$(info "INCLUDE_SFLOW" : "$(INCLUDE_SFLOW)")
$(info "INCLUDE_NAT" : "$(INCLUDE_NAT)")
+$(info "INCLUDE_DHCP_RELAY" : "$(INCLUDE_DHCP_RELAY)")
$(info "INCLUDE_KUBERNETES" : "$(INCLUDE_KUBERNETES)")
$(info "INCLUDE_MACSEC" : "$(INCLUDE_MACSEC)")
$(info "TELEMETRY_WRITABLE" : "$(TELEMETRY_WRITABLE)")
$(info "PDDF_SUPPORT" : "$(PDDF_SUPPORT)")
$(info "MULTIARCH_QEMU_ENVIRON" : "$(MULTIARCH_QEMU_ENVIRON)")
+$(info "SONIC_VERSION_CONTROL_COMPONENTS": "$(SONIC_VERSION_CONTROL_COMPONENTS)")
$(info )
else
$(info SONiC Build System for $(CONFIGURED_PLATFORM):$(CONFIGURED_ARCH))
@@ -928,9 +939,11 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
export include_mgmt_framework="$(INCLUDE_MGMT_FRAMEWORK)"
export include_iccpd="$(INCLUDE_ICCPD)"
export pddf_support="$(PDDF_SUPPORT)"
+ export include_pde="$(INCLUDE_PDE)"
export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)"
export default_buffer_model="$(SONIC_BUFFER_MODEL)"
export include_kubernetes="$(INCLUDE_KUBERNETES)"
+ export kube_docker_proxy="$(KUBE_DOCKER_PROXY)"
export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)"
export installer_debs="$(addprefix $(IMAGE_DISTRO_DEBS_PATH)/,$($*_INSTALLS))"
export lazy_installer_debs="$(foreach deb, $($*_LAZY_INSTALLS),$(foreach device, $($(deb)_PLATFORM),$(addprefix $(device)@, $(IMAGE_DISTRO_DEBS_PATH)/$(deb))))"
diff --git a/sonic-slave-bullseye/Dockerfile.j2 b/sonic-slave-bullseye/Dockerfile.j2
new file mode 100644
index 000000000000..21f27e562838
--- /dev/null
+++ b/sonic-slave-bullseye/Dockerfile.j2
@@ -0,0 +1,496 @@
+{%- if CONFIGURED_ARCH == "armhf" and MULTIARCH_QEMU_ENVIRON == "y" %}
+FROM multiarch/qemu-user-static:x86_64-arm-5.0.0-2 as qemu
+FROM multiarch/debian-debootstrap:armhf-bullseye
+COPY --from=qemu /usr/bin/qemu-arm-static /usr/bin
+{%- elif CONFIGURED_ARCH == "arm64" and MULTIARCH_QEMU_ENVIRON == "y" %}
+FROM multiarch/debian-debootstrap:arm64-bullseye
+{%- else -%}
+FROM debian:bullseye
+{%- endif %}
+
+MAINTAINER gulv@microsoft.com
+
+COPY ["no-check-valid-until", "/etc/apt/apt.conf.d/"]
+
+## TODO: Re-add in any necessary mirror URLs here as they become available
+RUN echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian/ bullseye main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb-src [arch=amd64] http://debian-archive.trafficmanager.net/debian/ bullseye main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb [arch=amd64] http://debian-archive.trafficmanager.net/debian bullseye-backports main" >> /etc/apt/sources.list
+
+{%- if CONFIGURED_ARCH == "armhf" %}
+RUN echo "deb [arch=armhf] http://deb.debian.org/debian bullseye main contrib non-free" > /etc/apt/sources.list && \
+ echo "deb-src [arch=armhf] http://deb.debian.org/debian bullseye main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb [arch=armhf] http://deb.debian.org/debian bullseye-updates main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb-src [arch=armhf] http://deb.debian.org/debian bullseye-updates main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb [arch=armhf] http://security.debian.org bullseye/updates main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb-src [arch=armhf] http://security.debian.org bullseye/updates main contrib non-free" >> /etc/apt/sources.list && \
+ echo 'deb [arch=armhf] http://ftp.debian.org/debian bullseye-backports main' >> /etc/apt/sources.list && \
+ echo "deb [arch=armhf] http://packages.trafficmanager.net/debian/debian bullseye main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb [arch=armhf] http://packages.trafficmanager.net/debian/debian bullseye-updates main contrib non-free" >> /etc/apt/sources.list
+{%- elif CONFIGURED_ARCH == "arm64" %}
+RUN echo "deb [arch=arm64] http://deb.debian.org/debian bullseye main contrib non-free" > /etc/apt/sources.list && \
+ echo "deb-src [arch=arm64] http://deb.debian.org/debian bullseye main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb [arch=arm64] http://deb.debian.org/debian bullseye-updates main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb-src [arch=arm64] http://deb.debian.org/debian bullseye-updates main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb [arch=arm64] http://security.debian.org bullseye/updates main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb-src [arch=arm64] http://security.debian.org bullseye/updates main contrib non-free" >> /etc/apt/sources.list && \
+ echo 'deb [arch=arm64] http://ftp.debian.org/debian bullseye-backports main' >> /etc/apt/sources.list && \
+ echo "deb [arch=arm64] http://packages.trafficmanager.net/debian/debian bullseye main contrib non-free" >> /etc/apt/sources.list && \
+ echo "deb [arch=arm64] http://packages.trafficmanager.net/debian/debian bullseye-updates main contrib non-free" >> /etc/apt/sources.list
+{%- endif %}
+
+## Make apt-get non-interactive
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update && apt-get install -y \
+ apt-utils \
+ default-jre-headless \
+ openssh-server \
+ curl \
+ wget \
+ unzip \
+ git \
+ build-essential \
+ libtool \
+ lintian \
+ sudo \
+ dh-make \
+ dh-exec \
+ kmod \
+ libtinyxml2-dev \
+ python \
+ python3 \
+ python3-pip \
+ libncurses5-dev \
+ texinfo \
+ dh-autoreconf \
+ doxygen \
+ devscripts \
+ git-buildpackage \
+ perl-modules \
+ libswitch-perl \
+ libzmq5 \
+ libzmq3-dev \
+ jq \
+# For quagga build
+ libreadline-dev \
+ texlive-latex-base \
+ texlive-plain-generic \
+ texlive-fonts-recommended \
+ libpam0g-dev \
+ libpam-dev \
+ libcap-dev \
+ imagemagick \
+ ghostscript \
+ groff \
+ libpcre3-dev \
+ gawk \
+ chrpath \
+# For frr build
+ libc-ares-dev \
+ libsnmp-dev \
+ libjson-c-dev \
+ libsystemd-dev \
+ python3-ipaddr \
+ libcmocka-dev \
+ python3-all-dev \
+ python3-all-dbg \
+ install-info \
+ logrotate \
+# For libnl3 (local) build
+ cdbs \
+# For SAI meta build
+ libxml-simple-perl \
+ graphviz \
+ aspell \
+# For linux build
+ bc \
+ fakeroot \
+ build-essential \
+ devscripts \
+ quilt \
+ stgit \
+# For platform-modules build
+ module-assistant \
+# For thrift build\
+ gem2deb \
+ libevent-dev \
+ libglib2.0-dev \
+ python3-all-dev \
+ python3-twisted \
+ phpunit \
+ libbit-vector-perl \
+ openjdk-11-jdk \
+ javahelper \
+ maven-debian-helper \
+ ant \
+ libhttpclient-java \
+ libslf4j-java \
+ libservlet3.1-java \
+ pkg-php-tools \
+# For mellanox sdk build
+ libpcre3 \
+ libpcre3-dev \
+ byacc \
+ flex \
+ libglib2.0-dev \
+ bison \
+ expat \
+ libexpat1-dev \
+ dpatch \
+ libdb-dev \
+ libiptc-dev \
+ libxtables-dev \
+# For mellanox sai build
+ libtool-bin \
+ libxml2-dev \
+# For BFN sdk build
+ libusb-1.0-0-dev \
+ libcurl3-nss-dev \
+ libunwind8-dev \
+ telnet \
+ libc-ares2 \
+ libgoogle-perftools4 \
+# For build image
+ cpio \
+ squashfs-tools \
+ zip \
+# For broadcom sdk build
+{%- if CONFIGURED_ARCH == "amd64" %}
+ linux-compiler-gcc-10-x86 \
+{%- endif %}
+{%- if CONFIGURED_ARCH == "armhf" %}
+ linux-compiler-gcc-10-arm \
+{%- endif %}
+ linux-kbuild-5.10 \
+# teamd build
+ libdaemon-dev \
+ libdbus-1-dev \
+ libjansson-dev \
+# For cavium sdk build
+ libpcap-dev \
+ dnsutils \
+ libusb-dev \
+# For debian image reconfiguration
+ augeas-tools \
+# For p4 build
+ libyaml-dev \
+ libevent-dev \
+ libjudy-dev \
+ libedit-dev \
+ libnanomsg-dev \
+ python3-stdeb \
+# For redis build
+ libjemalloc-dev \
+ liblua5.1-0-dev \
+ lua-bitop-dev \
+ lua-cjson-dev \
+# For mft kernel module build
+ dkms \
+# For Jenkins static analysis, unit testing and code coverage
+ cppcheck \
+ clang \
+ pylint \
+ python3-pytest \
+ python3-pytest \
+ gcovr \
+ python3-pytest-cov \
+ python3-pytest-cov \
+ python3-parse \
+# For snmpd
+ default-libmysqlclient-dev \
+ libssl-dev \
+ libperl-dev \
+ libpci-dev \
+ libpci3 \
+ libsensors5 \
+ libsensors4-dev \
+ libwrap0-dev \
+# For lldpd
+ debhelper \
+ autotools-dev \
+ libbsd-dev \
+ pkg-config \
+ check \
+# For mpdecimal
+ docutils-common \
+ libjs-sphinxdoc \
+ libjs-underscore \
+ python3-docutils \
+ python3-jinja2 \
+ python3-markupsafe \
+ python3-pygments \
+ python3-roman \
+ python3-sphinx \
+ sphinx-common \
+ python3-sphinx \
+# For sonic config engine testing
+ python3-dev \
+{%- if CONFIGURED_ARCH == "armhf" or CONFIGURED_ARCH == "arm64" %}
+ libxslt-dev \
+{%- endif %}
+# For lockfile
+ procmail \
+# For gtest
+ libgtest-dev \
+ cmake \
+# For pam_tacplus build
+ autoconf-archive \
+# For iproute2
+ cm-super-minimal \
+ libatm1-dev \
+ libelf-dev \
+ libmnl-dev \
+ libselinux1-dev \
+ linuxdoc-tools \
+ lynx \
+ texlive-latex-extra \
+ texlive-latex-recommended \
+ iproute2 \
+# For bash
+ texi2html \
+# For initramfs
+ shellcheck \
+ bash-completion \
+{%- if CONFIGURED_ARCH == "amd64" %}
+# For sonic vs image build
+ dosfstools \
+ qemu-kvm \
+ libvirt-clients \
+{%- endif %}
+# For ntp
+ autogen \
+ libopts25-dev \
+ pps-tools \
+ dh-apparmor \
+# For lm-sensors
+ librrd8 \
+ librrd-dev \
+ rrdtool \
+# For smartmontools 6.6-1
+ automake1.11 \
+ libselinux1-dev \
+# For kdump-tools
+ liblzo2-dev \
+# For iptables
+ libnetfilter-conntrack-dev \
+ libnftnl-dev \
+# For SAI3.7
+ protobuf-compiler \
+ libprotobuf-dev \
+ xxd \
+# For DHCP Monitor tool
+ libexplain-dev \
+ libevent-dev \
+# For libyang
+ swig \
+# For build dtb
+ device-tree-compiler \
+# For sonic-mgmt-framework
+ autoconf \
+ m4 \
+ libxml2-utils \
+ xsltproc \
+ python3-lxml \
+ libexpat1-dev \
+ libcurl3-gnutls \
+ libcjson-dev \
+# For WPA supplication
+ qtbase5-dev \
+ aspell-en \
+ libpython2.7-dev \
+ libssl-dev \
+ dbus \
+ libdbus-1-dev \
+ libdbus-glib-1-2 \
+ libdbus-glib-1-dev \
+ libreadline-dev \
+ libncurses5-dev \
+ libpcsclite-dev \
+ docbook-to-man \
+ docbook-utils \
+# For kdump-tools
+ libbz2-dev \
+# For linkmgrd
+ libboost1.74-dev \
+ libboost-program-options1.74-dev \
+ libboost-system1.74-dev \
+ libboost-thread1.74-dev \
+ libboost-atomic1.74-dev \
+ libboost-chrono1.74-dev \
+ libboost-container1.74-dev \
+ libboost-context1.74-dev \
+ libboost-contract1.74-dev \
+ libboost-coroutine1.74-dev \
+ libboost-date-time1.74-dev \
+ libboost-fiber1.74-dev \
+ libboost-filesystem1.74-dev \
+ libboost-graph-parallel1.74-dev \
+ libboost-log1.74-dev \
+ libboost-regex1.74-dev \
+ googletest \
+ libgtest-dev \
+ libgcc-10-dev \
+# For sonic-host-services build
+ libcairo2-dev \
+ libdbus-1-dev \
+ libgirepository1.0-dev \
+ libsystemd-dev \
+ pkg-config
+
+# Build fix for ARMHF bullseye libsairedis
+{%- if CONFIGURED_ARCH == "armhf" %}
+ # Install doxygen build dependency packages
+ RUN apt install -y libxapian-dev yui-compressor libclang-3.9-dev texlive-extra-utils \
+ texlive-font-utils rdfind llvm-6.0-dev libclang-6.0-dev sassc
+
+ # Update doxygen with 64bit file offset patch
+ RUN dget -u http://deb.debian.org/debian/pool/main/d/doxygen/doxygen_1.8.13-10.dsc && \
+ cd doxygen-1.8.13 && \
+ sed -i '56 a add_definitions(-D_FILE_OFFSET_BITS=64)' CMakeLists.txt && \
+ DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b && \
+ cd .. && \
+ dpkg -i ./doxygen_1.8.13-10_armhf.deb && \
+ rm -fr doxygen*
+
+ # Aspell is unable to locate the language dictionaries.
+ # Re-installing aspell-en dictionary to fix it.
+ RUN apt-get install --reinstall -y aspell-en
+
+ # workaround because of https://bugs.launchpad.net/qemu/+bug/1805913, just disable aspell
+ RUN cp /bin/true /usr/bin/aspell
+{%- endif %}
+
+## Config dpkg
+## install the configuration file if it’s currently missing
+RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confmiss"
+## combined with confold: overwrite configuration files that you have not modified
+RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confdef"
+## do not modify the current configuration file, the new version is installed with a .dpkg-dist suffix
+RUN sudo augtool --autosave "set /files/etc/dpkg/dpkg.cfg/force-confold"
+
+# For linux build
+RUN apt-get -y build-dep linux
+
+# For gobgp and telemetry build
+RUN export VERSION=1.14.2 \
+{%- if CONFIGURED_ARCH == "armhf" %}
+ && wget https://storage.googleapis.com/golang/go$VERSION.linux-armv6l.tar.gz \
+ && tar -C /usr/local -xzf go$VERSION.linux-armv6l.tar.gz \
+{%- elif CONFIGURED_ARCH == "arm64" %}
+ && wget https://storage.googleapis.com/golang/go$VERSION.linux-arm64.tar.gz \
+ && tar -C /usr/local -xzf go$VERSION.linux-arm64.tar.gz \
+{%- else %}
+ && wget https://storage.googleapis.com/golang/go$VERSION.linux-amd64.tar.gz \
+ && tar -C /usr/local -xzf go$VERSION.linux-amd64.tar.gz \
+{%- endif %}
+ && echo 'export GOROOT=/usr/local/go' >> /etc/bash.bashrc \
+ && echo 'export PATH=$PATH:$GOROOT/bin' >> /etc/bash.bashrc \
+ && rm go$VERSION.linux-*.tar.gz
+
+RUN pip3 install --upgrade pip
+RUN apt-get purge -y python3-pip python3-yaml
+
+# For building Python packages
+RUN pip3 install setuptools==49.6.00
+RUN pip3 install wheel==0.35.1
+
+# For building sonic-utilities
+RUN pip3 install fastentrypoints
+
+# For running Python unit tests
+RUN pip3 install pytest-runner==5.2
+RUN pip3 install nose==1.3.7
+RUN pip3 install mockredispy==2.9.3
+
+# For p4 build
+RUN pip3 install \
+ ctypesgen==1.0.2 \
+ crc16
+
+# For sonic config engine testing
+# Install pyangbind here, outside sonic-config-engine dependencies, as pyangbind causes enum34 to be installed.
+# enum34 causes Python 're' package to not work properly as it redefines an incompatible enum.py module
+# https://github.com/robshakir/pyangbind/issues/232
+RUN pip3 install pyangbind==0.8.1
+RUN pip3 uninstall -y enum34
+
+# For templating
+RUN pip3 install j2cli==0.3.10
+
+# For sonic-mgmt-framework
+RUN pip3 install "PyYAML==5.4.1"
+RUN pip3 install "lxml==4.6.2"
+
+# For sonic-platform-common testing
+RUN pip3 install redis
+
+# For vs image build
+RUN pip3 install pexpect==4.8.0
+
+# For sonic-swss-common testing
+RUN pip3 install Pympler==0.8
+
+# For sonic_yang_model build
+RUN pip3 install pyang==2.4.0
+
+# For mgmt-framework build
+RUN pip3 install mmh3==2.5.1
+
+RUN pip3 install parameterized==0.8.1
+
+RUN apt-get install -y xsltproc
+
+# Install dependencies for isc-dhcp-relay build
+RUN apt-get -y build-dep isc-dhcp
+
+# Install vim
+RUN apt-get install -y vim
+
+# Install rsyslog
+RUN apt-get install -y rsyslog
+
+RUN cd /usr/src/gtest && cmake . && make -C /usr/src/gtest
+
+RUN mkdir /var/run/sshd
+EXPOSE 22
+
+# Install depot-tools (for git-retry)
+RUN git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git /usr/share/depot_tools
+ENV PATH /usr/share/depot_tools:$PATH
+
+# Install docker engine 20.10 inside docker and enable experimental feature
+RUN apt-get update
+RUN apt-get install -y \
+ apt-transport-https \
+ ca-certificates \
+ curl \
+ gnupg2 \
+ software-properties-common
+{%- if CONFIGURED_ARCH == "armhf" %}
+ RUN update-ca-certificates --fresh
+{%- endif %}
+RUN curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
+RUN add-apt-repository \
+ "deb [arch={{ CONFIGURED_ARCH }}] https://download.docker.com/linux/debian \
+ $(lsb_release -cs) \
+ stable"
+RUN apt-get update
+RUN apt-get install -y docker-ce=5:20.10.7~3-0~debian-bullseye docker-ce-cli=5:20.10.7~3-0~debian-bullseye
+RUN echo "DOCKER_OPTS=\"--experimental --storage-driver=vfs {{ DOCKER_EXTRA_OPTS }}\"" >> /etc/default/docker
+RUN update-alternatives --set iptables /usr/sbin/iptables-legacy
+
+# Install m2crypto package, needed by SWI tools
+RUN pip3 install m2crypto==0.36.0
+
+# Install swi tools
+RUN pip3 install git+https://github.com/aristanetworks/swi-tools.git@bead66bf261770237f7dd21ace3774ba04a017e9
+
+{% if CONFIGURED_ARCH != "amd64" -%}
+# Install node.js for azure pipeline
+RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
+RUN apt-get install -y nodejs
+
+# Tell azure pipeline to use node.js in the docker
+LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/bin/node"
+{% endif -%}
diff --git a/sonic-slave-bullseye/Dockerfile.user.j2 b/sonic-slave-bullseye/Dockerfile.user.j2
new file mode 100644
index 000000000000..5bc747beb2fc
--- /dev/null
+++ b/sonic-slave-bullseye/Dockerfile.user.j2
@@ -0,0 +1,34 @@
+ARG slave_base_tag_ref=latest
+{%- if MULTIARCH_QEMU_ENVIRON != "y" %}
+FROM sonic-slave-bullseye:${slave_base_tag_ref}
+{%- else %}
+FROM sonic-slave-bullseye-march-{{ CONFIGURED_ARCH }}:${slave_base_tag_ref}
+{%- endif %}
+
+# Add user
+ARG user
+ARG uid
+ARG guid
+ARG hostname
+
+ENV BUILD_HOSTNAME $hostname
+ENV USER $user
+
+RUN groupadd -f -r -g $guid g$user
+
+RUN useradd $user -l -u $uid -g $guid -d /var/$user -m -s /bin/bash
+
+RUN gpasswd -a $user docker
+
+# Config git for stg
+RUN su $user -c "git config --global user.name $user"
+RUN su $user -c "git config --global user.email $user@contoso.com"
+
+COPY sonic-jenkins-id_rsa.pub /var/$user/.ssh/authorized_keys2
+RUN chown $user /var/$user/.ssh -R
+RUN chmod go= /var/$user/.ssh -R
+
+# Add user to sudoers
+RUN echo "$user ALL=(ALL) NOPASSWD:ALL" >>/etc/sudoers
+
+USER $user
diff --git a/sonic-slave-bullseye/no-check-valid-until b/sonic-slave-bullseye/no-check-valid-until
new file mode 100644
index 000000000000..c7c25d017f7f
--- /dev/null
+++ b/sonic-slave-bullseye/no-check-valid-until
@@ -0,0 +1,4 @@
+# Instruct apt-get to NOT check the "Valid Until" date in Release files
+# Once the Debian team archives a repo, they stop updating this date
+
+Acquire::Check-Valid-Until "false";
diff --git a/sonic-slave-bullseye/sonic-jenkins-id_rsa.pub b/sonic-slave-bullseye/sonic-jenkins-id_rsa.pub
new file mode 100644
index 000000000000..2a19c9e70d3c
--- /dev/null
+++ b/sonic-slave-bullseye/sonic-jenkins-id_rsa.pub
@@ -0,0 +1 @@
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC769BQUJVeSIOyPsN4/Vo8xTqXQ6RI7ysVyCw/ABP3FIxf+fxmtm8t/Nbp9hq0uLHOjCw8UQbJ+XltsThFWJfH6RJY5NbfvwG7nUDjfjjp+SGEIHaVgIlpiuqiPbZ6QMjZ8Q0Sgi5p5ts1xe/4TFThwOJBHmhwydD5nk3BH7P3DDwlOCov5gjM40uMZJkketlO83zGG+25zu7O0hfDVt1vyK9bNWAhhPmGc79zdetfeFCxjimsff2m31B1KuVXiT5PDB1w+BSrUK6nNzJubnYCRgjg4prVTjA50EhlT2P7EoJAbW3TnTq8vUDkcstsGe/HZpfIB1VHBX97u4fAfGJZ root@acs-jenkins
diff --git a/sonic-slave-buster/Dockerfile.j2 b/sonic-slave-buster/Dockerfile.j2
index 3cc41bf04594..890572320fa2 100644
--- a/sonic-slave-buster/Dockerfile.j2
+++ b/sonic-slave-buster/Dockerfile.j2
@@ -307,8 +307,6 @@ RUN apt-get update && apt-get install -y \
# For WPA supplication
qtbase5-dev \
aspell-en \
- libhiredis-dev \
- libnl-3-dev \
swig3.0 \
libpython2.7-dev \
libssl-dev \
diff --git a/src/dhcpmon/src/dhcp_device.c b/src/dhcpmon/src/dhcp_device.c
index f45483f8504c..3078295e49a4 100644
--- a/src/dhcpmon/src/dhcp_device.c
+++ b/src/dhcpmon/src/dhcp_device.c
@@ -21,25 +21,51 @@
#include
#include
#include
+#include
+#include
+#include
#include "dhcp_device.h"
+/** DHCP versions flags */
+static bool dhcpv4_enabled;
+static bool dhcpv6_enabled;
+
/** Counter print width */
#define DHCP_COUNTER_WIDTH 9
/** Start of Ether header of a captured frame */
#define ETHER_START_OFFSET 0
+/** EtherType field offset from Ether header of a captured frame */
+#define ETHER_TYPE_OFFSET (ETHER_START_OFFSET + 12)
/** Start of IP header of a captured frame */
#define IP_START_OFFSET (ETHER_START_OFFSET + ETHER_HDR_LEN)
-/** Start of UDP header of a captured frame */
-#define UDP_START_OFFSET (IP_START_OFFSET + sizeof(struct ip))
-/** Start of DHCP header of a captured frame */
-#define DHCP_START_OFFSET (UDP_START_OFFSET + sizeof(struct udphdr))
-/** Start of DHCP Options segment of a captured frame */
-#define DHCP_OPTIONS_HEADER_SIZE 240
+/** Start of UDP header on IPv4 packet of a captured frame */
+#define UDPv4_START_OFFSET (IP_START_OFFSET + sizeof(struct ip))
+/** Start of DHCPv4 header of a captured frame */
+#define DHCPv4_START_OFFSET (UDPv4_START_OFFSET + sizeof(struct udphdr))
+/** Start of DHCPv4 Options segment of a captured frame */
+#define DHCPv4_OPTIONS_HEADER_SIZE 240
/** Offset of DHCP GIADDR */
#define DHCP_GIADDR_OFFSET 24
+/** IPv6 link-local prefix */
+#define IPV6_LINK_LOCAL_PREFIX 0x80fe
+/** Start of UDP header on IPv6 packet of a captured frame */
+#define UDPv6_START_OFFSET (IP_START_OFFSET + sizeof(struct ip6_hdr))
+/** Start of DHCPv6 header of a captured frame */
+#define DHCPv6_START_OFFSET (UDPv6_START_OFFSET + sizeof(struct udphdr))
+/** Size of 'type' field on DHCPv6 header */
+#define DHCPv6_TYPE_LENGTH 1
+/** Size of DHCPv6 relay message header to first option */
+#define DHCPv6_RELAY_MSG_OPTIONS_OFFSET 34
+/** Size of 'option' field on DHCPv6 header */
+#define DHCPv6_OPTION_LENGTH 2
+/** Size of 'option length' field on DHCPv6 header */
+#define DHCPv6_OPTION_LEN_LENGTH 2
+/** DHCPv6 OPTION_RELAY_MSG */
+#define DHCPv6_OPTION_RELAY_MSG 9
+
#define OP_LDHA (BPF_LD | BPF_H | BPF_ABS) /** bpf ldh Abs */
#define OP_LDHI (BPF_LD | BPF_H | BPF_IND) /** bpf ldh Ind */
#define OP_LDB (BPF_LD | BPF_B | BPF_ABS) /** bpf ldb Abs*/
@@ -49,34 +75,40 @@
#define OP_JSET (BPF_JMP | BPF_JSET | BPF_K) /** bpf jset */
#define OP_LDXB (BPF_LDX | BPF_B | BPF_MSH) /** bpf ldxb */
-/** Berkeley Packet Filter program for "udp and (port 67 or port 68)".
+/** Berkeley Packet Filter program for "udp and (port 546 or port 547 or port 67 or port 68)".
* This program is obtained using the following command tcpdump:
- * `tcpdump -dd "udp and (port 67 or port 68)"`
+ * `tcpdump -dd "udp and (port 546 or port 547 or port 67 or port 68)"`
*/
static struct sock_filter dhcp_bpf_code[] = {
- {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x0000000c}, // (000) ldh [12]
- {.code = OP_JEQ, .jt = 0, .jf = 7, .k = 0x000086dd}, // (001) jeq #0x86dd jt 2 jf 9
- {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000014}, // (002) ldb [20]
- {.code = OP_JEQ, .jt = 0, .jf = 18, .k = 0x00000011}, // (003) jeq #0x11 jt 4 jf 22
- {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000036}, // (004) ldh [54]
- {.code = OP_JEQ, .jt = 15, .jf = 0, .k = 0x00000043}, // (005) jeq #0x43 jt 21 jf 6
- {.code = OP_JEQ, .jt = 14, .jf = 0, .k = 0x00000044}, // (006) jeq #0x44 jt 21 jf 7
- {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000038}, // (007) ldh [56]
- {.code = OP_JEQ, .jt = 12, .jf = 11, .k = 0x00000043}, // (008) jeq #0x43 jt 21 jf 20
- {.code = OP_JEQ, .jt = 0, .jf = 12, .k = 0x00000800}, // (009) jeq #0x800 jt 10 jf 22
- {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000017}, // (010) ldb [23]
- {.code = OP_JEQ, .jt = 0, .jf = 10, .k = 0x00000011}, // (011) jeq #0x11 jt 12 jf 22
- {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000014}, // (012) ldh [20]
- {.code = OP_JSET, .jt = 8, .jf = 0, .k = 0x00001fff}, // (013) jset #0x1fff jt 22 jf 14
- {.code = OP_LDXB, .jt = 0, .jf = 0, .k = 0x0000000e}, // (014) ldxb 4*([14]&0xf)
- {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x0000000e}, // (015) ldh [x + 14]
- {.code = OP_JEQ, .jt = 4, .jf = 0, .k = 0x00000043}, // (016) jeq #0x43 jt 21 jf 17
- {.code = OP_JEQ, .jt = 3, .jf = 0, .k = 0x00000044}, // (017) jeq #0x44 jt 21 jf 18
- {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x00000010}, // (018) ldh [x + 16]
- {.code = OP_JEQ, .jt = 1, .jf = 0, .k = 0x00000043}, // (019) jeq #0x43 jt 21 jf 20
- {.code = OP_JEQ, .jt = 0, .jf = 1, .k = 0x00000044}, // (020) jeq #0x44 jt 21 jf 22
- {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00040000}, // (021) ret #262144
- {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00000000}, // (022) ret #0
+ {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x0000000c}, // (000) ldh [12]
+ {.code = OP_JEQ, .jt = 0, .jf = 9, .k = 0x000086dd}, // (001) jeq #0x86dd jt 2 jf 11
+ {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000014}, // (002) ldb [20]
+ {.code = OP_JEQ, .jt = 0, .jf = 24, .k = 0x00000011}, // (003) jeq #0x11 jt 4 jf 28
+ {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000036}, // (004) ldh [54]
+ {.code = OP_JEQ, .jt = 21, .jf = 0, .k = 0x00000222}, // (005) jeq #0x222 jt 27 jf 6
+ {.code = OP_JEQ, .jt = 20, .jf = 0, .k = 0x00000223}, // (006) jeq #0x223 jt 27 jf 7
+ {.code = OP_JEQ, .jt = 19, .jf = 0, .k = 0x00000043}, // (007) jeq #0x43 jt 27 jf 8
+ {.code = OP_JEQ, .jt = 18, .jf = 0, .k = 0x00000044}, // (008) jeq #0x44 jt 27 jf 9
+ {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000038}, // (009) ldh [56]
+ {.code = OP_JEQ, .jt = 16, .jf = 13, .k = 0x00000222}, // (010) jeq #0x222 jt 27 jf 24
+ {.code = OP_JEQ, .jt = 0, .jf = 16, .k = 0x00000800}, // (011) jeq #0x800 jt 12 jf 28
+ {.code = OP_LDB, .jt = 0, .jf = 0, .k = 0x00000017}, // (012) ldb [23]
+ {.code = OP_JEQ, .jt = 0, .jf = 14, .k = 0x00000011}, // (013) jeq #0x11 jt 14 jf 28
+ {.code = OP_LDHA, .jt = 0, .jf = 0, .k = 0x00000014}, // (014) ldh [20]
+ {.code = OP_JSET, .jt = 12, .jf = 0, .k = 0x00001fff}, // (015) jset #0x1fff jt 28 jf 16
+ {.code = OP_LDXB, .jt = 0, .jf = 0, .k = 0x0000000e}, // (016) ldxb 4*([14]&0xf)
+ {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x0000000e}, // (017) ldh [x + 14]
+ {.code = OP_JEQ, .jt = 8, .jf = 0, .k = 0x00000222}, // (018) jeq #0x222 jt 27 jf 19
+ {.code = OP_JEQ, .jt = 7, .jf = 0, .k = 0x00000223}, // (019) jeq #0x223 jt 27 jf 20
+ {.code = OP_JEQ, .jt = 6, .jf = 0, .k = 0x00000043}, // (020) jeq #0x43 jt 27 jf 21
+ {.code = OP_JEQ, .jt = 5, .jf = 0, .k = 0x00000044}, // (021) jeq #0x44 jt 27 jf 22
+ {.code = OP_LDHI, .jt = 0, .jf = 0, .k = 0x00000010}, // (022) ldh [x + 16]
+ {.code = OP_JEQ, .jt = 3, .jf = 0, .k = 0x00000222}, // (023) jeq #0x222 jt 27 jf 24
+ {.code = OP_JEQ, .jt = 2, .jf = 0, .k = 0x00000223}, // (024) jeq #0x223 jt 27 jf 25
+ {.code = OP_JEQ, .jt = 1, .jf = 0, .k = 0x00000043}, // (025) jeq #0x43 jt 27 jf 26
+ {.code = OP_JEQ, .jt = 0, .jf = 1, .k = 0x00000044}, // (026) jeq #0x44 jt 27 jf 28
+ {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00040000}, // (027) ret #262144
+ {.code = OP_RET, .jt = 0, .jf = 0, .k = 0x00000000}, // (028) ret
};
/** Filter program socket struct */
@@ -89,16 +121,27 @@ static struct sock_fprog dhcp_sock_bfp = {
*/
static dhcp_device_context_t aggregate_dev = {0};
-/** Monitored DHCP message type */
-static dhcp_message_type_t monitored_msgs[] = {
- DHCP_MESSAGE_TYPE_DISCOVER,
- DHCP_MESSAGE_TYPE_OFFER,
- DHCP_MESSAGE_TYPE_REQUEST,
- DHCP_MESSAGE_TYPE_ACK
+/** Monitored DHCPv4 message type */
+static dhcpv4_message_type_t v4_monitored_msgs[] = {
+ DHCPv4_MESSAGE_TYPE_DISCOVER,
+ DHCPv4_MESSAGE_TYPE_OFFER,
+ DHCPv4_MESSAGE_TYPE_REQUEST,
+ DHCPv4_MESSAGE_TYPE_ACK
+};
+
+/** Monitored DHCPv6 message type */
+static dhcpv6_message_type_t v6_monitored_msgs[] = {
+ DHCPv6_MESSAGE_TYPE_SOLICIT,
+ DHCPv6_MESSAGE_TYPE_ADVERTISE,
+ DHCPv6_MESSAGE_TYPE_REQUEST,
+ DHCPv6_MESSAGE_TYPE_REPLY
};
-/** Number of monitored DHCP message type */
-static uint8_t monitored_msg_sz = sizeof(monitored_msgs) / sizeof(*monitored_msgs);
+/** Number of monitored DHCPv4 message type */
+static uint8_t v4_monitored_msg_sz = sizeof(v4_monitored_msgs) / sizeof(*v4_monitored_msgs);
+
+/** Number of monitored DHCPv6 message type */
+static uint8_t v6_monitored_msg_sz = sizeof(v6_monitored_msgs) / sizeof(*v6_monitored_msgs);
/**
* @code handle_dhcp_option_53(context, dhcp_option, dir, iphdr, dhcphdr);
@@ -123,27 +166,27 @@ static void handle_dhcp_option_53(dhcp_device_context_t *context,
switch (dhcp_option[2])
{
// DHCP messages send by client
- case DHCP_MESSAGE_TYPE_DISCOVER:
- case DHCP_MESSAGE_TYPE_REQUEST:
- case DHCP_MESSAGE_TYPE_DECLINE:
- case DHCP_MESSAGE_TYPE_RELEASE:
- case DHCP_MESSAGE_TYPE_INFORM:
+ case DHCPv4_MESSAGE_TYPE_DISCOVER:
+ case DHCPv4_MESSAGE_TYPE_REQUEST:
+ case DHCPv4_MESSAGE_TYPE_DECLINE:
+ case DHCPv4_MESSAGE_TYPE_RELEASE:
+ case DHCPv4_MESSAGE_TYPE_INFORM:
giaddr = ntohl(dhcphdr[DHCP_GIADDR_OFFSET] << 24 | dhcphdr[DHCP_GIADDR_OFFSET + 1] << 16 |
dhcphdr[DHCP_GIADDR_OFFSET + 2] << 8 | dhcphdr[DHCP_GIADDR_OFFSET + 3]);
if ((context->giaddr_ip == giaddr && context->is_uplink && dir == DHCP_TX) ||
(!context->is_uplink && dir == DHCP_RX && iphdr->ip_dst.s_addr == INADDR_BROADCAST)) {
- context->counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
- aggregate_dev.counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
+ context->counters.v4counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
+ aggregate_dev.counters.v4counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
}
break;
// DHCP messages send by server
- case DHCP_MESSAGE_TYPE_OFFER:
- case DHCP_MESSAGE_TYPE_ACK:
- case DHCP_MESSAGE_TYPE_NAK:
+ case DHCPv4_MESSAGE_TYPE_OFFER:
+ case DHCPv4_MESSAGE_TYPE_ACK:
+ case DHCPv4_MESSAGE_TYPE_NAK:
if ((context->giaddr_ip == iphdr->ip_dst.s_addr && context->is_uplink && dir == DHCP_RX) ||
(!context->is_uplink && dir == DHCP_TX)) {
- context->counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
- aggregate_dev.counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
+ context->counters.v4counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
+ aggregate_dev.counters.v4counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option[2]]++;
}
break;
default:
@@ -152,6 +195,43 @@ static void handle_dhcp_option_53(dhcp_device_context_t *context,
}
}
+/**
+ * @code handle_dhcpv6_option(context, dhcp_option, dir);
+ *
+ * @brief handle the logic related to DHCPv6 option
+ *
+ * @param context Device (interface) context
+ * @param dhcp_option pointer to DHCP option buffer space
+ * @param dir packet direction
+ *
+ * @return none
+ */
+static void handle_dhcpv6_option(dhcp_device_context_t *context,
+ const u_char dhcp_option,
+ dhcp_packet_direction_t dir)
+{
+ switch (dhcp_option)
+ {
+ case DHCPv6_MESSAGE_TYPE_SOLICIT:
+ case DHCPv6_MESSAGE_TYPE_REQUEST:
+ case DHCPv6_MESSAGE_TYPE_CONFIRM:
+ case DHCPv6_MESSAGE_TYPE_RENEW:
+ case DHCPv6_MESSAGE_TYPE_REBIND:
+ case DHCPv6_MESSAGE_TYPE_RELEASE:
+ case DHCPv6_MESSAGE_TYPE_DECLINE:
+ case DHCPv6_MESSAGE_TYPE_ADVERTISE:
+ case DHCPv6_MESSAGE_TYPE_REPLY:
+ case DHCPv6_MESSAGE_TYPE_RECONFIGURE:
+ case DHCPv6_MESSAGE_TYPE_INFORMATION_REQUEST:
+ context->counters.v6counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option]++;
+ aggregate_dev.counters.v6counters[DHCP_COUNTERS_CURRENT][dir][dhcp_option]++;
+ break;
+ default:
+ syslog(LOG_WARNING, "handle_dhcpv6_option(%s): Unknown DHCPv6 option type %d", context->intf, dhcp_option);
+ break;
+ }
+}
+
/**
* @code read_callback(fd, event, arg);
*
@@ -171,16 +251,29 @@ static void read_callback(int fd, short event, void *arg)
while ((event == EV_READ) &&
((buffer_sz = recv(fd, context->buffer, context->snaplen, MSG_DONTWAIT)) > 0)) {
struct ether_header *ethhdr = (struct ether_header*) context->buffer;
- struct ip *iphdr = (struct ip*) (context->buffer + IP_START_OFFSET);
- struct udphdr *udp = (struct udphdr*) (context->buffer + UDP_START_OFFSET);
- uint8_t *dhcphdr = context->buffer + DHCP_START_OFFSET;
- int dhcp_option_offset = DHCP_START_OFFSET + DHCP_OPTIONS_HEADER_SIZE;
-
- if ((buffer_sz > UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) &&
- (ntohs(udp->len) > DHCP_OPTIONS_HEADER_SIZE)) {
- int dhcp_sz = ntohs(udp->len) < buffer_sz - UDP_START_OFFSET - sizeof(struct udphdr) ?
- ntohs(udp->len) : buffer_sz - UDP_START_OFFSET - sizeof(struct udphdr);
- int dhcp_option_sz = dhcp_sz - DHCP_OPTIONS_HEADER_SIZE;
+ struct ip *iphdr;
+ struct ip6_hdr *ipv6hdr;
+ struct udphdr *udp;
+ uint8_t *dhcphdr;
+ int dhcp_option_offset;
+
+ bool is_ipv4 = (ntohs(ethhdr->ether_type) == ETHERTYPE_IP);
+ if (is_ipv4) {
+ iphdr = (struct ip*) (context->buffer + IP_START_OFFSET);
+ udp = (struct udphdr*) (context->buffer + UDPv4_START_OFFSET);
+ dhcphdr = context->buffer + DHCPv4_START_OFFSET;
+ dhcp_option_offset = DHCPv4_START_OFFSET + DHCPv4_OPTIONS_HEADER_SIZE;
+ } else {
+ ipv6hdr = (struct ip6_hdr*) (context->buffer + IP_START_OFFSET);
+ udp = (struct udphdr*) (context->buffer + UDPv6_START_OFFSET);
+ dhcphdr = context->buffer + DHCPv6_START_OFFSET;
+ dhcp_option_offset = DHCPv6_START_OFFSET;
+ }
+ if (is_ipv4 && dhcpv4_enabled && (buffer_sz > UDPv4_START_OFFSET + sizeof(struct udphdr) + DHCPv4_OPTIONS_HEADER_SIZE) &&
+ (ntohs(udp->len) > DHCPv4_OPTIONS_HEADER_SIZE)) {
+ int dhcp_sz = ntohs(udp->len) < buffer_sz - UDPv4_START_OFFSET - sizeof(struct udphdr) ?
+ ntohs(udp->len) : buffer_sz - UDPv4_START_OFFSET - sizeof(struct udphdr);
+ int dhcp_option_sz = dhcp_sz - DHCPv4_OPTIONS_HEADER_SIZE;
const u_char *dhcp_option = context->buffer + dhcp_option_offset;
dhcp_packet_direction_t dir = (ethhdr->ether_shost[0] == context->mac[0] &&
ethhdr->ether_shost[1] == context->mac[1] &&
@@ -214,6 +307,35 @@ static void read_callback(int fd, short event, void *arg)
offset += dhcp_option[offset + 1] + 2;
}
}
+ }
+ else if (!is_ipv4 && dhcpv6_enabled && (buffer_sz > UDPv6_START_OFFSET + sizeof(struct udphdr) + DHCPv6_TYPE_LENGTH)) {
+ const u_char* dhcp_option = context->buffer + dhcp_option_offset;
+ dhcp_packet_direction_t dir = (ethhdr->ether_shost[0] == context->mac[0] &&
+ ethhdr->ether_shost[1] == context->mac[1] &&
+ ethhdr->ether_shost[2] == context->mac[2] &&
+ ethhdr->ether_shost[3] == context->mac[3] &&
+ ethhdr->ether_shost[4] == context->mac[4] &&
+ ethhdr->ether_shost[5] == context->mac[5]) ?
+ DHCP_TX : DHCP_RX;
+ int offset = 0;
+ uint16_t option = 0;
+ // Get to inner DHCP header from encapsulated RELAY_FORWARD or RELAY_REPLY header
+ while (dhcp_option[offset] == DHCPv6_MESSAGE_TYPE_RELAY_FORWARD || dhcp_option[offset] == DHCPv6_MESSAGE_TYPE_RELAY_REPLY)
+ {
+ // Get to DHCPv6_OPTION_RELAY_MSG from all options
+ offset += DHCPv6_RELAY_MSG_OPTIONS_OFFSET;
+ option = htons(*((uint16_t*)(&(dhcp_option[offset]))));
+
+ while (option != DHCPv6_OPTION_RELAY_MSG)
+ {
+ offset += DHCPv6_OPTION_LENGTH;
+ // Add to offset the option length and get the next option ID
+ offset += htons(*((uint16_t*)(&(dhcp_option[offset]))));
+ option = htons(*((uint16_t*)(&(dhcp_option[offset]))));
+ }
+ offset += DHCPv6_OPTION_LENGTH + DHCPv6_OPTION_LEN_LENGTH;
+ }
+ handle_dhcpv6_option(context, dhcp_option[offset], dir);
} else {
syslog(LOG_WARNING, "read_callback(%s): read length (%ld) is too small to capture DHCP options",
context->intf, buffer_sz);
@@ -222,29 +344,54 @@ static void read_callback(int fd, short event, void *arg)
}
/**
- * @code dhcp_device_is_dhcp_inactive(counters);
+ * @code dhcp_device_is_dhcp_inactive(v4counters, v6counters, type);
*
* @brief Check if there were no DHCP activity
*
- * @param counters current/snapshot counter
+ * @param v4counters current/snapshot v4counter
+ *
+ * @param v6counters current/snapshot v6counter
+ *
+ * @param type DHCP type
*
* @return true if there were no DHCP activity, false otherwise
*/
-static bool dhcp_device_is_dhcp_inactive(uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT])
+static bool dhcp_device_is_dhcp_inactive(uint64_t v4counters[][DHCP_DIR_COUNT][DHCPv4_MESSAGE_TYPE_COUNT],
+ uint64_t v6counters[][DHCP_DIR_COUNT][DHCPv6_MESSAGE_TYPE_COUNT],
+ dhcp_type_t type)
{
- uint64_t *rx_counters = counters[DHCP_COUNTERS_CURRENT][DHCP_RX];
- uint64_t *rx_counter_snapshot = counters[DHCP_COUNTERS_SNAPSHOT][DHCP_RX];
-
bool rv = true;
- for (uint8_t i = 0; (i < monitored_msg_sz) && rv; i++) {
- rv = rx_counters[monitored_msgs[i]] == rx_counter_snapshot[monitored_msgs[i]];
+ uint64_t *rx_counters;
+ uint64_t *rx_counter_snapshot;
+
+ switch (type)
+ {
+ case DHCPv4_TYPE:
+ rx_counters = v4counters[DHCP_COUNTERS_CURRENT][DHCP_RX];
+ rx_counter_snapshot = v4counters[DHCP_COUNTERS_SNAPSHOT][DHCP_RX];
+ for (uint8_t i = 0; (i < v4_monitored_msg_sz) && rv; i++) {
+ rv = rx_counters[v4_monitored_msgs[i]] == rx_counter_snapshot[v4_monitored_msgs[i]];
+ }
+ break;
+
+ case DHCPv6_TYPE:
+ rx_counters = v6counters[DHCP_COUNTERS_CURRENT][DHCP_RX];
+ rx_counter_snapshot = v6counters[DHCP_COUNTERS_SNAPSHOT][DHCP_RX];
+ for (uint8_t i = 0; (i < v6_monitored_msg_sz) && rv; i++) {
+ rv = rx_counters[v6_monitored_msgs[i]] == rx_counter_snapshot[v6_monitored_msgs[i]];
+ }
+ break;
+
+ default:
+ syslog(LOG_ERR, "Unknown DHCP type %d\n", type);
+ break;
}
return rv;
}
/**
- * @code dhcp_device_is_dhcp_msg_unhealthy(type, counters);
+ * @code dhcp_device_is_dhcpv4_msg_unhealthy(type, counters);
*
* @brief Check if DHCP relay is functioning properly for message of type 'type'.
* For every rx of message 'type', there should be increment of the same message type.
@@ -254,34 +401,76 @@ static bool dhcp_device_is_dhcp_inactive(uint64_t counters[][DHCP_DIR_COUNT][DHC
*
* @return true if DHCP message 'type' is transmitted,false otherwise
*/
-static bool dhcp_device_is_dhcp_msg_unhealthy(dhcp_message_type_t type,
- uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT])
+static bool dhcp_device_is_dhcpv4_msg_unhealthy(dhcpv4_message_type_t type,
+ uint64_t v4counters[][DHCP_DIR_COUNT][DHCPv4_MESSAGE_TYPE_COUNT])
{
// check if DHCP message 'type' is being relayed
- return ((counters[DHCP_COUNTERS_CURRENT][DHCP_RX][type] > counters[DHCP_COUNTERS_SNAPSHOT][DHCP_RX][type]) &&
- (counters[DHCP_COUNTERS_CURRENT][DHCP_TX][type] <= counters[DHCP_COUNTERS_SNAPSHOT][DHCP_TX][type]) );
+ return ((v4counters[DHCP_COUNTERS_CURRENT][DHCP_RX][type] > v4counters[DHCP_COUNTERS_SNAPSHOT][DHCP_RX][type]) &&
+ (v4counters[DHCP_COUNTERS_CURRENT][DHCP_TX][type] <= v4counters[DHCP_COUNTERS_SNAPSHOT][DHCP_TX][type]) );
}
/**
- * @code dhcp_device_check_positive_health(counters, counters_snapshot);
+ * @code dhcp_device_is_dhcpv6_msg_unhealthy(type, counters);
*
- * @brief Check if DHCP relay is functioning properly for monitored messages (Discover, Offer, Request, ACK.)
- * For every rx of monitored messages, there should be increment of the same message type.
+ * @brief Check if DHCP relay is functioning properly for message of type 'type'.
+ * For every rx of message 'type', there should be increment of the same message type.
*
+ * @param type DHCP message type
* @param counters current/snapshot counter
*
+ * @return true if DHCP message 'type' is transmitted,false otherwise
+ */
+static bool dhcp_device_is_dhcpv6_msg_unhealthy(dhcpv6_message_type_t type,
+ uint64_t v6counters[][DHCP_DIR_COUNT][DHCPv6_MESSAGE_TYPE_COUNT])
+{
+ // check if DHCP message 'type' is being relayed
+ return ((v6counters[DHCP_COUNTERS_CURRENT][DHCP_RX][type] > v6counters[DHCP_COUNTERS_SNAPSHOT][DHCP_RX][type]) &&
+ (v6counters[DHCP_COUNTERS_CURRENT][DHCP_TX][type] <= v6counters[DHCP_COUNTERS_SNAPSHOT][DHCP_TX][type]) );
+}
+
+/**
+ * @code dhcp_device_check_positive_health(v4counters, v6counters, type);
+ *
+ * @brief Check if DHCPv4/6 relay is functioning properly for monitored messages.
+ * DHCPv4 (Discover, Offer, Request, ACK.) and DHCPv6 (Solicit, Advertise, Request, Reply).
+ * For every rx of monitored messages, there should be increment of the same message type.
+ *
+ * @param v4counters current/snapshot counter
+ *
+ * @param v6counters current/snapshot counter
+ *
+ * @param type DHCP type
+ *
* @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE
*/
-static dhcp_mon_status_t dhcp_device_check_positive_health(uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT])
+static dhcp_mon_status_t dhcp_device_check_positive_health(uint64_t v4counters[][DHCP_DIR_COUNT][DHCPv4_MESSAGE_TYPE_COUNT],
+ uint64_t v6counters[][DHCP_DIR_COUNT][DHCPv6_MESSAGE_TYPE_COUNT],
+ dhcp_type_t type)
{
dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY;
bool is_dhcp_unhealthy = false;
- for (uint8_t i = 0; (i < monitored_msg_sz) && !is_dhcp_unhealthy; i++) {
- is_dhcp_unhealthy = dhcp_device_is_dhcp_msg_unhealthy(monitored_msgs[i], counters);
+
+ switch (type)
+ {
+ case DHCPv4_TYPE:
+ for (uint8_t i = 0; (i < v4_monitored_msg_sz) && !is_dhcp_unhealthy; i++) {
+ is_dhcp_unhealthy = dhcp_device_is_dhcpv4_msg_unhealthy(v4_monitored_msgs[i], v4counters);
+ }
+ break;
+
+ case DHCPv6_TYPE:
+ for (uint8_t i = 0; (i < v6_monitored_msg_sz) && !is_dhcp_unhealthy; i++) {
+ is_dhcp_unhealthy = dhcp_device_is_dhcpv6_msg_unhealthy(v6_monitored_msgs[i], v6counters);
+ }
+ break;
+
+ default:
+ syslog(LOG_ERR, "Unknown DHCP type %d\n", type);
+ break;
}
- // if we have rx DORA then we should have corresponding tx DORA (DORA being relayed)
+ // if we have rx DORA/SARR then we should have corresponding tx DORA/SARR (DORA/SARR being relayed)
if (is_dhcp_unhealthy) {
rv = DHCP_MON_STATUS_UNHEALTHY;
}
@@ -290,27 +479,47 @@ static dhcp_mon_status_t dhcp_device_check_positive_health(uint64_t counters[][D
}
/**
- * @code dhcp_device_check_negative_health(counters);
+ * @code dhcp_device_check_negative_health(v4counters, v6counters, type);
*
* @brief Check that DHCP relayed messages are not being transmitted out of this interface/dev
* using its counters. The interface is negatively healthy if there are not DHCP message
* travelling through it.
*
- * @param counters recent interface counter
- * @param counters_snapshot snapshot counters
+ * @param v4counters current/snapshot counter
+ * @param v6counters current/snapshot counter
+ * @param type DHCP type
*
* @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE
*/
-static dhcp_mon_status_t dhcp_device_check_negative_health(uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT])
+static dhcp_mon_status_t dhcp_device_check_negative_health(uint64_t v4counters[][DHCP_DIR_COUNT][DHCPv4_MESSAGE_TYPE_COUNT],
+ uint64_t v6counters[][DHCP_DIR_COUNT][DHCPv6_MESSAGE_TYPE_COUNT],
+ dhcp_type_t type)
{
dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY;
+ bool is_dhcp_unhealthy = false;
- uint64_t *tx_counters = counters[DHCP_COUNTERS_CURRENT][DHCP_TX];
- uint64_t *tx_counter_snapshot = counters[DHCP_COUNTERS_SNAPSHOT][DHCP_TX];
+ uint64_t *tx_counters;
+ uint64_t *tx_counter_snapshot;
- bool is_dhcp_unhealthy = false;
- for (uint8_t i = 0; (i < monitored_msg_sz) && !is_dhcp_unhealthy; i++) {
- is_dhcp_unhealthy = tx_counters[monitored_msgs[i]] > tx_counter_snapshot[monitored_msgs[i]];
+ switch (type)
+ {
+ case DHCPv4_TYPE:
+ tx_counters = v4counters[DHCP_COUNTERS_CURRENT][DHCP_TX];
+ tx_counter_snapshot = v4counters[DHCP_COUNTERS_SNAPSHOT][DHCP_TX];
+ for (uint8_t i = 0; (i < v4_monitored_msg_sz) && !is_dhcp_unhealthy; i++) {
+ is_dhcp_unhealthy = tx_counters[v4_monitored_msgs[i]] > tx_counter_snapshot[v4_monitored_msgs[i]];
+ }
+ break;
+ case DHCPv6_TYPE:
+ tx_counters = v6counters[DHCP_COUNTERS_CURRENT][DHCP_TX];
+ tx_counter_snapshot = v6counters[DHCP_COUNTERS_SNAPSHOT][DHCP_TX];
+ for (uint8_t i = 0; (i < v6_monitored_msg_sz) && !is_dhcp_unhealthy; i++) {
+ is_dhcp_unhealthy = tx_counters[v6_monitored_msgs[i]] > tx_counter_snapshot[v6_monitored_msgs[i]];
+ }
+ break;
+ default:
+ syslog(LOG_ERR, "Unknown DHCP type %d\n", type);
+ break;
}
// for negative validation, return unhealthy if DHCP packet are being
@@ -323,7 +532,7 @@ static dhcp_mon_status_t dhcp_device_check_negative_health(uint64_t counters[][D
}
/**
- * @code dhcp_device_check_health(check_type, counters, counters_snapshot);
+ * @code dhcp_device_check_health(check_type, v4counters, v6counters, type);
*
* @brief Check that DHCP relay is functioning properly given a check type. Positive check
* indicates for every rx of DHCP message of type 'type', there would increment of
@@ -332,59 +541,80 @@ static dhcp_mon_status_t dhcp_device_check_negative_health(uint64_t counters[][D
* considered unhealthy.
*
* @param check_type type of health check
- * @param counters current/snapshot counter
+ * @param v4counters current/snapshot counters
+ * @param v6counters current/snapshot counters
+ * @param type DHCP type
*
* @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE
*/
static dhcp_mon_status_t dhcp_device_check_health(dhcp_mon_check_t check_type,
- uint64_t counters[][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT])
+ uint64_t v4counters[][DHCP_DIR_COUNT][DHCPv4_MESSAGE_TYPE_COUNT],
+ uint64_t v6counters[][DHCP_DIR_COUNT][DHCPv6_MESSAGE_TYPE_COUNT],
+ dhcp_type_t type)
{
dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY;
- if (dhcp_device_is_dhcp_inactive(aggregate_dev.counters)) {
+ if (dhcp_device_is_dhcp_inactive(aggregate_dev.counters.v4counters, aggregate_dev.counters.v6counters, type)) {
rv = DHCP_MON_STATUS_INDETERMINATE;
} else if (check_type == DHCP_MON_CHECK_POSITIVE) {
- rv = dhcp_device_check_positive_health(counters);
+ rv = dhcp_device_check_positive_health(v4counters, v6counters, type);
} else if (check_type == DHCP_MON_CHECK_NEGATIVE) {
- rv = dhcp_device_check_negative_health(counters);
+ rv = dhcp_device_check_negative_health(v4counters, v6counters, type);
}
return rv;
}
/**
- * @code dhcp_print_counters(vlan_intf, type, counters);
+ * @code dhcp_print_counters(vlan_intf, type, v4counters, v6counters);
*
* @brief prints DHCP counters to sylsog.
*
- * @param vlan_intf vlan interface name
- * @param type counter type
- * @param counters interface counter
+ * @param vlan_intf vlan interface name
+ * @param type counter type
+ * @param v4counters interface counter
+ * @param v6counters interface counter
*
* @return none
*/
static void dhcp_print_counters(const char *vlan_intf,
dhcp_counters_type_t type,
- uint64_t counters[][DHCP_MESSAGE_TYPE_COUNT])
+ uint64_t v4counters[][DHCPv4_MESSAGE_TYPE_COUNT],
+ uint64_t v6counters[][DHCPv6_MESSAGE_TYPE_COUNT])
{
- static const char *counter_desc[DHCP_COUNTERS_COUNT] = {
+ static const char *v4_counter_desc[DHCP_COUNTERS_COUNT] = {
+ [DHCP_COUNTERS_CURRENT] = " Current",
+ [DHCP_COUNTERS_SNAPSHOT] = "Snapshot"
+ };
+ static const char *v6_counter_desc[DHCP_COUNTERS_COUNT] = {
[DHCP_COUNTERS_CURRENT] = " Current",
[DHCP_COUNTERS_SNAPSHOT] = "Snapshot"
};
syslog(
LOG_NOTICE,
- "[%*s-%*s rx/tx] Discover: %*lu/%*lu, Offer: %*lu/%*lu, Request: %*lu/%*lu, ACK: %*lu/%*lu\n",
+ "DHCPv4 [%*s-%*s rx/tx] Discover: %*lu/%*lu, Offer: %*lu/%*lu, Request: %*lu/%*lu, ACK: %*lu/%*lu\n\
+ DHCPv6 [%*s-%*s rx/tx] Solicit: %*lu/%*lu, Advertise: %*lu/%*lu, Request: %*lu/%*lu, Reply: %*lu/%*lu\n",
+ IF_NAMESIZE, vlan_intf,
+ (int) strlen(v4_counter_desc[type]), v4_counter_desc[type],
+ DHCP_COUNTER_WIDTH, v4counters[DHCP_RX][DHCPv4_MESSAGE_TYPE_DISCOVER],
+ DHCP_COUNTER_WIDTH, v4counters[DHCP_TX][DHCPv4_MESSAGE_TYPE_DISCOVER],
+ DHCP_COUNTER_WIDTH, v4counters[DHCP_RX][DHCPv4_MESSAGE_TYPE_OFFER],
+ DHCP_COUNTER_WIDTH, v4counters[DHCP_TX][DHCPv4_MESSAGE_TYPE_OFFER],
+ DHCP_COUNTER_WIDTH, v4counters[DHCP_RX][DHCPv4_MESSAGE_TYPE_REQUEST],
+ DHCP_COUNTER_WIDTH, v4counters[DHCP_TX][DHCPv4_MESSAGE_TYPE_REQUEST],
+ DHCP_COUNTER_WIDTH, v4counters[DHCP_RX][DHCPv4_MESSAGE_TYPE_ACK],
+ DHCP_COUNTER_WIDTH, v4counters[DHCP_TX][DHCPv4_MESSAGE_TYPE_ACK],
IF_NAMESIZE, vlan_intf,
- (int) strlen(counter_desc[type]), counter_desc[type],
- DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_DISCOVER],
- DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_DISCOVER],
- DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_OFFER],
- DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_OFFER],
- DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_REQUEST],
- DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_REQUEST],
- DHCP_COUNTER_WIDTH, counters[DHCP_RX][DHCP_MESSAGE_TYPE_ACK],
- DHCP_COUNTER_WIDTH, counters[DHCP_TX][DHCP_MESSAGE_TYPE_ACK]
+ (int) strlen(v6_counter_desc[type]), v6_counter_desc[type],
+ DHCP_COUNTER_WIDTH, v6counters[DHCP_RX][DHCPv6_MESSAGE_TYPE_SOLICIT],
+ DHCP_COUNTER_WIDTH, v6counters[DHCP_TX][DHCPv6_MESSAGE_TYPE_SOLICIT],
+ DHCP_COUNTER_WIDTH, v6counters[DHCP_RX][DHCPv6_MESSAGE_TYPE_ADVERTISE],
+ DHCP_COUNTER_WIDTH, v6counters[DHCP_TX][DHCPv6_MESSAGE_TYPE_ADVERTISE],
+ DHCP_COUNTER_WIDTH, v6counters[DHCP_RX][DHCPv6_MESSAGE_TYPE_REQUEST],
+ DHCP_COUNTER_WIDTH, v6counters[DHCP_TX][DHCPv6_MESSAGE_TYPE_REQUEST],
+ DHCP_COUNTER_WIDTH, v6counters[DHCP_RX][DHCPv6_MESSAGE_TYPE_REPLY],
+ DHCP_COUNTER_WIDTH, v6counters[DHCP_TX][DHCPv6_MESSAGE_TYPE_REPLY]
);
}
@@ -454,12 +684,12 @@ int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context)
strncpy(ifr.ifr_name, context->intf, sizeof(ifr.ifr_name) - 1);
ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
- // Get network address
+ // Get v4 network address
if (ioctl(fd, SIOCGIFADDR, &ifr) == -1) {
syslog(LOG_ALERT, "ioctl: %s", explain_ioctl(fd, SIOCGIFADDR, &ifr));
break;
}
- context->ip = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr;
+ context->ipv4 = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr;
// Get mac address
if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
@@ -470,6 +700,30 @@ int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context)
close(fd);
+ // Get v6 network address
+ memset(&context->ipv6, 0, sizeof(context->ipv6));
+ struct ifaddrs *ifa, *ifa_tmp;
+
+ if (getifaddrs(&ifa) == -1) {
+ syslog(LOG_ALERT, "getifaddrs failed");
+ break;
+ }
+
+ ifa_tmp = ifa;
+ while (ifa_tmp) {
+ // Check if current interface has a valid IPv6 address (not link local address)
+ if ((strncmp(ifa_tmp->ifa_name, context->intf, sizeof(context->intf)) == 0) &&
+ (ifa_tmp->ifa_addr) &&
+ (ifa_tmp->ifa_addr->sa_family == AF_INET6) &&
+ (((struct sockaddr_in6*)(ifa_tmp->ifa_addr))->sin6_addr.__in6_u.__u6_addr16[0] != IPV6_LINK_LOCAL_PREFIX)) {
+
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6*) ifa_tmp->ifa_addr;
+ memcpy(&context->ipv6, &in6->sin6_addr, sizeof(context->ipv6));
+ }
+ ifa_tmp = ifa_tmp->ifa_next;
+ }
+ freeifaddrs(ifa);
+
rv = 0;
} while (0);
@@ -477,20 +731,41 @@ int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context)
}
/**
- * @code dhcp_device_get_ip(context);
+ * @code dhcp_device_get_ipv4(context);
*
* @brief Accessor method
*
* @param context pointer to device (interface) context
*
- * @return interface IP
+ * @return interface IPv4
*/
-int dhcp_device_get_ip(dhcp_device_context_t *context, in_addr_t *ip)
+int dhcp_device_get_ipv4(dhcp_device_context_t *context, in_addr_t *ip)
{
int rv = -1;
if (context != NULL && ip != NULL) {
- *ip = context->ip;
+ *ip = context->ipv4;
+ rv = 0;
+ }
+
+ return rv;
+}
+
+/**
+ * @code dhcp_device_get_ipv6(context);
+ *
+ * @brief Accessor method
+ *
+ * @param context pointer to device (interface) context
+ *
+ * @return interface IPv6
+ */
+int dhcp_device_get_ipv6(dhcp_device_context_t *context, struct in6_addr *ip)
+{
+ int rv = -1;
+
+ if (context != NULL && ip != NULL) {
+ *ip = context->ipv6;
rv = 0;
}
@@ -528,7 +803,8 @@ int dhcp_device_init(dhcp_device_context_t **context, const char *intf, uint8_t
dev_context->is_uplink = is_uplink;
- memset(dev_context->counters, 0, sizeof(dev_context->counters));
+ memset(dev_context->counters.v4counters, 0, sizeof(dev_context->counters.v4counters));
+ memset(dev_context->counters.v6counters, 0, sizeof(dev_context->counters.v6counters));
*context = dev_context;
rv = 0;
@@ -543,14 +819,15 @@ int dhcp_device_init(dhcp_device_context_t **context, const char *intf, uint8_t
}
/**
- * @code dhcp_device_start_capture(context, snaplen, base, giaddr_ip);
+ * @code dhcp_device_start_capture(context, snaplen, base, giaddr_ip, v6_vlan_ip);
*
* @brief starts packet capture on this interface
*/
int dhcp_device_start_capture(dhcp_device_context_t *context,
size_t snaplen,
struct event_base *base,
- in_addr_t giaddr_ip)
+ in_addr_t giaddr_ip,
+ struct in6_addr v6_vlan_ip)
{
int rv = -1;
@@ -560,12 +837,20 @@ int dhcp_device_start_capture(dhcp_device_context_t *context,
break;
}
- if (snaplen < UDP_START_OFFSET + sizeof(struct udphdr) + DHCP_OPTIONS_HEADER_SIZE) {
- syslog(LOG_ALERT, "dhcp_device_start_capture(%s): snap length is too low to capture DHCP options", context->intf);
+ // snaplen check for DHCPv4 size
+ if (dhcpv4_enabled && snaplen < UDPv4_START_OFFSET + sizeof(struct udphdr) + DHCPv4_OPTIONS_HEADER_SIZE) {
+ syslog(LOG_ALERT, "dhcp_device_start_capture(%s): snap length is too low to capture DHCPv4 options", context->intf);
+ break;
+ }
+
+ // snaplen check for DHCPv6 size - DHCPv6 message type is the first byte of the udp payload
+ if (dhcpv6_enabled && snaplen < DHCPv6_START_OFFSET + 1) {
+ syslog(LOG_ALERT, "dhcp_device_start_capture(%s): snap length is too low to capture DHCPv6 option", context->intf);
break;
}
context->giaddr_ip = giaddr_ip;
+ context->v6_vlan_ip = v6_vlan_ip;
context->buffer = (uint8_t *) malloc(snaplen);
if (context->buffer == NULL) {
@@ -603,17 +888,17 @@ void dhcp_device_shutdown(dhcp_device_context_t *context)
}
/**
- * @code dhcp_device_get_status(check_type, context);
+ * @code dhcp_device_get_status(check_type, context, type);
*
* @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate
* status
*/
-dhcp_mon_status_t dhcp_device_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context)
+dhcp_mon_status_t dhcp_device_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context, dhcp_type_t type)
{
dhcp_mon_status_t rv = DHCP_MON_STATUS_HEALTHY;
if (context != NULL) {
- rv = dhcp_device_check_health(check_type, context->counters);
+ rv = dhcp_device_check_health(check_type, context->counters.v4counters, context->counters.v6counters, type);
}
return rv;
@@ -627,9 +912,17 @@ dhcp_mon_status_t dhcp_device_get_status(dhcp_mon_check_t check_type, dhcp_devic
void dhcp_device_update_snapshot(dhcp_device_context_t *context)
{
if (context != NULL) {
- memcpy(context->counters[DHCP_COUNTERS_SNAPSHOT],
- context->counters[DHCP_COUNTERS_CURRENT],
- sizeof(context->counters[DHCP_COUNTERS_SNAPSHOT]));
+ if (dhcpv4_enabled) {
+ memcpy(context->counters.v4counters[DHCP_COUNTERS_SNAPSHOT],
+ context->counters.v4counters[DHCP_COUNTERS_CURRENT],
+ sizeof(context->counters.v4counters[DHCP_COUNTERS_SNAPSHOT]));
+ }
+
+ if (dhcpv6_enabled) {
+ memcpy(context->counters.v6counters[DHCP_COUNTERS_SNAPSHOT],
+ context->counters.v6counters[DHCP_COUNTERS_CURRENT],
+ sizeof(context->counters.v6counters[DHCP_COUNTERS_SNAPSHOT]));
+ }
}
}
@@ -641,6 +934,17 @@ void dhcp_device_update_snapshot(dhcp_device_context_t *context)
void dhcp_device_print_status(dhcp_device_context_t *context, dhcp_counters_type_t type)
{
if (context != NULL) {
- dhcp_print_counters(context->intf, type, context->counters[type]);
+ dhcp_print_counters(context->intf, type, context->counters.v4counters[type], context->counters.v6counters[type]);
}
}
+
+/**
+ * @code dhcp_device_active_types(dhcpv4, dhcpv6);
+ *
+ * @brief update local variables with active protocols
+ */
+void dhcp_device_active_types(bool dhcpv4, bool dhcpv6)
+{
+ dhcpv4_enabled = dhcpv4;
+ dhcpv6_enabled = dhcpv6;
+}
diff --git a/src/dhcpmon/src/dhcp_device.h b/src/dhcpmon/src/dhcp_device.h
index aa686f4e2718..f8aa874bfcce 100644
--- a/src/dhcpmon/src/dhcp_device.h
+++ b/src/dhcpmon/src/dhcp_device.h
@@ -18,21 +18,43 @@
/**
- * DHCP message types
+ * DHCPv4 message types
**/
typedef enum
{
- DHCP_MESSAGE_TYPE_DISCOVER = 1,
- DHCP_MESSAGE_TYPE_OFFER = 2,
- DHCP_MESSAGE_TYPE_REQUEST = 3,
- DHCP_MESSAGE_TYPE_DECLINE = 4,
- DHCP_MESSAGE_TYPE_ACK = 5,
- DHCP_MESSAGE_TYPE_NAK = 6,
- DHCP_MESSAGE_TYPE_RELEASE = 7,
- DHCP_MESSAGE_TYPE_INFORM = 8,
-
- DHCP_MESSAGE_TYPE_COUNT
-} dhcp_message_type_t;
+ DHCPv4_MESSAGE_TYPE_DISCOVER = 1,
+ DHCPv4_MESSAGE_TYPE_OFFER = 2,
+ DHCPv4_MESSAGE_TYPE_REQUEST = 3,
+ DHCPv4_MESSAGE_TYPE_DECLINE = 4,
+ DHCPv4_MESSAGE_TYPE_ACK = 5,
+ DHCPv4_MESSAGE_TYPE_NAK = 6,
+ DHCPv4_MESSAGE_TYPE_RELEASE = 7,
+ DHCPv4_MESSAGE_TYPE_INFORM = 8,
+
+ DHCPv4_MESSAGE_TYPE_COUNT
+} dhcpv4_message_type_t;
+
+/**
+ * DHCPv6 message types
+ **/
+typedef enum
+{
+ DHCPv6_MESSAGE_TYPE_SOLICIT = 1,
+ DHCPv6_MESSAGE_TYPE_ADVERTISE = 2,
+ DHCPv6_MESSAGE_TYPE_REQUEST = 3,
+ DHCPv6_MESSAGE_TYPE_CONFIRM = 4,
+ DHCPv6_MESSAGE_TYPE_RENEW = 5,
+ DHCPv6_MESSAGE_TYPE_REBIND = 6,
+ DHCPv6_MESSAGE_TYPE_REPLY = 7,
+ DHCPv6_MESSAGE_TYPE_RELEASE = 8,
+ DHCPv6_MESSAGE_TYPE_DECLINE = 9,
+ DHCPv6_MESSAGE_TYPE_RECONFIGURE = 10,
+ DHCPv6_MESSAGE_TYPE_INFORMATION_REQUEST = 11,
+ DHCPv6_MESSAGE_TYPE_RELAY_FORWARD = 12,
+ DHCPv6_MESSAGE_TYPE_RELAY_REPLY = 13,
+
+ DHCPv6_MESSAGE_TYPE_COUNT
+} dhcpv6_message_type_t;
/** packet direction */
typedef enum
@@ -60,6 +82,13 @@ typedef enum
DHCP_MON_STATUS_INDETERMINATE, /** DHCP relay health could not be determined */
} dhcp_mon_status_t;
+/** dhcp type */
+typedef enum
+{
+ DHCPv4_TYPE,
+ DHCPv6_TYPE,
+} dhcp_type_t;
+
/** dhcp check type */
typedef enum
{
@@ -67,19 +96,28 @@ typedef enum
DHCP_MON_CHECK_POSITIVE, /** Validate that received DORA packets are relayed */
} dhcp_mon_check_t;
+typedef struct
+{
+ uint64_t v4counters[DHCP_COUNTERS_COUNT][DHCP_DIR_COUNT][DHCPv4_MESSAGE_TYPE_COUNT];
+ /** current/snapshot counters of DHCPv4 packets */
+ uint64_t v6counters[DHCP_COUNTERS_COUNT][DHCP_DIR_COUNT][DHCPv6_MESSAGE_TYPE_COUNT];
+ /** current/snapshot counters of DHCPv6 packets */
+} counters_t;
+
/** DHCP device (interface) context */
typedef struct
{
int sock; /** Raw socket associated with this device/interface */
- in_addr_t ip; /** network address of this device (interface) */
+ in_addr_t ipv4; /** ipv4 network address of this device (interface) */
+ struct in6_addr ipv6; /** ipv6 network address of this device (interface) */
uint8_t mac[ETHER_ADDR_LEN]; /** hardware address of this device (interface) */
- in_addr_t giaddr_ip; /** Gateway IP address */
+ in_addr_t giaddr_ip; /** Gateway IPv4 address */
+ struct in6_addr v6_vlan_ip; /** Vlan IPv6 address */
uint8_t is_uplink; /** north interface? */
char intf[IF_NAMESIZE]; /** device (interface) name */
uint8_t *buffer; /** buffer used to read socket data */
size_t snaplen; /** snap length or buffer size */
- uint64_t counters[DHCP_COUNTERS_COUNT][DHCP_DIR_COUNT][DHCP_MESSAGE_TYPE_COUNT];
- /** current/snapshot counters of DHCP packets */
+ counters_t counters; /** counters for DHCPv4/6 packets */
} dhcp_device_context_t;
/**
@@ -94,16 +132,28 @@ typedef struct
int initialize_intf_mac_and_ip_addr(dhcp_device_context_t *context);
/**
- * @code dhcp_device_get_ip(context, ip);
+ * @code dhcp_device_get_ipv4(context, ip);
+ *
+ * @brief Accessor method
+ *
+ * @param context pointer to device (interface) context
+ * @param ip(out) pointer to device IPv4
+ *
+ * @return 0 on success, otherwise for failure
+ */
+int dhcp_device_get_ipv4(dhcp_device_context_t *context, in_addr_t *ip);
+
+/**
+ * @code dhcp_device_get_ipv6(context, ip);
*
* @brief Accessor method
*
* @param context pointer to device (interface) context
- * @param ip(out) pointer to device IP
+ * @param ip(out) pointer to device IPv6
*
* @return 0 on success, otherwise for failure
*/
-int dhcp_device_get_ip(dhcp_device_context_t *context, in_addr_t *ip);
+int dhcp_device_get_ipv6(dhcp_device_context_t *context, struct in6_addr *ip);
/**
* @code dhcp_device_get_aggregate_context();
@@ -130,7 +180,7 @@ int dhcp_device_init(dhcp_device_context_t **context,
uint8_t is_uplink);
/**
- * @code dhcp_device_start_capture(context, snaplen, base, giaddr_ip);
+ * @code dhcp_device_start_capture(context, snaplen, base, giaddr_ip, v6_vlan_ip);
*
* @brief starts packet capture on this interface
*
@@ -138,13 +188,15 @@ int dhcp_device_init(dhcp_device_context_t **context,
* @param snaplen length of packet capture
* @param base pointer to libevent base
* @param giaddr_ip gateway IP address
+ * @param v6_vlan_ip vlan IPv6 address
*
* @return 0 on success, otherwise for failure
*/
int dhcp_device_start_capture(dhcp_device_context_t *context,
size_t snaplen,
struct event_base *base,
- in_addr_t giaddr_ip);
+ in_addr_t giaddr_ip,
+ struct in6_addr v6_vlan_ip);
/**
* @code dhcp_device_shutdown(context);
@@ -158,17 +210,18 @@ int dhcp_device_start_capture(dhcp_device_context_t *context,
void dhcp_device_shutdown(dhcp_device_context_t *context);
/**
- * @code dhcp_device_get_status(check_type, context);
+ * @code dhcp_device_get_status(check_type, context, type);
*
* @brief collects DHCP relay status info for a given interface. If context is null, it will report aggregate
* status
*
* @param check_type Type of validation
* @param context Device (interface) context
+ * @param type DHCP type
*
* @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE
*/
-dhcp_mon_status_t dhcp_device_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context);
+dhcp_mon_status_t dhcp_device_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context, dhcp_type_t type);
/**
* @code dhcp_device_update_snapshot(context);
@@ -185,10 +238,21 @@ void dhcp_device_update_snapshot(dhcp_device_context_t *context);
* @brief prints status counters to syslog. If context is null, it will print aggregate status
*
* @param context Device (interface) context
- * @param counters_type Counter type to be printed
+ * @param type Counter type to be printed
*
* @return none
*/
void dhcp_device_print_status(dhcp_device_context_t *context, dhcp_counters_type_t type);
+/**
+ * @code dhcp_device_active_types(dhcpv4, dhcpv6);
+ *
+ * @brief update local variables with active protocols
+ *
+ * @param dhcpv4 DHCPv4 enable flag
+ * @param dhcpv6 DHCPv6 enable flag
+ *
+ * @return none
+ */
+void dhcp_device_active_types(bool dhcpv4, bool dhcpv6);
#endif /* DHCP_DEVICE_H_ */
diff --git a/src/dhcpmon/src/dhcp_devman.c b/src/dhcpmon/src/dhcp_devman.c
index 65484798dbd6..e7a25322207f 100644
--- a/src/dhcpmon/src/dhcp_devman.c
+++ b/src/dhcpmon/src/dhcp_devman.c
@@ -9,6 +9,8 @@
#include
#include
#include
+#include
+#include
#include "dhcp_devman.h"
@@ -35,7 +37,8 @@ static uint32_t dhcp_num_mgmt_intf = 0;
/** On Device vlan interface IP address corresponding vlan downlink IP
* This IP is used to filter Offer/Ack packet coming from DHCP server */
-static in_addr_t vlan_ip = 0;
+static in_addr_t v4_vlan_ip = 0;
+static struct in6_addr v6_vlan_ip = {0};
/* Device loopback interface ip, which will be used as the giaddr in dual tor setup. */
static in_addr_t loopback_ip = 0;
@@ -136,7 +139,8 @@ int dhcp_devman_add_intf(const char *name, char intf_type)
rv = dhcp_device_init(&dev->dev_context, dev->name, dev->is_uplink);
if (rv == 0 && intf_type == 'd') {
- rv = dhcp_device_get_ip(dev->dev_context, &vlan_ip);
+ rv = dhcp_device_get_ipv4(dev->dev_context, &v4_vlan_ip);
+ rv = dhcp_device_get_ipv6(dev->dev_context, &v6_vlan_ip);
dhcp_device_context_t *agg_dev = dhcp_device_get_aggregate_context();
@@ -174,7 +178,7 @@ int dhcp_devman_setup_dual_tor_mode(const char *name)
}
if (initialize_intf_mac_and_ip_addr(&loopback_intf_context) == 0 &&
- dhcp_device_get_ip(&loopback_intf_context, &loopback_ip) == 0) {
+ dhcp_device_get_ipv4(&loopback_intf_context, &loopback_ip) == 0) {
dual_tor_mode = 1;
} else {
syslog(LOG_ALERT, "failed to retrieve ip addr for loopback interface (%s)", name);
@@ -197,11 +201,13 @@ int dhcp_devman_start_capture(size_t snaplen, struct event_base *base)
if ((dhcp_num_south_intf == 1) && (dhcp_num_north_intf >= 1)) {
LIST_FOREACH(int_ptr, &intfs, entry) {
- rv = dhcp_device_start_capture(int_ptr->dev_context, snaplen, base, dual_tor_mode ? loopback_ip : vlan_ip);
+ rv = dhcp_device_start_capture(int_ptr->dev_context, snaplen, base, dual_tor_mode ? loopback_ip : v4_vlan_ip, v6_vlan_ip);
if (rv == 0) {
+ char ipv6_addr[INET6_ADDRSTRLEN];
+ inet_ntop(AF_INET6, &int_ptr->dev_context->ipv6, ipv6_addr, sizeof(ipv6_addr));
syslog(LOG_INFO,
- "Capturing DHCP packets on interface %s, ip: 0x%08x, mac [%02x:%02x:%02x:%02x:%02x:%02x] \n",
- int_ptr->name, int_ptr->dev_context->ip, int_ptr->dev_context->mac[0],
+ "Capturing DHCP packets on interface %s, ipv4: 0x%08x, ipv6: %s, mac [%02x:%02x:%02x:%02x:%02x:%02x] \n",
+ int_ptr->name, int_ptr->dev_context->ipv4, ipv6_addr, int_ptr->dev_context->mac[0],
int_ptr->dev_context->mac[1], int_ptr->dev_context->mac[2], int_ptr->dev_context->mac[3],
int_ptr->dev_context->mac[4], int_ptr->dev_context->mac[5]);
}
@@ -219,13 +225,13 @@ int dhcp_devman_start_capture(size_t snaplen, struct event_base *base)
}
/**
- * @code dhcp_devman_get_status(check_type, context);
+ * @code dhcp_devman_get_status(check_type, context, type);
*
* @brief collects DHCP relay status info.
*/
-dhcp_mon_status_t dhcp_devman_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context)
+dhcp_mon_status_t dhcp_devman_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context, dhcp_type_t type)
{
- return dhcp_device_get_status(check_type, context);
+ return dhcp_device_get_status(check_type, context, type);
}
/**
@@ -267,3 +273,13 @@ void dhcp_devman_print_status(dhcp_device_context_t *context, dhcp_counters_type
dhcp_device_print_status(context, type);
}
}
+
+/**
+ * @code dhcp_devman_active_types(dhcpv4, dhcpv6);
+ *
+ * @brief update local variables with active protocols
+ */
+void dhcp_devman_active_types(bool dhcpv4, bool dhcpv6)
+{
+ dhcp_device_active_types(dhcpv4, dhcpv6);
+}
diff --git a/src/dhcpmon/src/dhcp_devman.h b/src/dhcpmon/src/dhcp_devman.h
index 948e79cde4f4..6e30c654f69e 100644
--- a/src/dhcpmon/src/dhcp_devman.h
+++ b/src/dhcpmon/src/dhcp_devman.h
@@ -87,16 +87,17 @@ int dhcp_devman_setup_dual_tor_mode(const char *name);
int dhcp_devman_start_capture(size_t snaplen, struct event_base *base);
/**
- * @code dhcp_devman_get_status(check_type, context);
+ * @code dhcp_devman_get_status(check_type, context, type);
*
* @brief collects DHCP relay status info.
*
* @param check_type Type of validation
* @param context pointer to device (interface) context
+ * @param type DHCP type
*
* @return DHCP_MON_STATUS_HEALTHY, DHCP_MON_STATUS_UNHEALTHY, or DHCP_MON_STATUS_INDETERMINATE
*/
-dhcp_mon_status_t dhcp_devman_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context);
+dhcp_mon_status_t dhcp_devman_get_status(dhcp_mon_check_t check_type, dhcp_device_context_t *context, dhcp_type_t type);
/**
* @code dhcp_devman_update_snapshot(context);
@@ -119,4 +120,16 @@ void dhcp_devman_update_snapshot(dhcp_device_context_t *context);
*/
void dhcp_devman_print_status(dhcp_device_context_t *context, dhcp_counters_type_t type);
+/**
+ * @code dhcp_devman_active_types(dhcpv4, dhcpv6);
+ *
+ * @brief update local variables with active protocols
+ *
+ * @param dhcpv4 flag indicating dhcpv4 is enabled
+ * @param dhcpv6 flag indicating dhcpv6 is enabled
+ *
+ * @return none
+ */
+void dhcp_devman_active_types(bool dhcpv4, bool dhcpv6);
+
#endif /* DHCP_DEVMAN_H_ */
diff --git a/src/dhcpmon/src/dhcp_mon.c b/src/dhcpmon/src/dhcp_mon.c
index 74d9869741d1..2777b6484082 100644
--- a/src/dhcpmon/src/dhcp_mon.c
+++ b/src/dhcpmon/src/dhcp_mon.c
@@ -12,16 +12,24 @@
#include
#include
#include
+#include
#include "dhcp_mon.h"
#include "dhcp_devman.h"
+/** DHCP device/interface state counters */
+typedef struct
+{
+ int v4_count; /** count in the number of DHCPv4 unhealthy checks */
+ int v6_count; /** count in the number of DHCPv6 unhealthy checks */
+} dhcp_mon_count_t;
+
/** DHCP device/interface state */
typedef struct
{
dhcp_mon_check_t check_type; /** check type */
dhcp_device_context_t* (*get_context)(); /** functor to a device context accessor function */
- int count; /** count in the number of unhealthy checks */
+ dhcp_mon_count_t counters; /** count in the number of unhealthy checks */
const char *msg; /** message to be printed if unhealthy state is determined */
} dhcp_mon_state_t;
@@ -29,6 +37,10 @@ typedef struct
static int window_interval_sec = 18;
/** dhcp_unhealthy_max_count max count of consecutive unhealthy statuses before reporting to syslog */
static int dhcp_unhealthy_max_count = 10;
+/** DHCP versions flags */
+static bool dhcpv4_enabled;
+static bool dhcpv6_enabled;
+
/** libevent base struct */
static struct event_base *base;
/** libevent timeout event struct */
@@ -45,13 +57,15 @@ static dhcp_mon_state_t state_data[] = {
[0] = {
.check_type = DHCP_MON_CHECK_POSITIVE,
.get_context = dhcp_devman_get_agg_dev,
- .count = 0,
+ .counters.v4_count = 0,
+ .counters.v6_count = 0,
.msg = "dhcpmon detected disparity in DHCP Relay behavior. Duration: %d (sec) for vlan: '%s'\n"
},
[1] = {
.check_type = DHCP_MON_CHECK_NEGATIVE,
.get_context = dhcp_devman_get_mgmt_dev,
- .count = 0,
+ .counters.v4_count = 0,
+ .counters.v6_count = 0,
.msg = "dhcpmon detected DHCP packets traveling through mgmt interface (please check BGP routes.)"
" Duration: %d (sec) for intf: '%s'\n"
}
@@ -78,36 +92,89 @@ static void signal_callback(evutil_socket_t fd, short event, void *arg)
}
/**
- * @code check_dhcp_relay_health(state_data);
+ * @code check_dhcp_relay_health(state_data, dhcp_type);
*
* @brief check DHCP relay overall health
*
* @param state_data pointer to dhcpmon state data
*
+ * @param type DHCP type
+ *
* @return none
*/
-static void check_dhcp_relay_health(dhcp_mon_state_t *state_data)
+static void check_dhcp_relay_health(dhcp_mon_state_t *state_data, dhcp_type_t type)
{
dhcp_device_context_t *context = state_data->get_context();
- dhcp_mon_status_t dhcp_mon_status = dhcp_devman_get_status(state_data->check_type, context);
+ dhcp_mon_status_t dhcp_mon_status = dhcp_devman_get_status(state_data->check_type, context, type);
switch (dhcp_mon_status)
{
case DHCP_MON_STATUS_UNHEALTHY:
- if (++state_data->count > dhcp_unhealthy_max_count) {
- syslog(LOG_ALERT, state_data->msg, state_data->count * window_interval_sec, context->intf);
- dhcp_devman_print_status(context, DHCP_COUNTERS_SNAPSHOT);
- dhcp_devman_print_status(context, DHCP_COUNTERS_CURRENT);
+ switch (type)
+ {
+ case DHCPv4_TYPE:
+ if (++state_data->counters.v4_count > dhcp_unhealthy_max_count) {
+ syslog(LOG_ALERT, state_data->msg, state_data->counters.v4_count * window_interval_sec, context->intf);
+ dhcp_devman_print_status(context, DHCP_COUNTERS_SNAPSHOT);
+ dhcp_devman_print_status(context, DHCP_COUNTERS_CURRENT);
+ }
+ break;
+ case DHCPv6_TYPE:
+ if (++state_data->counters.v6_count > dhcp_unhealthy_max_count) {
+ syslog(LOG_ALERT, state_data->msg, state_data->counters.v6_count * window_interval_sec, context->intf);
+ dhcp_devman_print_status(context, DHCP_COUNTERS_SNAPSHOT);
+ dhcp_devman_print_status(context, DHCP_COUNTERS_CURRENT);
+ }
+ break;
+
+ default:
+ syslog(LOG_ERR, "Unknown DHCP type %d\n", type);
+ break;
}
break;
+
case DHCP_MON_STATUS_HEALTHY:
- state_data->count = 0;
+ switch (type)
+ {
+ case DHCPv4_TYPE:
+ state_data->counters.v4_count = 0;
+ break;
+ case DHCPv6_TYPE:
+ state_data->counters.v6_count = 0;
+ break;
+ default:
+ syslog(LOG_ERR, "Unknown DHCP type %d\n", type);
+ break;
+ }
break;
+
case DHCP_MON_STATUS_INDETERMINATE:
- if (state_data->count) {
- state_data->count++;
+ switch (type)
+ {
+ case DHCPv4_TYPE:
+ if (state_data->counters.v4_count) {
+ if (++state_data->counters.v4_count > dhcp_unhealthy_max_count) {
+ syslog(LOG_ALERT, state_data->msg, state_data->counters.v4_count * window_interval_sec, context->intf);
+ dhcp_devman_print_status(context, DHCP_COUNTERS_SNAPSHOT);
+ dhcp_devman_print_status(context, DHCP_COUNTERS_CURRENT);
+ }
+ }
+ break;
+ case DHCPv6_TYPE:
+ if (state_data->counters.v6_count) {
+ if (++state_data->counters.v6_count > dhcp_unhealthy_max_count) {
+ syslog(LOG_ALERT, state_data->msg, state_data->counters.v6_count * window_interval_sec, context->intf);
+ dhcp_devman_print_status(context, DHCP_COUNTERS_SNAPSHOT);
+ dhcp_devman_print_status(context, DHCP_COUNTERS_CURRENT);
+ }
+ }
+ break;
+ default:
+ syslog(LOG_ERR, "Unknown DHCP type %d\n", type);
+ break;
}
break;
+
default:
syslog(LOG_ERR, "DHCP Relay returned unknown status %d\n", dhcp_mon_status);
break;
@@ -128,7 +195,12 @@ static void check_dhcp_relay_health(dhcp_mon_state_t *state_data)
static void timeout_callback(evutil_socket_t fd, short event, void *arg)
{
for (uint8_t i = 0; i < sizeof(state_data) / sizeof(*state_data); i++) {
- check_dhcp_relay_health(&state_data[i]);
+ if (dhcpv4_enabled) {
+ check_dhcp_relay_health(&state_data[i], DHCPv4_TYPE);
+ }
+ if (dhcpv6_enabled) {
+ check_dhcp_relay_health(&state_data[i], DHCPv6_TYPE);
+ }
}
dhcp_devman_update_snapshot(NULL);
@@ -141,13 +213,17 @@ static void timeout_callback(evutil_socket_t fd, short event, void *arg)
* seconds. It also writes to syslog when dhcp relay has been unhealthy for consecutive max_count checks.
*
*/
-int dhcp_mon_init(int window_sec, int max_count)
+int dhcp_mon_init(int window_sec, int max_count, bool dhcpv4, bool dhcpv6)
{
int rv = -1;
do {
window_interval_sec = window_sec;
dhcp_unhealthy_max_count = max_count;
+ dhcpv4_enabled = dhcpv4;
+ dhcpv6_enabled = dhcpv6;
+
+ dhcp_devman_active_types(dhcpv4, dhcpv6);
base = event_base_new();
if (base == NULL) {
diff --git a/src/dhcpmon/src/dhcp_mon.h b/src/dhcpmon/src/dhcp_mon.h
index ae8911ab51fc..facd46da6860 100644
--- a/src/dhcpmon/src/dhcp_mon.h
+++ b/src/dhcpmon/src/dhcp_mon.h
@@ -17,10 +17,12 @@
*
* @param window_sec time interval between health checks
* @param max_count max count of consecutive unhealthy statuses before reporting to syslog
+ * @param dhcpv4 flag indicating dhcpv4 is enabled
+ * @param dhcpv6 flag indicating dhcpv6 is enabled
*
* @return 0 upon success, otherwise upon failure
*/
-int dhcp_mon_init(int window_sec, int max_count);
+int dhcp_mon_init(int window_sec, int max_count, bool dhcpv4, bool dhcpv6);
/**
* @code dhcp_mon_shutdown();
diff --git a/src/dhcpmon/src/main.c b/src/dhcpmon/src/main.c
index 29bc534accf0..1cf931821495 100644
--- a/src/dhcpmon/src/main.c
+++ b/src/dhcpmon/src/main.c
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include "dhcp_mon.h"
#include "dhcp_devman.h"
@@ -41,7 +42,8 @@ static const uint32_t dhcpmon_default_unhealthy_max_count = 10;
static void usage(const char *prog)
{
printf("Usage: %s -id {-iu }+ -im [-u ]"
- "[-w ] [-c ] [-s ] [-d]\n", prog);
+ "[-w ] [-c ] [-s ]"
+ "[-4 ] [-6 ] [-d]\n", prog);
printf("where\n");
printf("\tsouth interface: is a vlan interface,\n");
printf("\tnorth interface: is a TOR-T1 interface,\n");
@@ -112,6 +114,8 @@ int main(int argc, char **argv)
int max_unhealthy_count = dhcpmon_default_unhealthy_max_count;
size_t snaplen = dhcpmon_default_snaplen;
int make_daemon = 0;
+ bool dhcpv4_enabled = false;
+ bool dhcpv6_enabled = false;
setlogmask(LOG_UPTO(LOG_INFO));
openlog(basename(argv[0]), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_DAEMON);
@@ -155,6 +159,14 @@ int main(int argc, char **argv)
max_unhealthy_count = atoi(argv[i + 1]);
i += 2;
break;
+ case '4':
+ dhcpv4_enabled = true;
+ i++;
+ break;
+ case '6':
+ dhcpv6_enabled = true;
+ i++;
+ break;
default:
fprintf(stderr, "%s: %c: Unknown option\n", basename(argv[0]), argv[i][1]);
usage(basename(argv[0]));
@@ -165,7 +177,11 @@ int main(int argc, char **argv)
dhcpmon_daemonize();
}
- if ((dhcp_mon_init(window_interval, max_unhealthy_count) == 0) &&
+ if (!dhcpv4_enabled && !dhcpv6_enabled) {
+ dhcpv4_enabled = true;
+ }
+
+ if ((dhcp_mon_init(window_interval, max_unhealthy_count, dhcpv4_enabled, dhcpv6_enabled) == 0) &&
(dhcp_mon_start(snaplen) == 0)) {
rv = EXIT_SUCCESS;
diff --git a/src/iccpd/include/iccp_cli.h b/src/iccpd/include/iccp_cli.h
index c85fc4316b5f..3365495d2caa 100644
--- a/src/iccpd/include/iccp_cli.h
+++ b/src/iccpd/include/iccp_cli.h
@@ -36,10 +36,10 @@ typedef enum
typedef struct cli_param_queue
{
- char ifname[16];
+ char ifname[16];
cli_queue_type_et type;
- int param;
- int itf_add;
+ int param;
+ int itf_add;
LIST_ENTRY(cli_param_queue) cli_queue_next;
} cli_param_queue_st;
@@ -50,18 +50,21 @@ typedef struct cli_param_queue
#define MCLAG_INTF_STR "mclag_interface"
#define SYSTEM_MAC_STR "system_mac"
-int set_mc_lag_id(struct CSM* csm, uint16_t domain);
-int set_peer_link(int mid, const char* ifname);
-int set_local_address(int mid, const char* addr);
-int set_peer_address(int mid, const char* addr);
-int unset_mc_lag_id(struct CSM* csm, uint16_t domain);
+int set_mc_lag_id(struct CSM *csm, uint16_t domain);
+int set_peer_link(int mid, const char *ifname);
+int set_local_address(int mid, const char *addr);
+int set_peer_address(int mid, const char *addr);
+int unset_mc_lag_id(struct CSM *csm, uint16_t domain);
int unset_peer_link(int mid);
int unset_local_address(int mid);
int unset_peer_address(int mid);
-int iccp_cli_attach_mclag_domain_to_port_channel(int domain, const char* ifname);
-int iccp_cli_detach_mclag_domain_to_port_channel(const char* ifname);
-int set_local_system_id(const char* mac);
-int unset_local_system_id( );
+int iccp_cli_attach_mclag_domain_to_port_channel(int domain, const char *ifname);
+int iccp_cli_detach_mclag_domain_to_port_channel(const char *ifname);
+int set_local_system_id(const char *mac);
+int unset_local_system_id();
+
+int set_keepalive_time(int mid, int keepalive_time);
+int set_session_timeout(int mid, int session_timeout_val);
#endif
diff --git a/src/iccpd/include/iccp_cmd.h b/src/iccpd/include/iccp_cmd.h
index 01f37456b71d..31c905c1eb92 100644
--- a/src/iccpd/include/iccp_cmd.h
+++ b/src/iccpd/include/iccp_cmd.h
@@ -26,4 +26,7 @@
int iccp_config_from_file(char *config_default_dir);
+int set_mc_lag_by_id(uint16_t mid);
+int unset_mc_lag_by_id(uint16_t mid);
+
#endif /* ICCP_CMD_H_ */
diff --git a/src/iccpd/include/iccp_cmd_show.h b/src/iccpd/include/iccp_cmd_show.h
index a41fbadf8c77..7dad3ec1be1e 100644
--- a/src/iccpd/include/iccp_cmd_show.h
+++ b/src/iccpd/include/iccp_cmd_show.h
@@ -33,4 +33,6 @@ extern int iccp_ndisc_dump(char * *buf, int *num, int mclag_id);
extern int iccp_mac_dump(char * *buf, int *num, int mclag_id);
extern int iccp_local_if_dump(char * *buf, int *num, int mclag_id);
extern int iccp_peer_if_dump(char * *buf, int *num, int mclag_id);
+extern int iccp_cmd_dbg_counter_dump(char * *buf, int *data_len, int mclag_id);
+extern int iccp_unique_ip_if_dump(char * *buf, int *num, int mclag_id);
#endif
diff --git a/src/iccpd/include/iccp_csm.h b/src/iccpd/include/iccp_csm.h
index 01e424d13271..cc8879f8c835 100644
--- a/src/iccpd/include/iccp_csm.h
+++ b/src/iccpd/include/iccp_csm.h
@@ -45,10 +45,10 @@
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
-#endif /* INET_ADDRSTRLEN */
+#endif /* INET_ADDRSTRLEN */
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
-#endif /* INET6_ADDRSTRLEN */
+#endif /* INET6_ADDRSTRLEN */
/* For socket binding */
#define ICCP_TCP_PORT 8888
#define MAX_ACCEPT_CONNETIONS 20
@@ -113,10 +113,15 @@ struct CSM
time_t peer_warm_reboot_time;
time_t warm_reboot_disconn_time;
char peer_itf_name[IFNAMSIZ];
+ time_t peer_link_learning_retry_time;
char peer_ip[INET_ADDRSTRLEN];
char sender_ip[INET_ADDRSTRLEN];
void* sock_read_event_ptr;
+ int keepalive_time;
+ int session_timeout;
+ int peer_link_learning_enable;
+
/* Msg queue */
TAILQ_HEAD(msg_list, Msg) msg_list;
@@ -164,5 +169,5 @@ void iccp_csm_correspond_from_rg_connect_msg(struct CSM*, struct Msg*);
void iccp_csm_correspond_from_rg_disconnect_msg(struct CSM*, struct Msg*);
int mlacp_bind_port_channel_to_csm(struct CSM* csm, const char *ifname);
-
+int iccp_csm_init_mac_msg(struct MACMsg **mac_msg, char* data, int len);
#endif /* ICCP_CSM_H_ */
diff --git a/src/iccpd/include/iccp_ifm.h b/src/iccpd/include/iccp_ifm.h
index bbb1af67ee90..d668b569a869 100644
--- a/src/iccpd/include/iccp_ifm.h
+++ b/src/iccpd/include/iccp_ifm.h
@@ -37,6 +37,8 @@ int do_one_neigh_request(struct nlmsghdr *n);
void iccp_from_netlink_port_state_handler( char * ifname, int state);
-void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n);
+void vlan_mbrship_change_handler(unsigned int vlan_id, char *mbr_if_name, int add_flag);
+void del_all_pending_vlan_mbr_ifs(struct System *sys);
+void move_pending_vlan_mbr_to_lif(struct System *sys, struct LocalInterface* lif);
#endif // LACP_IFM_H
diff --git a/src/iccpd/include/iccp_netlink.h b/src/iccpd/include/iccp_netlink.h
index a4f321736d0c..483de43b2698 100644
--- a/src/iccpd/include/iccp_netlink.h
+++ b/src/iccpd/include/iccp_netlink.h
@@ -26,9 +26,7 @@
#include
#include
#include
-
#include
-
#include "../include/system.h"
#include "../include/port.h"
#include
@@ -37,6 +35,7 @@
#define NDISC_NEIGHBOUR_ADVERTISEMENT 136
#define ND_OPT_TARGET_LL_ADDR 2
#define NEXTHDR_ICMP 58
+#define ICCP_NLE_SEQ_MISMATCH -16
struct nd_msg
{
@@ -51,17 +50,20 @@ struct in6_pktinfo
unsigned int ipi6_ifindex; /* send/recv interface index */
};
-int iccp_get_port_member_list(struct LocalInterface* lif);
+int iccp_get_port_member_list(struct LocalInterface *lif);
void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg);
void iccp_event_handler_obj_input_dellink(struct nl_object *obj, void *arg);
int iccp_system_init_netlink_socket();
void iccp_system_dinit_netlink_socket();
int iccp_init_netlink_event_fd(struct System *sys);
-int iccp_handle_events(struct System * sys);
-void update_if_ipmac_on_standby(struct LocalInterface* lif_po);
+int iccp_handle_events(struct System *sys);
+void update_if_ipmac_on_standby(struct LocalInterface *lif_po, int dir);
int iccp_sys_local_if_list_get_addr();
-int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *mac, char *portname);
+int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *mac, char *portname, int permanent, int dir);
int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInterface *lif);
+void recover_if_ipmac_on_standby(struct LocalInterface* lif_po, int dir);
+void update_vlan_if_mac_on_standby(struct LocalInterface* lif_vlan, int dir);
+void recover_vlan_if_mac_on_standby(struct LocalInterface* lif_vlan, int dir, uint8_t *remote_system_mac);
+void update_vlan_if_mac_on_iccp_up(struct LocalInterface* lif_peer, int is_up, uint8_t *remote_system_mac);
#endif
-
diff --git a/src/iccpd/include/logger.h b/src/iccpd/include/logger.h
index a90fece2a4d9..9e7c90474fa4 100644
--- a/src/iccpd/include/logger.h
+++ b/src/iccpd/include/logger.h
@@ -32,7 +32,7 @@
typedef enum _iccpd_log_level_t
{
CRITICAL_LOG_LEVEL = 0,
- ERR_LOG_LEVEL = 1,
+ ERR_LOG_LEVEL = 1,
WARN_LOG_LEVEL = 2,
NOTICE_LOG_LEVEL = 3,
INFO_LOG_LEVEL = 4,
diff --git a/src/iccpd/include/mlacp_fsm.h b/src/iccpd/include/mlacp_fsm.h
index b335e78cd007..688fdcdd775f 100644
--- a/src/iccpd/include/mlacp_fsm.h
+++ b/src/iccpd/include/mlacp_fsm.h
@@ -26,9 +26,12 @@
#define _MLACP_FSM_H
#include "../include/port.h"
+#include "../include/mlacp_tlv.h"
#define MLCAP_SYNC_PHY_DEV_SEC 1 /*every 1 sec*/
+#define MLACP_LOCAL_IF_DOWN_TIMER 600 // 600 seconds.
+
#define MLACP(csm_ptr) (csm_ptr->app_csm.mlacp)
struct CSM;
@@ -47,7 +50,7 @@ typedef enum MLACP_APP_STATE MLACP_APP_STATE_E;
/* for sender only*/
enum MLACP_SYNC_STATE
{
- MLACP_SYNC_SYSCONF=0,
+ MLACP_SYNC_SYSCONF = 0,
MLACP_SYNC_AGGCONF,
MLACP_SYNC_AGGSTATE,
MLACP_SYNC_AGGINFO,
@@ -66,6 +69,85 @@ struct Remote_System
uint32_t node_id;
};
+/****************************************************************
+ * Debug counters to track message sent and received between
+ * MC-LAG peers over ICCP
+ ***************************************************************/
+typedef uint8_t ICCP_DBG_CNTR_DIR_e;
+enum ICCP_DBG_CNTR_DIR_e
+{
+ ICCP_DBG_CNTR_DIR_TX = 0,
+ ICCP_DBG_CNTR_DIR_RX = 1,
+ ICCP_DBG_CNTR_DIR_MAX
+};
+
+typedef uint8_t ICCP_DBG_CNTR_STS_e;
+enum ICCP_DBG_CNTR_STS_e
+{
+ ICCP_DBG_CNTR_STS_OK = 0,
+ ICCP_DBG_CNTR_STS_ERR = 1, /* Send error or receive processing error*/
+ ICCP_DBG_CNTR_STS_MAX
+};
+
+/* Change MCLAGDCTL_MAX_DBG_COUNTERS if ICCP_DBG_CNTR_MSG_MAX is more than 32 */
+enum ICCP_DBG_CNTR_MSG
+{
+ ICCP_DBG_CNTR_MSG_SYS_CONFIG = 0,
+ ICCP_DBG_CNTR_MSG_AGGR_CONFIG = 1,
+ ICCP_DBG_CNTR_MSG_AGGR_STATE = 2,
+ ICCP_DBG_CNTR_MSG_MAC_INFO = 3,
+ ICCP_DBG_CNTR_MSG_ARP_INFO = 4,
+ ICCP_DBG_CNTR_MSG_L2MC_INFO = 5,
+ ICCP_DBG_CNTR_MSG_PORTCHANNEL_INFO = 6,
+ ICCP_DBG_CNTR_MSG_PEER_LINK_INFO = 7,
+ ICCP_DBG_CNTR_MSG_HEART_BEAT = 8,
+ ICCP_DBG_CNTR_MSG_NAK = 9,
+ ICCP_DBG_CNTR_MSG_SYNC_DATA = 10,
+ ICCP_DBG_CNTR_MSG_SYNC_REQ = 11,
+ ICCP_DBG_CNTR_MSG_WARM_BOOT = 12,
+ ICCP_DBG_CNTR_MSG_IF_UP_ACK = 13,
+ ICCP_DBG_CNTR_MSG_STP_CONNECT = 14,
+ ICCP_DBG_CNTR_MSG_STP_DISCONNECT = 15,
+ ICCP_DBG_CNTR_MSG_STP_SYSTEM_CONFIG = 16,
+ ICCP_DBG_CNTR_MSG_STP_REGION_NAME = 17,
+ ICCP_DBG_CNTR_MSG_STP_REVISION_LEVEL = 18,
+ ICCP_DBG_CNTR_MSG_STP_INSTANCE_PRIORITY = 19,
+ ICCP_DBG_CNTR_MSG_STP_CONFIGURATION_DIGEST = 20,
+ ICCP_DBG_CNTR_MSG_STP_TC_INSTANCES = 21,
+ ICCP_DBG_CNTR_MSG_STP_ROOT_TIME_PARAM = 22,
+ ICCP_DBG_CNTR_MSG_STP_MIST_ROOT_TIME_PARAM = 23,
+ ICCP_DBG_CNTR_MSG_STP_SYNC_REQ = 24,
+ ICCP_DBG_CNTR_MSG_STP_SYNC_DATA = 25,
+ ICCP_DBG_CNTR_MSG_STP_PO_PORT_MAP = 26,
+ ICCP_DBG_CNTR_MSG_STP_AGE_OUT = 27,
+ ICCP_DBG_CNTR_MSG_STP_COMMON_MSG = 28,
+ ICCP_DBG_CNTR_MSG_MAX
+};
+typedef enum ICCP_DBG_CNTR_MSG ICCP_DBG_CNTR_MSG_e;
+
+/* Count messages sent to MCLAG peer */
+#define MLACP_SET_ICCP_TX_DBG_COUNTER(csm, tlv_type, status)\
+do{\
+ ICCP_DBG_CNTR_MSG_e dbg_type;\
+ dbg_type = mlacp_fsm_iccp_to_dbg_msg_type(tlv_type);\
+ if (csm && ((dbg_type) < ICCP_DBG_CNTR_MSG_MAX) && ((status) < ICCP_DBG_CNTR_STS_MAX))\
+ ++MLACP(csm).dbg_counters.iccp_counters[dbg_type][ICCP_DBG_CNTR_DIR_TX][status];\
+}while(0);
+
+/* Count messages received from MCLAG peer */
+#define MLACP_SET_ICCP_RX_DBG_COUNTER(csm, tlv_type, status)\
+do{\
+ ICCP_DBG_CNTR_MSG_e dbg_type;\
+ dbg_type = mlacp_fsm_iccp_to_dbg_msg_type(tlv_type);\
+ if (csm && ((dbg_type) < ICCP_DBG_CNTR_MSG_MAX) && ((status) < ICCP_DBG_CNTR_STS_MAX))\
+ ++MLACP(csm).dbg_counters.iccp_counters[dbg_type][ICCP_DBG_CNTR_DIR_RX][status];\
+}while(0);
+
+typedef struct mlacp_dbg_counter_info
+{
+ uint64_t iccp_counters[ICCP_DBG_CNTR_MSG_MAX][ICCP_DBG_CNTR_DIR_MAX][ICCP_DBG_CNTR_STS_MAX];
+}mlacp_dbg_counter_info_t;
+
struct mLACP
{
int id;
@@ -88,12 +170,16 @@ struct mLACP
TAILQ_HEAD(arp_info_list, Msg) arp_list;
TAILQ_HEAD(ndisc_msg_list, Msg) ndisc_msg_list;
TAILQ_HEAD(ndisc_info_list, Msg) ndisc_list;
- TAILQ_HEAD(mac_msg_list, Msg) mac_msg_list;
- TAILQ_HEAD(mac_info_list, Msg) mac_list;
+ TAILQ_HEAD(mac_msg_list, MACMsg) mac_msg_list;
+
+ struct mac_rb_tree mac_rb;
LIST_HEAD(lif_list, LocalInterface) lif_list;
LIST_HEAD(lif_purge_list, LocalInterface) lif_purge_list;
LIST_HEAD(pif_list, PeerInterface) pif_list;
+
+ /* ICCP message tx/rx debug counters */
+ mlacp_dbg_counter_info_t dbg_counters;
};
void mlacp_init(struct CSM* csm, int all);
@@ -101,9 +187,13 @@ void mlacp_finalize(struct CSM* csm);
void mlacp_fsm_transit(struct CSM* csm);
void mlacp_enqueue_msg(struct CSM*, struct Msg*);
struct Msg* mlacp_dequeue_msg(struct CSM*);
+char* mlacp_state(struct CSM* csm);
/* from app_csm*/
extern int mlacp_bind_local_if(struct CSM* csm, struct LocalInterface* local_if);
extern int mlacp_unbind_local_if(struct LocalInterface* local_if);
+/* Debug counter API */
+ICCP_DBG_CNTR_MSG_e mlacp_fsm_iccp_to_dbg_msg_type(uint32_t tlv_type);
+
#endif /* _MLACP_HANDLER_H */
diff --git a/src/iccpd/include/mlacp_link_handler.h b/src/iccpd/include/mlacp_link_handler.h
index 624b4111a7ee..5de4dba5bb8b 100644
--- a/src/iccpd/include/mlacp_link_handler.h
+++ b/src/iccpd/include/mlacp_link_handler.h
@@ -23,9 +23,16 @@
#ifndef __MLACP_LINK_HANDLER__
#define __MLACP_LINK_HANDLER__
+#include
#include "../include/iccp_csm.h"
#include "../include/mlacp_tlv.h"
+#define MCLAG_MAX_MSG_LEN 4096
+#define ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE MCLAG_MAX_MSG_LEN
+#define ICCP_MLAGSYNCD_RECV_MSG_BUFFER_SIZE (MCLAG_MAX_MSG_LEN * 256)
+
+extern char g_iccp_recv_buf[];
+
/*****************************************
* Link Handler
*
@@ -43,18 +50,48 @@ void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable);
void peerlink_port_isolate_cleanup(struct CSM* csm);
void update_peerlink_isolate_from_all_csm_lif(struct CSM* csm);
-void del_mac_from_chip(struct MACMsg *mac_msg);
-void add_mac_to_chip(struct MACMsg *mac_msg, uint8_t mac_type);
-uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg *mac_msg, uint8_t set);
-void iccp_get_fdb_change_from_syncd(void);
+ssize_t iccp_send_to_mclagsyncd(uint8_t msg_type, char *send_buff, uint16_t send_len);
+
+void del_mac_from_chip(struct MACMsg* mac_msg);
+void add_mac_to_chip(struct MACMsg* mac_msg, uint8_t mac_type);
+uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg* mac_msg, uint8_t set, uint8_t update_peer);
extern int mclagd_ctl_sock_create();
extern int mclagd_ctl_sock_accept(int fd);
extern int mclagd_ctl_interactive_process(int client_fd);
extern int parseMacString(const char *str_mac, uint8_t *bin_mac);
+
char *show_ip_str(uint32_t ipv4_addr);
char *show_ipv6_str(char *ipv6_addr);
void syncd_info_close();
int iccp_connect_syncd();
+
+void mlacp_link_disable_traffic_distribution(struct LocalInterface *lif);
+void mlacp_link_enable_traffic_distribution(struct LocalInterface *lif);
+int mlacp_link_set_iccp_state(int mlag_id, bool is_oper_up);
+int mlacp_link_set_iccp_role(int mlag_id, bool is_active_role, uint8_t *system_id);
+int mlacp_link_set_iccp_system_id(int mlag_id, uint8_t *system_id);
+int mlacp_link_del_iccp_info(int mlag_id);
+int mlacp_link_set_remote_if_state(int mlag_id, char *po_name, bool is_oper_up);
+int mlacp_link_del_remote_if_info(int mlag_id, char *po_name);
+int mlacp_link_set_peerlink_port_isolation(int mlag_id, char *po_name, bool is_isolation_enable);
+
+void mlacp_mlag_intf_detach_handler(struct CSM* csm, struct LocalInterface* local_if);
+void mlacp_peer_mlag_intf_delete_handler(struct CSM* csm, char *mlag_if_name);
+
+int iccp_mclagsyncd_msg_handler(struct System *sys);
+int syn_local_neigh_mac_info_to_peer(struct LocalInterface *local_if, int sync_add,
+ int is_v4, int is_v6, int sync_mac, int ack, int is_ipv6_ll, int dir);
+int syn_local_mac_info_to_peer(struct CSM* csm, struct LocalInterface *local_if, int sync_add, int is_sag);
+int syn_local_arp_info_to_peer(struct CSM* csm, struct LocalInterface *local_if, int sync_add, int ack);
+int syn_local_nd_info_to_peer(struct CSM* csm, struct LocalInterface *local_if, int sync_add, int ack, int is_ipv6_ll, int dir);
+int syn_ack_local_neigh_mac_info_to_peer(char *ifname, int is_ipv6_ll);
+int is_unique_ip_configured(char *ifname);
+void set_peerlink_learn_kernel(struct CSM* csm, int enable, int dir);
+void set_peer_mac_in_kernel(char *mac, int vlan, int add);
+void mlacp_fix_bridge_mac(struct CSM* csm);
+void update_orphan_port_mac(struct CSM *csm, struct LocalInterface *lif, int state);
+void mlacp_convert_remote_mac_to_local(struct CSM *csm, char *po_name);
+int sync_unique_ip();
#endif
diff --git a/src/iccpd/include/mlacp_sync_prepare.h b/src/iccpd/include/mlacp_sync_prepare.h
index 17cd8f260155..d5dcce9c0b34 100644
--- a/src/iccpd/include/mlacp_sync_prepare.h
+++ b/src/iccpd/include/mlacp_sync_prepare.h
@@ -45,12 +45,19 @@ int mlacp_prepare_for_sync_request_tlv(struct CSM* csm, char* buf, size_t max_bu
int mlacp_prepare_for_sync_data_tlv(struct CSM* csm, char* buf, size_t max_buf_size, int end);
int mlacp_prepare_for_sys_config(struct CSM* csm, char* buf, size_t max_buf_size);
int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_buf_size, struct MACMsg* mac_msg, int count);
-int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, struct ARPMsg* arp_msg, int count);
-int mlacp_prepare_for_ndisc_info(struct CSM *csm, char *buf, size_t max_buf_size, struct NDISCMsg *ndisc_msg, int count);
+int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, struct ARPMsg* arp_msg, int count, int dir);
+int mlacp_prepare_for_ndisc_info(struct CSM *csm, char *buf, size_t max_buf_size, struct NDISCMsg *ndisc_msg, int count, int dir);
int mlacp_prepare_for_heartbeat(struct CSM* csm, char* buf, size_t max_buf_size);
int mlacp_prepare_for_Aggport_state(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* local_if);
int mlacp_prepare_for_Aggport_config(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* lif, int purge_flag);
int mlacp_prepare_for_port_channel_info(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* port_channel);
int mlacp_prepare_for_port_peerlink_info(struct CSM* csm, char* buf, size_t max_buf_size, struct LocalInterface* peerlink_port);
int iccp_netlink_if_hwaddr_set(uint32_t ifindex, uint8_t *addr, unsigned int addr_len);
-#endif
\ No newline at end of file
+int mlacp_prepare_for_if_up_ack(
+ struct CSM *csm,
+ char *buf,
+ size_t max_buf_size,
+ uint8_t if_type,
+ uint16_t if_id,
+ uint8_t port_isolation_enable);
+#endif
diff --git a/src/iccpd/include/mlacp_sync_update.h b/src/iccpd/include/mlacp_sync_update.h
index 2a5d5b598d05..612134e10795 100644
--- a/src/iccpd/include/mlacp_sync_update.h
+++ b/src/iccpd/include/mlacp_sync_update.h
@@ -36,15 +36,16 @@ int mlacp_fsm_update_system_conf(struct CSM* csm, mLACPSysConfigTLV* tlv);
int mlacp_fsm_update_Aggport_state(struct CSM* csm, mLACPAggPortStateTLV* tlv);
int mlacp_fsm_update_arp_info(struct CSM* csm, struct mLACPARPInfoTLV* tlv);
-int mlacp_fsm_update_ndisc_info(struct CSM *csm, struct mLACPNDISCInfoTLV* tlv);
+int mlacp_fsm_update_ndisc_info(struct CSM *csm, struct mLACPNDISCInfoTLV *tlv);
int mlacp_fsm_update_heartbeat(struct CSM* csm, struct mLACPHeartbeatTLV* tlv);
int mlacp_fsm_update_warmboot(struct CSM* csm, struct mLACPWarmbootTLV* tlv);
+
void mlacp_enqueue_arp(struct CSM* csm, struct Msg* msg);
-void mlacp_enqueue_ndisc(struct CSM *csm, struct Msg* msg);
+void mlacp_enqueue_ndisc(struct CSM *csm, struct Msg *msg);
int mlacp_fsm_update_Agg_conf(struct CSM* csm, mLACPAggConfigTLV* portconf);
int mlacp_fsm_update_port_channel_info(struct CSM* csm, struct mLACPPortChannelInfoTLV* tlv);
int mlacp_fsm_update_peerlink_info(struct CSM* csm, struct mLACPPeerLinkInfoTLV* tlv);
int mlacp_fsm_update_mac_info_from_peer(struct CSM* csm, struct mLACPMACInfoTLV* tlv);
-#endif
\ No newline at end of file
+#endif
diff --git a/src/iccpd/include/mlacp_tlv.h b/src/iccpd/include/mlacp_tlv.h
index 7d3a4e18e4e2..ae2b47c1dcaf 100644
--- a/src/iccpd/include/mlacp_tlv.h
+++ b/src/iccpd/include/mlacp_tlv.h
@@ -28,6 +28,9 @@
#include "../include/msg_format.h"
#include "../include/port.h"
+#include "../include/openbsd_tree.h"
+#include "../include/mlacp_tlv.h"
+
#define MLACP_SYSCONF_NODEID_MSB_MASK 0x80
#define MLACP_SYSCONF_NODEID_NODEID_MASK 0x70
@@ -349,8 +352,9 @@ struct mLACPVLANInfoTLV
/* Mac entry Information TLV*/
struct mLACPMACData
{
- uint8_t type;/*add or del*/
- char mac_str[ETHER_ADDR_STR_LEN];
+ uint8_t type;/*add or del*/
+ uint8_t mac_type;
+ uint8_t mac_addr[ETHER_ADDR_LEN];
uint16_t vid;
/*Current if name that set in chip*/
char ifname[MAX_L_PORT_NAME];
@@ -366,17 +370,24 @@ struct mLACPMACInfoTLV
struct mLACPMACData MacEntry[0];
} __attribute__ ((packed));
+#define NEIGH_LOCAL 1
+#define NEIGH_REMOTE 2
+
struct ARPMsg
{
- uint8_t op_type;
- char ifname[MAX_L_PORT_NAME];
- uint32_t ipv4_addr;
- uint8_t mac_addr[ETHER_ADDR_LEN];
+ uint8_t op_type;
+ uint8_t flag;
+ uint8_t learn_flag; /*Loacl or Remote*/
+ char ifname[MAX_L_PORT_NAME];
+ uint32_t ipv4_addr; // net order
+ uint8_t mac_addr[ETHER_ADDR_LEN];
};
struct NDISCMsg
{
uint8_t op_type;
+ uint8_t flag;
+ uint8_t learn_flag; /*Loacl or Remote*/
char ifname[MAX_L_PORT_NAME];
uint32_t ipv6_addr[4];
uint8_t mac_addr[ETHER_ADDR_LEN];
@@ -387,7 +398,7 @@ struct NDISCMsg
*/
struct mLACPARPInfoTLV
{
- ICCParameter icc_parameter;
+ ICCParameter icc_parameter;
/* Local Interface ID */
uint16_t num_of_entry;
struct ARPMsg ArpEntry[0];
@@ -432,11 +443,50 @@ struct mLACPWarmbootTLV
uint8_t warmboot;
} __attribute__ ((packed));
+/*
+ * NOS: interface up ack message
+ * ACK is sent by MLAG peer after processing MLAG interface up notification.
+ * The ack indicates that port-isolation is applied on the MLAG peer node
+ */
+typedef uint8_t PORT_ISOLATION_STATE_e;
+enum PORT_ISOLATION_STATE_e
+{
+ PORT_ISOLATION_STATE_DISABLE = 0,
+ PORT_ISOLATION_STATE_ENABLE = 1
+};
+
+typedef uint8_t IF_UP_ACK_TYPE_e;
+enum IF_UP_ACK_TYPE_e
+{
+ IF_UP_ACK_TYPE_PHY_PORT = 0,
+ IF_UP_ACK_TYPE_PORT_CHANNEL = 1
+};
+
+struct mLACPIfUpAckTLV {
+ ICCParameter icc_parameter;
+ uint8_t if_type;
+ uint8_t port_isolation_state;
+ uint16_t if_id; /* LAG: agg_id */
+}__attribute__ ((packed));
+
enum NEIGH_OP_TYPE
{
- NEIGH_SYNC_LIF,
- NEIGH_SYNC_ADD,
- NEIGH_SYNC_DEL,
+ NEIGH_SYNC_LIF = 0,
+ NEIGH_SYNC_ADD = 1,
+ NEIGH_SYNC_DEL = 2,
+};
+
+enum NEIGH_FLAG
+{
+ NEIGH_SYNC_FLAG_ACK = 1,
+ NEIGH_SYNC_FLAG_SELF_LL = 2,
+ NEIGH_SYNC_FLAG_SELF_IP = 4,
+};
+
+enum NEIGH_SYNC_DIR
+{
+ NEIGH_SYNC_CLIENT_IP = 1,
+ NEIGH_SYNC_SELF_IP = 2,
};
enum MAC_AGE_TYPE
@@ -456,20 +506,30 @@ enum MAC_TYPE
{
MAC_TYPE_STATIC = 1,
MAC_TYPE_DYNAMIC = 2,
+ MAC_TYPE_DYNAMIC_LOCAL = 3, /* Used while sending MAC to Syncd to program with aging enabled. */
};
struct MACMsg
{
+ RB_ENTRY(MACMsg) mac_entry_rb;
+ uint16_t vid;
+ uint8_t mac_addr[ETHER_ADDR_LEN];
uint8_t op_type; /*add or del*/
uint8_t fdb_type; /*static or dynamic*/
- char mac_str[ETHER_ADDR_STR_LEN];
- uint16_t vid;
+
/*Current if name that set in chip*/
char ifname[MAX_L_PORT_NAME];
/*if we set the mac to peer-link, origin_ifname store the
original if name that learned from chip*/
char origin_ifname[MAX_L_PORT_NAME];
uint8_t age_flag;/*local or peer is age?*/
+ uint8_t pending_local_del;
+ uint8_t add_to_syncd;
+
+ TAILQ_ENTRY(MACMsg) tail; // entry into mac_msg_list
};
+RB_HEAD(mac_rb_tree, MACMsg);
+RB_PROTOTYPE(mac_rb_tree, MACMsg, mac_entry_rb, MACMsg_compare);
+
#endif /* MLACP_TLV_H_ */
diff --git a/src/iccpd/include/msg_format.h b/src/iccpd/include/msg_format.h
index 1af8bf8a46a8..b10b2db16130 100644
--- a/src/iccpd/include/msg_format.h
+++ b/src/iccpd/include/msg_format.h
@@ -29,6 +29,11 @@
#define MAX_MSG_LOG_SIZE 128
+#define ETHER_ADDR_LEN 6
+
+/* Header version for message sent from ICCPd to Mclagsyncd */
+#define ICCPD_TO_MCLAGSYNCD_HDR_VERSION 1
+
/*
* RFC 5561
* 4. Capability Message
@@ -99,7 +104,8 @@
#define TLV_T_MLACP_MAC_INFO 0x1038
#define TLV_T_MLACP_WARMBOOT_FLAG 0x1039
#define TLV_T_MLACP_NDISC_INFO 0x103A
-#define TLV_T_MLACP_LIST_END 0x104a // list end
+#define TLV_T_MLACP_IF_UP_ACK 0x103B
+#define TLV_T_MLACP_LIST_END 0x104a //list end
/* Debug */
static char* get_tlv_type_string(int type)
@@ -178,6 +184,9 @@ static char* get_tlv_type_string(int type)
case TLV_T_MLACP_STP_INFO:
return "TLV_T_MLACP_STP_INFO";
+
+ case TLV_T_MLACP_IF_UP_ACK:
+ return "TLV_T_MLACP_IF_UP_ACK";
}
return "UNKNOWN";
@@ -426,8 +435,12 @@ struct AppDisconnectCauseTLV
/*syncd send msg type to iccpd*/
typedef enum mclag_syncd_msg_type_e_
{
- MCLAG_SYNCD_MSG_TYPE_NONE = 0,
- MCLAG_SYNCD_MSG_TYPE_FDB_OPERATION = 1
+ MCLAG_SYNCD_MSG_TYPE_NONE = 0,
+ MCLAG_SYNCD_MSG_TYPE_FDB_OPERATION = 1,
+ MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_DOMAIN = 2,
+ MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_IFACE = 3,
+ MCLAG_SYNCD_MSG_TYPE_VLAN_MBR_UPDATES = 4,
+ MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_UNIQUE_IP = 5
}mclag_syncd_msg_type_e;
typedef enum mclag_msg_type_e_
@@ -438,7 +451,16 @@ typedef enum mclag_msg_type_e_
MCLAG_MSG_TYPE_FLUSH_FDB = 3,
MCLAG_MSG_TYPE_SET_MAC = 4,
MCLAG_MSG_TYPE_SET_FDB = 5,
- MCLAG_MSG_TYPE_GET_FDB_CHANGES = 20
+ MCLAG_MSG_TYPE_SET_TRAFFIC_DIST_ENABLE = 6,
+ MCLAG_MSG_TYPE_SET_TRAFFIC_DIST_DISABLE = 7,
+ MCLAG_MSG_TYPE_SET_ICCP_STATE = 8,
+ MCLAG_MSG_TYPE_SET_ICCP_ROLE = 9,
+ MCLAG_MSG_TYPE_SET_ICCP_SYSTEM_ID = 10,
+ MCLAG_MSG_TYPE_DEL_ICCP_INFO = 11,
+ MCLAG_MSG_TYPE_SET_REMOTE_IF_STATE = 12,
+ MCLAG_MSG_TYPE_DEL_REMOTE_IF_INFO = 13,
+ MCLAG_MSG_TYPE_SET_PEER_LINK_ISOLATION = 14,
+ MCLAG_MSG_TYPE_SET_ICCP_PEER_SYSTEM_ID = 15
}mclag_msg_type_e;
@@ -450,9 +472,33 @@ typedef enum mclag_sub_option_type_e_
MCLAG_SUB_OPTION_TYPE_MAC_LEARN_ENABLE = 3,
MCLAG_SUB_OPTION_TYPE_MAC_LEARN_DISABLE = 4,
MCLAG_SUB_OPTION_TYPE_SET_MAC_SRC = 5,
- MCLAG_SUB_OPTION_TYPE_SET_MAC_DST = 6
+ MCLAG_SUB_OPTION_TYPE_SET_MAC_DST = 6,
+ MCLAG_SUB_OPTION_TYPE_MCLAG_INTF_NAME = 7,
+ MCLAG_SUB_OPTION_TYPE_MCLAG_ID = 8,
+ MCLAG_SUB_OPTION_TYPE_ICCP_ROLE = 9,
+ MCLAG_SUB_OPTION_TYPE_SYSTEM_ID = 10,
+ MCLAG_SUB_OPTION_TYPE_OPER_STATUS = 11,
+ MCLAG_SUB_OPTION_TYPE_ISOLATION_STATE = 12,
+ MCLAG_SUB_OPTION_TYPE_PEER_SYSTEM_ID = 13
} mclag_sub_option_type_e;
+enum MCLAG_DOMAIN_CFG_OP_TYPE {
+ MCLAG_CFG_OPER_NONE = 0, //NOP
+ MCLAG_CFG_OPER_ADD = 1, //Add domain
+ MCLAG_CFG_OPER_DEL = 2, //Delete domain
+ MCLAG_CFG_OPER_UPDATE = 3, //update domain
+ MCLAG_CFG_OPER_ATTR_DEL = 4 //Attribute del
+};
+
+
+enum MCLAG_DOMAIN_CFG_ATTR_BMAP_FLAGS {
+ MCLAG_CFG_ATTR_NONE = 0x0,
+ MCLAG_CFG_ATTR_SRC_ADDR = 0x1,
+ MCLAG_CFG_ATTR_PEER_ADDR = 0x2,
+ MCLAG_CFG_ATTR_PEER_LINK = 0x4,
+ MCLAG_CFG_ATTR_KEEPALIVE_INTERVAL = 0x8,
+ MCLAG_CFG_ATTR_SESSION_TIMEOUT = 0x10
+};
struct IccpSyncdHDr
{
@@ -475,11 +521,37 @@ typedef struct mclag_sub_option_hdr_t_
struct mclag_fdb_info
{
- char mac[ETHER_ADDR_STR_LEN];
+ uint8_t mac[ETHER_ADDR_LEN];
unsigned int vid;
char port_name[MAX_L_PORT_NAME];
- short type; /*dynamic or static*/
- short op_type; /*add or del*/
+ short type; /*dynamic or static*/
+ short op_type; /*add or del*/
+};
+
+struct mclag_domain_cfg_info
+{
+ int op_type;/*add/del domain; add/del mclag domain */
+ int domain_id;
+ int keepalive_time;
+ int session_timeout;
+ char local_ip[INET_ADDRSTRLEN];
+ char peer_ip[INET_ADDRSTRLEN];
+ char peer_ifname[MAX_L_PORT_NAME];
+ uint8_t system_mac[ETHER_ADDR_LEN];
+ int attr_bmap;
+};
+
+struct mclag_iface_cfg_info
+{
+ int op_type; /*add/del mclag iface */
+ int domain_id;
+ char mclag_iface[MAX_L_PORT_NAME];
+};
+
+struct mclag_unique_ip_cfg_info
+{
+ int op_type;/*add/del mclag unique ip iface */
+ char mclag_unique_ip_ifname[MAX_L_PORT_NAME];
};
/* For storing message log: For Notification TLV */
@@ -491,6 +563,13 @@ struct MsgTypeSet
};
+struct mclag_vlan_mbr_info
+{
+ int op_type;/*add/del vlan_member */
+ unsigned int vid;
+ char mclag_iface[MAX_L_PORT_NAME];
+};
+
struct MsgLog
{
struct MsgTypeSet msg[MAX_MSG_LOG_SIZE];
diff --git a/src/iccpd/include/openbsd_tree.h b/src/iccpd/include/openbsd_tree.h
new file mode 100644
index 000000000000..c6dd8c1da9f0
--- /dev/null
+++ b/src/iccpd/include/openbsd_tree.h
@@ -0,0 +1,571 @@
+/* $OpenBSD: tree.h,v 1.14 2015/05/25 03:07:49 deraadt Exp $ */
+/*
+ * Copyright 2002 Niels Provos
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_TREE_H_
+#define _SYS_TREE_H_
+
+/*
+ * This file defines data structures for different types of trees:
+ * splay trees and red-black trees.
+ *
+ * A splay tree is a self-organizing data structure. Every operation
+ * on the tree causes a splay to happen. The splay moves the requested
+ * node to the root of the tree and partly rebalances it.
+ *
+ * This has the benefit that request locality causes faster lookups as
+ * the requested nodes move to the top of the tree. On the other hand,
+ * every lookup causes memory writes.
+ *
+ * The Balance Theorem bounds the total access time for m operations
+ * and n inserts on an initially empty tree as O((m + n)lg n). The
+ * amortized cost for a sequence of m accesses to a splay tree is O(lg n);
+ *
+ * A red-black tree is a binary search tree with the node color as an
+ * extra attribute. It fulfills a set of conditions:
+ * - every search path from the root to a leaf consists of the
+ * same number of black nodes,
+ * - each red node (except for the root) has a black parent,
+ * - each leaf node is black.
+ *
+ * Every operation on a red-black tree is bounded as O(lg n).
+ * The maximum height of a red-black tree is 2lg (n+1).
+ */
+
+#ifndef offsetof
+#ifdef __compiler_offsetof
+#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)
+#else
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+#endif
+
+#define SPLAY_HEAD(name, type) \
+ struct name { \
+ struct type *sph_root; /* root of the tree */ \
+ }
+
+#define SPLAY_INITIALIZER(root) \
+ { \
+ NULL \
+ }
+
+#define SPLAY_INIT(root) \
+ do { \
+ (root)->sph_root = NULL; \
+ } while (0)
+
+#define SPLAY_ENTRY(type) \
+ struct { \
+ struct type *spe_left; /* left element */ \
+ struct type *spe_right; /* right element */ \
+ }
+
+#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
+#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
+#define SPLAY_ROOT(head) (head)->sph_root
+#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
+
+/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
+#define SPLAY_ROTATE_RIGHT(head, tmp, field) \
+ do { \
+ SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
+ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
+ (head)->sph_root = tmp; \
+ } while (0)
+
+#define SPLAY_ROTATE_LEFT(head, tmp, field) \
+ do { \
+ SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
+ SPLAY_LEFT(tmp, field) = (head)->sph_root; \
+ (head)->sph_root = tmp; \
+ } while (0)
+
+#define SPLAY_LINKLEFT(head, tmp, field) \
+ do { \
+ SPLAY_LEFT(tmp, field) = (head)->sph_root; \
+ tmp = (head)->sph_root; \
+ (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
+ } while (0)
+
+#define SPLAY_LINKRIGHT(head, tmp, field) \
+ do { \
+ SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
+ tmp = (head)->sph_root; \
+ (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
+ } while (0)
+
+#define SPLAY_ASSEMBLE(head, node, left, right, field) \
+ do { \
+ SPLAY_RIGHT(left, field) = \
+ SPLAY_LEFT((head)->sph_root, field); \
+ SPLAY_LEFT(right, field) = \
+ SPLAY_RIGHT((head)->sph_root, field); \
+ SPLAY_LEFT((head)->sph_root, field) = \
+ SPLAY_RIGHT(node, field); \
+ SPLAY_RIGHT((head)->sph_root, field) = \
+ SPLAY_LEFT(node, field); \
+ } while (0)
+
+/* Generates prototypes and inline functions */
+
+#define SPLAY_PROTOTYPE(name, type, field, cmp) \
+ void name##_SPLAY(struct name *, struct type *); \
+ void name##_SPLAY_MINMAX(struct name *, int); \
+ struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
+ struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
+ \
+ /* Finds the node with the same key as elm */ \
+ static __inline struct type *name##_SPLAY_FIND(struct name *head, \
+ struct type *elm) \
+ { \
+ if (SPLAY_EMPTY(head)) \
+ return (NULL); \
+ name##_SPLAY(head, elm); \
+ if ((cmp)(elm, (head)->sph_root) == 0) \
+ return (head->sph_root); \
+ return (NULL); \
+ } \
+ \
+ static __inline struct type *name##_SPLAY_NEXT(struct name *head, \
+ struct type *elm) \
+ { \
+ name##_SPLAY(head, elm); \
+ if (SPLAY_RIGHT(elm, field) != NULL) { \
+ elm = SPLAY_RIGHT(elm, field); \
+ while (SPLAY_LEFT(elm, field) != NULL) { \
+ elm = SPLAY_LEFT(elm, field); \
+ } \
+ } else \
+ elm = NULL; \
+ return (elm); \
+ } \
+ \
+ static __inline struct type *name##_SPLAY_MIN_MAX(struct name *head, \
+ int val) \
+ { \
+ name##_SPLAY_MINMAX(head, val); \
+ return (SPLAY_ROOT(head)); \
+ }
+
+/* Main splay operation.
+ * Moves node close to the key of elm to top
+ */
+#define SPLAY_GENERATE(name, type, field, cmp) \
+ struct type *name##_SPLAY_INSERT(struct name *head, struct type *elm) \
+ { \
+ if (SPLAY_EMPTY(head)) { \
+ SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = \
+ NULL; \
+ } else { \
+ int __comp; \
+ name##_SPLAY(head, elm); \
+ __comp = (cmp)(elm, (head)->sph_root); \
+ if (__comp < 0) { \
+ SPLAY_LEFT(elm, field) = \
+ SPLAY_LEFT((head)->sph_root, field); \
+ SPLAY_RIGHT(elm, field) = (head)->sph_root; \
+ SPLAY_LEFT((head)->sph_root, field) = NULL; \
+ } else if (__comp > 0) { \
+ SPLAY_RIGHT(elm, field) = \
+ SPLAY_RIGHT((head)->sph_root, field); \
+ SPLAY_LEFT(elm, field) = (head)->sph_root; \
+ SPLAY_RIGHT((head)->sph_root, field) = NULL; \
+ } else \
+ return ((head)->sph_root); \
+ } \
+ (head)->sph_root = (elm); \
+ return (NULL); \
+ } \
+ \
+ struct type *name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
+ { \
+ struct type *__tmp; \
+ if (SPLAY_EMPTY(head)) \
+ return (NULL); \
+ name##_SPLAY(head, elm); \
+ if ((cmp)(elm, (head)->sph_root) == 0) { \
+ if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
+ (head)->sph_root = \
+ SPLAY_RIGHT((head)->sph_root, field); \
+ } else { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ (head)->sph_root = \
+ SPLAY_LEFT((head)->sph_root, field); \
+ name##_SPLAY(head, elm); \
+ SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
+ } \
+ return (elm); \
+ } \
+ return (NULL); \
+ } \
+ \
+ void name##_SPLAY(struct name *head, struct type *elm) \
+ { \
+ struct type __node, *__left, *__right, *__tmp; \
+ int __comp; \
+ \
+ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = \
+ NULL; \
+ __left = __right = &__node; \
+ \
+ while ((__comp = (cmp)(elm, (head)->sph_root))) { \
+ if (__comp < 0) { \
+ __tmp = SPLAY_LEFT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if ((cmp)(elm, __tmp) < 0) { \
+ SPLAY_ROTATE_RIGHT(head, __tmp, \
+ field); \
+ if (SPLAY_LEFT((head)->sph_root, \
+ field) \
+ == NULL) \
+ break; \
+ } \
+ SPLAY_LINKLEFT(head, __right, field); \
+ } else if (__comp > 0) { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if ((cmp)(elm, __tmp) > 0) { \
+ SPLAY_ROTATE_LEFT(head, __tmp, field); \
+ if (SPLAY_RIGHT((head)->sph_root, \
+ field) \
+ == NULL) \
+ break; \
+ } \
+ SPLAY_LINKRIGHT(head, __left, field); \
+ } \
+ } \
+ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
+ } \
+ \
+ /* Splay with either the minimum or the maximum element \
+ * Used to find minimum or maximum element in tree. \
+ */ \
+ void name##_SPLAY_MINMAX(struct name *head, int __comp) \
+ { \
+ struct type __node, *__left, *__right, *__tmp; \
+ \
+ SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = \
+ NULL; \
+ __left = __right = &__node; \
+ \
+ while (1) { \
+ if (__comp < 0) { \
+ __tmp = SPLAY_LEFT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if (__comp < 0) { \
+ SPLAY_ROTATE_RIGHT(head, __tmp, \
+ field); \
+ if (SPLAY_LEFT((head)->sph_root, \
+ field) \
+ == NULL) \
+ break; \
+ } \
+ SPLAY_LINKLEFT(head, __right, field); \
+ } else if (__comp > 0) { \
+ __tmp = SPLAY_RIGHT((head)->sph_root, field); \
+ if (__tmp == NULL) \
+ break; \
+ if (__comp > 0) { \
+ SPLAY_ROTATE_LEFT(head, __tmp, field); \
+ if (SPLAY_RIGHT((head)->sph_root, \
+ field) \
+ == NULL) \
+ break; \
+ } \
+ SPLAY_LINKRIGHT(head, __left, field); \
+ } \
+ } \
+ SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
+ }
+
+#define SPLAY_NEGINF -1
+#define SPLAY_INF 1
+
+#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
+#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
+#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
+#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
+#define SPLAY_MIN(name, x) \
+ (SPLAY_EMPTY(x) ? NULL : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
+#define SPLAY_MAX(name, x) \
+ (SPLAY_EMPTY(x) ? NULL : name##_SPLAY_MIN_MAX(x, SPLAY_INF))
+
+#define SPLAY_FOREACH(x, name, head) \
+ for ((x) = SPLAY_MIN(name, head); (x) != NULL; \
+ (x) = SPLAY_NEXT(name, head, x))
+
+/*
+ * Copyright (c) 2016 David Gwynne
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define RB_BLACK 0
+#define RB_RED 1
+
+struct rb_type {
+ int (*t_compare)(const void *, const void *);
+ void (*t_augment)(void *);
+ unsigned int t_offset; /* offset of rb_entry in type */
+};
+
+struct rbt_tree {
+ struct rb_entry *rbt_root;
+};
+
+struct rb_entry {
+ struct rb_entry *rbt_parent;
+ struct rb_entry *rbt_left;
+ struct rb_entry *rbt_right;
+ unsigned int rbt_color;
+};
+
+#define RB_HEAD(_name, _type) \
+ struct _name { \
+ struct rbt_tree rbh_root; \
+ }
+
+#define RB_ENTRY(_type) struct rb_entry
+
+static inline void _rb_init(struct rbt_tree *rbt)
+{
+ rbt->rbt_root = NULL;
+}
+
+static inline int _rb_empty(struct rbt_tree *rbt)
+{
+ return (rbt->rbt_root == NULL);
+}
+
+void *_rb_insert(const struct rb_type *, struct rbt_tree *, void *);
+void *_rb_remove(const struct rb_type *, struct rbt_tree *, void *);
+void *_rb_find(const struct rb_type *, struct rbt_tree *, const void *);
+void *_rb_nfind(const struct rb_type *, struct rbt_tree *, const void *);
+void *_rb_root(const struct rb_type *, struct rbt_tree *);
+void *_rb_min(const struct rb_type *, struct rbt_tree *);
+void *_rb_max(const struct rb_type *, struct rbt_tree *);
+void *_rb_next(const struct rb_type *, void *);
+void *_rb_prev(const struct rb_type *, void *);
+void *_rb_left(const struct rb_type *, void *);
+void *_rb_right(const struct rb_type *, void *);
+void *_rb_parent(const struct rb_type *, void *);
+void _rb_set_left(const struct rb_type *, void *, void *);
+void _rb_set_right(const struct rb_type *, void *, void *);
+void _rb_set_parent(const struct rb_type *, void *, void *);
+void _rb_poison(const struct rb_type *, void *, unsigned long);
+int _rb_check(const struct rb_type *, void *, unsigned long);
+
+#define RB_INITIALIZER(_head) { { NULL } }
+
+#define RB_PROTOTYPE(_name, _type, _field, _cmp) \
+ extern const struct rb_type *const _name##_RB_TYPE; \
+ \
+ __attribute__((__unused__)) static inline void _name##_RB_INIT( \
+ struct _name *head) \
+ { \
+ _rb_init(&head->rbh_root); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_INSERT(struct _name *head, struct _type *elm) \
+ { \
+ return _rb_insert(_name##_RB_TYPE, &head->rbh_root, elm); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_REMOVE(struct _name *head, struct _type *elm) \
+ { \
+ return _rb_remove(_name##_RB_TYPE, &head->rbh_root, elm); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_FIND(struct _name *head, const struct _type *key) \
+ { \
+ return _rb_find(_name##_RB_TYPE, &head->rbh_root, key); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_NFIND(struct _name *head, const struct _type *key) \
+ { \
+ return _rb_nfind(_name##_RB_TYPE, &head->rbh_root, key); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_ROOT(struct _name *head) \
+ { \
+ return _rb_root(_name##_RB_TYPE, &head->rbh_root); \
+ } \
+ \
+ __attribute__((__unused__)) static inline int _name##_RB_EMPTY( \
+ struct _name *head) \
+ { \
+ return _rb_empty(&head->rbh_root); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_MIN(struct _name *head) \
+ { \
+ return _rb_min(_name##_RB_TYPE, &head->rbh_root); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_MAX(struct _name *head) \
+ { \
+ return _rb_max(_name##_RB_TYPE, &head->rbh_root); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_NEXT(struct _type *elm) \
+ { \
+ return _rb_next(_name##_RB_TYPE, elm); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_PREV(struct _type *elm) \
+ { \
+ return _rb_prev(_name##_RB_TYPE, elm); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_LEFT(struct _type *elm) \
+ { \
+ return _rb_left(_name##_RB_TYPE, elm); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_RIGHT(struct _type *elm) \
+ { \
+ return _rb_right(_name##_RB_TYPE, elm); \
+ } \
+ \
+ __attribute__((__unused__)) static inline struct _type \
+ *_name##_RB_PARENT(struct _type *elm) \
+ { \
+ return _rb_parent(_name##_RB_TYPE, elm); \
+ } \
+ \
+ __attribute__((__unused__)) static inline void _name##_RB_SET_LEFT( \
+ struct _type *elm, struct _type *left) \
+ { \
+ _rb_set_left(_name##_RB_TYPE, elm, left); \
+ } \
+ \
+ __attribute__((__unused__)) static inline void _name##_RB_SET_RIGHT( \
+ struct _type *elm, struct _type *right) \
+ { \
+ _rb_set_right(_name##_RB_TYPE, elm, right); \
+ } \
+ \
+ __attribute__((__unused__)) static inline void _name##_RB_SET_PARENT( \
+ struct _type *elm, struct _type *parent) \
+ { \
+ _rb_set_parent(_name##_RB_TYPE, elm, parent); \
+ } \
+ \
+ __attribute__((__unused__)) static inline void _name##_RB_POISON( \
+ struct _type *elm, unsigned long poison) \
+ { \
+ _rb_poison(_name##_RB_TYPE, elm, poison); \
+ } \
+ \
+ __attribute__((__unused__)) static inline int _name##_RB_CHECK( \
+ struct _type *elm, unsigned long poison) \
+ { \
+ return _rb_check(_name##_RB_TYPE, elm, poison); \
+ }
+
+#define RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _aug) \
+ static int _name##_RB_COMPARE(const void *lptr, const void *rptr) \
+ { \
+ const struct _type *l = lptr, *r = rptr; \
+ return _cmp(l, r); \
+ } \
+ static const struct rb_type _name##_RB_INFO = { \
+ _name##_RB_COMPARE, _aug, offsetof(struct _type, _field), \
+ }; \
+ const struct rb_type *const _name##_RB_TYPE = &_name##_RB_INFO;
+
+#define RB_GENERATE_AUGMENT(_name, _type, _field, _cmp, _aug) \
+ static void _name##_RB_AUGMENT(void *ptr) \
+ { \
+ struct _type *p = ptr; \
+ return _aug(p); \
+ } \
+ RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, _name##_RB_AUGMENT)
+
+#define RB_GENERATE(_name, _type, _field, _cmp) \
+ RB_GENERATE_INTERNAL(_name, _type, _field, _cmp, NULL)
+
+#define RB_INIT(_name, _head) _name##_RB_INIT(_head)
+#define RB_INSERT(_name, _head, _elm) _name##_RB_INSERT(_head, _elm)
+#define RB_REMOVE(_name, _head, _elm) _name##_RB_REMOVE(_head, _elm)
+#define RB_FIND(_name, _head, _key) _name##_RB_FIND(_head, _key)
+#define RB_NFIND(_name, _head, _key) _name##_RB_NFIND(_head, _key)
+#define RB_ROOT(_name, _head) _name##_RB_ROOT(_head)
+#define RB_EMPTY(_name, _head) _name##_RB_EMPTY(_head)
+#define RB_MIN(_name, _head) _name##_RB_MIN(_head)
+#define RB_MAX(_name, _head) _name##_RB_MAX(_head)
+#define RB_NEXT(_name, _elm) _name##_RB_NEXT(_elm)
+#define RB_PREV(_name, _elm) _name##_RB_PREV(_elm)
+#define RB_LEFT(_name, _elm) _name##_RB_LEFT(_elm)
+#define RB_RIGHT(_name, _elm) _name##_RB_RIGHT(_elm)
+#define RB_PARENT(_name, _elm) _name##_RB_PARENT(_elm)
+#define RB_SET_LEFT(_name, _elm, _l) _name##_RB_SET_LEFT(_elm, _l)
+#define RB_SET_RIGHT(_name, _elm, _r) _name##_RB_SET_RIGHT(_elm, _r)
+#define RB_SET_PARENT(_name, _elm, _p) _name##_RB_SET_PARENT(_elm, _p)
+#define RB_POISON(_name, _elm, _p) _name##_RB_POISON(_elm, _p)
+#define RB_CHECK(_name, _elm, _p) _name##_RB_CHECK(_elm, _p)
+
+#define RB_FOREACH(_e, _name, _head) \
+ for ((_e) = RB_MIN(_name, (_head)); (_e) != NULL; \
+ (_e) = RB_NEXT(_name, (_e)))
+
+#define RB_FOREACH_SAFE(_e, _name, _head, _n) \
+ for ((_e) = RB_MIN(_name, (_head)); \
+ (_e) != NULL && ((_n) = RB_NEXT(_name, (_e)), 1); (_e) = (_n))
+
+#define RB_FOREACH_REVERSE(_e, _name, _head) \
+ for ((_e) = RB_MAX(_name, (_head)); (_e) != NULL; \
+ (_e) = RB_PREV(_name, (_e)))
+
+#define RB_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \
+ for ((_e) = RB_MAX(_name, (_head)); \
+ (_e) != NULL && ((_n) = RB_PREV(_name, (_e)), 1); (_e) = (_n))
+
+#endif /* _SYS_TREE_H_ */
diff --git a/src/iccpd/include/port.h b/src/iccpd/include/port.h
index dbd9d45fa83d..2275645e3a83 100644
--- a/src/iccpd/include/port.h
+++ b/src/iccpd/include/port.h
@@ -25,9 +25,17 @@
#define PORT_H_
#include
+#include
#include
#include
+#include "../include/openbsd_tree.h"
+
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif /* INET_ADDRSTRLEN */
+
+
#define ETHER_ADDR_LEN 6
#define ETHER_ADDR_STR_LEN 18
/*
@@ -47,9 +55,10 @@
#define IF_T_UNKNOW -1
#define IF_T_PORT 0
#define IF_T_PORT_CHANNEL 1
-#define IF_T_VLAN 2
-#define IF_T_VXLAN 3
-#define IF_T_BRIDGE 4
+#define IF_T_VLAN 2
+#define IF_T_VXLAN 3
+#define IF_T_BRIDGE 4
+
typedef struct
{
char *ifname;
@@ -62,14 +71,38 @@ struct If_info
LIST_ENTRY(If_info) csm_next;
};
+struct Unq_ip_If_info
+{
+ char name[MAX_L_PORT_NAME];
+ LIST_ENTRY(Unq_ip_If_info) if_next;
+};
+
struct VLAN_ID
{
uint16_t vid;
uint16_t vlan_removed;
struct LocalInterface* vlan_itf; /* loacl vlan interface */
- LIST_ENTRY(VLAN_ID) port_next;
+ RB_ENTRY(VLAN_ID) vlan_entry;
};
+RB_HEAD(vlan_rb_tree, VLAN_ID);
+RB_PROTOTYPE(vlan_rb_tree, VLAN_ID, vlan_rb_tree, vlan_node_compare);
+
+struct PendingVlanMbrIf
+{
+ char name[MAX_L_PORT_NAME];
+ struct vlan_rb_tree vlan_tree;
+ LIST_ENTRY(PendingVlanMbrIf) if_next;
+};
+
+#define VLAN_RB_REMOVE(name, head, elm) do { \
+ RB_REMOVE(name, head, elm); \
+ (elm)->vlan_entry.rbt_parent = NULL; \
+ (elm)->vlan_entry.rbt_left = NULL; \
+ (elm)->vlan_entry.rbt_right = NULL; \
+} while (0)
+
+
struct PeerInterface
{
int ifindex;
@@ -88,7 +121,7 @@ struct PeerInterface
struct CSM* csm;
LIST_ENTRY(PeerInterface) mlacp_next;
- LIST_HEAD(peer_vlan_list, VLAN_ID) vlan_list;
+ struct vlan_rb_tree vlan_tree;
};
struct LocalInterface
@@ -104,6 +137,8 @@ struct LocalInterface
uint8_t prefixlen;
uint32_t ipv6_addr[4];
uint8_t prefixlen_v6;
+ uint32_t ipv6_ll_addr[4];
+ uint8_t ll_prefixlen_v6;
uint8_t l3_mode;
uint8_t l3_mac_addr[ETHER_ADDR_LEN];
@@ -115,12 +150,18 @@ struct LocalInterface
int mlacp_state; /* Record mlacp state */
uint8_t isolate_to_peer_link;
+ time_t po_down_time;
+
struct CSM* csm;
uint8_t changed;
uint8_t port_config_sync;
+ bool is_traffic_disable; /* Disable traffic tx/rx */
+ bool is_l3_proto_enabled; /* Enable L3 Protocol support */
+ uint32_t vlan_count;
+ uint32_t master_ifindex; /* VRF ifindex*/
- LIST_HEAD(local_vlan_list, VLAN_ID) vlan_list;
+ struct vlan_rb_tree vlan_tree;
LIST_ENTRY(LocalInterface) system_next;
LIST_ENTRY(LocalInterface) system_purge_next;
@@ -128,7 +169,7 @@ struct LocalInterface
LIST_ENTRY(LocalInterface) mlacp_purge_next;
};
-struct LocalInterface* local_if_create(int ifindex, char* ifname, int type);
+struct LocalInterface* local_if_create(int ifindex, char* ifname, int type, uint8_t state);
struct LocalInterface* local_if_find_by_name(const char* ifname);
struct LocalInterface* local_if_find_by_ifindex(int ifindex);
struct LocalInterface* local_if_find_by_po_id(int po_id);
@@ -141,7 +182,6 @@ int local_if_is_l3_mode(struct LocalInterface* local_if);
void local_if_init(struct LocalInterface*);
void local_if_finalize(struct LocalInterface*);
-void ether_mac_set_addr_with_if_name(char *name, uint8_t* mac);
struct PeerInterface* peer_if_create(struct CSM* csm, int peer_if_number, int type);
struct PeerInterface* peer_if_find_by_name(struct CSM* csm, char* name);
diff --git a/src/iccpd/include/scheduler.h b/src/iccpd/include/scheduler.h
index a1b31039d794..a4c791d3d73f 100644
--- a/src/iccpd/include/scheduler.h
+++ b/src/iccpd/include/scheduler.h
@@ -38,9 +38,9 @@ struct CSM;
struct System;
#define CONNECT_INTERVAL_SEC 1
-#define CONNECT_TIMEOUT_MSEC 100
+#define CONNECT_TIMEOUT_MSEC 100
#define HEARTBEAT_TIMEOUT_SEC 15
-#define TRANSIT_INTERVAL_SEC 1
+#define TRANSIT_INTERVAL_SEC 1
#define EPOLL_TIMEOUT_MSEC 100
int scheduler_prepare_session(struct CSM*);
@@ -56,5 +56,6 @@ int scheduler_csm_read_callback(struct CSM* csm);
int iccp_get_server_sock_fd();
int scheduler_server_accept();
int iccp_receive_signal_handler(struct System* sys);
+void scheduler_csm_socket_cleanup(struct CSM* csm, int location);
#endif /* SCHEDULER_H_ */
diff --git a/src/iccpd/include/system.h b/src/iccpd/include/system.h
index 3ee314d253aa..c188d1a6d287 100644
--- a/src/iccpd/include/system.h
+++ b/src/iccpd/include/system.h
@@ -34,6 +34,7 @@
#include
#include
+#include
#include "../include/port.h"
@@ -52,6 +53,245 @@ struct CSM;
#define MAX_BUFSIZE 4096
#endif
+extern char mac_print_str[ETHER_ADDR_STR_LEN];
+
+#define MAC_IN_MSG_LIST(head, elm, field) \
+ (((elm)->field.tqe_next != NULL) || \
+ ((elm)->field.tqe_prev != NULL))
+
+#define CLEAR_MAC_IN_MSG_LIST(head, elm, field) \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = NULL;
+
+#define MAC_TAILQ_REMOVE(head, elm, field) do { \
+ TAILQ_REMOVE(head, elm, field); \
+ (elm)->field.tqe_next = NULL; \
+ (elm)->field.tqe_prev = NULL; \
+} while (/*CONSTCOND*/0)
+
+#define MAC_RB_REMOVE(name, head, elm) do { \
+ RB_REMOVE(name, head, elm); \
+ (elm)->mac_entry_rb.rbt_parent = NULL; \
+ (elm)->mac_entry_rb.rbt_left = NULL; \
+ (elm)->mac_entry_rb.rbt_right = NULL; \
+} while (/*CONSTCOND*/0)
+
+/* Debug counters */
+/* Debug counters to track messages ICCPd sent to MclagSyncd */
+typedef uint8_t SYNCD_DBG_CNTR_STS_e;
+enum SYNCD_DBG_CNTR_STS_e
+{
+ SYNCD_DBG_CNTR_STS_OK = 0,
+ SYNCD_DBG_CNTR_STS_ERR = 1, /* Send error or receive processing error*/
+ SYNCD_DBG_CNTR_STS_MAX
+};
+
+typedef uint8_t SYNCD_TX_DBG_CNTR_MSG_e;
+enum SYNCD_TX_DBG_CNTR_MSG_e
+{
+ SYNCD_TX_DBG_CNTR_MSG_PORT_ISOLATE = 0,
+ SYNCD_TX_DBG_CNTR_MSG_PORT_MAC_LEARN_MODE = 1,
+ SYNCD_TX_DBG_CNTR_MSG_FLUSH_FDB = 2,
+ SYNCD_TX_DBG_CNTR_MSG_SET_IF_MAC = 3,
+ SYNCD_TX_DBG_CNTR_MSG_SET_FDB = 4,
+ SYNCD_TX_DBG_CNTR_MSG_SET_TRAFFIC_DIST_ENABLE = 5,
+ SYNCD_TX_DBG_CNTR_MSG_SET_TRAFFIC_DIST_DISABLE = 6,
+ SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_STATE = 7,
+ SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_ROLE = 8,
+ SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_SYSTEM_ID = 9,
+ SYNCD_TX_DBG_CNTR_MSG_DEL_ICCP_INFO = 10,
+ SYNCD_TX_DBG_CNTR_MSG_SET_REMOTE_IF_STATE = 11,
+ SYNCD_TX_DBG_CNTR_MSG_DEL_REMOTE_IF_INFO = 12,
+ SYNCD_TX_DBG_CNTR_MSG_PEER_LINK_ISOLATION = 13,
+ SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_PEER_SYSTEM_ID = 14,
+ SYNCD_TX_DBG_CNTR_MSG_MAX
+};
+
+typedef uint8_t SYNCD_RX_DBG_CNTR_MSG_e;
+enum SYNCD_RX_DBG_CNTR_MSG_e
+{
+ SYNCD_RX_DBG_CNTR_MSG_MAC = 0,
+ SYNCD_RX_DBG_CNTR_MSG_CFG_MCLAG_DOMAIN = 1,
+ SYNCD_RX_DBG_CNTR_MSG_CFG_MCLAG_IFACE = 2,
+ SYNCD_RX_DBG_CNTR_MSG_CFG_MCLAG_UNIQUE_IP = 3,
+ SYNCD_RX_DBG_CNTR_MSG_VLAN_MBR_UPDATES = 4,
+ SYNCD_RX_DBG_CNTR_MSG_MAX
+};
+
+/* Count messages ICCP daemon sent to MclagSyncd */
+#define SYSTEM_SET_SYNCD_TX_DBG_COUNTER(sys, syncd_msg_type, status)\
+do{\
+ SYNCD_TX_DBG_CNTR_MSG_e dbg_type;\
+ dbg_type = system_syncdtx_to_dbg_msg_type(syncd_msg_type);\
+ if (sys && ((dbg_type) < SYNCD_TX_DBG_CNTR_MSG_MAX) && ((status) < SYNCD_DBG_CNTR_STS_MAX))\
+ {\
+ ++sys->dbg_counters.syncd_tx_counters[dbg_type][status];\
+ }\
+}while(0);
+
+/* Count messages ICCP daemon received from MclagSyncd */
+#define SYSTEM_SET_SYNCD_RX_DBG_COUNTER(sys, syncd_msg_type, status)\
+do{\
+ SYNCD_RX_DBG_CNTR_MSG_e dbg_type;\
+ dbg_type = system_syncdrx_to_dbg_msg_type(syncd_msg_type);\
+ if (sys && ((dbg_type) < SYNCD_RX_DBG_CNTR_MSG_MAX) && ((status) < SYNCD_DBG_CNTR_STS_MAX))\
+ {\
+ ++sys->dbg_counters.syncd_rx_counters[dbg_type][status];\
+ }\
+}while(0);
+
+#define SYSTEM_INCR_SESSION_DOWN_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.session_down_counter;\
+
+#define SYSTEM_GET_SESSION_DOWN_COUNTER(sys)\
+ ( (sys) ? (sys)->dbg_counters.session_down_counter: 0)
+
+#define SYSTEM_INCR_PEER_LINK_DOWN_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.peer_link_down_counter;\
+
+#define SYSTEM_INCR_WARMBOOT_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.warmboot_counter;
+
+#define SYSTEM_INCR_INVALID_PEER_MSG_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.rx_peer_invalid_msg_counter;
+
+#define SYSTEM_GET_INVALID_PEER_MSG_COUNTER(sys)\
+ ((sys) ? ((sys)->dbg_counters.rx_peer_invalid_msg_counter) ? 0)
+
+#define SYSTEM_INCR_RX_READ_SOCK_ZERO_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.rx_read_sock_zero_len_counter;
+
+#define SYSTEM_INCR_HDR_READ_SOCK_ERR_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.rx_peer_hdr_read_sock_err_counter;
+
+#define SYSTEM_INCR_HDR_READ_SOCK_ZERO_LEN_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.rx_peer_hdr_read_sock_zero_len_counter;
+
+#define SYSTEM_INCR_TLV_READ_SOCK_ERR_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.rx_peer_tlv_read_sock_err_counter;
+
+#define SYSTEM_INCR_TLV_READ_SOCK_ZERO_LEN_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.rx_peer_tlv_read_sock_zero_len_counter;
+
+#define SYSTEM_INCR_SOCKET_CLOSE_ERR_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.socket_close_err_counter;
+
+#define SYSTEM_INCR_SOCKET_CLEANUP_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.socket_cleanup_counter;
+
+#define SYSTEM_INCR_RX_RETRY_FAIL_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.rx_retry_fail_counter;
+
+#define SYSTEM_INCR_MAC_ENTRY_ALLOC_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.mac_entry_alloc_counter;
+
+#define SYSTEM_INCR_MAC_ENTRY_FREE_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.mac_entry_free_counter;
+
+#define SYSTEM_INCR_RX_READ_SOCK_ZERO_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.rx_read_sock_zero_len_counter;
+
+#define SYSTEM_INCR_RX_READ_SOCK_ERR_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.rx_read_sock_err_counter;
+
+#define SYSTEM_INCR_RX_READ_STP_SOCK_ZERO_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.rx_read_stp_sock_zero_len_counter;
+
+#define SYSTEM_INCR_RX_READ_STP_SOCK_ERR_COUNTER(sys)\
+ if (sys)\
+ ++sys->dbg_counters.rx_read_stp_sock_err_counter;
+#define SYSTEM_SET_RETRY_COUNTER(sys, num_retry)\
+ if (sys)\
+ {\
+ sys->dbg_counters.rx_retry_total_counter += num_retry;\
+ if (num_retry > sys->dbg_counters.rx_retry_max_counter)\
+ sys->dbg_counters.rx_retry_max_counter = num_retry;\
+ }
+
+#define SYSTEM_INCR_NETLINK_UNKNOWN_IF_NAME(ifname)\
+do {\
+ struct System *sys;\
+ sys = system_get_instance();\
+ if (sys)\
+ {\
+ ++sys->dbg_counters.unknown_if_name_count;\
+ if (sys->dbg_counters.unknown_if_name_count < 10)\
+ {\
+ ICCPD_LOG_NOTICE("ICCP_FSM","NETLINK_COUNTER: Unknown if_name %s", ifname);\
+ }\
+ }\
+}while(0)
+
+#define SYSTEM_INCR_NETLINK_RX_ERROR()\
+do {\
+ struct System *sys;\
+ sys = system_get_instance();\
+ if (sys)\
+ ++sys->dbg_counters.rx_error_count;\
+}while(0)
+
+typedef struct system_dbg_counter_info
+{
+ /* Netlink message counters */
+ uint32_t newlink_count;
+ uint32_t dellink_count;
+ uint32_t newnbr_count;
+ uint32_t delnbr_count;
+ uint32_t newaddr_count;
+ uint32_t deladdr_count;
+ uint32_t unknown_type_count;
+ uint32_t rx_error_count;
+
+ /* Netlink link sub-message count */
+ uint32_t unknown_if_name_count;
+
+ /* Netlink neighbor sub-message count */
+ uint32_t newmac_count;
+ uint32_t delmac_count;
+
+ uint32_t session_down_counter; //not counting down due to warmboot
+ uint32_t peer_link_down_counter;
+ uint32_t warmboot_counter;
+ uint32_t rx_peer_invalid_msg_counter; //counts partial msgs received as sending end is not sending partial msgs
+ uint32_t rx_peer_hdr_read_sock_err_counter; //counts socket header read errors
+ uint32_t rx_peer_hdr_read_sock_zero_len_counter; //counts socket header read zero length
+ uint32_t rx_peer_tlv_read_sock_err_counter; //counts socket data/tlv read errors
+ uint32_t rx_peer_tlv_read_sock_zero_len_counter; //counts socket data/tlv read zero length
+ uint32_t socket_close_err_counter; //socket close failure
+ uint32_t socket_cleanup_counter; //socket cleanup outside of session down
+ uint32_t rx_retry_max_counter; //max non-blocking RX retry for one message
+ uint32_t rx_retry_total_counter; //total number of non-blocking RX retry
+ uint32_t rx_retry_fail_counter; //total number of non-blocking RX retry failure
+
+ uint32_t rx_read_sock_zero_len_counter; //counts socket header read zero length from sync_fd
+ uint32_t rx_read_sock_err_counter; //counts socket header read zero length from sync_fd
+ uint32_t rx_read_stp_sock_zero_len_counter; //counts socket header read zero length from syncd
+ uint32_t rx_read_stp_sock_err_counter; //counts socket header read zero length from syncd
+
+ uint32_t mac_entry_alloc_counter;
+ uint32_t mac_entry_free_counter;
+
+ uint64_t syncd_tx_counters[SYNCD_TX_DBG_CNTR_MSG_MAX][SYNCD_DBG_CNTR_STS_MAX];
+ uint64_t syncd_rx_counters[SYNCD_RX_DBG_CNTR_MSG_MAX][SYNCD_DBG_CNTR_STS_MAX];
+}system_dbg_counter_info_t;
+
struct System
{
int server_fd;/* Peer-Link Socket*/
@@ -78,6 +318,8 @@ struct System
LIST_HEAD(csm_list, CSM) csm_list;
LIST_HEAD(lif_all_list, LocalInterface) lif_list;
LIST_HEAD(lif_purge_all_list, LocalInterface) lif_purge_list;
+ LIST_HEAD(unq_ip_all_if_list, Unq_ip_If_info) unq_ip_if_list;
+ LIST_HEAD(pending_vlan_mbr_if_list, PendingVlanMbrIf) pending_vlan_mbr_if_list;
/* Settings */
char* log_file_path;
@@ -91,13 +333,23 @@ struct System
time_t csm_trans_time;
int need_sync_team_again;
int need_sync_netlink_again;
+
+ /* ICCDd/MclagSyncd debug counters */
+ system_dbg_counter_info_t dbg_counters;
};
struct CSM* system_create_csm();
struct CSM* system_get_csm_by_peer_ip(const char*);
+struct CSM* system_get_csm_by_peer_ifname(char *ifname);
struct CSM* system_get_csm_by_mlacp_id(int id);
+struct CSM* system_get_first_csm();
struct System* system_get_instance();
void system_finalize();
void system_init(struct System*);
+SYNCD_TX_DBG_CNTR_MSG_e system_syncdtx_to_dbg_msg_type(uint32_t msg_type);
+SYNCD_RX_DBG_CNTR_MSG_e system_syncdrx_to_dbg_msg_type(uint32_t msg_type);
+
+char *mac_addr_to_str(uint8_t mac_addr[ETHER_ADDR_LEN]);
+void system_update_netlink_counters(uint16_t netlink_msg_type, struct nlmsghdr *nlh);
#endif /* SYSTEM_H_ */
diff --git a/src/iccpd/src/Makefile.am b/src/iccpd/src/Makefile.am
index 9d19dbb5285c..7415f8d4dbb7 100644
--- a/src/iccpd/src/Makefile.am
+++ b/src/iccpd/src/Makefile.am
@@ -17,6 +17,7 @@ iccpd_SOURCES = \
mlacp_link_handler.c \
mlacp_sync_prepare.c mlacp_sync_update.c\
mlacp_fsm.c \
- iccp_netlink.c
+ iccp_netlink.c \
+ openbsd_tree.c
iccpd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON)
iccpd_LDADD = -lnl-genl-3 -lnl-route-3 -lnl-3 -lpthread
diff --git a/src/iccpd/src/app_csm.c b/src/iccpd/src/app_csm.c
index 589cf94015d8..4ef5f13b5e35 100644
--- a/src/iccpd/src/app_csm.c
+++ b/src/iccpd/src/app_csm.c
@@ -239,7 +239,7 @@ int mlacp_bind_local_if(struct CSM* csm, struct LocalInterface* lif)
if (lif_po->type == IF_T_PORT_CHANNEL && lif_po->po_id == lif->po_id)
{
/*if join a po member, may swss restart, reset portchannel ip mac to mclagsyncd*/
- update_if_ipmac_on_standby(lif_po);
+ update_if_ipmac_on_standby(lif_po, 1);
return 0;
}
}
diff --git a/src/iccpd/src/iccp_cli.c b/src/iccpd/src/iccp_cli.c
index 8d0ede8b3feb..59235215bffb 100644
--- a/src/iccpd/src/iccp_cli.c
+++ b/src/iccpd/src/iccp_cli.c
@@ -52,10 +52,8 @@ int unset_mc_lag_id( struct CSM *csm, uint16_t id)
if (!csm)
return MCLAG_ERROR;
- /* Mlag-ID, RG-ID, MLACP-ID*/
- csm->mlag_id = 0;
- csm->iccp_info.icc_rg_id = 0;
- csm->app_csm.mlacp.id = 0;
+ /* Remove ICCP info from STATE_DB */
+ mlacp_link_del_iccp_info(csm->mlag_id);
iccp_csm_finalize(csm);
@@ -73,7 +71,9 @@ int set_peer_link(int mid, const char* ifname)
len = strlen(ifname);
- if (strncmp(ifname, FRONT_PANEL_PORT_PREFIX, strlen(FRONT_PANEL_PORT_PREFIX)) != 0 && strncmp(ifname, PORTCHANNEL_PREFIX, strlen(PORTCHANNEL_PREFIX)) != 0 && strncmp(ifname, VXLAN_TUNNEL_PREFIX, strlen(VXLAN_TUNNEL_PREFIX)) != 0)
+ if (strncmp(ifname, FRONT_PANEL_PORT_PREFIX, strlen(FRONT_PANEL_PORT_PREFIX)) != 0
+ && strncmp(ifname, PORTCHANNEL_PREFIX, strlen(PORTCHANNEL_PREFIX)) != 0
+ && strncmp(ifname, VXLAN_TUNNEL_PREFIX, strlen(VXLAN_TUNNEL_PREFIX)) != 0)
{
ICCPD_LOG_ERR(__FUNCTION__, "Peer-link is %s, must be Ethernet or PortChannel or VTTNL(Vxlan tunnel)", ifname);
return MCLAG_ERROR;
@@ -83,8 +83,11 @@ int set_peer_link(int mid, const char* ifname)
if (csm == NULL)
return MCLAG_ERROR;
- if (len > IFNAMSIZ)
+ if (len > MAX_L_PORT_NAME)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Peer-link %s, Strlen %d greater than MAX:%d ", ifname, len, MAX_L_PORT_NAME);
return MCLAG_ERROR;
+ }
if (strlen(csm->peer_itf_name) > 0)
{
@@ -114,7 +117,7 @@ int set_peer_link(int mid, const char* ifname)
csm->mlag_id, ifname);
}
- memset(csm->peer_itf_name, 0, IFNAMSIZ);
+ memset(csm->peer_itf_name, 0, MAX_L_PORT_NAME);
memcpy(csm->peer_itf_name, ifname, len);
/* update peer-link link handler*/
@@ -128,6 +131,8 @@ int set_peer_link(int mid, const char* ifname)
if (lif->type == IF_T_PORT_CHANNEL)
iccp_get_port_member_list(lif);
+
+ set_peerlink_learn_kernel(csm, 0, 4);
}
/*disconnect the link for mac and arp sync up*/
@@ -147,15 +152,17 @@ int unset_peer_link(int mid)
if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
{
/*must be enabled mac learn*/
- if (csm->peer_link_if)
+ if (csm->peer_link_if) {
set_peerlink_mlag_port_learn(csm->peer_link_if, 1);
+ set_peerlink_learn_kernel(csm, 1, 5);
+ }
}
/* update peer-link link handler*/
scheduler_session_disconnect_handler(csm);
/* clean peer-link*/
- memset(csm->peer_itf_name, 0, IFNAMSIZ);
+ memset(csm->peer_itf_name, 0, MAX_L_PORT_NAME);
if (csm->peer_link_if)
{
csm->peer_link_if->is_peer_link = 0;
@@ -282,6 +289,42 @@ int unset_peer_address(int mid)
return 0;
}
+int set_keepalive_time(int mid, int keepalive_time)
+{
+ struct CSM* csm = NULL;
+ size_t len = 0;
+
+ csm = system_get_csm_by_mlacp_id(mid);
+ if (csm == NULL)
+ return MCLAG_ERROR;
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Set keepalive_time : %d", keepalive_time);
+
+ if (csm->keepalive_time != keepalive_time)
+ {
+ csm->keepalive_time = keepalive_time;
+ //reset heartbeat send time to send keepalive immediately
+ csm->heartbeat_send_time = 0;
+ }
+ return 0;
+}
+
+int set_session_timeout(int mid, int session_timeout_val)
+{
+ struct CSM* csm = NULL;
+ size_t len = 0;
+
+ csm = system_get_csm_by_mlacp_id(mid);
+ if (csm == NULL)
+ return MCLAG_ERROR;
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Set session timeout : %d", session_timeout_val);
+
+ csm->session_timeout = session_timeout_val;
+ return 0;
+}
+
+
int iccp_cli_attach_mclag_domain_to_port_channel( int domain, const char* ifname)
{
struct CSM* csm = NULL;
@@ -352,17 +395,30 @@ int iccp_cli_detach_mclag_domain_to_port_channel( const char* ifname)
|| lif_po->po_id <= 0
|| lif_po->csm == NULL)
{
+ if (lif_po)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "CSM already detached for ifname = %s", lif_po->name);
+ }
return MCLAG_ERROR;
}
/* find csm*/
csm = lif_po->csm;
+ if(!csm)
+ {
+ ICCPD_LOG_WARN(__FUNCTION__, "unexpected condition!!!; lif->csm not found!; Detach mclag from ifname = %s", lif_po->name);
+ return 0;
+ }
+
ICCPD_LOG_DEBUG(__FUNCTION__, "Detach mclag id = %d from ifname = %s",
csm->mlag_id, lif_po->name);
+ //if it is standby node change back the mac to its original system mac
+ recover_if_ipmac_on_standby(lif_po, 1);
+
/* process link state handler before detaching it.*/
- mlacp_mlag_link_del_handler(csm, lif_po);
+ mlacp_mlag_intf_detach_handler(csm, lif_po);
unbind_poid = lif_po->po_id;
mlacp_unbind_local_if(lif_po);
@@ -377,6 +433,7 @@ int iccp_cli_detach_mclag_domain_to_port_channel( const char* ifname)
if (strcmp(ifname, cif->name) == 0)
LIST_REMOVE(cif, csm_next);
}
+
return 0;
}
diff --git a/src/iccpd/src/iccp_cmd.c b/src/iccpd/src/iccp_cmd.c
index 50025a8e3810..8b39b73d0f6b 100644
--- a/src/iccpd/src/iccp_cmd.c
+++ b/src/iccpd/src/iccp_cmd.c
@@ -55,6 +55,21 @@ int set_mc_lag_by_id(uint16_t mid)
return ret;
}
+int unset_mc_lag_by_id(uint16_t mid)
+{
+ int ret = 0;
+ struct CSM* csm = NULL;
+
+ csm = system_get_csm_by_mlacp_id(mid);
+ if (csm)
+ {
+ ret = unset_mc_lag_id(csm, mid);
+ return ret;
+ }
+
+ return MCLAG_ERROR;
+}
+
#define CONFIG_LINE_LEN 512
int iccp_config_from_command(char * line)
diff --git a/src/iccpd/src/iccp_cmd_show.c b/src/iccpd/src/iccp_cmd_show.c
index 18b2e5bded8e..984984434dc0 100644
--- a/src/iccpd/src/iccp_cmd_show.c
+++ b/src/iccpd/src/iccp_cmd_show.c
@@ -20,6 +20,7 @@
*
* Maintainer: jianjun, grace Li from nephos
*/
+#include
#include
#include
#include
@@ -33,6 +34,8 @@
#include "../include/iccp_cmd_show.h"
#include "../include/mlacp_link_handler.h"
+extern int local_if_l3_proto_enabled(const char* ifname);
+
int iccp_mclag_config_dump(char * *buf, int *num, int mclag_id)
{
struct mclagd_state state_info;
@@ -67,6 +70,11 @@ int iccp_mclag_config_dump(char * *buf, int *num, int mclag_id)
else
state_info.keepalive = 0;
+ if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
+ state_info.info_sync_done = 1;
+ else
+ state_info.info_sync_done = 0;
+
if (mclag_id > 0)
{
if (csm->mlag_id == mclag_id)
@@ -93,13 +101,15 @@ int iccp_mclag_config_dump(char * *buf, int *num, int mclag_id)
if (peer_link_if)
memcpy(state_info.peer_link_mac, peer_link_if->mac_addr, 6);
+ state_info.keepalive_time = csm->keepalive_time;
+ state_info.session_timeout = csm->session_timeout;
+
logconfig = logger_get_configuration();
memcpy(state_info.loglevel, log_level_to_string(logconfig->log_level), strlen( log_level_to_string(logconfig->log_level)));
state_info.role = csm->role_type;
str_size = MCLAGDCTL_PORT_MEMBER_BUF_LEN;
- len = 0;
LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next)
{
@@ -177,6 +187,7 @@ int iccp_arp_dump(char * *buf, int *num, int mclag_id)
iccpd_arp = (struct ARPMsg*)msg->buf;
mclagd_arp.op_type = iccpd_arp->op_type;
+ mclagd_arp.learn_flag = iccpd_arp->learn_flag;
memcpy(mclagd_arp.ifname, iccpd_arp->ifname, strlen(iccpd_arp->ifname));
memcpy(mclagd_arp.ipv4_addr, show_ip_str(iccpd_arp->ipv4_addr), 16);
memcpy(mclagd_arp.mac_addr, iccpd_arp->mac_addr, 6);
@@ -219,7 +230,6 @@ int iccp_ndisc_dump(char * *buf, int *num, int mclag_id)
if (!(sys = system_get_instance()))
{
- ICCPD_LOG_INFO(__FUNCTION__, "cannot find sys!\n");
return EXEC_TYPE_NO_EXIST_SYS;
}
@@ -243,12 +253,12 @@ int iccp_ndisc_dump(char * *buf, int *num, int mclag_id)
iccpd_ndisc = (struct NDISCMsg *)msg->buf;
mclagd_ndisc.op_type = iccpd_ndisc->op_type;
+ mclagd_ndisc.learn_flag = iccpd_ndisc->learn_flag;
memcpy(mclagd_ndisc.ifname, iccpd_ndisc->ifname, strlen(iccpd_ndisc->ifname));
memcpy(mclagd_ndisc.ipv6_addr, show_ipv6_str((char *)iccpd_ndisc->ipv6_addr), 46);
memcpy(mclagd_ndisc.mac_addr, iccpd_ndisc->mac_addr, 6);
- memcpy(ndisc_buf + MCLAGD_REPLY_INFO_HDR + ndisc_num * sizeof(struct mclagd_ndisc_msg),
- &mclagd_ndisc, sizeof(struct mclagd_ndisc_msg));
+ memcpy(ndisc_buf + MCLAGD_REPLY_INFO_HDR + ndisc_num * sizeof(struct mclagd_ndisc_msg), &mclagd_ndisc, sizeof(struct mclagd_ndisc_msg));
ndisc_num++;
@@ -302,14 +312,13 @@ int iccp_mac_dump(char * *buf, int *num, int mclag_id)
continue;
}
- TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail)
+ RB_FOREACH (iccpd_mac, mac_rb_tree, &MLACP(csm).mac_rb)
{
memset(&mclagd_mac, 0, sizeof(struct mclagd_mac_msg));
- iccpd_mac = (struct MACMsg*)msg->buf;
mclagd_mac.op_type = iccpd_mac->op_type;
mclagd_mac.fdb_type = iccpd_mac->fdb_type;
- memcpy(mclagd_mac.mac_str, iccpd_mac->mac_str, ETHER_ADDR_STR_LEN);
+ memcpy(mclagd_mac.mac_addr, iccpd_mac->mac_addr, ETHER_ADDR_LEN);
mclagd_mac.vid = iccpd_mac->vid;
memcpy(mclagd_mac.ifname, iccpd_mac->ifname, strlen(iccpd_mac->ifname));
memcpy(mclagd_mac.origin_ifname, iccpd_mac->origin_ifname, strlen(iccpd_mac->origin_ifname));
@@ -328,7 +337,7 @@ int iccp_mac_dump(char * *buf, int *num, int mclag_id)
return EXEC_TYPE_FAILED;
}
}
- }
+ }
*buf = mac_buf;
*num = mac_num;
@@ -344,6 +353,7 @@ int iccp_local_if_dump(char * *buf, int *num, int mclag_id)
struct System *sys = NULL;
struct CSM *csm = NULL;
struct LocalInterface *lif_po = NULL;
+ struct LocalInterface *lif_peer = NULL;
struct mclagd_local_if mclagd_lif;
struct VLAN_ID* vlan_id = NULL;
char * str_buf = NULL;
@@ -398,7 +408,7 @@ int iccp_local_if_dump(char * *buf, int *num, int mclag_id)
else if (lif_po->state == PORT_STATE_TEST)
memcpy(mclagd_lif.state, "Test", 4);
- memcpy(mclagd_lif.ipv4_addr, show_ip_str(htonl(lif_po->ipv4_addr)), 16);
+ memcpy(mclagd_lif.ipv4_addr, show_ip_str(lif_po->ipv4_addr), 16);
mclagd_lif.prefixlen = lif_po->prefixlen;
mclagd_lif.l3_mode = local_if_is_l3_mode(lif_po);
@@ -422,17 +432,47 @@ int iccp_local_if_dump(char * *buf, int *num, int mclag_id)
memcpy(mclagd_lif.mlacp_state, "ERROR", 5);
mclagd_lif.isolate_to_peer_link = lif_po->isolate_to_peer_link;
+ mclagd_lif.is_traffic_disable = lif_po->is_traffic_disable;
str_buf = mclagd_lif.vlanlist;
len = 0;
- LIST_FOREACH(vlan_id, &(lif_po->vlan_list), port_next)
+ int prev_vlan_id = 0;
+ int range = 0;
+ int to_be_printed = 0;
+
+ RB_FOREACH (vlan_id, vlan_rb_tree, &(lif_po->vlan_tree))
{
- if (vlan_id != NULL )
+ if (str_size - len < 4)
+ break;
+ if (!prev_vlan_id || vlan_id->vid != prev_vlan_id + 1)
{
- if (str_size - len < 4)
- break;
+ if (range)
+ {
+ if (str_size - len < (4 + ((range)?8:0)))
+ {
+ break;
+ }
+ len += snprintf(str_buf + len, str_size - len, "- %d ", prev_vlan_id);
+ }
len += snprintf(str_buf + len, str_size - len, "%d ", vlan_id->vid);
+ range = 0;
+ to_be_printed = 0;
+ }
+ else
+ {
+ range = 1;
+ to_be_printed = 1;
+ }
+ prev_vlan_id = vlan_id->vid;
+ }
+
+ if (to_be_printed && (str_size - len > (4 + ((range)?8:0))))
+ {
+ if (prev_vlan_id)
+ {
+ len += snprintf(str_buf + len, str_size - len, "%s%d ", range?"- ":"", prev_vlan_id);
+ range = 0;
}
}
@@ -449,6 +489,116 @@ int iccp_local_if_dump(char * *buf, int *num, int mclag_id)
return EXEC_TYPE_FAILED;
}
}
+
+ if (csm->peer_link_if) {
+
+ lif_peer = csm->peer_link_if;
+
+ memset(&mclagd_lif, 0, sizeof(struct mclagd_local_if));
+
+ mclagd_lif.ifindex = lif_peer->ifindex;
+
+ if (lif_peer->type == IF_T_UNKNOW)
+ memcpy(mclagd_lif.type, "Unknown", strlen("unknown"));
+ else if (lif_peer->type == IF_T_PORT)
+ memcpy(mclagd_lif.type, "Ethernet", strlen("Ethernet"));
+ else if (lif_peer->type == IF_T_PORT_CHANNEL)
+ memcpy(mclagd_lif.type, "PortChannel", 11);
+
+ memcpy(mclagd_lif.name, lif_peer->name, MAX_L_PORT_NAME);
+ memcpy(mclagd_lif.mac_addr, lif_peer->mac_addr, ETHER_ADDR_LEN);
+
+ if (lif_peer->state == PORT_STATE_UP)
+ memcpy(mclagd_lif.state, "Up", strlen("Up"));
+ else if (lif_peer->state == PORT_STATE_DOWN)
+ memcpy(mclagd_lif.state, "Down", strlen("Down"));
+ else if (lif_peer->state == PORT_STATE_ADMIN_DOWN)
+ memcpy(mclagd_lif.state, "Admin-down", strlen("Admin-down"));
+ else if (lif_peer->state == PORT_STATE_TEST)
+ memcpy(mclagd_lif.state, "Test", strlen("Test"));
+
+ memcpy(mclagd_lif.ipv4_addr, show_ip_str(lif_peer->ipv4_addr), 16);
+ mclagd_lif.prefixlen = lif_peer->prefixlen;
+
+ mclagd_lif.l3_mode = local_if_is_l3_mode(lif_peer);
+
+ mclagd_lif.is_peer_link = lif_peer->is_peer_link;
+
+ memcpy(mclagd_lif.portchannel_member_buf, lif_peer->portchannel_member_buf, 512);
+
+ mclagd_lif.po_id = lif_peer->po_id;
+ mclagd_lif.po_active = lif_peer->po_active;
+ /*mlacp_state*/
+ if (lif_peer->mlacp_state == MLACP_STATE_INIT)
+ memcpy(mclagd_lif.mlacp_state, "INIT", strlen("INIT"));
+ else if (lif_peer->mlacp_state == MLACP_STATE_STAGE1)
+ memcpy(mclagd_lif.mlacp_state, "STAGE1", strlen("STAGE1"));
+ else if (lif_peer->mlacp_state == MLACP_STATE_STAGE2)
+ memcpy(mclagd_lif.mlacp_state, "STAGE2", strlen("STAGE2"));
+ else if (lif_peer->mlacp_state == MLACP_STATE_EXCHANGE)
+ memcpy(mclagd_lif.mlacp_state, "EXCHANGE", strlen("EXCHANGE"));
+ else if (lif_peer->mlacp_state == MLACP_STATE_ERROR)
+ memcpy(mclagd_lif.mlacp_state, "ERROR", strlen("ERROR"));
+
+ mclagd_lif.isolate_to_peer_link = lif_peer->isolate_to_peer_link;
+ mclagd_lif.is_traffic_disable = lif_peer->is_traffic_disable;
+
+ str_buf = mclagd_lif.vlanlist;
+
+ len = 0;
+ int prev_vlan_id = 0;
+ int range = 0;
+ int to_be_printed = 0;
+
+ RB_FOREACH (vlan_id, vlan_rb_tree, &(lif_peer->vlan_tree))
+ {
+ if (str_size - len < 4)
+ break;
+ if (!prev_vlan_id || vlan_id->vid != prev_vlan_id + 1)
+ {
+ if (range)
+ {
+ if (str_size - len < (4 + ((range)?8:0)))
+ {
+ break;
+ }
+ len += snprintf(str_buf + len, str_size - len, "- %d ", prev_vlan_id);
+ }
+ len += snprintf(str_buf + len, str_size - len, "%d ", vlan_id->vid);
+ range = 0;
+ to_be_printed = 0;
+ }
+ else
+ {
+ range = 1;
+ to_be_printed = 1;
+ }
+ prev_vlan_id = vlan_id->vid;
+ }
+
+ if (to_be_printed && (str_size - len > (4 + ((range)?8:0))))
+ {
+ if (prev_vlan_id)
+ {
+ len += snprintf(str_buf + len, str_size - len, "%s%d ", range?"- ":"", prev_vlan_id);
+ range = 0;
+ }
+ }
+
+ memcpy(lif_buf + MCLAGD_REPLY_INFO_HDR + lif_num * sizeof(struct mclagd_local_if),
+ &mclagd_lif, sizeof(struct mclagd_local_if));
+
+ lif_num++;
+
+ if ((lif_num + 1) * sizeof(struct mclagd_local_if) > (lif_buf_size - MCLAGD_REPLY_INFO_HDR))
+ {
+ lif_buf_size += MCLAGDCTL_CMD_SIZE;
+ lif_buf = (char*)realloc(lif_buf, lif_buf_size);
+ if (!lif_buf)
+ return EXEC_TYPE_FAILED;
+ }
+
+ }
}
*buf = lif_buf;
@@ -473,6 +623,7 @@ int iccp_peer_if_dump(char * *buf, int *num, int mclag_id)
if (!(sys = system_get_instance()))
{
+ ICCPD_LOG_INFO(__FUNCTION__, "cannot find sys!\n");
return EXEC_TYPE_NO_EXIST_SYS;
}
@@ -542,3 +693,122 @@ int iccp_peer_if_dump(char * *buf, int *num, int mclag_id)
return EXEC_TYPE_SUCCESS;
}
+/* Allocate a buffer to return the internal debug counters
+ * The allocated buffer should include MCLAGD_REPLY_INFO_HDR byte header
+ * No buffer is allocated if error is returned
+ */
+int iccp_cmd_dbg_counter_dump(char **buf, int *data_len, int mclag_id)
+{
+ struct System *sys = NULL;
+ struct CSM *csm = NULL;
+ char *temp_ptr, *counter_buf = NULL;
+ mclagd_dbg_counter_info_t *counter_ptr;
+ int buf_size = 0;
+ int id_exist = 0;
+ int num_csm = 0;
+ bool is_first_csm;
+
+ if (!(sys = system_get_instance()))
+ {
+ ICCPD_LOG_INFO(__FUNCTION__, "cannot find sys!\n");
+ return EXEC_TYPE_NO_EXIST_SYS;
+ }
+ if (mclag_id >0)
+ num_csm = 1;
+ else
+ {
+ LIST_FOREACH(csm, &(sys->csm_list), next)
+ {
+ ++num_csm;
+ }
+ }
+ buf_size = MCLAGD_REPLY_INFO_HDR + sizeof(mclagd_dbg_counter_info_t) +
+ (sizeof(mlacp_dbg_counter_info_t) * num_csm);
+ counter_buf = (char*)malloc(buf_size);
+ if (!counter_buf)
+ return EXEC_TYPE_FAILED;
+
+ memset(counter_buf, 0, buf_size);
+ counter_ptr =
+ (mclagd_dbg_counter_info_t *)(counter_buf + MCLAGD_REPLY_INFO_HDR);
+ memcpy(&counter_ptr->system_dbg, &sys->dbg_counters, sizeof(sys->dbg_counters));
+ counter_ptr->num_iccp_counter_blocks = num_csm;
+ temp_ptr = counter_ptr->iccp_dbg_counters;
+ is_first_csm = true;
+
+ LIST_FOREACH(csm, &(sys->csm_list), next)
+ {
+ if (mclag_id >0)
+ {
+ if (csm->mlag_id == mclag_id)
+ id_exist = 1;
+ else
+ continue;
+ }
+ if (is_first_csm)
+ is_first_csm = false;
+ else
+ temp_ptr += sizeof(MLACP(csm).dbg_counters);
+
+ memcpy(temp_ptr, &MLACP(csm).dbg_counters,
+ sizeof(MLACP(csm).dbg_counters));
+ }
+
+ if (mclag_id >0 && !id_exist)
+ {
+ if (counter_buf)
+ free(counter_buf);
+ return EXEC_TYPE_NO_EXIST_MCLAGID;
+ }
+ *buf = counter_buf;
+ *data_len = buf_size - MCLAGD_REPLY_INFO_HDR;
+ return EXEC_TYPE_SUCCESS;
+}
+
+int iccp_unique_ip_if_dump(char **buf, int *num, int mclag_id)
+{
+ struct System *sys = NULL;
+ struct mclagd_unique_ip_if mclagd_lif;
+ char *str_buf = NULL;
+ int str_size = MCLAGDCTL_PARA3_LEN - 1;
+ int len = 0;
+ int lif_num = 0;
+ int lif_buf_size = MCLAGDCTL_CMD_SIZE;
+ char *lif_buf = NULL;
+ struct Unq_ip_If_info* unq_ip_if = NULL;
+
+ if (!(sys = system_get_instance()))
+ {
+ ICCPD_LOG_INFO(__FUNCTION__, "cannot find sys!\n");
+ return EXEC_TYPE_NO_EXIST_SYS;
+ }
+
+ lif_buf = (char*)malloc(lif_buf_size);
+ if (!lif_buf)
+ return EXEC_TYPE_FAILED;
+
+ LIST_FOREACH(unq_ip_if, &(sys->unq_ip_if_list), if_next)
+ {
+ memset(&mclagd_lif, 0, sizeof(struct mclagd_unique_ip_if));
+ memcpy(mclagd_lif.name, unq_ip_if->name, MAX_L_PORT_NAME);
+ mclagd_lif.active = local_if_l3_proto_enabled(unq_ip_if->name);
+
+ memcpy(lif_buf + MCLAGD_REPLY_INFO_HDR + lif_num * sizeof(struct mclagd_unique_ip_if),
+ &mclagd_lif, sizeof(struct mclagd_unique_ip_if));
+
+ lif_num++;
+
+ if ((lif_num + 1) * sizeof(struct mclagd_unique_ip_if) > (lif_buf_size - MCLAGD_REPLY_INFO_HDR))
+ {
+ lif_buf_size += MCLAGDCTL_CMD_SIZE;
+ lif_buf = (char*)realloc(lif_buf, lif_buf_size);
+ if (!lif_buf)
+ return EXEC_TYPE_FAILED;
+ }
+ }
+
+ *buf = lif_buf;
+ *num = lif_num;
+
+ return EXEC_TYPE_SUCCESS;
+}
diff --git a/src/iccpd/src/iccp_consistency_check.c b/src/iccpd/src/iccp_consistency_check.c
index 90ac9cd9e790..6898b366f2bc 100644
--- a/src/iccpd/src/iccp_consistency_check.c
+++ b/src/iccpd/src/iccp_consistency_check.c
@@ -112,13 +112,9 @@ static int iccp_check_interface_vlan(char* ifname)
if (peer_if == NULL)
return -4;
- LIST_FOREACH(local_vlan, &(local_if->vlan_list), port_next)
+ RB_FOREACH (local_vlan, vlan_rb_tree, &(local_if->vlan_tree))
{
- LIST_FOREACH(peer_vlan, &(peer_if->vlan_list), port_next)
- {
- if (peer_vlan->vid == local_vlan->vid)
- break;
- }
+ peer_vlan = RB_FIND(vlan_rb_tree, &(peer_if->vlan_tree), local_vlan);
if (peer_vlan == NULL)
{
@@ -126,14 +122,9 @@ static int iccp_check_interface_vlan(char* ifname)
}
}
- LIST_FOREACH(peer_vlan, &(peer_if->vlan_list), port_next)
+ RB_FOREACH (peer_vlan, vlan_rb_tree, &(peer_if->vlan_tree))
{
-
- LIST_FOREACH(local_vlan, &(local_if->vlan_list), port_next)
- {
- if (peer_vlan->vid == local_vlan->vid)
- break;
- }
+ local_vlan = RB_FIND(vlan_rb_tree, &(local_if->vlan_tree), peer_vlan);
if (local_vlan == NULL)
{
diff --git a/src/iccpd/src/iccp_csm.c b/src/iccpd/src/iccp_csm.c
index 79e17b9e1ba2..1560b41f3d81 100644
--- a/src/iccpd/src/iccp_csm.c
+++ b/src/iccpd/src/iccp_csm.c
@@ -20,7 +20,7 @@
*
* Maintainer: jianjun, grace Li from nephos
*/
-
+#include
#include
#include
@@ -29,6 +29,7 @@
#include "../include/scheduler.h"
#include "../include/msg_format.h"
#include "../include/iccp_csm.h"
+#include "../include/iccp_cli.h"
#include "../include/mlacp_link_handler.h"
/*****************************************
* Define
@@ -121,6 +122,8 @@ void iccp_csm_init(struct CSM* csm)
memset(csm->peer_ip, 0, INET_ADDRSTRLEN);
memset(csm->iccp_info.sender_name, 0, MAX_L_ICC_SENDER_NAME);
csm->iccp_info.icc_rg_id = 0x0;
+ csm->keepalive_time = CONNECT_INTERVAL_SEC;
+ csm->session_timeout = HEARTBEAT_TIMEOUT_SEC;
}
/* Connection State Machine instance status reset */
@@ -141,6 +144,8 @@ void iccp_csm_status_reset(struct CSM* csm, int all)
csm->heartbeat_update_time = 0;
csm->peer_warm_reboot_time = 0;
csm->warm_reboot_disconn_time = 0;
+ csm->peer_link_learning_retry_time = 0;
+ csm->peer_link_learning_enable = 0;
csm->role_type = STP_ROLE_NONE;
csm->sock_read_event_ptr = NULL;
csm->peer_link_if = NULL;
@@ -165,6 +170,9 @@ void iccp_csm_finalize(struct CSM* csm)
{
struct If_info * cif = NULL;
struct System* sys = NULL;
+ struct LocalInterface* lifp = NULL;
+ struct LocalInterface* local_if = NULL;
+ struct LocalInterface* local_if_next = NULL;
if (csm == NULL)
return;
@@ -176,21 +184,40 @@ void iccp_csm_finalize(struct CSM* csm)
if (sys->warmboot_exit != WARM_REBOOT)
{
/*Enable peer link port MAC learning*/
- if (csm->peer_link_if)
+ if (csm->peer_link_if) {
set_peerlink_mlag_port_learn(csm->peer_link_if, 1);
+ set_peerlink_learn_kernel(csm, 1, 1);
+ }
}
/* Disconnect from peer */
scheduler_session_disconnect_handler(csm);
+ //Delete all MCLAG interfaces
+ local_if = LIST_FIRST(&(MLACP(csm).lif_list));
+ while (local_if != NULL)
+ {
+ local_if_next = LIST_NEXT(local_if,mlacp_next);
+ iccp_cli_detach_mclag_domain_to_port_channel(local_if->name);
+ local_if = local_if_next;
+ }
+
/* Release all Connection State Machine instance */
app_csm_finalize(csm);
- LIST_FOREACH(cif, &(csm->if_bind_list), csm_next)
+ LIST_FOREACH(lifp, &(MLACP(csm).lif_list), mlacp_next)
{
- LIST_REMOVE(cif, csm_next);
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Resetting CSM pointer for %s", lifp->name);
+ lifp->csm = NULL;
}
+ while (!LIST_EMPTY(&(csm->if_bind_list)))
+ {
+ cif = LIST_FIRST(&(csm->if_bind_list));
+ LIST_REMOVE(cif,csm_next);
+ free(cif);
+ }
+
/* Release iccp_csm */
pthread_mutex_destroy(&(csm->conn_mutex));
iccp_csm_msg_list_finalize(csm);
@@ -219,6 +246,8 @@ int iccp_csm_send(struct CSM* csm, char* buf, int msg_len)
{
LDPHdr* ldp_hdr = (LDPHdr*)buf;
ICCParameter* param = NULL;
+ ssize_t rc;
+ uint16_t tlv_type;
if (csm == NULL || buf == NULL || csm->sock_fd <= 0 || msg_len <= 0)
return MCLAG_ERROR;
@@ -228,7 +257,7 @@ int iccp_csm_send(struct CSM* csm, char* buf, int msg_len)
else
param = (struct ICCParameter*)&buf[sizeof(ICCHdr)];
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "Send(%d): len=[%d] msg_type=[%s (0x%X, 0x%X)]", csm->sock_fd, msg_len, get_tlv_type_string(param->type), ldp_hdr->msg_type, param->type);*/
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Send(%d): len=[%d] msg_type=[%s (0x%X, 0x%X)]", csm->sock_fd, msg_len, get_tlv_type_string(ntohs(param->type)), ldp_hdr->msg_type, ntohs(param->type));
csm->msg_log.msg[csm->msg_log.end_index].msg_id = ntohl(ldp_hdr->msg_id);
csm->msg_log.msg[csm->msg_log.end_index].type = ntohs(ldp_hdr->msg_type);
csm->msg_log.msg[csm->msg_log.end_index].tlv = ntohs(param->type);
@@ -236,7 +265,20 @@ int iccp_csm_send(struct CSM* csm, char* buf, int msg_len)
if (csm->msg_log.end_index >= 128)
csm->msg_log.end_index = 0;
- return write(csm->sock_fd, buf, msg_len);
+ tlv_type = ntohs(param->type);
+ rc = write(csm->sock_fd, buf, msg_len);
+ if ((rc <= 0) || (rc != msg_len))
+ {
+ MLACP_SET_ICCP_TX_DBG_COUNTER(
+ csm, tlv_type, ICCP_DBG_CNTR_STS_ERR);
+ ICCPD_LOG_ERR("ICCP_FSM", "Failed to write msg %s/0x%x, msg_len:%d, rc %d Error:%s ", get_tlv_type_string(tlv_type), tlv_type, msg_len, rc, strerror(errno));
+ }
+ else
+ {
+ MLACP_SET_ICCP_TX_DBG_COUNTER(
+ csm, tlv_type, ICCP_DBG_CNTR_STS_OK);
+ }
+ return (rc);
}
/* Connection State Machine Transition */
@@ -776,8 +818,34 @@ int iccp_csm_init_msg(struct Msg** msg, char* data, int len)
return MCLAG_ERROR;
}
+/* MAC Message initialization */
+int iccp_csm_init_mac_msg(struct MACMsg **mac_msg, char* data, int len)
+{
+ struct MACMsg* iccp_mac_msg = NULL;
+
+ if (mac_msg == NULL)
+ return -2;
+
+ if (data == NULL || len <= 0)
+ return MCLAG_ERROR;
+
+ iccp_mac_msg = (struct MACMsg*)malloc(sizeof(struct MACMsg));
+ if (iccp_mac_msg == NULL)
+ return -3;
+
+ memset(iccp_mac_msg, 0, sizeof(struct MACMsg));
+ memcpy(iccp_mac_msg, data, len);
+
+ *mac_msg = iccp_mac_msg;
+
+ return 0;
+}
+
+
void iccp_csm_stp_role_count(struct CSM *csm)
{
+ struct If_info * cif = NULL;
+
/* decide the role, lower ip to be active & socket client*/
if (csm->role_type == STP_ROLE_NONE)
{
@@ -786,12 +854,18 @@ void iccp_csm_stp_role_count(struct CSM *csm)
/* Active*/
ICCPD_LOG_INFO(__FUNCTION__, "Role: [Active]");
csm->role_type = STP_ROLE_ACTIVE;
+ /* Send ICCP role update and system ID */
+ mlacp_link_set_iccp_role(csm->mlag_id, true, MLACP(csm).system_id);
}
else
{
/* Standby*/
ICCPD_LOG_INFO(__FUNCTION__, "Role [Standby]");
csm->role_type = STP_ROLE_STANDBY;
+ /* Send ICCP role update */
+ mlacp_link_set_iccp_role(csm->mlag_id, false, NULL);
+ /*Set Bridge MAC to MY MAC*/
+ mlacp_fix_bridge_mac(csm);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/iccpd/src/iccp_ifm.c b/src/iccpd/src/iccp_ifm.c
index 258c661e03a4..4349599f5308 100644
--- a/src/iccpd/src/iccp_ifm.c
+++ b/src/iccpd/src/iccp_ifm.c
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -99,9 +100,12 @@ int iccp_sys_local_if_list_get_init()
nl_cb_put(cb);
if (ret < 0)
{
- ICCPD_LOG_ERR(__FUNCTION__, "receive netlink msg error. ret = %d errno = %d ", ret, errno);
if (ret != -NLE_DUMP_INTR)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "No retry, receive netlink msg error. ret = %d errno = %d ", ret, errno);
return ret;
+ }
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Retry: receive netlink msg error. ret = %d errno = %d ", ret, errno);
retry = 1;
}
}
@@ -109,7 +113,7 @@ int iccp_sys_local_if_list_get_init()
return ret;
}
-static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int msgtype)
+static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int msgtype, int is_del)
{
struct System *sys = NULL;
struct CSM *csm = NULL;
@@ -117,6 +121,12 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int
struct ARPMsg *arp_msg = NULL, *arp_info = NULL;
struct VLAN_ID *vlan_id_list = NULL;
struct Msg *msg_send = NULL;
+ uint16_t vid = 0;
+ int entry_exists = 0;
+ struct LocalInterface *peer_link_if = NULL;
+ int ln = 0;
+ uint16_t vlan_id = 0;
+ struct VLAN_ID vlan_key = { 0 };
char buf[MAX_BUFSIZE];
size_t msg_len = 0;
@@ -136,12 +146,12 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int
/* create ARP msg*/
memset(buf, 0, MAX_BUFSIZE);
msg_len = sizeof(struct ARPMsg);
- arp_msg = (struct ARPMsg*)&buf;
+ arp_msg = (struct ARPMsg *)&buf;
arp_msg->op_type = NEIGH_SYNC_LIF;
sprintf(arp_msg->ifname, "%s", arp_lif->name);
if (tb[NDA_DST])
memcpy(&arp_msg->ipv4_addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST]));
- if (tb[NDA_LLADDR])
+ if (!is_del && tb[NDA_LLADDR])
memcpy(arp_msg->mac_addr, RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR]));
arp_msg->ipv4_addr = arp_msg->ipv4_addr;
@@ -153,36 +163,72 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int
arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4],
arp_msg->mac_addr[5]);
+ if (msgtype != RTM_DELNEIGH) {
+ if (arp_lif->ipv4_addr == 0) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "IP not configured on %s, ignore ARP", arp_lif->name);
+ return;
+ }
+ }
+
+ uint8_t bcast_mac[ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ if (memcmp(arp_msg->mac_addr, bcast_mac, ETHER_ADDR_LEN) == 0)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Ignoring neighbor entry due to bcast lladdr");
+ msgtype = RTM_DELNEIGH;
+ }
+
+ if ((strncmp(arp_msg->ifname, VLAN_PREFIX, strlen(VLAN_PREFIX)) == 0)) {
+ sscanf (arp_msg->ifname, "Vlan%hu", &vlan_id);
+ }
+
+ if (vlan_id) {
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vlan_id;
+ }
+
/* Find MLACP itf, member of port-channel*/
LIST_FOREACH(csm, &(sys->csm_list), next)
{
+ vid = 0;
+ ln = __LINE__;
LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next)
{
- if (lif_po->type != IF_T_PORT_CHANNEL)
+ if (lif_po->type != IF_T_PORT_CHANNEL) {
+ ln = __LINE__;
continue;
+ }
if (!local_if_is_l3_mode(lif_po))
{
+ vid = 0;
/* Is the L2 MLAG itf belong to a vlan?*/
- LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next)
- {
- if ( !(vlan_id_list->vlan_itf
- && vlan_id_list->vlan_itf->ifindex == ndm->ndm_ifindex))
- continue;
- break;
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(lif_po->vlan_tree), &vlan_key);
+
+ if (!vlan_id_list) {
+ ln = __LINE__;
+ continue;
+ }
+
+ if (!vlan_id_list->vlan_itf) {
+ ln = __LINE__;
+ continue;
}
- if (!vlan_id_list)
+ if (vlan_id_list->vlan_itf->ifindex != ndm->ndm_ifindex) {
+ ln = __LINE__;
continue;
+ }
- ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled member port of vlan %s",
- vlan_id_list->vlan_itf->name);
+ vid = vlan_id_list->vid;
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled member port of vlan %d", vid);
}
else
{
/* Is the ARP belong to a L3 mode MLAG itf?*/
- if (ndm->ndm_ifindex != lif_po->ifindex)
+ if (ndm->ndm_ifindex != lif_po->ifindex) {
+ ln = __LINE__;
continue;
+ }
ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled intf %s", lif_po->name);
}
@@ -192,22 +238,53 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int
break;
}
- if (lif_po)
+ if (lif_po) {
break;
+ } else if (csm->peer_link_if){
+ peer_link_if = csm->peer_link_if;
+ if (!local_if_is_l3_mode(peer_link_if)) {
+ vid = 0;
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(peer_link_if->vlan_tree), &vlan_key);
+
+ if (vlan_id_list && vlan_id_list->vlan_itf) {
+ if (vlan_id_list->vlan_itf->ifindex == ndm->ndm_ifindex) {
+ vid = vlan_id_list->vid;
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from peer link vlan %d", vid);
+ verify_arp = 1;
+ lif_po = peer_link_if;
+ break;
+ }
+ }
+ }
+ }
}
- if (!(csm && lif_po))
+ if (!(csm && lif_po)) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP received no PO ln %d", ln);
return;
- if (!verify_arp)
+ }
+ if (!verify_arp) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP received no verify_arp ln %d", ln);
return;
+ }
+
+ if (vid != 0) {
+ if (vid && vlan_id_list && vlan_id_list->vlan_itf) {
+ if (arp_msg->ipv4_addr == vlan_id_list->vlan_itf->ipv4_addr) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Ignore My ip %s", show_ip_str(arp_msg->ipv4_addr));
+ return;
+ }
+ }
+ }
/* update lif ARP*/
TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail)
{
- arp_info = (struct ARPMsg*)msg->buf;
+ arp_info = (struct ARPMsg *)msg->buf;
if (arp_info->ipv4_addr != arp_msg->ipv4_addr)
continue;
+ entry_exists = 1;
if (msgtype == RTM_DELNEIGH)
{
/* delete ARP*/
@@ -222,8 +299,7 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int
/* update ARP*/
if (arp_info->op_type != arp_msg->op_type
|| strcmp(arp_info->ifname, arp_msg->ifname) != 0
- || memcmp(arp_info->mac_addr, arp_msg->mac_addr,
- ETHER_ADDR_LEN) != 0)
+ || memcmp(arp_info->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN) != 0)
{
arp_update = 1;
arp_info->op_type = arp_msg->op_type;
@@ -244,11 +320,12 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int
if (!msg)
{
arp_msg->op_type = NEIGH_SYNC_LIF;
- if (iccp_csm_init_msg(&msg, (char*)arp_msg, msg_len) == 0)
+ arp_msg->learn_flag = NEIGH_LOCAL;
+ if (iccp_csm_init_msg(&msg, (char *)arp_msg, msg_len) == 0)
{
mlacp_enqueue_arp(csm, msg);
/*ICCPD_LOG_DEBUG(__FUNCTION__, "ARP-list enqueue: %s, add %s",
- arp_msg->ifname, show_ip_str(arp_msg->ipv4_addr));*/
+ arp_msg->ifname, show_ip_str((arp_msg->ipv4_addr));*/
}
else
ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP-list: %s, add %s",
@@ -259,7 +336,8 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int
if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
{
arp_msg->op_type = NEIGH_SYNC_ADD;
- if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0)
+ arp_msg->flag = 0;
+ if (iccp_csm_init_msg(&msg_send, (char *)arp_msg, msg_len) == 0)
{
TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail);
/*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[ADD] message for %s",
@@ -268,16 +346,16 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int
else
ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] message for %s",
show_ip_str(arp_msg->ipv4_addr));
-
}
}
else
{
/* enqueue iccp_msg (delete)*/
- if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
+ if ((MLACP(csm).current_state == MLACP_STATE_EXCHANGE) && entry_exists)
{
arp_msg->op_type = NEIGH_SYNC_DEL;
- if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0)
+ arp_msg->flag = 0;
+ if (iccp_csm_init_msg(&msg_send, (char *)arp_msg, msg_len) == 0)
{
TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail);
/*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ARP[DEL] message for %s",
@@ -286,14 +364,16 @@ static void do_arp_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int
else
ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[DEL] message for %s",
show_ip_str(arp_msg->ipv4_addr));
-
+ } else {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP[DEL] message for %s skipped. entry_exists %d",
+ show_ip_str(arp_msg->ipv4_addr), entry_exists);
}
}
return;
}
-static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int msgtype)
+static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], int msgtype, int is_del)
{
struct System *sys = NULL;
struct CSM *csm = NULL;
@@ -301,11 +381,19 @@ static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], i
struct NDISCMsg *ndisc_msg = NULL, *ndisc_info = NULL;
struct VLAN_ID *vlan_id_list = NULL;
struct Msg *msg_send = NULL;
+ uint16_t vid = 0;
+ int entry_exists = 0;
+ int is_link_local = 0;
+ int ln = 0;
+ uint16_t vlan_id = 0;
+ struct VLAN_ID vlan_key = { 0 };
char buf[MAX_BUFSIZE];
size_t msg_len = 0;
+ char addr_null[16] = { 0 };
struct LocalInterface *lif_po = NULL, *ndisc_lif = NULL;
+ struct LocalInterface *peer_link_if = NULL;
int verify_neigh = 0;
int neigh_update = 0;
@@ -325,7 +413,7 @@ static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], i
sprintf(ndisc_msg->ifname, "%s", ndisc_lif->name);
if (tb[NDA_DST])
memcpy(&ndisc_msg->ipv6_addr, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST]));
- if (tb[NDA_LLADDR])
+ if (!is_del && tb[NDA_LLADDR])
memcpy(ndisc_msg->mac_addr, RTA_DATA(tb[NDA_LLADDR]), RTA_PAYLOAD(tb[NDA_LLADDR]));
ICCPD_LOG_NOTICE(__FUNCTION__, "ndisc type %s, state (%04X)(%d), ifindex [%d] (%s), ip %s, mac [%02X:%02X:%02X:%02X:%02X:%02X]",
@@ -335,36 +423,75 @@ static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], i
ndisc_msg->mac_addr[0], ndisc_msg->mac_addr[1], ndisc_msg->mac_addr[2], ndisc_msg->mac_addr[3], ndisc_msg->mac_addr[4],
ndisc_msg->mac_addr[5]);
+
+ if (msgtype != RTM_DELNEIGH) {
+ if (memcmp(ndisc_lif->ipv6_addr, addr_null, 16) == 0) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "IPv6 address not configured on %s, ignore ND", ndisc_lif->name);
+ return;
+ }
+ }
+
+ uint8_t bcast_mac[ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ if (memcmp(ndisc_msg->mac_addr, bcast_mac, ETHER_ADDR_LEN) == 0)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Ignoring neighbor entry due to bcast lladdr");
+ msgtype = RTM_DELNEIGH;
+ return;
+ }
+
+ if ((strncmp(ndisc_msg->ifname, VLAN_PREFIX, strlen(VLAN_PREFIX)) == 0)) {
+ sscanf (ndisc_msg->ifname, "Vlan%hu", &vlan_id);
+ }
+
+ if (vlan_id) {
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vlan_id;
+ }
/* Find MLACP itf, member of port-channel */
LIST_FOREACH(csm, &(sys->csm_list), next)
{
+ vid = 0;
+ ln = __LINE__;
LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next)
{
- if (lif_po->type != IF_T_PORT_CHANNEL)
+ if (lif_po->type != IF_T_PORT_CHANNEL) {
+ ln = __LINE__;
continue;
+ }
+ vid = 0;
if (!local_if_is_l3_mode(lif_po))
{
- /* Is the L2 MLAG itf belong to a vlan? */
- LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next)
- {
- if (!(vlan_id_list->vlan_itf && vlan_id_list->vlan_itf->ifindex == ndm->ndm_ifindex))
- continue;
- break;
+ /* Is the L2 MLAG itf belong to a vlan?*/
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(lif_po->vlan_tree), &vlan_key);
+
+ if (!vlan_id_list) {
+ ln = __LINE__;
+ continue;
}
- if (!vlan_id_list)
+ if (!vlan_id_list->vlan_itf) {
+ ln = __LINE__;
continue;
+ }
- ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled member port of vlan %s", vlan_id_list->vlan_itf->name);
+ if (vlan_id_list->vlan_itf->ifindex != ndm->ndm_ifindex) {
+ ln = __LINE__;
+ continue;
+ }
+
+ vid = vlan_id_list->vid;
+ ICCPD_LOG_DEBUG(__FUNCTION__, "neighor is from intf %s of vlan %d", lif_po->name, vid);
}
else
{
/* Is the ND belong to a L3 mode MLAG itf? */
- if (ndm->ndm_ifindex != lif_po->ifindex)
+ if (ndm->ndm_ifindex != lif_po->ifindex) {
+ ln = __LINE__;
continue;
+ }
- ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled intf %s", lif_po->name);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "neighbor is from intf %s", lif_po->name);
}
verify_neigh = 1;
@@ -372,14 +499,58 @@ static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], i
break;
}
- if (lif_po)
+ if (lif_po) {
break;
+ } else if (csm->peer_link_if){
+ peer_link_if = csm->peer_link_if;
+ if (!local_if_is_l3_mode(peer_link_if)) {
+ vid = 0;
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(peer_link_if->vlan_tree), &vlan_key);
+
+ if (vlan_id_list && vlan_id_list->vlan_itf) {
+ if (vlan_id_list->vlan_itf->ifindex == ndm->ndm_ifindex) {
+ vid = vlan_id_list->vid;
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from peer link vlan %d", vid);
+ verify_neigh = 1;
+ lif_po = peer_link_if;
+ break;
+ }
+ }
+ }
+ }
}
- if (!(csm && lif_po))
+ if (!(csm && lif_po)) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ND received no PO ln %d", ln);
return;
- if (!verify_neigh)
+ }
+ if (!verify_neigh) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ND received no verify_ndisc ln %d", ln);
return;
+ }
+
+ if ((memcmp(show_ipv6_str((char *)ndisc_msg->ipv6_addr), "FE80", 4) == 0)
+ || (memcmp(show_ipv6_str((char *)ndisc_msg->ipv6_addr), "fe80", 4) == 0))
+ {
+ is_link_local = 1;
+ }
+
+ if (vid && vlan_id_list && vlan_id_list->vlan_itf) {
+ if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)vlan_id_list->vlan_itf->ipv6_addr, 16) == 0)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Ignoring neighbor entry for My Ip %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
+ return;
+ }
+
+ if (is_link_local)
+ {
+ if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)vlan_id_list->vlan_itf->ipv6_ll_addr, 16) == 0)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Ignoring neighbor entry for My Ip %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
+ return;
+ }
+ }
+ }
/* update lif ND */
TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail)
@@ -389,6 +560,7 @@ static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], i
if (memcmp(&ndisc_info->ipv6_addr, &ndisc_msg->ipv6_addr, 16) != 0)
continue;
+ entry_exists = 1;
if (msgtype == RTM_DELNEIGH)
{
/* delete ND */
@@ -402,8 +574,7 @@ static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], i
{
/* update ND */
if (ndisc_info->op_type != ndisc_info->op_type
- || strcmp(ndisc_info->ifname, ndisc_info->ifname) != 0
- || memcmp(ndisc_info->mac_addr, ndisc_info->mac_addr, ETHER_ADDR_LEN) != 0)
+ || strcmp(ndisc_info->ifname, ndisc_info->ifname) != 0 || memcmp(ndisc_info->mac_addr, ndisc_info->mac_addr, ETHER_ADDR_LEN) != 0)
{
neigh_update = 1;
ndisc_info->op_type = ndisc_msg->op_type;
@@ -424,6 +595,7 @@ static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], i
if (!msg)
{
ndisc_msg->op_type = NEIGH_SYNC_LIF;
+ ndisc_msg->learn_flag = NEIGH_LOCAL;
if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, msg_len) == 0)
{
mlacp_enqueue_ndisc(csm, msg);
@@ -438,6 +610,7 @@ static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], i
if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
{
ndisc_msg->op_type = NEIGH_SYNC_ADD;
+ ndisc_msg->flag = 0;
if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0)
{
TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail);
@@ -445,23 +618,26 @@ static void do_ndisc_learn_from_kernel(struct ndmsg *ndm, struct rtattr *tb[], i
}
else
ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc[ADD] message for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
-
}
}
else
{
/* enqueue iccp_msg (delete) */
- if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
+ /* send delete notification, only if entry is present in DB*/
+ if ((MLACP(csm).current_state == MLACP_STATE_EXCHANGE) && entry_exists)
{
ndisc_msg->op_type = NEIGH_SYNC_DEL;
+ ndisc_msg->flag = 0;
if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0)
{
TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail);
/* ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue Ndisc[DEL] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr)); */
}
else
- ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc[DEL] message for [%x:%x:%x:%x]", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
-
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue Ndisc[DEL] message for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
+ } else {
+ ICCPD_LOG_DEBUG(__FUNCTION__, " Ndisc[DEL] message for %s skipped. entry_exists %d",
+ show_ipv6_str((char *)ndisc_msg->ipv6_addr), entry_exists);
}
}
@@ -502,7 +678,10 @@ int do_one_neigh_request(struct nlmsghdr *n)
{
struct ndmsg *ndm = NLMSG_DATA(n);
int len = n->nlmsg_len;
- struct rtattr *tb[NDA_MAX + 1] = {0};
+ struct rtattr *tb[NDA_MAX + 1] = {{0}};
+ int is_del = 0;
+ int msgtype = n->nlmsg_type;
+ struct CSM* csm = NULL;
if (n->nlmsg_type == NLMSG_DONE)
{
@@ -513,20 +692,33 @@ int do_one_neigh_request(struct nlmsghdr *n)
if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH )
return(0);
+ /*Check if mclag configured*/
+ csm = system_get_first_csm();
+ if (!csm)
+ return(0);
+
len -= NLMSG_LENGTH(sizeof(*ndm));
if (len < 0)
return MCLAG_ERROR;
ifm_parse_rtattr(tb, NDA_MAX, NDA_RTA(ndm), len);
- if (n->nlmsg_type == RTM_NEWNEIGH
- && (ndm->ndm_state == NUD_INCOMPLETE
+ if (ndm->ndm_state == NUD_INCOMPLETE
|| ndm->ndm_state == NUD_FAILED
|| ndm->ndm_state == NUD_NOARP
|| ndm->ndm_state == NUD_PERMANENT
- || ndm->ndm_state == NUD_NONE))
+ || ndm->ndm_state == NUD_NONE)
{
- return(0);
+ if ((ndm->ndm_state == NUD_FAILED)
+ || (ndm->ndm_state == NUD_INCOMPLETE))
+ {
+ is_del = 1;
+ msgtype = RTM_DELNEIGH;
+ }
+
+ if (!is_del) {
+ return(0);
+ }
}
if (!tb[NDA_DST] || ndm->ndm_type != RTN_UNICAST)
@@ -536,16 +728,18 @@ int do_one_neigh_request(struct nlmsghdr *n)
if (ndm->ndm_family == AF_INET)
{
- do_arp_learn_from_kernel(ndm, tb, n->nlmsg_type);
+ do_arp_learn_from_kernel(ndm, tb, msgtype, is_del);
}
if (ndm->ndm_family == AF_INET6)
{
- do_ndisc_learn_from_kernel(ndm, tb, n->nlmsg_type);
+ do_ndisc_learn_from_kernel(ndm, tb, msgtype, is_del);
}
- return(0);
+
+ return (0);
}
+/*Handle arp received from kernel*/
static int iccp_neigh_valid_handler(struct nl_msg *msg, void *arg)
{
struct nlmsghdr *nlh = nlmsg_hdr(msg);
@@ -615,6 +809,11 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui
struct ARPMsg *arp_msg = NULL, *arp_info = NULL;
struct VLAN_ID *vlan_id_list = NULL;
struct Msg *msg_send = NULL;
+ uint16_t vid = 0;
+ struct LocalInterface *peer_link_if = NULL;
+ int ln = 0;
+ uint16_t vlan_id = 0;
+ struct VLAN_ID vlan_key = { 0 };
char buf[MAX_BUFSIZE];
size_t msg_len = 0;
@@ -645,35 +844,70 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui
arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4],
arp_msg->mac_addr[5]);
+ if (arp_lif->ipv4_addr == 0) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "IP not configured on %s, ignore ARP", arp_lif->name);
+ return;
+ }
+
+ uint8_t bcast_mac[ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ if (memcmp(arp_msg->mac_addr, bcast_mac, ETHER_ADDR_LEN) == 0)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Ignoring neighbor entry due to bcast lladdr");
+ return;
+ }
+
+ if ((strncmp(arp_lif->name, VLAN_PREFIX, strlen(VLAN_PREFIX)) == 0)) {
+ sscanf (arp_lif->name, "Vlan%hu", &vlan_id);
+ }
+
+ if (vlan_id) {
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vlan_id;
+ }
/* Find MLACP itf, member of port-channel*/
LIST_FOREACH(csm, &(sys->csm_list), next)
{
+ vid = 0;
+ ln = __LINE__;
LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next)
{
- if (lif_po->type != IF_T_PORT_CHANNEL)
+ if (lif_po->type != IF_T_PORT_CHANNEL) {
+ ln = __LINE__;
continue;
+ }
+ vid = 0;
if (!local_if_is_l3_mode(lif_po))
{
/* Is the L2 MLAG itf belong to a vlan?*/
- LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next)
- {
- if ( !(vlan_id_list->vlan_itf
- && vlan_id_list->vlan_itf->ifindex == ifindex))
- continue;
- break;
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(lif_po->vlan_tree), &vlan_key);
+
+ if (!vlan_id_list) {
+ ln = __LINE__;
+ continue;
+ }
+
+ if (!vlan_id_list->vlan_itf) {
+ ln = __LINE__;
+ continue;
}
- if (!vlan_id_list)
+ if (vlan_id_list->vlan_itf->ifindex != ifindex) {
+ ln = __LINE__;
continue;
- ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled port %s of vlan %s",
- lif_po->name, vlan_id_list->vlan_itf->name);
+ }
+
+ vid = vlan_id_list->vid;
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled port %s of vlan %d",
+ lif_po->name, vid);
}
else
{
/* Is the ARP belong to a L3 mode MLAG itf?*/
- if (ifindex != lif_po->ifindex)
+ if (ifindex != lif_po->ifindex) {
+ ln = __LINE__;
continue;
+ }
ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from mclag enabled intf %s", lif_po->name);
}
@@ -682,20 +916,50 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui
break;
}
- if (lif_po)
+ if (lif_po) {
break;
+ } else if (csm->peer_link_if){
+ peer_link_if = csm->peer_link_if;
+ if (!local_if_is_l3_mode(peer_link_if)) {
+ vid = 0;
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(peer_link_if->vlan_tree), &vlan_key);
+
+ if (vlan_id_list && vlan_id_list->vlan_itf) {
+ if (vlan_id_list->vlan_itf->ifindex == ifindex) {
+ vid = vlan_id_list->vid;
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is from peer link vlan %d", vid);
+ verify_arp = 1;
+ lif_po = peer_link_if;
+ break;
+ }
+ }
+ }
+ }
}
- if (!(csm && lif_po))
+ if (!(csm && lif_po)) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP received no PO ln %d", ln);
return;
- if (!verify_arp)
+ }
+ if (!verify_arp) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP received no verify_arp ln %d", ln);
return;
+ }
- if (iccp_check_if_addr_from_netlink(AF_INET, (uint8_t *)&addr, arp_lif))
- {
- ICCPD_LOG_DEBUG(__FUNCTION__, "ARP %s is identical with the ip address of interface %s",
- show_ip_str(arp_msg->ipv4_addr), arp_lif->name);
- return;
+ if (vid == 0) {
+ if (iccp_check_if_addr_from_netlink(AF_INET, (uint8_t *)&addr, arp_lif))
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP %s is identical with the ip address of interface %s",
+ show_ip_str(arp_msg->ipv4_addr), arp_lif->name);
+ return;
+ }
+ } else {
+ if (vid && vlan_id_list && vlan_id_list->vlan_itf) {
+ if (arp_msg->ipv4_addr == vlan_id_list->vlan_itf->ipv4_addr) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Ignore My ip %s", show_ip_str(arp_msg->ipv4_addr));
+ return;
+ }
+ }
}
/* update lif ARP*/
@@ -708,15 +972,13 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui
/* update ARP*/
if (arp_info->op_type != arp_msg->op_type
|| strcmp(arp_info->ifname, arp_msg->ifname) != 0
- || memcmp(arp_info->mac_addr, arp_msg->mac_addr,
- ETHER_ADDR_LEN) != 0)
+ || memcmp(arp_info->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN) != 0)
{
arp_info->op_type = arp_msg->op_type;
sprintf(arp_info->ifname, "%s", arp_msg->ifname);
memcpy(arp_info->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Update ARP for %s by ARP reply, intf %s mac [%02X:%02X:%02X:%02X:%02X:%02X]",
- show_ip_str(arp_msg->ipv4_addr), arp_msg->ifname,
- arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2], arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Update ARP for %s",
+ show_ip_str(arp_msg->ipv4_addr));
}
break;
}
@@ -725,6 +987,7 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui
if (!msg)
{
arp_msg->op_type = NEIGH_SYNC_LIF;
+ arp_msg->learn_flag = NEIGH_LOCAL;
if (iccp_csm_init_msg(&msg, (char*)arp_msg, msg_len) == 0)
{
mlacp_enqueue_arp(csm, msg);
@@ -740,6 +1003,7 @@ void do_arp_update_from_reply_packet(unsigned int ifindex, unsigned int addr, ui
if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
{
arp_msg->op_type = NEIGH_SYNC_ADD;
+ arp_msg->flag = 0;
if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, msg_len) == 0)
{
TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail);
@@ -764,9 +1028,16 @@ void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, ui
struct Msg *msg_send = NULL;
char mac_str[18] = "";
uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ uint16_t vid = 0;
+ int err = 0, ln = 0;
+ struct LocalInterface *peer_link_if = NULL;
+ int is_link_local = 0;
char buf[MAX_BUFSIZE];
size_t msg_len = 0;
+ char addr_null[16] = { 0 };
+ uint16_t vlan_id = 0;
+ struct VLAN_ID vlan_key = { 0 };
struct LocalInterface *lif_po = NULL, *ndisc_lif = NULL;
@@ -790,37 +1061,70 @@ void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, ui
memcpy((char *)ndisc_msg->ipv6_addr, ipv6_addr, 16);
memcpy(ndisc_msg->mac_addr, mac_addr, ETHER_ADDR_LEN);
- ICCPD_LOG_DEBUG(__FUNCTION__, "nd ifindex [%d] (%s) ip %s mac %s",
- ifindex, ndisc_lif->name, show_ipv6_str(ipv6_addr), mac_str);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "nd ifindex [%d] (%s) ip %s mac %s", ifindex, ndisc_lif->name, show_ipv6_str(ipv6_addr), mac_str);
+
+ if (memcmp(ndisc_lif->ipv6_addr, addr_null, 16) == 0) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "IPv6 address not configured on %s, ignore ND", ndisc_lif->name);
+ return;
+ }
+
+ uint8_t bcast_mac[ETHER_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ if (memcmp(ndisc_msg->mac_addr, bcast_mac, ETHER_ADDR_LEN) == 0)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Ignoring neighbor entry due to bcast lladdr");
+ return;
+ }
+ if ((strncmp(ndisc_lif->name, VLAN_PREFIX, strlen(VLAN_PREFIX)) == 0)) {
+ sscanf (ndisc_lif->name, "Vlan%hu", &vlan_id);
+ }
+
+ if (vlan_id) {
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vlan_id;
+ }
/* Find MLACP itf, member of port-channel */
LIST_FOREACH(csm, &(sys->csm_list), next)
{
+ vid = 0;
LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next)
{
- if (lif_po->type != IF_T_PORT_CHANNEL)
+ if (lif_po->type != IF_T_PORT_CHANNEL) {
+ ln = __LINE__;
continue;
+ }
+ vid = 0;
if (!local_if_is_l3_mode(lif_po))
{
- /* Is the L2 MLAG itf belong to a vlan? */
- LIST_FOREACH(vlan_id_list, &(lif_po->vlan_list), port_next)
- {
- if (!(vlan_id_list->vlan_itf && vlan_id_list->vlan_itf->ifindex == ifindex))
- continue;
- break;
+ /* Is the L2 MLAG itf belong to a vlan?*/
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(lif_po->vlan_tree), &vlan_key);
+
+ if (!vlan_id_list) {
+ ln = __LINE__;
+ continue;
}
- if (!vlan_id_list)
+ if (!vlan_id_list->vlan_itf) {
+ ln = __LINE__;
continue;
- ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled port %s of vlan %s", lif_po->name, vlan_id_list->vlan_itf->name);
+ }
+
+ if (vlan_id_list->vlan_itf->ifindex != ifindex) {
+ ln = __LINE__;
+ continue;
+ }
+
+ vid = vlan_id_list->vid;
}
else
{
/* Is the ND belong to a L3 mode MLAG itf? */
- if (ifindex != lif_po->ifindex)
+ if (ifindex != lif_po->ifindex) {
+ ln = __LINE__;
continue;
- ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from mclag enabled port %s", lif_po->name);
+ }
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from intf %s", lif_po->name);
}
verify_ndisc = 1;
@@ -828,20 +1132,57 @@ void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, ui
break;
}
- if (lif_po)
+ if (lif_po) {
break;
+ } else if (csm->peer_link_if) {
+ peer_link_if = csm->peer_link_if;
+ if (!local_if_is_l3_mode(peer_link_if)) {
+ vid = 0;
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(peer_link_if->vlan_tree), &vlan_key);
+
+ if (vlan_id_list && vlan_id_list->vlan_itf) {
+ if (vlan_id_list->vlan_itf->ifindex == ifindex) {
+ vid = vlan_id_list->vid;
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ND is from peer link vlan %d", vid);
+ verify_ndisc = 1;
+ lif_po = peer_link_if;
+ break;
+ }
+ }
+ }
+ }
}
- if (!(csm && lif_po))
+ if (!(csm && lif_po)) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ND received no PO ln %d", ln);
return;
- if (!verify_ndisc)
+ }
+ if (!verify_ndisc) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ND received no verify_ndisc ln %d", ln);
return;
+ }
- if (iccp_check_if_addr_from_netlink(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, ndisc_lif))
+ if ((memcmp(show_ipv6_str((char *)ndisc_msg->ipv6_addr), "FE80", 4) == 0)
+ || (memcmp(show_ipv6_str((char *)ndisc_msg->ipv6_addr), "fe80", 4) == 0))
{
- ICCPD_LOG_DEBUG(__FUNCTION__, "NA %s is identical with the ipv6 address of interface %s",
- show_ipv6_str((char *)ndisc_msg->ipv6_addr), ndisc_lif->name);
- return;
+ is_link_local = 1;
+ }
+
+ if (vid && vlan_id_list && vlan_id_list->vlan_itf) {
+ if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)vlan_id_list->vlan_itf->ipv6_addr, 16) == 0)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Ignoring neighbor entry for My Ip %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
+ return;
+ }
+
+ if (is_link_local)
+ {
+ if (memcmp((char *)ndisc_msg->ipv6_addr, (char *)vlan_id_list->vlan_itf->ipv6_ll_addr, 16) == 0)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Ignoring neighbor entry for My Ip %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
+ return;
+ }
+ }
}
/* update lif ND */
@@ -862,13 +1203,12 @@ void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, ui
/* update ND */
if (ndisc_info->op_type != ndisc_msg->op_type
- || strcmp(ndisc_info->ifname, ndisc_msg->ifname) != 0
- || memcmp(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN) != 0)
+ || strcmp(ndisc_info->ifname, ndisc_msg->ifname) != 0 || memcmp(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN) != 0)
{
ndisc_info->op_type = ndisc_msg->op_type;
sprintf(ndisc_info->ifname, "%s", ndisc_msg->ifname);
memcpy(ndisc_info->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN);
- ICCPD_LOG_DEBUG(__FUNCTION__, "Update ND for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Update ND for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
}
break;
}
@@ -883,6 +1223,7 @@ void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, ui
}
ndisc_msg->op_type = NEIGH_SYNC_LIF;
+ ndisc_msg->learn_flag = NEIGH_LOCAL;
if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, msg_len) == 0)
{
mlacp_enqueue_ndisc(csm, msg);
@@ -892,17 +1233,22 @@ void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, ui
ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue NDISC-list: %s, add %s", ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr));
}
- if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 1, ndisc_msg->mac_addr, ndisc_msg->ifname) < 0)
+ ICCPD_LOG_DEBUG(__FUNCTION__, "add nd entry(%s, %s, %s) to kernel",
+ ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr), mac_str);
+ if ((err = iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 1, ndisc_msg->mac_addr, ndisc_msg->ifname, 0, 3)) < 0)
{
- ICCPD_LOG_WARN(__FUNCTION__, "Failed to add ND entry(%s, %s, %s) to kernel",
- ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr), mac_str);
- return;
+ if (err != ICCP_NLE_SEQ_MISMATCH) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Failed to add nd entry(%s, %s, %s) to kernel, status %d",
+ ndisc_msg->ifname, show_ipv6_str((char *)ndisc_msg->ipv6_addr), mac_str, err);
+ return;
+ }
}
/* enqueue iccp_msg (add) */
if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
{
ndisc_msg->op_type = NEIGH_SYNC_ADD;
+ ndisc_msg->flag = 0;
if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, msg_len) == 0)
{
TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail);
@@ -914,12 +1260,14 @@ void do_ndisc_update_from_reply_packet(unsigned int ifindex, char *ipv6_addr, ui
return;
}
+
void iccp_from_netlink_port_state_handler( char * ifname, int state)
{
struct CSM *csm = NULL;
struct LocalInterface *lif_po = NULL;
struct System *sys;
int po_is_active = 0;
+ int is_mclag_intf = 0;
if ((sys = system_get_instance()) == NULL)
{
@@ -948,91 +1296,240 @@ void iccp_from_netlink_port_state_handler( char * ifname, int state)
if (lif_po->type == IF_T_PORT_CHANNEL && strncmp(lif_po->name, ifname, MAX_L_PORT_NAME) == 0)
{
mlacp_portchannel_state_handler(csm, lif_po, po_is_active);
+ is_mclag_intf = 1;
}
}
+ if (!is_mclag_intf)
+ {
+ lif_po = local_if_find_by_name(ifname);
+ update_orphan_port_mac(csm, lif_po, po_is_active);
+ }
+
}
return;
}
-void iccp_parse_if_vlan_info_from_netlink(struct nlmsghdr *n)
+
+//find pending vlan member interface
+struct PendingVlanMbrIf* find_pending_vlan_mbr_if(struct System *sys, const char* ifname)
{
- struct LocalInterface *lif = NULL;
- int msglen = 0;
+ struct PendingVlanMbrIf* mbr_if = NULL;
- msglen = n->nlmsg_len;
+ if (!ifname || !sys)
+ return NULL;
- while (NLMSG_OK(n, msglen))
+ LIST_FOREACH(mbr_if, &(sys->pending_vlan_mbr_if_list), if_next)
{
- struct ifinfomsg *ifm = NLMSG_DATA(n);
- int len = n->nlmsg_len;
- struct rtattr *tb[IFLA_MAX + 1] = {0};
+ if (strcmp(mbr_if->name, ifname) == 0)
+ return mbr_if;
+ }
+
+ return NULL;
+}
- if (n->nlmsg_type != RTM_NEWLINK)
+//add specific vlan id to pending vlan membership interface
+int add_pending_vlan_mbr(struct PendingVlanMbrIf* mbr_if, uint16_t vid)
+{
+ struct VLAN_ID *vlan = NULL;
+ struct VLAN_ID vlan_key = { 0 };
+ char vlan_name[16] = "";
+ if (!mbr_if)
+ {
+ return MCLAG_ERROR;
+ }
+
+ sprintf(vlan_name, "Vlan%d", vid);
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vid;
+
+ vlan = RB_FIND(vlan_rb_tree, &(mbr_if->vlan_tree), &vlan_key);
+
+ if (!vlan)
+ {
+ vlan = (struct VLAN_ID*)malloc(sizeof(struct VLAN_ID));
+ if (!vlan)
{
- return;
+ ICCPD_LOG_WARN(__FUNCTION__, "Add Pending Vlan Member for If:%s Vlan:%d creation, malloc failed", mbr_if->name, vid);
+ return MCLAG_ERROR;
}
- len -= NLMSG_LENGTH(sizeof(*ifm));
- if (len < 0)
+ memset(vlan, 0, sizeof(struct VLAN_ID));
+ vlan->vid = vid;
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Add VLAN %d to pending vlan member if:%s ", vid, mbr_if->name);
+ RB_INSERT(vlan_rb_tree, &(mbr_if->vlan_tree), vlan);
+ }
+ return 0;
+}
+
+//delete specific vlan id from pending vlan membership interface
+void del_pending_vlan_mbr(struct PendingVlanMbrIf* mbr_if, uint16_t vid)
+{
+ struct VLAN_ID *vlan = NULL;
+ struct VLAN_ID vlan_key = { 0 };
+ if (!mbr_if)
+ {
+ return;
+ }
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vid;
+
+ vlan = RB_FIND(vlan_rb_tree, &(mbr_if->vlan_tree), &vlan_key);
+
+ if (vlan != NULL)
+ {
+ VLAN_RB_REMOVE(vlan_rb_tree, &(mbr_if->vlan_tree), vlan);
+ free(vlan);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Remove VLAN %d from pending vlan mbr If:%s ",vid, mbr_if->name);
+ }
+ return;
+}
+
+
+//delete all pending vlan members for a given vlan member interface
+void del_all_pending_vlan_mbrs(struct PendingVlanMbrIf* lif)
+{
+ struct VLAN_ID* vlan = NULL;
+ struct VLAN_ID* vlan_temp = NULL;
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Remove all Pending VLANs from %s", lif->name);
+ RB_FOREACH_SAFE(vlan, vlan_rb_tree, &(lif->vlan_tree), vlan_temp)
+ {
+ VLAN_RB_REMOVE(vlan_rb_tree, &(lif->vlan_tree), vlan);
+ free(vlan);
+ }
+ return;
+}
+
+//update vlan membership for a given interface; this function can be called
+//whenever vlan membership is received from mclagsyncd and local interface is not found
+void update_pending_vlan_mbr(char *mbr_if_name, unsigned int vlan_id, int add_flag)
+{
+ struct System *sys = NULL;
+ struct PendingVlanMbrIf *mbr_if;
+ struct VLAN_ID* vlan = NULL;
+ struct VLAN_ID* vlan_temp = NULL;
+
+ if (!(sys = system_get_instance()))
+ {
+ return;
+ }
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "update pending vlan:%d member for if:%s event:%s \n", vlan_id, mbr_if_name, add_flag ? "add":"delete");
+ mbr_if = find_pending_vlan_mbr_if(sys, mbr_if_name);
+ //if mbr_if not found create
+ if (!mbr_if)
+ {
+ if (!add_flag)
{
- ICCPD_LOG_WARN(__FUNCTION__, "BUG: wrong nlmsg len %d\n", len);
return;
}
- if (ifm->ifi_family != AF_BRIDGE)
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Create pending vlan member if %s \n", mbr_if_name);
+ if (!(mbr_if = (struct PendingVlanMbrIf *)malloc(sizeof(struct PendingVlanMbrIf))))
{
+ ICCPD_LOG_WARN(__FUNCTION__, "Pending Vlan Member If:%s creation, malloc failed", mbr_if_name);
return;
}
+ snprintf(mbr_if->name, MAX_L_PORT_NAME, "%s", mbr_if_name);
+ RB_INIT(vlan_rb_tree, &mbr_if->vlan_tree);
+ LIST_INSERT_HEAD(&(sys->pending_vlan_mbr_if_list), mbr_if, if_next);
+ }
+ if (add_flag)
+ {
+ //add to pending vlan member if
+ add_pending_vlan_mbr(mbr_if, vlan_id);
+ }
+ else
+ {
+ //delete from pending vlan member if
+ del_pending_vlan_mbr(mbr_if, vlan_id);
+ }
+}
- if ((lif = local_if_find_by_ifindex(ifm->ifi_index)) != NULL)
- {
- parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifm), len);
- /* if AF_SPEC isn't there, vlan table is not preset for this port */
- if (!tb[IFLA_AF_SPEC])
- {
- ICCPD_LOG_WARN(__FUNCTION__, "Vlan table is not preset for %d", ifm->ifi_index);
- return;
- }
- else
- {
- struct rtattr *i, *list = tb[IFLA_AF_SPEC];
- int rem = RTA_PAYLOAD(list);
- struct VLAN_ID *vlan = NULL;
-
- /*set vlan flag is removed*/
- LIST_FOREACH(vlan, &(lif->vlan_list), port_next)
- {
- vlan->vlan_removed = 1;
- }
+//move pending vlan membership from pending member interface to system lif
+void move_pending_vlan_mbr_to_lif(struct System *sys, struct LocalInterface* lif)
+{
+ struct PendingVlanMbrIf *mbr_if;
+ struct VLAN_ID* vlan = NULL;
+ struct VLAN_ID* vlan_temp = NULL;
+ if (!sys || !lif)
+ {
+ return;
+ }
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Move pending vlan members for %s, %d\n", lif->name, lif->ifindex);
+ mbr_if = find_pending_vlan_mbr_if(sys, lif->name);
+ if (!mbr_if)
+ {
+ ICCPD_LOG_INFO(__FUNCTION__, "No pending vlan members for %s, %d\n", lif->name, lif->ifindex);
+ return;
+ }
- for (i = RTA_DATA(list); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
- {
- struct bridge_vlan_info *vinfo;
+ RB_FOREACH_SAFE(vlan, vlan_rb_tree, &(mbr_if->vlan_tree), vlan_temp)
+ {
+ //add vlan to system lif
+ local_if_add_vlan(lif, vlan->vid);
- if (i->rta_type != IFLA_BRIDGE_VLAN_INFO)
- continue;
+ //delete from pending vlan member if
+ del_pending_vlan_mbr(mbr_if, vlan->vid);
+ }
- vinfo = RTA_DATA(i);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Delete pending vlan member if %s \n", lif->name);
+ LIST_REMOVE(mbr_if, if_next);
+ free(mbr_if);
- local_if_add_vlan(lif, vinfo->vid);
- }
+}
- /*After update vlan list, remove unused item*/
- LIST_FOREACH(vlan, &(lif->vlan_list), port_next)
- {
- if (vlan->vlan_removed == 1)
- {
- ICCPD_LOG_DEBUG(__FUNCTION__, "Remove %s from VLAN %d", lif->name, vlan->vid);
+//remove all pending vlan member interface and vlan memberships
+void del_all_pending_vlan_mbr_ifs(struct System *sys)
+{
+ struct PendingVlanMbrIf *pending_vlan_mbr_if = NULL;
- LIST_REMOVE(vlan, port_next);
- free(vlan);
- }
- }
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Delete all pending vlan members \n");
+
+ while (!LIST_EMPTY(&(sys->pending_vlan_mbr_if_list)))
+ {
+ pending_vlan_mbr_if = LIST_FIRST(&(sys->pending_vlan_mbr_if_list));
+ LIST_REMOVE(pending_vlan_mbr_if, if_next);
+ del_all_pending_vlan_mbrs(pending_vlan_mbr_if);
+ free(pending_vlan_mbr_if);
+ }
+}
+
+void vlan_mbrship_change_handler(unsigned int vlan_id, char *mbr_if_name, int add_flag)
+{
+ struct LocalInterface *lif = NULL;
+ struct LocalInterface *vlan_lif = NULL;
+ char vlan_name[16] = "";
+
+ lif = local_if_find_by_name(mbr_if_name);
+ if (!lif)
+ {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Rx vlan:%d mbr if:%s event %s; No MCLAG If", vlan_id, mbr_if_name, add_flag ? "add":"delete");
+ update_pending_vlan_mbr(mbr_if_name, vlan_id, add_flag);
+ return;
+ }
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Rx vlan:%d mbr if:%s event %s", vlan_id, mbr_if_name, add_flag ? "add":"delete");
+
+ if (add_flag) //vlan membership got added
+ {
+ sprintf(vlan_name, "Vlan%d", vlan_id);
+ vlan_lif = local_if_find_by_name(vlan_name);
+ if (!vlan_lif) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "%s LIF not present", vlan_name);
+ vlan_lif = local_if_create( -1, vlan_name, IF_T_VLAN, IF_OPER_DOWN);
+ if (vlan_lif) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "%s LIF created with ifindex -1", vlan_name);
}
}
- n = NLMSG_NEXT(n, msglen);
+ local_if_add_vlan(lif, vlan_id);
}
+ else //vlan membership got deleted
+ {
+ local_if_del_vlan(lif, vlan_id);
+ }
+ return;
}
diff --git a/src/iccpd/src/iccp_main.c b/src/iccpd/src/iccp_main.c
index 86920f07e1fb..fe3594583a51 100644
--- a/src/iccpd/src/iccp_main.c
+++ b/src/iccpd/src/iccp_main.c
@@ -134,6 +134,7 @@ void iccpd_signal_handler(int sig)
if (err == -1 && errno == EINTR)
goto retry;
+ SYSTEM_INCR_WARMBOOT_COUNTER(sys);
return;
}
diff --git a/src/iccpd/src/iccp_netlink.c b/src/iccpd/src/iccp_netlink.c
index 002c254ae9c1..1143f370ffc5 100644
--- a/src/iccpd/src/iccp_netlink.c
+++ b/src/iccpd/src/iccp_netlink.c
@@ -35,10 +35,9 @@
#include
#include
#include
-#include
-#include
#include
#include
+#include
#include
#include
@@ -57,6 +56,8 @@
#include "../include/mlacp_link_handler.h"
#include "../include/msg_format.h"
#include "../include/iccp_netlink.h"
+#include "../include/mlacp_sync_update.h"
+#include "../include/mlacp_tlv.h"
/**
* SECTION: Netlink helpers
@@ -72,6 +73,9 @@
#define NETLINK_BROADCAST_SEND_ERROR 0x4
#endif
+/* Use the same socket buffer size as in SwSS common */
+#define NETLINK_SOCKET_BUFFER_SIZE 16777216
+
static int iccp_ack_handler(struct nl_msg *msg, void *arg)
{
bool *acked = arg;
@@ -141,7 +145,7 @@ int iccp_send_and_recv(struct System *sys, struct nl_msg *msg,
}
err = 0;
- put_cb:
+put_cb:
nl_cb_put(cb);
return err;
}
@@ -416,7 +420,7 @@ int iccp_get_port_member_list(struct LocalInterface* lif)
int iccp_netlink_if_hwaddr_set(uint32_t ifindex, uint8_t *addr, unsigned int addr_len)
{
struct rtnl_link *link;
- int err;
+ int err = 0;
struct nl_addr *nl_addr;
struct System* sys = NULL;
@@ -441,8 +445,10 @@ int iccp_netlink_if_hwaddr_set(uint32_t ifindex, uint8_t *addr, unsigned int add
nl_addr_put(nl_addr);
- errout:
+errout:
rtnl_link_put(link);
+ ICCPD_LOG_NOTICE(__FUNCTION__, "ifindex %x, mac %02x:%02x:%02x:%02x:%02x:%02x, err %d",
+ ifindex, addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], err);
return err;
}
@@ -489,7 +495,7 @@ void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr )
dst_len = strlen(mac_addr);
memcpy(sub_msg->data, mac_addr, dst_len);
- ICCPD_LOG_NOTICE(__FUNCTION__, "If name %s ip %s mac %s", lif->name, show_ip_str(htonl(lif->ipv4_addr)), sub_msg->data);
+ ICCPD_LOG_NOTICE(__FUNCTION__, "If name %s ip %s mac %s", lif->name, show_ip_str(lif->ipv4_addr), sub_msg->data);
sub_msg->op_len = dst_len;
msg_hdr->len += sizeof(mclag_sub_option_hdr_t);
@@ -497,8 +503,18 @@ void iccp_set_interface_ipadd_mac(struct LocalInterface *lif, char * mac_addr )
/*send msg*/
if (sys->sync_fd)
- write(sys->sync_fd, msg_buf, msg_hdr->len);
-
+ {
+ if (write(sys->sync_fd,msg_buf, msg_hdr->len) == -1)
+ {
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(
+ sys, msg_hdr->type, ICCP_DBG_CNTR_STS_ERR);
+ }
+ else
+ {
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(
+ sys, msg_hdr->type, ICCP_DBG_CNTR_STS_OK);
+ }
+ }
return;
}
@@ -547,7 +563,67 @@ int iccp_netlink_if_shutdown_set(uint32_t ifindex)
rtnl_link_put(link);
return err;
}
-void update_if_ipmac_on_standby(struct LocalInterface* lif_po)
+
+//Set IFF up flag for all member ports of a port-channel
+static int iccp_netlink_set_portchannel_iff_flag(
+ struct LocalInterface* lif_po,
+ bool is_iff_up,
+ int location)
+{
+ int rv, ret_rv = 0;
+ char* token;
+ struct LocalInterface* member_if;
+ char *tmp_member_buf = NULL;
+
+ if (!lif_po)
+ return MCLAG_ERROR;
+
+ tmp_member_buf = strdup(lif_po->portchannel_member_buf);
+ if (!tmp_member_buf)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Fail to allocate memory to bring %s %s",
+ is_iff_up ? "up" : "down", lif_po->name);
+ return MCLAG_ERROR;
+ }
+ else
+ {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Bring %s %s, members %s",
+ is_iff_up ? "up" : "down", lif_po->name,
+ lif_po->portchannel_member_buf);
+ }
+ /* Port-channel members are stored as comma separated strings */
+ token = strtok(tmp_member_buf, ",");
+ while (token != NULL)
+ {
+ member_if = local_if_find_by_name(token);
+ if (member_if)
+ {
+ if (is_iff_up)
+ rv = iccp_netlink_if_startup_set(member_if->ifindex);
+ else
+ rv = iccp_netlink_if_shutdown_set(member_if->ifindex);
+ if (rv != 0)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__,
+ "Set %s:%s, if_up(%d), location(%d) failed, rv %d",
+ lif_po->name, member_if->name, is_iff_up, location, rv);
+ ret_rv = rv;
+ }
+ }
+ else
+ {
+ ICCPD_LOG_ERR(__FUNCTION__,
+ "Can't find member %s:%s, if_up(%d), location %d",
+ lif_po->name, token, is_iff_up, location);
+ }
+ token = strtok(NULL, ",");
+ }
+ if (tmp_member_buf)
+ free(tmp_member_buf);
+ return ret_rv;
+}
+
+void update_if_ipmac_on_standby(struct LocalInterface* lif_po, int dir)
{
struct CSM* csm;
uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@@ -557,6 +633,7 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po)
struct LocalInterface* lif_Bri;
char macaddr[64];
int ret = 0;
+ struct PeerInterface* pif = NULL;
if (!csm)
return;
@@ -572,17 +649,22 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po)
if (memcmp(MLACP(csm).remote_system.system_id, null_mac, ETHER_ADDR_LEN) == 0)
return;
- /*Set new mac*/
- if (memcmp( lif_po->mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN) != 0)
+ pif = peer_if_find_by_name(csm, lif_po->name);
+
+ /*Set new mac only if remote MLAG interface also exists */
+ if (pif && (memcmp( lif_po->mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN) != 0))
{
/*Backup old sysmac*/
memcpy(lif_po->mac_addr_ori, lif_po->mac_addr, ETHER_ADDR_LEN);
ICCPD_LOG_NOTICE(__FUNCTION__,
- "%s Change the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X].",
+ "%s Change the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X], dir %d",
(csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active",
- lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2], lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5],
- MLACP(csm).remote_system.system_id[0], MLACP(csm).remote_system.system_id[1], MLACP(csm).remote_system.system_id[2], MLACP(csm).remote_system.system_id[3], MLACP(csm).remote_system.system_id[4], MLACP(csm).remote_system.system_id[5]);
+ lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2],
+ lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5],
+ MLACP(csm).remote_system.system_id[0], MLACP(csm).remote_system.system_id[1],
+ MLACP(csm).remote_system.system_id[2], MLACP(csm).remote_system.system_id[3],
+ MLACP(csm).remote_system.system_id[4], MLACP(csm).remote_system.system_id[5], dir);
ret = iccp_netlink_if_hwaddr_set(lif_po->ifindex, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN);
if (ret != 0)
@@ -602,13 +684,13 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po)
{
if (memcmp(lif_po->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN) != 0)
{
- iccp_set_interface_ipadd_mac(lif_po, macaddr );
+ iccp_set_interface_ipadd_mac(lif_po, macaddr);
memcpy(lif_po->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN);
}
}
else
{
- LIST_FOREACH(vlan, &(lif_po->vlan_list), port_next)
+ RB_FOREACH(vlan, vlan_rb_tree, &(lif_po->vlan_tree))
{
if (!vlan->vlan_itf)
continue;
@@ -616,12 +698,25 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po)
/*If the po is under a vlan, update vlan mac*/
if (local_if_is_l3_mode(vlan->vlan_itf))
{
- if (memcmp(vlan->vlan_itf->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN) != 0)
+
+ ICCPD_LOG_NOTICE(__FUNCTION__,
+ "%s Change the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X], proto %d, dir %d",
+ (csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active",
+ vlan->vlan_itf->name, vlan->vlan_itf->l3_mac_addr[0], vlan->vlan_itf->l3_mac_addr[1],
+ vlan->vlan_itf->l3_mac_addr[2], vlan->vlan_itf->l3_mac_addr[3],
+ vlan->vlan_itf->l3_mac_addr[4], vlan->vlan_itf->l3_mac_addr[5],
+ MLACP(csm).remote_system.system_id[0], MLACP(csm).remote_system.system_id[1],
+ MLACP(csm).remote_system.system_id[2], MLACP(csm).remote_system.system_id[3],
+ MLACP(csm).remote_system.system_id[4], MLACP(csm).remote_system.system_id[5],
+ vlan->vlan_itf->is_l3_proto_enabled, dir);
+
+ if ((memcmp(vlan->vlan_itf->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN) != 0)
+ && (vlan->vlan_itf->is_l3_proto_enabled == false))
{
- ret = iccp_netlink_if_hwaddr_set(vlan->vlan_itf->ifindex, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN);
+ ret = iccp_netlink_if_hwaddr_set(vlan->vlan_itf->ifindex, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN);
if (ret != 0)
{
- ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret);
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Set %s mac error, ret = %d, dir %d", vlan->vlan_itf->name, ret, dir);
}
/* Refresh link local address according the new MAC */
@@ -631,6 +726,8 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po)
iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr);
memcpy(vlan->vlan_itf->l3_mac_addr, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN);
}
+ } else {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "%s not L3 interface, dir %d", vlan->vlan_itf->name, dir);
}
}
}
@@ -638,9 +735,9 @@ void update_if_ipmac_on_standby(struct LocalInterface* lif_po)
return;
}
-void recover_if_ipmac_on_standby(struct LocalInterface* lif_po)
+void recover_if_ipmac_on_standby(struct LocalInterface *lif_po, int dir)
{
- struct CSM* csm;
+ struct CSM *csm;
uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
struct VLAN_ID *vlan = NULL;
@@ -663,20 +760,27 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po)
if (memcmp( lif_po->mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN) != 0)
{
ICCPD_LOG_NOTICE(__FUNCTION__,
- "%s Recover the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X].",
+ "%s Recover the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X], dir %d",
(csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active",
- lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2], lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5],
- MLACP(csm).system_id[0], MLACP(csm).system_id[1], MLACP(csm).system_id[2], MLACP(csm).system_id[3], MLACP(csm).system_id[4], MLACP(csm).system_id[5]);
+ lif_po->name, lif_po->mac_addr[0], lif_po->mac_addr[1], lif_po->mac_addr[2],
+ lif_po->mac_addr[3], lif_po->mac_addr[4], lif_po->mac_addr[5],
+ MLACP(csm).system_id[0], MLACP(csm).system_id[1], MLACP(csm).system_id[2],
+ MLACP(csm).system_id[3], MLACP(csm).system_id[4], MLACP(csm).system_id[5], dir);
ret = iccp_netlink_if_hwaddr_set(lif_po->ifindex, MLACP(csm).system_id, ETHER_ADDR_LEN);
if (ret != 0)
{
- ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", lif_po->name, ret);
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Set %s mac error, ret = %d, dir %d", lif_po->name, ret, dir);
}
/* Refresh link local address according the new MAC */
iccp_netlink_if_shutdown_set(lif_po->ifindex);
iccp_netlink_if_startup_set(lif_po->ifindex);
+ /* Set the interface MAC address back to its local address so that subsequent vlan member
+ * add processing (local_if_add_vlan) will not use the old MAC address for
+ * update_if_ipmac_on_standby()
+ */
+ memcpy(lif_po->mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN);
}
/*Set portchannel ip mac */
@@ -684,23 +788,25 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po)
SET_MAC_STR(macaddr, MLACP(csm).system_id);
if (local_if_is_l3_mode(lif_po))
{
- iccp_set_interface_ipadd_mac(lif_po, macaddr );
+ iccp_set_interface_ipadd_mac(lif_po, macaddr);
memcpy(lif_po->l3_mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN);
}
else
{
- LIST_FOREACH(vlan, &(lif_po->vlan_list), port_next)
+ RB_FOREACH(vlan, vlan_rb_tree, &(lif_po->vlan_tree))
{
if (!vlan->vlan_itf)
continue;
/*If the po is under a vlan, update vlan mac*/
- if (local_if_is_l3_mode(vlan->vlan_itf))
+ if (local_if_is_l3_mode(vlan->vlan_itf) && (vlan->vlan_itf->is_l3_proto_enabled == false))
{
- ret = iccp_netlink_if_hwaddr_set(vlan->vlan_itf->ifindex, MLACP(csm).system_id, ETHER_ADDR_LEN);
+ ret = iccp_netlink_if_hwaddr_set(vlan->vlan_itf->ifindex, MLACP(csm).system_id, ETHER_ADDR_LEN);
if (ret != 0)
{
- ICCPD_LOG_ERR(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret);
+ if (ret != ICCP_NLE_SEQ_MISMATCH) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Set %s mac error, ret = %d", vlan->vlan_itf->name, ret);
+ }
}
/* Refresh link local address according the new MAC */
@@ -709,6 +815,9 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po)
iccp_set_interface_ipadd_mac(vlan->vlan_itf, macaddr);
memcpy(vlan->vlan_itf->l3_mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN);
+ } else {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "%s not L3 interface, proto %d, dir %d",
+ vlan->vlan_itf->name, vlan->vlan_itf->is_l3_proto_enabled, dir);
}
}
}
@@ -716,7 +825,7 @@ void recover_if_ipmac_on_standby(struct LocalInterface* lif_po)
return;
}
-int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *mac, char *portname)
+int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *mac, char *portname, int permanent, int dir)
{
struct System *sys = NULL;
struct rtnl_neigh *neigh = NULL;
@@ -728,29 +837,29 @@ int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *m
int err = 0;
if (!(sys = system_get_instance()))
- return MCLAG_ERROR;
+ return -2;
lif = local_if_find_by_name(portname);
if (!lif)
- return MCLAG_ERROR;
+ return -3;
neigh = rtnl_neigh_alloc();
if (!neigh)
{
ICCPD_LOG_INFO(__FUNCTION__, "Unable to allocate neighbour object");
- return MCLAG_ERROR;
+ return -4;
}
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Notify kernel %s %s entry(ip:%s, mac:%s, intf:%s)",
+ ICCPD_LOG_DEBUG(__FUNCTION__, "notify kernel %s %s entry(ip:%s, mac:%s, intf:%s), dir %d",
add ? "add" : "del", (family == AF_INET) ? "ARP" : "ND",
- (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, portname);
+ (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, portname, dir);
nl_addr_mac = nl_addr_build(AF_LLC, (void *)mac, ETHER_ADDR_LEN);
if (!nl_addr_mac)
{
- err = MCLAG_ERROR;
+ err = -5;
goto errout;
}
@@ -761,26 +870,29 @@ int iccp_netlink_neighbor_request(int family, uint8_t *addr, int add, uint8_t *m
if (!nl_addr_dst)
{
- err = MCLAG_ERROR;
+ err = -6;
goto errout;
}
rtnl_neigh_set_lladdr(neigh, nl_addr_mac);
rtnl_neigh_set_dst(neigh, nl_addr_dst);
rtnl_neigh_set_ifindex(neigh, lif->ifindex);
- rtnl_neigh_set_state(neigh, NUD_REACHABLE);
+ if (permanent) {
+ rtnl_neigh_set_state(neigh, NUD_PERMANENT|NUD_NOARP);
+ rtnl_neigh_set_flags(neigh, NTF_EXT_LEARNED);
+ } else {
+ rtnl_neigh_set_state(neigh, NUD_REACHABLE);
+ }
if (add)
{
if ((err = rtnl_neigh_add(sys->route_sock, neigh, NLM_F_REPLACE | NLM_F_CREATE)) < 0)
- ICCPD_LOG_WARN(__FUNCTION__, "Add %s (ip:%s, mac:%s) error, err = %d", (family == AF_INET) ? "ARP" : "ND",
- (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, err);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "add neigh error, err = %d", err);
}
else
{
if ((err = rtnl_neigh_delete(sys->route_sock, neigh, 0)) < 0)
- ICCPD_LOG_WARN(__FUNCTION__, "Del %s (ip:%s, mac:%s) error, err = %d", (family == AF_INET) ? "ARP" : "ND",
- (family == AF_INET) ? show_ip_str(*((int *)addr)) : show_ipv6_str(addr), mac_str, err);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "del neigh error, err = %d", err);
}
errout:
@@ -794,13 +906,15 @@ void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg)
{
struct rtnl_link *link;
unsigned int *event = arg;
- uint32_t ifindex;
+ uint32_t ifindex = 0;
char * ifname, *p;
struct LocalInterface *lif = NULL;
struct nl_addr *nl_addr;
int addr_type = 0;
int op_state = 0;
int link_flag = 0;
+ uint32_t master_ifindex = 0;
+ char addr_null[16] = { 0 };
link = (struct rtnl_link *)obj;
ifindex = rtnl_link_get_ifindex(link);
@@ -808,6 +922,12 @@ void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg)
ifname = rtnl_link_get_name(link);
nl_addr = rtnl_link_get_addr(link);
link_flag = rtnl_link_get_flags(link);
+ master_ifindex = rtnl_link_get_master(link);
+
+ if (ifindex < 0) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "invalid ifindex %d", ifindex);
+ return;
+ }
if (nl_addr)
addr_type = nl_addr_guess_family(nl_addr);
@@ -825,15 +945,33 @@ void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg)
lif = local_if_find_by_name(ifname);
if (!lif)
{
- lif = local_if_create(ifindex, ifname, IF_T_VXLAN);
+ lif = local_if_create(ifindex, ifname, IF_T_VXLAN,
+ (op_state == IF_OPER_UP) ? PORT_STATE_UP : PORT_STATE_DOWN);
lif->state = PORT_STATE_UP;
}
return;
}
else
- lif = local_if_find_by_ifindex(ifindex);
+ {
+ lif = local_if_find_by_name(ifname);
+ }
- if (!lif)
+ if (lif && (lif->ifindex == -1) && (lif->type == IF_T_VLAN))
+ {
+ lif->ifindex = ifindex;
+ lif->state = (op_state == IF_OPER_UP) ? PORT_STATE_UP : PORT_STATE_DOWN;
+
+ if (addr_type == AF_LLC)
+ {
+ memcpy( lif->mac_addr, nl_addr_get_binary_addr(nl_addr), ETHER_ADDR_LEN);
+ }
+
+ ICCPD_LOG_NOTICE(__FUNCTION__,
+ "Update Vlan local_if = %s ifindex = %d MAC = %02x:%02x:%02x:%02x:%02x:%02x, state = %s",
+ ifname, lif->ifindex, lif->mac_addr[0], lif->mac_addr[1], lif->mac_addr[2],
+ lif->mac_addr[3], lif->mac_addr[4], lif->mac_addr[5], lif->state ? "down" : "up");
+ }
+ else if (!lif || lif->ifindex != ifindex)
{
const itf_type_t if_whitelist[] = {
{ PORTCHANNEL_PREFIX, IF_T_PORT_CHANNEL },
@@ -849,15 +987,36 @@ void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg)
if ((strncmp(ifname,
if_whitelist[i].ifname, strlen(if_whitelist[i].ifname)) == 0))
{
- lif = local_if_create(ifindex, ifname, if_whitelist[i].type);
-
- lif->state = PORT_STATE_DOWN;
-
- if (IF_OPER_UP == op_state )
+
+ /*if the iface exists, but the ifindex changed, then delete old
+ * interface and add the new interface
+ * possible scenario is due to many kernel events, there is
+ * possiblility of losing if deletion event and just
+ * getting a add of same iface with new ifindex.
+ * to address this possibility if add event of interface is
+ * received with new ifindex different from old interace,
+ * then delete the old ifindex interface and add new if with new
+ * ifindex
+ */
+ if (lif && lif->ifindex != ifindex)
{
- lif->state = PORT_STATE_UP;
+ ICCPD_LOG_NOTICE(__FUNCTION__, "%s ifindex changed from old ifindex:%d to new ifindex:%d ", ifname, lif->ifindex, ifindex);
+ if ((strncmp(ifname, FRONT_PANEL_PORT_PREFIX, strlen(FRONT_PANEL_PORT_PREFIX)) == 0))
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Front panel port %s ifindex changed !!! from old ifindex:%d to new ifindex:%d ", ifname, lif->ifindex, ifindex);
+ }
+ local_if_destroy(lif->name);
}
+ /* Provide state info when local_if is created so that po_active
+ * flag can be set correctly instead of assuming it is always
+ * active. This helps address the issue where MLAG interface
+ * up update to remote MLAG peer is not sent if port-channel
+ * is configured as MLAG interface when it is down
+ */
+ lif = local_if_create(ifindex, ifname, if_whitelist[i].type,
+ (op_state == IF_OPER_UP) ? PORT_STATE_UP : PORT_STATE_DOWN);
+
switch (addr_type)
{
case AF_LLC:
@@ -865,28 +1024,45 @@ void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg)
default:
break;
}
-
break;
}
}
+ if (if_whitelist[i].ifname == NULL)
+ {
+ SYSTEM_INCR_NETLINK_UNKNOWN_IF_NAME(ifname);
+ }
}
else /*update*/
{
/*update*/
- if (lif->state == PORT_STATE_DOWN && op_state == IF_OPER_UP)
+ if (lif->state == PORT_STATE_DOWN && (link_flag & IFF_LOWER_UP))
{
lif->state = PORT_STATE_UP;
/*if(lif->type ==IF_T_PORT_CHANNEL)*/
ICCPD_LOG_NOTICE(__FUNCTION__, "Update local port %s state up", ifname);
+ /* If local interface is not configured as MLAG interface yet,
+ * its po_active status must be updated. Otherwise, incorrect
+ * status will be used to determine the traffic_disable setting
+ */
+ if ((lif->type == IF_T_PORT_CHANNEL) && (lif->csm == NULL))
+ lif->po_active = 1;
+
iccp_from_netlink_port_state_handler(lif->name, lif->state);
}
- else if (lif->state == PORT_STATE_UP && ( IF_OPER_UP != op_state || !(link_flag & IFF_LOWER_UP)))
+ else if (lif->state == PORT_STATE_UP && ( !(link_flag & IFF_LOWER_UP)))
{
lif->state = PORT_STATE_DOWN;
/*if(lif->type ==IF_T_PORT_CHANNEL)*/
ICCPD_LOG_NOTICE(__FUNCTION__, "Update local port %s state down", ifname);
+ /* If local interface is not configured as MLAG interface yet,
+ * its po_active status must be updated. Otherwise, incorrect
+ * status will be used to determine the traffic_disable setting
+ */
+ if ((lif->type == IF_T_PORT_CHANNEL) && (lif->csm == NULL))
+ lif->po_active = 0;
+
iccp_from_netlink_port_state_handler(lif->name, lif->state);
}
@@ -902,6 +1078,26 @@ void iccp_event_handler_obj_input_newlink(struct nl_object *obj, void *arg)
default:
break;
}
+
+ if ((lif->type == IF_T_VLAN) && (lif->master_ifindex != master_ifindex))
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "master idx %d - %d, l3_proto %d",
+ lif->master_ifindex, master_ifindex, lif->is_l3_proto_enabled);
+ if (master_ifindex) {
+ lif->master_ifindex = master_ifindex;
+ lif->l3_mode = 1;
+ update_vlan_if_mac_on_standby(lif, 5);
+ } else {
+ if ((lif->ipv4_addr == 0) && (memcmp(lif->ipv6_addr, addr_null, 16) == 0)) {
+ if (lif->is_l3_proto_enabled == false) {
+ recover_vlan_if_mac_on_standby(lif, 5, NULL);
+ }
+ lif->l3_mode = 0;
+ memset(lif->l3_mac_addr, 0, ETHER_ADDR_LEN);
+ }
+ lif->master_ifindex = 0;
+ }
+ }
}
return;
@@ -922,103 +1118,6 @@ void iccp_event_handler_obj_input_dellink(struct nl_object *obj, void *arg)
return;
}
-void iccp_event_handler_obj_input_newaddr(struct nl_object *obj, void *arg)
-{
- struct rtnl_addr *addr;
- struct nl_addr *nl_addr;
- struct LocalInterface *lif;
- uint32_t ifindex;
- char addrStr[65] = { 0 };
- char addr_null[16] = { 0 };
- addr = (struct rtnl_addr *)obj;
-
- ifindex = rtnl_addr_get_ifindex(addr);
- nl_addr = rtnl_addr_get_local(addr);
-
- if (!(lif = local_if_find_by_ifindex(ifindex)))
- return;
-
- if (rtnl_addr_get_family(addr) == AF_INET)
- {
- lif->ipv4_addr = *(uint32_t *) nl_addr_get_binary_addr(nl_addr);
- lif->prefixlen = nl_addr_get_prefixlen(nl_addr);
- lif->l3_mode = 1;
- lif->port_config_sync = 1;
- if (memcmp((char *)lif->ipv6_addr, addr_null, 16) == 0)
- update_if_ipmac_on_standby(lif);
- ICCPD_LOG_DEBUG(__FUNCTION__, "Ifname %s index %d address %s", lif->name, lif->ifindex, show_ip_str(lif->ipv4_addr));
- }
- else if (rtnl_addr_get_family(addr) == AF_INET6)
- {
- if (memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "FE80", 4) == 0
- || memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "fe80", 4) == 0)
- return;
-
- memcpy((char *)lif->ipv6_addr, nl_addr_get_binary_addr(nl_addr), 16);
- lif->prefixlen = nl_addr_get_prefixlen(nl_addr);
- lif->l3_mode = 1;
- lif->port_config_sync = 1;
- if (lif->ipv4_addr == 0)
- update_if_ipmac_on_standby(lif);
- ICCPD_LOG_DEBUG(__FUNCTION__, "Ifname %s index %d address %s", lif->name, lif->ifindex, show_ipv6_str((char *)lif->ipv6_addr));
- }
-
- return;
-}
-
-void iccp_event_handler_obj_input_deladdr(struct nl_object *obj, void *arg)
-{
- struct rtnl_addr *addr;
- struct nl_addr *nl_addr;
- struct LocalInterface *lif;
- uint32_t ifindex;
- char addr_null[16] = { 0 };
-
- addr = (struct rtnl_addr *)obj;
-
- ifindex = rtnl_addr_get_ifindex(addr);
- nl_addr = rtnl_addr_get_local(addr);
-
- if (!(lif = local_if_find_by_ifindex(ifindex)))
- return;
-
- if (rtnl_addr_get_family(addr) == AF_INET)
- {
- lif->ipv4_addr = 0;
- lif->prefixlen = 0;
- }
- else if (rtnl_addr_get_family(addr) == AF_INET6)
- {
- if (memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "FE80", 4) == 0
- || memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "fe80", 4) == 0)
- return;
-
- memset((char *)lif->ipv6_addr, 0, 16);
- lif->prefixlen_v6 = 0;
- }
-
- if (lif->ipv4_addr == 0 && memcmp((char *)lif->ipv6_addr, addr_null, 16) == 0)
- {
- lif->l3_mode = 0;
- memset(lif->l3_mac_addr, 0, ETHER_ADDR_LEN);
- }
-
- return;
-}
-
-int iccp_addr_valid_handler(struct nl_msg *msg, void *arg)
-{
- struct nlmsghdr *nlh = nlmsg_hdr(msg);
- unsigned int event = 0;
- if (nlh->nlmsg_type != RTM_NEWADDR)
- return 0;
-
- if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newaddr, &event) < 0)
- ICCPD_LOG_ERR(__FUNCTION__, "Unknown message type.");
-
- return 0;
-}
-
int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInterface *lif)
{
struct
@@ -1123,6 +1222,268 @@ int iccp_check_if_addr_from_netlink(int family, uint8_t *addr, struct LocalInter
return 0;
}
+int iccp_del_self_ip_from_neigh_table (struct LocalInterface *lif, int addr_family)
+{
+ struct System *sys = NULL;
+ struct CSM *csm = NULL;
+ struct Msg *msg = NULL;
+ struct ARPMsg *arp_msg = NULL, *arp_info = NULL;
+ struct NDISCMsg *ndisc_msg = NULL, *ndisc_info = NULL;
+ int err = 0;
+
+ if (!(sys = system_get_instance()))
+ {
+ return -1;
+ }
+
+ if (addr_family == AF_INET) {
+
+ LIST_FOREACH(csm, &(sys->csm_list), next)
+ {
+ TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail)
+ {
+ arp_info = (struct ARPMsg *)msg->buf;
+ if (arp_info->ipv4_addr == lif->ipv4_addr) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, " Delete ARP %s", show_ip_str(lif->ipv4_addr));
+ break;
+ }
+ }
+
+ if (msg)
+ {
+ TAILQ_REMOVE(&(MLACP(csm).arp_list), msg, tail);
+ free(msg->buf);
+ free(msg);
+ msg = NULL;
+ break;
+ }
+ }
+ } else if (addr_family == AF_INET6) {
+
+ LIST_FOREACH(csm, &(sys->csm_list), next)
+ {
+ TAILQ_FOREACH(msg, &MLACP(csm).ndisc_list, tail)
+ {
+ ndisc_info = (struct NDISCMsg *)msg->buf;
+
+ if (memcmp(&ndisc_info->ipv6_addr, &lif->ipv6_addr, 16) == 0) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, " Delete neighbor %s", show_ipv6_str((char *)lif->ipv6_addr));
+ break;
+ }
+ }
+
+ if (msg)
+ {
+ TAILQ_REMOVE(&MLACP(csm).ndisc_list, msg, tail);
+ free(msg->buf);
+ free(msg);
+ msg = NULL;
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void iccp_event_handler_obj_input_newaddr(struct nl_object *obj, void *arg)
+{
+ struct rtnl_addr *addr;
+ struct nl_addr *nl_addr;
+ struct LocalInterface *lif;
+ uint32_t ifindex;
+ char addrStr[65] = { 0 };
+ char addr_null[16] = { 0 };
+ addr = (struct rtnl_addr *)obj;
+ int sync_add = 1, is_v4 = 0, is_v6 = 0, sync_mac = 0;
+
+ ifindex = rtnl_addr_get_ifindex(addr);
+ nl_addr = rtnl_addr_get_local(addr);
+
+ if (!(lif = local_if_find_by_ifindex(ifindex)))
+ return;
+
+ if (rtnl_addr_get_family(addr) == AF_INET)
+ {
+ if (lif->ipv4_addr != 0) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Ignore Multiple IP Add on ifname %s index %d present address %s l3_proto %d\n",
+ lif->name, lif->ifindex, show_ip_str(lif->ipv4_addr), lif->is_l3_proto_enabled);
+ return;
+ }
+
+ lif->ipv4_addr = *(uint32_t *) nl_addr_get_binary_addr(nl_addr);
+ lif->prefixlen = nl_addr_get_prefixlen(nl_addr);
+ lif->l3_mode = 1;
+ lif->port_config_sync = 1;
+ if (memcmp((char *)lif->ipv6_addr, addr_null, 16) == 0)
+ {
+ update_if_ipmac_on_standby(lif, 6);
+ update_vlan_if_mac_on_standby(lif, 2);
+ sync_mac = 1;
+ }
+ iccp_del_self_ip_from_neigh_table (lif, AF_INET);
+ if (lif->is_l3_proto_enabled)
+ {
+ is_v4 = 1;
+ syn_local_neigh_mac_info_to_peer(lif, sync_add, is_v4, is_v6, sync_mac, 1, 0, 4);
+ }
+ ICCPD_LOG_NOTICE(__FUNCTION__, " ifname %s index %d address %s l3_proto %d\n",
+ lif->name, lif->ifindex, show_ip_str(lif->ipv4_addr), lif->is_l3_proto_enabled);
+ }
+ else if (rtnl_addr_get_family(addr) == AF_INET6)
+ {
+ if (memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "FE80", 4) == 0
+ || memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "fe80", 4) == 0) {
+
+ memcpy((char *)lif->ipv6_ll_addr, nl_addr_get_binary_addr(nl_addr), 16);
+ lif->ll_prefixlen_v6 = nl_addr_get_prefixlen(nl_addr);
+ ICCPD_LOG_NOTICE(__FUNCTION__, " ifname %s index %d address %s l3_proto %d, prefix_len %d\n",
+ lif->name, lif->ifindex, show_ipv6_str((char *)lif->ipv6_ll_addr), lif->is_l3_proto_enabled, lif->ll_prefixlen_v6);
+ return;
+ }
+
+ if (memcmp((char *)lif->ipv6_addr, addr_null, 16) != 0) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Ignore Multiple IP Add on ifname %s index %d present address %s l3_proto %d\n",
+ lif->name, lif->ifindex, show_ipv6_str((char *)lif->ipv6_addr), lif->is_l3_proto_enabled);
+ return;
+ }
+
+ memcpy((char *)lif->ipv6_addr, nl_addr_get_binary_addr(nl_addr), 16);
+ lif->prefixlen_v6 = nl_addr_get_prefixlen(nl_addr);
+ lif->l3_mode = 1;
+ lif->port_config_sync = 1;
+ if (lif->ipv4_addr == 0)
+ {
+ update_if_ipmac_on_standby(lif, 7);
+ update_vlan_if_mac_on_standby(lif, 3);
+ sync_mac = 1;
+ }
+ iccp_del_self_ip_from_neigh_table (lif, AF_INET6);
+ if (lif->is_l3_proto_enabled)
+ {
+ is_v6 = 1;
+ syn_local_neigh_mac_info_to_peer(lif, sync_add, is_v4, is_v6, sync_mac, 1, 0, 6);
+ }
+ ICCPD_LOG_NOTICE(__FUNCTION__, " ifname %s index %d address %s l3_proto %d\n",
+ lif->name, lif->ifindex, show_ipv6_str((char *)lif->ipv6_addr), lif->is_l3_proto_enabled);
+ }
+
+ return;
+}
+
+void iccp_event_handler_obj_input_deladdr(struct nl_object *obj, void *arg)
+{
+ struct rtnl_addr *addr;
+ struct nl_addr *nl_addr;
+ struct LocalInterface *lif;
+ uint32_t ifindex;
+ char addr_null[16] = { 0 };
+ int sync_add = 0, is_v4 = 0, is_v6 = 0, sync_mac = 0;
+
+ uint32_t ipv4_addr = 0;
+ uint32_t ipv6_addr[4];
+
+ addr = (struct rtnl_addr *)obj;
+
+ ifindex = rtnl_addr_get_ifindex(addr);
+ nl_addr = rtnl_addr_get_local(addr);
+
+ if (!(lif = local_if_find_by_ifindex(ifindex)))
+ return;
+
+ if (rtnl_addr_get_family(addr) == AF_INET)
+ {
+ ipv4_addr = *(uint32_t *) nl_addr_get_binary_addr(nl_addr);
+
+ if (lif->ipv4_addr != ipv4_addr) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Received address DEL ip %s", show_ip_str(ipv4_addr));
+ ICCPD_LOG_NOTICE(__FUNCTION__, "IP Mismatch. Ignore DEL on ifname %s index %d present address %s l3_proto %d\n",
+ lif->name, lif->ifindex, show_ip_str(lif->ipv4_addr), lif->is_l3_proto_enabled);
+ return;
+ }
+
+ ICCPD_LOG_NOTICE(__FUNCTION__, "l3_proto %d, ifname %s index %d is_vrf %d address %s\n",
+ lif->is_l3_proto_enabled, lif->name, lif->ifindex, lif->master_ifindex, show_ip_str(lif->ipv4_addr));
+ if (memcmp((char *)lif->ipv6_addr, addr_null, 16) == 0)
+ {
+ sync_mac = 1;
+ if (lif->master_ifindex == 0) {
+ recover_vlan_if_mac_on_standby(lif, 2, NULL);
+ }
+ }
+
+ if (lif->is_l3_proto_enabled)
+ {
+ is_v4 = 1;
+ syn_local_neigh_mac_info_to_peer(lif, sync_add, is_v4, is_v6, sync_mac, 0, 0, 7);
+ }
+ lif->ipv4_addr = 0;
+ lif->prefixlen = 0;
+ }
+ else if (rtnl_addr_get_family(addr) == AF_INET6)
+ {
+ if (memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "FE80", 4) == 0
+ || memcmp(show_ipv6_str((char *)nl_addr_get_binary_addr(nl_addr)), "fe80", 4) == 0) {
+
+ ICCPD_LOG_NOTICE(__FUNCTION__, "l3_proto %d, ifname %s index %d is_vrf %d address %s\n",
+ lif->is_l3_proto_enabled, lif->name, lif->ifindex, lif->master_ifindex, show_ipv6_str((char *)lif->ipv6_ll_addr));
+
+ memset((char *)lif->ipv6_ll_addr, 0, 16);
+ lif->ll_prefixlen_v6 = 0;
+ return;
+ }
+
+ memcpy((char *)ipv6_addr, nl_addr_get_binary_addr(nl_addr), 16);
+
+ if (memcmp((char *)lif->ipv6_addr, ipv6_addr, 16) != 0)
+ {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Received address DEL for ip %s", show_ipv6_str((char *)ipv6_addr));
+ ICCPD_LOG_NOTICE(__FUNCTION__, "IP Mismatch. Ignore DEL on ifname %s index %d, l3_proto %d, is_vrf %d present address %s\n",
+ lif->name, lif->ifindex, lif->is_l3_proto_enabled, lif->master_ifindex, show_ipv6_str((char *)lif->ipv6_addr));
+ return;
+ }
+
+ ICCPD_LOG_NOTICE(__FUNCTION__, "l3_proto %d, ifname %s index %d is_vrf %d address %s\n",
+ lif->is_l3_proto_enabled, lif->name, lif->ifindex, lif->master_ifindex, show_ipv6_str((char *)lif->ipv6_addr));
+ if (lif->ipv4_addr == 0)
+ {
+ sync_mac = 1;
+ if (lif->master_ifindex == 0) {
+ recover_vlan_if_mac_on_standby(lif, 3, NULL);
+ }
+ }
+
+ if (lif->is_l3_proto_enabled)
+ {
+ is_v6 = 1;
+ syn_local_neigh_mac_info_to_peer(lif, sync_add, is_v4, is_v6, sync_mac, 0, 0, 9);
+ }
+ memset((char *)lif->ipv6_addr, 0, 16);
+ lif->prefixlen_v6 = 0;
+ }
+
+ if ((lif->ipv4_addr == 0) && (lif->master_ifindex == 0) && (memcmp((char *)lif->ipv6_addr, addr_null, 16) == 0))
+ {
+ lif->l3_mode = 0;
+ memset(lif->l3_mac_addr, 0, ETHER_ADDR_LEN);
+ }
+
+ return;
+}
+
+int iccp_addr_valid_handler(struct nl_msg *msg, void *arg)
+{
+ struct nlmsghdr *nlh = nlmsg_hdr(msg);
+ unsigned int event = 0;
+ if (nlh->nlmsg_type != RTM_NEWADDR)
+ return 0;
+
+ if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newaddr, &event) < 0)
+ ICCPD_LOG_ERR(__FUNCTION__, "Unknown message type.");
+
+ return 0;
+}
+
int iccp_sys_local_if_list_get_addr()
{
struct System *sys = NULL;
@@ -1178,12 +1539,16 @@ static int iccp_route_event_handler(struct nl_msg *msg, void *arg)
struct nlmsghdr *nlh = nlmsg_hdr(msg);
unsigned int event = 1;
+ /* Update netlink message counters */
+ system_update_netlink_counters(nlh->nlmsg_type, nlh);
+
switch (nlh->nlmsg_type)
{
case RTM_NEWLINK:
if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newlink, &event) < 0)
ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_NEWLINK)");
- iccp_parse_if_vlan_info_from_netlink(nlh);
+ //vlan membership changes are handled through state db updates
+ //iccp_parse_if_vlan_info_from_netlink(nlh);
break;
case RTM_DELLINK:
@@ -1198,12 +1563,13 @@ static int iccp_route_event_handler(struct nl_msg *msg, void *arg)
case RTM_NEWADDR:
if (nl_msg_parse(msg, &iccp_event_handler_obj_input_newaddr, NULL) < 0)
- ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_NEWADDR).");
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type.");
break;
case RTM_DELADDR:
if (nl_msg_parse(msg, &iccp_event_handler_obj_input_deladdr, NULL) < 0)
- ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type(RTM_DELADDR).");
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Unknown message type.");
break;
+
default:
return NL_OK;
}
@@ -1314,7 +1680,9 @@ int iccp_system_init_netlink_socket()
if (err)
goto err_route_sock_connect;
- err = nl_socket_set_buffer_size(sys->route_sock, 98304, 0);
+ /* Set the same buffer size as done in SwSS common*/
+ //err = nl_socket_set_buffer_size(sys->route_sock, 98304, 0);
+ err = nl_socket_set_buffer_size(sys->route_sock, NETLINK_SOCKET_BUFFER_SIZE, 0);
if (err)
{
ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink route event sock.");
@@ -1332,7 +1700,9 @@ int iccp_system_init_netlink_socket()
goto err_route_event_sock_connect;
}
- err = nl_socket_set_buffer_size(sys->route_event_sock, 983040, 0);
+ /* Set the same buffer size as done in SwSS common*/
+ //err = nl_socket_set_buffer_size(sys->route_event_sock, 98304, 0);
+ err = nl_socket_set_buffer_size(sys->route_event_sock, NETLINK_SOCKET_BUFFER_SIZE, 0);
if (err)
{
ICCPD_LOG_ERR(__FUNCTION__, "Failed to set buffer size of netlink route event sock.");
@@ -1387,7 +1757,7 @@ int iccp_system_init_netlink_socket()
err = nl_socket_add_membership(sys->route_event_sock, RTNLGRP_IPV4_IFADDR);
if (err < 0)
{
- ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership.");
+ ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership.");
goto err_return;
}
err = nl_socket_add_membership(sys->route_event_sock, RTNLGRP_IPV6_IFADDR);
@@ -1396,7 +1766,8 @@ int iccp_system_init_netlink_socket()
ICCPD_LOG_ERR(__FUNCTION__, "Failed to add netlink membership.");
goto err_return;
}
- /* receive arp packet socket */
+
+ /*receive arp packet socket*/
sys->arp_receive_fd = socket(PF_PACKET, SOCK_DGRAM, 0);
if (sys->arp_receive_fd < 0)
{
@@ -1418,37 +1789,52 @@ int iccp_system_init_netlink_socket()
}
}
+ /* receive ipv6 packet socket */
+ //sys->ndisc_receive_fd = socket(PF_PACKET, SOCK_DGRAM, 0);
sys->ndisc_receive_fd = iccp_make_nd_socket();
-
if (sys->ndisc_receive_fd < 0)
{
+ // ICCPD_LOG_ERR(__FUNCTION__, "socket error ");
goto err_return;
}
+ if (0)
+ {
+ struct sockaddr_ll sll;
+ memset(&sll, 0, sizeof(sll));
+ sll.sll_family = AF_PACKET;
+ sll.sll_protocol = htons(ETH_P_IPV6);
+ sll.sll_ifindex = 0;
+ if (bind(sys->ndisc_receive_fd, (struct sockaddr *)&sll, sizeof(sll)) < 0)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "socket bind error");
+ goto err_return;
+ }
+ }
goto succes_return;
- err_return:
+err_return:
- err_route_event_sock_connect:
+err_route_event_sock_connect:
nl_socket_free(sys->route_event_sock);
- err_route_sock_alloc:
- err_route_sock_connect:
+err_route_sock_alloc:
+err_route_sock_connect:
nl_socket_free(sys->route_sock);
- err_route_event_sock_alloc:
- err_genric_event_sock_connect:
+err_route_event_sock_alloc:
+err_genric_event_sock_connect:
nl_socket_free(sys->genric_event_sock);
- err_genric_event_sock_alloc:
- err_genric_sock_connect:
+err_genric_event_sock_alloc:
+err_genric_sock_connect:
nl_socket_free(sys->genric_sock);
return err;
- err_genric_sock_alloc:
+err_genric_sock_alloc:
- succes_return:
+succes_return:
return 0;
}
@@ -1510,6 +1896,7 @@ static int iccp_receive_arp_packet_handler(struct System *sys)
unsigned int ifindex;
unsigned int addr;
uint8_t mac_addr[ETHER_ADDR_LEN];
+ struct CSM* csm = NULL;
n = recvfrom(sys->arp_receive_fd, buf, sizeof(buf), MSG_DONTWAIT,
(struct sockaddr*)&sll, &sll_len);
@@ -1529,6 +1916,11 @@ static int iccp_receive_arp_packet_handler(struct System *sys)
sizeof(*a) + 2 * 4 + 2 * a->ar_hln > n)
return 0;
+ /*Check if mclag configured*/
+ csm = system_get_first_csm();
+ if (!csm)
+ return 0;
+
ifindex = sll.sll_ifindex;
memcpy(mac_addr, (char*)(a + 1), ETHER_ADDR_LEN);
memcpy(&addr, (char*)(a + 1) + a->ar_hln, 4);
@@ -1554,6 +1946,7 @@ int iccp_receive_ndisc_packet_handler(struct System *sys)
int8_t *opt = NULL;
int opt_len = 0, l = 0;
int len;
+ struct CSM* csm = NULL;
memset(mac_addr, 0, ETHER_ADDR_LEN);
@@ -1571,7 +1964,7 @@ int iccp_receive_ndisc_packet_handler(struct System *sys)
if (len < 0)
{
- ICCPD_LOG_WARN(__FUNCTION__, "Ndisc recvmsg error!");
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ndisc recvmsg error!");
return MCLAG_ERROR;
}
@@ -1590,6 +1983,11 @@ int iccp_receive_ndisc_packet_handler(struct System *sys)
ndmsg = (struct nd_msg *)buf;
+ /*Check if mclag configured*/
+ csm = system_get_first_csm();
+ if (!csm)
+ return 0;
+
if (ndmsg->icmph.icmp6_type != NDISC_NEIGHBOUR_ADVERTISEMENT)
return 0;
@@ -1624,8 +2022,6 @@ int iccp_receive_ndisc_packet_handler(struct System *sys)
}
}
- /* ICCPD_LOG_DEBUG(__FUNCTION__, "Recv na pkt(%s,%02X:%02X:%02X:%02X:%02X:%02X)!", show_ipv6_str((char *)&target), mac_addr[0], mac_addr[1],
- mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); */
do_ndisc_update_from_reply_packet(ifindex, (char *)&target, mac_addr);
return 0;
@@ -1672,7 +2068,8 @@ static int iccp_netlink_route_sock_event_handler(struct System *sys)
if (ret)
{
sys->need_sync_netlink_again = 1;
- ICCPD_LOG_DEBUG(__FUNCTION__, "fd %d recvmsg error ret = %d errno = %d ", nl_socket_get_fd(sys->route_event_sock), ret, errno);
+ ICCPD_LOG_NOTICE(__FUNCTION__, "fd %d recvmsg error ret = %d errno = %d ", nl_socket_get_fd(sys->route_event_sock), ret, errno);
+ SYSTEM_INCR_NETLINK_RX_ERROR();
}
/*get netlink info again when error happens */
if (ret == 0 && sys->need_sync_netlink_again == 1)
@@ -1684,7 +2081,6 @@ static int iccp_netlink_route_sock_event_handler(struct System *sys)
}
extern int iccp_get_receive_fdb_sock_fd(struct System *sys);
-extern int iccp_receive_fdb_handler_from_syncd(struct System *sys);
/* cond HIDDEN_SYMBOLS */
struct iccp_eventfd
@@ -1710,11 +2106,11 @@ static const struct iccp_eventfd iccp_eventfds[] = {
{
.get_fd = iccp_get_receive_arp_packet_sock_fd,
.event_handler = iccp_receive_arp_packet_handler,
- },
+ },
{
- .get_fd = iccp_get_receive_ndisc_packet_sock_fd,
- .event_handler = iccp_receive_ndisc_packet_handler,
- }
+ .get_fd = iccp_get_receive_ndisc_packet_sock_fd,
+ .event_handler = iccp_receive_ndisc_packet_handler,
+ }
};
/* \cond HIDDEN_SYMBOLS */
@@ -1759,7 +2155,7 @@ int iccp_init_netlink_event_fd(struct System *sys)
return 0;
- close_efd:
+close_efd:
close(efd);
return err;
@@ -1781,6 +2177,7 @@ int iccp_handle_events(struct System * sys)
int i;
int err;
int max_nfds;
+ struct mLACPHeartbeatTLV dummy_tlv;
max_nfds = ICCP_EVENT_FDS_COUNT + sys->readfd_count;
@@ -1817,8 +2214,7 @@ int iccp_handle_events(struct System * sys)
if (events[i].data.fd == sys->sync_fd)
{
- iccp_receive_fdb_handler_from_syncd(sys);
-
+ iccp_mclagsyncd_msg_handler(sys);
continue;
}
@@ -1835,7 +2231,11 @@ int iccp_handle_events(struct System * sys)
{
if (csm->sock_fd == events[i].data.fd )
{
- scheduler_csm_read_callback(csm);
+ if (scheduler_csm_read_callback(csm) != MCLAG_ERROR)
+ {
+ //consider any msg from peer as heartbeat update, this will be in scenarios of scaled msg sync b/w peers
+ mlacp_fsm_update_heartbeat(csm, &dummy_tlv);
+ }
break;
}
}
@@ -1845,3 +2245,248 @@ int iccp_handle_events(struct System * sys)
return 0;
}
+void update_vlan_if_mac_on_standby(struct LocalInterface* lif_vlan, int dir)
+{
+ struct CSM* csm = NULL;
+ struct System* sys = NULL;
+ struct LocalInterface *lif_po = NULL;
+ struct LocalInterface *lif_peer = NULL;
+ uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ char macaddr[64];
+ uint8_t system_mac[ETHER_ADDR_LEN];
+ int ret = 0;
+ struct VLAN_ID vlan_key = { 0 };
+ struct VLAN_ID *vlan = NULL;
+ int vid = 0, vlan_member = 0;
+
+ if (lif_vlan->type != IF_T_VLAN)
+ return;
+
+ if ((sys = system_get_instance()) == NULL)
+ return;
+
+ sscanf (lif_vlan->name, "Vlan%d", &vid);
+
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vid;
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, " ifname %s vid %d, l3_proto %d, dir %d\n",
+ lif_vlan->name, vid, lif_vlan->is_l3_proto_enabled, dir);
+ LIST_FOREACH(csm, &(sys->csm_list), next)
+ {
+ if (csm->peer_link_if) {
+ lif_peer = csm->peer_link_if;
+ vlan = RB_FIND(vlan_rb_tree, &(lif_peer->vlan_tree), &vlan_key);
+ if (vlan && vlan->vlan_itf)
+ {
+ vlan_member = 1;
+ break;
+ }
+ }
+
+ LIST_FOREACH(lif_po, &(MLACP(csm).lif_list), mlacp_next)
+ {
+ if (lif_po->type == IF_T_PORT_CHANNEL)
+ {
+ vlan = RB_FIND(vlan_rb_tree, &(lif_po->vlan_tree), &vlan_key);
+ if (vlan)
+ {
+ vlan_member = 1;
+ break;
+ }
+ }
+ }
+ if (vlan_member)
+ {
+ break;
+ }
+ }
+
+ if (!csm) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, " csm not initialised.");
+ return;
+ }
+
+ if (csm->role_type != STP_ROLE_STANDBY)
+ return;
+
+ memset(macaddr, 0, 64);
+ memset(system_mac, 0, ETHER_ADDR_LEN);
+ if (lif_vlan->is_l3_proto_enabled == false)
+ {
+ if (memcmp(MLACP(csm).remote_system.system_id, null_mac, ETHER_ADDR_LEN) == 0) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, " remote system_id not initialised.");
+ return;
+ }
+ memcpy(system_mac, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN);
+ SET_MAC_STR(macaddr, MLACP(csm).remote_system.system_id);
+ } else {
+ if (memcmp(MLACP(csm).system_id, null_mac, ETHER_ADDR_LEN) == 0){
+ ICCPD_LOG_NOTICE(__FUNCTION__, " system_id not initialised.");
+ return;
+ }
+ memcpy(system_mac, MLACP(csm).system_id, ETHER_ADDR_LEN);
+ SET_MAC_STR(macaddr, MLACP(csm).system_id);
+ }
+
+ if (memcmp(system_mac, null_mac, ETHER_ADDR_LEN) == 0) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, " system_id not present.");
+ return;
+ }
+
+ ICCPD_LOG_DEBUG(__FUNCTION__,
+ "%s Change the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X], dir %d",
+ (csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active",
+ lif_vlan->name, lif_vlan->mac_addr[0], lif_vlan->mac_addr[1], lif_vlan->mac_addr[2],
+ lif_vlan->mac_addr[3], lif_vlan->mac_addr[4], lif_vlan->mac_addr[5],
+ system_mac[0], system_mac[1], system_mac[2], system_mac[3], system_mac[4], system_mac[5], dir);
+
+ if (local_if_is_l3_mode(lif_vlan))
+ {
+ if (memcmp(lif_vlan->l3_mac_addr, system_mac, ETHER_ADDR_LEN) != 0)
+ {
+ ret = iccp_netlink_if_hwaddr_set(lif_vlan->ifindex, system_mac, ETHER_ADDR_LEN);
+ if (ret != 0)
+ {
+ ICCPD_LOG_NOTICE(__FUNCTION__, " set %s mac error, ret = %d, dir %d", lif_vlan->name, ret, dir);
+ }
+
+ /* Refresh link local address according the new MAC */
+ iccp_netlink_if_shutdown_set(lif_vlan->ifindex);
+ iccp_netlink_if_startup_set(lif_vlan->ifindex);
+
+ iccp_set_interface_ipadd_mac(lif_vlan, macaddr);
+ memcpy(lif_vlan->l3_mac_addr, system_mac, ETHER_ADDR_LEN);
+ if (lif_vlan->is_l3_proto_enabled == false) {
+ set_peer_mac_in_kernel (macaddr, vid, 1);
+ }
+ } else {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "%s mac alreay updated, dir %d", lif_vlan->name, dir);
+ }
+ } else {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "%s not L3 interface, dir %d", lif_vlan->name, dir);
+ }
+
+ return;
+}
+
+void recover_vlan_if_mac_on_standby(struct LocalInterface* lif_vlan, int dir, uint8_t *remote_system_mac)
+{
+ struct CSM *csm = NULL;
+ struct System* sys = NULL;
+ uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ char macaddr[64];
+ char remote_macaddr[64];
+ uint8_t system_mac[ETHER_ADDR_LEN];
+ int ret = 0;
+ int vid = 0;
+
+ if (lif_vlan->type != IF_T_VLAN)
+ return;
+
+ if ((sys = system_get_instance()) == NULL)
+ return;
+
+ LIST_FOREACH(csm, &(sys->csm_list), next)
+ {
+ if (csm->peer_link_if) {
+ break;
+ }
+ }
+
+ if (csm == NULL) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, " csm not initialised.");
+ return;
+ }
+
+ if (csm->role_type != STP_ROLE_STANDBY)
+ return;
+
+ sscanf (lif_vlan->name, "Vlan%d", &vid);
+
+ memset(macaddr, 0, 64);
+ memset(remote_macaddr, 0, 64);
+ memset(system_mac, 0, ETHER_ADDR_LEN);
+ ICCPD_LOG_DEBUG(__FUNCTION__, " ifname %s, l3_proto %d, dir %d\n",
+ lif_vlan->name, lif_vlan->is_l3_proto_enabled, dir);
+ if (lif_vlan->is_l3_proto_enabled == true)
+ {
+ if (memcmp(MLACP(csm).remote_system.system_id, null_mac, ETHER_ADDR_LEN) == 0) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, " remote system_id not initialised.");
+ return;
+ }
+ memcpy(system_mac, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN);
+ SET_MAC_STR(macaddr, MLACP(csm).remote_system.system_id);
+ } else {
+ if (memcmp(MLACP(csm).system_id, null_mac, ETHER_ADDR_LEN) == 0) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, " system_id not initialised.");
+ return;
+ }
+ memcpy(system_mac, MLACP(csm).system_id, ETHER_ADDR_LEN);
+ SET_MAC_STR(macaddr, MLACP(csm).system_id);
+ }
+
+ if (memcmp(system_mac, null_mac, ETHER_ADDR_LEN) == 0) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, " system_id not present.");
+ return;
+ }
+
+ ICCPD_LOG_DEBUG(__FUNCTION__,
+ "%s Change the system-id of %s from [%02X:%02X:%02X:%02X:%02X:%02X] to [%02X:%02X:%02X:%02X:%02X:%02X], dir %d",
+ (csm->role_type == STP_ROLE_STANDBY) ? "Standby" : "Active", lif_vlan->name,
+ lif_vlan->l3_mac_addr[0], lif_vlan->l3_mac_addr[1], lif_vlan->l3_mac_addr[2],
+ lif_vlan->l3_mac_addr[3], lif_vlan->l3_mac_addr[4], lif_vlan->l3_mac_addr[5],
+ system_mac[0], system_mac[1], system_mac[2], system_mac[3], system_mac[4], system_mac[5], dir);
+
+ if (local_if_is_l3_mode(lif_vlan))
+ {
+ if (memcmp(lif_vlan->l3_mac_addr, system_mac, ETHER_ADDR_LEN) != 0)
+ {
+ ret = iccp_netlink_if_hwaddr_set(lif_vlan->ifindex, system_mac, ETHER_ADDR_LEN);
+ if (ret != 0)
+ {
+ ICCPD_LOG_NOTICE(__FUNCTION__, " set %s mac error, ret = %d, dir %d", lif_vlan->name, ret, dir);
+ }
+
+ /* Refresh link local address according the new MAC */
+ iccp_netlink_if_shutdown_set(lif_vlan->ifindex);
+ iccp_netlink_if_startup_set(lif_vlan->ifindex);
+
+ iccp_set_interface_ipadd_mac(lif_vlan, macaddr);
+ memcpy(lif_vlan->l3_mac_addr, system_mac, ETHER_ADDR_LEN);
+
+ if (memcmp(MLACP(csm).remote_system.system_id, null_mac, ETHER_ADDR_LEN) != 0) {
+ SET_MAC_STR(remote_macaddr, MLACP(csm).remote_system.system_id);
+ set_peer_mac_in_kernel (remote_macaddr, vid, 0);
+ } else if ((dir == 4) && remote_system_mac) {
+ if (memcmp(remote_system_mac, null_mac, ETHER_ADDR_LEN) != 0) {
+ SET_MAC_STR(remote_macaddr, remote_system_mac);
+ set_peer_mac_in_kernel (remote_macaddr, vid, 0);
+ }
+ }
+ }
+ } else {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "%s not L3 interface, dir %d", lif_vlan->name, dir);
+ }
+
+ return;
+}
+
+void update_vlan_if_mac_on_iccp_up(struct LocalInterface* lif_peer, int is_up, uint8_t *remote_system_mac)
+{
+ struct VLAN_ID *vlan_id_list = NULL;
+
+ ICCPD_LOG_NOTICE(__FUNCTION__, " lif name %s, up %d", lif_peer->name, is_up);
+ RB_FOREACH(vlan_id_list, vlan_rb_tree, &(lif_peer->vlan_tree))
+ {
+ if (!vlan_id_list->vlan_itf)
+ continue;
+
+ if (is_up) {
+ update_vlan_if_mac_on_standby(vlan_id_list->vlan_itf, 4);
+ } else {
+ recover_vlan_if_mac_on_standby(vlan_id_list->vlan_itf, 4, remote_system_mac);
+ }
+
+ }
+}
diff --git a/src/iccpd/src/logger.c b/src/iccpd/src/logger.c
index 2c17610f7afc..3ed9f79bfea5 100644
--- a/src/iccpd/src/logger.c
+++ b/src/iccpd/src/logger.c
@@ -35,7 +35,7 @@ static uint32_t _iccpd_log_level_map[] =
LOG_WARNING,
LOG_NOTICE,
LOG_INFO,
- LOG_DEBUG,
+ LOG_DEBUG
};
char* log_level_to_string(int level)
@@ -100,7 +100,7 @@ void log_finalize()
/*do nothing*/
}
-void write_log(const int level, const char* tag, const char* format, ...)
+void write_log(int level, const char* tag, const char* format, ...)
{
struct LoggerConfig* config = logger_get_configuration();
char buf[LOGBUF_SIZE];
diff --git a/src/iccpd/src/mclagdctl/mclagdctl.c b/src/iccpd/src/mclagdctl/mclagdctl.c
index 630e333be6ed..2eccd944636a 100644
--- a/src/iccpd/src/mclagdctl/mclagdctl.c
+++ b/src/iccpd/src/mclagdctl/mclagdctl.c
@@ -29,7 +29,11 @@
#include
#include
#include
+#include
+#include
#include "mclagdctl.h"
+#include "../../include/mlacp_fsm.h"
+#include "../../include/system.h"
static int mclagdctl_sock_fd = -1;
char *mclagdctl_sock_path = "/var/run/iccpd/mclagdctl.sock";
@@ -38,11 +42,25 @@ char *mclagdctl_sock_path = "/var/run/iccpd/mclagdctl.sock";
Already implemented command:
mclagdctl -i dump state
mclagdctl -i dump arp
+ mclagdctl -i dump nd
mclagdctl -i dump mac
+ mclagdctl -i dump unique_ip
mclagdctl -i dump portlist local
mclagdctl -i dump portlist peer
*/
+#define ETHER_ADDR_LEN 6
+char mac_print_str[18];
+
+char *mac_addr_to_str(uint8_t* mac_addr)
+{
+ memset(mac_print_str, 0, sizeof(mac_print_str));
+ snprintf(mac_print_str, sizeof(mac_print_str), "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
+
+ return mac_print_str;
+}
+
static struct command_type command_types[] =
{
{
@@ -68,13 +86,13 @@ static struct command_type command_types[] =
.parse_msg = mclagdctl_parse_dump_arp,
},
{
- .id = ID_CMDTYPE_D_A,
- .parent_id = ID_CMDTYPE_D,
- .info_type = INFO_TYPE_DUMP_NDISC,
- .name = "nd",
- .enca_msg = mclagdctl_enca_dump_ndisc,
- .parse_msg = mclagdctl_parse_dump_ndisc,
- },
+ .id = ID_CMDTYPE_D_A,
+ .parent_id = ID_CMDTYPE_D,
+ .info_type = INFO_TYPE_DUMP_NDISC,
+ .name = "nd",
+ .enca_msg = mclagdctl_enca_dump_ndisc,
+ .parse_msg = mclagdctl_parse_dump_ndisc,
+ },
{
.id = ID_CMDTYPE_D_A,
.parent_id = ID_CMDTYPE_D,
@@ -83,6 +101,14 @@ static struct command_type command_types[] =
.enca_msg = mclagdctl_enca_dump_mac,
.parse_msg = mclagdctl_parse_dump_mac,
},
+ {
+ .id = ID_CMDTYPE_D_A,
+ .parent_id = ID_CMDTYPE_D,
+ .info_type = INFO_TYPE_DUMP_UNIQUE_IP,
+ .name = "unique_ip",
+ .enca_msg = mclagdctl_enca_dump_unique_ip,
+ .parse_msg = mclagdctl_parse_dump_unique_ip,
+ },
{
.id = ID_CMDTYPE_D_P,
.parent_id = ID_CMDTYPE_D,
@@ -104,6 +130,19 @@ static struct command_type command_types[] =
.enca_msg = mclagdctl_enca_dump_peer_portlist,
.parse_msg = mclagdctl_parse_dump_peer_portlist,
},
+ {
+ .id = ID_CMDTYPE_D_D,
+ .parent_id = ID_CMDTYPE_D,
+ .name = "debug",
+ },
+ {
+ .id = ID_CMDTYPE_D_D_C,
+ .parent_id = ID_CMDTYPE_D_D,
+ .info_type = INFO_TYPE_DUMP_DBG_COUNTERS,
+ .name = "counters",
+ .enca_msg = mclagdctl_enca_dump_dbg_counters,
+ .parse_msg = mclagdctl_parse_dump_dbg_counters,
+ },
{
.id = ID_CMDTYPE_C,
.name = "config",
@@ -117,7 +156,7 @@ static struct command_type command_types[] =
.name = "loglevel",
.enca_msg = mclagdctl_enca_config_loglevel,
.parse_msg = mclagdctl_parse_config_loglevel,
- },
+ },
};
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -250,8 +289,18 @@ int mclagdctl_parse_dump_state(char *msg, int data_len)
{
state_info = (struct mclagd_state*)(msg + len * count);
- fprintf(stdout, "%s: %s\n", "The MCLAG's keepalive is", state_info->keepalive ? "OK" : "ERROR");
+ if (inet_addr(state_info->local_ip) < inet_addr(state_info->peer_ip))
+ {
+ state_info->role = 1;
+ }
+ else
+ {
+ state_info->role = 2;
+ }
+ fprintf(stdout, "%s: %s\n", "The MCLAG's keepalive is", state_info->keepalive ? "OK" : "ERROR");
+ fprintf(stdout, "%s: %s\n", "MCLAG info sync is",
+ state_info->info_sync_done ? "completed" : "incomplete");
if (state_info->mclag_id <= 0)
fprintf(stdout, "%s: %s\n", "Domain id", "Unknown");
else
@@ -260,6 +309,8 @@ int mclagdctl_parse_dump_state(char *msg, int data_len)
fprintf(stdout, "%s: %s\n", "Local Ip", state_info->local_ip);
fprintf(stdout, "%s: %s\n", "Peer Ip", state_info->peer_ip);
fprintf(stdout, "%s: %s\n", "Peer Link Interface", state_info->peer_link_if);
+ fprintf(stdout, "%s: %d\n", "Keepalive time", state_info->keepalive_time);
+ fprintf(stdout, "%s: %d\n", "sesssion Timeout ", state_info->session_timeout);
fprintf(stdout, "%s: %02x:%02x:%02x:%02x:%02x:%02x \n",
"Peer Link Mac",
@@ -267,9 +318,10 @@ int mclagdctl_parse_dump_state(char *msg, int data_len)
state_info->peer_link_mac[2], state_info->peer_link_mac[3],
state_info->peer_link_mac[4], state_info->peer_link_mac[5]);
- if (state_info->role == 0)
+ /*if (state_info->role == 0)
fprintf(stdout, "%s: %s\n", "Role", "None");
- else if (state_info->role == 1)
+ */
+ if (state_info->role == 1)
fprintf(stdout, "%s: %s\n", "Role", "Active");
else if (state_info->role == 2)
fprintf(stdout, "%s: %s\n", "Role", "Standby");
@@ -328,6 +380,7 @@ int mclagdctl_parse_dump_arp(char *msg, int data_len)
fprintf(stdout, "%-20s", "IP");
fprintf(stdout, "%-20s", "MAC");
fprintf(stdout, "%-20s", "DEV");
+ fprintf(stdout, "%s", "Flag");
fprintf(stdout, "\n");
len = sizeof(struct mclagd_arp_msg);
@@ -344,6 +397,13 @@ int mclagdctl_parse_dump_arp(char *msg, int data_len)
arp_info->mac_addr[4], arp_info->mac_addr[5]);
fprintf(stdout, " ");
fprintf(stdout, "%-20s", arp_info->ifname);
+ if (arp_info->learn_flag == NEIGH_REMOTE) {
+ fprintf(stdout, "%s", "R");
+ } else if (arp_info->learn_flag == NEIGH_LOCAL) {
+ fprintf(stdout, "%s", "L");
+ } else {
+ fprintf(stdout, "%s", "-");
+ }
fprintf(stdout, "\n");
}
@@ -360,6 +420,7 @@ int mclagdctl_parse_dump_ndisc(char *msg, int data_len)
fprintf(stdout, "%-52s", "IPv6");
fprintf(stdout, "%-20s", "MAC");
fprintf(stdout, "%-20s", "DEV");
+ fprintf(stdout, "%s", "Flag");
fprintf(stdout, "\n");
len = sizeof(struct mclagd_ndisc_msg);
@@ -372,10 +433,16 @@ int mclagdctl_parse_dump_ndisc(char *msg, int data_len)
fprintf(stdout, "%-52s", ndisc_info->ipv6_addr);
fprintf(stdout, "%02x:%02x:%02x:%02x:%02x:%02x",
ndisc_info->mac_addr[0], ndisc_info->mac_addr[1],
- ndisc_info->mac_addr[2], ndisc_info->mac_addr[3],
- ndisc_info->mac_addr[4], ndisc_info->mac_addr[5]);
+ ndisc_info->mac_addr[2], ndisc_info->mac_addr[3], ndisc_info->mac_addr[4], ndisc_info->mac_addr[5]);
fprintf(stdout, " ");
fprintf(stdout, "%-20s", ndisc_info->ifname);
+ if (ndisc_info->learn_flag == NEIGH_REMOTE) {
+ fprintf(stdout, "%s", "R");
+ } else if (ndisc_info->learn_flag == NEIGH_LOCAL) {
+ fprintf(stdout, "%s", "L");
+ } else {
+ fprintf(stdout, "%s", "-");
+ }
fprintf(stdout, "\n");
}
@@ -430,7 +497,8 @@ int mclagdctl_parse_dump_mac(char *msg, int data_len)
else
fprintf(stdout, "%-5s", "D");
- fprintf(stdout, "%-20s", mac_info->mac_str);
+ fprintf(stdout, "%-20s", mac_addr_to_str(mac_info->mac_addr));
+
fprintf(stdout, "%-5d", mac_info->vid);
fprintf(stdout, "%-20s", mac_info->ifname);
fprintf(stdout, "%-20s", mac_info->origin_ifname);
@@ -502,10 +570,11 @@ int mclagdctl_parse_dump_local_portlist(char *msg, int data_len)
fprintf(stdout, "%s: %s\n", "IsL3Interface", lif_info->l3_mode ? "Yes" : "No");
/*fprintf(stdout, "%s: %s\n", "IsPeerlink", lif_info->is_peer_link ? "Yes" : "No");*/
fprintf(stdout, "%s: %s\n", "MemberPorts", lif_info->portchannel_member_buf);
- /*fprintf(stdout,"%s: %d\n" ,"PortchannelId", lif_info->po_id);
- fprintf(stdout,"%s: %d\n" ,"PortchannelIsUp", lif_info->po_active);
- fprintf(stdout,"%s: %s\n", "MlacpState", lif_info->mlacp_state);*/
+ /*fprintf(stdout,"%s: %d\n" ,"PortchannelId", lif_info->po_id);*/
+ fprintf(stdout,"%s: %d\n" ,"PortchannelIsUp", lif_info->po_active);
+ /*fprintf(stdout,"%s: %s\n", "MlacpState", lif_info->mlacp_state);*/
fprintf(stdout, "%s: %s\n", "IsIsolateWithPeerlink", lif_info->isolate_to_peer_link ? "Yes" : "No");
+ fprintf(stdout,"%s: %s\n" ,"IsTrafficDisable", lif_info->is_traffic_disable ? "Yes":"No");
fprintf(stdout, "%s: %s\n", "VlanList", lif_info->vlanlist);
}
else
@@ -514,6 +583,7 @@ int mclagdctl_parse_dump_local_portlist(char *msg, int data_len)
fprintf(stdout, "%s: %s\n", "Type", lif_info->type);
fprintf(stdout, "%s: %s\n", "PortName", lif_info->name);
fprintf(stdout, "%s: %s\n", "State", lif_info->state);
+ fprintf(stdout, "%s: %s\n", "VlanList", lif_info->vlanlist);
/*fprintf(stdout,"%s: %d\n" ,"PortchannelId", lif_info->po_id);*/
}
@@ -584,6 +654,277 @@ int mclagdctl_parse_dump_peer_portlist(char *msg, int data_len)
return 0;
}
+int mclagdctl_enca_dump_unique_ip(char *msg, int mclag_id, int argc, char **argv)
+{
+ struct mclagdctl_req_hdr req;
+
+ if (mclag_id <= 0)
+ {
+ fprintf(stderr, "Need to specify mclag-id through the parameter i !\n");
+ return MCLAG_ERROR;
+ }
+
+ memset(&req, 0, sizeof(struct mclagdctl_req_hdr));
+ req.info_type = INFO_TYPE_DUMP_UNIQUE_IP;
+ req.mclag_id = mclag_id;
+ memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr));
+
+ return 1;
+}
+
+int mclagdctl_parse_dump_unique_ip(char *msg, int data_len)
+{
+ struct mclagd_unique_ip_if *ip_if_info = NULL;
+ int len = 0;
+ int count = 0;
+ int pos = 0;
+
+ for (pos = 0; pos < 60; ++pos)
+ fprintf(stdout, "-");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "%-20s", "Ifname");
+ fprintf(stdout, "%-5s", "Active");
+ fprintf(stdout, "\n");
+
+ for (pos = 0; pos < 60; ++pos)
+ fprintf(stdout, "-");
+ fprintf(stdout, "\n");
+
+ len = sizeof(struct mclagd_unique_ip_if);
+
+ for (; data_len >= len; data_len -= len, count++)
+ {
+ ip_if_info = (struct mclagd_unique_ip_if*)(msg + len * count);
+
+ fprintf(stdout, "%-20s %-5s\n", ip_if_info->name, ip_if_info->active?"Yes":"No");
+ }
+
+ if (count == 0)
+ {
+ fprintf(stdout, "%s\n", "Unique IP configuration not enabled on any interface");
+ }
+
+ for (pos = 0; pos < 60; ++pos)
+ fprintf(stdout, "-");
+
+ fprintf(stdout, "\n\n");
+ return 0;
+}
+
+/* mclag_id parameter is optional */
+int mclagdctl_enca_dump_dbg_counters(char *msg, int mclag_id, int argc, char **argv)
+{
+ struct mclagdctl_req_hdr req;
+
+ memset(&req, 0, sizeof(struct mclagdctl_req_hdr));
+ req.info_type = INFO_TYPE_DUMP_DBG_COUNTERS;
+ req.mclag_id = mclag_id;
+ memcpy((struct mclagdctl_req_hdr *)msg, &req, sizeof(struct mclagdctl_req_hdr));
+
+ return 1;
+}
+
+static char *mclagdctl_dbg_counter_iccpid2str(ICCP_DBG_CNTR_MSG_e iccp_cntr_id)
+{
+ /* Keep the string to 15 characters.
+ * Update mclagdctl_parse_dump_dbg_counters if increase
+ */
+ switch(iccp_cntr_id)
+ {
+ case ICCP_DBG_CNTR_MSG_SYS_CONFIG:
+ return "SysConfig";
+ case ICCP_DBG_CNTR_MSG_AGGR_CONFIG:
+ return "AggrConfig";
+ case ICCP_DBG_CNTR_MSG_AGGR_STATE:
+ return "AggrState";
+ case ICCP_DBG_CNTR_MSG_MAC_INFO:
+ return "MacInfo";
+ case ICCP_DBG_CNTR_MSG_ARP_INFO:
+ return "ArpInfo";
+ case ICCP_DBG_CNTR_MSG_PORTCHANNEL_INFO:
+ return "PoInfo";
+ case ICCP_DBG_CNTR_MSG_PEER_LINK_INFO:
+ return "PeerLinkInfo";
+ case ICCP_DBG_CNTR_MSG_HEART_BEAT:
+ return "Heartbeat";
+ case ICCP_DBG_CNTR_MSG_NAK:
+ return "Nak";
+ case ICCP_DBG_CNTR_MSG_SYNC_DATA:
+ return "SyncData";
+ case ICCP_DBG_CNTR_MSG_SYNC_REQ:
+ return "SyncReq";
+ case ICCP_DBG_CNTR_MSG_WARM_BOOT:
+ return "Warmboot";
+ case ICCP_DBG_CNTR_MSG_IF_UP_ACK:
+ return "IfUpAck";
+ default:
+ return "Unknown";
+ }
+}
+
+static char *mclagdctl_dbg_counter_syncdtx2str(SYNCD_TX_DBG_CNTR_MSG_e syncdtx_id)
+{
+ /* Keep the string to 20 characters.
+ * Update mclagdctl_parse_dump_dbg_counters if increase
+ */
+ switch(syncdtx_id)
+ {
+ case SYNCD_TX_DBG_CNTR_MSG_PORT_ISOLATE:
+ return "PortIsolation";
+ case SYNCD_TX_DBG_CNTR_MSG_PORT_MAC_LEARN_MODE:
+ return "MacLearnMode";
+ case SYNCD_TX_DBG_CNTR_MSG_FLUSH_FDB:
+ return "FlushFdb";
+ case SYNCD_TX_DBG_CNTR_MSG_SET_IF_MAC:
+ return "SetIfMac";
+ case SYNCD_TX_DBG_CNTR_MSG_SET_FDB:
+ return "SetFdb";
+ case SYNCD_TX_DBG_CNTR_MSG_SET_TRAFFIC_DIST_ENABLE:
+ return "TrafficDistEnable";
+ case SYNCD_TX_DBG_CNTR_MSG_SET_TRAFFIC_DIST_DISABLE:
+ return "TrafficDistDisable";
+ case SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_STATE:
+ return "SetIccpState";
+ case SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_ROLE:
+ return "SetIccpRole";
+ case SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_SYSTEM_ID:
+ return "SetSystemId";
+ case SYNCD_TX_DBG_CNTR_MSG_DEL_ICCP_INFO:
+ return "DelIccpInfo";
+ case SYNCD_TX_DBG_CNTR_MSG_SET_REMOTE_IF_STATE:
+ return "SetRemoteIntfSts";
+ case SYNCD_TX_DBG_CNTR_MSG_DEL_REMOTE_IF_INFO:
+ return "DelRemoteIntf";
+ case SYNCD_TX_DBG_CNTR_MSG_PEER_LINK_ISOLATION:
+ return "PeerLinkIsolation";
+ case SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_PEER_SYSTEM_ID:
+ return "SetPeerSystemId";
+ default:
+ return "Unknown";
+ }
+}
+
+static char *mclagdctl_dbg_counter_syncdrx2str(SYNCD_RX_DBG_CNTR_MSG_e syncdrx_id)
+{
+ /* Keep the string to 20 characters.
+ * Update mclagdctl_parse_dump_dbg_counters if increase
+ */
+ switch(syncdrx_id)
+ {
+ case SYNCD_RX_DBG_CNTR_MSG_MAC:
+ return "FdbChange";
+ case SYNCD_RX_DBG_CNTR_MSG_CFG_MCLAG_DOMAIN:
+ return "CfgMclag";
+ case SYNCD_RX_DBG_CNTR_MSG_CFG_MCLAG_IFACE:
+ return "CfgMclagIface";
+ case SYNCD_RX_DBG_CNTR_MSG_CFG_MCLAG_UNIQUE_IP:
+ return "CfgMclagUniqueIp";
+ case SYNCD_RX_DBG_CNTR_MSG_VLAN_MBR_UPDATES:
+ return "vlanMbrshipChange";
+ default:
+ return "Unknown";
+ }
+}
+
+int mclagdctl_parse_dump_dbg_counters(char *msg, int data_len)
+{
+ mclagd_dbg_counter_info_t *dbg_counter_p;
+ system_dbg_counter_info_t *sys_counter_p;
+ mlacp_dbg_counter_info_t *iccp_counter_p;
+ int i, j;
+
+ dbg_counter_p = (mclagd_dbg_counter_info_t *)msg;
+ sys_counter_p = (system_dbg_counter_info_t *)&dbg_counter_p->system_dbg;
+
+ /* Global counters */
+ fprintf(stdout, "%-20s%u\n", "ICCP session down:",
+ sys_counter_p->session_down_counter);
+ fprintf(stdout, "%-20s%u\n", "Peer link down:",
+ sys_counter_p->peer_link_down_counter);
+ fprintf(stdout, "%-20s%u\n", "Rx invalid msg:",
+ sys_counter_p->rx_peer_invalid_msg_counter);
+ fprintf(stdout, "%-20s%u\n", "Rx sock error(hdr):",
+ sys_counter_p->rx_peer_hdr_read_sock_err_counter);
+ fprintf(stdout, "%-20s%u\n", "Rx zero len(hdr):",
+ sys_counter_p->rx_peer_hdr_read_sock_zero_len_counter);
+ fprintf(stdout, "%-20s%u\n", "Rx sock error(tlv):",
+ sys_counter_p->rx_peer_tlv_read_sock_err_counter);
+ fprintf(stdout, "%-20s%u\n", "Rx zero len(tlv):",
+ sys_counter_p->rx_peer_tlv_read_sock_zero_len_counter);
+ fprintf(stdout, "%-20s%u\n", "Rx retry max:",
+ sys_counter_p->rx_retry_max_counter);
+ fprintf(stdout, "%-20s%u\n", "Rx retry total:",
+ sys_counter_p->rx_retry_total_counter);
+ fprintf(stdout, "%-20s%u\n", "Rx retry fail:",
+ sys_counter_p->rx_retry_fail_counter);
+ fprintf(stdout, "%-20s%u\n", "Socket close err:",
+ sys_counter_p->socket_close_err_counter);
+ fprintf(stdout, "%-20s%u\n", "Socket cleanup:",
+ sys_counter_p->socket_cleanup_counter);
+
+ fprintf(stdout, "\n");
+ fprintf(stdout, "%-20s%u\n\n", "Warmboot:", sys_counter_p->warmboot_counter);
+
+ /* ICCP daemon to Mclagsyncd messages */
+ fprintf(stdout, "%-20s%-20s%-20s\n", "ICCP to MclagSyncd", "TX_OK", "TX_ERROR");
+ fprintf(stdout, "%-20s%-20s%-20s\n", "------------------", "-----", "--------");
+ for (i = 0; i < SYNCD_TX_DBG_CNTR_MSG_MAX; ++i)
+ {
+ fprintf(stdout, "%-20s%-20lu%-20lu\n",
+ mclagdctl_dbg_counter_syncdtx2str(i),
+ sys_counter_p->syncd_tx_counters[i][0],
+ sys_counter_p->syncd_tx_counters[i][1]);
+ }
+
+ fprintf(stdout, "\n%-20s%-20s%-20s\n", "MclagSyncd to ICCP", "RX_OK", "RX_ERROR");
+ fprintf(stdout, "%-20s%-20s%-20s\n", "------------------", "-----", "--------");
+ for (i = 0; i < SYNCD_RX_DBG_CNTR_MSG_MAX; ++i)
+ {
+ fprintf(stdout, "%-20s%-20lu%-20lu\n",
+ mclagdctl_dbg_counter_syncdrx2str(i),
+ sys_counter_p->syncd_rx_counters[i][0],
+ sys_counter_p->syncd_rx_counters[i][1]);
+ }
+ /* Print ICCP messages exchanged between MLAG peers */
+ fprintf(stdout, "\n%-20s%-20s%-20s%-20s%-20s\n",
+ "ICCP to Peer", "TX_OK", "RX_OK", "TX_ERROR", "RX_ERROR");
+ fprintf(stdout, "%-20s%-20s%-20s%-20s%-20s\n",
+ "------------", "-----", "-----", "--------", "--------");
+
+ iccp_counter_p = (mlacp_dbg_counter_info_t *)dbg_counter_p->iccp_dbg_counters;
+ for (i = 0; i < dbg_counter_p->num_iccp_counter_blocks; ++i)
+ {
+ if (i > 0)
+ ++iccp_counter_p;
+
+ for (j = 0; j < ICCP_DBG_CNTR_MSG_MAX; ++j)
+ {
+ fprintf(stdout, "%-20s%-20lu%-20lu%-20lu%-20lu\n",
+ mclagdctl_dbg_counter_iccpid2str(j),
+ iccp_counter_p->iccp_counters[j][0][0],
+ iccp_counter_p->iccp_counters[j][1][0],
+ iccp_counter_p->iccp_counters[j][0][1],
+ iccp_counter_p->iccp_counters[j][1][1]);
+ }
+ fprintf(stdout, "\n");
+ }
+ /* Netlink counters */
+ fprintf(stdout, "\nNetlink Counters\n");
+ fprintf(stdout, "-----------------\n");
+ fprintf(stdout, "Link add/del: %u/%u\n",
+ sys_counter_p->newlink_count, sys_counter_p->dellink_count);
+ fprintf(stdout, " Unknown if_name: %u\n", sys_counter_p->unknown_if_name_count);
+ fprintf(stdout, "Neighbor(ARP) add/del: %u/%u\n",
+ sys_counter_p->newnbr_count, sys_counter_p->delnbr_count);
+ fprintf(stdout, " MAC entry add/del: %u/%u\n",
+ sys_counter_p->newmac_count, sys_counter_p->delmac_count);
+ fprintf(stdout, "Address add/del: %u/%u\n",
+ sys_counter_p->newaddr_count, sys_counter_p->deladdr_count);
+ fprintf(stdout, "Unexpected message type: %u\n", sys_counter_p->unknown_type_count);
+ fprintf(stdout, "Receive error: %u\n\n", sys_counter_p->rx_error_count);
+ return 0;
+}
+
int mclagdctl_enca_config_loglevel(char *msg, int log_level, int argc, char **argv)
{
struct mclagdctl_req_hdr req;
@@ -940,4 +1281,3 @@ int main(int argc, char **argv)
return ret;
}
-
diff --git a/src/iccpd/src/mclagdctl/mclagdctl.h b/src/iccpd/src/mclagdctl/mclagdctl.h
index 91155ecb7321..ce31b58a1871 100644
--- a/src/iccpd/src/mclagdctl/mclagdctl.h
+++ b/src/iccpd/src/mclagdctl/mclagdctl.h
@@ -17,7 +17,11 @@
*
* Maintainer: Jim Jiang from nephos
*/
+#include
+#include
+#include "../../include/system.h"
+#define ETHER_ADDR_LEN 6
#define MCLAGDCTL_PARA1_LEN 16
#define MCLAGDCTL_PARA2_LEN 32
#define MCLAGDCTL_PARA3_LEN 64
@@ -54,8 +58,11 @@ enum id_command_type
ID_CMDTYPE_D_P,
ID_CMDTYPE_D_P_L,
ID_CMDTYPE_D_P_P,
+ ID_CMDTYPE_D_D,
+ ID_CMDTYPE_D_D_C,
ID_CMDTYPE_C,
ID_CMDTYPE_C_L,
+ ID_CMDTYPE_C_D,
};
enum mclagdctl_notify_peer_type
@@ -65,9 +72,12 @@ enum mclagdctl_notify_peer_type
INFO_TYPE_DUMP_ARP,
INFO_TYPE_DUMP_NDISC,
INFO_TYPE_DUMP_MAC,
+ INFO_TYPE_DUMP_UNIQUE_IP,
INFO_TYPE_DUMP_LOCAL_PORTLIST,
INFO_TYPE_DUMP_PEER_PORTLIST,
+ INFO_TYPE_DUMP_DBG_COUNTERS,
INFO_TYPE_CONFIG_LOGLEVEL,
+ INFO_TYPE_CONFIG_DOWN,
INFO_TYPE_FINISH,
};
@@ -122,21 +132,28 @@ struct mclagd_state
{
int mclag_id;
int keepalive;
+ int info_sync_done;
char local_ip[MCLAGDCTL_INET_ADDR_LEN];
char peer_ip[MCLAGDCTL_INET_ADDR_LEN];
char peer_link_if[MCLAGDCTL_MAX_L_PORT_NANE];
unsigned char peer_link_mac[MCLAGDCTL_ETHER_ADDR_LEN];
int role;
char enabled_po[MCLAGDCTL_PORT_MEMBER_BUF_LEN];
+ int session_timeout;
+ int keepalive_time;
char loglevel[MCLAGDCTL_PARA1_LEN];
};
+#define NEIGH_LOCAL 1
+#define NEIGH_REMOTE 2
+
struct mclagd_arp_msg
{
char op_type;
char ifname[MCLAGDCTL_MAX_L_PORT_NANE];
char ipv4_addr[MCLAGDCTL_INET_ADDR_LEN];
unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN];
+ uint8_t learn_flag;
};
struct mclagd_ndisc_msg
@@ -145,13 +162,14 @@ struct mclagd_ndisc_msg
char ifname[MCLAGDCTL_MAX_L_PORT_NANE];
char ipv6_addr[MCLAGDCTL_INET6_ADDR_LEN];
unsigned char mac_addr[MCLAGDCTL_ETHER_ADDR_LEN];
+ uint8_t learn_flag;
};
struct mclagd_mac_msg
{
unsigned char op_type;/*add or del*/
unsigned char fdb_type;/*static or dynamic*/
- char mac_str[ETHER_ADDR_STR_LEN];
+ uint8_t mac_addr[ETHER_ADDR_LEN];
unsigned short vid;
/*Current if name that set in chip*/
char ifname[MCLAGDCTL_MAX_L_PORT_NANE];
@@ -178,7 +196,7 @@ struct mclagd_local_if
unsigned char po_active;
char mlacp_state[MCLAGDCTL_PARA1_LEN];
unsigned char isolate_to_peer_link;
-
+ bool is_traffic_disable;
char vlanlist[MCLAGDCTL_PARA3_LEN];
};
@@ -193,6 +211,21 @@ struct mclagd_peer_if
unsigned char po_active;
};
+typedef struct mclagd_dbg_counter_info
+{
+ system_dbg_counter_info_t system_dbg;
+ uint8_t num_iccp_counter_blocks;
+ uint8_t iccp_dbg_counters[0];
+ /* Variable length counter buffers containing N mlacp_dbg_counter_info_t
+ */
+}mclagd_dbg_counter_info_t;
+
+struct mclagd_unique_ip_if
+{
+ int active;
+ char name[MCLAGDCTL_MAX_L_PORT_NANE];
+};
+
extern int mclagdctl_enca_dump_state(char *msg, int mclag_id, int argc, char **argv);
extern int mclagdctl_parse_dump_state(char *msg, int data_len);
extern int mclagdctl_enca_dump_arp(char *msg, int mclag_id, int argc, char **argv);
@@ -208,3 +241,7 @@ extern int mclagdctl_parse_dump_peer_portlist(char *msg, int data_len);
int mclagdctl_enca_config_loglevel(char *msg, int log_level, int argc, char **argv);
int mclagdctl_parse_config_loglevel(char *msg, int data_len);
+extern int mclagdctl_enca_dump_dbg_counters(char *msg, int mclag_id, int argc, char **argv);
+extern int mclagdctl_parse_dump_dbg_counters(char *msg, int data_len);
+extern int mclagdctl_enca_dump_unique_ip(char *msg, int mclag_id, int argc, char **argv);
+extern int mclagdctl_parse_dump_unique_ip(char *msg, int data_len);
diff --git a/src/iccpd/src/mlacp_fsm.c b/src/iccpd/src/mlacp_fsm.c
index c56eb9051736..b64369775403 100644
--- a/src/iccpd/src/mlacp_fsm.c
+++ b/src/iccpd/src/mlacp_fsm.c
@@ -35,10 +35,13 @@
#include
#include
#include
+#include
#include "../include/mlacp_tlv.h"
#include "../include/mlacp_sync_prepare.h"
#include "../include/mlacp_link_handler.h"
#include "../include/mlacp_sync_update.h"
+#include "../include/system.h"
+#include "../include/scheduler.h"
#include
@@ -58,6 +61,18 @@
TAILQ_INIT(&(list)); \
}
+#define MLACP_MAC_MSG_QUEUE_REINIT(list) \
+ { \
+ struct MACMsg* mac_msg = NULL; \
+ while (!TAILQ_EMPTY(&(list))) { \
+ mac_msg = TAILQ_FIRST(&(list)); \
+ TAILQ_REMOVE(&(list), mac_msg, tail); \
+ if (mac_msg->op_type == MAC_SYNC_DEL) \
+ free(mac_msg); \
+ } \
+ TAILQ_INIT(&(list)); \
+ }
+
#define PIF_QUEUE_REINIT(list) \
{ \
while (!LIST_EMPTY(&(list))) { \
@@ -76,7 +91,7 @@
lif = LIST_FIRST(&(list)); \
if (lif->type == IF_T_PORT_CHANNEL && lif->is_arp_accept) { \
if ((set_sys_arp_accept_flag(lif->name, 0)) == 0) \
- lif->is_arp_accept = 0; \
+ lif->is_arp_accept = 0; \
} \
LIST_REMOVE (lif, mlacp_next); \
} \
@@ -93,22 +108,48 @@
LIST_INIT(&(list)); \
}
+
+void mlacp_local_lif_clear_pending_mac(struct CSM* csm, struct LocalInterface *local_lif);
+/*****************************************
+* Rb tree Functions
+*
+* ***************************************/
+
+static int MACMsg_compare(const struct MACMsg *mac1, const struct MACMsg *mac2)
+{
+ if (mac1->vid < mac2->vid)
+ return -1;
+
+ if (mac1->vid > mac2->vid)
+ return 1;
+
+ if(memcmp((char *)&mac1->mac_addr, (char *)&mac2->mac_addr, ETHER_ADDR_LEN) < 0)
+ return -1;
+
+ if(memcmp((char *)&mac1->mac_addr, (char *)&mac2->mac_addr, ETHER_ADDR_LEN) > 0)
+ return 1;
+
+ return 0;
+}
+
+RB_GENERATE(mac_rb_tree, MACMsg, mac_entry_rb, MACMsg_compare);
+
#define WARM_REBOOT_TIMEOUT 90
+#define PEER_REBOOT_TIMEOUT 300
/*****************************************
* Static Function
*
* ***************************************/
-static char *mlacp_state(struct CSM* csm);
+char *mlacp_state(struct CSM* csm);
static void mlacp_resync_arp(struct CSM* csm);
-static void mlacp_resync_ndisc(struct CSM* csm);
-static void mlacp_resync_mac(struct CSM* csm);
+static void mlacp_resync_ndisc(struct CSM *csm);
/* Sync Sender APIs*/
static void mlacp_sync_send_sysConf(struct CSM* csm);
static void mlacp_sync_send_aggConf(struct CSM* csm);
static void mlacp_sync_send_aggState(struct CSM* csm);
static void mlacp_sync_send_syncArpInfo(struct CSM* csm);
-static void mlacp_sync_send_syncNdiscInfo(struct CSM* csm);
+static void mlacp_sync_send_syncNdiscInfo(struct CSM *csm);
static void mlacp_sync_send_heartbeat(struct CSM* csm);
static void mlacp_sync_send_syncDoneData(struct CSM* csm);
/* Sync Reciever APIs*/
@@ -138,6 +179,15 @@ static void mlacp_stage_sync_request_handler(struct CSM* csm, struct Msg* msg);
static void mlacp_stage_handler(struct CSM* csm, struct Msg* msg);
static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg);
+void mlacp_local_lif_state_mac_handler(struct CSM* csm);
+
+/* Interface up ack */
+static void mlacp_fsm_send_if_up_ack(
+ struct CSM *csm,
+ uint8_t if_type,
+ uint16_t if_id,
+ uint8_t port_isolation_enable);
+
/******************************************************************
* Sync Sender APIs
*
@@ -210,19 +260,35 @@ static void mlacp_sync_send_aggState(struct CSM* csm)
static void mlacp_sync_send_syncMacInfo(struct CSM* csm)
{
int msg_len = 0;
- struct Msg* msg = NULL;
+ struct MACMsg* mac_msg = NULL;
+ struct MACMsg mac_find;
int count = 0;
memset(g_csm_buf, 0, CSM_BUFFER_SIZE);
+ memset(&mac_find, 0, sizeof(struct MACMsg));
while (!TAILQ_EMPTY(&(MLACP(csm).mac_msg_list)))
{
- msg = TAILQ_FIRST(&(MLACP(csm).mac_msg_list));
- TAILQ_REMOVE(&(MLACP(csm).mac_msg_list), msg, tail);
- msg_len = mlacp_prepare_for_mac_info_to_peer(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct MACMsg*)msg->buf, count);
+ mac_msg = TAILQ_FIRST(&(MLACP(csm).mac_msg_list));
+ MAC_TAILQ_REMOVE(&(MLACP(csm).mac_msg_list), mac_msg, tail);
+
+ msg_len = mlacp_prepare_for_mac_info_to_peer(csm, g_csm_buf, CSM_BUFFER_SIZE, mac_msg, count);
count++;
- free(msg->buf);
- free(msg);
+
+ //free mac_msg if marked for delete.
+ if (mac_msg->op_type == MAC_SYNC_DEL)
+ {
+ if (!(mac_msg->mac_entry_rb.rbt_parent))
+ {
+ //If the entry is parent then the parent pointer would be null
+ //search to confirm if the MAC is present in RB tree. if not then free.
+ mac_find.vid = mac_msg->vid ;
+ memcpy(mac_find.mac_addr, mac_msg->mac_addr, ETHER_ADDR_LEN);
+ if (!RB_FIND(mac_rb_tree, &MLACP(csm).mac_rb ,&mac_find))
+ free(mac_msg);
+ }
+ }
+
if (count >= MAX_MAC_ENTRY_NUM)
{
iccp_csm_send(csm, g_csm_buf, msg_len);
@@ -251,7 +317,7 @@ static void mlacp_sync_send_syncArpInfo(struct CSM* csm)
msg = TAILQ_FIRST(&(MLACP(csm).arp_msg_list));
TAILQ_REMOVE(&(MLACP(csm).arp_msg_list), msg, tail);
- msg_len = mlacp_prepare_for_arp_info(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct ARPMsg*)msg->buf, count);
+ msg_len = mlacp_prepare_for_arp_info(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct ARPMsg*)msg->buf, count, NEIGH_SYNC_CLIENT_IP);
count++;
free(msg->buf);
free(msg);
@@ -283,7 +349,7 @@ static void mlacp_sync_send_syncNdiscInfo(struct CSM *csm)
msg = TAILQ_FIRST(&(MLACP(csm).ndisc_msg_list));
TAILQ_REMOVE(&(MLACP(csm).ndisc_msg_list), msg, tail);
- msg_len = mlacp_prepare_for_ndisc_info(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct NDISCMsg *)msg->buf, count);
+ msg_len = mlacp_prepare_for_ndisc_info(csm, g_csm_buf, CSM_BUFFER_SIZE, (struct NDISCMsg *)msg->buf, count, NEIGH_SYNC_CLIENT_IP);
count++;
free(msg->buf);
free(msg);
@@ -301,6 +367,7 @@ static void mlacp_sync_send_syncNdiscInfo(struct CSM *csm)
return;
}
+
static void mlacp_sync_send_syncPortChannelInfo(struct CSM* csm)
{
struct System* sys = NULL;
@@ -348,7 +415,7 @@ static void mlacp_sync_send_heartbeat(struct CSM* csm)
int msg_len = 0;
if ((csm->heartbeat_send_time == 0) ||
- ((time(NULL) - csm->heartbeat_send_time) > 1))
+ ((time(NULL) - csm->heartbeat_send_time) > csm->keepalive_time))
{
memset(g_csm_buf, 0, CSM_BUFFER_SIZE);
msg_len = mlacp_prepare_for_heartbeat(csm, g_csm_buf, CSM_BUFFER_SIZE);
@@ -386,8 +453,15 @@ static void mlacp_sync_recv_sysConf(struct CSM* csm, struct Msg* msg)
if (mlacp_fsm_update_system_conf(csm, sysconf) == MCLAG_ERROR)
{
/*NOTE: we just change the node ID local side without sending NAK msg*/
- ICCPD_LOG_WARN(__FUNCTION__, "Same Node ID = %d, send NAK", MLACP(csm).remote_system.node_id);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "RX same Node ID = %d, send NAK", MLACP(csm).remote_system.node_id);
mlacp_sync_send_nak_handler(csm, msg);
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ sysconf->icc_parameter.type, ICCP_DBG_CNTR_STS_ERR);
+ }
+ else
+ {
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ sysconf->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
}
return;
@@ -419,6 +493,13 @@ static void mlacp_sync_recv_aggConf(struct CSM* csm, struct Msg* msg)
if (mlacp_fsm_update_Agg_conf(csm, portconf) == MCLAG_ERROR)
{
mlacp_sync_send_nak_handler(csm, msg);
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ portconf->icc_parameter.type, ICCP_DBG_CNTR_STS_ERR);
+ }
+ else
+ {
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ portconf->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
}
return;
@@ -433,7 +514,22 @@ static void mlacp_sync_recv_aggState(struct CSM* csm, struct Msg* msg)
{
mlacp_sync_send_nak_handler(csm, msg);
/*MLACP(csm).error_msg = "Receive a port state update on an non-existed port. It is suggest to check the environment and re-initialize mLACP again.";*/
- return;
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ portstate->icc_parameter.type, ICCP_DBG_CNTR_STS_ERR);
+ }
+ else
+ {
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ portstate->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
+ }
+ /* Send interface up ack for MLAG interface regardless of the
+ * processing return code
+ */
+ if (portstate->agg_state == PORT_STATE_UP)
+ {
+ mlacp_fsm_send_if_up_ack(
+ csm, IF_UP_ACK_TYPE_PORT_CHANNEL, ntohs(portstate->agg_id),
+ PORT_ISOLATION_STATE_ENABLE);
}
return;
@@ -448,7 +544,12 @@ static void mlacp_sync_recv_syncData(struct CSM* csm, struct Msg* msg)
{
/* Sync done*/
MLACP(csm).wait_for_sync_data = 0;
+ ICCPD_LOG_DEBUG("ICCP_FSM", "RX sync done");
}
+ else
+ ICCPD_LOG_DEBUG("ICCP_FSM", "RX sync start");
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ syncdata->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
return;
}
@@ -460,8 +561,13 @@ static void mlacp_sync_recv_syncReq(struct CSM* csm, struct Msg* msg)
mlacp_sync_req = (mLACPSyncReqTLV*)&msg->buf[sizeof(ICCHdr)];
MLACP(csm).sync_req_num = ntohs(mlacp_sync_req->req_num);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "RX sync_requrest: req_no %d",
+ MLACP(csm).sync_req_num);
+
/* Reply the peer all sync info*/
mlacp_sync_send_all_info_handler(csm);
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ mlacp_sync_req->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
return;
}
@@ -474,6 +580,13 @@ static void mlacp_sync_recv_portChanInfo(struct CSM* csm, struct Msg* msg)
if (mlacp_fsm_update_port_channel_info(csm, portconf) == MCLAG_ERROR)
{
mlacp_sync_send_nak_handler(csm, msg);
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ portconf->icc_parameter.type, ICCP_DBG_CNTR_STS_ERR);
+ }
+ else
+ {
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ portconf->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
}
return;
@@ -485,6 +598,8 @@ static void mlacp_sync_recv_peerLlinkInfo(struct CSM* csm, struct Msg* msg)
peerlink = (mLACPPeerLinkInfoTLV*)&(msg->buf[sizeof(ICCHdr)]);
mlacp_fsm_update_peerlink_info( csm, peerlink);
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ peerlink->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
return;
}
@@ -495,6 +610,8 @@ static void mlacp_sync_recv_macInfo(struct CSM* csm, struct Msg* msg)
mac_info = (struct mLACPMACInfoTLV *)&(msg->buf[sizeof(ICCHdr)]);
mlacp_fsm_update_mac_info_from_peer(csm, mac_info);
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ mac_info->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
return;
}
@@ -505,6 +622,8 @@ static void mlacp_sync_recv_arpInfo(struct CSM* csm, struct Msg* msg)
arp_info = (struct mLACPARPInfoTLV *)&(msg->buf[sizeof(ICCHdr)]);
mlacp_fsm_update_arp_info(csm, arp_info);
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ arp_info->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
return;
}
@@ -518,6 +637,7 @@ static void mlacp_sync_recv_ndiscInfo(struct CSM *csm, struct Msg *msg)
return;
}
+
static void mlacp_sync_recv_stpInfo(struct CSM* csm, struct Msg* msg)
{
/*Don't support currently*/
@@ -530,6 +650,8 @@ static void mlacp_sync_recv_heartbeat(struct CSM* csm, struct Msg* msg)
tlv = (struct mLACPHeartbeatTLV *)(&msg->buf[sizeof(ICCHdr)]);
mlacp_fsm_update_heartbeat(csm, tlv);
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ tlv->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
return;
}
@@ -540,10 +662,102 @@ static void mlacp_sync_recv_warmboot(struct CSM* csm, struct Msg* msg)
tlv = (struct mLACPWarmbootTLV *)(&msg->buf[sizeof(ICCHdr)]);
mlacp_fsm_update_warmboot(csm, tlv);
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ tlv->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
return;
}
+static void mlacp_fsm_recv_if_up_ack(struct CSM* csm, struct Msg* msg)
+{
+ struct mLACPIfUpAckTLV *tlv = NULL;
+ struct LocalInterface *local_if = NULL;
+ uint16_t if_id;
+
+ tlv = (struct mLACPIfUpAckTLV *)(&msg->buf[sizeof(ICCHdr)]);
+ if (tlv == NULL)
+ return;
+
+ if_id = ntohs(tlv->if_id);
+
+ if (tlv->if_type == IF_UP_ACK_TYPE_PORT_CHANNEL)
+ {
+ local_if = local_if_find_by_po_id(if_id);
+
+ ICCPD_LOG_DEBUG("ICCP_FSM",
+ "RX if_up_ack: po_id %d, local if 0x%x, active %u",
+ if_id, local_if, local_if ? local_if->po_active : 0);
+
+ /* Ignore the ack if MLAG interface has gone down */
+ if (local_if && local_if->po_active)
+ mlacp_link_enable_traffic_distribution(local_if);
+
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ tlv->icc_parameter.type, ICCP_DBG_CNTR_STS_OK);
+ }
+ else
+ {
+ ICCPD_LOG_ERR("ICCP_FSM", "RX if_up_ack: invalid i/f type %u, i/f ID %u",
+ tlv->if_type, if_id);
+ MLACP_SET_ICCP_RX_DBG_COUNTER(csm,
+ tlv->icc_parameter.type, ICCP_DBG_CNTR_STS_ERR);
+ }
+}
+
+void mlacp_local_lif_state_mac_handler(struct CSM* csm)
+{
+ struct LocalInterface* local_if = NULL;
+
+ LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next)
+ {
+ if ((local_if->state == PORT_STATE_DOWN) && (local_if->type == IF_T_PORT_CHANNEL))
+ {
+ // clear the pending macs if timer is expired.
+ if (local_if->po_down_time && ((time(NULL) - local_if->po_down_time) > MLACP_LOCAL_IF_DOWN_TIMER))
+ {
+ mlacp_local_lif_clear_pending_mac(csm, local_if);
+ local_if->po_down_time = 0;
+ }
+ }
+ }
+}
+
+void mlacp_peer_link_learning_handler(struct CSM* csm)
+{
+ if (csm->peer_link_if == NULL)
+ return;
+
+ if (csm->peer_link_if->vlan_count == 0) {
+ return;
+ }
+
+ if (csm->peer_link_learning_retry_time && ((time(NULL) - csm->peer_link_learning_retry_time) > 2))
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "peer_link_learning_enable %d", csm->peer_link_learning_enable);
+ set_peerlink_learn_kernel(csm, csm->peer_link_learning_enable, 10);
+ }
+}
+
+void mlacp_mac_msg_queue_reinit(struct CSM* csm)
+{
+
+ struct MACMsg* mac_msg = NULL;
+
+ MLACP_MAC_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list);
+
+ ICCPD_LOG_NOTICE("ICCP_FDB", "mlacp_mac_msg_queue_reinit clear mac_msg_list pointers in existing MAC entries");
+
+ // unset the mac_msg_list pointers for existing MAC entries.
+ RB_FOREACH (mac_msg, mac_rb_tree, &MLACP(csm).mac_rb)
+ {
+ if (MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ CLEAR_MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail);
+ }
+ }
+ return;
+}
+
/*****************************************
* MLACP Init
*
@@ -563,7 +777,8 @@ void mlacp_init(struct CSM* csm, int all)
MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list);
MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list);
MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list);
- MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list);
+ mlacp_mac_msg_queue_reinit(csm);
+
PIF_QUEUE_REINIT(MLACP(csm).pif_list);
LIF_PURGE_QUEUE_REINIT(MLACP(csm).lif_purge_list);
@@ -572,7 +787,7 @@ void mlacp_init(struct CSM* csm, int all)
/* if no clean all, keep the arp info & local interface info for next connection*/
MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_list);
MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_list);
- MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_list);
+ RB_INIT(mac_rb_tree, &MLACP(csm).mac_rb );
LIF_QUEUE_REINIT(MLACP(csm).lif_list);
MLACP(csm).node_id = MLACP_SYSCONF_NODEID_MSB_MASK;
@@ -596,10 +811,11 @@ void mlacp_finalize(struct CSM* csm)
MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list);
MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list);
MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list);
- MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list);
+ mlacp_mac_msg_queue_reinit(csm);
MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_list);
MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_list);
- MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_list);
+
+ RB_INIT(mac_rb_tree, &MLACP(csm).mac_rb );
/* remove lif & lif-purge queue */
LIF_QUEUE_REINIT(MLACP(csm).lif_list);
@@ -637,8 +853,14 @@ void mlacp_fsm_transit(struct CSM* csm)
MLACP_MSG_QUEUE_REINIT(MLACP(csm).mlacp_msg_list);
MLACP_MSG_QUEUE_REINIT(MLACP(csm).arp_msg_list);
MLACP_MSG_QUEUE_REINIT(MLACP(csm).ndisc_msg_list);
- MLACP_MSG_QUEUE_REINIT(MLACP(csm).mac_msg_list);
+ mlacp_mac_msg_queue_reinit(csm);
MLACP(csm).current_state = MLACP_STATE_INIT;
+ if (csm->sock_fd > 0)
+ {
+ /* Close CSM socket and reset its value */
+ scheduler_csm_socket_cleanup(csm, 2);
+ SYSTEM_INCR_SOCKET_CLEANUP_COUNTER(system_get_instance());
+ }
}
return;
}
@@ -657,6 +879,9 @@ void mlacp_fsm_transit(struct CSM* csm)
mlacp_sync_send_heartbeat(csm);
+ mlacp_local_lif_state_mac_handler(csm);
+ mlacp_peer_link_learning_handler(csm);
+
/* Dequeue msg if any*/
while (have_msg)
{
@@ -728,7 +953,7 @@ void mlacp_fsm_transit(struct CSM* csm)
}
/* Helper function for dumping application state machine */
-static char* mlacp_state(struct CSM* csm)
+char* mlacp_state(struct CSM* csm)
{
if (csm == NULL )
return "MLACP_NULL";
@@ -767,12 +992,6 @@ void mlacp_enqueue_msg(struct CSM* csm, struct Msg* msg)
if (msg == NULL )
return;
- #if 0
- icc_hdr = (ICCHdr*)msg->buf;
- icc_param = (ICCParameter*)&msg->buf[sizeof(ICCHdr)];
- ICCPD_LOG_DEBUG("mlacp_fsm", " mLACP enqueue: tlv = 0x%04x", icc_param->type);
- #endif
-
TAILQ_INSERT_TAIL(&(MLACP(csm).mlacp_msg_list), msg, tail);
return;
@@ -792,32 +1011,77 @@ struct Msg* mlacp_dequeue_msg(struct CSM* csm)
return msg;
}
-/******************************************
-* When peerlink ready, prepare the MACMsg
-*
-******************************************/
-static void mlacp_resync_mac(struct CSM* csm)
+void mlacp_sync_mac(struct CSM* csm)
{
- struct Msg* msg = NULL;
struct MACMsg* mac_msg = NULL;
- struct Msg *msg_send = NULL;
-
- /* recover MAC info sync from peer*/
- if (!TAILQ_EMPTY(&(MLACP(csm).mac_list)))
+ RB_FOREACH (mac_msg, mac_rb_tree, &MLACP(csm).mac_rb)
{
- TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail)
+ /*If MAC with local age flag, dont sync to peer. Such MAC only exist when peer is warm-reboot.
+ If peer is warm-reboot, peer age flag is not set when connection is lost.
+ When MAC is aged in local switch, this MAC is not deleted for no peer age flag.
+ After warm-reboot, this MAC must be learnt by peer and sync to local switch*/
+ if (!(mac_msg->age_flag & MAC_AGE_LOCAL))
{
- mac_msg = (struct MACMsg*)msg->buf;
mac_msg->op_type = MAC_SYNC_ADD;
- if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0)
+ //As part of local sync do not delete peer age
+ //mac_msg->age_flag &= ~MAC_AGE_PEER;
+
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), mac_msg, tail);
+ }
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Sync MAC: MAC-msg-list enqueue interface %s, "
+ "MAC %s vlan %d, age_flag %d", mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->age_flag);
+ }
+ else
+ {
+ /*If MAC with local age flag and is point to MCLAG enabled port, reomove local age flag*/
+ if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0)
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Sync MAC: MAC-msg-list not enqueue for local age flag: %s, mac %s vlan-id %d, age_flag %d",
+ mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->age_flag);
+ /* After warmboot remote mac can exist, should not
+ update existing flag
+ */
+ //mac_msg->age_flag &= ~MAC_AGE_LOCAL;
+ }
+ }
+ }
+ return;
+}
+
+void mlacp_local_lif_clear_pending_mac(struct CSM* csm, struct LocalInterface *local_lif)
+{
+ ICCPD_LOG_DEBUG("ICCP_FDB", "mlacp_local_lif_clear_pending_mac If: %s ", local_lif->name );
+ struct MACMsg* mac_msg = NULL, *mac_temp = NULL;
+ RB_FOREACH_SAFE (mac_msg, mac_rb_tree, &MLACP(csm).mac_rb, mac_temp)
+ {
+ if (mac_msg->pending_local_del && strcmp(mac_msg->origin_ifname, local_lif->name) == 0)
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Clear pending MAC: MAC-msg-list not enqueue for local age flag: %s, mac %s vlan-id %d, age_flag %d, remove local age flag",
+ mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->age_flag);
+
+ del_mac_from_chip(mac_msg);
+
+ // if static dont delete mac
+ if (mac_msg->fdb_type != MAC_TYPE_STATIC)
{
- mac_msg->age_flag &= ~MAC_AGE_PEER;
- TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail);
- ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);
+ //TBD do we need to send delete notification to peer .?
+ MAC_RB_REMOVE(mac_rb_tree, &MLACP(csm).mac_rb, mac_msg);
+
+ mac_msg->op_type = MAC_SYNC_DEL;
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ free(mac_msg);
+ }
}
+ else
+ mac_msg->pending_local_del = 0;
}
}
+ return;
}
/******************************************
@@ -837,6 +1101,7 @@ static void mlacp_resync_arp(struct CSM* csm)
{
arp_msg = (struct ARPMsg*)msg->buf;
arp_msg->op_type = NEIGH_SYNC_ADD;
+ arp_msg->flag = 0;
if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, sizeof(struct ARPMsg)) == 0)
{
TAILQ_INSERT_TAIL(&(MLACP(csm).arp_msg_list), msg_send, tail);
@@ -862,6 +1127,7 @@ static void mlacp_resync_ndisc(struct CSM *csm)
{
ndisc_msg = (struct NDISCMsg *)msg->buf;
ndisc_msg->op_type = NEIGH_SYNC_ADD;
+ ndisc_msg->flag = 0;
if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0)
{
TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail);
@@ -1016,6 +1282,15 @@ static void mlacp_sync_receiver_handler(struct CSM* csm, struct Msg* msg)
case TLV_T_MLACP_WARMBOOT_FLAG:
mlacp_sync_recv_warmboot(csm, msg);
break;
+
+ case TLV_T_MLACP_IF_UP_ACK:
+ mlacp_fsm_recv_if_up_ack(csm, msg);
+ break;
+
+ default:
+ ICCPD_LOG_ERR("ICCP_FSM", "Receive unsupported msg 0x%x from peer",
+ icc_param->type);
+ break;
}
/*ICCPD_LOG_DEBUG("mlacp_fsm", " [Sync Recv] %s... DONE", get_tlv_type_string(icc_param->type));*/
@@ -1238,7 +1513,13 @@ static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg)
iccp_csm_send(csm, g_csm_buf, len);
/* Destroy old interface*/
if (lif_purge != NULL)
+ {
+ /* Re-enable traffic distribution on MCLAG interface */
+ if ((lif_purge->type == IF_T_PORT_CHANNEL) && lif_purge->is_traffic_disable)
+ mlacp_link_enable_traffic_distribution(lif_purge);
+
LIST_REMOVE(lif_purge, mlacp_purge_next);
+ }
}
/* Send mlag lif*/
@@ -1246,6 +1527,10 @@ static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg)
{
if (lif->type == IF_T_PORT_CHANNEL && lif->port_config_sync)
{
+ /* Disable traffic distribution on LAG members if LAG is down */
+ if (!lif->po_active)
+ mlacp_link_disable_traffic_distribution(lif);
+
/* Send port channel information*/
memset(g_csm_buf, 0, CSM_BUFFER_SIZE);
len = mlacp_prepare_for_Aggport_config(csm, g_csm_buf, CSM_BUFFER_SIZE, lif, 0);
@@ -1264,8 +1549,12 @@ static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg)
/* Send port channel state information*/
memset(g_csm_buf, 0, CSM_BUFFER_SIZE);
len = mlacp_prepare_for_Aggport_state(csm, g_csm_buf, CSM_BUFFER_SIZE, lif);
- iccp_csm_send(csm, g_csm_buf, len);
- lif->changed = 0;
+ //if po state send to peer is not successful, next time will try to
+ //send again, until then dont unmark lif->changed flag
+ if (iccp_csm_send(csm, g_csm_buf, len) > 0)
+ {
+ lif->changed = 0;
+ }
}
}
@@ -1291,3 +1580,90 @@ static void mlacp_exchange_handler(struct CSM* csm, struct Msg* msg)
return;
}
+
+/*****************************************
+ * Interface up ACK
+ *
+ ****************************************/
+static void mlacp_fsm_send_if_up_ack(
+ struct CSM *csm,
+ uint8_t if_type,
+ uint16_t if_id,
+ uint8_t port_isolation_enable)
+{
+ struct System* sys = NULL;
+ int msg_len = 0;
+ int rc = -10;
+
+ sys = system_get_instance();
+ if (sys == NULL)
+ return;
+
+ /* Interface up ACK is expected only after the interface is up */
+ if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE)
+ return;
+
+ memset(g_csm_buf, 0, CSM_BUFFER_SIZE);
+ msg_len = mlacp_prepare_for_if_up_ack(
+ csm, g_csm_buf, CSM_BUFFER_SIZE, if_type, if_id, port_isolation_enable);
+ if (msg_len > 0)
+ rc = iccp_csm_send(csm, g_csm_buf, msg_len);
+
+ if (rc <= 0)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "failed, interface type/id %d/%d, rc %d",
+ if_type, if_id, rc);
+ }
+ else
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"interface type/id %d/%d", if_type, if_id);
+ }
+}
+
+/* MLACP ICCP mesage type to debug counter type conversion */
+ICCP_DBG_CNTR_MSG_e mlacp_fsm_iccp_to_dbg_msg_type(uint32_t tlv_type)
+{
+ switch (tlv_type)
+ {
+ case TLV_T_MLACP_SYSTEM_CONFIG:
+ return ICCP_DBG_CNTR_MSG_SYS_CONFIG;
+
+ case TLV_T_MLACP_AGGREGATOR_CONFIG:
+ return ICCP_DBG_CNTR_MSG_AGGR_CONFIG;
+
+ case TLV_T_MLACP_AGGREGATOR_STATE:
+ return ICCP_DBG_CNTR_MSG_AGGR_STATE;
+
+ case TLV_T_MLACP_SYNC_REQUEST:
+ return ICCP_DBG_CNTR_MSG_SYNC_REQ;
+
+ case TLV_T_MLACP_SYNC_DATA:
+ return ICCP_DBG_CNTR_MSG_SYNC_DATA;
+
+ case TLV_T_MLACP_HEARTBEAT:
+ return ICCP_DBG_CNTR_MSG_HEART_BEAT;
+
+ case TLV_T_MLACP_PORT_CHANNEL_INFO:
+ return ICCP_DBG_CNTR_MSG_PORTCHANNEL_INFO;
+
+ case TLV_T_MLACP_PEERLINK_INFO:
+ return ICCP_DBG_CNTR_MSG_PEER_LINK_INFO;
+
+ case TLV_T_MLACP_ARP_INFO:
+ return ICCP_DBG_CNTR_MSG_ARP_INFO;
+
+ case TLV_T_MLACP_MAC_INFO:
+ return ICCP_DBG_CNTR_MSG_MAC_INFO;
+
+ case TLV_T_MLACP_WARMBOOT_FLAG:
+ return ICCP_DBG_CNTR_MSG_WARM_BOOT;
+
+ case TLV_T_MLACP_IF_UP_ACK:
+ return ICCP_DBG_CNTR_MSG_IF_UP_ACK;
+
+ default:
+ ICCPD_LOG_DEBUG(__FUNCTION__, "No debug counter for TLV type %u",
+ tlv_type);
+ return ICCP_DBG_CNTR_MSG_MAX;
+ }
+}
diff --git a/src/iccpd/src/mlacp_link_handler.c b/src/iccpd/src/mlacp_link_handler.c
index 8bc533e387bd..c0e561988e55 100644
--- a/src/iccpd/src/mlacp_link_handler.c
+++ b/src/iccpd/src/mlacp_link_handler.c
@@ -24,6 +24,7 @@
#include
#include
+#include
#include
#include
#include
@@ -39,7 +40,14 @@
#include "../include/iccp_csm.h"
#include "mclagdctl/mclagdctl.h"
#include "../include/iccp_cmd_show.h"
+#include "../include/iccp_cli.h"
+#include "../include/iccp_cmd.h"
+#include "../include/mlacp_link_handler.h"
+#include "../include/mlacp_sync_prepare.h"
#include "../include/iccp_netlink.h"
+#include "../include/scheduler.h"
+#include "../include/iccp_ifm.h"
+
/*****************************************
* Enum
*
@@ -57,6 +65,17 @@ typedef enum route_manipulate_type
* ***************************************/
char g_ipv4_str[INET_ADDRSTRLEN];
char g_ipv6_str[INET6_ADDRSTRLEN];
+char g_iccp_mlagsyncd_recv_buf[ICCP_MLAGSYNCD_RECV_MSG_BUFFER_SIZE] = { 0 };
+char g_iccp_mlagsyncd_send_buf[ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE] = { 0 };
+
+
+extern void mlacp_sync_mac(struct CSM* csm);
+
+#define SYNCD_SEND_RETRY_INTERVAL_USEC 50000 //50 mseconds
+#define SYNCD_SEND_RETRY_MAX 5
+
+#define SYNCD_RECV_RETRY_INTERVAL_USEC 50000 //50 mseconds
+#define SYNCD_RECV_RETRY_MAX 5
/*****************************************
* Tool : show ip string
@@ -111,6 +130,7 @@ static int arp_set_handler(struct CSM* csm,
struct Msg* msg = NULL;
struct ARPMsg* arp_msg = NULL;
char mac_str[18] = "";
+ int err = 0;
if (!csm || !lif)
return 0;
@@ -121,7 +141,7 @@ static int arp_set_handler(struct CSM* csm,
goto del_arp;
/* Process Add */
- add_arp:
+add_arp:
if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE)
return 0;
@@ -141,13 +161,12 @@ static int arp_set_handler(struct CSM* csm,
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", arp_msg->mac_addr[0], arp_msg->mac_addr[1], arp_msg->mac_addr[2],
arp_msg->mac_addr[3], arp_msg->mac_addr[4], arp_msg->mac_addr[5]);
- iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_msg->ipv4_addr, 1, arp_msg->mac_addr, arp_msg->ifname);
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add dynamic ARP to kernel [%s]",
- show_ip_str(arp_msg->ipv4_addr));*/
+ err = iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_msg->ipv4_addr, 1, arp_msg->mac_addr, arp_msg->ifname, 0, 4);
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Add dynamic ARP to kernel [%s], status %d", show_ip_str(arp_msg->ipv4_addr), err);
}
goto done;
- del_arp:
+del_arp:
/* Process Del */
TAILQ_FOREACH(msg, &MLACP(csm).arp_list, tail)
{
@@ -161,13 +180,12 @@ static int arp_set_handler(struct CSM* csm,
if (arp_msg->op_type == NEIGH_SYNC_DEL)
continue;
- /* link broken, del all dynamic arp on the lif*/
- iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_msg->ipv4_addr, 0, arp_msg->mac_addr, arp_msg->ifname);
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "Del dynamic ARP [%s]",
- show_ip_str(arp_msg->ipv4_addr));*/
+ err = iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_msg->ipv4_addr, 0, arp_msg->mac_addr, arp_msg->ifname, 0, 5);
+ /* link broken, del all dynamic arp on the lif */
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Del dynamic ARP [%s], status %d", show_ip_str(arp_msg->ipv4_addr), err);
}
- done:
+done:
return 0;
}
@@ -176,6 +194,7 @@ static int ndisc_set_handler(struct CSM *csm, struct LocalInterface *lif, int ad
struct Msg *msg = NULL;
struct NDISCMsg *ndisc_msg = NULL;
char mac_str[18] = "";
+ int err = 0;
if (!csm || !lif)
return 0;
@@ -206,8 +225,8 @@ static int ndisc_set_handler(struct CSM *csm, struct LocalInterface *lif, int ad
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", ndisc_msg->mac_addr[0], ndisc_msg->mac_addr[1], ndisc_msg->mac_addr[2],
ndisc_msg->mac_addr[3], ndisc_msg->mac_addr[4], ndisc_msg->mac_addr[5]);
- iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 1, ndisc_msg->mac_addr, ndisc_msg->ifname);
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add dynamic ND to kernel [%s]", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/
+ err = iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 1, ndisc_msg->mac_addr, ndisc_msg->ifname, 0, 6);
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Add dynamic ND to kernel [%s], status %d", show_ipv6_str((char *)ndisc_msg->ipv6_addr), err);
}
goto done;
@@ -225,9 +244,10 @@ static int ndisc_set_handler(struct CSM *csm, struct LocalInterface *lif, int ad
if (ndisc_msg->op_type == NEIGH_SYNC_DEL)
continue;
+ err = iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 1, ndisc_msg->mac_addr, ndisc_msg->ifname, 0, 7);
+
/* link broken, del all dynamic ndisc on the lif */
- iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_msg->ipv6_addr, 0, ndisc_msg->mac_addr, ndisc_msg->ifname);
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "Del dynamic ND [%s]", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Del dynamic ND [%s], status %d", show_ipv6_str((char *)ndisc_msg->ipv6_addr), err);
}
done:
@@ -309,6 +329,7 @@ static void update_po_if_info(struct CSM *csm,
{
local_if->changed = 1;
local_if->po_active = (po_state != 0);
+
/*printf("update po [%s=%d]\n",local_if->name, local_if->po_active);*/
}
local_if->mlacp_state = MLACP(csm).current_state;
@@ -375,47 +396,129 @@ static int peer_po_is_alive(struct CSM *csm, int po_ifindex)
return pif_active;
}
+// return -1 if failed
+ssize_t iccp_send_to_mclagsyncd(uint8_t msg_type, char *send_buff, uint16_t msg_len)
+{
+ struct System *sys;
+ ssize_t write = 0;
+ int num_retry = 0;
+ size_t pos = 0;
+ int send_len = 0;
+
+ sys = system_get_instance();
+ if (sys == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
+ return MCLAG_ERROR;
+ }
+
+ if (sys->sync_fd)
+ {
+ while (msg_len > 0)
+ {
+ send_len = send(sys->sync_fd, &send_buff[pos], msg_len, MSG_DONTWAIT);
+
+ if (send_len == -1)
+ {
+ if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+ {
+ ++num_retry;
+ if (num_retry > SYNCD_SEND_RETRY_MAX)
+ {
+ ICCPD_LOG_ERR("ICCP_FSM", "Send to mclagsyncd Non-blocking send() retry failed,msg_type: %d msg_len/send_len %d/%d",
+ msg_type, msg_len, send_len);
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(
+ sys, msg_type, ICCP_DBG_CNTR_STS_ERR);
+ return MCLAG_ERROR;
+ }
+ else
+ {
+ usleep(SYNCD_SEND_RETRY_INTERVAL_USEC);
+ send_len = 0;
+ }
+ }
+ else
+ {
+ ICCPD_LOG_ERR("ICCP_FSM", "Send to mclagsyncd Non-blocking send() failed, msg_type: %d errno %d",
+ msg_type, errno);
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(sys, msg_type, ICCP_DBG_CNTR_STS_ERR);
+ return MCLAG_ERROR;
+ }
+ }
+ else if (send_len == 0)
+ {
+ ICCPD_LOG_ERR("ICCP_FSM", "Send to mclagsyncd Non-blocking send() failed socket closed msg_type: %d errno %d",
+ msg_type, errno);
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(
+ sys, msg_type, ICCP_DBG_CNTR_STS_ERR);
+ return MCLAG_ERROR;
+ }
+ msg_len -= send_len;
+ pos += send_len;
+ }
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(sys, msg_type, ICCP_DBG_CNTR_STS_OK);
+ }
+
+ return pos;
+
+}
+
+#if 0
static void mlacp_clean_fdb(void)
{
struct IccpSyncdHDr * msg_hdr;
- char *msg_buf = g_csm_buf;
-
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
+ ssize_t rc;
struct System *sys;
sys = system_get_instance();
if (sys == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
return;
- memset(msg_buf, 0, CSM_BUFFER_SIZE);
+ }
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
msg_hdr = (struct IccpSyncdHDr *)msg_buf;
- msg_hdr->ver = 1;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
msg_hdr->type = MCLAG_MSG_TYPE_FLUSH_FDB;
msg_hdr->len = sizeof(struct IccpSyncdHDr);
if (sys->sync_fd)
- write(sys->sync_fd, msg_buf, msg_hdr->len);
+ {
+ rc = iccp_send_to_mclagsyncd(msg_hdr->type, msg_buf, msg_hdr->len);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Notify mclagsyncd to clear FDB");
+ if (rc <= 0)
+ {
+ ICCPD_LOG_WARN(__FUNCTION__, "Send to Mclagsyncd failed rc: %d",rc);
+ }
+ }
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Notify mclagsyncd to clear FDB");
return;
}
+#endif
void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable)
{
struct IccpSyncdHDr * msg_hdr;
mclag_sub_option_hdr_t * sub_msg;
- char *msg_buf = g_csm_buf;
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
int msg_len;
struct System *sys;
+ ssize_t rc;
sys = system_get_instance();
if (sys == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
return;
+ }
if (!lif)
return;
- memset(msg_buf, 0, CSM_BUFFER_SIZE);
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
msg_hdr = (struct IccpSyncdHDr *)msg_buf;
- msg_hdr->ver = 1;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
msg_hdr->type = MCLAG_MSG_TYPE_PORT_MAC_LEARN_MODE;
msg_hdr->len = sizeof(struct IccpSyncdHDr);
@@ -433,201 +536,735 @@ void set_peerlink_mlag_port_learn(struct LocalInterface *lif, int enable)
msg_hdr->len += sizeof(mclag_sub_option_hdr_t);
msg_hdr->len += sub_msg->op_len;
- ICCPD_LOG_NOTICE(__FUNCTION__, "Send %s port MAC learn msg to mclagsyncd for %s",
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Send %s port MAC learn msg to mclagsyncd for %s",
sub_msg->op_type == MCLAG_SUB_OPTION_TYPE_MAC_LEARN_DISABLE ? "DISABLE":"ENABLE", lif->name);
/*send msg*/
if (sys->sync_fd)
- write(sys->sync_fd, msg_buf, msg_hdr->len);
-
+ {
+ rc = write(sys->sync_fd,msg_buf, msg_hdr->len);
+ if ((rc <= 0) || (rc != msg_hdr->len))
+ {
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(
+ sys, msg_hdr->type, ICCP_DBG_CNTR_STS_ERR);
+ ICCPD_LOG_ERR(__FUNCTION__, "Failed to write for %s, rc %d",
+ lif->name, rc);
+ }
+ else
+ {
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(
+ sys, msg_hdr->type, ICCP_DBG_CNTR_STS_OK);
+ }
+ }
return;
}
-static void set_peerlink_mlag_port_kernel_forward(
- struct CSM *csm,
- struct LocalInterface *lif,
- int enable)
+/* Send request to Mclagsyncd to enable or disable traffic on
+ * MLAG interface
+ */
+static int mlacp_link_set_traffic_dist_mode(
+ char *po_name,
+ bool is_enable)
{
- if (!csm || !csm->peer_link_if || !lif)
- return;
+ struct IccpSyncdHDr *msg_hdr;
+ mclag_sub_option_hdr_t *sub_msg;
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
+ int msg_len;
+ struct System *sys;
+ ssize_t rc = 0;
- char cmd[256] = { 0 };
+ sys = system_get_instance();
+ if (sys == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
+ return MCLAG_ERROR;
+ }
- sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP",
- "-D", csm->peer_link_if->name, lif->name);
- ICCPD_LOG_NOTICE(__FUNCTION__, " ebtable cmd %s", cmd );
- system(cmd);
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
+ msg_hdr->type = is_enable ?
+ MCLAG_MSG_TYPE_SET_TRAFFIC_DIST_ENABLE :
+ MCLAG_MSG_TYPE_SET_TRAFFIC_DIST_DISABLE;
+ msg_hdr->len = sizeof(struct IccpSyncdHDr);
- sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP",
- (enable) ? "-A" : "-D", csm->peer_link_if->name, lif->name);
- ICCPD_LOG_NOTICE(__FUNCTION__, " ebtable cmd %s", cmd );
- system(cmd);
+ /* Sub-message: port-channel name */
+ sub_msg =(mclag_sub_option_hdr_t*) &msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MCLAG_INTF_NAME;
+ sub_msg->op_len = strlen(po_name);
+ memcpy(sub_msg->data, po_name, sub_msg->op_len);
- return;
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
+
+ if (sys->sync_fd)
+ rc = iccp_send_to_mclagsyncd(msg_hdr->type, msg_buf, msg_hdr->len);
+
+ if ((rc <= 0) || (rc != msg_hdr->len))
+ {
+ ICCPD_LOG_ERR(__FUNCTION__,
+ "Failed to write traffic %s for %s, rc %d",
+ is_enable ? "enable" : "disable", po_name, rc);
+ return MCLAG_ERROR;
+ }
+ else
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "%s traffic dist for interface %s",
+ is_enable ? "Enable" : "Disable", po_name);
+ return 0;
+ }
}
-void update_peerlink_isolate_from_all_csm_lif(
- struct CSM* csm)
+/* Send request to Mclagsyncd to update ICCP state
+ * The message includes MLAG id and ICCP state
+ */
+int mlacp_link_set_iccp_state(
+ int mlag_id,
+ bool is_oper_up)
{
- struct LocalInterface *lif = NULL;
- struct IccpSyncdHDr * msg_hdr;
- mclag_sub_option_hdr_t * sub_msg;
- char msg_buf[4096];
- struct System *sys;
-
- char mlag_po_buf[512];
- int src_len = 0, dst_len = 0;
+ struct IccpSyncdHDr *msg_hdr;
+ mclag_sub_option_hdr_t *sub_msg;
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
+ struct System *sys;
+ ssize_t rc = 0;
sys = system_get_instance();
if (sys == NULL)
- return;
-
- if (!csm || !csm->peer_link_if)
- return;
-
- memset(msg_buf, 0, 4095);
- memset(mlag_po_buf, 0, 511);
-
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
+ return MCLAG_ERROR;
+ }
+ /* On startup, session down processing is triggered as part of
+ * peer link info setting before the socket to Mclagsyncd is setup.
+ * Check for valid socket to log a notification instead of an error
+ */
+ if ((sys->sync_fd <= 0) && (!is_oper_up))
+ {
+ ICCPD_LOG_NOTICE(__FUNCTION__,
+ "Unconnected socket to Mclagsyncd, skip mlag %d ICCP down update",
+ mlag_id);
+ return MCLAG_ERROR;
+ }
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
msg_hdr = (struct IccpSyncdHDr *)msg_buf;
- msg_hdr->ver = 1;
- msg_hdr->type = MCLAG_MSG_TYPE_PORT_ISOLATE;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
+ msg_hdr->type = MCLAG_MSG_TYPE_SET_ICCP_STATE;
msg_hdr->len = sizeof(struct IccpSyncdHDr);
- /*sub msg src*/
+ /* Sub-message: mlag ID */
sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
- sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_ISOLATE_SRC;
-
- if (csm->peer_link_if->type == IF_T_VXLAN)
- {
- /*TBD: vxlan tunnel port isolation will be supportted later*/
- return;
-#if 0
- int begin_eth_port = 0;
-
- /*VTTNL0001;Ethernet0001,Ethernet0002*/
- /*src_len= strlen(csm->peer_link_if->name); */
- src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", csm->peer_link_if->name);
- src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", ";");
-
- /*traverse all ethernet port */
- LIST_FOREACH(lif, &(sys->lif_list), system_next)
- {
- if (lif->type != IF_T_PORT)
- continue;
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MCLAG_ID;
+ sub_msg->op_len = sizeof(mlag_id);
+ memcpy(sub_msg->data, &mlag_id, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
- /* need to isolate port, get it's name */
- if (begin_eth_port != 0)
- {
- src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", ",");
- }
+ /* Sub-message: operational status */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_OPER_STATUS;
+ sub_msg->op_len = sizeof(is_oper_up);
+ memcpy(sub_msg->data, &is_oper_up, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
- src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", lif->name);
- begin_eth_port = 1;
- }
- memcpy(sub_msg->data, src_buf, src_len);
+ if (sys->sync_fd)
+ rc = iccp_send_to_mclagsyncd(msg_hdr->type, msg_buf, msg_hdr->len);
- ICCPD_LOG_DEBUG(__FUNCTION__, "isolate src %s, data %s, len %d", src_buf, sub_msg->data, src_len);
-#endif
+ if ((rc <= 0) || (rc != msg_hdr->len))
+ {
+ ICCPD_LOG_ERR(__FUNCTION__,
+ "Failed to write mlag %d, ICCP status %s, rc %d",
+ mlag_id, is_oper_up ? "up" : "down", rc);
+ return MCLAG_ERROR;
}
else
{
- src_len = strlen(csm->peer_link_if->name);
- memcpy(sub_msg->data, csm->peer_link_if->name, src_len);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Set mlag %d, ICCP status %s",
+ mlag_id, is_oper_up ? "up" : "down");
+ return 0;
}
- sub_msg->op_len = src_len;
+}
- /*sub msg dst */
- msg_hdr->len += sub_msg->op_len;
- msg_hdr->len += sizeof(mclag_sub_option_hdr_t);
- sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
- sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_ISOLATE_DST;
+/* Send request to Mclagsyncd to update ICCP role
+ * The message includes MLAG id and ICCP active/standby role. System ID
+ * is also included for active role
+ */
+int mlacp_link_set_iccp_role(
+ int mlag_id,
+ bool is_active_role,
+ uint8_t *system_id)
+{
+ struct IccpSyncdHDr *msg_hdr;
+ mclag_sub_option_hdr_t *sub_msg;
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
+ struct System *sys;
+ ssize_t rc = 0;
- /*traverse all portchannel member port and send msg to syncd */
- LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next)
+ sys = system_get_instance();
+ if (sys == NULL)
{
- if (lif->type != IF_T_PORT_CHANNEL)
- continue;
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
+ return MCLAG_ERROR;
+ }
- /* check pif port state and lif pochannel state */
- if (lif->isolate_to_peer_link == 1)
- {
- /* need to isolate port, get it's member name */
- if (strlen(mlag_po_buf) != 0)
- dst_len += snprintf(mlag_po_buf + dst_len, sizeof(mlag_po_buf) - dst_len, "%s", ",");
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
+ msg_hdr->type = MCLAG_MSG_TYPE_SET_ICCP_ROLE;
+ msg_hdr->len = sizeof(struct IccpSyncdHDr);
- dst_len += snprintf(mlag_po_buf + dst_len, sizeof(mlag_po_buf) - dst_len, "%s", lif->portchannel_member_buf);
- }
- }
+ /* Sub-message: mlag ID */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MCLAG_ID;
+ sub_msg->op_len = sizeof(mlag_id);
+ memcpy(sub_msg->data, &mlag_id, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
- sub_msg->op_len = dst_len;
- msg_hdr->len += sizeof(mclag_sub_option_hdr_t);
- msg_hdr->len += sub_msg->op_len;
+ /* Sub-message: active/standby role */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_ICCP_ROLE;
+ sub_msg->op_len = sizeof(is_active_role);
+ memcpy(sub_msg->data, &is_active_role, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
- if (dst_len)
+ /* Sub-message: system ID if it is active role */
+ if (is_active_role)
{
- memcpy(sub_msg->data, mlag_po_buf, dst_len);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port %s", csm->peer_link_if->name, mlag_po_buf);
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_SYSTEM_ID;
+ sub_msg->op_len = ETHER_ADDR_LEN;
+ memcpy(sub_msg->data, system_id, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
+ }
+ if (sys->sync_fd)
+ rc = iccp_send_to_mclagsyncd(msg_hdr->type, msg_buf, msg_hdr->len);
+
+ if ((rc <= 0) || (rc != msg_hdr->len))
+ {
+ ICCPD_LOG_ERR(__FUNCTION__,
+ "Failed to write mlag %d, ICCP role %s, rc %d",
+ mlag_id, is_active_role ? "active" : "standby", rc);
+ return MCLAG_ERROR;
}
else
{
- ICCPD_LOG_NOTICE(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port is NULL", csm->peer_link_if->name);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Set mlag %d, ICCP role to %s",
+ mlag_id, is_active_role ? "active" : "standby");
+ return 0;
}
-
- /*send msg*/
- if (sys->sync_fd)
- write(sys->sync_fd, msg_buf, msg_hdr->len);
-
- return;
}
-static void set_peerlink_mlag_port_isolate(
- struct CSM *csm,
- struct LocalInterface *lif,
- int enable)
+/* Send request to Mclagsyncd to update ICCP system ID
+ * The message includes MLAG id and system id
+ */
+int mlacp_link_set_iccp_system_id(
+ int mlag_id,
+ uint8_t *system_id)
{
- if (!lif)
- return;
+ struct IccpSyncdHDr *msg_hdr;
+ mclag_sub_option_hdr_t *sub_msg;
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
+ struct System *sys;
+ ssize_t rc = 0;
- lif->isolate_to_peer_link = enable;
+ sys = system_get_instance();
+ if (sys == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
+ return MCLAG_ERROR;
+ }
- if (!csm || !csm->peer_link_if )
- return;
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
+ msg_hdr->type = MCLAG_MSG_TYPE_SET_ICCP_SYSTEM_ID;
+ msg_hdr->len = sizeof(struct IccpSyncdHDr);
- if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE)
- return;
+ /* Sub-message: mlag ID */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MCLAG_ID;
+ sub_msg->op_len = sizeof(mlag_id);
+ memcpy(sub_msg->data, &mlag_id, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
- ICCPD_LOG_DEBUG(__FUNCTION__, "%s port-isolate from %s to %s",
- enable ? "Enable" : "Disable", csm->peer_link_if->name, lif->name);
- update_peerlink_isolate_from_all_csm_lif(csm);
+ /* Sub-message: system ID */
+ sub_msg = (mclag_sub_option_hdr_t*)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_SYSTEM_ID;
+ sub_msg->op_len = ETHER_ADDR_LEN;
+ memcpy(sub_msg->data, system_id, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
- /* Kernel also needs to block traffic from peerlink to mlag-port*/
- set_peerlink_mlag_port_kernel_forward(csm, lif, enable);
+ if (sys->sync_fd)
+ rc = iccp_send_to_mclagsyncd(msg_hdr->type, msg_buf, msg_hdr->len);
- return;
+ if ((rc <= 0) || (rc != msg_hdr->len))
+ {
+ ICCPD_LOG_ERR(__FUNCTION__,
+ "Failed to write mlag %d, ICCP system ID %s, rc %d",
+ mlag_id, mac_addr_to_str(system_id), rc);
+ return MCLAG_ERROR;
+ }
+ else
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__,
+ "Set mlag %d, ICCP system ID to %s",
+ mlag_id, mac_addr_to_str(system_id));
+ return 0;
+ }
}
-void peerlink_port_isolate_cleanup(struct CSM* csm)
+/* Send request to Mclagsyncd to remove MCLAG table entry.
+ * The message includes MLAG id
+ */
+int mlacp_link_del_iccp_info(
+ int mlag_id)
{
- struct LocalInterface *local_if = NULL;
-
- if (!csm)
- return;
+ struct IccpSyncdHDr *msg_hdr;
+ mclag_sub_option_hdr_t *sub_msg;
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
+ struct System *sys;
+ ssize_t rc = 0;
- /* Clean all port block*/
- LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next)
+ sys = system_get_instance();
+ if (sys == NULL)
{
- if (local_if->type == IF_T_PORT_CHANNEL)
- {
- set_peerlink_mlag_port_isolate(csm, local_if, 0);
- }
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
+ return MCLAG_ERROR;
}
- return;
-}
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
+ msg_hdr->type = MCLAG_MSG_TYPE_DEL_ICCP_INFO;
+ msg_hdr->len = sizeof(struct IccpSyncdHDr);
-void update_peerlink_isolate_from_pif(
- struct CSM *csm,
- struct PeerInterface *pif,
+ /* Sub-message: mlag ID */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MCLAG_ID;
+ sub_msg->op_len = sizeof(mlag_id);
+ memcpy(sub_msg->data, &mlag_id, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
+
+ if (sys->sync_fd)
+ rc = send(sys->sync_fd,msg_buf, msg_hdr->len, MSG_DONTWAIT);
+
+ if ((rc <= 0) || (rc != msg_hdr->len))
+ {
+ ICCPD_LOG_ERR(__FUNCTION__,
+ "Failed to write mlag %d delete request, rc %d", mlag_id, rc);
+ return MCLAG_ERROR;
+ }
+ else
+ {
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(sys, msg_hdr->type, ICCP_DBG_CNTR_STS_OK);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "Delete mlag %d", mlag_id);
+ return 0;
+ }
+}
+
+
+/* Send request to Mclagsyncd to update remote interface state
+ * The message includes MLAG id, LAG interface name and operational status
+ */
+int mlacp_link_set_remote_if_state(
+ int mlag_id,
+ char *po_name,
+ bool is_oper_up)
+{
+ struct IccpSyncdHDr *msg_hdr;
+ mclag_sub_option_hdr_t *sub_msg;
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
+ struct System *sys;
+ ssize_t rc = 0;
+
+ sys = system_get_instance();
+ if (sys == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
+ return MCLAG_ERROR;
+ }
+
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
+ msg_hdr->type = MCLAG_MSG_TYPE_SET_REMOTE_IF_STATE;
+ msg_hdr->len = sizeof(struct IccpSyncdHDr);
+
+ /* Sub-message: mlag ID */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MCLAG_ID;
+ sub_msg->op_len = sizeof(mlag_id);
+ memcpy(sub_msg->data, &mlag_id, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
+
+ /* Sub-message: MLAG interface name */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MCLAG_INTF_NAME;
+ sub_msg->op_len = strlen(po_name);
+ memcpy(sub_msg->data, po_name, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
+
+ /* Sub-message: operational status */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_OPER_STATUS;
+ sub_msg->op_len = sizeof(is_oper_up);
+ memcpy(sub_msg->data, &is_oper_up, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
+
+ if (sys->sync_fd)
+ rc = iccp_send_to_mclagsyncd(msg_hdr->type, msg_buf, msg_hdr->len);
+
+ if ((rc <= 0) || (rc != msg_hdr->len))
+ {
+ ICCPD_LOG_ERR(__FUNCTION__,
+ "Failed to write mlag %d, remote if %s status %s, rc %d",
+ mlag_id, po_name, is_oper_up ? "up" : "down", rc);
+ return MCLAG_ERROR;
+ }
+ else
+ {
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(sys, msg_hdr->type, ICCP_DBG_CNTR_STS_OK);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "Set mlag %d, remote if %s status %s",
+ mlag_id, po_name, is_oper_up ? "up" : "down");
+ return 0;
+ }
+}
+
+
+/* Send request to Mclagsyncd to remove remote interface table entry
+ * The message includes MLAG id and remote interface name
+ */
+int mlacp_link_del_remote_if_info(
+ int mlag_id,
+ char *po_name)
+{
+ struct IccpSyncdHDr *msg_hdr;
+ mclag_sub_option_hdr_t *sub_msg;
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
+ struct System *sys;
+ ssize_t rc = 0;
+
+ sys = system_get_instance();
+ if (sys == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
+ return MCLAG_ERROR;
+ }
+
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
+ msg_hdr->type = MCLAG_MSG_TYPE_DEL_REMOTE_IF_INFO;
+ msg_hdr->len = sizeof(struct IccpSyncdHDr);
+
+ /* Sub-message: mlag ID */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MCLAG_ID;
+ sub_msg->op_len = sizeof(mlag_id);
+ memcpy(sub_msg->data, &mlag_id, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
+
+ /* Sub-message: MLAG interface name */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MCLAG_INTF_NAME;
+ sub_msg->op_len = strlen(po_name);
+ memcpy(sub_msg->data, po_name, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
+
+ if (sys->sync_fd)
+ rc = iccp_send_to_mclagsyncd(msg_hdr->type, msg_buf, msg_hdr->len);
+
+ if ((rc <= 0) || (rc != msg_hdr->len))
+ {
+ ICCPD_LOG_ERR(__FUNCTION__,
+ "Failed to write mlag %d, del remote if %s, rc %d",
+ mlag_id, po_name, rc);
+ return MCLAG_ERROR;
+ }
+ else
+ {
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(sys, msg_hdr->type, ICCP_DBG_CNTR_STS_OK);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "Delete mlag %d, remote if %s",
+ mlag_id, po_name);
+ return 0;
+ }
+}
+
+/* Send request to Mclagsyncd to update port isolation state
+ * The message includes LAG interface name and enable/disable state
+ */
+int mlacp_link_set_peerlink_port_isolation(
+ int mlag_id,
+ char *po_name,
+ bool is_isolation_enable)
+{
+ struct IccpSyncdHDr *msg_hdr;
+ mclag_sub_option_hdr_t *sub_msg;
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
+ struct System *sys;
+ ssize_t rc = 0;
+
+ sys = system_get_instance();
+ if (sys == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
+ return MCLAG_ERROR;
+ }
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
+ msg_hdr->type = MCLAG_MSG_TYPE_SET_PEER_LINK_ISOLATION;
+ msg_hdr->len = sizeof(struct IccpSyncdHDr);
+
+ /* Sub-message: mlag ID */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MCLAG_ID;
+ sub_msg->op_len = sizeof(mlag_id);
+ memcpy(sub_msg->data, &mlag_id, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
+
+ /* Sub-message: MLAG interface name */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_MCLAG_INTF_NAME;
+ sub_msg->op_len = strlen(po_name);
+ memcpy(sub_msg->data, po_name, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
+
+ /* Sub-message: isolation enable/disable */
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_ISOLATION_STATE;
+ sub_msg->op_len = sizeof(is_isolation_enable);
+ memcpy(sub_msg->data, &is_isolation_enable, sub_msg->op_len);
+ msg_hdr->len += (sizeof(mclag_sub_option_hdr_t) + sub_msg->op_len);
+
+ if (sys->sync_fd)
+ rc = iccp_send_to_mclagsyncd(msg_hdr->type, msg_buf, msg_hdr->len);
+
+ if ((rc <= 0) || (rc != msg_hdr->len))
+ {
+ ICCPD_LOG_ERR(__FUNCTION__,
+ "Failed to write mlag %d, %s port isolation %s, rc %d",
+ mlag_id, po_name, is_isolation_enable ? "enable" : "disable", rc);
+ return MCLAG_ERROR;
+ }
+ else
+ {
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(sys, msg_hdr->type, ICCP_DBG_CNTR_STS_OK);
+ ICCPD_LOG_NOTICE("ICCP_FSM", "Set mlag %d, %s port isolation %s",
+ mlag_id, po_name, is_isolation_enable ? "enable" : "disable");
+ return 0;
+ }
+}
+
+static void set_peerlink_mlag_port_kernel_forward(
+ struct CSM *csm,
+ struct LocalInterface *lif,
+ int enable)
+{
+ if (!csm || !csm->peer_link_if || !lif)
+ return;
+
+ char cmd[256] = { 0 };
+
+ sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP",
+ "-D", csm->peer_link_if->name, lif->name);
+ ICCPD_LOG_DEBUG(__FUNCTION__, " ebtable cmd %s", cmd );
+ system(cmd);
+
+ sprintf(cmd, "ebtables %s FORWARD -i %s -o %s -j DROP",
+ (enable) ? "-I" : "-D", csm->peer_link_if->name, lif->name);
+ ICCPD_LOG_DEBUG(__FUNCTION__, " ebtable cmd %s", cmd );
+ system(cmd);
+
+ return;
+}
+
+void update_peerlink_isolate_from_all_csm_lif(
+ struct CSM* csm)
+{
+ struct LocalInterface *lif = NULL;
+ struct IccpSyncdHDr * msg_hdr;
+ mclag_sub_option_hdr_t * sub_msg;
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
+ struct System *sys;
+
+ char mlag_po_buf[512];
+ int src_len = 0, dst_len = 0;
+ ssize_t rc;
+
+ sys = system_get_instance();
+ if (sys == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
+ return;
+ }
+
+ if (!csm || !csm->peer_link_if)
+ return;
+
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
+ memset(mlag_po_buf, 0, 511);
+
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
+ msg_hdr->type = MCLAG_MSG_TYPE_PORT_ISOLATE;
+ msg_hdr->len = sizeof(struct IccpSyncdHDr);
+
+ /*sub msg src*/
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_ISOLATE_SRC;
+
+ if (csm->peer_link_if->type == IF_T_VXLAN)
+ {
+ /*TBD: vxlan tunnel port isolation will be supportted later*/
+ return;
+#if 0
+ int begin_eth_port = 0;
+
+ /*VTTNL0001;Ethernet0001,Ethernet0002*/
+ /*src_len= strlen(csm->peer_link_if->name); */
+ src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", csm->peer_link_if->name);
+ src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", ";");
+
+ /*traverse all ethernet port */
+ LIST_FOREACH(lif, &(sys->lif_list), system_next)
+ {
+ if (lif->type != IF_T_PORT)
+ continue;
+
+ /* need to isolate port, get it's name */
+ if (begin_eth_port != 0)
+ {
+ src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", ",");
+ }
+
+ src_len += snprintf(src_buf + src_len, sizeof(src_buf) - src_len, "%s", lif->name);
+ begin_eth_port = 1;
+ }
+ memcpy(sub_msg->data, src_buf, src_len);
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "isolate src %s, data %s, len %d", src_buf, sub_msg->data, src_len);
+#endif
+ }
+ else
+ {
+ src_len = strlen(csm->peer_link_if->name);
+ memcpy(sub_msg->data, csm->peer_link_if->name, src_len);
+ }
+ sub_msg->op_len = src_len;
+
+ /*sub msg dst */
+ msg_hdr->len += sub_msg->op_len;
+ msg_hdr->len += sizeof(mclag_sub_option_hdr_t);
+ sub_msg = (mclag_sub_option_hdr_t *)&msg_buf[msg_hdr->len];
+ sub_msg->op_type = MCLAG_SUB_OPTION_TYPE_ISOLATE_DST;
+
+ /*traverse all portchannel member port and send msg to syncd */
+ LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next)
+ {
+ if (lif->type != IF_T_PORT_CHANNEL)
+ continue;
+
+ /* check pif port state and lif pochannel state */
+ if (lif->isolate_to_peer_link == 1)
+ {
+ /* need to isolate port, get it's member name */
+ if (strlen(mlag_po_buf) != 0)
+ dst_len += snprintf(mlag_po_buf + dst_len, sizeof(mlag_po_buf) - dst_len, "%s", ",");
+
+ dst_len += snprintf(mlag_po_buf + dst_len, sizeof(mlag_po_buf) - dst_len, "%s%s%s",
+ lif->name, lif->portchannel_member_buf[0] == 0 ? "" : ",", lif->portchannel_member_buf);
+ }
+ }
+
+ sub_msg->op_len = dst_len;
+ msg_hdr->len += sizeof(mclag_sub_option_hdr_t);
+ msg_hdr->len += sub_msg->op_len;
+
+ if (dst_len)
+ {
+ memcpy(sub_msg->data, mlag_po_buf, dst_len);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port %s", csm->peer_link_if->name, mlag_po_buf);
+ }
+ else
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Send port isolate msg to mclagsyncd, src port %s, dst port is NULL", csm->peer_link_if->name);
+ }
+
+ /*send msg*/
+ if (sys->sync_fd)
+ {
+ rc = write(sys->sync_fd,msg_buf, msg_hdr->len);
+ if ((rc <= 0) || (rc != msg_hdr->len))
+ {
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(
+ sys, msg_hdr->type, ICCP_DBG_CNTR_STS_ERR);
+ ICCPD_LOG_ERR(__FUNCTION__, "Failed to write, rc %d", rc);
+ }
+ else
+ {
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(
+ sys, msg_hdr->type, ICCP_DBG_CNTR_STS_OK);
+ }
+ }
+
+ return;
+}
+
+static void set_peerlink_mlag_port_isolate(
+ struct CSM *csm,
+ struct LocalInterface *lif,
+ int enable,
+ bool is_unbind_pending)
+{
+ if (!lif)
+ return;
+
+ lif->isolate_to_peer_link = enable;
+
+ if (!csm || !csm->peer_link_if )
+ return;
+
+ if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE)
+ return;
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "%s port-isolate from %s to %s",
+ enable ? "Enable" : "Disable", csm->peer_link_if->name, lif->name);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "Set port isolation %s: mlag_if %s, members %s",
+ enable ? "enable" : "disable", lif->name, lif->portchannel_member_buf);
+
+ update_peerlink_isolate_from_all_csm_lif(csm);
+
+ /* Kernel also needs to block traffic from peerlink to mlag-port*/
+ set_peerlink_mlag_port_kernel_forward(csm, lif, enable);
+
+ /* Do not need to send update to Mclagsyncd to update the local
+ * MLAG interface table in STATE_DB because Mclagsyncd will delete
+ * the entry
+ */
+ if (!is_unbind_pending)
+ mlacp_link_set_peerlink_port_isolation(csm->mlag_id, lif->name, enable);
+}
+
+void peerlink_port_isolate_cleanup(struct CSM* csm)
+{
+ struct LocalInterface *local_if = NULL;
+
+ if (!csm)
+ return;
+
+ /* Clean all port block*/
+ LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next)
+ {
+ if (local_if->type == IF_T_PORT_CHANNEL)
+ {
+ set_peerlink_mlag_port_isolate(csm, local_if, 0, false);
+ }
+ }
+
+ return;
+}
+
+void update_peerlink_isolate_from_pif(
+ struct CSM *csm,
+ struct PeerInterface *pif,
int pif_po_state,
int new_create)
{
@@ -667,16 +1304,16 @@ void update_peerlink_isolate_from_pif(
if (pif_po_state == 1)
{
/* both peer-pair link up, enable port-isolate*/
- ICCPD_LOG_DEBUG(__FUNCTION__, "Enable port-isolate from %s to %s",
- csm->peer_link_if->name, lif->name);
- set_peerlink_mlag_port_isolate(csm, lif, 1);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "Enable port-isolate: from peer_link %s to mlag_if %s",
+ csm->peer_link_if->name, lif->name);
+ set_peerlink_mlag_port_isolate(csm, lif, 1, false);
}
else
{
/* local link up, and peer link changes to down, disable port-isolate*/
- ICCPD_LOG_DEBUG(__FUNCTION__, "Disable port-isolate from %s to %s",
- csm->peer_link_if->name, lif->name);
- set_peerlink_mlag_port_isolate(csm, lif, 0);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "Disable port-isolate: from peer_link %s to mlag_if %s",
+ csm->peer_link_if->name, lif->name);
+ set_peerlink_mlag_port_isolate(csm, lif, 0, false);
}
}
else
@@ -711,7 +1348,7 @@ static void update_peerlink_isolate_from_lif(
break;
}
- ICCPD_LOG_DEBUG(__FUNCTION__, "From if %s local(%s) / peer(%s)",
+ ICCPD_LOG_DEBUG(__FUNCTION__, " from local %s local(%s) / peer(%s)",
lif->name, (lif_po_state) ? "up" : "down", (pif_po_state) ? "up" : "down");
if (lif_po_state == 1)
@@ -721,14 +1358,14 @@ static void update_peerlink_isolate_from_lif(
/* both peer-pair link up, enable port-isolate*/
ICCPD_LOG_DEBUG(__FUNCTION__, "Enable port-isolate from %s to %s",
csm->peer_link_if->name, lif->name);
- set_peerlink_mlag_port_isolate(csm, lif, 1);
+ set_peerlink_mlag_port_isolate(csm, lif, 1, false);
}
else
{
/* peer link down, local link changes to up, disable port-isolate*/
ICCPD_LOG_DEBUG(__FUNCTION__, " Disable port-isolate from %s to %s",
csm->peer_link_if->name, lif->name);
- set_peerlink_mlag_port_isolate(csm, lif, 0);
+ set_peerlink_mlag_port_isolate(csm, lif, 0, false);
}
}
else
@@ -750,14 +1387,8 @@ static void update_l2_po_state(struct CSM *csm,
if (!csm || !lif)
return;
- /*L2 po*/
- /*if (po_state != lif->po_active && po_state == 0)
- {
- mlacp_clean_fdb();
- }*/
-
/*Is there any L3 vlan over L2 po?*/
- LIST_FOREACH(vlan, &(lif->vlan_list), port_next)
+ RB_FOREACH (vlan, vlan_rb_tree, &(lif->vlan_tree))
{
route_type = ROUTE_NONE;
@@ -869,6 +1500,7 @@ void syn_arp_info_to_peer(struct CSM *csm, struct LocalInterface *local_if)
arp_msg = (struct ARPMsg*)msg->buf;
arp_msg->op_type = NEIGH_SYNC_ADD;
+ arp_msg->flag = 0;
if (iccp_csm_init_msg(&msg_send, (char*)arp_msg, sizeof(struct ARPMsg)) == 0)
{
@@ -878,7 +1510,7 @@ void syn_arp_info_to_peer(struct CSM *csm, struct LocalInterface *local_if)
}
else
ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ARP[ADD] for %s",
- show_ip_str(arp_msg->ipv4_addr));
+ show_ip_str(htonl(arp_msg->ipv4_addr)));
}
}
@@ -905,19 +1537,21 @@ void syn_ndisc_info_to_peer(struct CSM *csm, struct LocalInterface *local_if)
ndisc_msg = (struct NDISCMsg *)msg->buf;
ndisc_msg->op_type = NEIGH_SYNC_ADD;
+ ndisc_msg->flag = 0;
if (iccp_csm_init_msg(&msg_send, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0)
{
TAILQ_INSERT_TAIL(&(MLACP(csm).ndisc_msg_list), msg_send, tail);
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));*/
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
}
else
- ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue ND[ADD] for %s", show_ipv6_str((char *)ndisc_msg->ipv6_addr));
}
}
return;
}
+
void update_stp_peer_link(struct CSM *csm,
struct PeerInterface *pif,
int po_state, int new_create)
@@ -927,6 +1561,12 @@ void update_stp_peer_link(struct CSM *csm,
if (!csm || !pif)
return;
+
+ ICCPD_LOG_DEBUG("ICCP_FSM",
+ "PEER_MLAG_IF %s %s: po_active %d, new_state %s, sync_state %s",
+ pif->name, new_create ? "add" : "update",
+ pif->po_active, po_state ? "up" : "down", mlacp_state(csm));
+
if (new_create == 0 && po_state == pif->po_active)
return;
@@ -952,7 +1592,7 @@ void update_stp_peer_link(struct CSM *csm,
}
else
{
- LIST_FOREACH(vlan, &(lif->vlan_list), port_next)
+ RB_FOREACH(vlan, vlan_rb_tree, &(lif->vlan_tree))
{
if (!is_local_vlan_on(vlan))
continue;
@@ -979,255 +1619,471 @@ void update_stp_peer_link(struct CSM *csm,
break;
}
-
return;
}
-void iccp_get_fdb_change_from_syncd( void)
+void iccp_send_fdb_entry_to_syncd( struct MACMsg* mac_msg, uint8_t mac_type, uint8_t oper)
{
struct IccpSyncdHDr * msg_hdr;
- char msg_buf[512];
+ char *msg_buf = g_iccp_mlagsyncd_send_buf;
struct System *sys;
+ struct mclag_fdb_info * mac_info;
+ ssize_t rc;
+ uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
sys = system_get_instance();
if (sys == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
return;
+ }
- memset(msg_buf, 0, 512);
-
- msg_hdr = (struct IccpSyncdHDr *)msg_buf;
- msg_hdr->ver = 1;
- msg_hdr->type = MCLAG_MSG_TYPE_GET_FDB_CHANGES;
- msg_hdr->len = sizeof(struct IccpSyncdHDr);
-
- ICCPD_LOG_DEBUG(__FUNCTION__, "Send get fdb change msg to mclagsyncd");
-
- /*send msg*/
- if (sys->sync_fd > 0)
- write(sys->sync_fd, msg_buf, msg_hdr->len);
-
- return;
-}
-
-void iccp_send_fdb_entry_to_syncd( struct MACMsg* mac_msg, uint8_t mac_type)
-{
- struct IccpSyncdHDr * msg_hdr;
- char msg_buf[512];
- struct System *sys;
- struct mclag_fdb_info * mac_info;
-
- sys = system_get_instance();
- if (sys == NULL)
+ if (memcmp(mac_msg->mac_addr, null_mac, ETHER_ADDR_LEN) == 0)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid MAC address do not send to Syncd.");
return;
+ }
- memset(msg_buf, 0, 512);
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_SEND_MSG_BUFFER_SIZE);
msg_hdr = (struct IccpSyncdHDr *)msg_buf;
- msg_hdr->ver = 1;
+ msg_hdr->ver = ICCPD_TO_MCLAGSYNCD_HDR_VERSION;
msg_hdr->type = MCLAG_MSG_TYPE_SET_FDB;
/*mac msg */
mac_info = (struct mclag_fdb_info *)&msg_buf[sizeof(struct IccpSyncdHDr)];
mac_info->vid = mac_msg->vid;
memcpy(mac_info->port_name, mac_msg->ifname, MAX_L_PORT_NAME);
- memcpy(mac_info->mac, mac_msg->mac_str, ETHER_ADDR_STR_LEN);
+ memcpy(mac_info->mac, mac_msg->mac_addr, ETHER_ADDR_LEN);
mac_info->type = mac_type;
- mac_info->op_type = mac_msg->op_type;
+ mac_info->op_type = oper;
msg_hdr->len = sizeof(struct IccpSyncdHDr) + sizeof(struct mclag_fdb_info);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Send mac %s msg to mclagsyncd, vid %d ; ifname %s ; mac %s; type %s",
- mac_info->op_type == MAC_SYNC_ADD ? "add" : "del", mac_info->vid, mac_info->port_name, mac_info->mac, mac_info->type == MAC_TYPE_STATIC ? "static" : "dynamic");
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Send fdb to syncd: write mac msg vid : %d ; ifname %s ; mac %s fdb type %d ; op type %s",
+ mac_info->vid, mac_info->port_name, mac_addr_to_str(mac_info->mac), mac_info->type,
+ oper == MAC_SYNC_ADD ? "add" : "del");
/*send msg*/
if (sys->sync_fd > 0 )
- write(sys->sync_fd, msg_buf, msg_hdr->len);
+ {
+ rc = iccp_send_to_mclagsyncd(msg_hdr->type, msg_buf, msg_hdr->len);
+ if (rc <= 0)
+ {
+ ICCPD_LOG_WARN(__FUNCTION__, "Send to Mclagsyncd failed rc: %d",rc);
+ }
+ }
+ else
+ {
+ SYSTEM_SET_SYNCD_TX_DBG_COUNTER(sys, msg_hdr->type, ICCP_DBG_CNTR_STS_ERR);
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid sync_fd Failed to write, fd %d", sys->sync_fd);
+ }
+
+ if (oper == MAC_SYNC_DEL)
+ mac_msg->add_to_syncd = 0;
+ else
+ mac_msg->add_to_syncd = 1;
return;
}
void add_mac_to_chip(struct MACMsg* mac_msg, uint8_t mac_type)
{
- mac_msg->op_type = MAC_SYNC_ADD;
- iccp_send_fdb_entry_to_syncd( mac_msg, mac_type);
+ iccp_send_fdb_entry_to_syncd( mac_msg, mac_type, MAC_SYNC_ADD);
return;
}
void del_mac_from_chip(struct MACMsg* mac_msg)
{
- mac_msg->op_type = MAC_SYNC_DEL;
- iccp_send_fdb_entry_to_syncd( mac_msg, mac_msg->fdb_type);
+ iccp_send_fdb_entry_to_syncd( mac_msg, mac_msg->fdb_type, MAC_SYNC_DEL);
return;
}
-uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg* mac_msg, uint8_t set )
+uint8_t set_mac_local_age_flag(struct CSM *csm, struct MACMsg* mac_msg, uint8_t set, uint8_t update_peer )
{
uint8_t new_age_flag = 0;
- struct Msg *msg = NULL;
new_age_flag = mac_msg->age_flag;
if (set == 0)/*remove age flag*/
{
- new_age_flag &= ~MAC_AGE_LOCAL;
+ if (new_age_flag & MAC_AGE_LOCAL)
+ {
+ new_age_flag &= ~MAC_AGE_LOCAL;
- ICCPD_LOG_DEBUG(__FUNCTION__, "Remove local age flag: %d ifname %s, add %s vlan-id %d, age_flag %d",
- new_age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "After Remove local age, flag: %d interface %s, "
+ "add %s vlan-id %d, old age_flag %d", new_age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->age_flag);
- /*send mac MAC_SYNC_ADD message to peer*/
- if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
- {
- mac_msg->op_type = MAC_SYNC_ADD;
- if (iccp_csm_init_msg(&msg, (char*)mac_msg, sizeof(struct MACMsg)) == 0)
+ /*send mac MAC_SYNC_ADD message to peer*/
+ if ((MLACP(csm).current_state == MLACP_STATE_EXCHANGE) && update_peer)
{
- TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg, tail);
+ mac_msg->op_type = MAC_SYNC_ADD;
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), mac_msg, tail);
+ }
/*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d",
mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/
}
- else
+ }
+ }
+ else/*set age flag*/
+ {
+ if (!(new_age_flag & MAC_AGE_LOCAL))
+ {
+ new_age_flag |= MAC_AGE_LOCAL;
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "After local age set, flag: %d interface %s, "
+ "MAC %s vlan-id %d, old age_flag %d", new_age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->age_flag);
+
+ /*send mac MAC_SYNC_DEL message to peer*/
+ if ((MLACP(csm).current_state == MLACP_STATE_EXCHANGE) && update_peer)
{
- ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue MAC-msg-list: %s, add %s vlan-id %d, age_flag %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);
+ mac_msg->op_type = MAC_SYNC_DEL;
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), mac_msg, tail);
}
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Set local age: MAC-msg-list enqueue interface: %s, oper: %s "
+ "MAC %s vlan-id %d, age_flag %d", mac_msg->ifname,
+ (mac_msg->op_type == MAC_SYNC_ADD) ? "add":"del",
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->age_flag);
+ }
}
}
- else/*set age flag*/
+ return new_age_flag;
+}
+
+/*Deal with mac add,del,move when portchannel up or down*/
+static void update_l2_mac_state(struct CSM *csm,
+ struct LocalInterface *lif,
+ int po_state)
+{
+ struct MACMsg* mac_msg = NULL, *mac_temp = NULL;
+ struct PeerInterface* pif = NULL;
+ pif = peer_if_find_by_name(csm, lif->name);
+
+ if (!csm || !lif)
+ return;
+
+ if (po_state == 0)
+ {
+ lif->po_down_time = time(NULL);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf down, ifname: %s, po_down_time: %u", lif->name, lif->po_down_time);
+ }
+ else
{
- new_age_flag |= MAC_AGE_LOCAL;
+ lif->po_down_time = 0;
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf up, ifname: %s, clear po_down_time, time %u", lif->name, lif->po_down_time);
+ }
+
- ICCPD_LOG_DEBUG(__FUNCTION__, "Add local age flag: %s, add %s vlan-id %d, age_flag %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);
+ RB_FOREACH_SAFE (mac_msg, mac_rb_tree, &MLACP(csm).mac_rb, mac_temp)
+ {
+ /* find the MAC for this interface*/
+ if (strcmp(lif->name, mac_msg->origin_ifname) != 0)
+ continue;
- /*send mac MAC_SYNC_DEL message to peer*/
- if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
+ /*portchannel down*/
+ if (po_state == 0)
{
- mac_msg->op_type = MAC_SYNC_DEL;
- if (iccp_csm_init_msg(&msg, (char*)mac_msg, sizeof(struct MACMsg)) == 0)
+ // MAC is locally learned do not delete MAC, Move to peer_link
+ if ((mac_msg->age_flag == MAC_AGE_PEER) && pif && (pif->state == PORT_STATE_UP))
{
- TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg, tail);
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/
+ if ((strlen(csm->peer_itf_name) != 0) && csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP)
+ {
+ memcpy(mac_msg->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf down, MAC learn local only, age flag %d, "
+ "redirect MAC to peer-link: %s, MAC %s vlan-id %d",
+ mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+
+ add_mac_to_chip(mac_msg, mac_msg->fdb_type);
+ }
+ else
+ {
+ del_mac_from_chip(mac_msg);
+ memcpy(mac_msg->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf down, MAC learn local only, age flag %d, "
+ "can not redirect, del MAC as peer-link %s not available or down, "
+ "MAC %s vlan-id %d", mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ }
+
+ mac_msg->pending_local_del = 1;
+
+ continue;
+ }
+
+ mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1, 1);
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf down, age flag %d, MAC %s, "
+ "vlan-id %d, Interface: %s", mac_msg->age_flag ,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->ifname);
+
+ if (mac_msg->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER))
+ {
+ /*send mac del message to mclagsyncd.*/
+ if (mac_msg->fdb_type != MAC_TYPE_STATIC)
+ del_mac_from_chip(mac_msg);
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf down, del MAC %s, vlan-id %d,"
+ " Interface: %s,", mac_addr_to_str(mac_msg->mac_addr),
+ mac_msg->vid, mac_msg->ifname);
+
+ MAC_RB_REMOVE(mac_rb_tree, &MLACP(csm).mac_rb, mac_msg);
+
+ // free only if not in change list to be send to peer node,
+ // else free is taken care after sending the update to peer
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ free(mac_msg);
+ }
}
else
{
- ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue MAC-msg-list: %s, del %s vlan-id %d, age_flag %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);
+ /*If local is aged but peer is not aged, redirect the mac to peer-link*/
+ if (strlen(csm->peer_itf_name) != 0)
+ {
+ /*Send mac add message to mclagsyncd. fdb_type is not changed*/
+ /*Is need to delete the old item before add?(Old item probably is static)*/
+ if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP)
+ {
+ memcpy(mac_msg->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
+ add_mac_to_chip(mac_msg, mac_msg->fdb_type);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf down, age flag %d, "
+ "redirect MAC to peer-link: %s, MAC %s vlan-id %d",
+ mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ }
+ else
+ {
+ /*must redirect but peerlink is down, del mac from ASIC*/
+ /*if peerlink change to up, mac will add back to ASIC*/
+ del_mac_from_chip(mac_msg);
+ memcpy(mac_msg->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf down, age flag %d, "
+ "can not redirect, del MAC as peer-link: %s down, "
+ "MAC %s vlan-id %d", mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ }
+ }
+ else
+ {
+ /*peer-link is not configured, del mac from ASIC, mac still in mac_rb*/
+ del_mac_from_chip(mac_msg);
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf down, flag %d, peer-link: %s not available, "
+ "MAC %s vlan-id %d", mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ }
+ }
+ }
+ else /*portchannel up*/
+ {
+ /*the old item is redirect to peerlink for portchannel down*/
+ /*when this portchannel up, recover the mac back*/
+ if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0)
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf up, redirect MAC to Interface: %s,"
+ " MAC %s vlan-id %d, age flag: %d ", mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->age_flag);
+
+ if (mac_msg->pending_local_del)
+ mac_msg->pending_local_del = 0;
+
+ /*Remove MAC_AGE_LOCAL flag*/
+ // commenting this code to fix an issue, when interface comes back up dont delete age flag
+ // as the MAC is remote now, delete only if MAC learns again.
+ //mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0, 1);
+
+ /*Reverse interface from peer-link to the original portchannel*/
+ memcpy(mac_msg->ifname, mac_msg->origin_ifname, MAX_L_PORT_NAME);
+
+ /*Send dynamic or static mac add message to mclagsyncd*/
+
+ if (mac_msg->age_flag == MAC_AGE_LOCAL)
+ add_mac_to_chip(mac_msg, mac_msg->fdb_type);
+ else
+ add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC_LOCAL);
+ }
+ else
+ {
+ // Delete the MAC from HW so that it can be re-learned accordingly if traffic is still hitting local node.
+ if (mac_msg->pending_local_del)
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf up, Clear pending MAC: interface: %s, mac %s vlan-id %d, age_flag %d",
+ mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->age_flag);
+
+ del_mac_from_chip(mac_msg);
+
+ // if static dont delete mac
+ if (mac_msg->fdb_type != MAC_TYPE_STATIC)
+ {
+ //TBD do we need to send delete notification to peer .?
+ MAC_RB_REMOVE(mac_rb_tree, &MLACP(csm).mac_rb, mac_msg);
+
+ mac_msg->op_type = MAC_SYNC_DEL;
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ free(mac_msg);
+ }
+ }
+ else
+ mac_msg->pending_local_del = 0;
+ }
+
+// Dont set local learn unless learned from MCLAGSYNCD.
+// When interface is UP MAC addresses gets re-learned
+#if 0
+ /*this may be peerlink is not configured and portchannel is down*/
+ /*when this portchannel up, add the mac back to ASIC*/
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Intf up, add MAC %s to ASIC,"
+ " vlan-id %d Interface %s", mac_addr_to_str(mac_msg->mac_addr),
+ mac_msg->vid, mac_msg->ifname);
+
+ /*Remove MAC_AGE_LOCAL flag*/
+ mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0, 1);
+
+
+ memcpy(mac_msg->ifname, mac_msg->origin_ifname, MAX_L_PORT_NAME);
+
+ /*Send dynamic or static mac add message to mclagsyncd*/
+ add_mac_to_chip(mac_msg, mac_msg->fdb_type);
+#endif
}
}
}
- return new_age_flag;
+ return;
}
-/*Deal with mac add,del,move when portchannel up or down*/
-static void update_l2_mac_state(struct CSM *csm,
- struct LocalInterface *lif,
- int po_state)
+void update_orphan_port_mac(struct CSM *csm,
+ struct LocalInterface *lif,
+ int state)
+{
+ struct MACMsg* mac_msg = NULL, *mac_temp = NULL;
+
+ if (!csm || !lif)
+ return;
+
+ if (!state)
+ return;
+
+ RB_FOREACH_SAFE (mac_msg, mac_rb_tree, &MLACP(csm).mac_rb, mac_temp)
+ {
+ if (strcmp(mac_msg->origin_ifname, lif->name ) != 0)
+ continue;
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Orphan port is UP sync MAC: interface %s, "
+ "MAC %s vlan-id %d, age flag: %d, exchange state :%d", mac_msg->origin_ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid,
+ mac_msg->age_flag, MLACP(csm).current_state);
+
+ // sync local macs on orphan port , if any
+ if ((mac_msg->age_flag == MAC_AGE_PEER) && (MLACP(csm).current_state == MLACP_STATE_EXCHANGE))
+ {
+ mac_msg->op_type = MAC_SYNC_ADD;
+
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), mac_msg, tail);
+ }
+ }
+ }
+}
+
+void mlacp_convert_remote_mac_to_local(struct CSM *csm, char *po_name)
+{
+ struct MACMsg* mac_msg = NULL, *mac_temp = NULL;
+ struct LocalInterface* lif = NULL;
+ lif = local_if_find_by_name(po_name);
+
+ if (!csm || !lif)
+ return;
+
+ if (lif->state == PORT_STATE_DOWN)
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Do not Convert remote mac as Local interface %s is down", po_name);
+ return;
+ }
+
+ RB_FOREACH_SAFE (mac_msg, mac_rb_tree, &MLACP(csm).mac_rb, mac_temp)
+ {
+ if (strcmp(mac_msg->origin_ifname, po_name) != 0)
+ continue;
+
+ // convert only remote macs.
+ if (mac_msg->age_flag == MAC_AGE_LOCAL)
+ {
+ mac_msg->age_flag = MAC_AGE_PEER;
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Convert remote mac on Origin Interface as local: interface %s, "
+ "interface %s, MAC %s vlan-id %d age flag:%d", mac_msg->origin_ifname,
+ mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->age_flag);
+
+ /*Send mac add message to mclagsyncd with aging enabled*/
+ add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC_LOCAL);
+
+ mac_msg->op_type = MAC_SYNC_ADD;
+
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), mac_msg, tail);
+ }
+ }
+ }
+}
+
+//update remote macs to point to peerlink, if peer link is configured
+static void update_remote_macs_to_peerlink(struct CSM *csm, struct LocalInterface *lif)
{
- struct Msg* msg = NULL;
- struct MACMsg* mac_msg = NULL;
+ struct MACMsg* mac_entry = NULL;
if (!csm || !lif)
return;
- TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail)
+ RB_FOREACH (mac_entry, mac_rb_tree, &MLACP(csm).mac_rb)
{
- mac_msg = (struct MACMsg*)msg->buf;
-
/* find the MAC for this interface*/
- if (strcmp(lif->name, mac_msg->origin_ifname) != 0)
+ if (strcmp(lif->name, mac_entry->origin_ifname) != 0)
continue;
- /*portchannel down*/
- if (po_state == 0)
+ //consider only remote mac; rest of MACs no need to handle
+ if(mac_entry->age_flag & MAC_AGE_PEER)
{
- ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, age local MAC %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
-
- mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1);
-
- if (mac_msg->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER))
- {
- /*send mac del message to mclagsyncd.*/
- if (mac_msg->fdb_type != MAC_TYPE_STATIC)
- del_mac_from_chip(mac_msg);
+ continue;
+ }
- ICCPD_LOG_DEBUG(__FUNCTION__, "Intf %s down, del MAC %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Update remote macs to peer: age flag %d, MAC %s, "
+ "vlan-id %d, Interface: %s", mac_entry->age_flag ,
+ mac_addr_to_str(mac_entry->mac_addr), mac_entry->vid, mac_entry->ifname);
- /*If local and peer both aged, del the mac*/
- TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail);
- free(msg->buf);
- free(msg);
- }
- else
+ //If local interface unbinded, redirect the mac to peer-link if peer
+ //link is configured
+ if (strlen(csm->peer_itf_name) != 0)
+ {
+ /*Send mac add message to mclagsyncd. fdb_type is not changed*/
+ if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP)
{
- /*If local is aged but peer is not aged, redirect the mac to peer-link*/
- if (strlen(csm->peer_itf_name) != 0)
- {
- /*Send mac add message to mclagsyncd. fdb_type is not changed*/
- /*Is need to delete the old item before add?(Old item probably is static)*/
- if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP)
- {
- memcpy(mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ);
- add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC);
- }
- else
- {
- /*must redirect but peerlink is down, del mac from ASIC*/
- /*if peerlink change to up, mac will add back to ASIC*/
- del_mac_from_chip(mac_msg);
- memcpy(mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ);
- }
-
- ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, redirect MAC %s vlan-id %d to peer-link %s",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, csm->peer_itf_name);
- }
- else
+ //if the mac is already pointing to peer interface, no need to
+ //change it
+ if (strcmp(mac_entry->ifname, csm->peer_itf_name) != 0)
{
- /*peer-link is not configured, del mac from ASIC, mac still in mac_list*/
- del_mac_from_chip(mac_msg);
-
- ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s down, peer-link is not configured: MAC %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
+ memcpy(mac_entry->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
+ add_mac_to_chip(mac_entry, mac_entry->fdb_type);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Update remote macs to peer: age flag %d, "
+ "redirect MAC to peer-link: %s, MAC %s vlan-id %d",
+ mac_entry->age_flag, mac_entry->ifname,
+ mac_addr_to_str(mac_entry->mac_addr), mac_entry->vid);
}
}
}
- else /*portchannel up*/
- {
- /*the old item is redirect to peerlink for portchannel down*/
- /*when this portchannel up, recover the mac back*/
- if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0)
- {
- ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s up, redirect MAC %s vlan-id %d from peerlink to %s",
- mac_msg->origin_ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->origin_ifname);
-
- /*Remove MAC_AGE_LOCAL flag*/
- mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0);
-
- /*Reverse interface from peer-link to the original portchannel*/
- memcpy(mac_msg->ifname, mac_msg->origin_ifname, MAX_L_PORT_NAME);
-
- /*Send dynamic or static mac add message to mclagsyncd*/
- add_mac_to_chip(mac_msg, mac_msg->fdb_type);
- }
- else
- {
- /*this may be peerlink is not configured and portchannel is down*/
- /*when this portchannel up, add the mac back to ASIC*/
- ICCPD_LOG_NOTICE(__FUNCTION__, "Intf %s up, add MAC %s vlan-id %d to ASIC",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
-
- /*Remove MAC_AGE_LOCAL flag*/
- mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0);
-
- /*Send dynamic or static mac add message to mclagsyncd*/
- add_mac_to_chip(mac_msg, mac_msg->fdb_type);
- }
- }
}
-
return;
}
@@ -1237,6 +2093,13 @@ void mlacp_portchannel_state_handler(struct CSM* csm,
{
if (!csm || !local_if)
return;
+ ICCPD_LOG_DEBUG("ICCP_FSM",
+ "MLAG_IF(%s) %s %s: state %s, po_active %d, traffic_dis %d, sync_state %s cfg_sync/changed %d/%d",
+ local_if_is_l3_mode(local_if) ? "L3" : "L2",
+ local_if->name, po_state ? "up" : "down",
+ (local_if->state == PORT_STATE_UP) ? "up" : "down",
+ local_if->po_active, local_if->is_traffic_disable,
+ mlacp_state(csm), local_if->port_config_sync, local_if->changed);
update_peerlink_isolate_from_lif(csm, local_if, po_state);
@@ -1249,60 +2112,94 @@ void mlacp_portchannel_state_handler(struct CSM* csm,
update_po_if_info(csm, local_if, po_state);
+ /* Disable packet tx/rx on MLAG interface when it is down
+ * Traffic is re-enabled back after the interface is up and ack is
+ * received from peer
+ */
+ if (po_state == 0)
+ mlacp_link_disable_traffic_distribution(local_if);
+
return;
}
-static void mlacp_conn_handler_fdb(struct CSM* csm)
+void mlacp_mlag_intf_detach_handler(struct CSM* csm, struct LocalInterface* local_if)
{
- struct Msg* msg = NULL;
- struct MACMsg* mac_msg = NULL;
- struct Msg *msg_send = NULL;
-
- if (!csm)
+ if (!csm || !local_if)
return;
- if (!TAILQ_EMPTY(&(MLACP(csm).mac_list)))
- {
- TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail)
- {
- mac_msg = (struct MACMsg*)msg->buf;
+ ICCPD_LOG_DEBUG("ICCP_FSM",
+ "MLAG_IF(%s) %s Detach: state %s, po_active %d, traffic_dis %d, sync_state %s",
+ local_if_is_l3_mode(local_if) ? "L3" : "L2",
+ local_if->name,
+ (local_if->state == PORT_STATE_UP) ? "up" : "down",
+ local_if->po_active, local_if->is_traffic_disable,
+ mlacp_state(csm));
- /*Wait the ACK from peer?*/
- /*mac_msg->age_flag &= ~MAC_AGE_PEER;*/
+ //set port isolate for lifpo
+ mlacp_mlag_link_del_handler(csm, local_if);
- /*If MAC with local age flag, dont sync to peer. Such MAC only exist when peer is warm-reboot.
- If peer is warm-reboot, peer age flag is not set when connection is lost.
- When MAC is aged in local switch, this MAC is not deleted for no peer age flag.
- After warm-reboot, this MAC must be learnt by peer and sync to local switch*/
- if (!(mac_msg->age_flag & MAC_AGE_LOCAL))
- {
- /*Send mac add message to peer*/
- mac_msg->op_type = MAC_SYNC_ADD;
- if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0)
- {
- mac_msg->age_flag &= ~MAC_AGE_PEER;
- TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail);
- ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
- }
- }
- else
- {
- /*If MAC with local age flag and is point to MCLAG enabled port, reomove local age flag*/
- if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0)
- {
- ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list not enqueue for local age flag: %s, mac %s vlan-id %d, remove local age flag",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
- mac_msg->age_flag &= ~MAC_AGE_LOCAL;
- }
- }
+ //point remotely learnt macs to peer-link
+ update_remote_macs_to_peerlink(csm, local_if);
+
+ //Handle Route/ARP changes as if portchannel is down
+ if (!local_if_is_l3_mode(local_if))
+ update_l2_po_state(csm, local_if, 0);
+ else
+ update_l3_po_state(csm, local_if, 0);
+
+
+ //If the traffic is disabled due to interface flap; while coming up, if
+ //mclag interface is removed before receiving ack, it will be in
+ //blocked state; to address timing scenario unblock Tx/Rx of
+ //traffic on this portchannel if the traffic is blocked on this port
+ if(local_if->is_traffic_disable)
+ {
+ if ( !csm->peer_link_if || !(strcmp(csm->peer_link_if->name, local_if->name)) )
+ {
+ mlacp_link_enable_traffic_distribution(local_if);
}
}
return;
}
-static void mlacp_fix_bridge_mac(struct CSM* csm)
+//Handler to handle when mclag interface is deleted on peer end
+void mlacp_peer_mlag_intf_delete_handler(struct CSM* csm, char *mlag_if_name)
+{
+ struct LocalInterface *local_if = NULL;
+ if (!csm)
+ return;
+
+ local_if = local_if_find_by_name(mlag_if_name);
+
+ if (!local_if)
+ return;
+
+ ICCPD_LOG_DEBUG("ICCP_FSM",
+ "MLAG_IF(%s) %s Peer IF Delete Event: state %s, po_active %d, traffic_dis %d, sync_state %s",
+ local_if_is_l3_mode(local_if) ? "L3" : "L2",
+ local_if->name,
+ (local_if->state == PORT_STATE_UP) ? "up" : "down",
+ local_if->po_active, local_if->is_traffic_disable,
+ mlacp_state(csm));
+
+ //if it is standby node change back the mac to its original system mac
+ recover_if_ipmac_on_standby(local_if, 2);
+
+ return;
+}
+
+
+static void mlacp_conn_handler_fdb(struct CSM* csm)
+{
+ if (!csm)
+ return;
+ ICCPD_LOG_DEBUG(__FUNCTION__, " Sync MAC addresses to peer ");
+ mlacp_sync_mac(csm);
+ return;
+}
+
+void mlacp_fix_bridge_mac(struct CSM* csm)
{
char syscmd[128];
int ret = 0;
@@ -1320,7 +2217,7 @@ static void mlacp_fix_bridge_mac(struct CSM* csm)
/*The Bridge mac can not be the same as peer system id, so fix the Bridge MAC address here.*/
sprintf(syscmd, "ip link set dev Bridge address %s > /dev/null 2>&1", macaddr);
ret = system(syscmd);
- ICCPD_LOG_NOTICE(__FUNCTION__, " %s ret = %d", syscmd, ret);
+ ICCPD_LOG_DEBUG(__FUNCTION__, " %s ret = %d", syscmd, ret);
}
return;
@@ -1333,40 +2230,48 @@ static void mlacp_fix_bridge_mac(struct CSM* csm)
void mlacp_peer_conn_handler(struct CSM* csm)
{
struct LocalInterface *lif = NULL;
+ struct PeerInterface* peer_if;
static int once_connected = 0;
struct System* sys = NULL;
+ struct If_info * cif = NULL;
if (!csm)
return;
if ((sys = system_get_instance()) == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
return;
+ }
if (csm->warm_reboot_disconn_time != 0)
{
/*If peer reconnected, reset peer disconnect time*/
csm->warm_reboot_disconn_time = 0;
- ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot and reconnect, reset peer disconnect time!");
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Peer warm reboot and reconnect, reset warm disconnect time!");
}
if (csm->peer_link_if)
{
set_peerlink_mlag_port_learn(csm->peer_link_if, 0);
+ set_peerlink_learn_kernel(csm, 0, 7);
}
+ ICCPD_LOG_NOTICE("ICCP_FSM", "ICCP session up: warm reboot %s, role %s",
+ (sys->warmboot_start == WARM_REBOOT) ? "yes" : "no",
+ (csm->role_type == STP_ROLE_STANDBY) ? "standby" : "active");
+
/*If peer connect again, don't flush FDB*/
if (once_connected == 0)
{
once_connected = 1;
mlacp_fix_bridge_mac(csm);
- /*If warm reboot, don't flush FDB*/
- if (sys->warmboot_start != WARM_REBOOT)
- mlacp_clean_fdb();
+ // do not required to flush FDB
+ //if (sys->warmboot_start != WARM_REBOOT)
+ // mlacp_clean_fdb();
}
- iccp_get_fdb_change_from_syncd();
sys->csm_trans_time = time(NULL);
-
mlacp_conn_handler_fdb(csm);
LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next)
@@ -1377,77 +2282,184 @@ void mlacp_peer_conn_handler(struct CSM* csm)
}
}
+ /* Send ICCP up update to Mclagsyncd */
+ mlacp_link_set_iccp_state(csm->mlag_id, true);
+
+ /* Send remote interface status update to Mclagsyncd */
+ LIST_FOREACH(peer_if, &(MLACP(csm).pif_list), mlacp_next)
+ {
+ mlacp_link_set_remote_if_state(
+ csm->mlag_id, peer_if->name,
+ (peer_if->state == PORT_STATE_UP)? true : false);
+ }
+ /* Port isolation is cleaned up when session goes down via
+ * peerlink_port_isolate_cleanup(). MlagOrch blocks all traffic from
+ * ISL to all MLAG interfaces to avoid packet duplicate and transient
+ * loop to cover the case where peer link is still up when ICCP goes
+ * down. On session up, update port isolation group based on the
+ * latest remote interface state. This is needed to cover the case
+ * where all remote MLAG interfaces are down after ICCP comes back up
+ */
+ update_peerlink_isolate_from_all_csm_lif(csm);
+
+ if (csm->peer_link_if)
+ {
+ update_vlan_if_mac_on_iccp_up(csm->peer_link_if, 1, NULL);
+ }
+
+ sync_unique_ip();
return;
}
-extern void recover_if_ipmac_on_standby(struct LocalInterface* lif_po);
+void mlacp_peer_disconn_fdb_handler(struct CSM* csm)
+{
+ struct MACMsg* mac_msg = NULL, *mac_temp = NULL;
+
+ RB_FOREACH_SAFE (mac_msg, mac_rb_tree, &MLACP(csm).mac_rb, mac_temp)
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "ICCP session down: existing flag %d interface %s, MAC %s vlan-id %d,"
+ " pending_del %s", mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid,
+ (mac_msg->pending_local_del) ? "true":"false");
+
+ if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0)
+ {
+ mac_msg->age_flag |= MAC_AGE_PEER;
+
+ /* local and peer both aged, to be deleted*/
+ // delete peer-link check, delete all remote macs which are aged local and remote.
+ if ((mac_msg->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER)) || mac_msg->pending_local_del)
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "ICCP session down: del MAC pointing to peer_link for %s, "
+ "MAC %s vlan-id %d", mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+
+ /*Send mac del message to mclagsyncd, may be already deleted*/
+ del_mac_from_chip(mac_msg);
+
+ MAC_RB_REMOVE(mac_rb_tree, &MLACP(csm).mac_rb, mac_msg);
+ // free only if not in change list to be send to peer node,
+ // else free is taken care after sending the update to peer
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ free(mac_msg);
+ }
+ }
+ }
+ else
+ {
+ if (!mac_msg->age_flag)
+ {
+ // MAC learned on both nodes convert to local not update to ASIC required.
+ mac_msg->age_flag = MAC_AGE_PEER;
+ ICCPD_LOG_DEBUG("ICCP_FDB", "ICCP session down: MAC learned on both nodes update to local only"
+ " flag %d interface %s, MAC %s vlan-id %d", mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ }
+ else if (mac_msg->age_flag == MAC_AGE_LOCAL)
+ {
+ // MAC is remote pointing to MCLAG PO convert to local
+ add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC_LOCAL);
+ mac_msg->age_flag = MAC_AGE_PEER;
+ ICCPD_LOG_DEBUG("ICCP_FDB", "ICCP session down: MAC is remote convert to local"
+ " flag %d interface %s, MAC %s vlan-id %d", mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ }
+ //else MAC is local (mac_msg->age_flag == MAC_AGE_PEER) no changes required
+ }
+ }
+}
+
void mlacp_peer_disconn_handler(struct CSM* csm)
{
uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
struct LocalInterface* lif = NULL;
+ struct LocalInterface* peer_link_if = NULL;
+ struct PeerInterface* peer_if;
struct Msg* msg = NULL;
- struct MACMsg* mac_msg = NULL;
+ struct MACMsg* mac_msg = NULL, *mac_temp = NULL;
struct System* sys = NULL;
+ uint8_t remote_system_mac[ETHER_ADDR_LEN];
if (!csm)
return;
if ((sys = system_get_instance()) == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
return;
-
+ }
+ if (MLACP(csm).current_state != MLACP_STATE_INIT)
+ {
+ ICCPD_LOG_NOTICE("ICCP_FSM",
+ "ICCP session down: warm reboot %s, role %s, sync_state %s",
+ (sys->warmboot_exit == WARM_REBOOT) ? "yes" : "no",
+ (csm->role_type == STP_ROLE_STANDBY) ? "standby" : "active",
+ mlacp_state(csm));
+ }
/*If warm reboot, don't change FDB and MAC address*/
if (sys->warmboot_exit == WARM_REBOOT)
return;
- /*If peer is warm reboot, don't change FDB*/
if (csm->peer_warm_reboot_time != 0)
{
/*If peer disconnected, recover peer to normal reboot for next time*/
csm->peer_warm_reboot_time = 0;
/*peer connection must be establised again within 90s
- from last disconnection for peer warm reboot*/
+ from last disconnection for peer warm reboot*/
time(&csm->warm_reboot_disconn_time);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Peer warm reboot and disconnect, recover to normal reboot for next time!");
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Peer warm reboot and disconnect, recover to normal reboot for next time!");
return;
}
- TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail)
- {
- mac_msg = (struct MACMsg*)msg->buf;
-
- mac_msg->age_flag |= MAC_AGE_PEER;
- ICCPD_LOG_DEBUG(__FUNCTION__, "Add peer age flag: %s, MAC %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
-
- /* find the MAC that the port is peer-link or local and peer both aged, to be deleted*/
- if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0 && mac_msg->age_flag != (MAC_AGE_LOCAL | MAC_AGE_PEER))
- continue;
-
- ICCPD_LOG_NOTICE(__FUNCTION__, "Peer disconnect, del MAC for peer-link: %s, MAC %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
-
- /*Send mac del message to mclagsyncd, may be already deleted*/
- del_mac_from_chip(mac_msg);
+ mlacp_peer_disconn_fdb_handler(csm);
- TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail);
- free(msg->buf);
- free(msg);
- }
+ /* Send ICCP down update to Mclagsyncd before clearing all port isolation
+ * so that mclagsync can differentiate between session down and all remote
+ * MLAG interface down
+ */
+ mlacp_link_set_iccp_state(csm->mlag_id, false);
/* Clean all port block*/
peerlink_port_isolate_cleanup(csm);
+ memset(remote_system_mac, 0, ETHER_ADDR_LEN);
+ memcpy(remote_system_mac, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN);
memcpy(MLACP(csm).remote_system.system_id, null_mac, ETHER_ADDR_LEN);
/*If peer is disconnected, recover the MAC address.*/
- if (csm->role_type == STP_ROLE_STANDBY)
+ LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next)
{
- LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next)
+ if (csm->role_type == STP_ROLE_STANDBY)
+ recover_if_ipmac_on_standby(lif, 3);
+
+ /* Re-enable traffic tx/rx for MLAG interface regardless of its state
+ */
+ if (lif->is_traffic_disable)
{
- recover_if_ipmac_on_standby(lif);
+ mlacp_link_enable_traffic_distribution(lif);
}
}
+ if (csm->peer_link_if)
+ {
+ update_vlan_if_mac_on_iccp_up(csm->peer_link_if, 0, remote_system_mac);
+ }
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Peer disconnect %u times",
+ SYSTEM_GET_SESSION_DOWN_COUNTER(sys));
+ SYSTEM_INCR_SESSION_DOWN_COUNTER(sys);
+
+ /* On standby, system ID is reverted back to its local system ID.
+ * Update Mclagsyncd
+ * */
+ if (csm->role_type == STP_ROLE_STANDBY)
+ mlacp_link_set_iccp_system_id(csm->mlag_id, MLACP(csm).system_id);
+
+ /* Delete remote interface info */
+ LIST_FOREACH(peer_if, &(MLACP(csm).pif_list), mlacp_next)
+ {
+ mlacp_link_del_remote_if_info(csm->mlag_id, peer_if->name);
+ }
return;
}
@@ -1459,20 +2471,21 @@ void mlacp_peerlink_up_handler(struct CSM* csm)
if (!csm)
return;
+ ICCPD_LOG_DEBUG("ICCP_FSM", "PEER_LINK %s up: sync_state %s",
+ csm->peer_itf_name, mlacp_state(csm));
+
/*If peer link up, set all the mac that point to the peer-link in ASIC*/
- TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail)
+ RB_FOREACH (mac_msg, mac_rb_tree, &MLACP(csm).mac_rb)
{
- mac_msg = (struct MACMsg*)msg->buf;
-
/* Find the MAC that the port is peer-link to be added*/
if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0)
continue;
- ICCPD_LOG_NOTICE(__FUNCTION__, "Peer link up, add MAC to ASIC for peer-link: %s, MAC %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Peer link up, add MAC to ASIC for peer-link: %s, "
+ "MAC %s vlan-id %d", mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
/*Send mac add message to mclagsyncd, local age flag is already set*/
- add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC);
+ add_mac_to_chip(mac_msg, mac_msg->fdb_type);
}
return;
@@ -1480,42 +2493,51 @@ void mlacp_peerlink_up_handler(struct CSM* csm)
void mlacp_peerlink_down_handler(struct CSM* csm)
{
- struct Msg* msg = NULL;
+ struct MACMsg* mac_temp = NULL;
struct MACMsg* mac_msg = NULL;
if (!csm)
return;
+ ICCPD_LOG_DEBUG("ICCP_FSM", "PEER_LINK %s down: sync_state %s",
+ csm->peer_itf_name, mlacp_state(csm));
+
/*If peer link down, remove all the mac that point to the peer-link*/
- TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail)
+ RB_FOREACH_SAFE (mac_msg, mac_rb_tree, &MLACP(csm).mac_rb, mac_temp)
{
- mac_msg = (struct MACMsg*)msg->buf;
-
/* Find the MAC that the port is peer-link to be deleted*/
if (strcmp(mac_msg->ifname, csm->peer_itf_name) != 0)
continue;
- ICCPD_LOG_NOTICE(__FUNCTION__, "Peer link down, del MAC for peer-link: %s, MAC %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
+ if (!mac_msg->pending_local_del)
+ mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1, 1);
- mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Peer link down, del MAC for peer-link: %s,"
+ " MAC %s vlan-id %d", mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
/*Send mac del message to mclagsyncd*/
del_mac_from_chip(mac_msg);
- /*If peer is not age, keep the MAC in mac_list, but ASIC is deleted*/
+ /*If peer is not age, keep the MAC in mac_rb, but ASIC is deleted*/
if (mac_msg->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER))
{
/*If local and peer both aged, del the mac*/
- TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail);
- free(msg->buf);
- free(msg);
+ MAC_RB_REMOVE(mac_rb_tree, &MLACP(csm).mac_rb, mac_msg);
+
+ // free only if not in change list to be send to peer node,
+ // else free is taken care after sending the update to peer
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ free(mac_msg);
+ }
}
}
+ SYSTEM_INCR_PEER_LINK_DOWN_COUNTER(system_get_instance());
return;
}
+
/*****************************************
* Po add/remove handler
*
@@ -1527,7 +2549,22 @@ void mlacp_mlag_link_add_handler(struct CSM *csm, struct LocalInterface *lif)
if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE)
return;
- set_peerlink_mlag_port_isolate(csm, lif, 1);
+ //enable peerlink isolation only if the both mclag interfaces are up
+ update_peerlink_isolate_from_lif(csm, lif, lif->po_active);
+
+ //if it is standby node and peer interface is configured, update
+ //standby node mac to active's mac for this lif
+ if (csm->role_type == STP_ROLE_STANDBY)
+ {
+ struct PeerInterface* pif=NULL;
+ pif = peer_if_find_by_name(csm, lif->name);
+
+ if (pif)
+ {
+ update_if_ipmac_on_standby(lif, 4);
+ mlacp_link_set_iccp_system_id(csm->mlag_id, lif->mac_addr);
+ }
+ }
return;
}
@@ -1540,7 +2577,7 @@ void mlacp_mlag_link_del_handler(struct CSM *csm, struct LocalInterface *lif)
if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE)
return;
- set_peerlink_mlag_port_isolate(csm, lif, 0);
+ set_peerlink_mlag_port_isolate(csm, lif, 0, true);
return;
}
@@ -1555,8 +2592,10 @@ int iccp_connect_syncd()
struct epoll_event event;
if ((sys = system_get_instance()) == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
goto conn_fail;
-
+ }
if (sys->sync_fd >= 0)
return 0;
@@ -1565,7 +2604,6 @@ int iccp_connect_syncd()
{
count = 0;
}
-
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
@@ -1602,7 +2640,7 @@ int iccp_connect_syncd()
count = 0;
return 0;
- conn_fail:
+conn_fail:
if (count == 0)
ICCPD_LOG_DEBUG(__FUNCTION__, "Mclag syncd socket connect fail");
@@ -1616,7 +2654,10 @@ void syncd_info_close()
struct System* sys = NULL;
if ((sys = system_get_instance()) == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
return;
+ }
if (sys->sync_fd > 0)
{
@@ -1633,22 +2674,33 @@ int iccp_get_receive_fdb_sock_fd(struct System *sys)
}
/*When received MAC add and del packets from mclagsyncd, update mac information*/
-void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, char *ifname, uint8_t fdb_type, uint8_t op_type)
+void do_mac_update_from_syncd(uint8_t mac_addr[ETHER_ADDR_LEN], uint16_t vid, char *ifname, uint8_t fdb_type, uint8_t op_type)
{
struct System *sys = NULL;
struct CSM *csm = NULL;
struct Msg *msg = NULL;
- struct MACMsg *mac_msg = NULL, *mac_info = NULL;
+ struct MACMsg *mac_msg = NULL, *mac_info = NULL, *new_mac_msg = NULL;
+ struct MACMsg mac_find;
uint8_t mac_exist = 0;
char buf[MAX_BUFSIZE];
size_t msg_len = 0;
uint8_t from_mclag_intf = 0;/*0: orphan port, 1: MCLAG port*/
struct CSM *first_csm = NULL;
+ uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
struct LocalInterface *lif_po = NULL, *mac_lif = NULL;
if (!(sys = system_get_instance()))
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
+ return;
+ }
+
+ if (memcmp(mac_addr, null_mac, ETHER_ADDR_LEN) == 0)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid MAC address from syncd do not add.");
return;
+ }
/* create MAC msg*/
memset(buf, 0, MAX_BUFSIZE);
@@ -1656,12 +2708,24 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch
mac_msg = (struct MACMsg*)buf;
mac_msg->op_type = op_type;
mac_msg->fdb_type = fdb_type;
- sprintf(mac_msg->mac_str, "%s", mac_str);
+ memcpy(mac_msg->mac_addr, mac_addr, ETHER_ADDR_LEN);
mac_msg->vid = vid;
mac_msg->age_flag = 0;
-
- ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC msg from mclagsyncd, vid %d mac %s port %s optype %s ", vid, mac_str, ifname, op_type == MAC_SYNC_ADD ? "add" : "del");
+ mac_msg->pending_local_del = 0;
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: vid %d mac %s port %s type: %d optype %s ",
+ vid, mac_addr_to_str(mac_addr), ifname, fdb_type, op_type == MAC_SYNC_ADD ? "add" : "del");
+ /*Debug*/
+ #if 0
+ /* dump receive MAC info*/
+ fprintf(stderr, "\n======== MAC Update==========\n");
+ fprintf(stderr, " MAC = %s \n", mac_addr_to_str(mac_addr));
+ fprintf(stderr, " vlan id = %d\n", vid);
+ fprintf(stderr, " fdb type = %s\n", fdb_type == MAC_TYPE_STATIC ? "static" : "dynamic");
+ fprintf(stderr, " op type = %s\n", op_type == MAC_SYNC_ADD ? "add" : "del");
+ fprintf(stderr, "==============================\n");
+ #endif
/* Find MLACP itf, may be mclag enabled port-channel*/
LIST_FOREACH(csm, &(sys->csm_list), next)
@@ -1695,20 +2759,23 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch
if (!first_csm)
return;
- /*If support multiple CSM, the MAC list of orphan port must be moved to sys->mac_list*/
+ /*If support multiple CSM, the MAC list of orphan port must be moved to sys->mac_rb*/
csm = first_csm;
- /* find lif MAC+vid*/
- TAILQ_FOREACH(msg, &MLACP(csm).mac_list, tail)
- {
- mac_info = (struct MACMsg*)msg->buf;
+ struct PeerInterface* pif = NULL;
+ pif = peer_if_find_by_name(csm, ifname);
- /*MAC and vid are equal*/
- if (strcmp(mac_info->mac_str, mac_str) == 0 && mac_info->vid == vid)
- {
- mac_exist = 1;
- break;
- }
+ memset(&mac_find, 0, sizeof(struct MACMsg));
+ mac_find.vid = vid;
+ memcpy(mac_find.mac_addr,mac_addr, ETHER_ADDR_LEN);
+
+ mac_info = RB_FIND(mac_rb_tree, &MLACP(csm).mac_rb ,&mac_find);
+ if(mac_info)
+ {
+ mac_exist = 1;
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: RB_FIND success for the MAC entry : %s, "
+ " vid: %d , ifname %s, type: %d, age flag: %d", mac_addr_to_str(mac_info->mac_addr),
+ mac_info->vid, mac_info->ifname, mac_info->fdb_type, mac_info->age_flag );
}
/*handle mac add*/
@@ -1716,25 +2783,70 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch
{
/* Find local itf*/
if (!(mac_lif = local_if_find_by_name(ifname)))
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, " interface %s not present failed "
+ "to add MAC %s vlan %d", ifname, mac_addr_to_str(mac_addr), vid);
return;
+ }
sprintf(mac_msg->ifname, "%s", ifname);
sprintf(mac_msg->origin_ifname, "%s", ifname);
+ /*If the recv mac port is peer-link, no need to handle*/
+ if (strcmp(csm->peer_itf_name, mac_msg->ifname) == 0)
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC learn received on peer_link %s ignore MAC %s vlan %d",
+ mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ return;
+ }
+
/*same MAC exist*/
if (mac_exist)
{
- /*If the recv mac port is peer-link, that is add from iccpd, no need to handle*/
- if (strcmp(csm->peer_itf_name, mac_msg->ifname) == 0)
- {
- return;
- }
-
/*If the current mac port is peer-link, it will handle by port up event*/
/*if(strcmp(csm->peer_itf_name, mac_info->ifname) == 0)
{
return;
}*/
+ if (mac_lif->state == PORT_STATE_DOWN)
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: MAC add received, "
+ "MAC exists interface %s down, MAC %s vlan %d, is mclag interface : %s ",
+ mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid,
+ from_mclag_intf ? "true":"false" );
+
+ // if from mclag intf update mac to point to peer_link.
+ //else ignore mac.
+ if (from_mclag_intf && pif && (pif->state == PORT_STATE_UP))
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: MAC add received, "
+ "MAC exists interface %s down, point to peer link MAC %s, vlan %d, is pending local del : %s ",
+ mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid,
+ mac_info->pending_local_del ? "true":"false" );
+
+ mac_info->pending_local_del = 1;
+ mac_info->fdb_type = mac_msg->fdb_type;
+ memcpy(&mac_info->origin_ifname, mac_msg->ifname, MAX_L_PORT_NAME);
+
+ //existing mac must be pointing to peer_link, else update if info and send to syncd
+ if (strcmp(mac_info->ifname, csm->peer_itf_name) == 0)
+ {
+ add_mac_to_chip(mac_info, mac_msg->fdb_type);
+ }
+ else
+ {
+ // this for the case of MAC move , existing mac may point to different interface.
+ // need to update the ifname and update to syncd.
+ memcpy(&mac_info->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
+ add_mac_to_chip(mac_info, mac_msg->fdb_type);
+ }
+
+ return;
+ }
+
+ //else
+ //Update the MAC
+ }
/* update MAC*/
if (mac_info->fdb_type != mac_msg->fdb_type
@@ -1746,16 +2858,35 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch
sprintf(mac_info->origin_ifname, "%s", mac_msg->ifname);
/*Remove MAC_AGE_LOCAL flag*/
- mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 0);
+ mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 0, 1);
- ICCPD_LOG_DEBUG(__FUNCTION__, "Update MAC for %s, ifname %s", mac_msg->mac_str, mac_msg->ifname);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: Update MAC %s, vlan %d ifname %s",
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->ifname);
+ // MAC is local now Del entry from MCLAG_FDB_TABLE if peer not aged.
+ if (!(mac_msg->age_flag & MAC_AGE_PEER))
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", " MAC update from mclagsyncd: MAC move Update MAC remote to local %s, vlan %d"
+ " ifname %s, del entry from MCLAG_FDB_TABLE",
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->ifname);
+ mac_info->age_flag = MAC_AGE_PEER;
+ del_mac_from_chip(mac_msg);
+ }
}
else
{
/*All info are the same, Remove MAC_AGE_LOCAL flag, then return*/
/*In theory, this will be happened that mac age and then learn*/
- mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 0);
-
+ mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 0, 1);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: Duplicate update MAC %s, vlan %d ifname %s",
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->ifname);
+ // MAC is local now Del entry from MCLAG_FDB_TABLE if peer not aged.
+ if (!(mac_msg->age_flag & MAC_AGE_PEER))
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: Update MAC remote to local %s, vlan %d"
+ " ifname %s, del entry from MCLAG_FDB_TABLE",
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->ifname);
+ del_mac_from_chip(mac_msg);
+ }
return;
}
}
@@ -1763,48 +2894,72 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch
{
/*If the port the mac learn is change to down before the mac
sync to iccp, this mac must be deleted */
- if (mac_lif->state == PORT_STATE_DOWN)
+#if 0
+ if ((mac_lif->state == PORT_STATE_DOWN))
{
- del_mac_from_chip(mac_msg);
+ if ((!from_mclag_intf) && (mac_msg->fdb_type != MAC_TYPE_STATIC))
+ {
+ //ignore mac add
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: mclag interface %s down, MAC %s,"
+ " vlan %d ignore mac add.", ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ return;
+ }
+ }
+#endif
+ // If both local and remote MCLAG interfaces are down, ignore MAC and send delete to HW.
+ if (from_mclag_intf && (mac_lif->state == PORT_STATE_DOWN) && pif && (pif->state == PORT_STATE_DOWN))
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: mclag interface %s down on local and remote ignore MAC %s,"
+ " vlan %d ", ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ del_mac_from_chip(mac_msg);
return;
}
-
/*set MAC_AGE_PEER flag before send this item to peer*/
mac_msg->age_flag |= MAC_AGE_PEER;
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "Add peer age flag: %s, add %s vlan-id %d, age_flag %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: Add peer age flag, age %d interface %s, "
+ "MAC %s vlan-id %d ", mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
mac_msg->op_type = MAC_SYNC_ADD;
- if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
+ /*enqueue mac to mac-list*/
+ if (iccp_csm_init_mac_msg(&new_mac_msg, (char*)mac_msg, msg_len) == 0)
{
- struct Msg *msg_send = NULL;
- if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, msg_len) == 0)
- {
- mac_msg->age_flag &= ~MAC_AGE_PEER;
- TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail);
+ RB_INSERT(mac_rb_tree, &MLACP(csm).mac_rb, new_mac_msg);
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, age_flag %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid, mac_msg->age_flag);*/
- }
- else
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: MAC-list enqueue interface %s, "
+ "MAC %s vlan-id %d", mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+
+ //if port is down do not sync the MAC.
+ // For MAC learned on MCLAG interface point to peer_link.
+ // MAC learned on orphan port save MAC, when Orphan port is UP sync MAC
+ if (mac_lif->state == PORT_STATE_DOWN)
{
- ICCPD_LOG_WARN(__FUNCTION__, "Failed to enqueue MAC-msg-list: %s, MAC %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
+ if (from_mclag_intf && pif && (pif->state == PORT_STATE_UP))
+ {
+ mac_msg->pending_local_del = 1;
+ memcpy(&mac_msg->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
+ add_mac_to_chip(mac_msg, mac_msg->fdb_type);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: mclag interface %s down, MAC %s,"
+ " vlan %d point to peer link %s", ifname, mac_addr_to_str(mac_msg->mac_addr),
+ mac_msg->vid, mac_msg->ifname);
+ }
+ return;
}
- }
- /*enqueue mac to mac-list*/
- if (iccp_csm_init_msg(&msg, (char*)mac_msg, msg_len) == 0)
- {
- TAILQ_INSERT_TAIL(&(MLACP(csm).mac_list), msg, tail);
+ if ((MLACP(csm).current_state == MLACP_STATE_EXCHANGE))
+ {
+ TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), new_mac_msg, tail);
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-list enqueue: %s, add %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);*/
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: MAC-msg-list enqueue interface %s, "
+ "MAC %s vlan-id %d, age_flag %d", new_mac_msg->ifname,
+ mac_addr_to_str(new_mac_msg->mac_addr), new_mac_msg->vid, new_mac_msg->age_flag);
+ }
}
else
- ICCPD_LOG_DEBUG(__FUNCTION__, "Failed to enqueue MAC %s, MAC %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: Failed to enqueue interface %s, MAC %s vlan-id %d",
+ mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
}
}
else/*handle mac del*/
@@ -1815,63 +2970,94 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch
/*orphan port mac or origin from_mclag_intf but state is down*/
if (strcmp(mac_info->ifname, csm->peer_itf_name) == 0)
{
+ if (mac_info->pending_local_del)
+ {
+ //do not delete the MAC.
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: do not del pending MAC on %s(peer-link), "
+ "MAC %s vlan-id %d", mac_info->ifname,
+ mac_addr_to_str(mac_info->mac_addr), mac_info->vid);
+ return;
+ }
/*Set MAC_AGE_LOCAL flag*/
- mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 1);
+ mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 1, 1);
if (mac_info->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER))
{
- ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s(peer-link), del %s vlan-id %d",
- mac_info->ifname, mac_info->mac_str, mac_info->vid);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: Recv MAC del interface %s(peer-link), "
+ "MAC %s vlan-id %d", mac_info->ifname,
+ mac_addr_to_str(mac_info->mac_addr), mac_info->vid);
+
+ if (mac_info->add_to_syncd)
+ {
+ del_mac_from_chip(mac_info);
+ }
/*If peer link is down, del the mac*/
- TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail);
- free(msg->buf);
- free(msg);
+ MAC_RB_REMOVE(mac_rb_tree, &MLACP(csm).mac_rb, mac_info);
+
+ // free only if not in change list to be send to peer node,
+ // else free is taken care after sending the update to peer
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_info, tail))
+ {
+ free(mac_info);
+ }
}
else if (csm->peer_link_if && csm->peer_link_if->state != PORT_STATE_DOWN)
{
/*peer-link learn mac is control by iccpd, ignore the chip del info*/
- add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC);
+ add_mac_to_chip(mac_info, mac_info->fdb_type);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s(peer-link is up), add back %s vlan-id %d",
- mac_info->ifname, mac_info->mac_str, mac_info->vid);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: Recv MAC del interface %s(peer-link is up), "
+ "add back MAC %s vlan-id %d", mac_info->ifname,
+ mac_addr_to_str(mac_info->mac_addr), mac_info->vid);
}
return;
}
/*Add MAC_AGE_LOCAL flag*/
- mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 1);
+ mac_info->age_flag = set_mac_local_age_flag(csm, mac_info, 1, 1);
if (mac_info->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER))
{
- ICCPD_LOG_DEBUG(__FUNCTION__, "Recv MAC del msg: %s, del %s vlan-id %d",
- mac_info->ifname, mac_info->mac_str, mac_info->vid);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: Recv MAC del interface %s, "
+ "MAC %s vlan-id %d", mac_info->ifname,
+ mac_addr_to_str(mac_info->mac_addr), mac_info->vid);
+ //before removing the MAC send del to syncd if added before.
+ if (mac_info->add_to_syncd)
+ {
+ del_mac_from_chip(mac_info);
+ }
/*If local and peer both aged, del the mac (local orphan mac is here)*/
- TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail);
- free(msg->buf);
- free(msg);
+ MAC_RB_REMOVE(mac_rb_tree, &MLACP(csm).mac_rb, mac_info);
+
+ // free only if not in change list to be send to peer node,
+ // else free is taken care after sending the update to peer
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_info, tail))
+ {
+ free(mac_info);
+ }
}
else
{
- ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s, del %s vlan-id %d, peer is not age, add back to chip",
- mac_info->ifname, mac_info->mac_str, mac_info->vid);
-
- mac_info->fdb_type = MAC_TYPE_DYNAMIC;
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: Recv MAC del interface %s, "
+ "MAC %s vlan-id %d, peer is not age, add back to chip",
+ mac_info->ifname, mac_addr_to_str(mac_info->mac_addr), mac_info->vid);
if (from_mclag_intf && lif_po && lif_po->state == PORT_STATE_DOWN)
{
/*If local if is down, redirect the mac to peer-link*/
if (strlen(csm->peer_itf_name) != 0)
{
- memcpy(&mac_info->ifname, csm->peer_itf_name, IFNAMSIZ);
+ memcpy(&mac_info->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP)
{
- add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Recv MAC del msg: %s(down), del %s vlan-id %d, redirect to peer-link",
- mac_info->ifname, mac_info->mac_str, mac_info->vid);
+ add_mac_to_chip(mac_info, mac_info->fdb_type);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "MAC update from mclagsyncd: Recv MAC del interface %s(down), "
+ "MAC %s vlan-id %d, redirect to peer-link",
+ mac_info->ifname, mac_addr_to_str(mac_info->mac_addr), mac_info->vid);
}
}
@@ -1884,7 +3070,7 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch
if (!(mac_lif = local_if_find_by_name(mac_info->ifname)))
return;
if (mac_lif->state == PORT_STATE_UP)
- add_mac_to_chip(mac_info, MAC_TYPE_DYNAMIC);
+ add_mac_to_chip(mac_info, mac_info->fdb_type);
}
}
}
@@ -1892,53 +3078,588 @@ void do_mac_update_from_syncd(char mac_str[ETHER_ADDR_STR_LEN], uint16_t vid, ch
return;
}
-int iccp_receive_fdb_handler_from_syncd(struct System *sys)
+int iccp_mclagsyncd_mclag_domain_cfg_handler(struct System *sys, char *msg_buf)
+{
+ struct IccpSyncdHDr * msg_hdr;
+ struct mclag_domain_cfg_info* cfg_info;
+ int count, i = 0;
+ char system_mac_str[ETHER_ADDR_STR_LEN];
+
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+
+ count = (msg_hdr->len- sizeof(struct IccpSyncdHDr ))/sizeof(struct mclag_domain_cfg_info);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "recv domain cfg msg ; count %d ",count);
+
+ for (i = 0; i < count; i++)
+ {
+ cfg_info = (struct mclag_domain_cfg_info *)((char *)(msg_buf) + sizeof(struct IccpSyncdHDr) + i * sizeof(struct mclag_domain_cfg_info));
+
+ memcpy(system_mac_str, mac_addr_to_str(cfg_info->system_mac), sizeof(system_mac_str));
+
+ ICCPD_LOG_NOTICE(__FUNCTION__, "recv cfg msg ; domain_id:%d op_type:%d attr_bmap:0x%x local_ip:%s peer_ip:%s peer_ifname:%s system_mac:%s session_timeout:%d keepalive_time:%d",cfg_info->domain_id, cfg_info->op_type, cfg_info->attr_bmap, cfg_info->local_ip, cfg_info->peer_ip, cfg_info->peer_ifname, system_mac_str, cfg_info->session_timeout, cfg_info->keepalive_time);
+
+ if (cfg_info->op_type == MCLAG_CFG_OPER_ADD || cfg_info->op_type == MCLAG_CFG_OPER_UPDATE) //mclag domain create/update
+ {
+ if (cfg_info->op_type == MCLAG_CFG_OPER_ADD)
+ {
+ set_mc_lag_by_id(cfg_info->domain_id);
+ set_local_system_id(system_mac_str);
+ }
+
+ if(cfg_info->attr_bmap & MCLAG_CFG_ATTR_SRC_ADDR)
+ {
+ set_local_address(cfg_info->domain_id, cfg_info->local_ip);
+ }
+ if(cfg_info->attr_bmap & MCLAG_CFG_ATTR_PEER_ADDR)
+ {
+ set_peer_address(cfg_info->domain_id, cfg_info->peer_ip);
+ }
+
+ if(cfg_info->attr_bmap & MCLAG_CFG_ATTR_PEER_LINK)
+ {
+ set_peer_link(cfg_info->domain_id, cfg_info->peer_ifname);
+ }
+
+ if(cfg_info->attr_bmap & MCLAG_CFG_ATTR_KEEPALIVE_INTERVAL)
+ {
+ if (cfg_info->keepalive_time != -1)
+ {
+ set_keepalive_time(cfg_info->domain_id, cfg_info->keepalive_time);
+ }
+ else
+ {
+ set_keepalive_time(cfg_info->domain_id, CONNECT_INTERVAL_SEC);
+ }
+ }
+
+ if(cfg_info->attr_bmap & MCLAG_CFG_ATTR_SESSION_TIMEOUT)
+ {
+ if (cfg_info->session_timeout != -1)
+ {
+ set_session_timeout(cfg_info->domain_id, cfg_info->session_timeout);
+ }
+ else
+ {
+ set_session_timeout(cfg_info->domain_id, HEARTBEAT_TIMEOUT_SEC);
+ }
+ }
+ } //MCLAG Domain create/update End
+ else if (cfg_info->op_type == MCLAG_CFG_OPER_DEL) //mclag domain delete
+ {
+ unset_mc_lag_by_id(cfg_info->domain_id);
+ } //MCLAG Domain delete End
+ else if (cfg_info->op_type == MCLAG_CFG_OPER_ATTR_DEL) //mclag domain attribute delete
+ {
+ if(cfg_info->attr_bmap & MCLAG_CFG_ATTR_PEER_LINK)
+ {
+ unset_peer_link(cfg_info->domain_id);
+ }
+ else if(cfg_info->attr_bmap & MCLAG_CFG_ATTR_KEEPALIVE_INTERVAL)
+ {
+ //reset to default
+ set_keepalive_time(cfg_info->domain_id, CONNECT_INTERVAL_SEC);
+ }
+ else if(cfg_info->attr_bmap & MCLAG_CFG_ATTR_SESSION_TIMEOUT)
+ {
+ //reset to default
+ set_session_timeout(cfg_info->domain_id, HEARTBEAT_TIMEOUT_SEC);
+ }
+ else if(cfg_info->attr_bmap & MCLAG_CFG_ATTR_SRC_ADDR)
+ {
+ unset_local_address(cfg_info->domain_id);
+ }
+ else if(cfg_info->attr_bmap & MCLAG_CFG_ATTR_PEER_ADDR)
+ {
+ unset_peer_address(cfg_info->domain_id);
+ }
+ } //MCLAG Domain Attribute delete End
+ }
+
+ return 0;
+}
+
+int iccp_mclagsyncd_mclag_iface_cfg_handler(struct System *sys, char *msg_buf)
+{
+ struct IccpSyncdHDr * msg_hdr;
+ struct mclag_iface_cfg_info* cfg_info;
+ int count, i = 0;
+
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+
+ count = (msg_hdr->len- sizeof(struct IccpSyncdHDr))/sizeof(struct mclag_iface_cfg_info);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "recv domain cfg msg ; count %d ",count);
+
+ for (i =0; idomain_id, cfg_info->op_type, cfg_info->mclag_iface);
+
+ if (cfg_info->op_type == MCLAG_CFG_OPER_ADD)
+ {
+ iccp_cli_attach_mclag_domain_to_port_channel(cfg_info->domain_id, cfg_info->mclag_iface);
+ }
+ else if (cfg_info->op_type == MCLAG_CFG_OPER_DEL)
+ {
+ iccp_cli_detach_mclag_domain_to_port_channel(cfg_info->mclag_iface);
+ }
+ }
+ return 0;
+}
+
+int iccp_mclagsyncd_mclag_unique_ip_cfg_handler(struct System *sys, char *msg_buf)
{
- char *msg_buf = g_csm_buf;
struct IccpSyncdHDr *msg_hdr;
- struct mclag_fdb_info * mac_info;
- size_t pos = 0;
+ struct mclag_unique_ip_cfg_info *cfg_info;
+ struct LocalInterface *lif = NULL;
+ int count = 0, i = 0;
+ int sync_add = 0, is_v4 = 0, is_v6 = 0;
+ struct Unq_ip_If_info* unq_ip_if = NULL;
+
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+
+ count = (msg_hdr->len- sizeof(struct IccpSyncdHDr))/sizeof(struct mclag_unique_ip_cfg_info);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "recv domain cfg msg, count %d ",count);
+
+ for (i =0; iop_type, cfg_info->mclag_unique_ip_ifname);
+
+ if (cfg_info->op_type == MCLAG_CFG_OPER_ADD)
+ {
+ LIST_FOREACH(unq_ip_if, &(sys->unq_ip_if_list), if_next)
+ {
+ if (strcmp(unq_ip_if->name, cfg_info->mclag_unique_ip_ifname) == 0)
+ {
+ break;
+ }
+ }
+
+ if (!unq_ip_if)
+ {
+ unq_ip_if = (struct Unq_ip_If_info *)malloc(sizeof(struct Unq_ip_If_info));
+ if (!unq_ip_if)
+ return -1;
+
+ snprintf(unq_ip_if->name, MAX_L_PORT_NAME, "%s", cfg_info->mclag_unique_ip_ifname);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Add mclag_unique_ip_ifname %s", unq_ip_if->name);
+ LIST_INSERT_HEAD(&(sys->unq_ip_if_list), unq_ip_if, if_next);
+ }
+
+ }
+ else if (cfg_info->op_type == MCLAG_CFG_OPER_DEL)
+ {
+ LIST_FOREACH(unq_ip_if, &(sys->unq_ip_if_list), if_next)
+ {
+ if (strcmp(unq_ip_if->name, cfg_info->mclag_unique_ip_ifname) == 0)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Del mclag_unique_ip_ifname %s", unq_ip_if->name);
+ LIST_REMOVE(unq_ip_if, if_next);
+ free(unq_ip_if);
+ break;
+ }
+ }
+ }
+
+ lif = local_if_find_by_name(cfg_info->mclag_unique_ip_ifname);
+ if (lif)
+ {
+ if (cfg_info->op_type == MCLAG_CFG_OPER_ADD)
+ {
+ lif->is_l3_proto_enabled = true;
+ sync_add = 1;
+ if (lif->ipv4_addr)
+ {
+ is_v4 = 1;
+ }
+
+ if (lif->prefixlen_v6)
+ {
+ is_v6 = 1;
+ }
+ }
+ else if (cfg_info->op_type == MCLAG_CFG_OPER_DEL)
+ {
+ lif->is_l3_proto_enabled = false;
+ sync_add = 0;
+ if (lif->ipv4_addr)
+ {
+ is_v4 = 1;
+ }
+
+ if (lif->prefixlen_v6)
+ {
+ is_v6 = 1;
+ }
+ }
+
+ ICCPD_LOG_DEBUG(__FUNCTION__,"add %d, v4 %d, v6 %d, l3_mode %d, is_l3 %d",
+ sync_add, is_v4, is_v6, lif->l3_mode, local_if_is_l3_mode(lif));
+
+ if (local_if_is_l3_mode(lif))
+ {
+ if (sync_add) {
+ update_vlan_if_mac_on_standby(lif, 6);
+ }
+
+ syn_local_neigh_mac_info_to_peer(lif, sync_add, is_v4, is_v6, 1, 1, 0, 1);
+ } else {
+ if (!sync_add) {
+ recover_vlan_if_mac_on_standby(lif, 6, NULL);
+ syn_local_neigh_mac_info_to_peer(lif, sync_add, is_v4, is_v6, 1, 1, 0, 1);
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+int iccp_mclagsyncd_vlan_mbr_update_handler(struct System *sys, char *msg_buf)
+{
+ struct IccpSyncdHDr * msg_hdr;
+ struct mclag_vlan_mbr_info* vlan_mbr_info;
+ int count, i = 0;
+ int add_count = 0;
+ int del_count = 0;
+
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+
+ count = (msg_hdr->len- sizeof(struct IccpSyncdHDr))/sizeof(struct mclag_vlan_mbr_info);
+
+ for (i =0; iop_type, vlan_mbr_info->vid, vlan_mbr_info->mclag_iface);
+
+ if (vlan_mbr_info->op_type == MCLAG_CFG_OPER_ADD)
+ {
+ vlan_mbrship_change_handler(vlan_mbr_info->vid, vlan_mbr_info->mclag_iface, 1 /*add */);
+ add_count++;
+ }
+ else if (vlan_mbr_info->op_type == MCLAG_CFG_OPER_DEL)
+ {
+ vlan_mbrship_change_handler(vlan_mbr_info->vid, vlan_mbr_info->mclag_iface, 0 /* del */);
+ del_count++;
+ }
+ }
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Rx vlan member update count %d add/delete count: %d/%d", count, add_count, del_count);
+
+ return 0;
+}
+
+int iccp_receive_fdb_handler_from_syncd(struct System *sys, char *msg_buf)
+{
int count = 0;
int i = 0;
- int n = 0;
+ struct IccpSyncdHDr * msg_hdr;
+ struct mclag_fdb_info * mac_info;
+
+ msg_hdr = (struct IccpSyncdHDr *)msg_buf;
+
+ count = (msg_hdr->len- sizeof(struct IccpSyncdHDr))/sizeof(struct mclag_fdb_info);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "recv msg fdb count %d ",count );
+
+ for (i =0; imac, mac_info->vid, mac_info->port_name, mac_info->type, mac_info->op_type);
+ }
+ return 0;
+}
+
+int iccp_mclagsyncd_msg_handler(struct System *sys)
+{
+ int num_bytes_rxed = 0;
+ char *msg_buf = g_iccp_mlagsyncd_recv_buf;
+ struct IccpSyncdHDr * msg_hdr;
+ int pos = 0;
+ int recv_len = 0;
+ int num_retry = 0;
+ errno = 0;
if (sys == NULL)
return MCLAG_ERROR;
+ memset(msg_buf, 0, ICCP_MLAGSYNCD_RECV_MSG_BUFFER_SIZE);
- memset(msg_buf, 0, CSM_BUFFER_SIZE);
+ /* read (max_size - msg_size) so that we have space to
+ accomodate anything remaining in the last message */
+ num_bytes_rxed = recv(sys->sync_fd, msg_buf,
+ ICCP_MLAGSYNCD_RECV_MSG_BUFFER_SIZE - MCLAG_MAX_MSG_LEN, MSG_DONTWAIT );
- n = read(sys->sync_fd, msg_buf, CSM_BUFFER_SIZE);
- if (n <= 0)
+ if (num_bytes_rxed <= 0)
{
- ICCPD_LOG_ERR(__FUNCTION__, "read msg error!!!" );
- return MCLAG_ERROR;
+ // if received count is 0 socket is closed.
+ if (num_bytes_rxed == 0)
+ {
+ ICCPD_LOG_WARN("ICCP_FSM", "Recv fom Mclagsyncd read erro:%d ", num_bytes_rxed);
+ SYSTEM_INCR_RX_READ_SOCK_ZERO_COUNTER(system_get_instance());
+ return MCLAG_ERROR;
+ }
+
+ while( num_bytes_rxed < 0 )
+ {
+ recv_len = recv(sys->sync_fd, msg_buf,
+ ICCP_MLAGSYNCD_RECV_MSG_BUFFER_SIZE - MCLAG_MAX_MSG_LEN, MSG_DONTWAIT );
+
+ if (recv_len == -1)
+ {
+ if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+ {
+ ICCPD_LOG_NOTICE(
+ "ICCP_FSM", "Recv fom Mclagsyncd Non-blocking recv errno %d, num_retry %d",
+ errno, num_retry);
+ ++num_retry;
+ if (num_retry > SYNCD_RECV_RETRY_MAX)
+ {
+ ICCPD_LOG_NOTICE(
+ "ICCP_FSM", "Recv fom Mclagsyncd retry failed recv_len: %d", recv_len);
+ SYSTEM_INCR_RX_RETRY_FAIL_COUNTER(system_get_instance());
+ return MCLAG_ERROR;
+ }
+ else
+ {
+ usleep(SYNCD_RECV_RETRY_INTERVAL_USEC);
+ recv_len = 0;
+ }
+ }
+ else
+ {
+ ICCPD_LOG_NOTICE("ICCP_FSM", "Recv fom Mclagsyncd retry failed recv_len: %d", recv_len);
+ SYSTEM_INCR_HDR_READ_SOCK_ERR_COUNTER(system_get_instance());
+ return MCLAG_ERROR;
+ }
+ }
+ else if (recv_len == 0)
+ {
+ ICCPD_LOG_NOTICE("ICCP_FSM", "Recv fom Mclagsyncd error %d connection closed ", recv_len );
+ SYSTEM_INCR_HDR_READ_SOCK_ZERO_LEN_COUNTER(system_get_instance());
+ return MCLAG_ERROR;
+ }
+
+ num_bytes_rxed += recv_len;
+ }
}
- while (pos < n)
+ num_retry = 0;
+ while (pos < num_bytes_rxed) //iterate through all msgs
{
- msg_hdr = (struct IccpSyncdHDr *)&msg_buf[pos];
- if (msg_hdr->ver != 1 || msg_hdr->type != MCLAG_SYNCD_MSG_TYPE_FDB_OPERATION )
+ if ((num_bytes_rxed - pos) < sizeof(struct IccpSyncdHDr))
+ {
+ int recv_len = 0, len = 0;
+ int pending_len = sizeof(struct IccpSyncdHDr) - (num_bytes_rxed - pos);
+
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Recv fom Mclagsync header less than expected, trying to retrieve %d bytes more ", pending_len);
+
+ while (recv_len < pending_len)
+ {
+ int remaining_len = pending_len-recv_len;
+ len = recv(sys->sync_fd, msg_buf+num_bytes_rxed+recv_len, remaining_len, MSG_DONTWAIT);
+ if (len <= 0)
+ {
+ if (len == 0)
+ {
+ ICCPD_LOG_WARN("ICCP_FSM", "Recv fom Mclagsync header less than expected data read error; recv_len:%d pending_len:%d ", recv_len, pending_len);
+ SYSTEM_INCR_HDR_READ_SOCK_ZERO_LEN_COUNTER(system_get_instance());
+ return MCLAG_ERROR;
+ }
+
+ if (len == -1)
+ {
+ if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+ {
+ ICCPD_LOG_NOTICE(
+ "ICCP_FSM", "Recv fom Mclagsync header less than expected Non-blocking recv errno %d, num_retry %d",
+ errno, num_retry);
+ ++num_retry;
+ if (num_retry > SYNCD_RECV_RETRY_MAX)
+ {
+ ICCPD_LOG_ERR(
+ "ICCP_FSM", "Recv fom Mclagsync header less than expected Non-blocking recv() retry failed, len: %d, errno: %d", len, errno);
+ SYSTEM_INCR_RX_RETRY_FAIL_COUNTER(system_get_instance());
+ return MCLAG_ERROR;
+ }
+ else
+ {
+ usleep(SYNCD_RECV_RETRY_INTERVAL_USEC);
+ len = 0;
+ }
+ }
+ else
+ {
+ ICCPD_LOG_WARN("ICCP_FSM", "Recv fom Mclagsyncd header less than expected error; recv_len:%d errno %d",
+ recv_len, errno);
+ SYSTEM_INCR_HDR_READ_SOCK_ERR_COUNTER(system_get_instance());
+ return MCLAG_ERROR;
+ }
+ }
+ }
+ ICCPD_LOG_NOTICE("ICCP_FSM", "received %d pending bytes", len);
+ recv_len += len;
+ }
+ }
+
+ msg_hdr = (struct IccpSyncdHDr *)(&msg_buf[pos]);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "rcv msg version %d type %d len %d pos:%d num_bytes_rxed:%d ",
+ msg_hdr->ver , msg_hdr->type, msg_hdr->len, pos, num_bytes_rxed);
+
+ if (!msg_hdr->len)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "msg length zero!!!!! ");
+ return MCLAG_ERROR;
+ }
+ if (msg_hdr->ver != 1)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "msg version %d wrong!!!!! ", msg_hdr->ver);
+ pos += msg_hdr->len;
+ continue;
+ }
+ if ((pos + msg_hdr->len) > num_bytes_rxed)
+ {
+ int recv_len = 0, len = 0;
+ int pending_len = pos + msg_hdr->len - num_bytes_rxed;
+
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Recv fom Mclagsyncd msg less than expected, trying to retrieve %d bytes more ",
+ pending_len);
+
+ while (recv_len < pending_len)
+ {
+ int remaining_len = pending_len-recv_len;
+ len = recv(sys->sync_fd, msg_buf+num_bytes_rxed+recv_len, remaining_len, MSG_DONTWAIT);
+ if (len <= 0)
+ {
+ if (len == 0)
+ {
+ ICCPD_LOG_WARN("ICCP_FSM", "Recv fom Mclagsyncd msg less than expected read error; len:%d ",len);
+ SYSTEM_INCR_TLV_READ_SOCK_ZERO_LEN_COUNTER(system_get_instance());
+ return MCLAG_ERROR;
+ }
+
+ if (len == -1)
+ {
+ if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+ {
+ ICCPD_LOG_NOTICE(
+ "ICCP_FSM", "Recv fom Mclagsyncd msg less than expected Non-blocking recv errno %d, num_retry %d",
+ errno, num_retry);
+ ++num_retry;
+ if (num_retry > SYNCD_RECV_RETRY_MAX)
+ {
+ ICCPD_LOG_ERR("ICCP_FSM", "Recv fom Mclagsyncd msg less than expected Non-blocking recv() retry failed len %d",len);
+ SYSTEM_INCR_RX_RETRY_FAIL_COUNTER(system_get_instance());
+ return MCLAG_ERROR;
+ }
+ else
+ {
+ usleep(SYNCD_RECV_RETRY_INTERVAL_USEC);
+ len = 0;
+ }
+ }
+ else
+ {
+ ICCPD_LOG_WARN("ICCP_FSM", "Recv fom Mclagsyncd msg less than expectedread retry error len:%d , errno %d",
+ len, errno);
+ SYSTEM_INCR_TLV_READ_SOCK_ERR_COUNTER(system_get_instance());
+ return MCLAG_ERROR;
+ }
+ }
+
+ }
+ ICCPD_LOG_NOTICE(__FUNCTION__, "received %d pending bytes", len);
+ recv_len += len;
+ }
+ }
+
+ if (msg_hdr->type == MCLAG_SYNCD_MSG_TYPE_FDB_OPERATION)
+ {
+ iccp_receive_fdb_handler_from_syncd(sys, &msg_buf[pos]);
+ }
+ else if (msg_hdr->type == MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_DOMAIN)
+ {
+ iccp_mclagsyncd_mclag_domain_cfg_handler(sys, &msg_buf[pos]);
+ }
+ else if (msg_hdr->type == MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_IFACE)
+ {
+ iccp_mclagsyncd_mclag_iface_cfg_handler(sys, &msg_buf[pos]);
+ }
+ else if (msg_hdr->type == MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_UNIQUE_IP)
+ {
+ iccp_mclagsyncd_mclag_unique_ip_cfg_handler(sys, &msg_buf[pos]);
+ }
+ else if (msg_hdr->type == MCLAG_SYNCD_MSG_TYPE_VLAN_MBR_UPDATES)
{
- ICCPD_LOG_ERR(__FUNCTION__, "msg version or type wrong!!!!! ");
- return MCLAG_ERROR;
+ iccp_mclagsyncd_vlan_mbr_update_handler(sys, &msg_buf[pos]);
}
-
- count = ( msg_hdr->len - sizeof(struct IccpSyncdHDr )) / sizeof(struct mclag_fdb_info);
- ICCPD_LOG_DEBUG(__FUNCTION__, "recv msg fdb count %d ", count);
-
- for (i = 0; i < count; i++)
+ else
{
- mac_info = (struct mclag_fdb_info *)&msg_buf[pos + sizeof(struct IccpSyncdHDr ) + i * sizeof(struct mclag_fdb_info)];
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "recv msg fdb count %d vid %d mac %s port %s optype %s ", i, mac_info->vid, mac_info->mac, mac_info->port_name, mac_info->op_type == MAC_SYNC_ADD ? "add" : "del");*/
- do_mac_update_from_syncd(mac_info->mac, mac_info->vid, mac_info->port_name, mac_info->type, mac_info->op_type);
+ ICCPD_LOG_ERR(__FUNCTION__, "recv unknown msg type %d ", msg_hdr->type);
+ pos += msg_hdr->len;
+ continue;
}
-
pos += msg_hdr->len;
+ SYSTEM_SET_SYNCD_RX_DBG_COUNTER(sys, msg_hdr->type, ICCP_DBG_CNTR_STS_OK);
}
-
return 0;
}
+
+ /*
+ * Send request to Mclagsyncd to disable traffic for MLAG interface
+ */
+ void mlacp_link_disable_traffic_distribution(struct LocalInterface *lif)
+ {
+ int rc;
+
+ /* Update traffic distribution only if local interface is still bound to MLAG */
+ if (!lif || !lif->csm)
+ return;
+
+ /* Expecting ACK from peer only after reaching EXCHANGE state */
+ if (MLACP(lif->csm).current_state != MLACP_STATE_EXCHANGE)
+ return;
+
+ /* Disable traffic distribution for all LAG member ports when LAG goes down.
+ * If MLAG interface goes down again while waiting for i/f up ack,
+ * do not need to update hardware again
+ */
+ if ((lif->type == IF_T_PORT_CHANNEL) && (!lif->po_active) &&
+ (!lif->is_traffic_disable))
+ {
+ rc = mlacp_link_set_traffic_dist_mode(lif->name, false);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "MLAG_IF %s: set traffic disable, rc %d",
+ lif->name, rc);
+ if (rc == 0)
+ lif->is_traffic_disable = true;
+ }
+ }
+
+ /*
+ * Send request to Mclagsyncd to enable traffic for MLAG interface
+ * Note:
+ * 1. Caller should check for LAG up before calling this API in normal case.
+ * 2. For the ICCP session down case or LAG interface is no longer MLAG
+ * interface, this API is called regardless of the LAG state
+ */
+ void mlacp_link_enable_traffic_distribution(struct LocalInterface *lif)
+ {
+ int rc;
+
+ /* Update traffic distribution only if local interface is still bound to MLAG */
+ if (!lif || !lif->csm)
+ return;
+
+ if ((lif->type == IF_T_PORT_CHANNEL) && lif->is_traffic_disable)
+ {
+ rc = mlacp_link_set_traffic_dist_mode(lif->name, true);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "MLAG_IF %s: set traffic enable, rc %d",
+ lif->name, rc);
+ if (rc == 0)
+ lif->is_traffic_disable = false;
+ }
+}
+
char * mclagd_ctl_cmd_str(int req_type)
{
switch (req_type)
@@ -1961,8 +3682,15 @@ char * mclagd_ctl_cmd_str(int req_type)
case INFO_TYPE_DUMP_PEER_PORTLIST:
return "dump peer portlist";
+ case INFO_TYPE_DUMP_DBG_COUNTERS:
+ return "dump debug counters";
+
+ case INFO_TYPE_DUMP_UNIQUE_IP:
+ return "dump unique_ip";
+
case INFO_TYPE_CONFIG_LOGLEVEL:
return "config loglevel";
+
default:
break;
}
@@ -1979,7 +3707,10 @@ int mclagd_ctl_sock_create()
int ret = 0;
if ((sys = system_get_instance()) == NULL)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid system instance");
return MCLAG_ERROR;
+ }
if (sys->sync_ctrl_fd > 0)
return sys->sync_ctrl_fd;
@@ -2259,7 +3990,7 @@ void mclagd_ctl_handle_dump_local_portlist(int client_fd, int mclag_id)
{
char * Pbuf = NULL;
char buf[512] = { 0 };
- int lif_num = 0;;
+ int lif_num = 0;
int ret = 0;
struct mclagd_reply_hdr *hd = NULL;
int len_tmp = 0;
@@ -2335,6 +4066,83 @@ void mclagd_ctl_handle_dump_peer_portlist(int client_fd, int mclag_id)
return;
}
+void mclagd_ctl_handle_dump_dbg_counters(int client_fd, int mclag_id)
+{
+ char * Pbuf = NULL;
+ char buf[512] = {0};
+ int data_len = 0;
+ int ret = 0;
+ struct mclagd_reply_hdr *hd = NULL;
+ int len_tmp = 0;
+
+ ret = iccp_cmd_dbg_counter_dump(&Pbuf, &data_len, mclag_id);
+ if (ret != EXEC_TYPE_SUCCESS)
+ {
+ len_tmp = sizeof(struct mclagd_reply_hdr);
+ memcpy(buf, &len_tmp, sizeof(int));
+ hd = (struct mclagd_reply_hdr *)(buf + sizeof(int));
+ hd->exec_result = ret;
+ hd->info_type = INFO_TYPE_DUMP_DBG_COUNTERS;
+ hd->data_len = 0;
+ mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR);
+
+ if (Pbuf)
+ free(Pbuf);
+ return;
+ }
+
+ hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int));
+ hd->exec_result = EXEC_TYPE_SUCCESS;
+ hd->info_type = INFO_TYPE_DUMP_DBG_COUNTERS;
+ hd->data_len = data_len;
+ len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr));
+ memcpy(Pbuf, &len_tmp, sizeof(int));
+ mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len);
+
+ if (Pbuf)
+ free(Pbuf);
+}
+
+void mclagd_ctl_handle_dump_unique_ip(int client_fd, int mclag_id)
+{
+ char *Pbuf = NULL;
+ char buf[512] = { 0 };
+ int lif_num = 0;
+ int ret = 0;
+ struct mclagd_reply_hdr *hd = NULL;
+ int len_tmp = 0;
+
+ ret = iccp_unique_ip_if_dump(&Pbuf, &lif_num, mclag_id);
+ if (ret != EXEC_TYPE_SUCCESS)
+ {
+ len_tmp = sizeof(struct mclagd_reply_hdr);
+ memcpy(buf, &len_tmp, sizeof(int));
+ hd = (struct mclagd_reply_hdr *)(buf + sizeof(int));
+ hd->exec_result = ret;
+ hd->info_type = INFO_TYPE_DUMP_LOCAL_PORTLIST;
+ hd->data_len = 0;
+ mclagd_ctl_sock_write(client_fd, buf, MCLAGD_REPLY_INFO_HDR);
+
+ if (Pbuf)
+ free(Pbuf);
+
+ return;
+ }
+
+ hd = (struct mclagd_reply_hdr *)(Pbuf + sizeof(int));
+ hd->exec_result = EXEC_TYPE_SUCCESS;
+ hd->info_type = INFO_TYPE_DUMP_UNIQUE_IP;
+ hd->data_len = lif_num * sizeof(struct mclagd_unique_ip_if);
+ len_tmp = (hd->data_len + sizeof(struct mclagd_reply_hdr));
+ memcpy(Pbuf, &len_tmp, sizeof(int));
+ mclagd_ctl_sock_write(client_fd, Pbuf, MCLAGD_REPLY_INFO_HDR + hd->data_len);
+
+ if (Pbuf)
+ free(Pbuf);
+
+ return;
+}
+
void mclagd_ctl_handle_config_loglevel(int client_fd, int log_level)
{
char buf[sizeof(struct mclagd_reply_hdr)+sizeof(int)];
@@ -2389,7 +4197,7 @@ int mclagd_ctl_interactive_process(int client_fd)
case INFO_TYPE_DUMP_MAC:
mclagd_ctl_handle_dump_mac(client_fd, req->mclag_id);
- break;
+ break;
case INFO_TYPE_DUMP_LOCAL_PORTLIST:
mclagd_ctl_handle_dump_local_portlist(client_fd, req->mclag_id);
@@ -2399,6 +4207,14 @@ int mclagd_ctl_interactive_process(int client_fd)
mclagd_ctl_handle_dump_peer_portlist(client_fd, req->mclag_id);
break;
+ case INFO_TYPE_DUMP_DBG_COUNTERS:
+ mclagd_ctl_handle_dump_dbg_counters(client_fd, req->mclag_id);
+ break;
+
+ case INFO_TYPE_DUMP_UNIQUE_IP:
+ mclagd_ctl_handle_dump_unique_ip(client_fd, req->mclag_id);
+ break;
+
case INFO_TYPE_CONFIG_LOGLEVEL:
mclagd_ctl_handle_config_loglevel(client_fd, req->mclag_id);
break;
@@ -2410,4 +4226,339 @@ int mclagd_ctl_interactive_process(int client_fd)
return 0;
}
+int syn_local_mac_info_to_peer(struct CSM* csm, struct LocalInterface *local_if, int sync_add, int is_sag)
+{
+ struct MACMsg mac_msg = {0};
+ int msg_len = 0, rc = MCLAG_ERROR;
+ int vid = 0;
+ uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ if (!csm || !local_if) {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"invalid parameters");
+ return MCLAG_ERROR;
+ }
+
+ if (memcmp(MLACP(csm).system_id, null_mac, ETHER_ADDR_LEN) == 0) {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"invalid system id");
+ return MCLAG_ERROR;
+ }
+
+ if (sync_add) {
+ mac_msg.op_type = MAC_SYNC_ADD;
+ } else {
+ mac_msg.op_type = MAC_SYNC_DEL;
+ }
+
+ if (is_sag) {
+ sscanf (local_if->name,"sag%d.256",&vid);
+ } else {
+ sscanf (local_if->name,"Vlan%d",&vid);
+ }
+
+ mac_msg.vid = vid;
+ mac_msg.fdb_type = MAC_TYPE_STATIC;
+ memcpy(mac_msg.origin_ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
+ memcpy(mac_msg.mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN);
+
+ ICCPD_LOG_DEBUG(__FUNCTION__,"add %d, mac name %s, vid %d", sync_add, mac_msg.origin_ifname, mac_msg.vid);
+ ICCPD_LOG_DEBUG(__FUNCTION__,"mac [%02X:%02X:%02X:%02X:%02X:%02X]",
+ mac_msg.mac_addr[0], mac_msg.mac_addr[1], mac_msg.mac_addr[2], mac_msg.mac_addr[3], mac_msg.mac_addr[4], mac_msg.mac_addr[5]);
+
+ memset(g_csm_buf, 0, CSM_BUFFER_SIZE);
+ msg_len = mlacp_prepare_for_mac_info_to_peer(csm, g_csm_buf, CSM_BUFFER_SIZE, &mac_msg, 0);
+ if (msg_len > 0)
+ rc = iccp_csm_send(csm, g_csm_buf, msg_len);
+
+ if (rc <= 0)
+ {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "failed rc %d, msg_len %d", rc, msg_len);
+ }
+ else
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"success");
+ }
+ return rc;
+}
+
+int syn_local_arp_info_to_peer(struct CSM* csm, struct LocalInterface *local_if, int sync_add, int ack)
+{
+ struct ARPMsg arp_msg = {0};
+ int msg_len = 0, rc = MCLAG_ERROR;
+
+ if (!csm || !local_if) {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"invalid parameters");
+ return MCLAG_ERROR;
+ }
+
+ if (sync_add) {
+ arp_msg.op_type = NEIGH_SYNC_ADD;
+ if (ack) {
+ arp_msg.flag |= NEIGH_SYNC_FLAG_ACK;
+ }
+ } else {
+ arp_msg.op_type = NEIGH_SYNC_DEL;
+ }
+
+ arp_msg.ipv4_addr = local_if->ipv4_addr;
+ arp_msg.flag |= NEIGH_SYNC_FLAG_SELF_IP;
+ memcpy(arp_msg.ifname, local_if->name, MAX_L_PORT_NAME);
+ memcpy(arp_msg.mac_addr, local_if->mac_addr, ETHER_ADDR_LEN);
+
+ ICCPD_LOG_DEBUG(__FUNCTION__," add %d ack %d ifname %s, ip %s", sync_add, ack, arp_msg.ifname, show_ip_str(arp_msg.ipv4_addr));
+ ICCPD_LOG_DEBUG(__FUNCTION__," mac [%02X:%02X:%02X:%02X:%02X:%02X]",
+ arp_msg.mac_addr[0], arp_msg.mac_addr[1], arp_msg.mac_addr[2], arp_msg.mac_addr[3], arp_msg.mac_addr[4], arp_msg.mac_addr[5]);
+
+ memset(g_csm_buf, 0, CSM_BUFFER_SIZE);
+ msg_len = mlacp_prepare_for_arp_info(csm, g_csm_buf, CSM_BUFFER_SIZE, &arp_msg, 0, NEIGH_SYNC_SELF_IP);
+ if (msg_len > 0)
+ rc = iccp_csm_send(csm, g_csm_buf, msg_len);
+
+ if (rc <= 0)
+ {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "failed rc %d, msg_len %d", rc, msg_len);
+ }
+ else
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"success");
+ }
+
+ return rc;
+}
+
+int syn_local_nd_info_to_peer(struct CSM* csm, struct LocalInterface *local_if, int sync_add, int ack, int is_ipv6_ll, int dir)
+{
+ struct NDISCMsg nd_msg = {0};
+ int msg_len = 0, rc = MCLAG_ERROR;
+ uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ if (!csm || !local_if) {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"invalid parameters");
+ return MCLAG_ERROR;
+ }
+
+ if (sync_add) {
+ nd_msg.op_type = NEIGH_SYNC_ADD;
+ if (ack) {
+ nd_msg.flag |= NEIGH_SYNC_FLAG_ACK;
+ }
+ } else {
+ nd_msg.op_type = NEIGH_SYNC_DEL;
+ }
+
+ if (is_ipv6_ll) {
+ if (local_if->ll_prefixlen_v6 == 0) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, " Link Local Address not configured.");
+ return MCLAG_ERROR;
+ }
+ nd_msg.flag |= NEIGH_SYNC_FLAG_SELF_LL;
+ memcpy(nd_msg.ipv6_addr, local_if->ipv6_ll_addr, 16);
+ if (memcmp(MLACP(csm).system_id, null_mac, ETHER_ADDR_LEN) == 0){
+ ICCPD_LOG_NOTICE(__FUNCTION__, " system_id not initialised.");
+ return MCLAG_ERROR;
+ }
+ memcpy(nd_msg.mac_addr, MLACP(csm).system_id, ETHER_ADDR_LEN);
+ } else {
+ nd_msg.flag |= NEIGH_SYNC_FLAG_SELF_IP;
+ memcpy(nd_msg.ipv6_addr, local_if->ipv6_addr, 16);
+ memcpy(nd_msg.mac_addr, local_if->mac_addr, ETHER_ADDR_LEN);
+ }
+ memcpy(nd_msg.ifname, local_if->name, MAX_L_PORT_NAME);
+
+ ICCPD_LOG_DEBUG(__FUNCTION__,"add %d, ack %d, flag %x, is_ll %d, dir %d, ifname %s, ip %s", sync_add, ack,
+ nd_msg.flag, is_ipv6_ll, dir, nd_msg.ifname, show_ipv6_str((char *)nd_msg.ipv6_addr));
+ ICCPD_LOG_DEBUG(__FUNCTION__,"mac [%02X:%02X:%02X:%02X:%02X:%02X]",
+ nd_msg.mac_addr[0], nd_msg.mac_addr[1], nd_msg.mac_addr[2], nd_msg.mac_addr[3], nd_msg.mac_addr[4], nd_msg.mac_addr[5]);
+
+ memset(g_csm_buf, 0, CSM_BUFFER_SIZE);
+ msg_len = mlacp_prepare_for_ndisc_info(csm, g_csm_buf, CSM_BUFFER_SIZE, &nd_msg, 0, NEIGH_SYNC_SELF_IP);
+ if (msg_len > 0)
+ rc = iccp_csm_send(csm, g_csm_buf, msg_len);
+
+ if (rc <= 0)
+ {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "failed rc %d, msg_len %d", rc, msg_len);
+ }
+ else
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"success");
+ }
+
+ return rc;
+}
+
+int syn_local_neigh_mac_info_to_peer(struct LocalInterface *local_if,
+ int sync_add, int is_v4, int is_v6, int sync_mac, int ack, int is_ipv6_ll, int dir)
+{
+ struct System* sys = NULL;
+ struct CSM* csm = NULL;
+
+ if ((sys = system_get_instance()) == NULL) {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"system instance not present, skip sync");
+ return MCLAG_ERROR;
+ }
+
+ while (!LIST_EMPTY(&(sys->csm_list)))
+ {
+ csm = LIST_FIRST(&(sys->csm_list));
+ break;
+ }
+
+ if (!csm) {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"csm not present, skip sync");
+ return MCLAG_ERROR;
+ }
+
+ if (MLACP(csm).current_state != MLACP_STATE_EXCHANGE) {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"Session not up, skip sync");
+ return MCLAG_ERROR;
+ }
+
+ if (local_if->type != IF_T_VLAN) {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"invalid if type %d", local_if->type);
+ return MCLAG_ERROR;
+ }
+
+ ICCPD_LOG_DEBUG(__FUNCTION__,"add %d, v4 %d, v6 %d, mac %d ack %d, is_ipv6_ll %d, dir %d",
+ sync_add, is_v4, is_v6, sync_mac, ack, is_ipv6_ll, dir);
+
+ if (csm->peer_link_if)
+ {
+ set_peerlink_learn_kernel(csm, 0, 9);
+ }
+ if (sync_mac) {
+ syn_local_mac_info_to_peer(csm, local_if, sync_add, is_ipv6_ll);
+ }
+
+ if (is_v4) {
+ syn_local_arp_info_to_peer(csm, local_if, sync_add, ack);
+ }
+
+ if (is_v6) {
+ syn_local_nd_info_to_peer(csm, local_if, sync_add, ack, is_ipv6_ll, 1);
+ }
+
+ return 0;
+}
+
+int syn_ack_local_neigh_mac_info_to_peer(char *ifname, int is_ipv6_ll)
+{
+ struct LocalInterface *lif = NULL;
+ int sync_add = 0, is_v4 = 0, is_v6 = 0;
+
+ if (!ifname)
+ return -1;
+
+ lif = local_if_find_by_name(ifname);
+ if (lif)
+ {
+ if (is_ipv6_ll) {
+ syn_local_neigh_mac_info_to_peer(lif, 1, 0, 1, 1, 0, 1, 2);
+ return 0;
+ }
+
+ if (lif->ipv4_addr)
+ {
+ is_v4 = 1;
+ }
+
+ if (lif->prefixlen_v6)
+ {
+ is_v6 = 1;
+ }
+ ICCPD_LOG_DEBUG(__FUNCTION__," v4 %d, v6 %d, l3_mode %d, proto %d", is_v4, is_v6, lif->l3_mode, lif->is_l3_proto_enabled);
+ if (lif->l3_mode && lif->is_l3_proto_enabled) {
+ syn_local_neigh_mac_info_to_peer(lif, 1, is_v4, is_v6, 1, 0, 0, 3);
+ }
+ }
+ return 0;
+}
+
+int is_unique_ip_configured(char *ifname)
+{
+ struct System* sys = NULL;
+ struct Unq_ip_If_info* unq_ip_if = NULL;
+
+ if (!(sys = system_get_instance()))
+ return 0;
+
+ LIST_FOREACH(unq_ip_if, &(sys->unq_ip_if_list), if_next)
+ {
+ if (strcmp(unq_ip_if->name, ifname) == 0)
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int sync_unique_ip()
+{
+ struct System* sys = NULL;
+ struct Unq_ip_If_info* unq_ip_if = NULL;
+ struct LocalInterface* local_if = NULL;
+
+ if (!(sys = system_get_instance()))
+ return 0;
+
+ LIST_FOREACH(unq_ip_if, &(sys->unq_ip_if_list), if_next)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "unq_ip_if name %s", unq_ip_if->name);
+ syn_ack_local_neigh_mac_info_to_peer(unq_ip_if->name, 0);
+ }
+
+ return 0;
+}
+
+void set_peer_mac_in_kernel(char *mac, int vlan, int add)
+{
+ char cmd[256] = { 0 };
+ int ret = 0;
+
+ ICCPD_LOG_DEBUG(__FUNCTION__,"mac %s, vlan %d, add %d", mac, vlan, add);
+
+ if (add) {
+ sprintf(cmd, "bridge fdb replace %s dev Bridge vlan %d local", mac, vlan);
+ } else {
+ sprintf(cmd, "bridge fdb del %s dev Bridge vlan %d local", mac, vlan);
+ }
+
+ ret = system(cmd);
+ ICCPD_LOG_DEBUG(__FUNCTION__, " cmd %s ret = %d", cmd, ret);
+
+ return;
+}
+
+void set_peerlink_learn_kernel(
+ struct CSM* csm,
+ int enable, int dir)
+{
+ struct LocalInterface *lif = NULL;
+ if (!csm || !csm->peer_link_if)
+ return;
+
+ lif = csm->peer_link_if;
+
+ ICCPD_LOG_DEBUG(__FUNCTION__,"ifname %s, enable %d, dir %d", lif->name, enable, dir);
+ char cmd[256] = { 0 };
+ int ret = 0;
+ if (enable == 0) {
+ sprintf(cmd, "bridge link set dev %s learning off", lif->name);
+ } else {
+ sprintf(cmd, "bridge link set dev %s learning on", lif->name);
+ }
+
+ ret = system(cmd);
+ ICCPD_LOG_DEBUG(__FUNCTION__, " cmd %s ret = %d", cmd, ret);
+
+ if (ret != 0)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__, " cmd %s ret = %d", cmd, ret);
+ csm->peer_link_learning_enable = enable;
+ csm->peer_link_learning_retry_time = time(NULL);
+ } else {
+ csm->peer_link_learning_retry_time = 0;
+ }
+ return;
+}
diff --git a/src/iccpd/src/mlacp_sync_prepare.c b/src/iccpd/src/mlacp_sync_prepare.c
index ef1cd244a90a..a28a43e2b842 100644
--- a/src/iccpd/src/mlacp_sync_prepare.c
+++ b/src/iccpd/src/mlacp_sync_prepare.c
@@ -91,6 +91,10 @@ int mlacp_prepare_for_sync_request_tlv(struct CSM* csm, char* buf, size_t max_bu
tlv->port_num_agg_id = 0;
tlv->actor_key = 0;
+ ICCPD_LOG_DEBUG("ICCP_FSM", "TX sync_request: role %s, sync_state %s",
+ (csm->role_type == STP_ROLE_STANDBY) ? "standby" : "active",
+ mlacp_state(csm));
+
return msg_len;
}
@@ -138,6 +142,7 @@ int mlacp_prepare_for_sync_data_tlv(struct CSM* csm, char* buf, size_t max_buf_s
else
tlv->flags = htons(0x01);
+ ICCPD_LOG_DEBUG("ICCP_CSM", "TX sync %s", end ? "end" : "start");
return msg_len;
}
@@ -182,6 +187,10 @@ int mlacp_prepare_for_sys_config(struct CSM* csm, char* buf, size_t max_buf_size
memcpy(tlv->sys_id, MLACP(csm).system_id, ETHER_ADDR_LEN);
tlv->sys_priority = htons(MLACP(csm).system_priority);
tlv->node_id = MLACP(csm).node_id;
+
+ ICCPD_LOG_DEBUG("ICCP_FSM", "TX sys_config: systemID %s, priority %u, nodeID %u",
+ mac_addr_to_str(MLACP(csm).system_id), MLACP(csm).system_priority,
+ MLACP(csm).node_id);
return msg_len;
}
@@ -232,6 +241,8 @@ int mlacp_prepare_for_Aggport_state(struct CSM* csm, char* buf, size_t max_buf_s
tlv->actor_key = 0;
tlv->agg_state = local_if->state;
+ ICCPD_LOG_DEBUG("ICCP_FSM", "TX aggrport_state: %s is %s",
+ local_if->name, (local_if->state == PORT_STATE_UP) ? "up" : "down");
return msg_len;
}
@@ -280,6 +291,8 @@ int mlacp_prepare_for_Aggport_config(struct CSM* csm,
memcpy(tlv->agg_name, lif->name, MAX_L_PORT_NAME);
memcpy(tlv->mac_addr, lif->mac_addr, ETHER_ADDR_LEN);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "TX aggrport_config: %s, purge_flag %d, mac %s",
+ lif->name, purge_flag, mac_addr_to_str(lif->mac_addr));
return msg_len;
}
@@ -322,12 +335,13 @@ int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_bu
MacData = (struct mLACPMACData *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPMACInfoTLV) + sizeof(struct mLACPMACData) * count];
MacData->type = mac_msg->op_type;
- sprintf(MacData->mac_str, "%s", mac_msg->mac_str);
+ MacData->mac_type = mac_msg->fdb_type;
+ memcpy(MacData->mac_addr, mac_msg->mac_addr,ETHER_ADDR_LEN);
sprintf(MacData->ifname, "%s", mac_msg->origin_ifname);
MacData->vid = htons(mac_msg->vid);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Send MAC messge to peer, port %s mac = %s, vid = %d, type = %s count %d ", mac_msg->origin_ifname,
- mac_msg->mac_str, mac_msg->vid, mac_msg->op_type == MAC_SYNC_ADD ? "add" : "del", count);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Send MAC messge to peer, port %s mac = %s, vid = %d, type = %s count %d ", mac_msg->origin_ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->op_type == MAC_SYNC_ADD ? "add" : "del", count);
return msg_len;
}
@@ -336,7 +350,7 @@ int mlacp_prepare_for_mac_info_to_peer(struct CSM* csm, char* buf, size_t max_bu
* Preprare Sync ARP-Info TLV
*
* ***************************************/
-int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, struct ARPMsg* arp_msg, int count)
+int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size, struct ARPMsg* arp_msg, int count, int dir)
{
struct mLACPARPInfoTLV* tlv = NULL;
size_t msg_len = 0;
@@ -373,13 +387,15 @@ int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size,
ArpData = (struct ARPMsg *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPARPInfoTLV) + sizeof(struct ARPMsg) * count];
ArpData->op_type = arp_msg->op_type;
+ ArpData->flag = arp_msg->flag;
sprintf(ArpData->ifname, "%s", arp_msg->ifname);
ArpData->ipv4_addr = arp_msg->ipv4_addr;
memcpy(ArpData->mac_addr, arp_msg->mac_addr, ETHER_ADDR_LEN);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Send ARP messge to peer, if name %s mac %02x:%02x:%02x:%02x:%02x:%02x IP %s", ArpData->ifname, ArpData->mac_addr[0], ArpData->mac_addr[1], ArpData->mac_addr[2],
- ArpData->mac_addr[3], ArpData->mac_addr[4], ArpData->mac_addr[5], show_ip_str(ArpData->ipv4_addr));
-
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Send ARP messge to peer, dir %d, flag %d, if name %s mac %02x:%02x:%02x:%02x:%02x:%02x IP %s",
+ dir, ArpData->flag, ArpData->ifname,
+ ArpData->mac_addr[0], ArpData->mac_addr[1], ArpData->mac_addr[2], ArpData->mac_addr[3], ArpData->mac_addr[4],
+ ArpData->mac_addr[5], show_ip_str(ArpData->ipv4_addr));
return msg_len;
}
@@ -387,14 +403,13 @@ int mlacp_prepare_for_arp_info(struct CSM* csm, char* buf, size_t max_buf_size,
* Preprare Sync NDISC-Info TLV
*
* ***************************************/
-int mlacp_prepare_for_ndisc_info(struct CSM *csm, char *buf, size_t max_buf_size, struct NDISCMsg *ndisc_msg, int count)
+int mlacp_prepare_for_ndisc_info(struct CSM *csm, char *buf, size_t max_buf_size, struct NDISCMsg *ndisc_msg, int count, int dir)
{
-
struct mLACPNDISCInfoTLV *tlv = NULL;
size_t msg_len = 0;
size_t tlv_len = 0;
ICCHdr *icc_hdr = NULL;
- struct NDISCMsg *NdiscData;
+ struct NDISCMsg *NdiscData = NULL;
if (!csm)
return -1;
@@ -422,14 +437,16 @@ int mlacp_prepare_for_ndisc_info(struct CSM *csm, char *buf, size_t max_buf_size
tlv->icc_parameter.type = htons(TLV_T_MLACP_NDISC_INFO);
}
- NdiscData = (struct mLACPMACData *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPNDISCInfoTLV) + sizeof(struct NDISCMsg) * count];
+ NdiscData = (struct NDISCMsg *)&buf[sizeof(ICCHdr) + sizeof(struct mLACPNDISCInfoTLV) + sizeof(struct NDISCMsg) * count];
NdiscData->op_type = ndisc_msg->op_type;
+ NdiscData->flag = ndisc_msg->flag;
sprintf(NdiscData->ifname, "%s", ndisc_msg->ifname);
- memcpy(NdiscData->ipv6_addr, ndisc_msg->ipv6_addr, 32);
+ memcpy(NdiscData->ipv6_addr, ndisc_msg->ipv6_addr, 16);
memcpy(NdiscData->mac_addr, ndisc_msg->mac_addr, ETHER_ADDR_LEN);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Send ND messge to peer, if name %s mac =%02x:%02x:%02x:%02x:%02x:%02x IPv6 %s", NdiscData->ifname,
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Send ND messge to peer, dir %d, flag %d, if name %s mac =%02x:%02x:%02x:%02x:%02x:%02x IPv6 %s",
+ dir, NdiscData->flag, NdiscData->ifname,
NdiscData->mac_addr[0], NdiscData->mac_addr[1], NdiscData->mac_addr[2], NdiscData->mac_addr[3], NdiscData->mac_addr[4],
NdiscData->mac_addr[5], show_ipv6_str((char *)NdiscData->ipv6_addr));
@@ -465,9 +482,9 @@ int mlacp_prepare_for_port_channel_info(struct CSM* csm, char* buf,
return MCLAG_ERROR;
/* Calculate VLAN ID Length */
- LIST_FOREACH(vlan_id, &(port_channel->vlan_list), port_next)
- if (vlan_id != NULL)
- num_of_vlan_id++;
+ RB_FOREACH(vlan_id, vlan_rb_tree, &(port_channel->vlan_tree))
+ if (vlan_id != NULL)
+ num_of_vlan_id++;
tlv_len = sizeof(struct mLACPPortChannelInfoTLV) + sizeof(struct mLACPVLANData) * num_of_vlan_id;
@@ -500,7 +517,7 @@ int mlacp_prepare_for_port_channel_info(struct CSM* csm, char* buf,
tlv->num_of_vlan_id = htons(num_of_vlan_id);
num_of_vlan_id = 0;
- LIST_FOREACH(vlan_id, &(port_channel->vlan_list), port_next)
+ RB_FOREACH(vlan_id, vlan_rb_tree, &(port_channel->vlan_tree))
{
if (vlan_id != NULL )
{
@@ -512,7 +529,7 @@ int mlacp_prepare_for_port_channel_info(struct CSM* csm, char* buf,
}
ICCPD_LOG_DEBUG(__FUNCTION__, "PortChannel%d: ipv4 addr = %s l3 mode %d", port_channel->po_id, show_ip_str( tlv->ipv4_addr), tlv->l3_mode);
-
+ ICCPD_LOG_DEBUG("ICCP_FSM", "TX po_info: %s has %d vlans", port_channel->name, num_of_vlan_id);
return msg_len;
}
@@ -562,8 +579,8 @@ int mlacp_prepare_for_port_peerlink_info(struct CSM* csm, char* buf,
memcpy(tlv->if_name, peerlink_port->name, MAX_L_PORT_NAME);
tlv->port_type = peerlink_port->type;
- ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port is %s, type = %d", tlv->if_name, tlv->port_type);
-
+ ICCPD_LOG_DEBUG("ICCP_FSM", "TX peerlink_info: name %s, type %d",
+ peerlink_port->name, peerlink_port->type);
return msg_len;
}
@@ -649,8 +666,60 @@ int mlacp_prepare_for_warm_reboot(struct CSM* csm, char* buf, size_t max_buf_siz
tlv->icc_parameter.len = htons(sizeof(struct mLACPWarmbootTLV) - sizeof(ICCParameter));
tlv->warmboot = 0x1;
+ ICCPD_LOG_DEBUG("ICCP_FSM", "TX start warm reboot");
+ return msg_len;
+}
+
+/*****************************************
+* Prepare interface up ACK message
+*
+* ***************************************/
+int mlacp_prepare_for_if_up_ack(
+ struct CSM *csm,
+ char *buf,
+ size_t max_buf_size,
+ uint8_t if_type,
+ uint16_t if_id,
+ uint8_t port_isolation_state)
+{
+ struct System* sys = NULL;
+ ICCHdr* icc_hdr = (ICCHdr*) buf;
+ struct mLACPIfUpAckTLV* tlv = (struct mLACPIfUpAckTLV*) &buf[sizeof(ICCHdr)];
+ size_t msg_len = sizeof(ICCHdr) + sizeof(struct mLACPIfUpAckTLV);
+
+ if(csm == NULL)
+ return -1;
+
+ if(buf == NULL)
+ return -1;
+
+ if(msg_len > max_buf_size)
+ return -1;
+
+ if((sys = system_get_instance()) == NULL)
+ return -1;
+
+ /* Prepare for sync request */
+ memset(buf, 0, max_buf_size);
+
+ icc_hdr = (ICCHdr*) buf;
+ tlv = (struct mLACPIfUpAckTLV*) &buf[sizeof(ICCHdr)];
+
+ /* ICC header */
+ mlacp_fill_icc_header(csm, icc_hdr, msg_len);
+
+ /* If up ack TLV */
+ tlv->icc_parameter.u_bit = 0;
+ tlv->icc_parameter.f_bit = 0;
+ tlv->icc_parameter.type = htons(TLV_T_MLACP_IF_UP_ACK);
+
+ tlv->icc_parameter.len = htons(sizeof(struct mLACPIfUpAckTLV) - sizeof(ICCParameter));
+ tlv->if_type = if_type;
+ tlv->if_id = htons(if_id);
+ tlv->port_isolation_state = port_isolation_state;
- ICCPD_LOG_NOTICE(__FUNCTION__, "Send warm reboot notification to peer!");
+ ICCPD_LOG_DEBUG("ICCP_FSM", "TX if_up_ack: PortChannel%d, isolation_set %d",
+ if_id, port_isolation_state);
return msg_len;
}
diff --git a/src/iccpd/src/mlacp_sync_update.c b/src/iccpd/src/mlacp_sync_update.c
index b82fc1c16cb9..be2c75d12e5d 100644
--- a/src/iccpd/src/mlacp_sync_update.c
+++ b/src/iccpd/src/mlacp_sync_update.c
@@ -31,37 +31,48 @@
#include "../include/mlacp_tlv.h"
#include "../include/iccp_csm.h"
#include "../include/mlacp_link_handler.h"
+#include "../include/iccp_netlink.h"
#include "../include/iccp_consistency_check.h"
#include "../include/port.h"
-#include "../include/iccp_netlink.h"
+#include "../include/openbsd_tree.h"
+
/*****************************************
* Port-Conf Update
*
* ***************************************/
-extern void update_if_ipmac_on_standby(struct LocalInterface* lif_po);
+
int mlacp_fsm_update_system_conf(struct CSM* csm, mLACPSysConfigTLV*sysconf)
{
struct LocalInterface* lif = NULL;
+ uint8_t old_remote_system_id[ETHER_ADDR_LEN];
+
+ ICCPD_LOG_NOTICE("ICCP_FSM", "RX system_conf: systemID %s, priority %d, remote nodeID %d, nodeID %d",
+ mac_addr_to_str(MLACP(csm).remote_system.system_id),
+ MLACP(csm).remote_system.system_priority,
+ MLACP(csm).remote_system.node_id,
+ MLACP(csm).node_id);
/*NOTE
a little tricky, we change the NodeID local side if collision happened first time*/
if (sysconf->node_id == MLACP(csm).node_id)
MLACP(csm).node_id++;
+ memcpy(old_remote_system_id, MLACP(csm).remote_system.system_id, ETHER_ADDR_LEN);
+
memcpy(MLACP(csm).remote_system.system_id, sysconf->sys_id, ETHER_ADDR_LEN);
MLACP(csm).remote_system.system_priority = ntohs(sysconf->sys_priority);
MLACP(csm).remote_system.node_id = sysconf->node_id;
- ICCPD_LOG_DEBUG(__FUNCTION__, "SystemID [%02X:%02X:%02X:%02X:%02X:%02X], SystemPriority [%d], Remote NodeID [%d], NodeID [%d]",
- MLACP(csm).remote_system.system_id[0], MLACP(csm).remote_system.system_id[1], MLACP(csm).remote_system.system_id[2],
- MLACP(csm).remote_system.system_id[3], MLACP(csm).remote_system.system_id[4], MLACP(csm).remote_system.system_id[5],
- MLACP(csm).remote_system.system_priority,
- MLACP(csm).remote_system.node_id,
- MLACP(csm).node_id);
-
LIST_FOREACH(lif, &(MLACP(csm).lif_list), mlacp_next)
{
- update_if_ipmac_on_standby(lif);
+ update_if_ipmac_on_standby(lif, 2);
+ }
+
+ /* On standby, update system ID upon receiving change from active */
+ if ((csm->role_type == STP_ROLE_STANDBY) &&
+ (memcmp(old_remote_system_id, sysconf->sys_id, ETHER_ADDR_LEN) != 0))
+ {
+ mlacp_link_set_iccp_system_id(csm->mlag_id, sysconf->sys_id);
}
return 0;
@@ -76,10 +87,14 @@ int mlacp_fsm_update_Agg_conf(struct CSM* csm, mLACPAggConfigTLV* portconf)
struct PeerInterface* pif = NULL;
uint8_t po_active;
uint8_t new_create = 0;
+ struct LocalInterface *lif;
+
+ if (!csm)
+ return MCLAG_ERROR;
- ICCPD_LOG_DEBUG(__FUNCTION__, "Port name %s, po id %d flag %d MAC[%02x:%02x:%02x:%02x:%02x:%02x] ",
- portconf->agg_name, ntohs(portconf->agg_id), portconf->flags, portconf->mac_addr[0], portconf->mac_addr[1], portconf->mac_addr[2],
- portconf->mac_addr[3], portconf->mac_addr[4], portconf->mac_addr[5] );
+ ICCPD_LOG_DEBUG("ICCP_FSM", "RX aggrport_config: name %s, po_id %d, flag 0x%x, MAC %s",
+ portconf->agg_name, ntohs(portconf->agg_id), portconf->flags,
+ mac_addr_to_str(portconf->mac_addr));
/* Looking for the peer port instance, is any peer if exist?*/
pif = peer_if_find_by_name(csm, portconf->agg_name);
@@ -89,7 +104,16 @@ int mlacp_fsm_update_Agg_conf(struct CSM* csm, mLACPAggConfigTLV* portconf)
{
/*Purge*/
if (pif != NULL )
+ {
+ //This handler would take of handling mlacp changes based on peer
+ //mclag interface delete; recover back mac of po to original
+ //on standby etc
+ mlacp_peer_mlag_intf_delete_handler(csm, pif->name);
+
+ /* Delete remote interface info from STATE_DB */
+ mlacp_link_del_remote_if_info(csm->mlag_id, pif->name);
peer_if_destroy(pif);
+ }
else
MLACP(csm).need_to_sync = 1;
/*ICCPD_LOG_INFO("mlacp_fsm",
@@ -116,6 +140,21 @@ int mlacp_fsm_update_Agg_conf(struct CSM* csm, mLACPAggConfigTLV* portconf)
update_peerlink_isolate_from_pif(csm, pif, po_active, new_create);
pif->po_active = po_active;
+ /* When peer MLAG interface does not exist on active, standby does not set
+ * its MLAG interface MAC address to the active system MAC address.
+ * Peer MLAG interface is added now, update the standby MLAG interface
+ * MAC address
+ */
+ if (new_create)
+ {
+ mlacp_link_set_remote_if_state(csm->mlag_id, pif->name, (po_active)? true : false);
+ if ((csm->role_type == STP_ROLE_STANDBY))
+ {
+ lif = local_if_find_by_name(portconf->agg_name);
+ if (lif)
+ update_if_ipmac_on_standby(lif, 3);
+ }
+ }
return 0;
}
@@ -130,7 +169,10 @@ int mlacp_fsm_update_Aggport_state(struct CSM* csm, mLACPAggPortStateTLV* tlv)
if (csm == NULL || tlv == NULL)
return MCLAG_ERROR;
- ICCPD_LOG_DEBUG(__FUNCTION__, "Portchannel id %d state %d", ntohs(tlv->agg_id), tlv->agg_state);
+
+ ICCPD_LOG_DEBUG("ICCP_FSM", "RX aggrport_state: po_id %d, state %s, sync_state %s",
+ ntohs(tlv->agg_id), (tlv->agg_state == PORT_STATE_UP) ? "up" : "down",
+ mlacp_state(csm));
po_active = (tlv->agg_state == PORT_STATE_UP);
@@ -150,6 +192,18 @@ int mlacp_fsm_update_Aggport_state(struct CSM* csm, mLACPAggPortStateTLV* tlv)
peer_if->po_active = po_active;
ICCPD_LOG_DEBUG(__FUNCTION__, "Update peer interface %s to state %s", peer_if->name, tlv->agg_state ? "down" : "up");
+ /* Update remote interface state if ICCP reaches EXCHANGE state.
+ * Otherwise, it is updated after the session comes up
+ */
+ if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
+ {
+ if (tlv->agg_state == PORT_STATE_DOWN)
+ mlacp_convert_remote_mac_to_local(csm, peer_if->name);
+
+ mlacp_link_set_remote_if_state(
+ csm->mlag_id, peer_if->name,
+ (tlv->agg_state == PORT_STATE_UP)? true : false);
+ }
break;
}
@@ -161,15 +215,26 @@ int mlacp_fsm_update_Aggport_state(struct CSM* csm, mLACPAggPortStateTLV* tlv)
* ***************************************/
int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData *MacData)
{
-
struct Msg* msg = NULL;
- struct MACMsg *mac_msg = NULL, mac_data;
+ struct MACMsg *mac_msg = NULL, *new_mac_msg = NULL;
+ struct MACMsg mac_data, mac_find;
struct LocalInterface* local_if = NULL;
uint8_t from_mclag_intf = 0;/*0: orphan port, 1: MCLAG port*/
+ memset(&mac_data, 0, sizeof(struct MACMsg));
+ memset(&mac_find, 0, sizeof(struct MACMsg));
+ uint8_t null_mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ ICCPD_LOG_INFO("ICCP_FDB",
+ "Received MAC Info, interface=[%s] vid[%d] MAC[%s] OperType[%s] MacType[%d] ",
+ MacData->ifname, ntohs(MacData->vid), mac_addr_to_str(MacData->mac_addr),
+ MacData->type == MAC_SYNC_ADD ? "add" : "del", MacData->mac_type);
+
+ if (memcmp(MacData->mac_addr, null_mac, ETHER_ADDR_LEN) == 0)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Invalid MAC address from peer do not add.");
+ return 0;
+ }
- ICCPD_LOG_NOTICE(__FUNCTION__,
- "Received MAC Info, port[%s] vid[%d] MAC[%s] type[%s]",
- MacData->ifname, ntohs(MacData->vid), MacData->mac_str, MacData->type == MAC_SYNC_ADD ? "add" : "del");
/*Find the interface in MCLAG interface list*/
LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next)
@@ -181,104 +246,214 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData *
}
}
- /* update MAC list*/
- TAILQ_FOREACH(msg, &(MLACP(csm).mac_list), tail)
+ mac_find.vid = ntohs(MacData->vid);
+ memcpy(&mac_find.mac_addr, MacData->mac_addr, ETHER_ADDR_LEN);
+ mac_msg = RB_FIND(mac_rb_tree, &MLACP(csm).mac_rb ,&mac_find);
+
+ /*Same MAC is exist in local switch, this may be mac move*/
+ //if (strcmp(mac_msg->mac_str, MacData->mac_str) == 0 && mac_msg->vid == ntohs(MacData->vid))
+ if (mac_msg)
{
- mac_msg = (struct MACMsg*)msg->buf;
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Recv MAC update from peer RB_FIND success, existing MAC age flag:%d interface %s, "
+ "MAC %s vlan-id %d, fdb_type: %d, op_type %s", mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->fdb_type,
+ (mac_msg->op_type == MAC_SYNC_ADD) ? "add":"del");
- /*Same MAC is exist in local switch, this may be mac move*/
- if (strcmp(mac_msg->mac_str, MacData->mac_str) == 0 && mac_msg->vid == ntohs(MacData->vid))
+ if (MacData->type == MAC_SYNC_ADD)
{
- if (MacData->type == MAC_SYNC_ADD)
+ mac_msg->age_flag &= ~MAC_AGE_PEER;
+
+ if (from_mclag_intf && mac_msg->pending_local_del)
{
- mac_msg->age_flag &= ~MAC_AGE_PEER;
- ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ADD, Remove peer age flag:%d ifname %s, MAC %s vlan-id %d",
- mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
+ mac_msg->pending_local_del = 0;
+
+ mac_msg->age_flag = MAC_AGE_LOCAL;
- /*mac_msg->fdb_type = tlv->fdb_type;*/
- /*The port ifname is different to the local item*/
- if (from_mclag_intf == 0 || strcmp(mac_msg->ifname, MacData->ifname) != 0 || strcmp(mac_msg->origin_ifname, MacData->ifname) != 0)
+ // AS MAC was learned locally and in pending state due to IF is down,
+ // send del to peer when MAC add received from peer
+ mac_msg->op_type = MAC_SYNC_DEL;
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
{
- if (mac_msg->fdb_type != MAC_TYPE_STATIC)
- {
- /*Update local item*/
- memcpy(&mac_msg->origin_ifname, MacData->ifname, MAX_L_PORT_NAME);
- }
+ TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), mac_msg, tail);
+ }
+ }
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Recv ADD, Remove peer age flag:%d interface %s, "
+ "MAC %s vlan-id %d, op_type %s, from_mclag_intf: %d ", mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid,
+ (mac_msg->op_type == MAC_SYNC_ADD) ? "add":"del", from_mclag_intf);
- /*If the MAC is learned from orphan port, or from MCLAG port but the local port is down*/
- if (from_mclag_intf == 0 || (local_if->state == PORT_STATE_DOWN && strcmp(mac_msg->ifname, csm->peer_itf_name) != 0))
+ /*mac_msg->fdb_type = tlv->fdb_type;*/
+ /*The port ifname is different to the local item*/
+ if (strcmp(mac_msg->ifname, MacData->ifname) != 0 || strcmp(mac_msg->origin_ifname, MacData->ifname) != 0)
+ {
+ if (mac_msg->fdb_type != MAC_TYPE_STATIC)
+ {
+ /*Update local item*/
+ memcpy(&mac_msg->origin_ifname, MacData->ifname, MAX_L_PORT_NAME);
+ }
+ else
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Ignore Recv MAC ADD, Local static present,"
+ " interface %s, MAC %s vlan-id %d ", mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ //set back the peer age flag
+ mac_msg->age_flag |= MAC_AGE_PEER;
+ return 0;
+ }
+
+ /*If the MAC is learned from orphan port, or from MCLAG port but the local port is down*/
+ if (from_mclag_intf == 0 || local_if->state == PORT_STATE_DOWN )
+ {
+ /*Set MAC_AGE_LOCAL flag*/
+ mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1, 1);
+
+ if (strlen(csm->peer_itf_name) != 0)
{
- /*Set MAC_AGE_LOCAL flag*/
- mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1);
+ if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0)
+ {
+ /*This MAC is already point to peer-link*/
+ ICCPD_LOG_NOTICE("ICCP_FDB", "Remote MAC ADD local IF down, MAC already points to Peer_link done processing "
+ " interface %s, MAC %s vlan-id %d ", mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ return 0;
+ }
- if (strlen(csm->peer_itf_name) != 0)
+ if (csm->peer_link_if && (csm->peer_link_if->state == PORT_STATE_UP))
{
- if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0)
- {
- /* This MAC is already point to peer-link */
- return 0;
- }
+ /*Redirect the mac to peer-link*/
+ memcpy(&mac_msg->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
- if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP)
- {
- /*Redirect the mac to peer-link*/
- memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ);
+ /*Send mac add message to mclagsyncd*/
+ add_mac_to_chip(mac_msg, mac_msg->fdb_type);
- /*Send mac add message to mclagsyncd*/
- add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC);
- }
- else
- {
- /*must redirect but peerlink is down, del mac from ASIC*/
- /*if peerlink change to up, mac will add back to ASIC*/
- del_mac_from_chip(mac_msg);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Remote MAC ADD , local mac exist move to peer link up "
+ " interface %s, MAC %s vlan-id %d ", mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
- /*Redirect the mac to peer-link*/
- memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ);
- }
}
else
{
- /*must redirect but no peerlink, del mac from ASIC*/
- del_mac_from_chip(mac_msg);
+ /*Redirect the mac to peer-link, if peerlink is down FdbOrch deletes MAC*/
+ memcpy(&mac_msg->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
- /*Update local item*/
- memcpy(&mac_msg->ifname, MacData->ifname, MAX_L_PORT_NAME);
+ add_mac_to_chip(mac_msg, mac_msg->fdb_type);
- /*if orphan port mac but no peerlink, don't keep this mac*/
- if (from_mclag_intf == 0)
- {
- TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail);
- free(msg->buf);
- free(msg);
- return 0;
- }
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Remote MAC ADD , local mac exist move to peer link down "
+ " interface %s, MAC %s vlan-id %d ", mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
}
}
else
{
- /*Remove MAC_AGE_LOCAL flag*/
- mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0);
+ /*must redirect but no peerlink, del mac from ASIC*/
+ del_mac_from_chip(mac_msg);
/*Update local item*/
memcpy(&mac_msg->ifname, MacData->ifname, MAX_L_PORT_NAME);
- /*from MCLAG port and the local port is up, add mac to ASIC to update port*/
- add_mac_to_chip(mac_msg, MAC_TYPE_DYNAMIC);
+ /*if orphan port mac but no peerlink, don't keep this mac*/
+ if (from_mclag_intf == 0)
+ {
+ MAC_RB_REMOVE(mac_rb_tree, &MLACP(csm).mac_rb, mac_msg);
+
+ // free only if not in change list to be send to peer node,
+ // else free is taken care after sending the update to peer
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ free(mac_msg);
+ }
+
+ ICCPD_LOG_ERR(__FUNCTION__, "Ignore Recv MAC ADD "
+ "MAC %s vlan %d interface %s peer link not available ",
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->ifname);
+ return 0;
+ }
}
}
+ else
+ {
+ /*Update local item*/
+ memcpy(&mac_msg->ifname, MacData->ifname, MAX_L_PORT_NAME);
+
+ /*from MCLAG port and the local port is up, add mac to ASIC to update port*/
+ add_mac_to_chip(mac_msg, mac_msg->fdb_type);
+ }
}
+ else if(!from_mclag_intf && (strcmp(mac_msg->ifname, MacData->ifname) == 0))
+ {
+ // local to remote MAC move on Orphan port.
+ if (strlen(csm->peer_itf_name) != 0)
+ {
+ if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0)
+ {
+ /*This MAC is already point to peer-link*/
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Remote MAC ADD learn on Orphan port ,MAC already points to Peer_link"
+ " interface %s, MAC %s vlan-id %d ", mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ return 0;
+ }
- break;
+ if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP)
+ {
+ /*Redirect the mac to peer-link*/
+ memcpy(&mac_msg->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Remote MAC ADD learn on Orphan port ,point MAC address to Peer_link"
+ "interface %s, MAC %s vlan-id %d ", mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ /*Send mac add message to mclagsyncd*/
+ add_mac_to_chip(mac_msg, mac_msg->fdb_type);
+ }
+ else
+ {
+ /*Redirect the mac to peer-link*/
+ /*must redirect but if peerlink is down FdbOrch will delete MAC */
+ memcpy(&mac_msg->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
+ add_mac_to_chip(mac_msg, mac_msg->fdb_type);
+
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Remote MAC ADD learn on Orphan port ,point MAC address to Peer_link"
+ " peer link is down, delete the MAC, interface %s, MAC %s vlan-id %d ", mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid);
+ }
+ }
+ }
+
+ // Code to exchange MAC_SYNC_ACK notifications can be enabled in future, if MAC SYNC issues observed.
+ #if 0
+ mac_msg->op_type = MAC_SYNC_ACK;
+ if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0)
+ {
+ /*Reply mac ack message to peer, peer will clean MAC_AGE_PEER flag*/
+ TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ADD, MAC-msg-list enqueue: %s, "
+ "add %s vlan-id %d, op_type %d", mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->op_type);
+ }
+ #endif
}
+ // Code to exchange MAC_SYNC_ACK notifications can be enabled in future, if MAC SYNC issues observed.
+ #if 0
+ else if (tlv->type == MAC_SYNC_ACK)
+ {
+ /*Clean the MAC_AGE_PEER flag*/
+ mac_msg->age_flag &= ~MAC_AGE_PEER;
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Recv ACK, Remove peer age flag:%d ifname %s, "
+ "add %s vlan-id %d, op_type %d", mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->op_type);
+ }
+ #endif
+
}
/* delete/add MAC list*/
- if (msg && MacData->type == MAC_SYNC_DEL)
+ if (mac_msg && (MacData->type == MAC_SYNC_DEL))
{
mac_msg->age_flag |= MAC_AGE_PEER;
- ICCPD_LOG_DEBUG(__FUNCTION__, "Recv DEL, Add peer age flag: %d ifname %s, MAC %s vlan-id %d",
- mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Recv MAC DEL from peer: Add peer age flag: %d interface %s, "
+ "MAC %s vlan %d, op_type %s", mac_msg->age_flag, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid,
+ (mac_msg->op_type == MAC_SYNC_ADD) ? "add":"del");
if (mac_msg->age_flag == (MAC_AGE_LOCAL | MAC_AGE_PEER))
{
@@ -286,59 +461,67 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData *
del_mac_from_chip(mac_msg);
/*If local and peer both aged, del the mac*/
- TAILQ_REMOVE(&(MLACP(csm).mac_list), msg, tail);
- free(msg->buf);
- free(msg);
+ MAC_RB_REMOVE(mac_rb_tree, &MLACP(csm).mac_rb, mac_msg);
+
+ // free only if not in change list to be send to peer node,
+ // else free is taken care after sending the update to peer
+ if (!MAC_IN_MSG_LIST(&(MLACP(csm).mac_msg_list), mac_msg, tail))
+ {
+ free(mac_msg);
+ }
}
else
{
return 0;
}
}
- else if (!msg && MacData->type == MAC_SYNC_ADD)
+ else if (!mac_msg && (MacData->type == MAC_SYNC_ADD))
{
mac_msg = (struct MACMsg*)&mac_data;
- mac_msg->fdb_type = MAC_TYPE_DYNAMIC;
+ mac_msg->fdb_type = MacData->mac_type;
mac_msg->vid = ntohs(MacData->vid);
- sprintf(mac_msg->mac_str, "%s", MacData->mac_str);
+ memcpy(mac_msg->mac_addr, MacData->mac_addr, ETHER_ADDR_LEN);
sprintf(mac_msg->ifname, "%s", MacData->ifname);
sprintf(mac_msg->origin_ifname, "%s", MacData->ifname);
mac_msg->age_flag = 0;
+ /*Set MAC_AGE_LOCAL flag*/
+ mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1, 0);
+
/*If the MAC is learned from orphan port, or from MCLAG port but the local port is down*/
if (from_mclag_intf == 0 || local_if->state == PORT_STATE_DOWN)
{
- /*Set MAC_AGE_LOCAL flag*/
- mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 1);
if (strlen(csm->peer_itf_name) == 0)
{
- ICCPD_LOG_NOTICE(__FUNCTION__, "From orphan port or portchannel is down, but peer-link is not configured: ifname %s, MAC %s vlan-id %d",
- mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
-
/*if orphan port mac but no peerlink, don't keep this mac*/
+ //MAC to be saved and program when peer_link is configured..? TBD
if (from_mclag_intf == 0)
+ {
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Recv MAC ADD from peer: Ignore MAC learn on orphan port "
+ "peer-link is not configured interface %s, MAC %s vlan-id %d, "
+ " op_type %d", from_mclag_intf, mac_msg->ifname,
+ mac_addr_to_str(mac_msg->mac_addr),
+ mac_msg->vid, mac_msg->op_type);
return 0;
+ }
}
else
{
/*Redirect the mac to peer-link*/
- memcpy(&mac_msg->ifname, csm->peer_itf_name, IFNAMSIZ);
+ memcpy(&mac_msg->ifname, csm->peer_itf_name, MAX_L_PORT_NAME);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Redirect to peerlink for orphan port or portchannel is down, Add local age flag: %d ifname %s, MAC %s vlan-id %d",
- mac_msg->age_flag, mac_msg->ifname, mac_msg->mac_str, mac_msg->vid);
+ ICCPD_LOG_DEBUG("ICCP_FDB", "Recv MAC ADD from peer: Redirect to peerlink for orphan port or portchannel is down,"
+ " age flag: %d interface %s, MAC %s vlan %d, op_type %d",
+ mac_msg->age_flag, mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr),
+ mac_msg->vid, mac_msg->op_type);
}
}
- else
- {
- /*Remove MAC_AGE_LOCAL flag*/
- mac_msg->age_flag = set_mac_local_age_flag(csm, mac_msg, 0);
- }
- if (iccp_csm_init_msg(&msg, (char*)mac_msg, sizeof(struct MACMsg)) == 0)
+ if (iccp_csm_init_mac_msg(&new_mac_msg, (char*)mac_msg, sizeof(struct MACMsg)) == 0)
{
- TAILQ_INSERT_TAIL(&(MLACP(csm).mac_list), msg, tail);
/*ICCPD_LOG_INFO(__FUNCTION__, "add mac queue successfully");*/
+ RB_INSERT(mac_rb_tree, &MLACP(csm).mac_rb, new_mac_msg);
/*If the mac is from orphan port, or from MCLAG port but the local port is down*/
if (strcmp(mac_msg->ifname, csm->peer_itf_name) == 0)
@@ -347,11 +530,22 @@ int mlacp_fsm_update_mac_entry_from_peer( struct CSM* csm, struct mLACPMACData *
if (csm->peer_link_if && csm->peer_link_if->state == PORT_STATE_UP)
add_mac_to_chip(mac_msg, mac_msg->fdb_type);
}
- else
+ else if(local_if->state != PORT_STATE_DOWN)
{
/*from MCLAG port and the local port is up*/
add_mac_to_chip(mac_msg, mac_msg->fdb_type);
}
+ // Code to exchange MAC_SYNC_ACK notifications can be enabled in future, if MAC SYNC issues observed.
+ #if 0
+ mac_msg->op_type = MAC_SYNC_ACK;
+ if (iccp_csm_init_msg(&msg_send, (char*)mac_msg, sizeof(struct MACMsg)) == 0)
+ {
+ /*Reply mac ack message to peer, peer will clean MAC_AGE_PEER flag*/
+ TAILQ_INSERT_TAIL(&(MLACP(csm).mac_msg_list), msg_send, tail);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "MAC-msg-list enqueue: %s, add %s vlan-id %d, op_type %d",
+ mac_msg->ifname, mac_addr_to_str(mac_msg->mac_addr), mac_msg->vid, mac_msg->op_type);
+ }
+ #endif
}
}
@@ -366,7 +560,7 @@ int mlacp_fsm_update_mac_info_from_peer(struct CSM* csm, struct mLACPMACInfoTLV*
if (!csm || !tlv)
return MCLAG_ERROR;
count = ntohs(tlv->num_of_entry);
- ICCPD_LOG_INFO(__FUNCTION__, "Received MAC Info count %d", count );
+ ICCPD_LOG_INFO(__FUNCTION__, "Received MAC Info count %d ", count );
for (i = 0; i < count; i++)
{
@@ -433,51 +627,102 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry)
{
struct Msg* msg = NULL;
struct ARPMsg *arp_msg = NULL, arp_data;
- struct LocalInterface* local_if;
+ struct LocalInterface *local_if = NULL;
+ struct LocalInterface *vlan_if = NULL;
struct LocalInterface *peer_link_if = NULL;
+ struct LocalInterface *local_vlan_if = NULL;
struct VLAN_ID *vlan_id_list = NULL;
int set_arp_flag = 0;
+ int my_ip_arp_flag = 0;
+ int vlan_count = 0;
char mac_str[18] = "";
+ int err = 0, ln = 0;
+ int permanent_neigh = 0;
+ uint16_t vlan_id = 0;
+ struct VLAN_ID vlan_key = { 0 };
+ int vid_intf_present = 0;
if (!csm || !arp_entry)
return MCLAG_ERROR;
- sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", arp_entry->mac_addr[0], arp_entry->mac_addr[1], arp_entry->mac_addr[2],
- arp_entry->mac_addr[3], arp_entry->mac_addr[4], arp_entry->mac_addr[5]);
-
- ICCPD_LOG_NOTICE(__FUNCTION__,
+ #if 0
+ ICCPD_LOG_INFO(__FUNCTION__,
"Received ARP Info, intf[%s] IP[%s], MAC[%02x:%02x:%02x:%02x:%02x:%02x]",
arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr),
arp_entry->mac_addr[0], arp_entry->mac_addr[1], arp_entry->mac_addr[2],
arp_entry->mac_addr[3], arp_entry->mac_addr[4], arp_entry->mac_addr[5]);
+ #endif
- if (strncmp(arp_entry->ifname, "Vlan", 4) == 0)
+ sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", arp_entry->mac_addr[0], arp_entry->mac_addr[1], arp_entry->mac_addr[2],
+ arp_entry->mac_addr[3], arp_entry->mac_addr[4], arp_entry->mac_addr[5]);
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Received ARP Info, Flag %x, intf[%s] IP[%s], MAC[%s]", arp_entry->flag, arp_entry->ifname,
+ show_ip_str(arp_entry->ipv4_addr), mac_str);
+
+ if (strncmp(arp_entry->ifname, VLAN_PREFIX, strlen(VLAN_PREFIX)) == 0) {
+ sscanf (arp_entry->ifname, "Vlan%hu", &vlan_id);
+ }
+
+ if (vlan_id)
{
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vlan_id;
+
peer_link_if = local_if_find_by_name(csm->peer_itf_name);
if (peer_link_if && !local_if_is_l3_mode(peer_link_if))
{
+ ln = __LINE__;
/* Is peer-linlk itf belong to a vlan the same as peer?*/
- LIST_FOREACH(vlan_id_list, &(peer_link_if->vlan_list), port_next)
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(peer_link_if->vlan_tree), &vlan_key);
+
+ if (vlan_id_list)
{
- if (!vlan_id_list->vlan_itf)
- continue;
- if (strcmp(vlan_id_list->vlan_itf->name, arp_entry->ifname) != 0)
- continue;
- if (!local_if_is_l3_mode(vlan_id_list->vlan_itf))
- continue;
+ vlan_count++;
+ if (vlan_id_list->vlan_itf) {
+ if (strcmp(vlan_id_list->vlan_itf->name, arp_entry->ifname) == 0) {
+ ln = __LINE__;
+ vid_intf_present = 1;
+ }
+
+ if (vid_intf_present && local_if_is_l3_mode(vlan_id_list->vlan_itf)) {
+ if (arp_entry->ipv4_addr == vlan_id_list->vlan_itf->ipv4_addr) {
+ my_ip_arp_flag = 1;
+ }
+ }
- ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is learnt from intf %s, peer-link %s is the member of this vlan",
- vlan_id_list->vlan_itf->name, peer_link_if->name);
+ ICCPD_LOG_DEBUG(__FUNCTION__,
+ "ARP is learnt from intf %s, peer-link %s is the member of this vlan",
+ vlan_id_list->vlan_itf->name, peer_link_if->name);
- /* Peer-link belong to L3 vlan is alive, set the ARP info*/
- set_arp_flag = 1;
+ /* Peer-link belong to L3 vlan is alive, set the ARP info*/
+ set_arp_flag = 1;
+ }
+ }
- break;
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP Received ln %d, vlan_count %d, set_arp_flag %d, my_ip %d",
+ ln, vlan_count, set_arp_flag, my_ip_arp_flag);
+
+ if (vlan_count == 0)
+ {
+ vlan_if = local_if_find_by_name(arp_entry->ifname);
+ if (vlan_if && vlan_if->is_l3_proto_enabled)
+ {
+ if (arp_entry->ipv4_addr == vlan_if->ipv4_addr) {
+ my_ip_arp_flag = 1;
+ }
+ set_arp_flag = 1;
+ }
}
}
}
+ if(my_ip_arp_flag)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__," ignoring ARP sync for self ip %s ", show_ip_str(arp_entry->ipv4_addr));
+ return 0;
+ }
+
if (set_arp_flag == 0)
{
LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next)
@@ -487,20 +732,21 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry)
if (!local_if_is_l3_mode(local_if))
{
/* Is the L2 MLAG itf belong to a vlan the same as peer?*/
- LIST_FOREACH(vlan_id_list, &(local_if->vlan_list), port_next)
- {
- if (!vlan_id_list->vlan_itf)
- continue;
- if (strcmp(vlan_id_list->vlan_itf->name, arp_entry->ifname) != 0)
- continue;
- if (!local_if_is_l3_mode(vlan_id_list->vlan_itf))
- continue;
-
- ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is learnt from intf %s, mclag %s is the member of this vlan",
- vlan_id_list->vlan_itf->name, local_if->name);
- break;
+ if (vlan_id) {
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(local_if->vlan_tree), &vlan_key);
+ if (vlan_id_list && vlan_id_list->vlan_itf) {
+ if (arp_entry->ipv4_addr == vlan_id_list->vlan_itf->ipv4_addr) {
+ my_ip_arp_flag = 1;
+ }
+
+ ICCPD_LOG_DEBUG(__FUNCTION__,
+ "ARP is learnt from intf %s, mclag %s is the member of this vlan",
+ vlan_id_list->vlan_itf->name, local_if->name);
+ }
}
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP received PO %s, active %d, my_ip %d, ln %d",
+ local_if->name, local_if->po_active, my_ip_arp_flag, ln);
if (vlan_id_list && local_if->po_active == 1)
{
/* Any po of L3 vlan is alive, set the ARP info*/
@@ -513,7 +759,9 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry)
/* Is the ARP belong to a L3 mode MLAG itf?*/
if (strcmp(local_if->name, arp_entry->ifname) == 0)
{
- ICCPD_LOG_DEBUG(__FUNCTION__, "ARP is learnt from mclag L3 intf %s", local_if->name);
+ ICCPD_LOG_DEBUG(__FUNCTION__,
+ "ARP is learnt from mclag L3 intf %s, active %d",
+ local_if->name, local_if->po_active);
if (local_if->po_active == 1)
{
/* po is alive, set the ARP info*/
@@ -523,6 +771,7 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry)
}
else
{
+ ln = __LINE__;
continue;
}
}
@@ -530,35 +779,65 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry)
}
}
+ if(my_ip_arp_flag)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__," ignoring ARP sync for self ip %s ", show_ip_str(arp_entry->ipv4_addr));
+ return 0;
+ }
+
/* set dynamic ARP*/
if (set_arp_flag == 1)
{
+ if (arp_entry->flag & NEIGH_SYNC_FLAG_SELF_IP)
+ {
+ permanent_neigh = 1;
+ }
+
if (arp_entry->op_type == NEIGH_SYNC_ADD)
{
- if (iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_entry->ipv4_addr, 1, arp_entry->mac_addr, arp_entry->ifname) < 0)
+ err = iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_entry->ipv4_addr, 1, arp_entry->mac_addr, arp_entry->ifname, permanent_neigh, 8);
+ if (err < 0)
{
- ICCPD_LOG_WARN(__FUNCTION__, "ARP add failure for %s %s %s",
- arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str);
- return MCLAG_ERROR;
+ if (err != ICCP_NLE_SEQ_MISMATCH) {
+ ICCPD_LOG_ERR(__FUNCTION__, "ARP add failure for %s %s %s, status %d",
+ arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str, err);
+ return MCLAG_ERROR;
+ }
}
+
+ if (arp_entry->flag & NEIGH_SYNC_FLAG_ACK)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"Sync ARP on ACK ");
+ syn_ack_local_neigh_mac_info_to_peer(arp_entry->ifname, 0);
+ }
}
else
{
- if (iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_entry->ipv4_addr, 0, arp_entry->mac_addr, arp_entry->ifname) < 0)
+ err = iccp_netlink_neighbor_request(AF_INET, (uint8_t *)&arp_entry->ipv4_addr, 0, arp_entry->mac_addr, arp_entry->ifname, permanent_neigh, 9);
+ if (err < 0)
{
- ICCPD_LOG_WARN(__FUNCTION__, "ARP delete failure for %s %s %s",
- arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str);
- return MCLAG_ERROR;
+ if (err != ICCP_NLE_SEQ_MISMATCH) {
+ ICCPD_LOG_ERR(__FUNCTION__, "ARP delete failure for %s %s %s, status %d",
+ arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str, err);
+ return MCLAG_ERROR;
+ }
}
}
- /*ICCPD_LOG_DEBUG(__FUNCTION__, "%s: ARP update for %s %s %s",
- __FUNCTION__, arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str);*/
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ARP update for %s %s %s",
+ arp_entry->ifname, show_ip_str(arp_entry->ipv4_addr), mac_str);
}
else
{
- ICCPD_LOG_NOTICE(__FUNCTION__, "Failure: port-channel is not alive");
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Failure: port-channel is not alive, ln %d", ln);
/*TODO Set static route through peer-link or just skip it?*/
+ local_vlan_if = local_if_find_by_name(arp_entry->ifname);
+ if (local_vlan_if) {
+ if (arp_entry->ipv4_addr == local_vlan_if->ipv4_addr) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ignore my ip %s", show_ip_str(arp_entry->ipv4_addr));
+ return 0;
+ }
+ }
}
/* update ARP list*/
@@ -588,6 +867,8 @@ int mlacp_fsm_update_arp_entry(struct CSM* csm, struct ARPMsg *arp_entry)
sprintf(arp_msg->ifname, "%s", arp_entry->ifname);
arp_msg->ipv4_addr = arp_entry->ipv4_addr;
arp_msg->op_type = arp_entry->op_type;
+ arp_msg->flag = 0;
+ arp_msg->learn_flag = NEIGH_REMOTE;
memcpy(arp_msg->mac_addr, arp_entry->mac_addr, ETHER_ADDR_LEN);
if (iccp_csm_init_msg(&msg, (char*)arp_msg, sizeof(struct ARPMsg)) == 0)
{
@@ -629,7 +910,7 @@ int mlacp_fsm_update_arp_info(struct CSM* csm, struct mLACPARPInfoTLV* tlv)
if (!csm || !tlv)
return MCLAG_ERROR;
count = ntohs(tlv->num_of_entry);
- ICCPD_LOG_INFO(__FUNCTION__, "Received ARP Info count %d ", count );
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Received ARP Info count %d ", count );
for (i = 0; i < count; i++)
{
@@ -645,10 +926,21 @@ int mlacp_fsm_update_ndisc_entry(struct CSM *csm, struct NDISCMsg *ndisc_entry)
struct Msg *msg = NULL;
struct NDISCMsg *ndisc_msg = NULL, ndisc_data;
struct LocalInterface *local_if;
+ struct LocalInterface *vlan_if = NULL;
struct LocalInterface *peer_link_if = NULL;
+ struct LocalInterface *local_vlan_if = NULL;
struct VLAN_ID *vlan_id_list = NULL;
int set_ndisc_flag = 0;
char mac_str[18] = "";
+ int my_ip_nd_flag = 0;
+ int vlan_count = 0;
+ int err = 0, ln = 0;
+ int permanent_neigh = 0;
+ int is_ack_ll = 0;
+ int is_link_local = 0;
+ uint16_t vlan_id = 0;
+ struct VLAN_ID vlan_key = { 0 };
+ int vid_intf_present = 0;
if (!csm || !ndisc_entry)
return MCLAG_ERROR;
@@ -656,37 +948,98 @@ int mlacp_fsm_update_ndisc_entry(struct CSM *csm, struct NDISCMsg *ndisc_entry)
sprintf(mac_str, "%02x:%02x:%02x:%02x:%02x:%02x", ndisc_entry->mac_addr[0], ndisc_entry->mac_addr[1], ndisc_entry->mac_addr[2],
ndisc_entry->mac_addr[3], ndisc_entry->mac_addr[4], ndisc_entry->mac_addr[5]);
- ICCPD_LOG_NOTICE(__FUNCTION__,
- "Received ND Info, intf[%s] IP[%s], MAC[%s]", ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str);
+ ICCPD_LOG_DEBUG(__FUNCTION__,
+ "Received ND Info, intf[%s] Flag %x, IP[%s], MAC[%s]",
+ ndisc_entry->ifname, ndisc_entry->flag, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str);
+
+ if (strncmp(ndisc_entry->ifname, VLAN_PREFIX, strlen(VLAN_PREFIX)) == 0) {
+ sscanf (ndisc_entry->ifname, "Vlan%hu", &vlan_id);
+ }
+
+ if ((memcmp(show_ipv6_str((char *)ndisc_entry->ipv6_addr), "FE80", 4) == 0)
+ || (memcmp(show_ipv6_str((char *)ndisc_entry->ipv6_addr), "fe80", 4) == 0))
+ {
+ is_link_local = 1;
+ }
- if (strncmp(ndisc_entry->ifname, "Vlan", 4) == 0)
+ if (vlan_id)
{
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vlan_id;
+
peer_link_if = local_if_find_by_name(csm->peer_itf_name);
if (peer_link_if && !local_if_is_l3_mode(peer_link_if))
{
+ ln = __LINE__;
/* Is peer-linlk itf belong to a vlan the same as peer? */
- LIST_FOREACH(vlan_id_list, &(peer_link_if->vlan_list), port_next)
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(peer_link_if->vlan_tree), &vlan_key);
+
+ if (vlan_id_list)
{
- if (!vlan_id_list->vlan_itf)
- continue;
- if (strcmp(vlan_id_list->vlan_itf->name, ndisc_entry->ifname) != 0)
- continue;
- if (!local_if_is_l3_mode(vlan_id_list->vlan_itf))
- continue;
+ vlan_count++;
+ if (vlan_id_list->vlan_itf) {
+ if (strcmp(vlan_id_list->vlan_itf->name, ndisc_entry->ifname) == 0) {
+ ln = __LINE__;
+ vid_intf_present = 1;
+ }
- ICCPD_LOG_DEBUG(__FUNCTION__,
- "ND is learnt from intf %s, peer-link %s is the member of this vlan",
- vlan_id_list->vlan_itf->name, peer_link_if->name);
+ if (vid_intf_present && local_if_is_l3_mode(vlan_id_list->vlan_itf)) {
+ if (memcmp((char *)ndisc_entry->ipv6_addr, (char *)vlan_id_list->vlan_itf->ipv6_addr, 16) == 0)
+ {
+ my_ip_nd_flag = 1;
+ }
- /* Peer-link belong to L3 vlan is alive, set the NDISC info */
- set_ndisc_flag = 1;
+ if ((my_ip_nd_flag == 0) && is_link_local)
+ {
+ if (memcmp((char *)ndisc_entry->ipv6_addr, (char *)vlan_id_list->vlan_itf->ipv6_ll_addr, 16) == 0)
+ {
+ my_ip_nd_flag = 1;
+ }
+ }
+ }
- break;
+ ICCPD_LOG_DEBUG(__FUNCTION__,
+ "ND is learnt from intf %s, peer-link %s is the member of this vlan",
+ vlan_id_list->vlan_itf->name, peer_link_if->name);
+
+ /* Peer-link belong to L3 vlan is alive, set the NDISC info */
+ set_ndisc_flag = 1;
+ }
+ }
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ND Received ln %d, vlan_count %d, set_ndisc_flag %d, my_ip %d",
+ ln, vlan_count, set_ndisc_flag, my_ip_nd_flag);
+
+ if (vlan_count == 0)
+ {
+ vlan_if = local_if_find_by_name(ndisc_entry->ifname);
+ if (vlan_if && vlan_if->is_l3_proto_enabled)
+ {
+ if (memcmp((char *)ndisc_entry->ipv6_addr, (char *)vlan_if->ipv6_addr, 16) == 0)
+ {
+ my_ip_nd_flag = 1;
+ }
+
+ if ((my_ip_nd_flag == 0) && is_link_local)
+ {
+ if (memcmp((char *)ndisc_entry->ipv6_addr, (char *)vlan_if->ipv6_ll_addr, 16) == 0)
+ {
+ my_ip_nd_flag = 1;
+ }
+ }
+ set_ndisc_flag = 1;
+ }
}
}
}
+ if(my_ip_nd_flag)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__," ignoring ND sync for self ipv6 %s ", show_ipv6_str((char *)ndisc_entry->ipv6_addr));
+ return 0;
+ }
+
if (set_ndisc_flag == 0)
{
LIST_FOREACH(local_if, &(MLACP(csm).lif_list), mlacp_next)
@@ -695,21 +1048,24 @@ int mlacp_fsm_update_ndisc_entry(struct CSM *csm, struct NDISCMsg *ndisc_entry)
{
if (!local_if_is_l3_mode(local_if))
{
+ ln = __LINE__;
/* Is the L2 MLAG itf belong to a vlan the same as peer? */
- LIST_FOREACH(vlan_id_list, &(local_if->vlan_list), port_next)
- {
- if (!vlan_id_list->vlan_itf)
- continue;
- if (strcmp(vlan_id_list->vlan_itf->name, ndisc_entry->ifname) != 0)
- continue;
- if (!local_if_is_l3_mode(vlan_id_list->vlan_itf))
- continue;
+ if (vlan_id) {
+ vlan_id_list = RB_FIND(vlan_rb_tree, &(local_if->vlan_tree), &vlan_key);
+ if (vlan_id_list && vlan_id_list->vlan_itf) {
- ICCPD_LOG_DEBUG(__FUNCTION__,
- "ND is learnt from intf %s, %s is the member of this vlan", vlan_id_list->vlan_itf->name, local_if->name);
- break;
+ if (memcmp((char *)ndisc_entry->ipv6_addr, (char *)vlan_id_list->vlan_itf->ipv6_addr, 16) == 0)
+ {
+ my_ip_nd_flag = 1;
+ }
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ND is learnt from intf %s, %s is the member of this vlan, my_ip %d",
+ vlan_id_list->vlan_itf->name, local_if->name, my_ip_nd_flag);
+ }
}
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ND received PO %s, active %d, ln %d",
+ local_if->name, local_if->po_active, ln);
if (vlan_id_list && local_if->po_active == 1)
{
/* Any po of L3 vlan is alive, set the NDISC info */
@@ -722,7 +1078,8 @@ int mlacp_fsm_update_ndisc_entry(struct CSM *csm, struct NDISCMsg *ndisc_entry)
/* Is the ARP belong to a L3 mode MLAG itf? */
if (strcmp(local_if->name, ndisc_entry->ifname) == 0)
{
- ICCPD_LOG_DEBUG(__FUNCTION__, "ND is learnt from mclag L3 intf %s", local_if->name);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ND is learnt from mclag L3 intf %s, active %d",
+ local_if->name, local_if->po_active);
if (local_if->po_active == 1)
{
/* po is alive, set the NDISC info */
@@ -732,6 +1089,7 @@ int mlacp_fsm_update_ndisc_entry(struct CSM *csm, struct NDISCMsg *ndisc_entry)
}
else
{
+ ln = __LINE__;
continue;
}
}
@@ -739,36 +1097,69 @@ int mlacp_fsm_update_ndisc_entry(struct CSM *csm, struct NDISCMsg *ndisc_entry)
}
}
+ if(my_ip_nd_flag)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__," ignoring ND sync for self ipv6 %s ", show_ipv6_str((char *)ndisc_entry->ipv6_addr));
+ return 0;
+ }
/* set dynamic Ndisc */
if (set_ndisc_flag == 1)
{
+ if (ndisc_entry->flag & NEIGH_SYNC_FLAG_SELF_LL)
+ {
+ permanent_neigh = 1;
+ is_ack_ll = 1;
+ }
+
+ if (ndisc_entry->flag & NEIGH_SYNC_FLAG_SELF_IP)
+ {
+ permanent_neigh = 1;
+ }
+
if (ndisc_entry->op_type == NEIGH_SYNC_ADD)
{
- if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_entry->ipv6_addr, 1, ndisc_entry->mac_addr, ndisc_entry->ifname) < 0)
+ err = iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_entry->ipv6_addr, 1, ndisc_entry->mac_addr, ndisc_entry->ifname, permanent_neigh, 10);
+ if (err < 0)
{
- ICCPD_LOG_WARN(__FUNCTION__, "Failed to add nd entry(%s %s %s) to kernel",
- ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str);
- return MCLAG_ERROR;
+ if (err != ICCP_NLE_SEQ_MISMATCH) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Failed to add nd entry(%s %s %s) to kernel, status %d",
+ ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str, err);
+ return MCLAG_ERROR;
+ }
}
+ if (ndisc_entry->flag & NEIGH_SYNC_FLAG_ACK)
+ {
+ ICCPD_LOG_DEBUG(__FUNCTION__,"Sync ND on ACK ");
+ syn_ack_local_neigh_mac_info_to_peer(ndisc_entry->ifname, is_ack_ll);
+ }
}
else
{
- if (iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_entry->ipv6_addr, 0, ndisc_entry->mac_addr, ndisc_entry->ifname) < 0)
+ err = iccp_netlink_neighbor_request(AF_INET6, (uint8_t *)ndisc_entry->ipv6_addr, 0, ndisc_entry->mac_addr, ndisc_entry->ifname, permanent_neigh, 11);
+ if (err < 0)
{
- ICCPD_LOG_WARN(__FUNCTION__, "Failed to delete nd entry(%s %s %s) from kernel",
- ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str);
- return MCLAG_ERROR;
+ if (err != ICCP_NLE_SEQ_MISMATCH) {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Failed to delete nd entry(%s %s %s) from kernel status %d",
+ ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str, err);
+ return MCLAG_ERROR;
+ }
}
-
}
- /* ICCPD_LOG_DEBUG(__FUNCTION__, "NDISC update for %s %s %s", ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str); */
+ ICCPD_LOG_DEBUG(__FUNCTION__, "NDISC update for %s %s %s", ndisc_entry->ifname, show_ipv6_str((char *)ndisc_entry->ipv6_addr), mac_str);
}
else
{
- ICCPD_LOG_DEBUG(__FUNCTION__, "Failure: port-channel is not alive");
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Failure: port-channel is not alive, ln %d", ln);
/* TODO Set static route through peer-link or just skip it? */
+ local_vlan_if = local_if_find_by_name(ndisc_entry->ifname);
+ if (local_vlan_if) {
+ if (memcmp((char *)ndisc_entry->ipv6_addr, (char *)local_vlan_if->ipv6_addr, 16) == 0) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "ignore my ip %s", show_ipv6_str((char *)ndisc_entry->ipv6_addr));
+ return 0;
+ }
+ }
}
/* update NDISC list */
@@ -798,6 +1189,8 @@ int mlacp_fsm_update_ndisc_entry(struct CSM *csm, struct NDISCMsg *ndisc_entry)
sprintf(ndisc_msg->ifname, "%s", ndisc_entry->ifname);
memcpy((char *)ndisc_msg->ipv6_addr, (char *)ndisc_entry->ipv6_addr, 16);
ndisc_msg->op_type = ndisc_entry->op_type;
+ ndisc_msg->flag = 0;
+ ndisc_msg->learn_flag = NEIGH_REMOTE;
memcpy(ndisc_msg->mac_addr, ndisc_entry->mac_addr, ETHER_ADDR_LEN);
if (iccp_csm_init_msg(&msg, (char *)ndisc_msg, sizeof(struct NDISCMsg)) == 0)
{
@@ -868,7 +1261,7 @@ int mlacp_fsm_update_port_channel_info(struct CSM* csm,
if (peer_if->po_id != ntohs(tlv->agg_id))
continue;
- LIST_FOREACH(peer_vlan_id, &(peer_if->vlan_list), port_next)
+ RB_FOREACH(peer_vlan_id, vlan_rb_tree, &(peer_if->vlan_tree))
{
peer_vlan_id->vlan_removed = 1;
}
@@ -886,7 +1279,8 @@ int mlacp_fsm_update_port_channel_info(struct CSM* csm,
iccp_consistency_check(peer_if->name);
- ICCPD_LOG_DEBUG(__FUNCTION__, "Peer intf %s info: ipv4 addr %s l3 mode %d", peer_if->name, show_ip_str( tlv->ipv4_addr), peer_if->l3_mode);
+ ICCPD_LOG_DEBUG("ICCP_FSM", "RX Peer po_info: %s ipv4 addr %s l3 mode %d",
+ peer_if->name, show_ip_str( tlv->ipv4_addr), peer_if->l3_mode);
break;
}
@@ -909,10 +1303,10 @@ int mlacp_fsm_update_peerlink_info(struct CSM* csm,
}
if (csm->peer_link_if->type != tlv->port_type)
- ICCPD_LOG_NOTICE(__FUNCTION__, "Peerlink port type of peer %d is not same with local %d !", tlv->port_type, csm->peer_link_if->type);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port type of peer %d is not same with local %d !", tlv->port_type, csm->peer_link_if->type);
if (tlv->port_type == IF_T_VXLAN && strncmp(csm->peer_itf_name, tlv->if_name, strlen(csm->peer_itf_name)))
- ICCPD_LOG_NOTICE(__FUNCTION__, "Peerlink port is vxlan port, but peerlink port of peer %s is not same with local %s !", tlv->if_name, csm->peer_itf_name);
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Peerlink port is vxlan port, but peerlink port of peer %s is not same with local %s !", tlv->if_name, csm->peer_itf_name);
return 0;
}
@@ -939,8 +1333,7 @@ int mlacp_fsm_update_warmboot(struct CSM* csm, struct mLACPWarmbootTLV* tlv)
return MCLAG_ERROR;
time(&csm->peer_warm_reboot_time);
- ICCPD_LOG_NOTICE(__FUNCTION__, "Receive warm reboot notification from peer!");
-
+ ICCPD_LOG_DEBUG("ICCP_FSM", "RX peer warm reboot: start, sync_state %s",
+ mlacp_state(csm));
return 0;
}
-
diff --git a/src/iccpd/src/openbsd_tree.c b/src/iccpd/src/openbsd_tree.c
new file mode 100644
index 000000000000..b9d8202df049
--- /dev/null
+++ b/src/iccpd/src/openbsd_tree.c
@@ -0,0 +1,618 @@
+/* $OpenBSD: subr_tree.c,v 1.9 2017/06/08 03:30:52 dlg Exp $ */
+
+/*
+ * Copyright 2002 Niels Provos
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2016 David Gwynne
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+
+#include <../include/openbsd_tree.h>
+
+static inline struct rb_entry *rb_n2e(const struct rb_type *t, void *node)
+{
+ unsigned long addr = (unsigned long)node;
+
+ return ((struct rb_entry *)(addr + t->t_offset));
+}
+
+static inline void *rb_e2n(const struct rb_type *t, struct rb_entry *rbe)
+{
+ unsigned long addr = (unsigned long)rbe;
+
+ return ((void *)(addr - t->t_offset));
+}
+
+#define RBE_LEFT(_rbe) (_rbe)->rbt_left
+#define RBE_RIGHT(_rbe) (_rbe)->rbt_right
+#define RBE_PARENT(_rbe) (_rbe)->rbt_parent
+#define RBE_COLOR(_rbe) (_rbe)->rbt_color
+
+#define RBH_ROOT(_rbt) (_rbt)->rbt_root
+
+static inline void rbe_set(struct rb_entry *rbe, struct rb_entry *parent)
+{
+ RBE_PARENT(rbe) = parent;
+ RBE_LEFT(rbe) = RBE_RIGHT(rbe) = NULL;
+ RBE_COLOR(rbe) = RB_RED;
+}
+
+static inline void rbe_set_blackred(struct rb_entry *black,
+ struct rb_entry *red)
+{
+ RBE_COLOR(black) = RB_BLACK;
+ RBE_COLOR(red) = RB_RED;
+}
+
+static inline void rbe_augment(const struct rb_type *t, struct rb_entry *rbe)
+{
+ (*t->t_augment)(rb_e2n(t, rbe));
+}
+
+static inline void rbe_if_augment(const struct rb_type *t, struct rb_entry *rbe)
+{
+ if (t->t_augment != NULL)
+ rbe_augment(t, rbe);
+}
+
+static inline void rbe_rotate_left(const struct rb_type *t,
+ struct rbt_tree *rbt, struct rb_entry *rbe)
+{
+ struct rb_entry *parent;
+ struct rb_entry *tmp;
+
+ tmp = RBE_RIGHT(rbe);
+ RBE_RIGHT(rbe) = RBE_LEFT(tmp);
+ if (RBE_RIGHT(rbe) != NULL)
+ RBE_PARENT(RBE_LEFT(tmp)) = rbe;
+
+ parent = RBE_PARENT(rbe);
+ RBE_PARENT(tmp) = parent;
+ if (parent != NULL) {
+ if (rbe == RBE_LEFT(parent))
+ RBE_LEFT(parent) = tmp;
+ else
+ RBE_RIGHT(parent) = tmp;
+ } else
+ RBH_ROOT(rbt) = tmp;
+
+ RBE_LEFT(tmp) = rbe;
+ RBE_PARENT(rbe) = tmp;
+
+ if (t->t_augment != NULL) {
+ rbe_augment(t, rbe);
+ rbe_augment(t, tmp);
+ parent = RBE_PARENT(tmp);
+ if (parent != NULL)
+ rbe_augment(t, parent);
+ }
+}
+
+static inline void rbe_rotate_right(const struct rb_type *t,
+ struct rbt_tree *rbt, struct rb_entry *rbe)
+{
+ struct rb_entry *parent;
+ struct rb_entry *tmp;
+
+ tmp = RBE_LEFT(rbe);
+ RBE_LEFT(rbe) = RBE_RIGHT(tmp);
+ if (RBE_LEFT(rbe) != NULL)
+ RBE_PARENT(RBE_RIGHT(tmp)) = rbe;
+
+ parent = RBE_PARENT(rbe);
+ RBE_PARENT(tmp) = parent;
+ if (parent != NULL) {
+ if (rbe == RBE_LEFT(parent))
+ RBE_LEFT(parent) = tmp;
+ else
+ RBE_RIGHT(parent) = tmp;
+ } else
+ RBH_ROOT(rbt) = tmp;
+
+ RBE_RIGHT(tmp) = rbe;
+ RBE_PARENT(rbe) = tmp;
+
+ if (t->t_augment != NULL) {
+ rbe_augment(t, rbe);
+ rbe_augment(t, tmp);
+ parent = RBE_PARENT(tmp);
+ if (parent != NULL)
+ rbe_augment(t, parent);
+ }
+}
+
+static inline void rbe_insert_color(const struct rb_type *t,
+ struct rbt_tree *rbt, struct rb_entry *rbe)
+{
+ struct rb_entry *parent, *gparent, *tmp;
+
+ while ((parent = RBE_PARENT(rbe)) != NULL
+ && RBE_COLOR(parent) == RB_RED) {
+ gparent = RBE_PARENT(parent);
+
+ if (parent == RBE_LEFT(gparent)) {
+ tmp = RBE_RIGHT(gparent);
+ if (tmp != NULL && RBE_COLOR(tmp) == RB_RED) {
+ RBE_COLOR(tmp) = RB_BLACK;
+ rbe_set_blackred(parent, gparent);
+ rbe = gparent;
+ continue;
+ }
+
+ if (RBE_RIGHT(parent) == rbe) {
+ rbe_rotate_left(t, rbt, parent);
+ tmp = parent;
+ parent = rbe;
+ rbe = tmp;
+ }
+
+ rbe_set_blackred(parent, gparent);
+ rbe_rotate_right(t, rbt, gparent);
+ } else {
+ tmp = RBE_LEFT(gparent);
+ if (tmp != NULL && RBE_COLOR(tmp) == RB_RED) {
+ RBE_COLOR(tmp) = RB_BLACK;
+ rbe_set_blackred(parent, gparent);
+ rbe = gparent;
+ continue;
+ }
+
+ if (RBE_LEFT(parent) == rbe) {
+ rbe_rotate_right(t, rbt, parent);
+ tmp = parent;
+ parent = rbe;
+ rbe = tmp;
+ }
+
+ rbe_set_blackred(parent, gparent);
+ rbe_rotate_left(t, rbt, gparent);
+ }
+ }
+
+ RBE_COLOR(RBH_ROOT(rbt)) = RB_BLACK;
+}
+
+static inline void rbe_remove_color(const struct rb_type *t,
+ struct rbt_tree *rbt,
+ struct rb_entry *parent,
+ struct rb_entry *rbe)
+{
+ struct rb_entry *tmp;
+
+ while ((rbe == NULL || RBE_COLOR(rbe) == RB_BLACK)
+ && rbe != RBH_ROOT(rbt) && parent) {
+ if (RBE_LEFT(parent) == rbe) {
+ tmp = RBE_RIGHT(parent);
+ if (RBE_COLOR(tmp) == RB_RED) {
+ rbe_set_blackred(tmp, parent);
+ rbe_rotate_left(t, rbt, parent);
+ tmp = RBE_RIGHT(parent);
+ }
+ if ((RBE_LEFT(tmp) == NULL
+ || RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK)
+ && (RBE_RIGHT(tmp) == NULL
+ || RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
+ RBE_COLOR(tmp) = RB_RED;
+ rbe = parent;
+ parent = RBE_PARENT(rbe);
+ } else {
+ if (RBE_RIGHT(tmp) == NULL
+ || RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK) {
+ struct rb_entry *oleft;
+
+ oleft = RBE_LEFT(tmp);
+ if (oleft != NULL)
+ RBE_COLOR(oleft) = RB_BLACK;
+
+ RBE_COLOR(tmp) = RB_RED;
+ rbe_rotate_right(t, rbt, tmp);
+ tmp = RBE_RIGHT(parent);
+ }
+
+ RBE_COLOR(tmp) = RBE_COLOR(parent);
+ RBE_COLOR(parent) = RB_BLACK;
+ if (RBE_RIGHT(tmp))
+ RBE_COLOR(RBE_RIGHT(tmp)) = RB_BLACK;
+
+ rbe_rotate_left(t, rbt, parent);
+ rbe = RBH_ROOT(rbt);
+ break;
+ }
+ } else {
+ tmp = RBE_LEFT(parent);
+ if (RBE_COLOR(tmp) == RB_RED) {
+ rbe_set_blackred(tmp, parent);
+ rbe_rotate_right(t, rbt, parent);
+ tmp = RBE_LEFT(parent);
+ }
+
+ if ((RBE_LEFT(tmp) == NULL
+ || RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK)
+ && (RBE_RIGHT(tmp) == NULL
+ || RBE_COLOR(RBE_RIGHT(tmp)) == RB_BLACK)) {
+ RBE_COLOR(tmp) = RB_RED;
+ rbe = parent;
+ parent = RBE_PARENT(rbe);
+ } else {
+ if (RBE_LEFT(tmp) == NULL
+ || RBE_COLOR(RBE_LEFT(tmp)) == RB_BLACK) {
+ struct rb_entry *oright;
+
+ oright = RBE_RIGHT(tmp);
+ if (oright != NULL)
+ RBE_COLOR(oright) = RB_BLACK;
+
+ RBE_COLOR(tmp) = RB_RED;
+ rbe_rotate_left(t, rbt, tmp);
+ tmp = RBE_LEFT(parent);
+ }
+
+ RBE_COLOR(tmp) = RBE_COLOR(parent);
+ RBE_COLOR(parent) = RB_BLACK;
+ if (RBE_LEFT(tmp) != NULL)
+ RBE_COLOR(RBE_LEFT(tmp)) = RB_BLACK;
+
+ rbe_rotate_right(t, rbt, parent);
+ rbe = RBH_ROOT(rbt);
+ break;
+ }
+ }
+ }
+
+ if (rbe != NULL)
+ RBE_COLOR(rbe) = RB_BLACK;
+}
+
+static inline struct rb_entry *
+rbe_remove(const struct rb_type *t, struct rbt_tree *rbt, struct rb_entry *rbe)
+{
+ struct rb_entry *child, *parent, *old = rbe;
+ unsigned int color;
+
+ if (RBE_LEFT(rbe) == NULL)
+ child = RBE_RIGHT(rbe);
+ else if (RBE_RIGHT(rbe) == NULL)
+ child = RBE_LEFT(rbe);
+ else {
+ struct rb_entry *tmp;
+
+ rbe = RBE_RIGHT(rbe);
+ while ((tmp = RBE_LEFT(rbe)) != NULL)
+ rbe = tmp;
+
+ child = RBE_RIGHT(rbe);
+ parent = RBE_PARENT(rbe);
+ color = RBE_COLOR(rbe);
+ if (child != NULL)
+ RBE_PARENT(child) = parent;
+ if (parent != NULL) {
+ if (RBE_LEFT(parent) == rbe)
+ RBE_LEFT(parent) = child;
+ else
+ RBE_RIGHT(parent) = child;
+
+ rbe_if_augment(t, parent);
+ } else
+ RBH_ROOT(rbt) = child;
+ if (RBE_PARENT(rbe) == old)
+ parent = rbe;
+ *rbe = *old;
+
+ tmp = RBE_PARENT(old);
+ if (tmp != NULL) {
+ if (RBE_LEFT(tmp) == old)
+ RBE_LEFT(tmp) = rbe;
+ else
+ RBE_RIGHT(tmp) = rbe;
+
+ rbe_if_augment(t, tmp);
+ } else
+ RBH_ROOT(rbt) = rbe;
+
+ RBE_PARENT(RBE_LEFT(old)) = rbe;
+ if (RBE_RIGHT(old))
+ RBE_PARENT(RBE_RIGHT(old)) = rbe;
+
+ if (t->t_augment != NULL && parent != NULL) {
+ tmp = parent;
+ do {
+ rbe_augment(t, tmp);
+ tmp = RBE_PARENT(tmp);
+ } while (tmp != NULL);
+ }
+
+ goto color;
+ }
+
+ parent = RBE_PARENT(rbe);
+ color = RBE_COLOR(rbe);
+
+ if (child != NULL)
+ RBE_PARENT(child) = parent;
+ if (parent != NULL) {
+ if (RBE_LEFT(parent) == rbe)
+ RBE_LEFT(parent) = child;
+ else
+ RBE_RIGHT(parent) = child;
+
+ rbe_if_augment(t, parent);
+ } else
+ RBH_ROOT(rbt) = child;
+color:
+ if (color == RB_BLACK)
+ rbe_remove_color(t, rbt, parent, child);
+
+ return (old);
+}
+
+void *_rb_remove(const struct rb_type *t, struct rbt_tree *rbt, void *elm)
+{
+ struct rb_entry *rbe = rb_n2e(t, elm);
+ struct rb_entry *old;
+
+ old = rbe_remove(t, rbt, rbe);
+
+ return (old == NULL ? NULL : rb_e2n(t, old));
+}
+
+void *_rb_insert(const struct rb_type *t, struct rbt_tree *rbt, void *elm)
+{
+ struct rb_entry *rbe = rb_n2e(t, elm);
+ struct rb_entry *tmp;
+ struct rb_entry *parent = NULL;
+ void *node;
+ int comp = 0;
+
+ tmp = RBH_ROOT(rbt);
+ while (tmp != NULL) {
+ parent = tmp;
+
+ node = rb_e2n(t, tmp);
+ comp = (*t->t_compare)(elm, node);
+ if (comp < 0)
+ tmp = RBE_LEFT(tmp);
+ else if (comp > 0)
+ tmp = RBE_RIGHT(tmp);
+ else
+ return (node);
+ }
+
+ rbe_set(rbe, parent);
+
+ if (parent != NULL) {
+ if (comp < 0)
+ RBE_LEFT(parent) = rbe;
+ else
+ RBE_RIGHT(parent) = rbe;
+
+ rbe_if_augment(t, parent);
+ } else
+ RBH_ROOT(rbt) = rbe;
+
+ rbe_insert_color(t, rbt, rbe);
+
+ return (NULL);
+}
+
+/* Finds the node with the same key as elm */
+void *_rb_find(const struct rb_type *t, struct rbt_tree *rbt, const void *key)
+{
+ struct rb_entry *tmp = RBH_ROOT(rbt);
+ void *node;
+ int comp;
+
+ while (tmp != NULL) {
+ node = rb_e2n(t, tmp);
+ comp = (*t->t_compare)(key, node);
+ if (comp < 0)
+ tmp = RBE_LEFT(tmp);
+ else if (comp > 0)
+ tmp = RBE_RIGHT(tmp);
+ else
+ return (node);
+ }
+
+ return (NULL);
+}
+
+/* Finds the first node greater than or equal to the search key */
+void *_rb_nfind(const struct rb_type *t, struct rbt_tree *rbt, const void *key)
+{
+ struct rb_entry *tmp = RBH_ROOT(rbt);
+ void *node;
+ void *res = NULL;
+ int comp;
+
+ while (tmp != NULL) {
+ node = rb_e2n(t, tmp);
+ comp = (*t->t_compare)(key, node);
+ if (comp < 0) {
+ res = node;
+ tmp = RBE_LEFT(tmp);
+ } else if (comp > 0)
+ tmp = RBE_RIGHT(tmp);
+ else
+ return (node);
+ }
+
+ return (res);
+}
+
+void *_rb_next(const struct rb_type *t, void *elm)
+{
+ struct rb_entry *rbe = rb_n2e(t, elm);
+
+ if (RBE_RIGHT(rbe) != NULL) {
+ rbe = RBE_RIGHT(rbe);
+ while (RBE_LEFT(rbe) != NULL)
+ rbe = RBE_LEFT(rbe);
+ } else {
+ if (RBE_PARENT(rbe) && (rbe == RBE_LEFT(RBE_PARENT(rbe))))
+ rbe = RBE_PARENT(rbe);
+ else {
+ while (RBE_PARENT(rbe)
+ && (rbe == RBE_RIGHT(RBE_PARENT(rbe))))
+ rbe = RBE_PARENT(rbe);
+ rbe = RBE_PARENT(rbe);
+ }
+ }
+
+ return (rbe == NULL ? NULL : rb_e2n(t, rbe));
+}
+
+void *_rb_prev(const struct rb_type *t, void *elm)
+{
+ struct rb_entry *rbe = rb_n2e(t, elm);
+
+ if (RBE_LEFT(rbe)) {
+ rbe = RBE_LEFT(rbe);
+ while (RBE_RIGHT(rbe))
+ rbe = RBE_RIGHT(rbe);
+ } else {
+ if (RBE_PARENT(rbe) && (rbe == RBE_RIGHT(RBE_PARENT(rbe))))
+ rbe = RBE_PARENT(rbe);
+ else {
+ while (RBE_PARENT(rbe)
+ && (rbe == RBE_LEFT(RBE_PARENT(rbe))))
+ rbe = RBE_PARENT(rbe);
+ rbe = RBE_PARENT(rbe);
+ }
+ }
+
+ return (rbe == NULL ? NULL : rb_e2n(t, rbe));
+}
+
+void *_rb_root(const struct rb_type *t, struct rbt_tree *rbt)
+{
+ struct rb_entry *rbe = RBH_ROOT(rbt);
+
+ return (rbe == NULL ? rbe : rb_e2n(t, rbe));
+}
+
+void *_rb_min(const struct rb_type *t, struct rbt_tree *rbt)
+{
+ struct rb_entry *rbe = RBH_ROOT(rbt);
+ struct rb_entry *parent = NULL;
+
+ while (rbe != NULL) {
+ parent = rbe;
+ rbe = RBE_LEFT(rbe);
+ }
+
+ return (parent == NULL ? NULL : rb_e2n(t, parent));
+}
+
+void *_rb_max(const struct rb_type *t, struct rbt_tree *rbt)
+{
+ struct rb_entry *rbe = RBH_ROOT(rbt);
+ struct rb_entry *parent = NULL;
+
+ while (rbe != NULL) {
+ parent = rbe;
+ rbe = RBE_RIGHT(rbe);
+ }
+
+ return (parent == NULL ? NULL : rb_e2n(t, parent));
+}
+
+void *_rb_left(const struct rb_type *t, void *node)
+{
+ struct rb_entry *rbe = rb_n2e(t, node);
+ rbe = RBE_LEFT(rbe);
+ return (rbe == NULL ? NULL : rb_e2n(t, rbe));
+}
+
+void *_rb_right(const struct rb_type *t, void *node)
+{
+ struct rb_entry *rbe = rb_n2e(t, node);
+ rbe = RBE_RIGHT(rbe);
+ return (rbe == NULL ? NULL : rb_e2n(t, rbe));
+}
+
+void *_rb_parent(const struct rb_type *t, void *node)
+{
+ struct rb_entry *rbe = rb_n2e(t, node);
+ rbe = RBE_PARENT(rbe);
+ return (rbe == NULL ? NULL : rb_e2n(t, rbe));
+}
+
+void _rb_set_left(const struct rb_type *t, void *node, void *left)
+{
+ struct rb_entry *rbe = rb_n2e(t, node);
+ struct rb_entry *rbl = (left == NULL) ? NULL : rb_n2e(t, left);
+
+ RBE_LEFT(rbe) = rbl;
+}
+
+void _rb_set_right(const struct rb_type *t, void *node, void *right)
+{
+ struct rb_entry *rbe = rb_n2e(t, node);
+ struct rb_entry *rbr = (right == NULL) ? NULL : rb_n2e(t, right);
+
+ RBE_RIGHT(rbe) = rbr;
+}
+
+void _rb_set_parent(const struct rb_type *t, void *node, void *parent)
+{
+ struct rb_entry *rbe = rb_n2e(t, node);
+ struct rb_entry *rbp = (parent == NULL) ? NULL : rb_n2e(t, parent);
+
+ RBE_PARENT(rbe) = rbp;
+}
+
+void _rb_poison(const struct rb_type *t, void *node, unsigned long poison)
+{
+ struct rb_entry *rbe = rb_n2e(t, node);
+
+ RBE_PARENT(rbe) = RBE_LEFT(rbe) = RBE_RIGHT(rbe) =
+ (struct rb_entry *)poison;
+}
+
+int _rb_check(const struct rb_type *t, void *node, unsigned long poison)
+{
+ struct rb_entry *rbe = rb_n2e(t, node);
+
+ return ((unsigned long)RBE_PARENT(rbe) == poison
+ && (unsigned long)RBE_LEFT(rbe) == poison
+ && (unsigned long)RBE_RIGHT(rbe) == poison);
+}
diff --git a/src/iccpd/src/port.c b/src/iccpd/src/port.c
index e63429a77c2e..7e233a7c20bd 100644
--- a/src/iccpd/src/port.c
+++ b/src/iccpd/src/port.c
@@ -28,8 +28,23 @@
#include "../include/port.h"
#include "../include/system.h"
#include "../include/iccp_csm.h"
-#include "../include/iccp_netlink.h"
+#include "../include/mlacp_link_handler.h"
#include "../include/scheduler.h"
+#include "../include/iccp_netlink.h"
+#include "../include/iccp_ifm.h"
+
+
+static int vlan_node_compare(const struct VLAN_ID *p_vlan_node1, const struct VLAN_ID *p_vlan_node2)
+{
+ if (p_vlan_node1->vid < p_vlan_node2->vid)
+ return -1;
+
+ if (p_vlan_node1->vid > p_vlan_node2->vid)
+ return 1;
+
+ return 0;
+}
+RB_GENERATE(vlan_rb_tree, VLAN_ID, vlan_entry, vlan_node_compare);
void local_if_init(struct LocalInterface* local_if)
{
@@ -46,11 +61,14 @@ void local_if_init(struct LocalInterface* local_if)
local_if->is_peer_link = 0;
local_if->is_arp_accept = 0;
local_if->l3_mode = 0;
+ local_if->master_ifindex = 0;
local_if->state = PORT_STATE_DOWN;
local_if->prefixlen = 32;
local_if->csm = NULL;
local_if->isolate_to_peer_link = 0;
- LIST_INIT(&local_if->vlan_list);
+ local_if->is_l3_proto_enabled = false;
+ local_if->vlan_count = 0;
+ RB_INIT(vlan_rb_tree, &local_if->vlan_tree);
return;
}
@@ -64,7 +82,7 @@ void vlan_info_init(struct VLAN_ID* vlan)
return;
}
-struct LocalInterface* local_if_create(int ifindex, char* ifname, int type)
+struct LocalInterface* local_if_create(int ifindex, char* ifname, int type, uint8_t state)
{
struct System* sys = NULL;
struct LocalInterface* local_if = NULL;
@@ -77,11 +95,10 @@ struct LocalInterface* local_if_create(int ifindex, char* ifname, int type)
if (!(sys = system_get_instance()))
return NULL;
- if (ifindex < 0)
- return NULL;
-
- if ((local_if = local_if_find_by_ifindex(ifindex)))
- return local_if;
+ if (ifindex > 0) {
+ if ((local_if = local_if_find_by_ifindex(ifindex)))
+ return local_if;
+ }
if (!(local_if = (struct LocalInterface*)malloc(sizeof(struct LocalInterface))))
{
@@ -91,7 +108,10 @@ struct LocalInterface* local_if_create(int ifindex, char* ifname, int type)
local_if_init(local_if);
local_if->ifindex = ifindex;
- local_if->type = type;
+ local_if->type = type;
+ local_if->state = state;
+
+ local_if->po_down_time = 0;
if (local_if->type == IF_T_PORT_CHANNEL)
{
@@ -107,6 +127,7 @@ struct LocalInterface* local_if_create(int ifindex, char* ifname, int type)
return NULL;
local_if->po_id = atoi(&ifname[i]);
+ local_if->po_active = (state == PORT_STATE_UP) ? 1 : 0;
}
if (ifname)
@@ -121,7 +142,10 @@ struct LocalInterface* local_if_create(int ifindex, char* ifname, int type)
break;
case IF_T_VLAN:
- /* do nothing currently. */
+ if(is_unique_ip_configured(local_if->name))
+ {
+ local_if->is_l3_proto_enabled = true;
+ }
break;
case IF_T_VXLAN:
@@ -142,6 +166,9 @@ struct LocalInterface* local_if_create(int ifindex, char* ifname, int type)
LIST_INSERT_HEAD(&(sys->lif_list), local_if, system_next);
+ //if there is pending vlan membership for this interface move to system lif
+ move_pending_vlan_mbr_to_lif(sys, local_if);
+
/*Check the intf is peer-link? Only support PortChannel and Ethernet currently*/
/*When set peer-link, the local-if is probably not created*/
LIST_FOREACH(csm, &(sys->csm_list), next)
@@ -150,6 +177,7 @@ struct LocalInterface* local_if_create(int ifindex, char* ifname, int type)
{
local_if->is_peer_link = 1;
csm->peer_link_if = local_if;
+ set_peerlink_learn_kernel(csm, 0, 3);
break;
}
/*check the intf is bind with csm*/
@@ -217,24 +245,40 @@ struct LocalInterface* local_if_find_by_po_id(int po_id)
return NULL;
}
-static void local_if_vlan_remove(struct LocalInterface *lif_vlan)
+ void local_if_vlan_remove(struct LocalInterface *lif_vlan)
{
struct System *sys = NULL;
struct LocalInterface *lif = NULL;
struct VLAN_ID *vlan = NULL;
+ int vid = 0;
+ struct VLAN_ID vlan_key = { 0 };
+
+ if (!lif_vlan || lif_vlan->type != IF_T_VLAN)
+ {
+ return;
+ }
+
+ sscanf(lif_vlan->name, "Vlan%d", &vid);
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vid;
+
if ((sys = system_get_instance()) != NULL)
{
LIST_FOREACH(lif, &(sys->lif_list), system_next)
{
- LIST_FOREACH(vlan, &(lif->vlan_list), port_next)
+ if (lif->type == IF_T_VLAN)
+ continue;
+
+ //delink this vlan (lif_vlan) interface from all associated lifs
+ //in scenario where vlan membership delete comes later when compared
+ //to vlan interface delete from kernel
+ vlan = RB_FIND(vlan_rb_tree, &(lif->vlan_tree), &vlan_key);
+ if (vlan)
{
- if (lif_vlan != vlan->vlan_itf)
- continue;
-
vlan->vlan_itf = NULL;
}
- }
+ }
}
return;
@@ -279,6 +323,7 @@ void local_if_destroy(char *ifname)
{
struct LocalInterface* lif = NULL;
struct CSM *csm = NULL;
+ struct CSM *peer_ifname_csm = NULL;
struct System *sys = NULL;
if (!(sys = system_get_instance()))
@@ -297,21 +342,27 @@ void local_if_destroy(char *ifname)
else
local_if_remove(lif);
- csm = lif->csm;
- if (csm && csm->peer_link_if && strcmp(csm->peer_link_if->name, ifname) == 0)
+ //handle peer_link del case
+ if ( (peer_ifname_csm = system_get_csm_by_peer_ifname(ifname)) != NULL )
{
/*if the peerlink interface is not created, peer connection can not establish*/
- scheduler_session_disconnect_handler(csm);
+ scheduler_session_disconnect_handler(peer_ifname_csm);
+
+ // The function above calls iccp_csm_status_reset, which sets csm->Peer_link_if to NULL,
+ // accessing the peer_link_if cause crash due to null pointer access.
+#if 0
csm->peer_link_if->is_peer_link = 0;
csm->peer_link_if = NULL;
+#endif
}
+ csm = lif->csm;
if (csm && MLACP(csm).current_state == MLACP_STATE_EXCHANGE)
goto to_mlacp_purge;
else
goto to_sys_purge;
- to_sys_purge:
+to_sys_purge:
/* sys purge */
LIST_REMOVE(lif, system_next);
if (lif->csm)
@@ -319,7 +370,7 @@ void local_if_destroy(char *ifname)
LIST_INSERT_HEAD(&(sys->lif_purge_list), lif, system_purge_next);
return;
- to_mlacp_purge:
+to_mlacp_purge:
/* sys & mlacp purge */
LIST_REMOVE(lif, system_next);
LIST_REMOVE(lif, mlacp_next);
@@ -336,8 +387,11 @@ int local_if_is_l3_mode(struct LocalInterface* local_if)
if (local_if == NULL)
return 0;
- if (local_if->ipv4_addr != 0 || memcmp(local_if->ipv6_addr, addr_null, 16) != 0)
+ if ((local_if->ipv4_addr != 0)
+ || (memcmp(local_if->ipv6_addr, addr_null, 16) != 0)
+ || (local_if->master_ifindex != 0)) {
ret = 1;
+ }
return ret;
}
@@ -361,6 +415,25 @@ void local_if_change_flag_clear(void)
return;
}
+
+static void local_if_mlacp_purge_del(struct LocalInterface* lif)
+{
+ struct CSM* csm;
+ struct LocalInterface *lif_purge;
+
+ if (lif && lif->csm)
+ {
+ LIST_FOREACH(lif_purge, &(MLACP(lif->csm).lif_purge_list), mlacp_purge_next)
+ {
+ if (lif_purge == lif)
+ {
+ LIST_REMOVE(lif, mlacp_purge_next);
+ break;
+ }
+ }
+ }
+}
+
void local_if_purge_clear(void)
{
struct System* sys = NULL;
@@ -375,8 +448,7 @@ void local_if_purge_clear(void)
lif = LIST_FIRST(&(sys->lif_purge_list));
ICCPD_LOG_DEBUG(__FUNCTION__, "Purge %s", lif->name);
LIST_REMOVE(lif, system_purge_next);
- if (lif->mlacp_purge_next.le_next != 0 && lif->mlacp_purge_next.le_prev != 0)
- LIST_REMOVE(lif, mlacp_purge_next);
+ local_if_mlacp_purge_del(lif);
local_if_del_all_vlan(lif);
free(lif);
}
@@ -470,17 +542,15 @@ struct PeerInterface* peer_if_find_by_name(struct CSM* csm, char* name)
void peer_if_del_all_vlan(struct PeerInterface* pif)
{
- struct VLAN_ID *pvlan = NULL;
+ struct VLAN_ID *vlan = NULL;
+ struct VLAN_ID* vlan_temp = NULL;
- while (!LIST_EMPTY(&(pif->vlan_list)))
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Remove all VLANs from peer intf %s", pif->name);
+ RB_FOREACH_SAFE(vlan, vlan_rb_tree, &(pif->vlan_tree), vlan_temp)
{
- pvlan = LIST_FIRST(&(pif->vlan_list));
- ICCPD_LOG_DEBUG(__FUNCTION__, "Remove peer intf %s from VLAN %d",
- pif->name, pvlan->vid);
- LIST_REMOVE(pvlan, port_next);
- free(pvlan);
+ VLAN_RB_REMOVE(vlan_rb_tree, &(pif->vlan_tree), vlan);
+ free(vlan);
}
-
return;
}
@@ -497,73 +567,86 @@ void peer_if_destroy(struct PeerInterface* pif)
return;
}
-int local_if_add_vlan(struct LocalInterface* local_if, uint16_t vid)
+int local_if_add_vlan(struct LocalInterface* local_if, uint16_t vid)
{
struct VLAN_ID *vlan = NULL;
+ struct VLAN_ID vlan_key = { 0 };
char vlan_name[16] = "";
sprintf(vlan_name, "Vlan%d", vid);
- /* traverse 1 time */
- LIST_FOREACH(vlan, &(local_if->vlan_list), port_next)
- {
- if (vlan->vid == vid)
- break;
- }
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vid;
+ vlan = RB_FIND(vlan_rb_tree, &(local_if->vlan_tree), &vlan_key);
+
if (!vlan)
{
vlan = (struct VLAN_ID*)malloc(sizeof(struct VLAN_ID));
if (!vlan)
return MCLAG_ERROR;
- ICCPD_LOG_DEBUG(__FUNCTION__, "Add %s to VLAN %d", local_if->name, vid);
+ vlan_info_init(vlan);
+ vlan->vid = vid;
+ vlan->vlan_itf = local_if_find_by_name(vlan_name);
+
+ if (vlan->vlan_itf == NULL) {
+ ICCPD_LOG_DEBUG(__FUNCTION__, "vlan_itf %s not present", vlan_name);
+ }
+ local_if->vlan_count +=1;
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Add %s to VLAN %d vlan count %d", local_if->name, vid, local_if->vlan_count);
local_if->port_config_sync = 1;
- LIST_INSERT_HEAD(&(local_if->vlan_list), vlan, port_next);
+ RB_INSERT(vlan_rb_tree, &(local_if->vlan_tree), vlan);
}
- vlan_info_init(vlan);
- vlan->vid = vid;
vlan->vlan_removed = 0;
- vlan->vlan_itf = local_if_find_by_name(vlan_name);
-
- update_if_ipmac_on_standby(local_if);
+// update_if_ipmac_on_standby(local_if, 5);
+ if (vlan->vlan_itf)
+ {
+ if (local_if->is_peer_link)
+ {
+ update_vlan_if_mac_on_standby(vlan->vlan_itf, 1);
+ }
+ }
+ else
+ {
+ ICCPD_LOG_WARN(__FUNCTION__, "skip VLAN MAC update for vlan %d interface %s ", vid, local_if->name);
+ }
return 0;
}
void local_if_del_vlan(struct LocalInterface* local_if, uint16_t vid)
{
struct VLAN_ID *vlan = NULL;
+ struct VLAN_ID vlan_key = { 0 };
- /* traverse 1 time */
- LIST_FOREACH(vlan, &(local_if->vlan_list), port_next)
- {
- if (vlan->vid == vid)
- break;
- }
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vid;
+ vlan = RB_FIND(vlan_rb_tree, &(local_if->vlan_tree), &vlan_key);
+
if (vlan != NULL)
{
- LIST_REMOVE(vlan, port_next);
+ VLAN_RB_REMOVE(vlan_rb_tree, &(local_if->vlan_tree), vlan);
free(vlan);
local_if->port_config_sync = 1;
+ local_if->vlan_count -=1;
+ ICCPD_LOG_DEBUG(__FUNCTION__, "Remove %s from VLAN %d, count %d", local_if->name, vid, local_if->vlan_count);
}
-
- ICCPD_LOG_DEBUG(__FUNCTION__, "Remove %s from VLAN %d", local_if->name, vid);
-
return;
}
void local_if_del_all_vlan(struct LocalInterface* lif)
{
struct VLAN_ID* vlan = NULL;
+ struct VLAN_ID* vlan_temp = NULL;
- while (!LIST_EMPTY(&(lif->vlan_list)))
+ ICCPD_LOG_NOTICE(__FUNCTION__, "Remove all VLANs from %s", lif->name);
+ RB_FOREACH_SAFE(vlan, vlan_rb_tree, &(lif->vlan_tree), vlan_temp)
{
- vlan = LIST_FIRST(&(lif->vlan_list));
- ICCPD_LOG_DEBUG(__FUNCTION__, "Remove %s from VLAN %d", lif->name, vlan->vid);
- LIST_REMOVE(vlan, port_next);
+ VLAN_RB_REMOVE(vlan_rb_tree, &(lif->vlan_tree), vlan);
+ lif->vlan_count -=1;
free(vlan);
}
@@ -574,34 +657,30 @@ void local_if_del_all_vlan(struct LocalInterface* lif)
int peer_if_add_vlan(struct PeerInterface* peer_if, uint16_t vlan_id)
{
struct VLAN_ID *peer_vlan = NULL;
+ struct VLAN_ID vlan_key = { 0 };
char vlan_name[16] = "";
sprintf(vlan_name, "Vlan%d", vlan_id);
- /* traverse 1 time */
- LIST_FOREACH(peer_vlan, &(peer_if->vlan_list), port_next)
- {
- if (peer_vlan->vid == vlan_id)
- {
- ICCPD_LOG_DEBUG(__FUNCTION__, "Update VLAN ID %d for peer intf %s", peer_vlan->vid, peer_if->name);
- break;
- }
- }
+ memset(&vlan_key, 0, sizeof(struct VLAN_ID));
+ vlan_key.vid = vlan_id;
+ peer_vlan = RB_FIND(vlan_rb_tree, &(peer_if->vlan_tree), &vlan_key);
+
if (!peer_vlan)
{
peer_vlan = (struct VLAN_ID*)malloc(sizeof(struct VLAN_ID));
if (!peer_vlan)
return MCLAG_ERROR;
- ICCPD_LOG_DEBUG(__FUNCTION__, "Add peer intf %s to VLAN %d", peer_if->name, vlan_id);
- LIST_INSERT_HEAD(&(peer_if->vlan_list), peer_vlan, port_next);
+ vlan_info_init(peer_vlan);
+ peer_vlan->vid = vlan_id;
+
+ ICCPD_LOG_DEBUG(__FUNCTION__, "add VLAN ID = %d from peer's %s", vlan_id, peer_if->name);
+ RB_INSERT(vlan_rb_tree, &(peer_if->vlan_tree), peer_vlan);
}
- vlan_info_init(peer_vlan);
- peer_vlan->vid = vlan_id;
peer_vlan->vlan_removed = 0;
-
return 0;
}
@@ -610,14 +689,15 @@ int peer_if_clean_unused_vlan(struct PeerInterface* peer_if)
{
struct VLAN_ID *peer_vlan = NULL;
struct VLAN_ID *peer_vlan_next = NULL;
+ struct VLAN_ID *vlan_temp = NULL;
/* traverse 1 time */
- LIST_FOREACH(peer_vlan_next, &(peer_if->vlan_list), port_next)
+ RB_FOREACH_SAFE(peer_vlan_next, vlan_rb_tree, &(peer_if->vlan_tree), vlan_temp)
{
if (peer_vlan != NULL)
{
ICCPD_LOG_DEBUG(__FUNCTION__, "Remove peer intf %s from VLAN %d", peer_if->name, peer_vlan->vid);
- LIST_REMOVE(peer_vlan, port_next);
+ VLAN_RB_REMOVE(vlan_rb_tree, &(peer_if->vlan_tree), peer_vlan);
free(peer_vlan);
peer_vlan = NULL;
@@ -629,7 +709,7 @@ int peer_if_clean_unused_vlan(struct PeerInterface* peer_if)
if (peer_vlan != NULL)
{
ICCPD_LOG_DEBUG(__FUNCTION__, "Remove peer intf %s from VLAN %d", peer_if->name, peer_vlan->vid);
- LIST_REMOVE(peer_vlan, port_next);
+ VLAN_RB_REMOVE(vlan_rb_tree, &(peer_if->vlan_tree), peer_vlan);
free(peer_vlan);
}
@@ -660,9 +740,32 @@ int set_sys_arp_accept_flag(char* ifname, int flag)
memset(cmd, 0, 64);
snprintf(cmd, 63, "echo %d > /proc/sys/net/ipv4/conf/%s/arp_accept", flag, ifname);
if (system(cmd))
- ICCPD_LOG_WARN(__func__, "Failed to execute cmd = %s", flag, cmd);
+ ICCPD_LOG_WARN(__func__, "Failed to execute cmd = %s", cmd);
}
fclose(file_ptr);
return result;
}
+
+int local_if_l3_proto_enabled(const char* ifname)
+{
+ struct System* sys = NULL;
+ struct LocalInterface* local_if = NULL;
+
+ if (!ifname)
+ return 0;
+
+ if (!(sys = system_get_instance()))
+ return 0;
+
+ LIST_FOREACH(local_if, &(sys->lif_list), system_next)
+ {
+ if (strcmp(local_if->name, ifname) == 0)
+ {
+ if (local_if->is_l3_proto_enabled)
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/src/iccpd/src/scheduler.c b/src/iccpd/src/scheduler.c
index 0ff9d4f5e083..865f79b0da6b 100644
--- a/src/iccpd/src/scheduler.c
+++ b/src/iccpd/src/scheduler.c
@@ -48,6 +48,14 @@
*
******************************************************/
+//this needs to be fine tuned
+#define PEER_SOCK_SND_BUF_LEN (6 * 1024 * 1024)
+#define PEER_SOCK_RCV_BUF_LEN (6 * 1024 * 1024)
+#define RECV_RETRY_INTERVAL_USEC 100000
+#define RECV_RETRY_MAX 10
+
+extern int mlacp_prepare_for_warm_reboot(struct CSM* csm, char* buf, size_t max_buf_size);
+
static int session_conn_thread_lock(pthread_mutex_t *conn_mutex)
{
return 1; /*pthread_mutex_lock(conn_mutex);*/
@@ -71,10 +79,10 @@ static void heartbeat_check(struct CSM *csm)
return;
}
- if ( (time(NULL) - csm->heartbeat_update_time) > HEARTBEAT_TIMEOUT_SEC)
+ if ( (time(NULL) - csm->heartbeat_update_time) > csm->session_timeout)
{
/* hearbeat timeout*/
- ICCPD_LOG_WARN(__FUNCTION__, "iccpd connection timeout (heartbeat)");
+ ICCPD_LOG_WARN("ICCP_FSM", "iccpd connection timeout (heartbeat)");
scheduler_session_disconnect_handler(csm);
}
@@ -106,15 +114,13 @@ static int scheduler_transit_fsm()
iccp_csm_transit(csm);
app_csm_transit(csm);
mlacp_fsm_transit(csm);
-
- if (MLACP(csm).current_state == MLACP_STATE_EXCHANGE && (time(NULL) - sys->csm_trans_time) >= 60)
- {
- iccp_get_fdb_change_from_syncd();
- sys->csm_trans_time = time(NULL);
- }
}
- local_if_change_flag_clear();
+ //lif->changed flag is marked for state change for lif, for active node when
+ //it is in STAGE2 where it receiving cfg sync from peer if there is any po
+ //state change that change is not sent and this clear clears the marking and
+ //thus remote state is not updated; so commenting this out
+ //local_if_change_flag_clear();
local_if_purge_clear();
return 1;
@@ -131,6 +137,9 @@ int scheduler_csm_read_callback(struct CSM* csm)
size_t data_len = 0;
size_t pos = 0;
int recv_len = 0, len = 0, retval;
+ int num_retry = 0;
+ int total_retry_time = 0;
+ int total_data_len = 0;
if (csm->sock_fd <= 0)
return MCLAG_ERROR;
@@ -138,6 +147,7 @@ int scheduler_csm_read_callback(struct CSM* csm)
memset(peer_msg, 0, CSM_BUFFER_SIZE);
recv_len = 0;
+ errno = 0;
while (recv_len != sizeof(LDPHdr))
{
@@ -145,38 +155,92 @@ int scheduler_csm_read_callback(struct CSM* csm)
if (len == -1)
{
perror("recv(). Error");
+ ICCPD_LOG_WARN("ICCP_FSM", "Peer disconnect for header read error[%s] len = -1 till now received len = %d ", strerror(errno), recv_len);
+ SYSTEM_INCR_HDR_READ_SOCK_ERR_COUNTER(system_get_instance());
goto recv_err;
}
else if (len == 0)
{
- ICCPD_LOG_WARN(__FUNCTION__, "Peer disconnect for receive error");
+ ICCPD_LOG_WARN("ICCP_FSM", "Peer disconnect for header read error[%s] len = 0, till now received len = %d ",strerror(errno), recv_len);
+ SYSTEM_INCR_HDR_READ_SOCK_ZERO_LEN_COUNTER(system_get_instance());
goto recv_err;
}
recv_len += len;
/*usleep(100);*/
}
- data_len = ntohs(ldp_hdr->msg_len) - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS;
+ if (ntohs(ldp_hdr->msg_len) >= MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS)
+ {
+ data_len = ntohs(ldp_hdr->msg_len) - MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS;
+ }
+ else
+ {
+ ICCPD_LOG_ERR("ICCP_FSM", "Peer disconnect for invalid data error; length[%d] msg_type[0x%x] ", ntohs(ldp_hdr->msg_len), ntohs(ldp_hdr->msg_type));
+ SYSTEM_INCR_INVALID_PEER_MSG_COUNTER(system_get_instance());
+ goto recv_err;
+ }
+ total_data_len = data_len;
pos = 0;
while (data_len > 0)
{
- recv_len = recv(csm->sock_fd, &data[pos], data_len, 0);
+ /* When consecutive CCP session flaps happen, recv() call got stuck.
+ * Change recv() to non-blocking with retry mechanism. If max
+ * retry reaches, attempt one more retry after waiting for one KA
+ * interval before bringing down the session.
+ */
+ recv_len = recv(csm->sock_fd, &data[pos], data_len, MSG_DONTWAIT);
if (recv_len == -1)
{
- perror("continue recv(). Error");
- goto recv_err;
+ if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+ {
+ ICCPD_LOG_NOTICE(
+ "ICCP_FSM", "Non-blocking recv total/pending len %d/%d, errno %d, num_retry %d",
+ total_data_len, data_len, errno, num_retry);
+ ++num_retry;
+ if (num_retry > RECV_RETRY_MAX)
+ {
+ ICCPD_LOG_ERR(
+ "ICCP_FSM", "Non-blocking recv() retry failed, total/pending len %d/%d",
+ total_data_len, data_len);
+ SYSTEM_INCR_RX_RETRY_FAIL_COUNTER(system_get_instance());
+ goto recv_err;
+ }
+ else
+ {
+ if (num_retry == RECV_RETRY_MAX)
+ usleep((csm->session_timeout * 1000000) - total_retry_time);
+ else
+ {
+ total_retry_time += (num_retry * RECV_RETRY_INTERVAL_USEC);
+ usleep(num_retry * RECV_RETRY_INTERVAL_USEC);
+ }
+ recv_len = 0;
+ }
+ }
+ else
+ {
+ perror("continue recv() Error");
+ ICCPD_LOG_WARN("ICCP_FSM", "Peer data read error; recv_len:%d data_len:%d, errno %d",
+ recv_len, data_len, errno);
+ SYSTEM_INCR_TLV_READ_SOCK_ERR_COUNTER(system_get_instance());
+ goto recv_err;
+ }
}
else if (recv_len == 0)
{
- ICCPD_LOG_WARN(__FUNCTION__, "Peer disconnect for read error");
+ ICCPD_LOG_WARN("ICCP_FSM", "Peer disconnect for data read error; recv_len:%d data_len:%d ", recv_len, data_len);
+ SYSTEM_INCR_TLV_READ_SOCK_ZERO_LEN_COUNTER(system_get_instance());
goto recv_err;
}
data_len -= recv_len;
pos += recv_len;
/*usleep(100);*/
}
-
+ if (num_retry > 0)
+ {
+ SYSTEM_SET_RETRY_COUNTER(system_get_instance(), num_retry);
+ }
retval = iccp_csm_init_msg(&msg, peer_msg, ntohs(ldp_hdr->msg_len) + MSG_L_INCLUD_U_BIT_MSG_T_L_FIELDS);
if (retval == 0)
{
@@ -224,21 +288,21 @@ int scheduler_server_accept()
if (!csm)
{
/* can't find csm with peer ip*/
- ICCPD_LOG_INFO(__FUNCTION__, "csm null with peer ip [%s]", inet_ntoa(client_addr.sin_addr));
+ ICCPD_LOG_NOTICE("ICCP_FSM", "csm null with peer ip [%s]", inet_ntoa(client_addr.sin_addr));
goto reject_client;
}
if (csm->sock_fd > 0)
{
/* peer already connected*/
- ICCPD_LOG_INFO(__FUNCTION__, "csm sock is connected with peer ip [%s]", inet_ntoa(client_addr.sin_addr));
+ ICCPD_LOG_NOTICE("ICCP_FSM", "csm sock is connected with peer ip [%s]", inet_ntoa(client_addr.sin_addr));
goto reject_client;
}
if ((ret = scheduler_check_csm_config(csm)) < 0)
{
/* csm config error*/
- ICCPD_LOG_INFO(__FUNCTION__, "csm config error with peer ip [%s]", inet_ntoa(client_addr.sin_addr));
+ ICCPD_LOG_NOTICE("ICCP_FSM", "csm config error with peer ip [%s]", inet_ntoa(client_addr.sin_addr));
goto reject_client;
}
}
@@ -257,6 +321,8 @@ int scheduler_server_accept()
struct epoll_event event;
int err;
+ int send_buf_len = PEER_SOCK_SND_BUF_LEN;
+ int recv_buf_len = PEER_SOCK_RCV_BUF_LEN;
event.data.fd = new_fd;
event.events = EPOLLIN;
err = epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, new_fd, &event);
@@ -267,6 +333,14 @@ int scheduler_server_accept()
}
csm->sock_fd = new_fd;
+ if (setsockopt(csm->sock_fd, SOL_SOCKET, SO_SNDBUF, &send_buf_len, sizeof(send_buf_len)) == -1)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Set socket send buf option failed. Error");
+ }
+ if (setsockopt(csm->sock_fd, SOL_SOCKET, SO_RCVBUF, &recv_buf_len, sizeof(recv_buf_len)) == -1)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Set socket recv buf option failed. Error");
+ }
csm->current_state = ICCP_NONEXISTENT;
FD_SET(new_fd, &(sys->readfd));
sys->readfd_count++;
@@ -293,6 +367,8 @@ void iccp_get_start_type(struct System* sys)
if (strstr(g_csm_buf, "SONIC_BOOT_TYPE=warm"))
sys->warmboot_start = WARM_REBOOT;
+ ICCPD_LOG_DEBUG("ICCP_FSM", "Start ICCP: warm reboot %s",
+ (sys->warmboot_start == WARM_REBOOT)? "yes" : "no");
return;
}
@@ -309,8 +385,10 @@ void scheduler_init()
iccp_sys_local_if_list_get_init();
iccp_sys_local_if_list_get_addr();
/*Interfaces must be created before this func called*/
+ //no need to create iccpd config from startup file, it will be done through
+ //cli
iccp_config_from_file(sys->config_file_path);
-
+
/*Get kernel ARP info */
iccp_neigh_get_init();
@@ -331,7 +409,6 @@ void scheduler_init()
return;
}
-extern int mlacp_prepare_for_warm_reboot(struct CSM* csm, char* buf, size_t max_buf_size);
void mlacp_sync_send_warmboot_flag()
{
struct System* sys = NULL;
@@ -350,7 +427,7 @@ void mlacp_sync_send_warmboot_flag()
iccp_csm_send(csm, g_csm_buf, msg_len);
}
}
-
+ ICCPD_LOG_DEBUG("ICCP_FSM", "Send warmboot flag to peer. Start warmboot");
return;
}
@@ -542,12 +619,23 @@ void session_client_conn_handler(struct CSM *csm)
/* Conn OK*/
struct epoll_event event;
int err;
+ int send_buf_len = PEER_SOCK_SND_BUF_LEN;
+ int recv_buf_len = PEER_SOCK_RCV_BUF_LEN;
event.data.fd = connFd;
event.events = EPOLLIN;
err = epoll_ctl(sys->epoll_fd, EPOLL_CTL_ADD, connFd, &event);
if (err)
goto conn_fail;
csm->sock_fd = connFd;
+ if (setsockopt(csm->sock_fd, SOL_SOCKET, SO_SNDBUF, &send_buf_len, sizeof(send_buf_len)) == -1)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Set socket send buf option failed. Error");
+ }
+ if (setsockopt(csm->sock_fd, SOL_SOCKET, SO_RCVBUF, &recv_buf_len, sizeof(recv_buf_len)) == -1)
+ {
+ ICCPD_LOG_ERR(__FUNCTION__, "Set socket recv buf option failed. Error");
+ }
+
FD_SET(connFd, &(sys->readfd));
sys->readfd_count++;
ICCPD_LOG_INFO(__FUNCTION__, "Connect to server %s sucess .", csm->peer_ip);
@@ -707,6 +795,7 @@ int scheduler_check_csm_config(struct CSM* csm)
{
lif->is_peer_link = 1;
csm->peer_link_if = lif;
+ set_peerlink_learn_kernel(csm, 0, 2);
}
}
@@ -742,32 +831,66 @@ int scheduler_unregister_sock_read_event_callback(struct CSM* csm)
void scheduler_session_disconnect_handler(struct CSM* csm)
{
struct System* sys = NULL;
+ struct If_info * cif = NULL;
if ((sys = system_get_instance()) == NULL )
return;
- struct epoll_event event;
-
if (csm == NULL)
return;
+ ICCPD_LOG_NOTICE("ICCP_FSM", "scheduler session disconnect handler");
+
session_conn_thread_lock(&csm->conn_mutex);
scheduler_unregister_sock_read_event_callback(csm);
if (csm->sock_fd > 0)
{
- event.data.fd = csm->sock_fd;
- event.events = EPOLLIN;
- epoll_ctl(sys->epoll_fd, EPOLL_CTL_DEL, csm->sock_fd, &event);
-
- close(csm->sock_fd);
- csm->sock_fd = -1;
+ scheduler_csm_socket_cleanup(csm, 1);
}
mlacp_peer_disconn_handler(csm);
MLACP(csm).current_state = MLACP_STATE_INIT;
iccp_csm_status_reset(csm, 0);
+
time(&csm->connTimePrev);
session_conn_thread_unlock(&csm->conn_mutex);
return;
}
+
+void scheduler_csm_socket_cleanup(struct CSM* csm, int location)
+{
+ struct System* sys;
+ struct epoll_event event;
+
+ sys = system_get_instance();
+ if (sys == NULL)
+ return;
+
+ if (csm == NULL)
+ return;
+
+ if (csm->sock_fd <= 0)
+ return
+
+ event.data.fd = csm->sock_fd;
+ event.events = EPOLLIN;
+ if (epoll_ctl(sys->epoll_fd, EPOLL_CTL_DEL, csm->sock_fd, &event) != 0)
+ {
+ ICCPD_LOG_ERR("ICCP_FSM", "CSM socket %d epoll del error %d, location %d",
+ csm->sock_fd, errno, location);
+ }
+ if (close(csm->sock_fd) != 0)
+ {
+ ICCPD_LOG_ERR("ICCP_FSM", "CSM socket %d close error %d, location %d",
+ csm->sock_fd, errno, location);
+ SYSTEM_INCR_SOCKET_CLOSE_ERR_COUNTER(system_get_instance());
+ }
+ else
+ {
+ ICCPD_LOG_NOTICE("ICCP_FSM", "CSM socket %d close, location %d",
+ csm->sock_fd, location);
+ }
+ csm->sock_fd = -1;
+}
+
diff --git a/src/iccpd/src/system.c b/src/iccpd/src/system.c
index 33aca67f8079..293a2329af6f 100644
--- a/src/iccpd/src/system.c
+++ b/src/iccpd/src/system.c
@@ -22,11 +22,17 @@
*/
#include
+#include
#include "../include/iccp_csm.h"
#include "../include/logger.h"
#include "../include/iccp_netlink.h"
#include "../include/scheduler.h"
+#include "../include/mlacp_link_handler.h"
+#include "../include/iccp_ifm.h"
+
+#define ETHER_ADDR_LEN 6
+char mac_print_str[ETHER_ADDR_STR_LEN];
/* Singleton */
struct System* system_get_instance()
@@ -53,6 +59,7 @@ void system_init(struct System* sys)
if (sys == NULL )
return;
+ memset(sys, 0, sizeof(struct System));
sys->server_fd = -1;
sys->sync_fd = -1;
sys->sync_ctrl_fd = -1;
@@ -65,6 +72,8 @@ void system_init(struct System* sys)
LIST_INIT(&(sys->csm_list));
LIST_INIT(&(sys->lif_list));
LIST_INIT(&(sys->lif_purge_list));
+ LIST_INIT(&(sys->unq_ip_if_list));
+ LIST_INIT(&(sys->pending_vlan_mbr_if_list));
sys->log_file_path = strdup("/var/log/iccpd.log");
sys->cmd_file_path = strdup("/var/run/iccpd/iccpd.vty");
@@ -88,15 +97,21 @@ void system_finalize()
struct System* sys = NULL;
struct CSM* csm = NULL;
struct LocalInterface* local_if = NULL;
+ struct Unq_ip_If_info* unq_ip_if = NULL;
if ((sys = system_get_instance()) == NULL )
return;
- ICCPD_LOG_INFO(__FUNCTION__, "System resource pool is destructing.");
+ ICCPD_LOG_NOTICE(__FUNCTION__,
+ "System resource pool is destructing. Warmboot exit (%d)",
+ sys->warmboot_exit);
while (!LIST_EMPTY(&(sys->csm_list)))
{
csm = LIST_FIRST(&(sys->csm_list));
+ /* Remove ICCP info from STATE_DB if it is not warm reboot */
+ if (sys->warmboot_exit != WARM_REBOOT)
+ mlacp_link_del_iccp_info(csm->mlag_id);
iccp_csm_finalize(csm);
}
@@ -115,6 +130,16 @@ void system_finalize()
local_if_finalize(local_if);
}
+ //remove all pending vlan membership entries
+ del_all_pending_vlan_mbr_ifs(sys);
+
+ while (!LIST_EMPTY(&(sys->unq_ip_if_list)))
+ {
+ unq_ip_if = LIST_FIRST(&(sys->unq_ip_if_list));
+ LIST_REMOVE(unq_ip_if, if_next);
+ free(unq_ip_if);
+ }
+
iccp_system_dinit_netlink_socket();
if (sys->log_file_path != NULL )
@@ -185,6 +210,34 @@ struct CSM* system_get_csm_by_peer_ip(const char* peer_ip)
return NULL;
}
+//function to get CSM by peer interface name
+struct CSM* system_get_csm_by_peer_ifname(char *ifname)
+{
+ struct CSM *csm = NULL;
+ struct System* sys = NULL;
+
+ if (!ifname)
+ {
+ return NULL;
+ }
+
+ if ((sys = system_get_instance()) == NULL)
+ {
+ return NULL;
+ }
+
+ /* traverse all CSM and find matching csm with peer ifname */
+ LIST_FOREACH(csm, &(sys->csm_list), next)
+ {
+ //return matching csm
+ if (strcmp(ifname, csm->peer_itf_name) == 0)
+ {
+ return csm;
+ }
+ }
+ return NULL;
+}
+
struct CSM* system_get_csm_by_mlacp_id(int id)
{
struct System* sys = NULL;
@@ -201,3 +254,146 @@ struct CSM* system_get_csm_by_mlacp_id(int id)
return NULL;
}
+
+struct CSM* system_get_first_csm()
+{
+ struct System* sys = NULL;
+ struct CSM* csm = NULL;
+
+ if ((sys = system_get_instance()) == NULL )
+ return NULL;
+
+ LIST_FOREACH(csm, &(sys->csm_list), next)
+ {
+ return csm;
+ }
+
+ return NULL;
+}
+
+SYNCD_TX_DBG_CNTR_MSG_e system_syncdtx_to_dbg_msg_type(uint32_t msg_type)
+{
+ switch(msg_type)
+ {
+ case MCLAG_MSG_TYPE_PORT_ISOLATE:
+ return SYNCD_TX_DBG_CNTR_MSG_PORT_ISOLATE;
+
+ case MCLAG_MSG_TYPE_PORT_MAC_LEARN_MODE:
+ return SYNCD_TX_DBG_CNTR_MSG_PORT_MAC_LEARN_MODE;
+
+ case MCLAG_MSG_TYPE_FLUSH_FDB:
+ return SYNCD_TX_DBG_CNTR_MSG_FLUSH_FDB;
+
+ case MCLAG_MSG_TYPE_SET_MAC:
+ return SYNCD_TX_DBG_CNTR_MSG_SET_IF_MAC;
+
+ case MCLAG_MSG_TYPE_SET_FDB:
+ return SYNCD_TX_DBG_CNTR_MSG_SET_FDB;
+
+ case MCLAG_MSG_TYPE_SET_TRAFFIC_DIST_ENABLE:
+ return SYNCD_TX_DBG_CNTR_MSG_SET_TRAFFIC_DIST_ENABLE;
+
+ case MCLAG_MSG_TYPE_SET_TRAFFIC_DIST_DISABLE:
+ return SYNCD_TX_DBG_CNTR_MSG_SET_TRAFFIC_DIST_DISABLE;
+
+ case MCLAG_MSG_TYPE_SET_ICCP_STATE:
+ return SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_STATE;
+
+ case MCLAG_MSG_TYPE_SET_ICCP_ROLE:
+ return SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_ROLE;
+
+ case MCLAG_MSG_TYPE_SET_ICCP_SYSTEM_ID:
+ return SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_SYSTEM_ID;
+
+ case MCLAG_MSG_TYPE_SET_REMOTE_IF_STATE:
+ return SYNCD_TX_DBG_CNTR_MSG_SET_REMOTE_IF_STATE;
+
+ case MCLAG_MSG_TYPE_DEL_ICCP_INFO:
+ return SYNCD_TX_DBG_CNTR_MSG_DEL_ICCP_INFO;
+
+ case MCLAG_MSG_TYPE_DEL_REMOTE_IF_INFO:
+ return SYNCD_TX_DBG_CNTR_MSG_DEL_REMOTE_IF_INFO;
+
+ case MCLAG_MSG_TYPE_SET_PEER_LINK_ISOLATION:
+ return SYNCD_TX_DBG_CNTR_MSG_PEER_LINK_ISOLATION;
+
+ case MCLAG_MSG_TYPE_SET_ICCP_PEER_SYSTEM_ID:
+ return SYNCD_TX_DBG_CNTR_MSG_SET_ICCP_PEER_SYSTEM_ID;
+
+ default:
+ return SYNCD_TX_DBG_CNTR_MSG_MAX;
+ }
+}
+
+SYNCD_RX_DBG_CNTR_MSG_e system_syncdrx_to_dbg_msg_type(uint32_t msg_type)
+{
+ switch(msg_type)
+ {
+ case MCLAG_SYNCD_MSG_TYPE_FDB_OPERATION:
+ return SYNCD_RX_DBG_CNTR_MSG_MAC;
+ case MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_DOMAIN:
+ return SYNCD_RX_DBG_CNTR_MSG_CFG_MCLAG_DOMAIN;
+ case MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_IFACE:
+ return SYNCD_RX_DBG_CNTR_MSG_CFG_MCLAG_IFACE;
+ case MCLAG_SYNCD_MSG_TYPE_CFG_MCLAG_UNIQUE_IP:
+ return SYNCD_RX_DBG_CNTR_MSG_CFG_MCLAG_UNIQUE_IP;
+ case MCLAG_SYNCD_MSG_TYPE_VLAN_MBR_UPDATES:
+ return SYNCD_RX_DBG_CNTR_MSG_VLAN_MBR_UPDATES;
+ default:
+ return SYNCD_RX_DBG_CNTR_MSG_MAX;
+ }
+}
+
+char *mac_addr_to_str(uint8_t mac_addr[ETHER_ADDR_LEN])
+{
+ memset(mac_print_str, 0, sizeof(mac_print_str));
+ snprintf(mac_print_str, sizeof(mac_print_str), "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
+
+ return mac_print_str;
+}
+
+void system_update_netlink_counters(
+ uint16_t netlink_msg_type,
+ struct nlmsghdr *nlh)
+{
+ struct System *sys;
+ struct ndmsg *ndm = NLMSG_DATA(nlh);
+
+ sys = system_get_instance();
+ if (!sys)
+ return;
+
+ switch (netlink_msg_type)
+ {
+ case RTM_NEWLINK:
+ ++sys->dbg_counters.newlink_count;
+ break;
+ case RTM_DELLINK:
+ ++sys->dbg_counters.dellink_count;
+ break;
+ case RTM_NEWNEIGH:
+ ++sys->dbg_counters.newnbr_count;
+ if (ndm->ndm_family == AF_BRIDGE)
+ ++sys->dbg_counters.newmac_count;
+ break;
+ case RTM_DELNEIGH:
+ ++sys->dbg_counters.delnbr_count;
+ if (ndm->ndm_family == AF_BRIDGE)
+ ++sys->dbg_counters.delmac_count;
+ break;
+ case RTM_NEWADDR:
+ ++sys->dbg_counters.newaddr_count;
+ break;
+ case RTM_DELADDR:
+ ++sys->dbg_counters.deladdr_count;
+ break;
+ default:
+ ++sys->dbg_counters.unknown_type_count;
+ if (sys->dbg_counters.unknown_type_count < 5)
+ {
+ ICCPD_LOG_NOTICE(__FUNCTION__, "NETLINK_COUNTER: Unknown type %d", netlink_msg_type);
+ }
+ break;
+ }
+}
diff --git a/src/libteam/patch/0012-Increase-min_ports-upper-limit-to-1024.patch b/src/libteam/patch/0012-Increase-min_ports-upper-limit-to-1024.patch
new file mode 100644
index 000000000000..286df05d7739
--- /dev/null
+++ b/src/libteam/patch/0012-Increase-min_ports-upper-limit-to-1024.patch
@@ -0,0 +1,34 @@
+diff --git a/man/teamd.conf.5 b/man/teamd.conf.5
+index 350ffc9..dc913cd 100644
+--- a/man/teamd.conf.5
++++ b/man/teamd.conf.5
+@@ -248,7 +248,7 @@ Default:
+ .RE
+ .TP
+ .BR "runner.min_ports " (int)
+-Specifies the minimum number of ports that must be active before asserting carrier in the master interface, value can be 1 \(en 255.
++Specifies the minimum number of ports that must be active before asserting carrier in the master interface, value can be 1 \(en 1024.
+ .RS 7
+ .PP
+ Default:
+diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c
+index 9354ebb..a901398 100644
+--- a/teamd/teamd_runner_lacp.c
++++ b/teamd/teamd_runner_lacp.c
+@@ -151,6 +151,7 @@ struct lacp {
+ #define LACP_CFG_DFLT_FALLBACK false
+ int min_ports;
+ #define LACP_CFG_DFLT_MIN_PORTS 1
++#define LACP_CFG_DFLT_MIN_PORTS_MAX 1024
+ enum lacp_agg_select_policy agg_select_policy;
+ #define LACP_CFG_DFLT_AGG_SELECT_POLICY LACP_AGG_SELECT_LACP_PRIO
+ } cfg;
+@@ -493,7 +494,7 @@ static int lacp_load_config(struct teamd_context *ctx, struct lacp *lacp)
+ err = teamd_config_int_get(ctx, &tmp, "$.runner.min_ports");
+ if (err) {
+ lacp->cfg.min_ports = LACP_CFG_DFLT_MIN_PORTS;
+- } else if (tmp < 1 || tmp > UCHAR_MAX) {
++ } else if (tmp < 1 || tmp > LACP_CFG_DFLT_MIN_PORTS_MAX) {
+ teamd_log_err("\"min_ports\" value is out of its limits.");
+ return -EINVAL;
+ } else {
diff --git a/src/libteam/patch/series b/src/libteam/patch/series
index 5350d37e4653..cd7522918f43 100644
--- a/src/libteam/patch/series
+++ b/src/libteam/patch/series
@@ -9,3 +9,4 @@
0009-Fix-ifinfo_link_with_port-race-condition-with-newlink.patch
0010-When-read-of-timerfd-returned-0-don-t-consider-this-.patch
0011-Remove-extensive-debug-output.patch
+0012-Increase-min_ports-upper-limit-to-1024.patch
diff --git a/src/snmpd/Makefile b/src/snmpd/Makefile
index af225cfe61b6..50d0303540d6 100644
--- a/src/snmpd/Makefile
+++ b/src/snmpd/Makefile
@@ -29,11 +29,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
stg init
stg import -s ../patch-$(SNMPD_VERSION)/series
-ifeq ($(MULTIARCH_QEMU_ENVIRON), y)
dpkg-buildpackage -rfakeroot -b -d -us -uc -j1 --admindir $(SONIC_DPKG_ADMINDIR)
-else
- dpkg-buildpackage -rfakeroot -b -d -us -uc -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR)
-endif
popd
mv $(DERIVED_TARGETS) $* $(DEST)/
diff --git a/src/sonic-bgpcfgd/bgpcfgd/managers_static_rt.py b/src/sonic-bgpcfgd/bgpcfgd/managers_static_rt.py
index 974843366a90..6fafeda8142d 100644
--- a/src/sonic-bgpcfgd/bgpcfgd/managers_static_rt.py
+++ b/src/sonic-bgpcfgd/bgpcfgd/managers_static_rt.py
@@ -16,12 +16,14 @@ def __init__(self, common_objs, db, table):
"""
super(StaticRouteMgr, self).__init__(
common_objs,
- [("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"),],
+ [],
db,
table,
)
-
+
+ self.directory.subscribe([("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"),], self.on_bgp_asn_change)
self.static_routes = {}
+ self.vrf_pending_redistribution = set()
OP_DELETE = 'DELETE'
OP_ADD = 'ADD'
@@ -47,15 +49,10 @@ def set_handler(self, key, data):
# Enable redistribution of static routes when it is the first one get set
if not self.static_routes.get(vrf, {}):
- log_debug("Enabling static route redistribution")
- bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"]
- if vrf == 'default':
- cmd_list.append("router bgp %s" % bgp_asn)
+ if self.directory.path_exist("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"):
+ cmd_list.extend(self.enable_redistribution_command(vrf))
else:
- cmd_list.append("router bgp %s vrf %s" % (bgp_asn, vrf))
- for af in ["ipv4", "ipv6"]:
- cmd_list.append(" address-family %s" % af)
- cmd_list.append(" redistribute static")
+ self.vrf_pending_redistribution.add(vrf)
if cmd_list:
self.cfg_mgr.push_list(cmd_list)
@@ -78,15 +75,9 @@ def del_handler(self, key):
# Disable redistribution of static routes when it is the last one to delete
if self.static_routes.get(vrf, {}).keys() == {ip_prefix}:
- log_debug("Disabling static route redistribution")
- bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"]
- if vrf == 'default':
- cmd_list.append("router bgp %s" % bgp_asn)
- else:
- cmd_list.append("router bgp %s vrf %s" % (bgp_asn, vrf))
- for af in ["ipv4", "ipv6"]:
- cmd_list.append(" address-family %s" % af)
- cmd_list.append(" no redistribute static")
+ if self.directory.path_exist("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"):
+ cmd_list.extend(self.disable_redistribution_command(vrf))
+ self.vrf_pending_redistribution.discard(vrf)
if cmd_list:
self.cfg_mgr.push_list(cmd_list)
@@ -135,6 +126,38 @@ def generate_command(self, op, ip_nh, ip_prefix, vrf):
' vrf {}'.format(vrf) if vrf != 'default' else ''
)
+ def enable_redistribution_command(self, vrf):
+ log_debug("Enabling static route redistribution")
+ cmd_list = []
+ bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"]
+ if vrf == 'default':
+ cmd_list.append("router bgp %s" % bgp_asn)
+ else:
+ cmd_list.append("router bgp %s vrf %s" % (bgp_asn, vrf))
+ for af in ["ipv4", "ipv6"]:
+ cmd_list.append(" address-family %s" % af)
+ cmd_list.append(" redistribute static")
+ return cmd_list
+
+ def disable_redistribution_command(self, vrf):
+ log_debug("Disabling static route redistribution")
+ cmd_list = []
+ bgp_asn = self.directory.get_slot("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME)["localhost"]["bgp_asn"]
+ if vrf == 'default':
+ cmd_list.append("router bgp %s" % bgp_asn)
+ else:
+ cmd_list.append("router bgp %s vrf %s" % (bgp_asn, vrf))
+ for af in ["ipv4", "ipv6"]:
+ cmd_list.append(" address-family %s" % af)
+ cmd_list.append(" no redistribute static")
+ return cmd_list
+
+ def on_bgp_asn_change(self):
+ if self.directory.path_exist("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost/bgp_asn"):
+ for vrf in self.vrf_pending_redistribution:
+ self.cfg_mgr.push_list(self.enable_redistribution_command(vrf))
+ self.vrf_pending_redistribution.clear()
+
class IpNextHop:
def __init__(self, af_id, blackhole, dst_ip, if_name, dist, vrf):
zero_ip = lambda af: '0.0.0.0' if af == socket.AF_INET else '::'
diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf
index d992d9505c63..b6f7a668bc8c 100644
--- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf
+++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.conf.j2/all.conf
@@ -51,6 +51,7 @@ router bgp 55555
bgp graceful-restart restart-time 480
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 55.55.55.55
!
diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf
index 4a08df08dec7..5d09db596538 100644
--- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf
+++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/all.conf
@@ -30,6 +30,7 @@ router bgp 55555
bgp graceful-restart restart-time 480
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 55.55.55.55
!
diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf
index c1d0234f2ca2..14aa080efb5d 100644
--- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf
+++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/defaults.conf
@@ -30,6 +30,7 @@ router bgp 55555
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 55.55.55.55
!
diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/voq_chassis.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/voq_chassis.conf
new file mode 100644
index 000000000000..b48617a6d840
--- /dev/null
+++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/voq_chassis.conf
@@ -0,0 +1,67 @@
+!
+! template: bgpd/bgpd.main.conf.j2
+!
+! bgp multiple-instance
+!
+! BGP configuration
+!
+! TSA configuration
+!
+ip prefix-list PL_LoopbackV4 permit 55.55.55.55/32
+!
+ipv6 prefix-list PL_LoopbackV6 permit fc00::/64
+!
+ip prefix-list LOCAL_VLAN_IPV4_PREFIX seq 5 permit 10.10.10.0/24
+!
+ipv6 prefix-list LOCAL_VLAN_IPV6_PREFIX seq 10 permit fc01::/64
+!
+route-map HIDE_INTERNAL permit 10
+ set community no-export
+!
+!
+router bgp 55555
+!
+ bgp log-neighbor-changes
+ no bgp default ipv4-unicast
+ no bgp ebgp-requires-policy
+!
+ bgp bestpath as-path multipath-relax
+!
+ bgp graceful-restart restart-time 240
+ bgp graceful-restart
+ bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
+!
+ bgp router-id 55.55.55.56
+!
+ network 55.55.55.55/32
+ network 55.55.55.56/32 route-map HIDE_INTERNAL
+!
+ address-family ipv6
+ network fc00::1/64
+ exit-address-family
+ address-family ipv6
+ network fc00::2/128 route-map HIDE_INTERNAL
+ exit-address-family
+!
+ network 10.10.10.1/24
+ address-family ipv6
+ network fc01::1/64
+ exit-address-family
+!
+ address-family ipv4
+ redistribute connected route-map HIDE_INTERNAL
+ exit-address-family
+ address-family ipv6
+ redistribute connected route-map HIDE_INTERNAL
+ exit-address-family
+!
+ address-family ipv4
+ maximum-paths 64
+ exit-address-family
+ address-family ipv6
+ maximum-paths 64
+ exit-address-family
+!
+! end of template: bgpd/bgpd.main.conf.j2
+!
diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/voq_chassis.json b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/voq_chassis.json
new file mode 100644
index 000000000000..4cbb4c0048c3
--- /dev/null
+++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/bgpd.main.conf.j2/voq_chassis.json
@@ -0,0 +1,35 @@
+{
+ "DEVICE_METADATA": {
+ "localhost": {
+ "bgp_asn": "55555",
+ "sub_role": "",
+ "switch_type": "voq"
+ }
+ },
+ "LOOPBACK_INTERFACE": {
+ "Loopback0|55.55.55.55/32": {},
+ "Loopback0|fc00::1/128": {},
+ "Loopback4096|55.55.55.56/32": {},
+ "Loopback4096|fc00::2/128": {}
+ },
+ "VLAN_INTERFACE": {
+ "Vlan10|10.10.10.1/24": {},
+ "Vlan10|fc01::1/64": {},
+ "Vlan20": {"vnet_name": "Vnet1"},
+ "Vlan20|20.20.20.1/24": {},
+ "Vlan20|fd01::1/64": {}
+ },
+ "constants": {
+ "bgp": {
+ "multipath_relax": {
+ "enabled": true
+ },
+ "graceful_restart": {
+ "enabled": true
+ },
+ "maximum_paths": {
+ "enabled": true
+ }
+ }
+ }
+}
diff --git a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf
index 494f54b6bc22..bf01c12f2757 100644
--- a/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf
+++ b/src/sonic-bgpcfgd/tests/data/sonic-cfggen/frr.conf.j2/all.conf
@@ -70,6 +70,7 @@ router bgp 55555
bgp graceful-restart restart-time 480
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 55.55.55.55
!
diff --git a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py
index a9c93749d5c4..ff9b30ea3906 100644
--- a/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py
+++ b/src/sonic-bgpcfgd/tests/test_sonic-cfggen.py
@@ -45,6 +45,12 @@ def test_bgpd_main_conf_defaults():
"bgpd.main.conf.j2/defaults.json",
"bgpd.main.conf.j2/defaults.conf")
+def test_bgpd_main_conf_voq_chassis():
+ run_test("VOQ bgpd.main.conf.j2",
+ "bgpd/bgpd.main.conf.j2",
+ "bgpd.main.conf.j2/voq_chassis.json",
+ "bgpd.main.conf.j2/voq_chassis.conf")
+
def test_tsa_isolate():
run_test("tsa/bgpd.tsa.isolate.conf.j2",
"bgpd/tsa/bgpd.tsa.isolate.conf.j2",
diff --git a/src/sonic-bgpcfgd/tests/test_static_rt.py b/src/sonic-bgpcfgd/tests/test_static_rt.py
index 0fa2e3df6c2f..e0b9b1b17ebf 100644
--- a/src/sonic-bgpcfgd/tests/test_static_rt.py
+++ b/src/sonic-bgpcfgd/tests/test_static_rt.py
@@ -6,7 +6,7 @@
from collections import Counter
from swsscommon import swsscommon
-def constructor():
+def constructor(skip_bgp_asn=False):
cfg_mgr = MagicMock()
common_objs = {
@@ -17,7 +17,8 @@ def constructor():
}
mgr = StaticRouteMgr(common_objs, "CONFIG_DB", "STATIC_ROUTE")
- mgr.directory.put("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost", {"bgp_asn": "65100"})
+ if not skip_bgp_asn:
+ mgr.directory.put("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost", {"bgp_asn": "65100"})
assert len(mgr.static_routes) == 0
return mgr
@@ -573,3 +574,80 @@ def test_set_invalid_ipaddr():
False,
[]
)
+
+def test_set_del_no_bgp_asn():
+ mgr = constructor(skip_bgp_asn=True)
+ set_del_test(
+ mgr,
+ "SET",
+ ("vrfRED|10.1.3.0/24", {
+ "nexthop": "10.0.0.57,10.0.0.59,10.0.0.61",
+ "ifname": "PortChannel0001,PortChannel0002,PortChannel0003",
+ "distance": "10,20,30",
+ "nexthop-vrf": "nh_vrf,,default",
+ "blackhole": "false,false,false",
+ }),
+ True,
+ [
+ "ip route 10.1.3.0/24 10.0.0.57 PortChannel0001 10 nexthop-vrf nh_vrf vrf vrfRED",
+ "ip route 10.1.3.0/24 10.0.0.59 PortChannel0002 20 vrf vrfRED",
+ "ip route 10.1.3.0/24 10.0.0.61 PortChannel0003 30 nexthop-vrf default vrf vrfRED",
+ ]
+ )
+ set_del_test(
+ mgr,
+ "DEL",
+ ("vrfRED|10.1.3.0/24",),
+ True,
+ [
+ "no ip route 10.1.3.0/24 10.0.0.57 PortChannel0001 10 nexthop-vrf nh_vrf vrf vrfRED",
+ "no ip route 10.1.3.0/24 10.0.0.59 PortChannel0002 20 vrf vrfRED",
+ "no ip route 10.1.3.0/24 10.0.0.61 PortChannel0003 30 nexthop-vrf default vrf vrfRED",
+ ]
+ )
+
+def test_set_del_bgp_asn_change():
+ mgr = constructor(skip_bgp_asn=True)
+ set_del_test(
+ mgr,
+ "SET",
+ ("vrfRED|10.1.3.0/24", {
+ "nexthop": "10.0.0.57,10.0.0.59,10.0.0.61",
+ "ifname": "PortChannel0001,PortChannel0002,PortChannel0003",
+ "distance": "10,20,30",
+ "nexthop-vrf": "nh_vrf,,default",
+ "blackhole": "false,false,false",
+ }),
+ True,
+ [
+ "ip route 10.1.3.0/24 10.0.0.57 PortChannel0001 10 nexthop-vrf nh_vrf vrf vrfRED",
+ "ip route 10.1.3.0/24 10.0.0.59 PortChannel0002 20 vrf vrfRED",
+ "ip route 10.1.3.0/24 10.0.0.61 PortChannel0003 30 nexthop-vrf default vrf vrfRED",
+ ]
+ )
+
+ assert mgr.vrf_pending_redistribution == {"vrfRED"}
+
+ expected_cmds = [
+ "router bgp 65100 vrf vrfRED",
+ " address-family ipv4",
+ " redistribute static",
+ " address-family ipv6",
+ " redistribute static"
+ ]
+ def push_list(cmds):
+ set_del_test.push_list_called = True
+ assert Counter(cmds) == Counter(expected_cmds) # check if commands are expected (regardless of the order)
+ max_del_idx = -1
+ min_set_idx = len(cmds)
+ for idx in range(len(cmds)):
+ if cmds[idx].startswith('no ip') and idx > max_del_idx:
+ max_del_idx = idx
+ if cmds[idx].startswith('ip') and idx < min_set_idx:
+ min_set_idx = idx
+ assert max_del_idx < min_set_idx, "DEL command comes after SET command" # DEL commands should be done first
+ return True
+ mgr.cfg_mgr.push_list = push_list
+ mgr.directory.put("CONFIG_DB", swsscommon.CFG_DEVICE_METADATA_TABLE_NAME, "localhost", {"bgp_asn": "65100"})
+
+ assert not mgr.vrf_pending_redistribution
diff --git a/src/sonic-config-engine/config_samples.py b/src/sonic-config-engine/config_samples.py
index 5a58ca560221..f8dc4b1c13b3 100644
--- a/src/sonic-config-engine/config_samples.py
+++ b/src/sonic-config-engine/config_samples.py
@@ -10,6 +10,31 @@
else:
UNICODE_TYPE = unicode
+# The following config generation methods exits:
+# 't1': generate_t1_sample_config,
+# 'l2': generate_l2_config,
+# 'empty': generate_empty_config,
+# 'l1': generate_l1_config,
+# 'l3': generate_l3_config
+
+def generate_l1_config(data):
+ for port in natsorted(data['PORT']):
+ data['PORT'][port]['admin_status'] = 'up'
+ data['PORT'][port]['mtu'] = '9100'
+ return data;
+
+def generate_l3_config(data):
+ data['LOOPBACK_INTERFACE'] = {"Loopback0": {},
+ "Loopback0|10.1.0.1/32": {}}
+ data['BGP_NEIGHBOR'] = {}
+ data['DEVICE_NEIGHBOR'] = {}
+ data['INTERFACE'] = {}
+ for port in natsorted(data['PORT']):
+ data['PORT'][port]['admin_status'] = 'up'
+ data['PORT'][port]['mtu'] = '9100'
+ data['INTERFACE']['{}'.format(port)] = {}
+ return data;
+
def generate_t1_sample_config(data):
data['DEVICE_METADATA']['localhost']['hostname'] = 'sonic'
data['DEVICE_METADATA']['localhost']['type'] = 'LeafRouter'
@@ -126,7 +151,9 @@ def generate_l2_config(data):
_sample_generators = {
't1': generate_t1_sample_config,
'l2': generate_l2_config,
- 'empty': generate_empty_config
+ 'empty': generate_empty_config,
+ 'l1': generate_l1_config,
+ 'l3': generate_l3_config
}
def get_available_config():
diff --git a/src/sonic-config-engine/data/l1intf.j2 b/src/sonic-config-engine/data/l1intf.j2
new file mode 100644
index 000000000000..06222632e0da
--- /dev/null
+++ b/src/sonic-config-engine/data/l1intf.j2
@@ -0,0 +1,26 @@
+{
+ "DEVICE_METADATA": {
+ "localhost" : {
+ "hwsku" : "{{ DEVICE_METADATA.localhost.hwsku }}"
+ }
+ },
+ {% set ns = {'firstPrinted': False} -%}
+ "PORT": {
+ {%- for key, value in PORT.items() -%}
+ {%- if ns.firstPrinted %},{% endif %}
+
+ "{{ key }}": {
+ {%- for keyPort, valuePort in value.items() %}
+
+ {% if keyPort != "admin_status" %}"{{ keyPort }}": "{{ valuePort }}",{% endif %}
+ {%- endfor %}
+
+ "admin_status": "{{ value.admin_status|default("up") }}",
+ "mtu": "9100"
+ }
+ {%- if ns.update({'firstPrinted': True}) %}{% endif -%}
+ {%- endfor %}
+
+ }
+}
+
diff --git a/src/sonic-config-engine/data/l3intf.j2 b/src/sonic-config-engine/data/l3intf.j2
new file mode 100644
index 000000000000..255868eb8257
--- /dev/null
+++ b/src/sonic-config-engine/data/l3intf.j2
@@ -0,0 +1,65 @@
+{
+ "DEVICE_METADATA": {
+ "localhost" : {
+ "hwsku" : "{{ DEVICE_METADATA.localhost.hwsku }}"
+ }
+ },
+ {% set ns = {'firstPrinted': False} -%}
+ "PORT": {
+ {%- for key, value in PORT.items() -%}
+ {%- if ns.firstPrinted %},{% endif %}
+
+ "{{ key }}": {
+ {%- for keyPort, valuePort in value.items() %}
+
+ {% if keyPort != "admin_status" %}"{{ keyPort }}": "{{ valuePort }}",{% endif %}
+ {%- endfor %}
+
+ "admin_status": "{{ value.admin_status|default("up") }}",
+ "mtu": "9100"
+ }
+ {%- if ns.update({'firstPrinted': True}) %}{% endif -%}
+ {%- endfor %}
+
+ },
+ "LOOPBACK_INTERFACE": {
+ "Loopback0": {},
+ "Loopback0|10.1.0.1/32": {}
+ },
+ "BGP_NEIGHBOR": {},
+ "DEVICE_NEIGHBOR": {},
+ "INTERFACE": {
+ "Ethernet0": {},
+ "Ethernet1": {},
+ "Ethernet2": {},
+ "Ethernet3": {},
+ "Ethernet4": {},
+ "Ethernet5": {},
+ "Ethernet6": {},
+ "Ethernet7": {},
+ "Ethernet8": {},
+ "Ethernet9": {},
+ "Ethernet10": {},
+ "Ethernet11": {},
+ "Ethernet12": {},
+ "Ethernet13": {},
+ "Ethernet14": {},
+ "Ethernet15": {},
+ "Ethernet16": {},
+ "Ethernet17": {},
+ "Ethernet18": {},
+ "Ethernet19": {},
+ "Ethernet20": {},
+ "Ethernet21": {},
+ "Ethernet22": {},
+ "Ethernet23": {},
+ "Ethernet24": {},
+ "Ethernet25": {},
+ "Ethernet26": {},
+ "Ethernet27": {},
+ "Ethernet28": {},
+ "Ethernet29": {},
+ "Ethernet30": {},
+ "Ethernet31": {}
+ }
+}
diff --git a/src/sonic-config-engine/lazy_re.py b/src/sonic-config-engine/lazy_re.py
deleted file mode 100644
index b51c385c1cc6..000000000000
--- a/src/sonic-config-engine/lazy_re.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# monkey patch re.compile to improve import time of some packages
-
-import re
-
-_orig_re_compile = re.compile
-
-
-def __re_compile(*args, **kwargs):
- class __LazyReCompile(object):
- def __init__(self, *args, **kwargs):
- self.args = args
- self.kwargs = kwargs
- self.pattern_obj = None
-
- def __getattr__(self, name):
- if self.pattern_obj is None:
- self.pattern_obj = _orig_re_compile(*self.args, **self.kwargs)
- return getattr(self.pattern_obj, name)
- return __LazyReCompile(*args, **kwargs)
-
-re.compile = __re_compile
-
diff --git a/src/sonic-config-engine/minigraph.py b/src/sonic-config-engine/minigraph.py
index a982f861edca..0c2040d95f0e 100644
--- a/src/sonic-config-engine/minigraph.py
+++ b/src/sonic-config-engine/minigraph.py
@@ -562,6 +562,12 @@ def parse_dpg(dpg, hname):
vdhcpserver_list = vintfdhcpservers.split(';')
vlan_attributes['dhcp_servers'] = vdhcpserver_list
+ vintf_node = vintf.find(str(QName(ns, "Dhcpv6Relays")))
+ if vintf_node is not None and vintf_node.text is not None:
+ vintfdhcpservers = vintf_node.text
+ vdhcpserver_list = vintfdhcpservers.split(';')
+ vlan_attributes['dhcpv6_servers'] = vdhcpserver_list
+
vlanmac = vintf.find(str(QName(ns, "MacAddress")))
if vlanmac is not None and vlanmac.text is not None:
vlan_attributes['mac'] = vlanmac.text
@@ -803,6 +809,7 @@ def filter_bad_asn(table):
def parse_meta(meta, hname):
syslog_servers = []
dhcp_servers = []
+ dhcpv6_servers = []
ntp_servers = []
tacacs_servers = []
mgmt_routes = []
@@ -856,7 +863,7 @@ def parse_meta(meta, hname):
kube_data["enable"] = value
elif name == "KubernetesServerIp":
kube_data["ip"] = value
- return syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, switch_id, switch_type, max_cores, kube_data
+ return syslog_servers, dhcp_servers, dhcpv6_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, switch_id, switch_type, max_cores, kube_data
def parse_linkmeta(meta, hname):
@@ -1170,6 +1177,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
mux_cable_ports = {}
syslog_servers = []
dhcp_servers = []
+ dhcpv6_servers = []
ntp_servers = []
tacacs_servers = []
mgmt_routes = []
@@ -1217,7 +1225,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
elif child.tag == str(QName(ns, "UngDec")):
(u_neighbors, u_devices, _, _, _, _, _, _) = parse_png(child, hostname, None)
elif child.tag == str(QName(ns, "MetadataDeclaration")):
- (syslog_servers, dhcp_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, switch_id, switch_type, max_cores, kube_data) = parse_meta(child, hostname)
+ (syslog_servers, dhcp_servers, dhcpv6_servers, ntp_servers, tacacs_servers, mgmt_routes, erspan_dst, deployment_id, region, cloudtype, resource_type, downstream_subrole, switch_id, switch_type, max_cores, kube_data) = parse_meta(child, hostname)
elif child.tag == str(QName(ns, "LinkMetadataDeclaration")):
linkmetas = parse_linkmeta(child, hostname)
elif child.tag == str(QName(ns, "DeviceInfos")):
@@ -1480,6 +1488,11 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
# make all neighbors connected ports to 'admin_up'
ports[port]['admin_status'] = 'up'
+ # bring up the inband voq interfaces
+ for inband_port in voq_inband_intfs:
+ if inband_port in ports.keys():
+ ports[inband_port]['admin_status'] = 'up'
+
results['PORT'] = ports
results['CONSOLE_PORT'] = console_ports
@@ -1567,6 +1580,7 @@ def parse_xml(filename, platform=None, port_config_file=None, asic_name=None, hw
results['DEVICE_NEIGHBOR_METADATA'] = { key:devices[key] for key in devices if key in {device['name'] for device in neighbors.values()} }
results['SYSLOG_SERVER'] = dict((item, {}) for item in syslog_servers)
results['DHCP_SERVER'] = dict((item, {}) for item in dhcp_servers)
+ results['DHCPv6_SERVER'] = dict((item, {}) for item in dhcpv6_servers)
results['NTP_SERVER'] = dict((item, {}) for item in ntp_servers)
results['TACPLUS_SERVER'] = dict((item, {'priority': '1', 'tcp_port': '49'}) for item in tacacs_servers)
results['ACL_TABLE'] = filter_acl_table_bindings(acls, neighbors, pcs, sub_role)
diff --git a/src/sonic-config-engine/setup.py b/src/sonic-config-engine/setup.py
index 236d39e7117c..d19fcb1e5b6f 100644
--- a/src/sonic-config-engine/setup.py
+++ b/src/sonic-config-engine/setup.py
@@ -40,7 +40,6 @@
# Common modules for python2 and python3
py_modules = [
'config_samples',
- 'lazy_re',
'minigraph',
'openconfig_acl',
'portconfig',
diff --git a/src/sonic-config-engine/sonic-cfggen b/src/sonic-config-engine/sonic-cfggen
index dad68118902d..bd528c64e75e 100755
--- a/src/sonic-config-engine/sonic-cfggen
+++ b/src/sonic-config-engine/sonic-cfggen
@@ -17,15 +17,6 @@ See usage string for detail description for arguments.
from __future__ import print_function
-# monkey patch re.compile to do lazy regular expression compilation.
-# This is done to improve import time of jinja2, yaml, natsort modules, because they
-# do many regexp compilation at import time, so it will speed up sonic-cfggen invocations
-# that do not require template generation or yaml loading. sonic-cfggen is used in so many places
-# during system boot up that importing jinja2, yaml, natsort every time
-# without lazy regular expression compilation affect boot up time.
-# FIXME: remove this once sonic-cfggen and templates dependencies are replaced with a faster approach
-import lazy_re
-
import argparse
import contextlib
import jinja2
diff --git a/src/sonic-config-engine/tests/l1-l3-sample-port-config.ini b/src/sonic-config-engine/tests/l1-l3-sample-port-config.ini
new file mode 100644
index 000000000000..f6a3ea049b85
--- /dev/null
+++ b/src/sonic-config-engine/tests/l1-l3-sample-port-config.ini
@@ -0,0 +1,33 @@
+# name lanes alias index speed
+Ethernet0 1296,1297,1298,1299 Ethernet0 0 100000
+Ethernet1 1300,1301,1302,1303 Ethernet1 1 100000
+Ethernet2 1288,1289,1290,1291 Ethernet2 2 100000
+Ethernet3 1292,1293,1294,1295 Ethernet3 3 100000
+Ethernet4 1280,1281,1282,1283 Ethernet4 4 100000
+Ethernet5 1284,1285,1286,1287 Ethernet5 5 100000
+Ethernet6 1032,1033,1034,1035 Ethernet6 6 100000
+Ethernet7 1036,1037,1038,1039 Ethernet7 7 100000
+Ethernet8 1024,1025,1026,1027 Ethernet8 8 100000
+Ethernet9 1028,1029,1030,1031 Ethernet9 9 100000
+Ethernet10 772,773,774,775 Ethernet10 10 100000
+Ethernet11 768,769,770,771 Ethernet11 11 100000
+Ethernet12 780,781,782,783 Ethernet12 12 100000
+Ethernet13 776,777,778,779 Ethernet13 13 100000
+Ethernet14 528,529,530,531 Ethernet14 14 100000
+Ethernet15 532,533,534,535 Ethernet15 15 100000
+Ethernet16 520,521,522,523 Ethernet16 16 100000
+Ethernet17 524,525,526,527 Ethernet17 17 100000
+Ethernet18 512,513,514,515 Ethernet18 18 100000
+Ethernet19 516,517,518,519 Ethernet19 19 100000
+Ethernet20 272,273,274,275 Ethernet20 20 100000
+Ethernet21 276,277,278,279 Ethernet21 21 100000
+Ethernet22 264,265,266,267 Ethernet22 22 100000
+Ethernet23 268,269,270,271 Ethernet23 23 100000
+Ethernet24 256,257,258,259 Ethernet24 24 100000
+Ethernet25 260,261,262,263 Ethernet25 25 100000
+Ethernet26 16,17,18,19 Ethernet26 26 100000
+Ethernet27 20,21,22,23 Ethernet27 27 100000
+Ethernet28 8,9,10,11 Ethernet28 28 100000
+Ethernet29 12,13,14,15 Ethernet29 29 100000
+Ethernet30 0,1,2,3 Ethernet30 30 100000
+Ethernet31 4,5,6,7 Ethernet31 31 100000
diff --git a/src/sonic-config-engine/tests/sample-voq-graph.xml b/src/sonic-config-engine/tests/sample-voq-graph.xml
index 648f0b2b17a7..c6fc1b2f5d17 100644
--- a/src/sonic-config-engine/tests/sample-voq-graph.xml
+++ b/src/sonic-config-engine/tests/sample-voq-graph.xml
@@ -48,6 +48,11 @@
Vlan
1.1.1.1/24
+
+ Ethernet-IB0
+ port
+ 2.2.2.2/32
+
diff --git a/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf
index 4245076ad96f..2c146698a960 100644
--- a/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf
+++ b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr.conf
@@ -50,6 +50,7 @@ router bgp 65100
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 10.1.0.32
!
diff --git a/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr_backend_asic.conf b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr_backend_asic.conf
index 48ac8b54d013..a4ad1c677a77 100644
--- a/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr_backend_asic.conf
+++ b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr_backend_asic.conf
@@ -49,6 +49,7 @@ router bgp 65100
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 8.0.0.5
!
diff --git a/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr_frontend_asic.conf b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr_frontend_asic.conf
index 3806681a0225..b49d3ddd4dcd 100644
--- a/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr_frontend_asic.conf
+++ b/src/sonic-config-engine/tests/sample_output/py2/bgpd_frr_frontend_asic.conf
@@ -49,6 +49,7 @@ router bgp 65100
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 10.1.0.32
!
diff --git a/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf
index 3a1269c43533..35dfe5ea4b5d 100644
--- a/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf
+++ b/src/sonic-config-engine/tests/sample_output/py2/docker-dhcp-relay.supervisord.conf
@@ -40,9 +40,9 @@ dependent_startup=true
dependent_startup_wait_for=rsyslogd:running
[group:isc-dhcp-relay]
-programs=isc-dhcp-relay-Vlan1000
+programs=isc-dhcpv4-relay-Vlan1000,isc-dhcpv6-relay-Vlan1000
-[program:isc-dhcp-relay-Vlan1000]
+[program:isc-dhcpv4-relay-Vlan1000]
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu Vlan2000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 192.0.0.1 192.0.0.2
priority=3
autostart=false
@@ -52,19 +52,28 @@ stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=start:exited
+[program:isc-dhcpv6-relay-Vlan1000]
+command=/usr/sbin/dhcrelay -d -6 --name-alias-map-file /tmp/port-name-alias-map.txt -l Vlan1000 -u fc02:2000::1%%PortChannel04 -u fc02:2000::1%%PortChannel03 -u fc02:2000::1%%PortChannel01 -u fc02:2000::1%%PortChannel02 -u fc02:2000::2%%PortChannel04 -u fc02:2000::2%%PortChannel03 -u fc02:2000::2%%PortChannel01 -u fc02:2000::2%%PortChannel02
+priority=3
+autostart=false
+autorestart=false
+stdout_logfile=syslog
+stderr_logfile=syslog
+dependent_startup=true
+dependent_startup_wait_for=start:exited
+
[group:dhcpmon]
programs=dhcpmon-Vlan1000
[program:dhcpmon-Vlan1000]
-command=/usr/sbin/dhcpmon -id Vlan1000 -iu Vlan2000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 -im eth0
+command=/usr/sbin/dhcpmon -id Vlan1000 -iu Vlan2000 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -iu PortChannel01 -im eth0 -4 -6
priority=4
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
-dependent_startup_wait_for=isc-dhcp-relay-Vlan1000:running
-
+dependent_startup_wait_for=isc-dhcpv4-relay-Vlan1000:running isc-dhcpv6-relay-Vlan1000:running
diff --git a/src/sonic-config-engine/tests/sample_output/py2/frr.conf b/src/sonic-config-engine/tests/sample_output/py2/frr.conf
index 0b0c22db6809..707551c6942e 100644
--- a/src/sonic-config-engine/tests/sample_output/py2/frr.conf
+++ b/src/sonic-config-engine/tests/sample_output/py2/frr.conf
@@ -73,6 +73,7 @@ router bgp 65100
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 10.1.0.32
!
diff --git a/src/sonic-config-engine/tests/sample_output/py2/l1_intfs.json b/src/sonic-config-engine/tests/sample_output/py2/l1_intfs.json
new file mode 100644
index 000000000000..bc2d533e87a1
--- /dev/null
+++ b/src/sonic-config-engine/tests/sample_output/py2/l1_intfs.json
@@ -0,0 +1,261 @@
+{
+ "DEVICE_METADATA": {"localhost": {"hwsku": "32x1000Gb"}},
+ "PORT": {
+ "Ethernet0": {
+ "admin_status": "up",
+ "alias": "Ethernet0",
+ "index": "0",
+ "lanes": "1296,1297,1298,1299",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet1": {
+ "admin_status": "up",
+ "alias": "Ethernet1",
+ "index": "1",
+ "lanes": "1300,1301,1302,1303",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet10": {
+ "admin_status": "up",
+ "alias": "Ethernet10",
+ "index": "10",
+ "lanes": "772,773,774,775",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet11": {
+ "admin_status": "up",
+ "alias": "Ethernet11",
+ "index": "11",
+ "lanes": "768,769,770,771",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet12": {
+ "admin_status": "up",
+ "alias": "Ethernet12",
+ "index": "12",
+ "lanes": "780,781,782,783",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet13": {
+ "admin_status": "up",
+ "alias": "Ethernet13",
+ "index": "13",
+ "lanes": "776,777,778,779",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet14": {
+ "admin_status": "up",
+ "alias": "Ethernet14",
+ "index": "14",
+ "lanes": "528,529,530,531",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet15": {
+ "admin_status": "up",
+ "alias": "Ethernet15",
+ "index": "15",
+ "lanes": "532,533,534,535",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet16": {
+ "admin_status": "up",
+ "alias": "Ethernet16",
+ "index": "16",
+ "lanes": "520,521,522,523",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet17": {
+ "admin_status": "up",
+ "alias": "Ethernet17",
+ "index": "17",
+ "lanes": "524,525,526,527",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet18": {
+ "admin_status": "up",
+ "alias": "Ethernet18",
+ "index": "18",
+ "lanes": "512,513,514,515",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet19": {
+ "admin_status": "up",
+ "alias": "Ethernet19",
+ "index": "19",
+ "lanes": "516,517,518,519",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet2": {
+ "admin_status": "up",
+ "alias": "Ethernet2",
+ "index": "2",
+ "lanes": "1288,1289,1290,1291",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet20": {
+ "admin_status": "up",
+ "alias": "Ethernet20",
+ "index": "20",
+ "lanes": "272,273,274,275",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet21": {
+ "admin_status": "up",
+ "alias": "Ethernet21",
+ "index": "21",
+ "lanes": "276,277,278,279",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet22": {
+ "admin_status": "up",
+ "alias": "Ethernet22",
+ "index": "22",
+ "lanes": "264,265,266,267",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet23": {
+ "admin_status": "up",
+ "alias": "Ethernet23",
+ "index": "23",
+ "lanes": "268,269,270,271",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet24": {
+ "admin_status": "up",
+ "alias": "Ethernet24",
+ "index": "24",
+ "lanes": "256,257,258,259",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet25": {
+ "admin_status": "up",
+ "alias": "Ethernet25",
+ "index": "25",
+ "lanes": "260,261,262,263",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet26": {
+ "admin_status": "up",
+ "alias": "Ethernet26",
+ "index": "26",
+ "lanes": "16,17,18,19",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet27": {
+ "admin_status": "up",
+ "alias": "Ethernet27",
+ "index": "27",
+ "lanes": "20,21,22,23",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet28": {
+ "admin_status": "up",
+ "alias": "Ethernet28",
+ "index": "28",
+ "lanes": "8,9,10,11",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet29": {
+ "admin_status": "up",
+ "alias": "Ethernet29",
+ "index": "29",
+ "lanes": "12,13,14,15",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet3": {
+ "admin_status": "up",
+ "alias": "Ethernet3",
+ "index": "3",
+ "lanes": "1292,1293,1294,1295",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet30": {
+ "admin_status": "up",
+ "alias": "Ethernet30",
+ "index": "30",
+ "lanes": "0,1,2,3",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet31": {
+ "admin_status": "up",
+ "alias": "Ethernet31",
+ "index": "31",
+ "lanes": "4,5,6,7",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet4": {
+ "admin_status": "up",
+ "alias": "Ethernet4",
+ "index": "4",
+ "lanes": "1280,1281,1282,1283",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet5": {
+ "admin_status": "up",
+ "alias": "Ethernet5",
+ "index": "5",
+ "lanes": "1284,1285,1286,1287",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet6": {
+ "admin_status": "up",
+ "alias": "Ethernet6",
+ "index": "6",
+ "lanes": "1032,1033,1034,1035",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet7": {
+ "admin_status": "up",
+ "alias": "Ethernet7",
+ "index": "7",
+ "lanes": "1036,1037,1038,1039",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet8": {
+ "admin_status": "up",
+ "alias": "Ethernet8",
+ "index": "8",
+ "lanes": "1024,1025,1026,1027",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet9": {
+ "admin_status": "up",
+ "alias": "Ethernet9",
+ "index": "9",
+ "lanes": "1028,1029,1030,1031",
+ "mtu": "9100",
+ "speed": "100000"
+ }
+ }
+}
diff --git a/src/sonic-config-engine/tests/sample_output/py2/l3_intfs.json b/src/sonic-config-engine/tests/sample_output/py2/l3_intfs.json
new file mode 100644
index 000000000000..9ca31832303f
--- /dev/null
+++ b/src/sonic-config-engine/tests/sample_output/py2/l3_intfs.json
@@ -0,0 +1,301 @@
+{
+ "DEVICE_METADATA": {"localhost": {"hwsku": "32x1000Gb"}},
+ "PORT": {
+ "Ethernet0": {
+ "admin_status": "up",
+ "alias": "Ethernet0",
+ "index": "0",
+ "lanes": "1296,1297,1298,1299",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet1": {
+ "admin_status": "up",
+ "alias": "Ethernet1",
+ "index": "1",
+ "lanes": "1300,1301,1302,1303",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet10": {
+ "admin_status": "up",
+ "alias": "Ethernet10",
+ "index": "10",
+ "lanes": "772,773,774,775",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet11": {
+ "admin_status": "up",
+ "alias": "Ethernet11",
+ "index": "11",
+ "lanes": "768,769,770,771",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet12": {
+ "admin_status": "up",
+ "alias": "Ethernet12",
+ "index": "12",
+ "lanes": "780,781,782,783",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet13": {
+ "admin_status": "up",
+ "alias": "Ethernet13",
+ "index": "13",
+ "lanes": "776,777,778,779",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet14": {
+ "admin_status": "up",
+ "alias": "Ethernet14",
+ "index": "14",
+ "lanes": "528,529,530,531",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet15": {
+ "admin_status": "up",
+ "alias": "Ethernet15",
+ "index": "15",
+ "lanes": "532,533,534,535",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet16": {
+ "admin_status": "up",
+ "alias": "Ethernet16",
+ "index": "16",
+ "lanes": "520,521,522,523",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet17": {
+ "admin_status": "up",
+ "alias": "Ethernet17",
+ "index": "17",
+ "lanes": "524,525,526,527",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet18": {
+ "admin_status": "up",
+ "alias": "Ethernet18",
+ "index": "18",
+ "lanes": "512,513,514,515",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet19": {
+ "admin_status": "up",
+ "alias": "Ethernet19",
+ "index": "19",
+ "lanes": "516,517,518,519",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet2": {
+ "admin_status": "up",
+ "alias": "Ethernet2",
+ "index": "2",
+ "lanes": "1288,1289,1290,1291",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet20": {
+ "admin_status": "up",
+ "alias": "Ethernet20",
+ "index": "20",
+ "lanes": "272,273,274,275",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet21": {
+ "admin_status": "up",
+ "alias": "Ethernet21",
+ "index": "21",
+ "lanes": "276,277,278,279",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet22": {
+ "admin_status": "up",
+ "alias": "Ethernet22",
+ "index": "22",
+ "lanes": "264,265,266,267",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet23": {
+ "admin_status": "up",
+ "alias": "Ethernet23",
+ "index": "23",
+ "lanes": "268,269,270,271",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet24": {
+ "admin_status": "up",
+ "alias": "Ethernet24",
+ "index": "24",
+ "lanes": "256,257,258,259",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet25": {
+ "admin_status": "up",
+ "alias": "Ethernet25",
+ "index": "25",
+ "lanes": "260,261,262,263",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet26": {
+ "admin_status": "up",
+ "alias": "Ethernet26",
+ "index": "26",
+ "lanes": "16,17,18,19",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet27": {
+ "admin_status": "up",
+ "alias": "Ethernet27",
+ "index": "27",
+ "lanes": "20,21,22,23",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet28": {
+ "admin_status": "up",
+ "alias": "Ethernet28",
+ "index": "28",
+ "lanes": "8,9,10,11",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet29": {
+ "admin_status": "up",
+ "alias": "Ethernet29",
+ "index": "29",
+ "lanes": "12,13,14,15",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet3": {
+ "admin_status": "up",
+ "alias": "Ethernet3",
+ "index": "3",
+ "lanes": "1292,1293,1294,1295",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet30": {
+ "admin_status": "up",
+ "alias": "Ethernet30",
+ "index": "30",
+ "lanes": "0,1,2,3",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet31": {
+ "admin_status": "up",
+ "alias": "Ethernet31",
+ "index": "31",
+ "lanes": "4,5,6,7",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet4": {
+ "admin_status": "up",
+ "alias": "Ethernet4",
+ "index": "4",
+ "lanes": "1280,1281,1282,1283",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet5": {
+ "admin_status": "up",
+ "alias": "Ethernet5",
+ "index": "5",
+ "lanes": "1284,1285,1286,1287",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet6": {
+ "admin_status": "up",
+ "alias": "Ethernet6",
+ "index": "6",
+ "lanes": "1032,1033,1034,1035",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet7": {
+ "admin_status": "up",
+ "alias": "Ethernet7",
+ "index": "7",
+ "lanes": "1036,1037,1038,1039",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet8": {
+ "admin_status": "up",
+ "alias": "Ethernet8",
+ "index": "8",
+ "lanes": "1024,1025,1026,1027",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet9": {
+ "admin_status": "up",
+ "alias": "Ethernet9",
+ "index": "9",
+ "lanes": "1028,1029,1030,1031",
+ "mtu": "9100",
+ "speed": "100000"
+ }
+ },
+ "LOOPBACK_INTERFACE": {
+ "Loopback0": {},
+ "Loopback0|10.1.0.1/32": {}
+ },
+ "BGP_NEIGHBOR": {},
+ "DEVICE_NEIGHBOR": {},
+ "INTERFACE": {
+ "Ethernet0": {},
+ "Ethernet1": {},
+ "Ethernet2": {},
+ "Ethernet3": {},
+ "Ethernet4": {},
+ "Ethernet5": {},
+ "Ethernet6": {},
+ "Ethernet7": {},
+ "Ethernet8": {},
+ "Ethernet9": {},
+ "Ethernet10": {},
+ "Ethernet11": {},
+ "Ethernet12": {},
+ "Ethernet13": {},
+ "Ethernet14": {},
+ "Ethernet15": {},
+ "Ethernet16": {},
+ "Ethernet17": {},
+ "Ethernet18": {},
+ "Ethernet19": {},
+ "Ethernet20": {},
+ "Ethernet21": {},
+ "Ethernet22": {},
+ "Ethernet23": {},
+ "Ethernet24": {},
+ "Ethernet25": {},
+ "Ethernet26": {},
+ "Ethernet27": {},
+ "Ethernet28": {},
+ "Ethernet29": {},
+ "Ethernet30": {},
+ "Ethernet31": {}
+ }
+}
diff --git a/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-bgpd.conf
index 7633ac117bf7..d3b9b472c5bd 100644
--- a/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-bgpd.conf
+++ b/src/sonic-config-engine/tests/sample_output/py2/t2-chassis-fe-bgpd.conf
@@ -66,6 +66,7 @@ router bgp 4000
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 4.0.0.0
!
diff --git a/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf
index b8a7f2568232..e7534d4b9781 100644
--- a/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf
+++ b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr.conf
@@ -50,6 +50,7 @@ router bgp 65100
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 10.1.0.32
!
diff --git a/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr_backend_asic.conf b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr_backend_asic.conf
index 48ac8b54d013..a4ad1c677a77 100644
--- a/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr_backend_asic.conf
+++ b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr_backend_asic.conf
@@ -49,6 +49,7 @@ router bgp 65100
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 8.0.0.5
!
diff --git a/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr_frontend_asic.conf b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr_frontend_asic.conf
index 3806681a0225..b49d3ddd4dcd 100644
--- a/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr_frontend_asic.conf
+++ b/src/sonic-config-engine/tests/sample_output/py3/bgpd_frr_frontend_asic.conf
@@ -49,6 +49,7 @@ router bgp 65100
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 10.1.0.32
!
diff --git a/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf b/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf
index e5e5462bde77..bc24433a14cf 100644
--- a/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf
+++ b/src/sonic-config-engine/tests/sample_output/py3/docker-dhcp-relay.supervisord.conf
@@ -40,9 +40,9 @@ dependent_startup=true
dependent_startup_wait_for=rsyslogd:running
[group:isc-dhcp-relay]
-programs=isc-dhcp-relay-Vlan1000
+programs=isc-dhcpv4-relay-Vlan1000,isc-dhcpv6-relay-Vlan1000
-[program:isc-dhcp-relay-Vlan1000]
+[program:isc-dhcpv4-relay-Vlan1000]
command=/usr/sbin/dhcrelay -d -m discard -a %%h:%%p %%P --name-alias-map-file /tmp/port-name-alias-map.txt -id Vlan1000 -iu Vlan2000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 192.0.0.1 192.0.0.2
priority=3
autostart=false
@@ -52,19 +52,28 @@ stderr_logfile=syslog
dependent_startup=true
dependent_startup_wait_for=start:exited
+[program:isc-dhcpv6-relay-Vlan1000]
+command=/usr/sbin/dhcrelay -d -6 --name-alias-map-file /tmp/port-name-alias-map.txt -l Vlan1000 -u fc02:2000::1%%PortChannel01 -u fc02:2000::1%%PortChannel02 -u fc02:2000::1%%PortChannel03 -u fc02:2000::1%%PortChannel04 -u fc02:2000::2%%PortChannel01 -u fc02:2000::2%%PortChannel02 -u fc02:2000::2%%PortChannel03 -u fc02:2000::2%%PortChannel04
+priority=3
+autostart=false
+autorestart=false
+stdout_logfile=syslog
+stderr_logfile=syslog
+dependent_startup=true
+dependent_startup_wait_for=start:exited
+
[group:dhcpmon]
programs=dhcpmon-Vlan1000
[program:dhcpmon-Vlan1000]
-command=/usr/sbin/dhcpmon -id Vlan1000 -iu Vlan2000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -im eth0
+command=/usr/sbin/dhcpmon -id Vlan1000 -iu Vlan2000 -iu PortChannel01 -iu PortChannel02 -iu PortChannel03 -iu PortChannel04 -im eth0 -4 -6
priority=4
autostart=false
autorestart=false
stdout_logfile=syslog
stderr_logfile=syslog
dependent_startup=true
-dependent_startup_wait_for=isc-dhcp-relay-Vlan1000:running
-
+dependent_startup_wait_for=isc-dhcpv4-relay-Vlan1000:running isc-dhcpv6-relay-Vlan1000:running
diff --git a/src/sonic-config-engine/tests/sample_output/py3/frr.conf b/src/sonic-config-engine/tests/sample_output/py3/frr.conf
index 032eb26c5337..8dfec1a9c753 100644
--- a/src/sonic-config-engine/tests/sample_output/py3/frr.conf
+++ b/src/sonic-config-engine/tests/sample_output/py3/frr.conf
@@ -73,6 +73,7 @@ router bgp 65100
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 10.1.0.32
!
diff --git a/src/sonic-config-engine/tests/sample_output/py3/l1_intfs.json b/src/sonic-config-engine/tests/sample_output/py3/l1_intfs.json
new file mode 100644
index 000000000000..bc2d533e87a1
--- /dev/null
+++ b/src/sonic-config-engine/tests/sample_output/py3/l1_intfs.json
@@ -0,0 +1,261 @@
+{
+ "DEVICE_METADATA": {"localhost": {"hwsku": "32x1000Gb"}},
+ "PORT": {
+ "Ethernet0": {
+ "admin_status": "up",
+ "alias": "Ethernet0",
+ "index": "0",
+ "lanes": "1296,1297,1298,1299",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet1": {
+ "admin_status": "up",
+ "alias": "Ethernet1",
+ "index": "1",
+ "lanes": "1300,1301,1302,1303",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet10": {
+ "admin_status": "up",
+ "alias": "Ethernet10",
+ "index": "10",
+ "lanes": "772,773,774,775",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet11": {
+ "admin_status": "up",
+ "alias": "Ethernet11",
+ "index": "11",
+ "lanes": "768,769,770,771",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet12": {
+ "admin_status": "up",
+ "alias": "Ethernet12",
+ "index": "12",
+ "lanes": "780,781,782,783",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet13": {
+ "admin_status": "up",
+ "alias": "Ethernet13",
+ "index": "13",
+ "lanes": "776,777,778,779",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet14": {
+ "admin_status": "up",
+ "alias": "Ethernet14",
+ "index": "14",
+ "lanes": "528,529,530,531",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet15": {
+ "admin_status": "up",
+ "alias": "Ethernet15",
+ "index": "15",
+ "lanes": "532,533,534,535",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet16": {
+ "admin_status": "up",
+ "alias": "Ethernet16",
+ "index": "16",
+ "lanes": "520,521,522,523",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet17": {
+ "admin_status": "up",
+ "alias": "Ethernet17",
+ "index": "17",
+ "lanes": "524,525,526,527",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet18": {
+ "admin_status": "up",
+ "alias": "Ethernet18",
+ "index": "18",
+ "lanes": "512,513,514,515",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet19": {
+ "admin_status": "up",
+ "alias": "Ethernet19",
+ "index": "19",
+ "lanes": "516,517,518,519",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet2": {
+ "admin_status": "up",
+ "alias": "Ethernet2",
+ "index": "2",
+ "lanes": "1288,1289,1290,1291",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet20": {
+ "admin_status": "up",
+ "alias": "Ethernet20",
+ "index": "20",
+ "lanes": "272,273,274,275",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet21": {
+ "admin_status": "up",
+ "alias": "Ethernet21",
+ "index": "21",
+ "lanes": "276,277,278,279",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet22": {
+ "admin_status": "up",
+ "alias": "Ethernet22",
+ "index": "22",
+ "lanes": "264,265,266,267",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet23": {
+ "admin_status": "up",
+ "alias": "Ethernet23",
+ "index": "23",
+ "lanes": "268,269,270,271",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet24": {
+ "admin_status": "up",
+ "alias": "Ethernet24",
+ "index": "24",
+ "lanes": "256,257,258,259",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet25": {
+ "admin_status": "up",
+ "alias": "Ethernet25",
+ "index": "25",
+ "lanes": "260,261,262,263",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet26": {
+ "admin_status": "up",
+ "alias": "Ethernet26",
+ "index": "26",
+ "lanes": "16,17,18,19",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet27": {
+ "admin_status": "up",
+ "alias": "Ethernet27",
+ "index": "27",
+ "lanes": "20,21,22,23",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet28": {
+ "admin_status": "up",
+ "alias": "Ethernet28",
+ "index": "28",
+ "lanes": "8,9,10,11",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet29": {
+ "admin_status": "up",
+ "alias": "Ethernet29",
+ "index": "29",
+ "lanes": "12,13,14,15",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet3": {
+ "admin_status": "up",
+ "alias": "Ethernet3",
+ "index": "3",
+ "lanes": "1292,1293,1294,1295",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet30": {
+ "admin_status": "up",
+ "alias": "Ethernet30",
+ "index": "30",
+ "lanes": "0,1,2,3",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet31": {
+ "admin_status": "up",
+ "alias": "Ethernet31",
+ "index": "31",
+ "lanes": "4,5,6,7",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet4": {
+ "admin_status": "up",
+ "alias": "Ethernet4",
+ "index": "4",
+ "lanes": "1280,1281,1282,1283",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet5": {
+ "admin_status": "up",
+ "alias": "Ethernet5",
+ "index": "5",
+ "lanes": "1284,1285,1286,1287",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet6": {
+ "admin_status": "up",
+ "alias": "Ethernet6",
+ "index": "6",
+ "lanes": "1032,1033,1034,1035",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet7": {
+ "admin_status": "up",
+ "alias": "Ethernet7",
+ "index": "7",
+ "lanes": "1036,1037,1038,1039",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet8": {
+ "admin_status": "up",
+ "alias": "Ethernet8",
+ "index": "8",
+ "lanes": "1024,1025,1026,1027",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet9": {
+ "admin_status": "up",
+ "alias": "Ethernet9",
+ "index": "9",
+ "lanes": "1028,1029,1030,1031",
+ "mtu": "9100",
+ "speed": "100000"
+ }
+ }
+}
diff --git a/src/sonic-config-engine/tests/sample_output/py3/l3_intfs.json b/src/sonic-config-engine/tests/sample_output/py3/l3_intfs.json
new file mode 100644
index 000000000000..9ca31832303f
--- /dev/null
+++ b/src/sonic-config-engine/tests/sample_output/py3/l3_intfs.json
@@ -0,0 +1,301 @@
+{
+ "DEVICE_METADATA": {"localhost": {"hwsku": "32x1000Gb"}},
+ "PORT": {
+ "Ethernet0": {
+ "admin_status": "up",
+ "alias": "Ethernet0",
+ "index": "0",
+ "lanes": "1296,1297,1298,1299",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet1": {
+ "admin_status": "up",
+ "alias": "Ethernet1",
+ "index": "1",
+ "lanes": "1300,1301,1302,1303",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet10": {
+ "admin_status": "up",
+ "alias": "Ethernet10",
+ "index": "10",
+ "lanes": "772,773,774,775",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet11": {
+ "admin_status": "up",
+ "alias": "Ethernet11",
+ "index": "11",
+ "lanes": "768,769,770,771",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet12": {
+ "admin_status": "up",
+ "alias": "Ethernet12",
+ "index": "12",
+ "lanes": "780,781,782,783",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet13": {
+ "admin_status": "up",
+ "alias": "Ethernet13",
+ "index": "13",
+ "lanes": "776,777,778,779",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet14": {
+ "admin_status": "up",
+ "alias": "Ethernet14",
+ "index": "14",
+ "lanes": "528,529,530,531",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet15": {
+ "admin_status": "up",
+ "alias": "Ethernet15",
+ "index": "15",
+ "lanes": "532,533,534,535",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet16": {
+ "admin_status": "up",
+ "alias": "Ethernet16",
+ "index": "16",
+ "lanes": "520,521,522,523",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet17": {
+ "admin_status": "up",
+ "alias": "Ethernet17",
+ "index": "17",
+ "lanes": "524,525,526,527",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet18": {
+ "admin_status": "up",
+ "alias": "Ethernet18",
+ "index": "18",
+ "lanes": "512,513,514,515",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet19": {
+ "admin_status": "up",
+ "alias": "Ethernet19",
+ "index": "19",
+ "lanes": "516,517,518,519",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet2": {
+ "admin_status": "up",
+ "alias": "Ethernet2",
+ "index": "2",
+ "lanes": "1288,1289,1290,1291",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet20": {
+ "admin_status": "up",
+ "alias": "Ethernet20",
+ "index": "20",
+ "lanes": "272,273,274,275",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet21": {
+ "admin_status": "up",
+ "alias": "Ethernet21",
+ "index": "21",
+ "lanes": "276,277,278,279",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet22": {
+ "admin_status": "up",
+ "alias": "Ethernet22",
+ "index": "22",
+ "lanes": "264,265,266,267",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet23": {
+ "admin_status": "up",
+ "alias": "Ethernet23",
+ "index": "23",
+ "lanes": "268,269,270,271",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet24": {
+ "admin_status": "up",
+ "alias": "Ethernet24",
+ "index": "24",
+ "lanes": "256,257,258,259",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet25": {
+ "admin_status": "up",
+ "alias": "Ethernet25",
+ "index": "25",
+ "lanes": "260,261,262,263",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet26": {
+ "admin_status": "up",
+ "alias": "Ethernet26",
+ "index": "26",
+ "lanes": "16,17,18,19",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet27": {
+ "admin_status": "up",
+ "alias": "Ethernet27",
+ "index": "27",
+ "lanes": "20,21,22,23",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet28": {
+ "admin_status": "up",
+ "alias": "Ethernet28",
+ "index": "28",
+ "lanes": "8,9,10,11",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet29": {
+ "admin_status": "up",
+ "alias": "Ethernet29",
+ "index": "29",
+ "lanes": "12,13,14,15",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet3": {
+ "admin_status": "up",
+ "alias": "Ethernet3",
+ "index": "3",
+ "lanes": "1292,1293,1294,1295",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet30": {
+ "admin_status": "up",
+ "alias": "Ethernet30",
+ "index": "30",
+ "lanes": "0,1,2,3",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet31": {
+ "admin_status": "up",
+ "alias": "Ethernet31",
+ "index": "31",
+ "lanes": "4,5,6,7",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet4": {
+ "admin_status": "up",
+ "alias": "Ethernet4",
+ "index": "4",
+ "lanes": "1280,1281,1282,1283",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet5": {
+ "admin_status": "up",
+ "alias": "Ethernet5",
+ "index": "5",
+ "lanes": "1284,1285,1286,1287",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet6": {
+ "admin_status": "up",
+ "alias": "Ethernet6",
+ "index": "6",
+ "lanes": "1032,1033,1034,1035",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet7": {
+ "admin_status": "up",
+ "alias": "Ethernet7",
+ "index": "7",
+ "lanes": "1036,1037,1038,1039",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet8": {
+ "admin_status": "up",
+ "alias": "Ethernet8",
+ "index": "8",
+ "lanes": "1024,1025,1026,1027",
+ "mtu": "9100",
+ "speed": "100000"
+ },
+ "Ethernet9": {
+ "admin_status": "up",
+ "alias": "Ethernet9",
+ "index": "9",
+ "lanes": "1028,1029,1030,1031",
+ "mtu": "9100",
+ "speed": "100000"
+ }
+ },
+ "LOOPBACK_INTERFACE": {
+ "Loopback0": {},
+ "Loopback0|10.1.0.1/32": {}
+ },
+ "BGP_NEIGHBOR": {},
+ "DEVICE_NEIGHBOR": {},
+ "INTERFACE": {
+ "Ethernet0": {},
+ "Ethernet1": {},
+ "Ethernet2": {},
+ "Ethernet3": {},
+ "Ethernet4": {},
+ "Ethernet5": {},
+ "Ethernet6": {},
+ "Ethernet7": {},
+ "Ethernet8": {},
+ "Ethernet9": {},
+ "Ethernet10": {},
+ "Ethernet11": {},
+ "Ethernet12": {},
+ "Ethernet13": {},
+ "Ethernet14": {},
+ "Ethernet15": {},
+ "Ethernet16": {},
+ "Ethernet17": {},
+ "Ethernet18": {},
+ "Ethernet19": {},
+ "Ethernet20": {},
+ "Ethernet21": {},
+ "Ethernet22": {},
+ "Ethernet23": {},
+ "Ethernet24": {},
+ "Ethernet25": {},
+ "Ethernet26": {},
+ "Ethernet27": {},
+ "Ethernet28": {},
+ "Ethernet29": {},
+ "Ethernet30": {},
+ "Ethernet31": {}
+ }
+}
diff --git a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf
index 7633ac117bf7..d3b9b472c5bd 100644
--- a/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf
+++ b/src/sonic-config-engine/tests/sample_output/py3/t2-chassis-fe-bgpd.conf
@@ -66,6 +66,7 @@ router bgp 4000
bgp graceful-restart restart-time 240
bgp graceful-restart
bgp graceful-restart preserve-fw-state
+ bgp graceful-restart select-defer-time 45
!
bgp router-id 4.0.0.0
!
diff --git a/src/sonic-config-engine/tests/t0-sample-graph.xml b/src/sonic-config-engine/tests/t0-sample-graph.xml
index 266554dd331b..c06cc708c1ce 100644
--- a/src/sonic-config-engine/tests/t0-sample-graph.xml
+++ b/src/sonic-config-engine/tests/t0-sample-graph.xml
@@ -256,6 +256,7 @@
192.0.0.1;192.0.0.2
+ fc02:2000::1;fc02:2000::2
1000
1000
192.168.0.0/27
diff --git a/src/sonic-config-engine/tests/test_cfggen.py b/src/sonic-config-engine/tests/test_cfggen.py
index eff8324d6fd2..a607d9b3278c 100644
--- a/src/sonic-config-engine/tests/test_cfggen.py
+++ b/src/sonic-config-engine/tests/test_cfggen.py
@@ -31,6 +31,7 @@ def setUp(self):
self.ecmp_graph = os.path.join(self.test_dir, 'fg-ecmp-sample-minigraph.xml')
self.sample_resource_graph = os.path.join(self.test_dir, 'sample-graph-resource-type.xml')
self.sample_subintf_graph = os.path.join(self.test_dir, 'sample-graph-subintf.xml')
+ self.voq_port_config = os.path.join(self.test_dir, 'voq-sample-port-config.ini')
# To ensure that mock config_db data is used for unit-test cases
os.environ["CFGGEN_UNIT_TESTING"] = "2"
@@ -778,11 +779,44 @@ def test_minigraph_voq_system_ports(self):
}
)
- def test_minigraph_voq_inband_interface(self):
+ def test_minigraph_voq_inband_interface_vlan(self):
argument = "-m {} --var-json VOQ_INBAND_INTERFACE".format(self.sample_graph_voq)
+ output = self.run_script(argument)
+ output_dict = utils.to_dict(output.strip())
self.assertDictEqual(
- json.loads(self.run_script(argument)),
- { 'Vlan3094': {'inband_type': 'Vlan'},
- 'Vlan3094|1.1.1.1/24': {}
+ output_dict['Vlan3094'],
+ {'inband_type': 'Vlan'}
+ )
+ self.assertDictEqual(
+ output_dict['Vlan3094|1.1.1.1/24'],
+ {}
+ )
+
+ def test_minigraph_voq_inband_interface_port(self):
+ argument = "-m {} --var-json VOQ_INBAND_INTERFACE".format(self.sample_graph_voq)
+ output = self.run_script(argument)
+ output_dict = utils.to_dict(output.strip())
+ self.assertDictEqual(
+ output_dict['Ethernet-IB0'],
+ {'inband_type': 'port'}
+ )
+ self.assertDictEqual(
+ output_dict['Ethernet-IB0|2.2.2.2/32'],
+ {}
+ )
+
+ def test_minigraph_voq_inband_port(self):
+ argument = "-m {} -p {} --var-json PORT".format(self.sample_graph_voq, self.voq_port_config)
+ output = self.run_script(argument)
+ output_dict = utils.to_dict(output.strip())
+ self.assertDictEqual(
+ output_dict['Ethernet-IB0'],
+ {'lanes': '133',
+ 'alias': 'Recycle0',
+ 'description': 'Recycle0',
+ 'mtu': '9100',
+ 'tpid': '0x8100',
+ 'pfc_asym': 'off',
+ 'admin_status': 'up'
}
)
diff --git a/src/sonic-config-engine/tests/test_j2files.py b/src/sonic-config-engine/tests/test_j2files.py
index 532922083887..cb2d7682e7d2 100644
--- a/src/sonic-config-engine/tests/test_j2files.py
+++ b/src/sonic-config-engine/tests/test_j2files.py
@@ -17,6 +17,7 @@ def setUp(self):
self.t0_mvrf_minigraph = os.path.join(self.test_dir, 't0-sample-graph-mvrf.xml')
self.pc_minigraph = os.path.join(self.test_dir, 'pc-test-graph.xml')
self.t0_port_config = os.path.join(self.test_dir, 't0-sample-port-config.ini')
+ self.l1_l3_port_config = os.path.join(self.test_dir, 'l1-l3-sample-port-config.ini')
self.t0_7050cx3_port_config = os.path.join(self.test_dir, 't0_7050cx3_d48c8_port_config.ini')
self.t1_mlnx_minigraph = os.path.join(self.test_dir, 't1-sample-graph-mlnx.xml')
self.mlnx_port_config = os.path.join(self.test_dir, 'sample-port-config-mlnx.ini')
@@ -118,6 +119,42 @@ def test_l2switch_template(self):
output_json = json.loads(output)
self.assertTrue(json.dumps(sample_output_json, sort_keys=True) == json.dumps(output_json, sort_keys=True))
+
+ def test_l1_ports_template(self):
+ argument = '-k 32x1000Gb --preset l1 -p ' + self.l1_l3_port_config
+ output = self.run_script(argument)
+ output_json = json.loads(output)
+
+ sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'l1_intfs.json')
+ with open(sample_output_file) as sample_output_fd:
+ sample_output_json = json.load(sample_output_fd)
+
+ self.assertTrue(json.dumps(sample_output_json, sort_keys=True) == json.dumps(output_json, sort_keys=True))
+
+ template_dir = os.path.join(self.test_dir, '..', 'data', 'l1intf.j2')
+ argument = '-t ' + template_dir + ' -k 32x1000Gb -p ' + self.l1_l3_port_config
+ output = self.run_script(argument)
+ output_json = json.loads(output)
+
+ self.assertTrue(json.dumps(sample_output_json, sort_keys=True) == json.dumps(output_json, sort_keys=True))
+
+ def test_l3_ports_template(self):
+ argument = '-k 32x1000Gb --preset l3 -p ' + self.l1_l3_port_config
+ output = self.run_script(argument)
+ output_json = json.loads(output)
+
+ sample_output_file = os.path.join(self.test_dir, 'sample_output', utils.PYvX_DIR, 'l3_intfs.json')
+ with open(sample_output_file) as sample_output_fd:
+ sample_output_json = json.load(sample_output_fd)
+
+ self.assertTrue(json.dumps(sample_output_json, sort_keys=True) == json.dumps(output_json, sort_keys=True))
+
+ template_dir = os.path.join(self.test_dir, '..', 'data', 'l3intf.j2')
+ argument = '-t ' + template_dir + ' -k 32x1000Gb -p ' + self.l1_l3_port_config
+ output = self.run_script(argument)
+ output_json = json.loads(output)
+
+ self.assertTrue(json.dumps(sample_output_json, sort_keys=True) == json.dumps(output_json, sort_keys=True))
def test_l2switch_template_dualtor(self):
extra_args = {
diff --git a/src/sonic-config-engine/tests/test_multinpu_cfggen.py b/src/sonic-config-engine/tests/test_multinpu_cfggen.py
index 1a91772092ab..8a79be743848 100644
--- a/src/sonic-config-engine/tests/test_multinpu_cfggen.py
+++ b/src/sonic-config-engine/tests/test_multinpu_cfggen.py
@@ -407,14 +407,14 @@ def test_buffers_multi_asic_template(self):
output['CABLE_LENGTH'],
{
'AZURE': {
- 'Ethernet8': '300m',
+ 'Ethernet8': '0m',
'Ethernet0': '300m',
'Ethernet4': '300m',
'Ethernet-BP4': '5m',
'Ethernet-BP0': '5m',
'Ethernet-BP12': '5m',
'Ethernet-BP8': '5m',
- 'Ethernet12': '300m'
+ 'Ethernet12': '0m'
}
}
)
diff --git a/src/sonic-config-engine/tests/voq-sample-port-config.ini b/src/sonic-config-engine/tests/voq-sample-port-config.ini
new file mode 100644
index 000000000000..3910e29de0a3
--- /dev/null
+++ b/src/sonic-config-engine/tests/voq-sample-port-config.ini
@@ -0,0 +1,34 @@
+# name lanes alias
+Ethernet0 29,30,31,32 fortyGigE0/0
+Ethernet4 25,26,27,28 fortyGigE0/4
+Ethernet8 37,38,39,40 fortyGigE0/8
+Ethernet12 33,34,35,36 fortyGigE0/12
+Ethernet16 41,42,43,44 fortyGigE0/16
+Ethernet20 45,46,47,48 fortyGigE0/20
+Ethernet24 5,6,7,8 fortyGigE0/24
+Ethernet28 1,2,3,4 fortyGigE0/28
+Ethernet32 9,10,11,12 fortyGigE0/32
+Ethernet36 13,14,15,16 fortyGigE0/36
+Ethernet40 21,22,23,24 fortyGigE0/40
+Ethernet44 17,18,19,20 fortyGigE0/44
+Ethernet48 49,50,51,52 fortyGigE0/48
+Ethernet52 53,54,55,56 fortyGigE0/52
+Ethernet56 61,62,63,64 fortyGigE0/56
+Ethernet60 57,58,59,60 fortyGigE0/60
+Ethernet64 65,66,67,68 fortyGigE0/64
+Ethernet68 69,70,71,72 fortyGigE0/68
+Ethernet72 77,78,79,80 fortyGigE0/72
+Ethernet76 73,74,75,76 fortyGigE0/76
+Ethernet80 105,106,107,108 fortyGigE0/80
+Ethernet84 109,110,111,112 fortyGigE0/84
+Ethernet88 117,118,119,120 fortyGigE0/88
+Ethernet92 113,114,115,116 fortyGigE0/92
+Ethernet96 121,122,123,124 fortyGigE0/96
+Ethernet100 125,126,127,128 fortyGigE0/100
+Ethernet104 85,86,87,88 fortyGigE0/104
+Ethernet108 81,82,83,84 fortyGigE0/108
+Ethernet112 89,90,91,92 fortyGigE0/112
+Ethernet116 93,94,95,96 fortyGigE0/116
+Ethernet120 97,98,99,100 fortyGigE0/120
+Ethernet124 101,102,103,104 fortyGigE0/124
+Ethernet-IB0 133 Recycle0
diff --git a/src/sonic-ctrmgrd/ctrmgr/ctrmgr_iptables.py b/src/sonic-ctrmgrd/ctrmgr/ctrmgr_iptables.py
new file mode 100644
index 000000000000..74b9bfe44fc9
--- /dev/null
+++ b/src/sonic-ctrmgrd/ctrmgr/ctrmgr_iptables.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python3
+
+import ipaddress
+import os
+import re
+import socket
+import subprocess
+import syslog
+
+UNIT_TESTING = 0
+
+# NOTE:
+# Unable to use python-iptables as that does not create rules per ip-tables default
+# which is nf_tables. So rules added via iptc package will not be listed under
+# "sudo iptables -t nat -L -n". But available in kernel. To list, we need to
+# use legacy mode as "sudo iptables-legacy -t nat -L -n".
+# As we can't use two modes and using non-default could make any debugging effort
+# very tough.
+
+
+from urllib.parse import urlparse
+
+DST_FILE = "/etc/systemd/system/docker.service.d/http_proxy.conf"
+DST_IP = None
+DST_PORT = None
+SQUID_PORT = "3128"
+
+def _get_ip(ip_str):
+ ret = ""
+ if ip_str:
+ try:
+ ipaddress.ip_address(ip_str)
+ ret = ip_str
+ except ValueError:
+ pass
+
+ if not ret:
+ try:
+ ret = socket.gethostbyname(ip_str)
+ except (OSError, socket.error):
+ pass
+ if not ret:
+ syslog.syslog(syslog.LOG_ERR, "{} is neither IP nor resolves to IP".
+ format(ip_str))
+ return ret
+
+
+def _get_dst_info():
+ global DST_IP, DST_PORT
+ DST_IP = None
+ DST_PORT = None
+ print("DST_FILE={}".format(DST_FILE))
+ if os.path.exists(DST_FILE):
+ with open(DST_FILE, "r") as s:
+ for line in s.readlines():
+ url_match = re.search('^Environment=.HTTP_PROXY=(.+?)"', line)
+ if url_match:
+ url = urlparse(url_match.group(1))
+ DST_IP = _get_ip(url.hostname)
+ DST_PORT = url.port
+ break
+ else:
+ print("{} not available".format(DST_FILE))
+ print("DST_IP={}".format(DST_IP))
+
+
+def _is_rule_match(rule):
+ expect = "DNAT tcp -- 0.0.0.0/0 {} tcp dpt:{} to:".format(
+ DST_IP, DST_PORT)
+
+ # Remove duplicate spaces
+ rule = " ".join(rule.split()).strip()
+
+ if rule.startswith(expect):
+ return rule[len(expect):]
+ else:
+ return ""
+
+
+def check_proc(proc):
+ if proc.returncode:
+ syslog.syslog(syslog.LOG_ERR, "Failed to run: cmd: {}".format(proc.args))
+ syslog.syslog(syslog.LOG_ERR, "Failed to run: stdout: {}".format(proc.stdout))
+ syslog.syslog(syslog.LOG_ERR, "Failed to run: stderr: {}".format(proc.stderr))
+ if not UNIT_TESTING:
+ assert False
+
+
+def iptable_proxy_rule_upd(ip_str, port = SQUID_PORT):
+ _get_dst_info()
+ if not DST_IP:
+ # There is no proxy in use. Bail out.
+ return ""
+
+ destination = ""
+ if ip_str:
+ upd_ip = _get_ip(ip_str)
+ if not upd_ip:
+ return ""
+ destination = "{}:{}".format(upd_ip, port)
+
+ found = False
+ num = 0
+
+ while True:
+ num += 1
+
+ cmd = "sudo iptables -t nat -n -L OUTPUT {}".format(num)
+ proc = subprocess.run(cmd, shell=True, capture_output=True)
+ check_proc(proc)
+
+ if not proc.stdout:
+ # No more rule
+ break
+
+ rule_dest = _is_rule_match(proc.stdout.decode("utf-8").strip())
+ if rule_dest:
+ if not found and destination and (rule_dest == destination):
+ found = True
+ else:
+ # Duplicate or different IP - delete it
+ cmd = "sudo iptables -t nat -D OUTPUT {}".format(num)
+ proc = subprocess.run(cmd, shell=True, capture_output=True)
+ check_proc(proc)
+ # Decrement number to accommodate deleted rule
+ num -= 1
+
+ if destination and not found:
+ cmd = "sudo iptables -t nat -A OUTPUT -p tcp -d {} --dport {} -j DNAT --to-destination {}".format(
+ DST_IP, DST_PORT, destination)
+ proc = subprocess.run(cmd, shell=True, capture_output=True)
+
+ check_proc(proc)
+
+ return destination
diff --git a/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.py b/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.py
index 49c11d278170..3941a05a738a 100755
--- a/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.py
+++ b/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.py
@@ -8,6 +8,7 @@
import syslog
from collections import defaultdict
+from ctrmgr.ctrmgr_iptables import iptable_proxy_rule_upd
from swsscommon import swsscommon
from sonic_py_common import device_info
@@ -87,11 +88,13 @@
JOIN_LATENCY = "join_latency_on_boot_seconds"
JOIN_RETRY = "retry_join_interval_seconds"
LABEL_RETRY = "retry_labels_update_seconds"
+USE_K8S_PROXY = "use_k8s_as_http_proxy"
remote_ctr_config = {
JOIN_LATENCY: 10,
JOIN_RETRY: 10,
- LABEL_RETRY: 2
+ LABEL_RETRY: 2,
+ USE_K8S_PROXY: ""
}
def log_debug(m):
@@ -309,6 +312,9 @@ def __init__(self, server):
self.start_time = datetime.datetime.now()
+ if remote_ctr_config[USE_K8S_PROXY] == "y":
+ iptable_proxy_rule_upd(self.cfg_server[CFG_SER_IP])
+
if not self.st_server[ST_FEAT_UPDATE_TS]:
# This is upon system start. Sleep 10m before join
self.start_time += datetime.timedelta(
@@ -336,6 +342,9 @@ def on_config_update(self, key, op, data):
log_debug("Received config update: {}".format(str(data)))
self.cfg_server = cfg_data
+ if remote_ctr_config[USE_K8S_PROXY] == "y":
+ iptable_proxy_rule_upd(self.cfg_server[CFG_SER_IP])
+
if self.pending:
tnow = datetime.datetime.now()
if tnow < self.start_time:
@@ -359,7 +368,7 @@ def handle_update(self):
ip = self.cfg_server[CFG_SER_IP]
disable = self.cfg_server[CFG_SER_DISABLE] != "false"
-
+
pre_state = dict(self.st_server)
log_debug("server: handle_update: disable={} ip={}".format(disable, ip))
if disable or not ip:
diff --git a/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.service b/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.service
index 6052c10785da..f59314259bc6 100644
--- a/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.service
+++ b/src/sonic-ctrmgrd/ctrmgr/ctrmgrd.service
@@ -1,8 +1,9 @@
[Unit]
Description=Container Manager watcher daemon
-Requires=updategraph.service
-After=updategraph.service
-
+Requires=caclmgrd.service
+After=caclmgrd.service
+BindsTo=sonic.target
+After=sonic.target
[Service]
Type=simple
@@ -11,4 +12,4 @@ Restart=always
RestartSec=30
[Install]
-WantedBy=multi-user.target
+WantedBy=sonic.target
diff --git a/src/sonic-ctrmgrd/ctrmgr/remote_ctr.config.json b/src/sonic-ctrmgrd/ctrmgr/remote_ctr.config.json
index e7bca832e18b..3fb0c20fddcf 100644
--- a/src/sonic-ctrmgrd/ctrmgr/remote_ctr.config.json
+++ b/src/sonic-ctrmgrd/ctrmgr/remote_ctr.config.json
@@ -2,6 +2,7 @@
"join_latency_on_boot_seconds": 300,
"retry_join_interval_seconds": 30,
"retry_labels_update_seconds": 5,
- "revert_to_local_on_wait_seconds": 60
+ "revert_to_local_on_wait_seconds": 60,
+ "use_k8s_as_http_proxy": "n"
}
diff --git a/src/sonic-ctrmgrd/tests/ctrmgr_iptables_test.py b/src/sonic-ctrmgrd/tests/ctrmgr_iptables_test.py
new file mode 100755
index 000000000000..fc28cbecc8da
--- /dev/null
+++ b/src/sonic-ctrmgrd/tests/ctrmgr_iptables_test.py
@@ -0,0 +1,178 @@
+import os
+import re
+import sys
+from unittest.mock import MagicMock, patch
+
+import pytest
+
+from . import common_test
+
+sys.path.append("ctrmgr")
+import ctrmgr_iptables
+
+
+PROXY_FILE="http_proxy.conf"
+
+test_data = {
+ "1": {
+ "ip": "10.10.20.20",
+ "port": "3128",
+ "pre_rules": [
+ "DNAT tcp -- 20.20.0.0/0 172.16.1.1 tcp dpt:8080 to:100.127.20.21:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:11.11.11.11:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:11.11.11.11:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:11.11.11.11:8088",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3129 to:11.11.11.11:8088"
+ ],
+ "post_rules": [
+ "DNAT tcp -- 20.20.0.0/0 172.16.1.1 tcp dpt:8080 to:100.127.20.21:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3129 to:11.11.11.11:8088",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:10.10.20.20:3128"
+ ],
+ "ret": "10.10.20.20:3128"
+ },
+ "2": {
+ "ip": "",
+ "port": "",
+ "pre_rules": [
+ "DNAT tcp -- 20.20.0.0/0 172.16.1.1 tcp dpt:8080 to:100.127.20.21:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:11.11.11.11:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:11.11.11.11:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:11.11.11.11:8088"
+ ],
+ "post_rules": [
+ "DNAT tcp -- 20.20.0.0/0 172.16.1.1 tcp dpt:8080 to:100.127.20.21:8080"
+ ],
+ "ret": ""
+ },
+ "3": {
+ "ip": "www.google.com",
+ "port": "3128",
+ "pre_rules": [
+ "DNAT tcp -- 20.20.0.0/0 172.16.1.1 tcp dpt:8080 to:100.127.20.21:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:11.11.11.11:8080"
+ ],
+ "post_rules": [
+ "DNAT tcp -- 20.20.0.0/0 172.16.1.1 tcp dpt:8080 to:100.127.20.21:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:.*3128"
+ ]
+ },
+ "4": {
+ "ip": "www.google.comx",
+ "port": "3128",
+ "pre_rules": [
+ "DNAT tcp -- 20.20.0.0/0 172.16.1.1 tcp dpt:8080 to:100.127.20.21:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:11.11.11.11:8080"
+ ],
+ "post_rules": [
+ "DNAT tcp -- 20.20.0.0/0 172.16.1.1 tcp dpt:8080 to:100.127.20.21:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:11.11.11.11:8080"
+ ],
+ "ret": ""
+ },
+ "5": {
+ "ip": "www.google.comx",
+ "port": "3128",
+ "conf_file": "no_proxy.conf",
+ "pre_rules": [
+ "DNAT tcp -- 20.20.0.0/0 172.16.1.1 tcp dpt:8080 to:100.127.20.21:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:11.11.11.11:8080"
+ ],
+ "post_rules": [
+ "DNAT tcp -- 20.20.0.0/0 172.16.1.1 tcp dpt:8080 to:100.127.20.21:8080",
+ "DNAT tcp -- 0.0.0.0/0 172.16.1.1 tcp dpt:3128 to:11.11.11.11:8080"
+ ],
+ "ret": ""
+ }
+}
+
+
+current_tc = None
+current_rules = None
+
+class proc:
+ returncode = 0
+ stdout = None
+ stderr = None
+
+ def __init__(self, ret, stdout, stderr):
+ self.returncode = ret
+ self.stdout = bytearray(stdout, 'utf-8')
+ self.stderr = bytearray(stderr, 'utf-8')
+ print("out={} err={}".format(stdout, stderr))
+
+
+def mock_subproc_run(cmd, shell, capture_output):
+ cmd_prefix = "sudo iptables -t nat "
+ list_cmd = "{}-n -L OUTPUT ".format(cmd_prefix)
+ del_cmd = "{}-D OUTPUT ".format(cmd_prefix)
+ ins_cmd = "{}-A OUTPUT -p tcp -d ".format(cmd_prefix)
+
+ assert shell
+
+ print("cmd={}".format(cmd))
+ if cmd.startswith(list_cmd):
+ num = int(cmd[len(list_cmd):])
+ out = current_rules[num] if len(current_rules) > num else ""
+ return proc(0, out, "")
+
+ if cmd.startswith(del_cmd):
+ num = int(cmd[len(del_cmd):])
+ if num >= len(current_rules):
+ print("delete num={} is greater than len={}".format(num, len(current_rules)))
+ print("current_rules = {}".format(current_rules))
+ assert False
+ del current_rules[num]
+ return proc(0, "", "")
+
+ if cmd.startswith(ins_cmd):
+ l = cmd.split()
+ assert len(l) == 16
+ rule = "DNAT tcp -- 0.0.0.0/0 {} tcp dpt:{} to:{}".format(l[9], l[11], l[-1])
+ current_rules.append(rule)
+ return proc(0, "", "")
+
+ print("unknown cmd: {}".format(cmd))
+ return None
+
+
+def match_rules(pattern_list, str_list):
+ if len(pattern_list) != len(str_list):
+ print("pattern len {} != given {}".format(
+ len(pattern_list), len(str_list)))
+ return False
+
+ for i in range(len(pattern_list)):
+ if not re.match(pattern_list[i], str_list[i]):
+ print("{}: {} != {}".format(i, pattern_list[i], str_list[i]))
+ return False
+ return True
+
+
+class TestIPTableUpdate(object):
+
+ @patch("ctrmgr_iptables.subprocess.run")
+ def test_table(self, mock_proc):
+ global current_rules, current_tc
+
+ mock_proc.side_effect = mock_subproc_run
+ for i, tc in test_data.items():
+ print("----- Test: {} Start ------------------".format(i))
+ current_tc = tc
+ current_rules = tc["pre_rules"].copy()
+
+ ctrmgr_iptables.DST_IP = ""
+ ctrmgr_iptables.DST_PORT = ""
+ ctrmgr_iptables.DST_FILE = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)),
+ tc.get("conf_file", PROXY_FILE))
+ ret = ctrmgr_iptables.iptable_proxy_rule_upd(tc["ip"], tc["port"])
+ if "ret" in tc:
+ assert ret == tc["ret"]
+ if not match_rules(tc["post_rules"], current_rules):
+ print("current_rules={}".format(current_rules))
+ print("post_rules={}".format(tc["post_rules"]))
+ assert False
+ print("----- Test: {} End ------------------".format(i))
+
+
diff --git a/src/sonic-ctrmgrd/tests/ctrmgrd_test.py b/src/sonic-ctrmgrd/tests/ctrmgrd_test.py
index e0e821089346..171534b5a8d1 100755
--- a/src/sonic-ctrmgrd/tests/ctrmgrd_test.py
+++ b/src/sonic-ctrmgrd/tests/ctrmgrd_test.py
@@ -8,6 +8,7 @@
sys.path.append("ctrmgr")
import ctrmgrd
+import ctrmgr.ctrmgr_iptables
# ctrmgrd test cases
@@ -387,6 +388,11 @@ def init(self):
ctrmgrd.UNIT_TESTING = 1
ctrmgrd.SONIC_CTR_CONFIG = (
common_test.create_remote_ctr_config_json())
+ ctrmgr.ctrmgr_iptables.UNIT_TESTING = 1
+
+
+ def clear(self):
+ ctrmgr.ctrmgr_iptables.UNIT_TESTING = 0
@patch("ctrmgrd.swsscommon.DBConnector")
@@ -421,6 +427,7 @@ def test_server(self, mock_kube_wr, mock_kube_join, mock_kube_rst, mock_subs,
ret = common_test.check_kube_actions()
assert ret == 0
common_test.mock_selector.SLEEP_SECS = 0
+ self.clear()
@patch("ctrmgrd.swsscommon.DBConnector")
@@ -450,6 +457,7 @@ def test_feature(self, mock_kube_wr, mock_kube_join, mock_kube_rst, mock_subs,
ret = common_test.check_tables_returned()
assert ret == 0
+ self.clear()
@patch("ctrmgrd.swsscommon.DBConnector")
@@ -486,3 +494,4 @@ def test_labels(self, mock_kube_wr, mock_kube_join, mock_kube_rst, mock_subs,
ret = common_test.check_kube_actions()
assert ret == 0
+ self.clear()
diff --git a/src/sonic-ctrmgrd/tests/http_proxy.conf b/src/sonic-ctrmgrd/tests/http_proxy.conf
new file mode 100644
index 000000000000..4947352418a5
--- /dev/null
+++ b/src/sonic-ctrmgrd/tests/http_proxy.conf
@@ -0,0 +1,2 @@
+[Service]
+Environment="HTTP_PROXY=http://172.16.1.1:3128/"
diff --git a/src/sonic-ctrmgrd/tests/no_proxy.conf b/src/sonic-ctrmgrd/tests/no_proxy.conf
new file mode 100644
index 000000000000..ffdfa671bacb
--- /dev/null
+++ b/src/sonic-ctrmgrd/tests/no_proxy.conf
@@ -0,0 +1,2 @@
+[Service]
+Environment="NO_PROXY=10.10.10.10"
diff --git a/src/sonic-frr/patch/0009-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch b/src/sonic-frr/patch/0009-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch
new file mode 100644
index 000000000000..82a1b26fb98f
--- /dev/null
+++ b/src/sonic-frr/patch/0009-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch
@@ -0,0 +1,44 @@
+From 4b45abcdb107c8c5d58fd63a2616c54c800305b3 Mon Sep 17 00:00:00 2001
+From: Akhilesh Samineni
+Date: Mon, 5 Apr 2021 13:21:40 -0700
+Subject: [PATCH] Link local scope was not set while binding socket with local
+ address causing socket errors for bgp ipv6 link local neighbors.
+
+---
+ bgpd/bgp_network.c | 5 +++++
+ bgpd/bgp_zebra.c | 3 +++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c
+index 6a5c2c4b3..d7047a154 100644
+--- a/bgpd/bgp_network.c
++++ b/bgpd/bgp_network.c
+@@ -556,6 +556,11 @@ static int bgp_update_address(struct interface *ifp, const union sockunion *dst,
+ return 1;
+
+ prefix2sockunion(sel, addr);
++
++ if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6.sin6_addr)) {
++ addr->sin6.sin6_scope_id = ifp->ifindex;
++ }
++
+ return 0;
+ }
+
+diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
+index e42d6ee26..8e9fa8903 100644
+--- a/bgpd/bgp_zebra.c
++++ b/bgpd/bgp_zebra.c
+@@ -814,6 +814,9 @@ bool bgp_zebra_nexthop_set(union sockunion *local, union sockunion *remote,
+ ? peer->conf_if
+ : peer->ifname,
+ peer->bgp->vrf_id);
++ else if (peer->update_if)
++ ifp = if_lookup_by_name(peer->update_if,
++ peer->bgp->vrf_id);
+ } else if (peer->update_if)
+ ifp = if_lookup_by_name(peer->update_if,
+ peer->bgp->vrf_id);
+--
+2.18.0
+
diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series
index 29d350814927..2837a79f249a 100644
--- a/src/sonic-frr/patch/series
+++ b/src/sonic-frr/patch/series
@@ -6,3 +6,4 @@
0007-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch
0008-Add-support-of-bgp-l3vni-evpn.patch
0009-Add-bgp-bestpath-peer-type-multipath-relax.patch
+0009-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch
diff --git a/src/sonic-host-services/scripts/caclmgrd b/src/sonic-host-services/scripts/caclmgrd
index 8babd666d593..2d8b0b028f84 100755
--- a/src/sonic-host-services/scripts/caclmgrd
+++ b/src/sonic-host-services/scripts/caclmgrd
@@ -18,7 +18,7 @@ try:
import threading
import time
- from sonic_py_common import daemon_base, device_info
+ from sonic_py_common import daemon_base, device_info, multi_asic
from swsscommon import swsscommon
except ImportError as err:
raise ImportError("%s - required module not found" % str(err))
@@ -116,7 +116,8 @@ class ControlPlaneAclManager(daemon_base.DaemonBase):
if 'subtype' in metadata['localhost'] and metadata['localhost']['subtype'] == 'DualToR':
self.DualToR = True
- namespaces = device_info.get_all_namespaces()
+ namespaces = multi_asic.get_all_namespaces()
+
for front_asic_namespace in namespaces['front_ns']:
self.update_thread[front_asic_namespace] = None
self.lock[front_asic_namespace] = threading.Lock()
diff --git a/src/sonic-host-services/scripts/hostcfgd b/src/sonic-host-services/scripts/hostcfgd
index b9f3031d78e3..95c8e1221407 100755
--- a/src/sonic-host-services/scripts/hostcfgd
+++ b/src/sonic-host-services/scripts/hostcfgd
@@ -236,23 +236,38 @@ class FeatureHandler(object):
return feature_names, feature_suffixes
+ def get_systemd_unit_state(self, unit):
+ """ Returns service configuration """
+
+ cmd = "sudo systemctl show {} --property UnitFileState".format(unit)
+ proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ stdout, stderr = proc.communicate()
+ if proc.returncode != 0:
+ syslog.syslog(syslog.LOG_ERR, "Failed to get status of {}: rc={} stderr={}".format(unit, proc.returncode, stderr))
+ return 'invalid' # same as systemd's "invalid indicates that it could not be determined whether the unit file is enabled".
+
+ props = dict([line.split("=") for line in stdout.decode().strip().splitlines()])
+ return props["UnitFileState"]
+
+
def enable_feature(self, feature):
cmds = []
feature_names, feature_suffixes = self.get_feature_attribute(feature)
for feature_name in feature_names:
# Check if it is already enabled, if yes skip the system call
- cmd = "sudo systemctl status {}.{} | grep Loaded".format(feature_name, feature_suffixes[-1])
- proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- (stdout, stderr) = proc.communicate()
- if "enabled" in str(stdout):
+ unit_file_state = self.get_systemd_unit_state("{}.{}".format(feature_name, feature_suffixes[-1]))
+ if unit_file_state == "enabled":
continue
for suffix in feature_suffixes:
cmds.append("sudo systemctl unmask {}.{}".format(feature_name, suffix))
+
# If feature has timer associated with it, start/enable corresponding systemd .timer unit
# otherwise, start/enable corresponding systemd .service unit
+
cmds.append("sudo systemctl enable {}.{}".format(feature_name, feature_suffixes[-1]))
cmds.append("sudo systemctl start {}.{}".format(feature_name, feature_suffixes[-1]))
+
for cmd in cmds:
syslog.syslog(syslog.LOG_INFO, "Running cmd: '{}'".format(cmd))
try:
@@ -267,10 +282,8 @@ class FeatureHandler(object):
feature_names, feature_suffixes = self.get_feature_attribute(feature)
for feature_name in feature_names:
# Check if it is already disabled, if yes skip the system call
- cmd = "sudo systemctl status {}.{} | grep Loaded".format(feature_name, feature_suffixes[-1])
- proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- (stdout, stderr) = proc.communicate()
- if "disabled" in str(stdout) or "masked" in str(stdout):
+ unit_file_state = self.get_systemd_unit_state("{}.{}".format(feature_name, feature_suffixes[-1]))
+ if unit_file_state in ("disabled", "masked"):
continue
for suffix in reversed(feature_suffixes):
diff --git a/src/sonic-host-services/tests/hostcfgd/test_vectors.py b/src/sonic-host-services/tests/hostcfgd/test_vectors.py
index 3a7baa02ed43..f70e4a11c457 100644
--- a/src/sonic-host-services/tests/hostcfgd/test_vectors.py
+++ b/src/sonic-host-services/tests/hostcfgd/test_vectors.py
@@ -29,7 +29,7 @@
"has_timer": "False",
"high_mem_alert": "disabled",
"set_owner": "kube",
- "state": "enabled"
+ "state": "{% if not (DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined and DEVICE_METADATA['localhost']['type'] != 'ToRRouter') %}enabled{% else %}disabled{% endif %}"
},
"mux": {
"auto_restart": "enabled",
@@ -125,7 +125,7 @@
"has_timer": "False",
"high_mem_alert": "disabled",
"set_owner": "kube",
- "state": "enabled"
+ "state": "{% if not (DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined and DEVICE_METADATA['localhost']['type'] != 'ToRRouter') %}enabled{% else %}disabled{% endif %}"
},
"mux": {
"auto_restart": "enabled",
@@ -157,7 +157,7 @@
"has_timer": "False",
"high_mem_alert": "disabled",
"set_owner": "kube",
- "state": "enabled"
+ "state": "disabled"
},
"mux": {
"auto_restart": "enabled",
@@ -181,9 +181,6 @@
},
},
"expected_subprocess_calls": [
- call("sudo systemctl unmask dhcp_relay.service", shell=True),
- call("sudo systemctl enable dhcp_relay.service", shell=True),
- call("sudo systemctl start dhcp_relay.service", shell=True),
call("sudo systemctl stop mux.service", shell=True),
call("sudo systemctl disable mux.service", shell=True),
call("sudo systemctl mask mux.service", shell=True),
@@ -213,6 +210,99 @@
"memory": "0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M"
}
},
+ "FEATURE": {
+ "dhcp_relay": {
+ "auto_restart": "enabled",
+ "has_global_scope": "True",
+ "has_per_asic_scope": "False",
+ "has_timer": "False",
+ "high_mem_alert": "disabled",
+ "set_owner": "kube",
+ "state": "{% if not (DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined and DEVICE_METADATA['localhost']['type'] != 'ToRRouter') %}enabled{% else %}disabled{% endif %}"
+ },
+ "mux": {
+ "auto_restart": "enabled",
+ "has_global_scope": "True",
+ "has_per_asic_scope": "False",
+ "has_timer": "False",
+ "high_mem_alert": "disabled",
+ "set_owner": "local",
+ "state": "{% if 'subtype' in DEVICE_METADATA['localhost'] and DEVICE_METADATA['localhost']['subtype'] == 'DualToR' %}enabled{% else %}always_disabled{% endif %}"
+ },
+ "telemetry": {
+ "auto_restart": "enabled",
+ "has_global_scope": "True",
+ "has_per_asic_scope": "False",
+ "has_timer": "True",
+ "high_mem_alert": "disabled",
+ "set_owner": "kube",
+ "state": "enabled",
+ "status": "enabled"
+ },
+ },
+ },
+ "expected_config_db": {
+ "FEATURE": {
+ "dhcp_relay": {
+ "auto_restart": "enabled",
+ "has_global_scope": "True",
+ "has_per_asic_scope": "False",
+ "has_timer": "False",
+ "high_mem_alert": "disabled",
+ "set_owner": "kube",
+ "state": "disabled"
+ },
+ "mux": {
+ "auto_restart": "enabled",
+ "has_global_scope": "True",
+ "has_per_asic_scope": "False",
+ "has_timer": "False",
+ "high_mem_alert": "disabled",
+ "set_owner": "local",
+ "state": "always_disabled"
+ },
+ "telemetry": {
+ "auto_restart": "enabled",
+ "has_global_scope": "True",
+ "has_per_asic_scope": "False",
+ "has_timer": "True",
+ "high_mem_alert": "disabled",
+ "set_owner": "kube",
+ "state": "enabled",
+ "status": "enabled"
+ },
+ },
+ },
+ "expected_subprocess_calls": [
+ call("sudo systemctl stop mux.service", shell=True),
+ call("sudo systemctl disable mux.service", shell=True),
+ call("sudo systemctl mask mux.service", shell=True),
+ call("sudo systemctl unmask telemetry.service", shell=True),
+ call("sudo systemctl unmask telemetry.timer", shell=True),
+ call("sudo systemctl enable telemetry.timer", shell=True),
+ call("sudo systemctl start telemetry.timer", shell=True),
+ ],
+ "popen_attributes": {
+ 'communicate.return_value': ('output', 'error')
+ },
+ },
+ ],
+ [
+ "SingleToRCase_DHCP_Relay_Enabled",
+ {
+ "config_db": {
+ "DEVICE_METADATA": {
+ "localhost": {
+ "type": "ToR",
+ }
+ },
+ "KDUMP": {
+ "config": {
+ "enabled": "false",
+ "num_dumps": "3",
+ "memory": "0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M"
+ }
+ },
"FEATURE": {
"dhcp_relay": {
"auto_restart": "enabled",
@@ -318,7 +408,7 @@
"has_timer": "False",
"high_mem_alert": "disabled",
"set_owner": "kube",
- "state": "enabled"
+ "state": "{% if not (DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined and DEVICE_METADATA['localhost']['type'] is defined and DEVICE_METADATA['localhost']['type'] != 'ToRRouter') %}enabled{% else %}disabled{% endif %}"
},
"mux": {
"auto_restart": "enabled",
diff --git a/src/sonic-linux-kernel b/src/sonic-linux-kernel
index fcf7cdcc4cb9..14a4212e279e 160000
--- a/src/sonic-linux-kernel
+++ b/src/sonic-linux-kernel
@@ -1 +1 @@
-Subproject commit fcf7cdcc4cb9d566324b25c4690ce9483cc3342c
+Subproject commit 14a4212e279e579048afe28247e80420e7b46de6
diff --git a/src/sonic-platform-common b/src/sonic-platform-common
index 7670b49927cc..e168f1d46a9f 160000
--- a/src/sonic-platform-common
+++ b/src/sonic-platform-common
@@ -1 +1 @@
-Subproject commit 7670b49927ccddf7d090442dc3aa348cccb0c02b
+Subproject commit e168f1d46a9f1c30efc40065b3e80321c0f1ad9b
diff --git a/src/sonic-platform-daemons b/src/sonic-platform-daemons
index 53639ded1ec5..66e78174a726 160000
--- a/src/sonic-platform-daemons
+++ b/src/sonic-platform-daemons
@@ -1 +1 @@
-Subproject commit 53639ded1ec5a5d534f8f571dd7d7aa664ba086c
+Subproject commit 66e78174a7269cccc3da97b2b0f3846b69d6b8e7
diff --git a/src/sonic-platform-pde b/src/sonic-platform-pde
new file mode 160000
index 000000000000..f18ebc297d8b
--- /dev/null
+++ b/src/sonic-platform-pde
@@ -0,0 +1 @@
+Subproject commit f18ebc297d8b751c162dffd120d284d784aa977d
diff --git a/src/sonic-py-common/sonic_py_common/multi_asic.py b/src/sonic-py-common/sonic_py_common/multi_asic.py
index 1666fb47df1c..f6daba8e84a2 100644
--- a/src/sonic-py-common/sonic_py_common/multi_asic.py
+++ b/src/sonic-py-common/sonic_py_common/multi_asic.py
@@ -3,9 +3,7 @@
import subprocess
from natsort import natsorted
-from swsssdk import ConfigDBConnector
-from swsssdk import SonicDBConfig
-from swsssdk import SonicV2Connector
+from swsscommon import swsscommon
from .device_info import CONTAINER_PLATFORM_PATH
from .device_info import HOST_DEVICE_PATH
@@ -39,8 +37,7 @@ def connect_config_db_for_ns(namespace=DEFAULT_NAMESPACE):
Returns:
handle to the config_db for a namespace
"""
- SonicDBConfig.load_sonic_global_db_config()
- config_db = ConfigDBConnector(namespace=namespace)
+ config_db = swsscommon.ConfigDBConnector(namespace=namespace)
config_db.connect()
return config_db
@@ -58,8 +55,7 @@ def connect_to_all_dbs_for_ns(namespace=DEFAULT_NAMESPACE):
Returns:
handle to all the dbs for a namespaces
"""
- SonicDBConfig.load_sonic_global_db_config()
- db = SonicV2Connector(namespace=namespace)
+ db = swsscommon.SonicV2Connector(namespace=namespace)
for db_id in db.get_db_list():
db.connect(db_id)
return db
diff --git a/src/sonic-sairedis b/src/sonic-sairedis
index 0e2105a8e5c6..84fa50a88f7b 160000
--- a/src/sonic-sairedis
+++ b/src/sonic-sairedis
@@ -1 +1 @@
-Subproject commit 0e2105a8e5c6e14c3551ec2bf65b1ad41bb5060b
+Subproject commit 84fa50a88f7bd9b196018d89741fcf95ade0f983
diff --git a/src/sonic-snmpagent b/src/sonic-snmpagent
index 28b9dfd3a294..43b5e1abefb7 160000
--- a/src/sonic-snmpagent
+++ b/src/sonic-snmpagent
@@ -1 +1 @@
-Subproject commit 28b9dfd3a294904150b2d33bd3ff35a1a637d28d
+Subproject commit 43b5e1abefb7a1690e21d07eaa97479478bd5454
diff --git a/src/sonic-swss b/src/sonic-swss
index d594c47b9d7e..7aca82df3b56 160000
--- a/src/sonic-swss
+++ b/src/sonic-swss
@@ -1 +1 @@
-Subproject commit d594c47b9d7e8270a0b517834359ebca5799dfe4
+Subproject commit 7aca82df3b56276625ce3d70ffb45b849003b0d8
diff --git a/src/sonic-swss-common b/src/sonic-swss-common
index 11db9ba6403b..e95a4666ad90 160000
--- a/src/sonic-swss-common
+++ b/src/sonic-swss-common
@@ -1 +1 @@
-Subproject commit 11db9ba6403b92effd060bea33b4ca9812465f60
+Subproject commit e95a4666ad90f13c3675efb9238f273df5232e91
diff --git a/src/sonic-telemetry b/src/sonic-telemetry
index 6df988cce714..0443e6605025 160000
--- a/src/sonic-telemetry
+++ b/src/sonic-telemetry
@@ -1 +1 @@
-Subproject commit 6df988cce714ab7be3a914069ad24d30d153da13
+Subproject commit 0443e66050256a87f8e92db7cd3c36cc139ebe14
diff --git a/src/sonic-utilities b/src/sonic-utilities
index 186d851380f2..54b74a24b78d 160000
--- a/src/sonic-utilities
+++ b/src/sonic-utilities
@@ -1 +1 @@
-Subproject commit 186d851380f2807222daceecb54048ce8634fb89
+Subproject commit 54b74a24b78d52af5f758216e74c4ed74db740e5
diff --git a/src/sonic-yang-mgmt/sonic_yang.py b/src/sonic-yang-mgmt/sonic_yang.py
index ffc2e687ea91..ba982f8556e8 100644
--- a/src/sonic-yang-mgmt/sonic_yang.py
+++ b/src/sonic-yang-mgmt/sonic_yang.py
@@ -526,7 +526,7 @@ def find_data_dependencies(self, data_xpath):
schema_node = ly.Schema_Node_Leaf(data_node.schema())
backlinks = schema_node.backlinks()
- if backlinks.number() > 0:
+ if backlinks is not None and backlinks.number() > 0:
for link in backlinks.schema():
node_set = node.find_path(link.path())
for data_set in node_set.data():
diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_SonicYang.json b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_SonicYang.json
index f3e0c46f76b2..b62322d50bdb 100644
--- a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_SonicYang.json
+++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_SonicYang.json
@@ -1,144 +1,285 @@
{
- "yang_dir":"./tests/libyang-python-tests/sample-yang-models/",
- "data_file":"./tests/libyang-python-tests/config_data.json",
- "data_merge_file":"./tests/libyang-python-tests/config_data_merge.json",
- "modules":[
- {"file":"test-head.yang", "module":"test-head"},
- {"file":"test-port.yang", "module":"test-port"},
- {"file":"test-acl.yang", "module":"test-acl"},
- {"file":"test-interface.yang", "module":"test-interface"},
- {"file":"test-portchannel.yang", "module":"test-portchannel"},
- {"file":"test-vlan.yang", "module":"test-vlan"}
- ],
-
- "merged_nodes":[
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed", "value":"25000"},
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='200'][ip-prefix='2000:f500:45:6708::/64']/family",
- "value":"IPv6"}
- ],
-
- "new_nodes":[
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']/alias", "value":"Ethernet10_alias"},
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']/speed", "value":"5000"},
- {"xpath":"/test-acl:acl/ACL_RULE/ACL_RULE_LIST[ACL_TABLE_NAME='PACL-test'][RULE_NAME='rule_20']/RULE_NAME",
- "value":"rule_20"}
- ],
-
- "data_nodes":[
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/alias", "valid":"True"},
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet20']/alias", "valid":"False"},
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE", "valid":"True"},
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST", "valid":"False"},
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']", "valid":"True"}
- ],
-
- "set_nodes":[
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed", "value":"10000"},
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/mtu", "value":"1500"},
- {"xpath":"/test-vlan:vlan/VLAN/VLAN_LIST[vlanid='111']/description", "value":"server_vlan111"}
- ],
-
- "node_values":[
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed", "value":"25000"},
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/family",
- "value":"IPv6"}
- ],
-
- "schema_nodes":[
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/family",
- "value":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:family"},
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed",
- "value":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:speed"}
- ],
-
- "delete_nodes":[
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed", "valid":"False"},
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/mtu", "valid":"True"},
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet20']/mtu", "valid":"False"}
- ],
-
- "dependencies":[
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet8']/port_name",
- "dependencies":
- ["/test-acl:acl/ACL_TABLE/ACL_TABLE_LIST[ACL_TABLE_NAME='PACL-V6']/ports[.='Ethernet8']",
- "/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='10.1.1.64/26']/interface",
- "/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='2000:f500:40:a749::/126']/interface"]}
- ],
- "schema_dependencies":[
- {"xpath":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name",
- "schema_dependencies":
- ["/test-acl:acl/test-acl:ACL_TABLE/test-acl:ACL_TABLE_LIST/test-acl:ports",
- "/test-portchannel:portchannel/test-portchannel:PORTCHANNEL/test-portchannel:PORTCHANNEL_LIST/test-portchannel:members",
- "/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface",
- "/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port"]}
- ],
- "members":[
- {"xpath":"/test-port:port/PORT/PORT_LIST",
- "members":
- ["/test-port:port/PORT/PORT_LIST[port_name='Ethernet0']",
- "/test-port:port/PORT/PORT_LIST[port_name='Ethernet1']",
- "/test-port:port/PORT/PORT_LIST[port_name='Ethernet2']",
- "/test-port:port/PORT/PORT_LIST[port_name='Ethernet3']",
- "/test-port:port/PORT/PORT_LIST[port_name='Ethernet4']",
- "/test-port:port/PORT/PORT_LIST[port_name='Ethernet5']",
- "/test-port:port/PORT/PORT_LIST[port_name='Ethernet6']",
- "/test-port:port/PORT/PORT_LIST[port_name='Ethernet7']",
- "/test-port:port/PORT/PORT_LIST[port_name='Ethernet8']",
- "/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']",
- "/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']",
- "/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']"]}
- ],
-
- "parents":[
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/family",
- "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']"},
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/scope",
- "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"},
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/vlanid",
- "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"},
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/ip-prefix",
- "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"},
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/family",
- "parent":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']"},
- {"xpath":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed",
- "parent":"/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']"}
- ],
- "prefix":[
- {"module_name":"test-head", "module_prefix":"head"},
- {"module_name":"test-port", "module_prefix":"port"},
- {"module_name":"test-acl", "module_prefix":"acl"},
- {"module_name":"test-interface", "module_prefix":"intf"},
- {"module_name":"test-portchannel", "module_prefix":"lag"},
- {"module_name":"test-vlan", "module_prefix":"vlan"}
- ],
- "data_type":[
- {"xpath":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name", "data_type":"LY_TYPE_STRING"},
- {"xpath":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid", "data_type":"LY_TYPE_LEAFREF"}
- ],
- "leafref_type":[
- {"xpath":"/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/vlanid", "data_type":"LY_TYPE_UINT16"},
- {"xpath":"/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='2000:f500:40:a749::/126']/interface", "data_type":"LY_TYPE_STRING"},
- {"xpath":"/test-vlan:vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='111'][port='Ethernet0']/port", "data_type":"LY_TYPE_STRING"},
- {"xpath":"/test-vlan:vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='111'][port='Ethernet0']/vlanid", "data_type":"LY_TYPE_UINT16"}
- ],
- "leafref_type_schema":[
- {"xpath":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid",
- "data_type":"LY_TYPE_UINT16"},
- {"xpath":"/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface",
- "data_type":"LY_TYPE_STRING"},
- {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port",
- "data_type":"LY_TYPE_STRING"},
- {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:vlanid",
- "data_type":"LY_TYPE_UINT16"}
- ],
- "leafref_path":[
- {"xpath":"/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid",
- "leafref_path":"../../../VLAN/VLAN_LIST/vlanid"},
- {"xpath":"/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface",
- "leafref_path":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name"},
- {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port",
- "leafref_path":"/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name"},
- {"xpath":"/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:vlanid",
- "leafref_path":"../../../VLAN/VLAN_LIST/vlanid"}
- ]
+ "data_file" : "./tests/libyang-python-tests/config_data.json",
+ "data_merge_file" : "./tests/libyang-python-tests/config_data_merge.json",
+ "data_nodes" : [
+ {
+ "valid" : "True",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/alias"
+ },
+ {
+ "valid" : "False",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet20']/alias"
+ },
+ {
+ "valid" : "True",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE"
+ },
+ {
+ "valid" : "False",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST"
+ },
+ {
+ "valid" : "True",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']"
+ }
+ ],
+ "data_type" : [
+ {
+ "data_type" : "LY_TYPE_STRING",
+ "xpath" : "/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name"
+ },
+ {
+ "data_type" : "LY_TYPE_LEAFREF",
+ "xpath" : "/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid"
+ }
+ ],
+ "delete_nodes" : [
+ {
+ "valid" : "False",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed"
+ },
+ {
+ "valid" : "True",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/mtu"
+ },
+ {
+ "valid" : "False",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet20']/mtu"
+ }
+ ],
+ "dependencies" : [
+ {
+ "dependencies" : [
+ "/test-acl:acl/ACL_TABLE/ACL_TABLE_LIST[ACL_TABLE_NAME='PACL-V6']/ports[.='Ethernet8']",
+ "/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='10.1.1.64/26']/interface",
+ "/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='2000:f500:40:a749::/126']/interface"
+ ],
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet8']/port_name"
+ },
+ {
+ "dependencies" : [],
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet8']/alias"
+ }
+ ],
+ "leafref_path" : [
+ {
+ "leafref_path" : "../../../VLAN/VLAN_LIST/vlanid",
+ "xpath" : "/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid"
+ },
+ {
+ "leafref_path" : "/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name",
+ "xpath" : "/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface"
+ },
+ {
+ "leafref_path" : "/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name",
+ "xpath" : "/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port"
+ },
+ {
+ "leafref_path" : "../../../VLAN/VLAN_LIST/vlanid",
+ "xpath" : "/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:vlanid"
+ }
+ ],
+ "leafref_type" : [
+ {
+ "data_type" : "LY_TYPE_UINT16",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/vlanid"
+ },
+ {
+ "data_type" : "LY_TYPE_STRING",
+ "xpath" : "/test-interface:interface/INTERFACE/INTERFACE_LIST[interface='Ethernet8'][ip-prefix='2000:f500:40:a749::/126']/interface"
+ },
+ {
+ "data_type" : "LY_TYPE_STRING",
+ "xpath" : "/test-vlan:vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='111'][port='Ethernet0']/port"
+ },
+ {
+ "data_type" : "LY_TYPE_UINT16",
+ "xpath" : "/test-vlan:vlan/VLAN_MEMBER/VLAN_MEMBER_LIST[vlanid='111'][port='Ethernet0']/vlanid"
+ }
+ ],
+ "leafref_type_schema" : [
+ {
+ "data_type" : "LY_TYPE_UINT16",
+ "xpath" : "/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:vlanid"
+ },
+ {
+ "data_type" : "LY_TYPE_STRING",
+ "xpath" : "/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface"
+ },
+ {
+ "data_type" : "LY_TYPE_STRING",
+ "xpath" : "/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port"
+ },
+ {
+ "data_type" : "LY_TYPE_UINT16",
+ "xpath" : "/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:vlanid"
+ }
+ ],
+ "members" : [
+ {
+ "members" : [
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet0']",
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet1']",
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet2']",
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet3']",
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet4']",
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet5']",
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet6']",
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet7']",
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet8']",
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']",
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']",
+ "/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']"
+ ],
+ "xpath" : "/test-port:port/PORT/PORT_LIST"
+ }
+ ],
+ "merged_nodes" : [
+ {
+ "value" : "25000",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed"
+ },
+ {
+ "value" : "IPv6",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='200'][ip-prefix='2000:f500:45:6708::/64']/family"
+ }
+ ],
+ "modules" : [
+ {
+ "file" : "test-head.yang",
+ "module" : "test-head"
+ },
+ {
+ "file" : "test-port.yang",
+ "module" : "test-port"
+ },
+ {
+ "file" : "test-acl.yang",
+ "module" : "test-acl"
+ },
+ {
+ "file" : "test-interface.yang",
+ "module" : "test-interface"
+ },
+ {
+ "file" : "test-portchannel.yang",
+ "module" : "test-portchannel"
+ },
+ {
+ "file" : "test-vlan.yang",
+ "module" : "test-vlan"
+ }
+ ],
+ "new_nodes" : [
+ {
+ "value" : "Ethernet10_alias",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']/alias"
+ },
+ {
+ "value" : "5000",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet12']/speed"
+ },
+ {
+ "value" : "rule_20",
+ "xpath" : "/test-acl:acl/ACL_RULE/ACL_RULE_LIST[ACL_TABLE_NAME='PACL-test'][RULE_NAME='rule_20']/RULE_NAME"
+ }
+ ],
+ "node_values" : [
+ {
+ "value" : "25000",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed"
+ },
+ {
+ "value" : "IPv6",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/family"
+ }
+ ],
+ "parents" : [
+ {
+ "parent" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='2000:f500:45:6709::/64']/family"
+ },
+ {
+ "parent" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/scope"
+ },
+ {
+ "parent" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/vlanid"
+ },
+ {
+ "parent" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/ip-prefix"
+ },
+ {
+ "parent" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/family"
+ },
+ {
+ "parent" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed"
+ }
+ ],
+ "prefix" : [
+ {
+ "module_name" : "test-head",
+ "module_prefix" : "head"
+ },
+ {
+ "module_name" : "test-port",
+ "module_prefix" : "port"
+ },
+ {
+ "module_name" : "test-acl",
+ "module_prefix" : "acl"
+ },
+ {
+ "module_name" : "test-interface",
+ "module_prefix" : "intf"
+ },
+ {
+ "module_name" : "test-portchannel",
+ "module_prefix" : "lag"
+ },
+ {
+ "module_name" : "test-vlan",
+ "module_prefix" : "vlan"
+ }
+ ],
+ "schema_dependencies" : [
+ {
+ "schema_dependencies" : [
+ "/test-acl:acl/test-acl:ACL_TABLE/test-acl:ACL_TABLE_LIST/test-acl:ports",
+ "/test-portchannel:portchannel/test-portchannel:PORTCHANNEL/test-portchannel:PORTCHANNEL_LIST/test-portchannel:members",
+ "/test-interface:interface/test-interface:INTERFACE/test-interface:INTERFACE_LIST/test-interface:interface",
+ "/test-vlan:vlan/test-vlan:VLAN_MEMBER/test-vlan:VLAN_MEMBER_LIST/test-vlan:port"
+ ],
+ "xpath" : "/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:port_name"
+ }
+ ],
+ "schema_nodes" : [
+ {
+ "value" : "/test-vlan:vlan/test-vlan:VLAN_INTERFACE/test-vlan:VLAN_INTERFACE_LIST/test-vlan:family",
+ "xpath" : "/test-vlan:vlan/VLAN_INTERFACE/VLAN_INTERFACE_LIST[vlanid='111'][ip-prefix='10.1.1.64/26']/family"
+ },
+ {
+ "value" : "/test-port:port/test-port:PORT/test-port:PORT_LIST/test-port:speed",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/speed"
+ }
+ ],
+ "set_nodes" : [
+ {
+ "value" : "10000",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet10']/speed"
+ },
+ {
+ "value" : "1500",
+ "xpath" : "/test-port:port/PORT/PORT_LIST[port_name='Ethernet9']/mtu"
+ },
+ {
+ "value" : "server_vlan111",
+ "xpath" : "/test-vlan:vlan/VLAN/VLAN_LIST[vlanid='111']/description"
+ }
+ ],
+ "yang_dir" : "./tests/libyang-python-tests/sample-yang-models/"
}
diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py
index ec657fae234f..51bc30c89b73 100644
--- a/src/sonic-yang-models/setup.py
+++ b/src/sonic-yang-models/setup.py
@@ -65,6 +65,7 @@
'./yang-models/sonic-route-common.yang',
'./yang-models/sonic-route-map.yang',
'./yang-models/sonic-routing-policy-sets.yang',
+ './yang-models/sonic-sflow.yang',
'./yang-models/sonic-system-aaa.yang',
'./yang-models/sonic-system-tacacs.yang',
'./yang-models/sonic-types.yang',
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 95af4372618c..5f354328794b 100644
--- a/src/sonic-yang-models/tests/files/sample_config_db.json
+++ b/src/sonic-yang-models/tests/files/sample_config_db.json
@@ -630,6 +630,93 @@
]
}
},
+ "PBH_HASH_FIELD": {
+ "inner_ip_proto": {
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": "1"
+ },
+ "inner_l4_dst_port": {
+ "hash_field": "INNER_L4_DST_PORT",
+ "sequence_id": "2"
+ },
+ "inner_l4_src_port": {
+ "hash_field": "INNER_L4_SRC_PORT",
+ "sequence_id": "2"
+ },
+ "inner_dst_ipv4": {
+ "hash_field": "INNER_DST_IPV4",
+ "ip_mask": "255.0.0.0",
+ "sequence_id": "3"
+ },
+ "inner_src_ipv4": {
+ "hash_field": "INNER_SRC_IPV4",
+ "ip_mask": "0.0.0.255",
+ "sequence_id": "3"
+ },
+ "inner_dst_ipv6": {
+ "hash_field": "INNER_DST_IPV6",
+ "ip_mask": "ffff::",
+ "sequence_id": "4"
+ },
+ "inner_src_ipv6": {
+ "hash_field": "INNER_SRC_IPV6",
+ "ip_mask": "::ffff",
+ "sequence_id": "4"
+ }
+ },
+ "PBH_HASH": {
+ "inner_v4_hash": {
+ "hash_field_list": [
+ "inner_ip_proto",
+ "inner_l4_dst_port",
+ "inner_l4_src_port",
+ "inner_dst_ipv4",
+ "inner_src_ipv4"
+ ]
+ },
+ "inner_v6_hash": {
+ "hash_field_list": [
+ "inner_ip_proto",
+ "inner_l4_dst_port",
+ "inner_l4_src_port",
+ "inner_dst_ipv6",
+ "inner_src_ipv6"
+ ]
+ }
+ },
+ "PBH_RULE": {
+ "pbh_table|nvgre": {
+ "priority": "1",
+ "ether_type": "0x0800",
+ "ip_protocol": "0x2f",
+ "gre_key": "0x2500/0xffffff00",
+ "inner_ether_type": "0x86dd",
+ "hash": "inner_v6_hash",
+ "packet_action": "SET_ECMP_HASH",
+ "flow_counter": "DISABLED"
+ },
+ "pbh_table|vxlan": {
+ "priority": "2",
+ "ether_type": "0x0800",
+ "ip_protocol": "0x11",
+ "l4_dst_port": "0x12b5",
+ "inner_ether_type": "0x0800",
+ "hash": "inner_v4_hash",
+ "packet_action": "SET_LAG_HASH",
+ "flow_counter": "ENABLED"
+ }
+ },
+ "PBH_TABLE": {
+ "pbh_table": {
+ "interface_list": [
+ "Ethernet0",
+ "Ethernet4",
+ "PortChannel0003",
+ "PortChannel0004"
+ ],
+ "description": "NVGRE and VxLAN"
+ }
+ },
"INTERFACE": {
"Ethernet112": {},
"Ethernet14": {},
@@ -792,6 +879,36 @@
"polling_interval": "0"
}
},
+
+ "SFLOW_COLLECTOR": {
+ "collector1": {
+ "collector_ip": "10.100.12.13",
+ "collector_port": "6343"
+ },
+ "collector2": {
+ "collector_ip": "10.144.1.2"
+ }
+ },
+
+ "SFLOW_SESSION": {
+ "Ethernet0": {
+ "admin_state": "down",
+ "sample_rate": "40000"
+ },
+ "Ethernet16": {
+ "admin_state": "up",
+ "sample_rate": "32768"
+ }
+ },
+
+ "SFLOW" : {
+ "global": {
+ "admin_state": "up",
+ "polling_interval": "20",
+ "agent_id": "Ethernet0"
+ }
+ },
+
"AAA": {
"authentication": {
"login": "local"
@@ -925,6 +1042,7 @@
"trap_group": "queue1_group1"
}
}
+
},
"SAMPLE_CONFIG_DB_UNKNOWN": {
diff --git a/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py
index 5ed4ea3f6daf..355c9086a6fb 100644
--- a/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py
+++ b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py
@@ -46,6 +46,8 @@ def initTest(self):
'Mandatory': ['required element', 'Missing'],
'Verify': ['verified'],
'Range': ['does not satisfy', 'range'],
+ 'MinElements': ['Too few'],
+ 'MaxElements': ['Too many'],
'None': []
}
diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/pbh.json b/src/sonic-yang-models/tests/yang_model_tests/tests/pbh.json
new file mode 100644
index 000000000000..cb3a0a99fae4
--- /dev/null
+++ b/src/sonic-yang-models/tests/yang_model_tests/tests/pbh.json
@@ -0,0 +1,107 @@
+{
+ "PBH_TABLE_RULE_HASH_HASH_FIELD_VALID": {
+ "desc": "Configure PBH_TABLE, PBH_RULE, PBH_HASH and PBH_HASH_FIELD."
+ },
+ "PBH_TABLE_INVALID_INTERFACE": {
+ "desc": "Configure non-existing PORT/PORTCHANNEL in PBH_TABLE.",
+ "eStrKey": "InvalidValue"
+ },
+ "PBH_TABLE_EMPTY_INTERFACE_LIST": {
+ "desc": "Configure empty INTERFACE_LIST in PBH_TABLE.",
+ "eStrKey": "MinElements"
+ },
+ "PBH_TABLE_INVALID_DESCRIPTION": {
+ "desc": "Configure invalid DESCRIPTION in PBH_TABLE.",
+ "eStrKey": "Range"
+ },
+ "PBH_RULE_INVALID_TABLE": {
+ "desc": "Configure non-existing PBH_TABLE in PBH_RULE.",
+ "eStrKey": "LeafRef"
+ },
+ "PBH_RULE_INVALID_PRIORITY": {
+ "desc": "Configure invalid PRIORITY in PBH_RULE.",
+ "eStrKey": "InvalidValue"
+ },
+ "PBH_RULE_INVALID_GRE_KEY": {
+ "desc": "Configure invalid GRE_KEY in PBH_RULE.",
+ "eStrKey": "Pattern"
+ },
+ "PBH_RULE_INVALID_ETHER_TYPE": {
+ "desc": "Configure invalid ETHER_TYPE in PBH_RULE.",
+ "eStrKey": "Pattern"
+ },
+ "PBH_RULE_INVALID_IP_PROTOCOL": {
+ "desc": "Configure invalid IP_PROTOCOL in PBH_RULE.",
+ "eStrKey": "Pattern"
+ },
+ "PBH_RULE_INVALID_IPV6_NEXT_HEADER": {
+ "desc": "Configure invalid IPV6_NEXT_HEADER in PBH_RULE.",
+ "eStrKey": "Pattern"
+ },
+ "PBH_RULE_INVALID_L4_DST_PORT": {
+ "desc": "Configure invalid L4_DST_PORT in PBH_RULE.",
+ "eStrKey": "Pattern"
+ },
+ "PBH_RULE_INVALID_INNER_ETHER_TYPE": {
+ "desc": "Configure invalid INNER_ETHER_TYPE in PBH_RULE.",
+ "eStrKey": "Pattern"
+ },
+ "PBH_RULE_INVALID_HASH": {
+ "desc": "Configure non-existing PBH_HASH in PBH_RULE.",
+ "eStrKey": "LeafRef"
+ },
+ "PBH_RULE_INVALID_PACKET_ACTION": {
+ "desc": "Configure invalid PACKET_ACTION in PBH_RULE.",
+ "eStrKey": "InvalidValue"
+ },
+ "PBH_RULE_INVALID_FLOW_COUNTER": {
+ "desc": "Configure invalid FLOW_COUNTER in PBH_RULE.",
+ "eStrKey": "InvalidValue"
+ },
+ "PBH_RULE_DEFAULT_VALUE_PACKET_ACTION": {
+ "desc": "Verify default value for PACKET_ACTION field in PBH_RULE.",
+ "eStrKey": "Verify",
+ "verify": {
+ "xpath": "/sonic-pbh:sonic-pbh/PBH_RULE/PBH_RULE_LIST[table_name='pbh_table'][rule_name='nvgre']/packet_action",
+ "key": "sonic-pbh:packet_action",
+ "value": "SET_ECMP_HASH"
+ }
+ },
+ "PBH_RULE_DEFAULT_VALUE_FLOW_COUNTER": {
+ "desc": "Verify default value for FLOW_COUNTER field in PBH_RULE.",
+ "eStrKey": "Verify",
+ "verify": {
+ "xpath": "/sonic-pbh:sonic-pbh/PBH_RULE/PBH_RULE_LIST[table_name='pbh_table'][rule_name='nvgre']/flow_counter",
+ "key": "sonic-pbh:flow_counter",
+ "value": "DISABLED"
+ }
+ },
+ "PBH_HASH_INVALID_HASH_FIELD": {
+ "desc": "Configure invalid HASH_FIELD in PBH_HASH.",
+ "eStrKey": "LeafRef"
+ },
+ "PBH_HASH_EMPTY_HASH_FIELD_LIST": {
+ "desc": "Configure empty HASH_FIELD_LIST in PBH_HASH.",
+ "eStrKey": "MinElements"
+ },
+ "PBH_HASH_FIELD_INVALID_HASH_FIELD": {
+ "desc": "Configure invalid HASH_FIELD in PBH_HASH_FIELD.",
+ "eStrKey": "InvalidValue"
+ },
+ "PBH_HASH_FIELD_INVALID_IP_MASK": {
+ "desc": "Configure invalid IP_MASK in PBH_HASH_FIELD.",
+ "eStrKey": "InvalidValue"
+ },
+ "PBH_HASH_FIELD_IPV4_MASK_HASH_FIELD_MISMATCH": {
+ "desc": "Configure HASH_FIELD (INNER_DST_IPV6) with IPV4_MASK in PBH_HASH_FIELD.",
+ "eStrKey": "Must"
+ },
+ "PBH_HASH_FIELD_IPV6_MASK_HASH_FIELD_MISMATCH": {
+ "desc": "Configure HASH_FIELD (INNER_DST_IPV4) with IPV6_MASK in PBH_HASH_FIELD.",
+ "eStrKey": "Must"
+ },
+ "PBH_HASH_FIELD_INVALID_SEQUENCE_ID": {
+ "desc": "Configure invalid SEQUENCE_ID in PBH_HASH_FIELD.",
+ "eStrKey": "InvalidValue"
+ }
+}
diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/portchannel.json b/src/sonic-yang-models/tests/yang_model_tests/tests/portchannel.json
index c461fae1b674..693b0fd47b75 100644
--- a/src/sonic-yang-models/tests/yang_model_tests/tests/portchannel.json
+++ b/src/sonic-yang-models/tests/yang_model_tests/tests/portchannel.json
@@ -2,6 +2,13 @@
"PORT_CHANNEL_TEST": {
"desc": "Configure a member port in PORT_CHANNEL table."
},
+ "PORT_CHANNEL_MAX_VALID_MIN_LINKS": {
+ "desc": "Configure PortChannel with maximum valid value of min-links."
+ },
+ "PORT_CHANNEL_OUT_OF_RANGE_MIN_LINKS": {
+ "desc": "Configure PortChannel with greater than maximum valid value of min-links.",
+ "eStr": ["Value", "does not satisfy the constraint"]
+ },
"PORT_CHANNEL_WRONG_PATTERN": {
"desc": "INCORRECT PORTCHANNEL_NAME IN PORT_CHANNEL TABLE.",
"eStrKey" : "Pattern",
diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/sflow.json b/src/sonic-yang-models/tests/yang_model_tests/tests/sflow.json
new file mode 100644
index 000000000000..42d09a773c0d
--- /dev/null
+++ b/src/sonic-yang-models/tests/yang_model_tests/tests/sflow.json
@@ -0,0 +1,47 @@
+{
+ "SFLOW_COLLECTOR_TEST": {
+ "desc": "Configure a collector in SFLOW_COLLECTOR table."
+ },
+ "SFLOW_COLLECTOR_WRONG_NAME_TEST": {
+ "desc": "Configure a collector with incorrect name in SFLOW_COLLECTOR table.",
+ "eStr" : ["not", "satisfy", "the", "constraint", "1..64"]
+ },
+ "SFLOW_TEST_WITHOUT_COLLECTOR_IP": {
+ "desc": "Configure a collector without collector IP attribute in SFLOW_COLLECTOR table.",
+ "eStrKey" : "Mandatory"
+ },
+ "SFLOW_TEST_EXCEEDING_MAX_ELEMENTS": {
+ "desc": "Configure collectors above the specified limit in SFLOW_COLLECTOR table.",
+ "eStr": ["Too many \"SFLOW_COLLECTOR_LIST\" elements"]
+ },
+ "SFLOW_SESSION_TEST": {
+ "desc": "Configure a sflow session in SFLOW_SESSION table."
+ },
+ "SFLOW_SESSION_TEST_WITH_NON_EXIST_PORT": {
+ "desc": "Configure Port in SFLOW_SESSION table which does not exist in PORT table.",
+ "eStrKey": "InvalidValue"
+ },
+ "SFLOW_SESSION_TEST_WITH_INCORRECT_PORT_NAME_PATTERN": {
+ "desc": "Configure SFLOW_SESSION table with incorrect pattern in port name attribute.",
+ "eStrKey": "InvalidValue"
+ },
+ "SFLOW_SESSION_TEST_WITH_INCORRECT_SAMPLE_RATE": {
+ "desc": "Configure sflow session in SFLOW_SESSION table with an out of range sample rate.",
+ "eStr": ["sFlow sample rate must be [256-8388608]"]
+ },
+ "SFLOW_SESSION_TEST_WITH_INCORRECT_PORT_TYPE_IN_SAMPLE_RATE": {
+ "desc": "Configure sflow session in SFLOW_SESSION table with an incorrect port type in sample rate.",
+ "eStrKey": "Must"
+ },
+ "SFLOW_TEST": {
+ "desc": "Configure sflow global entry in SFLOW table."
+ },
+ "SFLOW_TEST_WITH_NON_EXIST_PORT": {
+ "desc": "Configure Port in SFLOW table which does not exist in PORT table.",
+ "eStrKey": "InvalidValue"
+ },
+ "SFLOW_TEST_WITH_INCORRECT_POLLING_INTERVAL": {
+ "desc": "Configure SFLOW table with an out of range polling interval.",
+ "eStr": ["sFlow polling interval must be [0, 5-300]"]
+ }
+}
diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/pbh.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/pbh.json
new file mode 100644
index 000000000000..36be9aa0132d
--- /dev/null
+++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/pbh.json
@@ -0,0 +1,974 @@
+{
+ "PBH_TABLE_RULE_HASH_HASH_FIELD_VALID": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ },
+ {
+ "hash_field_name": "inner_l4_dst_port",
+ "hash_field": "INNER_L4_DST_PORT",
+ "sequence_id": 2
+ },
+ {
+ "hash_field_name": "inner_l4_src_port",
+ "hash_field": "INNER_L4_SRC_PORT",
+ "sequence_id": 2
+ },
+ {
+ "hash_field_name": "inner_dst_ipv4",
+ "hash_field": "INNER_DST_IPV4",
+ "ip_mask": "255.0.0.0",
+ "sequence_id": 3
+ },
+ {
+ "hash_field_name": "inner_src_ipv4",
+ "hash_field": "INNER_SRC_IPV4",
+ "ip_mask": "0.0.0.255",
+ "sequence_id": 3
+ },
+ {
+ "hash_field_name": "inner_dst_ipv6",
+ "hash_field": "INNER_DST_IPV6",
+ "ip_mask": "ffff::",
+ "sequence_id": 4
+ },
+ {
+ "hash_field_name": "inner_src_ipv6",
+ "hash_field": "INNER_SRC_IPV6",
+ "ip_mask": "::ffff",
+ "sequence_id": 4
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v4_hash",
+ "hash_field_list": [
+ "inner_ip_proto",
+ "inner_l4_dst_port",
+ "inner_l4_src_port",
+ "inner_dst_ipv4",
+ "inner_src_ipv4"
+ ]
+ },
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto",
+ "inner_l4_dst_port",
+ "inner_l4_src_port",
+ "inner_dst_ipv6",
+ "inner_src_ipv6"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "ether_type": "0x0800",
+ "ip_protocol": "0x2f",
+ "gre_key": "0x2500/0xffffff00",
+ "inner_ether_type": "0x86dd",
+ "hash": "inner_v6_hash",
+ "packet_action": "SET_ECMP_HASH",
+ "flow_counter": "DISABLED"
+ },
+ {
+ "table_name": "pbh_table",
+ "rule_name": "vxlan",
+ "priority": 2,
+ "ether_type": "0x0800",
+ "ip_protocol": "0x11",
+ "l4_dst_port": "0x12b5",
+ "inner_ether_type": "0x0800",
+ "hash": "inner_v4_hash",
+ "packet_action": "SET_LAG_HASH",
+ "flow_counter": "ENABLED"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0",
+ "Ethernet4",
+ "PortChannel0001",
+ "PortChannel0002"
+ ],
+ "description": "NVGRE and VxLAN"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ },
+ {
+ "name": "Ethernet4",
+ "lanes": "4,5,6,7",
+ "speed": 100000
+ }
+ ]
+ }
+ },
+ "sonic-portchannel:sonic-portchannel": {
+ "sonic-portchannel:PORTCHANNEL": {
+ "PORTCHANNEL_LIST": [
+ {
+ "name": "PortChannel0001",
+ "admin_status": "up"
+ },
+ {
+ "name": "PortChannel0002",
+ "admin_status": "up"
+ }
+ ]
+ }
+ }
+ },
+ "PBH_TABLE_INVALID_INTERFACE": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "EthernetX",
+ "PortChannel000X"
+ ],
+ "description": "NVGRE and VxLAN"
+ }
+ ]
+ }
+ }
+ },
+ "PBH_TABLE_EMPTY_INTERFACE_LIST": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "description": "NVGRE and VxLAN"
+ }
+ ]
+ }
+ }
+ },
+ "PBH_TABLE_INVALID_DESCRIPTION": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": ""
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_INVALID_TABLE": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "invalid_value",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "hash": "inner_v6_hash"
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_INVALID_PRIORITY": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 4294967296,
+ "hash": "inner_v6_hash"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_INVALID_GRE_KEY": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "gre_key": "2500/0xffffff00",
+ "hash": "inner_v6_hash"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_INVALID_ETHER_TYPE": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "ether_type": "0800",
+ "hash": "inner_v6_hash"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_INVALID_IP_PROTOCOL": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "ip_protocol": "11",
+ "hash": "inner_v6_hash"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_INVALID_IPV6_NEXT_HEADER": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "ipv6_next_header": "11",
+ "hash": "inner_v6_hash"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_INVALID_L4_DST_PORT": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "l4_dst_port": "12b5",
+ "hash": "inner_v6_hash"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_INVALID_INNER_ETHER_TYPE": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "inner_ether_type": "86dd",
+ "hash": "inner_v6_hash"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_INVALID_HASH": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "hash": "invalid_value"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_INVALID_PACKET_ACTION": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "hash": "inner_v6_hash",
+ "packet_action": "INVALID_VALUE"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_INVALID_FLOW_COUNTER": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "hash": "inner_v6_hash",
+ "flow_counter": "INVALID_VALUE"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_DEFAULT_VALUE_PACKET_ACTION": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "hash": "inner_v6_hash"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_RULE_DEFAULT_VALUE_FLOW_COUNTER": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 1
+ }
+ ]
+ },
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "inner_ip_proto"
+ ]
+ }
+ ]
+ },
+ "sonic-pbh:PBH_RULE": {
+ "PBH_RULE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "rule_name": "nvgre",
+ "priority": 1,
+ "hash": "inner_v6_hash"
+ }
+ ]
+ },
+ "sonic-pbh:PBH_TABLE": {
+ "PBH_TABLE_LIST": [
+ {
+ "table_name": "pbh_table",
+ "interface_list": [
+ "Ethernet0"
+ ],
+ "description": "NVGRE"
+ }
+ ]
+ }
+ },
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "name": "Ethernet0",
+ "lanes": "0,1,2,3",
+ "speed": 100000
+ }
+ ]
+ }
+ }
+ },
+ "PBH_HASH_INVALID_HASH_FIELD": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash",
+ "hash_field_list": [
+ "invalid_value"
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "PBH_HASH_EMPTY_HASH_FIELD_LIST": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH": {
+ "PBH_HASH_LIST": [
+ {
+ "hash_name": "inner_v6_hash"
+ }
+ ]
+ }
+ }
+ },
+ "PBH_HASH_FIELD_INVALID_HASH_FIELD": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INVALID_VALUE",
+ "sequence_id": 1
+ }
+ ]
+ }
+ }
+ },
+ "PBH_HASH_FIELD_INVALID_IP_MASK": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_dst_ipv4",
+ "hash_field": "INNER_DST_IPV4",
+ "ip_mask": "INVALID_VALUE",
+ "sequence_id": 1
+ }
+ ]
+ }
+ }
+ },
+ "PBH_HASH_FIELD_IPV4_MASK_HASH_FIELD_MISMATCH": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_dst_ipv6",
+ "hash_field": "INNER_DST_IPV6",
+ "ip_mask": "255.0.0.0",
+ "sequence_id": 1
+ }
+ ]
+ }
+ }
+ },
+ "PBH_HASH_FIELD_IPV6_MASK_HASH_FIELD_MISMATCH": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_dst_ipv4",
+ "hash_field": "INNER_DST_IPV4",
+ "ip_mask": "ffff::",
+ "sequence_id": 1
+ }
+ ]
+ }
+ }
+ },
+ "PBH_HASH_FIELD_INVALID_SEQUENCE_ID": {
+ "sonic-pbh:sonic-pbh": {
+ "sonic-pbh:PBH_HASH_FIELD": {
+ "PBH_HASH_FIELD_LIST": [
+ {
+ "hash_field_name": "inner_ip_proto",
+ "hash_field": "INNER_IP_PROTOCOL",
+ "sequence_id": 4294967296
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/portchannel.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/portchannel.json
index 315d6cee6d91..d9a54b885958 100644
--- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/portchannel.json
+++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/portchannel.json
@@ -34,6 +34,70 @@
}
}
},
+ "PORT_CHANNEL_MAX_VALID_MIN_LINKS": {
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "admin_status": "up",
+ "alias": "eth0",
+ "description": "Ethernet0",
+ "lanes": "65",
+ "mtu": 9000,
+ "name": "Ethernet0",
+ "speed": 25000
+ }
+ ]
+ }
+ },
+ "sonic-portchannel:sonic-portchannel": {
+ "sonic-portchannel:PORTCHANNEL": {
+ "PORTCHANNEL_LIST": [
+ {
+ "admin_status": "up",
+ "members": [
+ "Ethernet0"
+ ],
+ "min_links": "1024",
+ "mtu": "9100",
+ "name": "PortChannel0001"
+ }
+ ]
+ }
+ }
+ },
+ "PORT_CHANNEL_OUT_OF_RANGE_MIN_LINKS": {
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "admin_status": "up",
+ "alias": "eth0",
+ "description": "Ethernet0",
+ "lanes": "65",
+ "mtu": 9000,
+ "name": "Ethernet0",
+ "speed": 25000
+ }
+ ]
+ }
+ },
+ "sonic-portchannel:sonic-portchannel": {
+ "sonic-portchannel:PORTCHANNEL": {
+ "PORTCHANNEL_LIST": [
+ {
+ "admin_status": "up",
+ "members": [
+ "Ethernet0"
+ ],
+ "min_links": "1025",
+ "mtu": "9100",
+ "name": "PortChannel0001"
+ }
+ ]
+ }
+ }
+ },
"PORT_CHANNEL_WRONG_PATTERN": {
"sonic-portchannel:sonic-portchannel": {
"sonic-portchannel:PORTCHANNEL": {
diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/sflow.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/sflow.json
new file mode 100644
index 000000000000..5d1a561a9f66
--- /dev/null
+++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/sflow.json
@@ -0,0 +1,225 @@
+{
+ "SFLOW_COLLECTOR_TEST": {
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW_COLLECTOR": {
+ "SFLOW_COLLECTOR_LIST": [
+ {
+ "name": "collector1",
+ "collector_ip": "10.100.12.13",
+ "collector_port": "6343"
+ }
+ ]
+ }
+ }
+ },
+
+ "SFLOW_COLLECTOR_WRONG_NAME_TEST": {
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW_COLLECTOR": {
+ "SFLOW_COLLECTOR_LIST": [
+ {
+ "name": "collector1111111111111111111111111111111111111111111111111111111111111111",
+ "collector_ip": "10.100.12.13"
+ }
+ ]
+ }
+ }
+ },
+
+ "SFLOW_TEST_WITHOUT_COLLECTOR_IP": {
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW_COLLECTOR": {
+ "SFLOW_COLLECTOR_LIST": [
+ {
+ "name": "collector1"
+ }
+ ]
+ }
+ }
+ },
+
+ "SFLOW_TEST_EXCEEDING_MAX_ELEMENTS": {
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW_COLLECTOR": {
+ "SFLOW_COLLECTOR_LIST": [
+ {
+ "name": "collector1",
+ "collector_ip": "10.100.12.13"
+ },
+ {
+ "name": "collector2",
+ "collector_ip": "10.144.1.2"
+ },
+ {
+ "name": "collector3",
+ "collector_ip": "10.100.12.15"
+ }
+ ]
+ }
+ }
+ },
+
+ "SFLOW_SESSION_TEST": {
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "admin_status": "up",
+ "alias": "eth0",
+ "description": "Ethernet0",
+ "lanes": "65",
+ "mtu": 9000,
+ "name": "Ethernet0",
+ "speed": 25000
+ }
+ ]
+ }
+ },
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW_SESSION": {
+ "SFLOW_SESSION_LIST": [
+ {
+ "port": "Ethernet0",
+ "admin_state": "up",
+ "sample_rate": "40000"
+ }
+ ]
+ }
+ }
+ },
+
+ "SFLOW_SESSION_TEST_WITH_NON_EXIST_PORT": {
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW_SESSION": {
+ "SFLOW_SESSION_LIST": [
+ {
+ "port": "Ethernet4",
+ "admin_state": "down",
+ "sample_rate": "32768"
+ }
+ ]
+ }
+ }
+ },
+
+ "SFLOW_SESSION_TEST_WITH_INCORRECT_PORT_NAME_PATTERN": {
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW_SESSION": {
+ "SFLOW_SESSION_LIST": [
+ {
+ "port": "allllll",
+ "admin_state": "down"
+ }
+ ]
+ }
+ }
+ },
+
+ "SFLOW_SESSION_TEST_WITH_INCORRECT_SAMPLE_RATE": {
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "admin_status": "up",
+ "alias": "eth0",
+ "description": "Ethernet0",
+ "lanes": "65",
+ "mtu": 9000,
+ "name": "Ethernet0",
+ "speed": 25000
+ }
+ ]
+ }
+ },
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW_SESSION": {
+ "SFLOW_SESSION_LIST": [
+ {
+ "port": "Ethernet0",
+ "admin_state": "up",
+ "sample_rate": "40"
+ }
+ ]
+ }
+ }
+ },
+
+ "SFLOW_SESSION_TEST_WITH_INCORRECT_PORT_TYPE_IN_SAMPLE_RATE": {
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW_SESSION": {
+ "SFLOW_SESSION_LIST": [
+ {
+ "port": "all",
+ "admin_state": "up",
+ "sample_rate": "40000"
+ }
+ ]
+ }
+ }
+ },
+
+ "SFLOW_TEST": {
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "admin_status": "up",
+ "alias": "eth0",
+ "description": "Ethernet0",
+ "lanes": "65",
+ "mtu": 9000,
+ "name": "Ethernet0",
+ "speed": 25000
+ }
+ ]
+ }
+ },
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW": {
+ "global": {
+ "agent_id": "Ethernet0",
+ "admin_state": "up",
+ "polling_interval": "20"
+ }
+ }
+ }
+ },
+
+ "SFLOW_TEST_WITH_NON_EXIST_PORT": {
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW": {
+ "global": {
+ "agent_id": "Ethernet0",
+ "admin_state": "up",
+ "polling_interval": "20"
+ }
+ }
+ }
+ },
+
+ "SFLOW_TEST_WITH_INCORRECT_POLLING_INTERVAL": {
+ "sonic-port:sonic-port": {
+ "sonic-port:PORT": {
+ "PORT_LIST": [
+ {
+ "admin_status": "up",
+ "alias": "eth0",
+ "description": "Ethernet0",
+ "lanes": "65",
+ "mtu": 9000,
+ "name": "Ethernet0",
+ "speed": 25000
+ }
+ ]
+ }
+ },
+ "sonic-sflow:sonic-sflow": {
+ "sonic-sflow:SFLOW": {
+ "global": {
+ "admin_state": "up",
+ "polling_interval": "305"
+ }
+ }
+ }
+ }
+}
diff --git a/src/sonic-yang-models/yang-models/sonic-pbh.yang b/src/sonic-yang-models/yang-models/sonic-pbh.yang
new file mode 100644
index 000000000000..21a4b5fecc69
--- /dev/null
+++ b/src/sonic-yang-models/yang-models/sonic-pbh.yang
@@ -0,0 +1,264 @@
+module sonic-pbh {
+
+ yang-version 1.1;
+
+ namespace "http://github.com/Azure/sonic-pbh";
+ prefix pbh;
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+
+ import sonic-port {
+ prefix port;
+ }
+
+ import sonic-portchannel {
+ prefix lag;
+ }
+
+ description "PBH YANG Module for SONiC OS: hashing for NVGRE & VxLAN with IPv4/IPv6 inner 5-tuple";
+
+ revision 2021-04-23 {
+ description "First Revision";
+ }
+
+ typedef hash-field {
+ description "Represents native hash field";
+ type enumeration {
+ enum INNER_IP_PROTOCOL;
+ enum INNER_L4_DST_PORT;
+ enum INNER_L4_SRC_PORT;
+ enum INNER_DST_IPV4;
+ enum INNER_SRC_IPV4;
+ enum INNER_DST_IPV6;
+ enum INNER_SRC_IPV6;
+ }
+ }
+
+ typedef packet-action {
+ description "Represents packet action";
+ type enumeration {
+ enum SET_ECMP_HASH;
+ enum SET_LAG_HASH;
+ }
+ }
+
+ typedef flow-counter {
+ description "Represents flow counter state";
+ type enumeration {
+ enum DISABLED;
+ enum ENABLED;
+ }
+ }
+
+ container sonic-pbh {
+
+ container PBH_HASH_FIELD {
+
+ description "PBH_HASH_FIELD part of config_db.json";
+
+ list PBH_HASH_FIELD_LIST {
+
+ key "hash_field_name";
+
+ leaf hash_field_name {
+ description "The name of this hash field";
+ type string {
+ length 1..255;
+ }
+ }
+
+ leaf hash_field {
+ description "Configures native hash field for this hash field";
+ mandatory true;
+ type pbh:hash-field;
+ }
+
+ leaf ip_mask {
+ description "Configures IPv4/IPv6 address mask for this hash field";
+ mandatory true;
+ type inet:ip-address-no-zone;
+ must "(boolean(../hash_field[.='INNER_DST_IPV4' or .='INNER_SRC_IPV4']) and contains(current(), '.'))
+ or (boolean(../hash_field[.='INNER_DST_IPV6' or .='INNER_SRC_IPV6']) and contains(current(), ':'))";
+ when "boolean(../hash_field[.='INNER_DST_IPV4' or .='INNER_SRC_IPV4' or .='INNER_DST_IPV6' or .='INNER_SRC_IPV6'])";
+ }
+
+ leaf sequence_id {
+ description "Configures in which order the fields are hashed and defines which fields should be associative";
+ mandatory true;
+ type uint32;
+ }
+
+ }
+ /* end of PBH_HASH_FIELD_LIST */
+ }
+ /* end of container PBH_HASH_FIELD */
+
+ container PBH_HASH {
+
+ description "PBH_HASH part of config_db.json";
+
+ list PBH_HASH_LIST {
+
+ key "hash_name";
+
+ leaf hash_name {
+ description "The name of this hash";
+ type string {
+ length 1..255;
+ }
+ }
+
+ leaf-list hash_field_list {
+ description "The list of hash fields to apply with this hash";
+ min-elements 1;
+ type leafref {
+ path "/pbh:sonic-pbh/pbh:PBH_HASH_FIELD/pbh:PBH_HASH_FIELD_LIST/pbh:hash_field_name";
+ }
+ }
+
+ }
+ /* end of PBH_HASH_LIST */
+ }
+ /* end of container PBH_HASH */
+
+ container PBH_RULE {
+
+ description "PBH_RULE part of config_db.json";
+
+ list PBH_RULE_LIST {
+
+ key "table_name rule_name";
+
+ leaf table_name {
+ description "The name of table which holds this rule";
+ type leafref {
+ path "/pbh:sonic-pbh/pbh:PBH_TABLE/pbh:PBH_TABLE_LIST/pbh:table_name";
+ }
+ }
+
+ leaf rule_name {
+ description "The name of this rule";
+ type string {
+ length 1..255;
+ }
+ }
+
+ leaf priority {
+ description "Configures priority for this rule";
+ mandatory true;
+ type uint32;
+ }
+
+ leaf gre_key {
+ description "Configures packet match for this rule: GRE key (value/mask)";
+ type string {
+ pattern "(0x){1}[a-fA-F0-9]{1,8}/(0x){1}[a-fA-F0-9]{1,8}";
+ }
+ }
+
+ leaf ether_type {
+ description "Configures packet match for this rule: EtherType (IANA Ethertypes)";
+ type string {
+ pattern "(0x){1}[a-fA-F0-9]{1,4}";
+ }
+ }
+
+ leaf ip_protocol {
+ description "Configures packet match for this rule: IP protocol (IANA Protocol Numbers)";
+ type string {
+ pattern "(0x){1}[a-fA-F0-9]{1,2}";
+ }
+ }
+
+ leaf ipv6_next_header {
+ description "Configures packet match for this rule: IPv6 Next header (IANA Protocol Numbers)";
+ type string {
+ pattern "(0x){1}[a-fA-F0-9]{1,2}";
+ }
+ }
+
+ leaf l4_dst_port {
+ description "Configures packet match for this rule: L4 destination port";
+ type string {
+ pattern "(0x){1}[a-fA-F0-9]{1,4}";
+ }
+ }
+
+ leaf inner_ether_type {
+ description "Configures packet match for this rule: inner EtherType (IANA Ethertypes)";
+ type string {
+ pattern "(0x){1}[a-fA-F0-9]{1,4}";
+ }
+ }
+
+ leaf hash {
+ description "The hash to apply with this rule";
+ mandatory true;
+ type leafref {
+ path "/pbh:sonic-pbh/pbh:PBH_HASH/pbh:PBH_HASH_LIST/pbh:hash_name";
+ }
+ }
+
+ leaf packet_action {
+ description "Configures packet action for this rule";
+ type pbh:packet-action;
+ default "SET_ECMP_HASH";
+ }
+
+ leaf flow_counter {
+ description "Enables/Disables packet/byte counter for this rule";
+ type pbh:flow-counter;
+ default "DISABLED";
+ }
+
+ }
+ /* end of PBH_RULE_LIST */
+ }
+ /* end of container PBH_RULE */
+
+ container PBH_TABLE {
+
+ description "PBH_TABLE part of config_db.json";
+
+ list PBH_TABLE_LIST {
+
+ key "table_name";
+
+ leaf table_name {
+ description "The name of this table";
+ type string {
+ length 1..255;
+ }
+ }
+
+ leaf-list interface_list {
+ description "Interfaces to which this table is applied";
+ min-elements 1;
+ type union {
+ type leafref {
+ path "/port:sonic-port/port:PORT/port:PORT_LIST/port:name";
+ }
+ type leafref {
+ path "/lag:sonic-portchannel/lag:PORTCHANNEL/lag:PORTCHANNEL_LIST/lag:name";
+ }
+ }
+ }
+
+ leaf description {
+ description "The description of this table";
+ mandatory true;
+ type string {
+ length 1..255;
+ }
+ }
+
+ }
+ /* end of PBH_TABLE_LIST */
+ }
+ /* end of container PBH_TABLE */
+ }
+ /* end of container sonic-pbh */
+}
+/* end of module sonic-pbh */
diff --git a/src/sonic-yang-models/yang-models/sonic-portchannel.yang b/src/sonic-yang-models/yang-models/sonic-portchannel.yang
index 837d18bef4c0..f02a45d93917 100644
--- a/src/sonic-yang-models/yang-models/sonic-portchannel.yang
+++ b/src/sonic-yang-models/yang-models/sonic-portchannel.yang
@@ -26,6 +26,10 @@ module sonic-portchannel {
description "PORTCHANNEL yang Module for SONiC OS";
+ revision 2021-06-13 {
+ description "Change min-links valid range from 1-128 to 1-1024";
+ }
+
revision 2021-03-31 {
description "Add PortChannel Interface List with VRF attribute";
}
@@ -74,8 +78,8 @@ module sonic-portchannel {
}
leaf min_links {
- type uint8 {
- range 1..128;
+ type uint16 {
+ range 1..1024;
}
}
diff --git a/src/sonic-yang-models/yang-models/sonic-sflow.yang b/src/sonic-yang-models/yang-models/sonic-sflow.yang
new file mode 100644
index 000000000000..62984f064c51
--- /dev/null
+++ b/src/sonic-yang-models/yang-models/sonic-sflow.yang
@@ -0,0 +1,141 @@
+module sonic-sflow{
+
+ namespace "http://github.com/Azure/sonic-sflow";
+ prefix sflow;
+ yang-version 1.1;
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+
+ import sonic-types {
+ prefix stypes;
+ }
+ import sonic-port {
+ prefix port;
+ }
+ /*
+ import sonic-vlan {
+ prefix vlan;
+ }
+ */
+ import sonic-portchannel {
+ prefix lag;
+ }
+ import sonic-mgmt_port {
+ prefix mgmt-port;
+ }
+
+ description "SFLOW yang Module for SONiC OS";
+
+ revision 2021-04-26 {
+ description "First Revision";
+ }
+
+ container sonic-sflow {
+
+ container SFLOW_COLLECTOR {
+ list SFLOW_COLLECTOR_LIST {
+ max-elements 2;
+ key "name";
+
+ leaf name {
+ type string {
+ length 1..64;
+ }
+ }
+
+ leaf collector_ip {
+ mandatory true;
+ type inet:ip-address;
+ }
+
+
+ leaf collector_port {
+ type inet:port-number;
+ default 6343;
+ }
+
+ } /* end of list SFLOW_COLLECTOR_LIST */
+ } /* end of container SFLOW_COLLECTOR */
+
+ container SFLOW_SESSION {
+ list SFLOW_SESSION_LIST {
+ key "port";
+
+ leaf port {
+ type union {
+ type leafref {
+ path "/port:sonic-port/port:PORT/port:PORT_LIST/port:name";
+ }
+ type string {
+ pattern "all";
+ }
+ }
+ description "Sets sflow session table attributes for either all interfaces or a specific Ethernet interface.";
+ }
+
+ leaf admin_state {
+ type stypes:admin_status;
+ default up;
+ }
+
+ leaf sample_rate {
+ must "../port != 'all'";
+ type uint32 {
+ range "256..8388608" {
+ error-message "sFlow sample rate must be [256-8388608]";
+ }
+ }
+ description "Sets the packet sampling rate. The rate is expressed as an integer N, where the intended sampling rate is 1/N packets.";
+ }
+ } /* end of list SFLOW_SESSION_LIST */
+ } /* end of container SFLOW_SESSION */
+
+ container SFLOW {
+
+ container global {
+
+ leaf admin_state {
+ type stypes:admin_status;
+ default down;
+ }
+
+ leaf polling_interval {
+ type uint16 {
+ range "0|5..300" {
+ error-message "sFlow polling interval must be [0, 5-300]";
+ }
+ }
+ description "The interval within which sFlow data is collected and sent to the configured collectors";
+ default 20;
+ }
+
+ leaf agent_id {
+ type union {
+ type leafref {
+ path "/port:sonic-port/port:PORT/port:PORT_LIST/port:name";
+ }
+ type leafref {
+ path "/lag:sonic-portchannel/lag:PORTCHANNEL/lag:PORTCHANNEL_LIST/lag:name";
+ }
+ type leafref {
+ path "/mgmt-port:sonic-mgmt_port/mgmt-port:MGMT_PORT/mgmt-port:MGMT_PORT_LIST/mgmt-port:name";
+ }
+ /*
+ type leafref {
+ path "/vlan:sonic-vlan/vlan:VLAN/vlan:VLAN_LIST/vlan:name";
+ }
+ */
+ type string {
+ pattern 'Vlan([0-9]{1,3}|[1-3][0-9]{3}|[4][0][0-8][0-9]|[4][0][9][0-4])';
+ }
+ }
+ description "Interface name";
+ }
+ } /* end of container global */
+ } /* end of container SFLOW */
+
+ } /* end of container sonic-sflow */
+
+} /* end of module sonic-sflow */
diff --git a/src/system-health/health_checker/hardware_checker.py b/src/system-health/health_checker/hardware_checker.py
index 263616578270..575564de8733 100644
--- a/src/system-health/health_checker/hardware_checker.py
+++ b/src/system-health/health_checker/hardware_checker.py
@@ -1,5 +1,5 @@
from natsort import natsorted
-from swsssdk import SonicV2Connector
+from swsscommon.swsscommon import SonicV2Connector
from .health_checker import HealthChecker
diff --git a/src/system-health/scripts/healthd b/src/system-health/scripts/healthd
index 799fa028f2e7..da0258bb59e5 100644
--- a/src/system-health/scripts/healthd
+++ b/src/system-health/scripts/healthd
@@ -9,7 +9,7 @@ import signal
import threading
from sonic_py_common.daemon_base import DaemonBase
-from swsssdk import SonicV2Connector
+from swsscommon.swsscommon import SonicV2Connector
from health_checker.manager import HealthCheckerManager
diff --git a/src/system-health/setup.py b/src/system-health/setup.py
index e8084701f08c..b0cc998e482f 100644
--- a/src/system-health/setup.py
+++ b/src/system-health/setup.py
@@ -3,7 +3,6 @@
dependencies = [
'natsort',
'sonic_py_common',
- 'swsssdk>=2.0.1',
]
setup(
diff --git a/src/system-health/tests/test_system_health.py b/src/system-health/tests/test_system_health.py
index 8fe8642b1014..8e3d3c77e9f1 100644
--- a/src/system-health/tests/test_system_health.py
+++ b/src/system-health/tests/test_system_health.py
@@ -10,14 +10,14 @@
"""
import os
import sys
-import swsssdk
+from swsscommon import swsscommon
from mock import Mock, MagicMock, patch
from sonic_py_common import device_info
from .mock_connector import MockConnector
-swsssdk.SonicV2Connector = MockConnector
+swsscommon.SonicV2Connector = MockConnector
test_path = os.path.dirname(os.path.abspath(__file__))
modules_path = os.path.dirname(test_path)
diff --git a/src/systemd-sonic-generator/.gitignore b/src/systemd-sonic-generator/.gitignore
index 06e13f381b69..e81dafbbcbce 100644
--- a/src/systemd-sonic-generator/.gitignore
+++ b/src/systemd-sonic-generator/.gitignore
@@ -1,4 +1,5 @@
systemd-sonic-generator
+ssg_test
debian/*
!debian/changelog
!debian/compat
diff --git a/src/systemd-sonic-generator/Makefile b/src/systemd-sonic-generator/Makefile
index 0f911ed8a4f9..565fcb8030a7 100644
--- a/src/systemd-sonic-generator/Makefile
+++ b/src/systemd-sonic-generator/Makefile
@@ -1,5 +1,9 @@
CC=gcc
-CFLAGS=-std=gnu99
+CFLAGS=-std=gnu99 -D_GNU_SOURCE
+
+CPP=g++
+CPPFLAGS=-std=c++11 -D_GNU_SOURCE
+LFLAGS=-lpthread -lboost_filesystem -lboost_system -lgtest
BINARY = systemd-sonic-generator
MAIN_TARGET = $(BINARY)_1.0.0_$(CONFIGURED_ARCH).deb
@@ -20,3 +24,18 @@ install: $(BINARY)
mkdir -p $(DESTDIR)/lib/systemd
mkdir -p $(DESTDIR)/lib/systemd/system-generators
cp ./systemd-sonic-generator $(DESTDIR)/lib/systemd/system-generators
+
+.PHONY: test
+test: ssg_test
+ ./ssg_test
+
+ssg_test: ssg-test.cc systemd-sonic-generator.o
+ $(CPP) $(CPPFLAGS) -o $@ $^ $(LFLAGS)
+
+systemd-sonic-generator.o: systemd-sonic-generator.c
+ $(CC) $(CFLAGS) -D_SSG_UNITTEST -o $@ -c $^
+
+clean:
+ rm -f ./systemd-sonic-generator
+ rm -f ./systemd-sonic-generator.o
+ rm -f ./ssg_test
diff --git a/src/systemd-sonic-generator/debian/changelog b/src/systemd-sonic-generator/debian/changelog
index 1cc6c755e6c8..17442f16b855 100644
--- a/src/systemd-sonic-generator/debian/changelog
+++ b/src/systemd-sonic-generator/debian/changelog
@@ -1,3 +1,3 @@
systemd-sonic-generator (1.0.0) UNRELEASED; urgency=medium
* Initial version
- -- Lawrence Lee Tue, 23 Jul 2019 16:00:00 -0800
+ -- Lawrence Lee Tue, 23 Jul 2019 16:00:00 -0800
diff --git a/src/systemd-sonic-generator/debian/rules b/src/systemd-sonic-generator/debian/rules
index 945fcf9d99b7..a482e044c808 100755
--- a/src/systemd-sonic-generator/debian/rules
+++ b/src/systemd-sonic-generator/debian/rules
@@ -8,7 +8,6 @@ PACKAGEVERSION = $(VERSION)
dh $@
override_dh_auto_clean:
-override_dh_auto_test:
override_dh_auto_build:
override_dh_auto_install:
make systemd-sonic-generator
diff --git a/src/systemd-sonic-generator/ssg-test.cc b/src/systemd-sonic-generator/ssg-test.cc
new file mode 100644
index 000000000000..1d0f33d54bec
--- /dev/null
+++ b/src/systemd-sonic-generator/ssg-test.cc
@@ -0,0 +1,550 @@
+/*------------------------------------------------------------------
+ * ssg-test.cc - systemd-sonic-generator Unit Test
+ *
+ * Initial: Apr 2021
+ *
+ * Copyright (c) 2021 by Cisco Systems, Inc.
+ *------------------------------------------------------------------
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include "systemd-sonic-generator.h"
+
+namespace fs = boost::filesystem;
+
+namespace SSGTest {
+#define IS_MULTI_ASIC(x) ((x) > 1)
+#define IS_SINGLE_ASIC(x) ((x) <= 1)
+#define NUM_UNIT_FILES 6
+
+/*
+ * This test class uses following directory hierarchy for input and output
+ * data for systemd-sonic-generator.
+ *
+ * tests/ssg-test/ --- Test data directory
+ * |
+ * |---generated_services.conf
+ * |---machine.conf (systemd-sonic-generator fetch platform from here)
+ * |---systemd/
+ * | |--- *.service (Test unit files are copied from
+ * | tests/testfiles/ to here)
+ * |----test_platform/ (test platform)
+ * | |---asic.conf
+ * |
+ * |----generator/ (Output Directory)
+ *
+ */
+const std::string TEST_ROOT_DIR = "tests/ssg-test/";
+const std::string TEST_UNIT_FILE_PREFIX = TEST_ROOT_DIR + "systemd/";
+const std::string TEST_ASIC_CONF_FORMAT = TEST_ROOT_DIR + "%s/asic.conf";
+const std::string TEST_MACHINE_CONF = TEST_ROOT_DIR + "machine.conf";
+
+const std::string TEST_PLATFORM_DIR = TEST_ROOT_DIR + "test_platform/";
+const std::string TEST_ASIC_CONF = TEST_PLATFORM_DIR + "asic.conf";
+
+const std::string TEST_OUTPUT_DIR = TEST_ROOT_DIR + "generator/";
+
+const std::string TEST_CONFIG_FILE = TEST_ROOT_DIR + "generated_services.conf";
+
+const std::string TEST_UNIT_FILES = "tests/testfiles/";
+
+/* Input data for generated_services.conf */
+const std::vector generated_services = {
+ "multi_inst_a.service", /* Single instance of a multi asic service a */
+ "multi_inst_a@.service", /* Multi-instance of a multi asic service a */
+ "multi_inst_b@.service", /* Multi-instance of a multi asic service b */
+ "single_inst.service", /* A single instance service */
+ "test.service", /* A single instance test service
+ to test dependency creation */
+ "test.timer", /* A timer service */
+};
+
+static std::mutex g_ssg_test_mutex;
+
+class SystemdSonicGeneratorFixture : public testing::Test {
+ protected:
+ /* Save global variables before running tests */
+ virtual void SetUp() {
+ /* one test runs at a time */
+ g_ssg_test_mutex.lock();
+
+ unit_file_prefix_ = g_unit_file_prefix;
+ config_file_ = g_config_file;
+ machine_config_file_ = g_machine_config_file;
+ asic_conf_format_ = g_asic_conf_format;
+ }
+
+ /* Restore global vars */
+ virtual void TearDown() {
+ g_unit_file_prefix = unit_file_prefix_;
+ g_config_file = config_file_;
+ g_machine_config_file = machine_config_file_;
+ g_asic_conf_format = asic_conf_format_;
+
+ g_ssg_test_mutex.unlock();
+ }
+
+ private:
+ const char* unit_file_prefix_;
+ const char* config_file_;
+ const char* machine_config_file_;
+ const char* asic_conf_format_;
+};
+
+/*
+ * class SsgFunctionTest
+ * Implements functions to execute functional level tests.
+ */
+class SsgFunctionTest : public SystemdSonicGeneratorFixture {
+ protected:
+ /* This function generates the generated_services.conf file */
+ void generate_generated_services_conf() {
+ FILE* fp = fopen(TEST_CONFIG_FILE.c_str(), "w");
+ ASSERT_NE(fp, nullptr);
+ for (std::string str : generated_services) {
+ fputs(str.c_str(), fp);
+ fputs("\n", fp);
+ }
+ fclose(fp);
+ }
+
+ /* copy files from src_dir to dest_dir */
+ void copyfiles(const char* src_dir, const char* dest_dir) {
+ // Iterate through the source directory
+ for (fs::directory_iterator file(src_dir);
+ file != fs::directory_iterator(); ++file) {
+ try {
+ fs::path current(file->path());
+ if(!fs::is_directory(current)) {
+ /* Copy file */
+ fs::copy_file( current, dest_dir / current.filename());
+ }
+ }
+ catch(fs::filesystem_error const & e) {
+ std:: cerr << e.what() << '\n';
+ }
+ }
+ }
+
+ /* Save global variables before running tests */
+ virtual void SetUp() {
+ FILE* fp;
+ SystemdSonicGeneratorFixture::SetUp();
+
+ /* Setup Input and Output directories and files */
+ fs::path path{TEST_UNIT_FILE_PREFIX.c_str()};
+ fs::create_directories(path);
+ path = fs::path(TEST_OUTPUT_DIR.c_str());
+ fs::create_directories(path);
+ path = fs::path(TEST_PLATFORM_DIR.c_str());
+ fs::create_directories(path);
+ fp = fopen(TEST_MACHINE_CONF.c_str(), "w");
+ ASSERT_NE(fp, nullptr);
+ fputs("onie_platform=test_platform", fp);
+ fclose(fp);
+ generate_generated_services_conf();
+ copyfiles(TEST_UNIT_FILES.c_str(), TEST_UNIT_FILE_PREFIX.c_str());
+ }
+
+ /* Restore global vars */
+ virtual void TearDown() {
+ /* Delete ssg_test directory */
+ EXPECT_TRUE(fs::exists(TEST_ROOT_DIR.c_str()));
+ fs::path path{TEST_ROOT_DIR.c_str()};
+ fs::remove_all(path);
+
+ SystemdSonicGeneratorFixture::TearDown();
+ }
+
+ private:
+};
+
+/*
+ * class SsgMainTest
+ * Implements functions to test ssg_main routine.
+ */
+class SsgMainTest : public SsgFunctionTest {
+ protected:
+ /* Retrun true if string belongs to a multi instance service */
+ bool is_multi_instance(const std::string str) {
+ return (str.find("@") != std::string::npos) ? true : false;
+ }
+
+ /* Returns true if it is a timer service */
+ bool is_timer_service(const std::string str) {
+ return (str.find(".timer") != std::string::npos) ? true : false;
+ }
+
+ /* Find a string in a file */
+ bool find_string_in_file(std::string str,
+ std::string file_name,
+ int num_asics) {
+ bool found = false;
+ std::string line;
+
+ std::ifstream file(TEST_UNIT_FILE_PREFIX + file_name);
+ while (getline(file, line) && !found) {
+ if (str == line) {
+ found = true;
+ }
+ }
+ return found;
+ }
+
+ /* This function validates if a given dependency list for an unit file
+ * exists in the unit file as per expected_result. The items in the list
+ * should exist if expected_result is true.
+ */
+ void validate_output_dependency_list(std::vector strs,
+ std::string target,
+ bool expected_result,
+ int num_asics) {
+ for (std::string str : strs) {
+ bool finished = false;
+ for (int i = 0 ; i < num_asics && !finished; ++i) {
+ auto str_t = str;
+ if (is_multi_instance(str)) {
+ /* insert instance id in string */
+ str_t = (boost::format{str} % i).str();
+ } else {
+ /* Run once for single instance */
+ finished = true;
+ }
+ EXPECT_EQ(find_string_in_file(str_t, target, num_asics),
+ expected_result)
+ << "Error validating " + str_t + " in " + target;
+ }
+ }
+ }
+
+ /* This function validates if unit file paths in the provided
+ * list strs exists or not as per expected_result. The unit files
+ * should exist if expected_result is true.
+ */
+ void validate_output_unit_files(std::vector strs,
+ std::string target,
+ bool expected_result,
+ int num_asics) {
+ for (std::string str : strs) {
+ bool finished = false;
+ for (int i = 0 ; i < num_asics && !finished; ++i) {
+ auto str_t = str;
+ if (is_multi_instance(str)) {
+ /* insert instance id in string */
+ str_t = (boost::format{str} % i).str();
+ } else {
+ /* Run once for single instance */
+ finished = true;
+ }
+ fs::path path{TEST_OUTPUT_DIR + target + "/" + str_t};
+ EXPECT_EQ(fs::exists(path), expected_result)
+ << "Failed validation: " << path;
+ }
+ }
+ }
+
+ /*
+ * This function validates the generated dependencies in a Unit File.
+ */
+ void validate_depedency_in_unit_file(int num_asics) {
+ std::string test_service = "test.service";
+
+ /* Validate Unit file dependency creation for multi instance
+ * services. These entries should be present for multi asic
+ * system but not present for single asic system.
+ */
+ validate_output_dependency_list(multi_asic_dependency_list,
+ test_service, IS_MULTI_ASIC(num_asics), num_asics);
+
+ /* Validate Unit file dependency creation for single instance
+ * services. These entries should not be present for multi asic
+ * system but present for single asic system.
+ */
+ validate_output_dependency_list(single_asic_dependency_list,
+ test_service, IS_SINGLE_ASIC(num_asics), num_asics);
+
+ /* Validate Unit file dependency creation for single instance
+ * common services. These entries should not be present for multi
+ * and single asic system.
+ */
+ validate_output_dependency_list(common_dependency_list,
+ test_service, true, num_asics);
+ }
+
+ /*
+ * This function validates the list of generated Service Unit Files.
+ */
+ void validate_service_file_generated_list(int num_asics) {
+ std::string test_target = "multi-user.target.wants";
+ validate_output_unit_files(multi_asic_service_list,
+ test_target, IS_MULTI_ASIC(num_asics), num_asics);
+ validate_output_unit_files(single_asic_service_list,
+ test_target, IS_SINGLE_ASIC(num_asics), num_asics);
+ validate_output_unit_files(common_service_list,
+ test_target, true, num_asics);
+ }
+
+ /* ssg_main test routine.
+ * input: num_asics number of asics
+ */
+ void ssg_main_test(int num_asics) {
+ FILE* fp;
+ std::vector argv_;
+ std::vector arguments = {
+ "ssg_main",
+ TEST_OUTPUT_DIR.c_str()
+ };
+ std::string num_asic_str = "NUM_ASIC=" + std::to_string(num_asics);
+
+ std::string unit_file_path = fs::current_path().string() + "/" +TEST_UNIT_FILE_PREFIX;
+ g_unit_file_prefix = unit_file_path.c_str();
+ g_config_file = TEST_CONFIG_FILE.c_str();
+ g_machine_config_file = TEST_MACHINE_CONF.c_str();
+ g_asic_conf_format = TEST_ASIC_CONF_FORMAT.c_str();
+
+ /* Set NUM_ASIC value in asic.conf */
+ fp = fopen(TEST_ASIC_CONF.c_str(), "w");
+ ASSERT_NE(fp, nullptr);
+ fputs(num_asic_str.c_str(), fp);
+ fclose(fp);
+
+ /* Create argv list for ssg_main. */
+ for (const auto& arg : arguments) {
+ argv_.push_back((char*)arg.data());
+ }
+ argv_.push_back(nullptr);
+
+ /* Call ssg_main */
+ EXPECT_EQ(ssg_main(argv_.size(), argv_.data()), 0);
+
+ /* Validate systemd service template creation. */
+ validate_service_file_generated_list(num_asics);
+
+ /* Validate Test Unit file for dependency creation. */
+ validate_depedency_in_unit_file(num_asics);
+ }
+
+ /* Save global variables before running tests */
+ virtual void SetUp() {
+ SsgFunctionTest::SetUp();
+ }
+
+ /* Restore global vars */
+ virtual void TearDown() {
+ SsgFunctionTest::TearDown();
+ }
+
+
+ private:
+ static const std::vector single_asic_service_list;
+ static const std::vector multi_asic_service_list;
+ static const std::vector common_service_list;
+ static const std::vector single_asic_dependency_list;
+ static const std::vector multi_asic_dependency_list;
+ static const std::vector common_dependency_list;
+};
+
+/*
+ * The following list defines the Service unit files symlinks generated by
+ * Systemd sonic generator for single and multi asic systems. The test case
+ * use these lists to check for presence/absence of unit files based on
+ * num_asics value.
+ */
+
+/* Systemd service Unit file list for single asic only system */
+const std::vector
+SsgMainTest::single_asic_service_list = {
+ "multi_inst_b.service",
+};
+
+/* Systemd service Unit file list for multi asic only system.
+ * %1% is formatter for boost::format API and replaced by asic num.
+ */
+const std::vector
+SsgMainTest::multi_asic_service_list = {
+ "multi_inst_a@%1%.service",
+ "multi_inst_b@%1%.service",
+};
+
+/* Common Systemd service Unit file list for single and multi asic system. */
+const std::vector
+SsgMainTest::common_service_list = {
+ "multi_inst_a.service",
+ "single_inst.service",
+ "test.service",
+
+};
+
+/*
+ * The following list defines the systemd dependencies in a unit file to be
+ * varified for single and multi asic systems. Based on num_asics and type of
+ * service listed as dependency in Unit file, systemd sonic generator modifies
+ * the original unit file, if required, for multi asic system.
+ * For example: if test.service file defines a dependency "After=multi_inst_a.service",
+ * as multi_inst_a.service is a multi instance service,
+ * for a system with 2 asics, systemd sonic generator shall modify
+ * test.service to include following dependency strings:
+ * "After=multi_inst_a@0.service"
+ * After=multi_inst_a@1.service"
+ */
+
+/* Systemd service Unit file dependency entries for Single asic system. */
+const std::vector
+SsgMainTest::single_asic_dependency_list = {
+ "After=multi_inst_a.service multi_inst_b.service",
+};
+
+/* Systemd service Unit file dependency entries for multi asic system. */
+const std::vector
+SsgMainTest::multi_asic_dependency_list = {
+ "After=multi_inst_a@%1%.service",
+ "After=multi_inst_b@%1%.service",
+};
+
+/* Common Systemd service Unit file dependency entries for single and multi asic
+ * systems.
+ */
+const std::vector
+SsgMainTest::common_dependency_list = {
+ "Before=single_inst.service",
+};
+
+/* Test get functions for global vasr*/
+TEST_F(SystemdSonicGeneratorFixture, get_global_vars) {
+ EXPECT_EQ(g_unit_file_prefix, nullptr);
+ EXPECT_STREQ(get_unit_file_prefix(), UNIT_FILE_PREFIX);
+ g_unit_file_prefix = TEST_UNIT_FILE_PREFIX.c_str();
+ EXPECT_STREQ(get_unit_file_prefix(), TEST_UNIT_FILE_PREFIX.c_str());
+
+ EXPECT_EQ(g_config_file, nullptr);
+ EXPECT_STREQ(get_config_file(), CONFIG_FILE);
+ g_config_file = TEST_CONFIG_FILE.c_str();
+ EXPECT_STREQ(get_config_file(), TEST_CONFIG_FILE.c_str());
+
+ EXPECT_EQ(g_machine_config_file, nullptr);
+ EXPECT_STREQ(get_machine_config_file(), MACHINE_CONF_FILE);
+ g_machine_config_file = TEST_MACHINE_CONF.c_str();
+ EXPECT_STREQ(get_machine_config_file(), TEST_MACHINE_CONF.c_str());
+
+ EXPECT_EQ(g_asic_conf_format, nullptr);
+ EXPECT_STREQ(get_asic_conf_format(), ASIC_CONF_FORMAT);
+ g_asic_conf_format = TEST_ASIC_CONF_FORMAT.c_str();
+ EXPECT_STREQ(get_asic_conf_format(), TEST_ASIC_CONF_FORMAT.c_str());
+}
+
+TEST_F(SystemdSonicGeneratorFixture, global_vars) {
+ EXPECT_EQ(g_unit_file_prefix, nullptr);
+ EXPECT_STREQ(get_unit_file_prefix(), UNIT_FILE_PREFIX);
+
+ EXPECT_EQ(g_config_file, nullptr);
+ EXPECT_STREQ(get_config_file(), CONFIG_FILE);
+
+ EXPECT_EQ(g_machine_config_file, nullptr);
+ EXPECT_STREQ(get_machine_config_file(), MACHINE_CONF_FILE);
+}
+
+/* TEST machine/unit/config if file is missing */
+TEST_F(SsgFunctionTest, missing_file) {
+ EXPECT_TRUE(fs::exists(TEST_MACHINE_CONF.c_str()));
+ EXPECT_TRUE(fs::exists(TEST_UNIT_FILE_PREFIX.c_str()));
+ EXPECT_TRUE(fs::exists(TEST_OUTPUT_DIR.c_str()));
+ EXPECT_TRUE(fs::exists(TEST_PLATFORM_DIR.c_str()));
+}
+
+/* TEST insert_instance_number() */
+TEST_F(SsgFunctionTest, insert_instance_number) {
+ char input[] = "test@.service";
+ for (int i = 0; i <= 100; ++i) {
+ std::string out = "test@" + std::to_string(i) + ".service";
+ char* ret = insert_instance_number(input, i);
+ ASSERT_NE(ret, nullptr);
+ EXPECT_STREQ(ret, out.c_str());
+ }
+}
+
+/* TEST get_num_of_asic() */
+TEST_F(SsgFunctionTest, get_num_of_asic) {
+ FILE* fp;
+
+ g_machine_config_file = TEST_MACHINE_CONF.c_str();
+ g_asic_conf_format = TEST_ASIC_CONF_FORMAT.c_str();
+
+ fp = fopen(TEST_ASIC_CONF.c_str(), "w");
+ ASSERT_NE(fp, nullptr);
+ fputs("NUM_ASIC=1", fp);
+ fclose(fp);
+ EXPECT_EQ(get_num_of_asic(), 1);
+
+ fp = fopen(TEST_ASIC_CONF.c_str(), "w");
+ ASSERT_NE(fp, nullptr);
+ fputs("NUM_ASIC=10", fp);
+ fclose(fp);
+ EXPECT_EQ(get_num_of_asic(), 10);
+
+ fp = fopen(TEST_ASIC_CONF.c_str(), "w");
+ ASSERT_NE(fp, nullptr);
+ fputs("NUM_ASIC=40", fp);
+ fclose(fp);
+ EXPECT_EQ(get_num_of_asic(), 40);
+}
+
+/* TEST get_unit_files()*/
+TEST_F(SsgFunctionTest, get_unit_files) {
+ g_unit_file_prefix = TEST_UNIT_FILE_PREFIX.c_str();
+ g_config_file = TEST_CONFIG_FILE.c_str();
+ char* unit_files[NUM_UNIT_FILES];
+ int num_unit_files = get_unit_files(unit_files);
+ EXPECT_EQ(num_unit_files, NUM_UNIT_FILES);
+ for (std::string service : generated_services) {
+ bool found = false;
+ for (auto& unit_file : unit_files) {
+ if(unit_file == service) {
+ found = true;
+ break;
+ }
+ }
+ EXPECT_TRUE(found) << "unit file not found: " << service;
+ }
+}
+
+/* TEST ssg_main() argv error */
+TEST_F(SsgMainTest, ssg_main_argv) {
+ FILE* fp;
+ std::vector argv_;
+ std::vector arguments = {
+ "ssg_main",
+ };
+
+ /* Create argv list for ssg_main. */
+ for (const auto& arg : arguments) {
+ argv_.push_back((char*)arg.data());
+ }
+
+ /* Call ssg_main */
+ EXPECT_EQ(ssg_main(argv_.size(), argv_.data()), 1);
+}
+
+/* TEST ssg_main() single asic */
+TEST_F(SsgMainTest, ssg_main_single_npu) {
+ ssg_main_test(1);
+}
+
+/* TEST ssg_main() multi(10) asic */
+TEST_F(SsgMainTest, ssg_main_10_npu) {
+ ssg_main_test(10);
+}
+
+/* TEST ssg_main() multi(40) asic */
+TEST_F(SsgMainTest, ssg_main_40_npu) {
+ ssg_main_test(40);
+}
+}
+
+int main(int argc, char** argv) {
+ testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/src/systemd-sonic-generator/systemd-sonic-generator.c b/src/systemd-sonic-generator/systemd-sonic-generator.c
index 1052e2db622a..96193b9fe3e3 100644
--- a/src/systemd-sonic-generator/systemd-sonic-generator.c
+++ b/src/systemd-sonic-generator/systemd-sonic-generator.c
@@ -9,14 +9,36 @@
#include
#include
-#define MAX_NUM_TARGETS 15
-#define MAX_NUM_INSTALL_LINES 15
+#define MAX_NUM_TARGETS 48
+#define MAX_NUM_INSTALL_LINES 48
#define MAX_NUM_UNITS 128
#define MAX_BUF_SIZE 512
-static const char* UNIT_FILE_PREFIX = "/usr/lib/systemd/system/";
-static const char* CONFIG_FILE = "/etc/sonic/generated_services.conf";
-static const char* MACHINE_CONF_FILE = "/host/machine.conf";
+const char* UNIT_FILE_PREFIX = "/usr/lib/systemd/system/";
+const char* CONFIG_FILE = "/etc/sonic/generated_services.conf";
+const char* MACHINE_CONF_FILE = "/host/machine.conf";
+const char* ASIC_CONF_FORMAT = "/usr/share/sonic/device/%s/asic.conf";
+
+const char* g_unit_file_prefix = NULL;
+const char* get_unit_file_prefix() {
+ return (g_unit_file_prefix) ? g_unit_file_prefix : UNIT_FILE_PREFIX;
+}
+
+const char* g_config_file = NULL;
+const char* get_config_file() {
+ return (g_config_file) ? g_config_file : CONFIG_FILE;
+}
+
+const char* g_machine_config_file = NULL;
+const char* get_machine_config_file() {
+ return (g_machine_config_file) ? g_machine_config_file : MACHINE_CONF_FILE;
+}
+
+const char* g_asic_conf_format = NULL;
+const char* get_asic_conf_format() {
+ return (g_asic_conf_format) ? g_asic_conf_format : ASIC_CONF_FORMAT;
+}
+
static int num_asics;
static char** multi_instance_services;
static int num_multi_inst;
@@ -128,7 +150,7 @@ static int get_install_targets_from_line(char* target_string, char* install_type
strcat(final_target, install_type);
free(target);
-
+
targets[num_targets + existing_targets] = strdup(final_target);
num_targets++;
}
@@ -152,12 +174,12 @@ static void replace_multi_inst_dep(char *src) {
ssize_t nread;
bool section_done = false;
char tmp_file_path[PATH_MAX];
-
+
/* Assumes that the service files has 3 sections,
* in the order: Unit, Service and Install.
- * Assumes that the timer file has 3 sectiosn,
+ * Assumes that the timer file has 3 sections,
* in the order: Unit, Timer and Install.
- * Read service dependency from Unit and Install
+ * Read service dependency from Unit and Install
* sections, replace if dependent on multi instance
* service.
*/
@@ -166,7 +188,7 @@ static void replace_multi_inst_dep(char *src) {
fp_tmp = fopen(tmp_file_path, "w");
while ((nread = getline(&line, &len, fp_src)) != -1 ) {
- if ((strstr(line, "[Service]") != NULL) ||
+ if ((strstr(line, "[Service]") != NULL) ||
(strstr(line, "[Timer]") != NULL)) {
section_done = true;
fputs(line,fp_tmp);
@@ -188,7 +210,7 @@ static void replace_multi_inst_dep(char *src) {
} else {
service_name = strdup(word);
service_name = strtok_r(service_name, ".", &save_ptr2);
- type = strtok_r(NULL, " ", &save_ptr2);
+ type = strtok_r(NULL, "\n", &save_ptr2);
if (is_multi_instance_service(word)) {
for(i = 0; i < num_asics; i++) {
snprintf(buf, MAX_BUF_SIZE, "%s=%s@%d.%s\n",
@@ -215,7 +237,7 @@ static void replace_multi_inst_dep(char *src) {
rename(tmp_file_path, src);
}
-static int get_install_targets(char* unit_file, char* targets[]) {
+int get_install_targets(char* unit_file, char* targets[]) {
/***
Returns install targets for a unit file
@@ -234,7 +256,7 @@ static int get_install_targets(char* unit_file, char* targets[]) {
char *instance_name;
char *dot_ptr;
- strcpy(file_path, UNIT_FILE_PREFIX);
+ strcpy(file_path, get_unit_file_prefix());
strcat(file_path, unit_file);
instance_name = strdup(unit_file);
@@ -280,7 +302,7 @@ static int get_install_targets(char* unit_file, char* targets[]) {
}
-static int get_unit_files(char* unit_files[]) {
+int get_unit_files(char* unit_files[]) {
/***
Reads a list of unit files to be installed from /etc/sonic/generated_services.conf
***/
@@ -289,18 +311,19 @@ static int get_unit_files(char* unit_files[]) {
size_t len = 0;
ssize_t read;
char *pos;
+ const char* config_file = get_config_file();
- fp = fopen(CONFIG_FILE, "r");
+ fp = fopen(config_file, "r");
if (fp == NULL) {
- fprintf(stderr, "Failed to open %s\n", CONFIG_FILE);
+ fprintf(stderr, "Failed to open %s\n", config_file);
exit(EXIT_FAILURE);
}
int num_unit_files = 0;
num_multi_inst = 0;
- multi_instance_services = malloc(MAX_NUM_UNITS * sizeof(char *));
+ multi_instance_services = calloc(MAX_NUM_UNITS, sizeof(char *));
while ((read = getline(&line, &len, fp)) != -1) {
if (num_unit_files >= MAX_NUM_UNITS) {
@@ -312,7 +335,7 @@ static int get_unit_files(char* unit_files[]) {
/* Get the multi-instance services */
pos = strchr(line, '@');
if (pos != NULL) {
- multi_instance_services[num_multi_inst] = malloc(strlen(line)*sizeof(char));
+ multi_instance_services[num_multi_inst] = calloc(strlen(line), sizeof(char));
strncpy(multi_instance_services[num_multi_inst], line, pos-line);
num_multi_inst++;
}
@@ -334,41 +357,33 @@ static int get_unit_files(char* unit_files[]) {
}
-static char* insert_instance_number(char* unit_file, int instance) {
+char* insert_instance_number(char* unit_file, int instance) {
/***
Adds an instance number to a systemd template name
E.g. given unit_file='example@.service', instance=3,
- returns a pointer to 'example@1.service'
+ returns a pointer to 'example@3.service'
***/
- char* prefix;
- char* suffix;
- char* instance_string;
char* instance_name;
- char* temp_unit_file;
-
- instance_string = malloc(2 * sizeof(char));
- snprintf(instance_string, 2, "%d", instance);
-
- instance_name = malloc(strlen(unit_file) + 2);
+ int ret;
+ int prefix_len;
+ const char *suffix = strchr(unit_file, '@');
+ if (!suffix) {
+ fprintf(stderr, "Invalid unit file %s for instance %d\n", unit_file, instance);
+ return NULL;
+ }
- if (instance_name == NULL) {
+ /***
+ suffix is "@.service", set suffix=".service"
+ prefix_len is length of "example@"
+ ***/
+ prefix_len = ++suffix - unit_file;
+ ret = asprintf(&instance_name, "%.*s%d%s", prefix_len, unit_file, instance, suffix);
+ if (ret == -1) {
fprintf(stderr, "Error creating instance %d of %s\n", instance, unit_file);
return NULL;
}
- temp_unit_file = strdup(unit_file);
- prefix = strtok(temp_unit_file, "@");
- suffix = strtok(NULL, "@");
-
- strcpy(instance_name, prefix);
- strcat(instance_name, "@");
- strcat(instance_name, instance_string);
- strcat(instance_name, suffix);
-
- free(instance_string);
- free(temp_unit_file);
-
return instance_name;
}
@@ -381,7 +396,7 @@ static int create_symlink(char* unit, char* target, char* install_dir, int insta
char* unit_instance;
int r;
- strcpy(src_path, UNIT_FILE_PREFIX);
+ strcpy(src_path, get_unit_file_prefix());
strcat(src_path, unit);
if (instance < 0) {
@@ -462,7 +477,7 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) {
assert(unit_file);
assert(target);
-
+
if ((num_asics > 1) && strstr(unit_file, "@") != NULL) {
@@ -476,16 +491,16 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) {
}
r = create_symlink(unit_file, target_instance, install_dir, i);
- if (r < 0)
+ if (r < 0)
fprintf(stderr, "Error installing %s for target %s\n", unit_file, target_instance);
-
+
free(target_instance);
- }
+ }
}
else {
r = create_symlink(unit_file, target, install_dir, -1);
- if (r < 0)
+ if (r < 0)
fprintf(stderr, "Error installing %s for target %s\n", unit_file, target);
}
@@ -493,7 +508,7 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) {
}
-static int get_num_of_asic() {
+int get_num_of_asic() {
/***
Determines if the current platform is single or multi-ASIC
***/
@@ -507,11 +522,12 @@ static int get_num_of_asic() {
char asic_file[512];
char* str_num_asic;
int num_asic = 1;
+ const char* machine_config_file = get_machine_config_file();
- fp = fopen(MACHINE_CONF_FILE, "r");
+ fp = fopen(machine_config_file, "r");
if (fp == NULL) {
- fprintf(stderr, "Failed to open %s\n", MACHINE_CONF_FILE);
+ fprintf(stderr, "Failed to open %s\n", machine_config_file);
exit(EXIT_FAILURE);
}
@@ -524,10 +540,9 @@ static int get_num_of_asic() {
break;
}
}
-
fclose(fp);
if(platform != NULL) {
- snprintf(asic_file, 512, "/usr/share/sonic/device/%s/asic.conf", platform);
+ snprintf(asic_file, 512, get_asic_conf_format(), platform);
fp = fopen(asic_file, "r");
if (fp != NULL) {
while ((nread = getline(&line, &len, fp)) != -1) {
@@ -549,8 +564,7 @@ static int get_num_of_asic() {
}
-
-int main(int argc, char **argv) {
+int ssg_main(int argc, char **argv) {
char* unit_files[MAX_NUM_UNITS];
char install_dir[PATH_MAX];
char* targets[MAX_NUM_TARGETS];
@@ -567,10 +581,8 @@ int main(int argc, char **argv) {
}
num_asics = get_num_of_asic();
-
strcpy(install_dir, argv[1]);
strcat(install_dir, "/");
-
num_unit_files = get_unit_files(unit_files);
// For each unit file, get the installation targets and install the unit
@@ -610,3 +622,10 @@ int main(int argc, char **argv) {
return 0;
}
+
+
+#ifndef _SSG_UNITTEST
+int main(int argc, char **argv) {
+ return ssg_main(argc, argv);
+}
+#endif
diff --git a/src/systemd-sonic-generator/systemd-sonic-generator.h b/src/systemd-sonic-generator/systemd-sonic-generator.h
new file mode 100644
index 000000000000..25c179caa0bf
--- /dev/null
+++ b/src/systemd-sonic-generator/systemd-sonic-generator.h
@@ -0,0 +1,35 @@
+/*------------------------------------------------------------------
+ * systemd-sonic-generator.h - Header file
+ *
+ * Initial: Apr 2021
+ *
+ * Copyright (c) 2021 by Cisco Systems, Inc.
+ *------------------------------------------------------------------
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* expose global vars for testing purpose */
+extern const char* UNIT_FILE_PREFIX;
+extern const char* CONFIG_FILE;
+extern const char* MACHINE_CONF_FILE;
+extern const char* ASIC_CONF_FORMAT;
+extern const char* g_unit_file_prefix;
+extern const char* g_config_file;
+extern const char* g_machine_config_file;
+extern const char* g_asic_conf_format;
+
+/* C-functions under test */
+extern const char* get_unit_file_prefix();
+extern const char* get_config_file();
+extern const char* get_machine_config_file();
+extern const char* get_asic_conf_format();
+extern char* insert_instance_number(char* unit_file, int instance);
+extern int ssg_main(int argc, char** argv);
+extern int get_num_of_asic();
+extern int get_install_targets(char* unit_file, char* targets[]);
+extern int get_unit_files(char* unit_files[]);
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/systemd-sonic-generator/tests/testfiles/multi_inst_a.service b/src/systemd-sonic-generator/tests/testfiles/multi_inst_a.service
new file mode 100644
index 000000000000..500cb0ae164e
--- /dev/null
+++ b/src/systemd-sonic-generator/tests/testfiles/multi_inst_a.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Multi Instance A Test service
+StartLimitIntervalSec=1200
+StartLimitBurst=3
+[Service]
+User=root
+ExecStop=/usr/bin/test.sh stop
+[Install]
+WantedBy=multi-user.target
diff --git a/src/systemd-sonic-generator/tests/testfiles/multi_inst_a@.service b/src/systemd-sonic-generator/tests/testfiles/multi_inst_a@.service
new file mode 100644
index 000000000000..816d698b4d1b
--- /dev/null
+++ b/src/systemd-sonic-generator/tests/testfiles/multi_inst_a@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Multi INstance A test Service
+
+After=multi_inst_a.service
+StartLimitIntervalSec=1200
+StartLimitBurst=3
+[Service]
+User=root
+ExecStop=/usr/bin/test.sh stop %i
+Restart=always
+RestartSec=30
+[Install]
+WantedBy=multi-user.target
diff --git a/src/systemd-sonic-generator/tests/testfiles/multi_inst_b.service b/src/systemd-sonic-generator/tests/testfiles/multi_inst_b.service
new file mode 100644
index 000000000000..04960be66c4e
--- /dev/null
+++ b/src/systemd-sonic-generator/tests/testfiles/multi_inst_b.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Multi instance b Test service
+
+Requires=multi_inst_a.service
+StartLimitIntervalSec=1200
+StartLimitBurst=3
+[Service]
+User=root
+ExecStop=/usr/bin/test.sh stop
+Restart=always
+RestartSec=30
+[Install]
+WantedBy=multi-user.target
diff --git a/src/systemd-sonic-generator/tests/testfiles/multi_inst_b@.service b/src/systemd-sonic-generator/tests/testfiles/multi_inst_b@.service
new file mode 100644
index 000000000000..dee76391da98
--- /dev/null
+++ b/src/systemd-sonic-generator/tests/testfiles/multi_inst_b@.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=Multi instance b Test service
+Requires=multi_inst_a@%i.service
+StartLimitIntervalSec=1200
+StartLimitBurst=3
+[Service]
+User=root
+ExecStart=/usr/local/bin/test.sh wait %i
+Restart=always
+RestartSec=30
+[Install]
+WantedBy=multi-user.target
diff --git a/src/systemd-sonic-generator/tests/testfiles/single_inst.service b/src/systemd-sonic-generator/tests/testfiles/single_inst.service
new file mode 100644
index 000000000000..7f0fd7252456
--- /dev/null
+++ b/src/systemd-sonic-generator/tests/testfiles/single_inst.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=Platform monitor container
+Requires=multi_inst_a.service
+StartLimitIntervalSec=1200
+StartLimitBurst=3
+[Service]
+ExecStart=/usr/bin/test.sh wait
+Restart=always
+RestartSec=30
+[Install]
+WantedBy=multi-user.target
diff --git a/src/systemd-sonic-generator/tests/testfiles/test.service b/src/systemd-sonic-generator/tests/testfiles/test.service
new file mode 100644
index 000000000000..e8b37f641fd3
--- /dev/null
+++ b/src/systemd-sonic-generator/tests/testfiles/test.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Multi ASIC Test service
+After=multi_inst_a.service multi_inst_b.service
+Before=single_inst.service
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/bin/test.sh start
+[Install]
+WantedBy=multi-user.target
diff --git a/src/systemd-sonic-generator/tests/testfiles/test.timer b/src/systemd-sonic-generator/tests/testfiles/test.timer
new file mode 100644
index 000000000000..254bec362ac3
--- /dev/null
+++ b/src/systemd-sonic-generator/tests/testfiles/test.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=Test Timer service
+After=multi_inst_b.service
+[Timer]
+OnUnitActiveSec=0 sec
+OnBootSec=3min 30 sec
+Unit=snmp.service
+[Install]
+WantedBy=timers.target
+WantedBy=multi_inst_b.service