From 4bd1dc541446c844123272f076da529099192b0c Mon Sep 17 00:00:00 2001 From: Aryeh Feigin <101218333+arfeigin@users.noreply.github.com> Date: Fri, 10 Mar 2023 18:41:06 +0200 Subject: [PATCH 01/25] Fast reboot finalizer (#1213) Updates PR #1196 according to required fast-reboot state-db change. Update syncd_init_common to check if fast-reboot is enabled according to the new value for FAST_REBOOT entry in STATE_DB. This PR should come along with the following PRs: sonic-net/sonic-utilities#2621 sonic-net/sonic-buildimage#13484 sonic-net/sonic-swss-common#742 sonic-net/sonic-platform-daemons#335 This set of PRs solves the issue sonic-net/sonic-buildimage#13251 --- syncd/scripts/syncd_init_common.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/syncd/scripts/syncd_init_common.sh b/syncd/scripts/syncd_init_common.sh index a1e538890..849221975 100644 --- a/syncd/scripts/syncd_init_common.sh +++ b/syncd/scripts/syncd_init_common.sh @@ -52,8 +52,8 @@ case "$(cat /proc/cmdline)" in ;; *SONIC_BOOT_TYPE=fast*|*fast-reboot*) # check that the key exists - SYSTEM_FAST_REBOOT=`sonic-db-cli STATE_DB GET "FAST_RESTART_ENABLE_TABLE|system"` - if [[ ${SYSTEM_FAST_REBOOT} == "enable" ]]; then + SYSTEM_FAST_REBOOT=`sonic-db-cli STATE_DB hget "FAST_RESTART_ENABLE_TABLE|system" enable` + if [[ x"${SYSTEM_FAST_REBOOT}" == x"true" ]]; then FAST_REBOOT='yes' else FAST_REBOOT='no' From acd57ae628a2c8f99851ce1a7c85bf154a88f972 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Tue, 14 Mar 2023 02:58:34 +0800 Subject: [PATCH 02/25] Ignore removing switch for mellanox platform due to known limitation (#1216) * Ignore removing switch for mellanox platform due to known limitation * Fix review comment * Fix review comment --- configure.ac | 4 ++++ syncd/Syncd.cpp | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 409eccfba..e7ccb4ee2 100644 --- a/configure.ac +++ b/configure.ac @@ -17,6 +17,10 @@ AX_ADD_AM_MACRO_STATIC([]) AM_CONDITIONAL(SONIC_ASIC_PLATFORM_BAREFOOT, test x$CONFIGURED_PLATFORM = xbarefoot) AM_CONDITIONAL(SONIC_ASIC_PLATFORM_BROADCOM, test x$CONFIGURED_PLATFORM = xbroadcom) +AM_CONDITIONAL(SONIC_ASIC_PLATFORM_MELLANOX, test x$CONFIGURED_PLATFORM = xmellanox) + +AM_COND_IF([SONIC_ASIC_PLATFORM_MELLANOX], + AC_DEFINE([MELLANOX], [1], [Define to 1 on Mellanox Platform])) AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging], diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index 78a1ea2d0..f6ebd904f 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -1,3 +1,4 @@ +#include "config.h" #include "Syncd.h" #include "VidManager.h" #include "NotificationHandler.h" @@ -4738,7 +4739,15 @@ void Syncd::run() m_mdioIpcServer->stopMdioThread(); - sai_status_t status = removeAllSwitches(); + sai_status_t status = SAI_STATUS_SUCCESS; +#ifdef MELLANOX + if (shutdownType != SYNCD_RESTART_TYPE_COLD) + { + status = removeAllSwitches(); + } +#else + status = removeAllSwitches(); +#endif // Stop notification thread after removing switch m_processor->stopNotificationsProcessingThread(); From 92c86676375aaf00cde13fafb658dbfa00cbbcd6 Mon Sep 17 00:00:00 2001 From: Liu Shilong Date: Fri, 17 Mar 2023 10:28:18 +0800 Subject: [PATCH 03/25] [ci] Continue on error when running test in CI build. (#1222) * [ci] Continue on error when running test. * [ci] Allow partially succeeded builds when downaloading swss-common --- .azure-pipelines/build-docker-sonic-vs-template.yml | 1 + .azure-pipelines/build-swss-template.yml | 1 + .azure-pipelines/build-template.yml | 1 + .azure-pipelines/test-docker-sonic-vs-template.yml | 4 +++- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.azure-pipelines/build-docker-sonic-vs-template.yml b/.azure-pipelines/build-docker-sonic-vs-template.yml index 62a4807ff..98b4c210e 100644 --- a/.azure-pipelines/build-docker-sonic-vs-template.yml +++ b/.azure-pipelines/build-docker-sonic-vs-template.yml @@ -47,6 +47,7 @@ jobs: path: $(Build.ArtifactStagingDirectory)/download runVersion: 'latestFromBranch' runBranch: 'refs/heads/$(BUILD_BRANCH)' + allowPartiallySucceededBuilds: true displayName: "Download sonic swss common deb packages" - task: DownloadPipelineArtifact@2 inputs: diff --git a/.azure-pipelines/build-swss-template.yml b/.azure-pipelines/build-swss-template.yml index a75646061..90850974a 100644 --- a/.azure-pipelines/build-swss-template.yml +++ b/.azure-pipelines/build-swss-template.yml @@ -78,6 +78,7 @@ jobs: artifact: ${{ parameters.swss_common_artifact_name }} runVersion: 'latestFromBranch' runBranch: 'refs/heads/$(BUILD_BRANCH)' + allowPartiallySucceededBuilds: true path: $(Build.ArtifactStagingDirectory)/download patterns: | libswsscommon_1.0.0_*.deb diff --git a/.azure-pipelines/build-template.yml b/.azure-pipelines/build-template.yml index c4ddaf51c..a243bb179 100644 --- a/.azure-pipelines/build-template.yml +++ b/.azure-pipelines/build-template.yml @@ -143,6 +143,7 @@ jobs: artifact: ${{ parameters.swss_common_artifact_name }} runVersion: 'latestFromBranch' runBranch: 'refs/heads/$(BUILD_BRANCH)' + allowPartiallySucceededBuilds: true path: $(Build.ArtifactStagingDirectory)/download displayName: "Download sonic swss common deb packages" - script: | diff --git a/.azure-pipelines/test-docker-sonic-vs-template.yml b/.azure-pipelines/test-docker-sonic-vs-template.yml index 144a96879..77e3b975f 100644 --- a/.azure-pipelines/test-docker-sonic-vs-template.yml +++ b/.azure-pipelines/test-docker-sonic-vs-template.yml @@ -50,6 +50,7 @@ jobs: path: $(Build.ArtifactStagingDirectory)/download runVersion: 'latestFromBranch' runBranch: 'refs/heads/$(BUILD_BRANCH)' + allowPartiallySucceededBuilds: true displayName: "Download sonic swss common deb packages" - script: | @@ -95,7 +96,8 @@ jobs: fi rm -rf $(Build.ArtifactStagingDirectory)/download displayName: "Run vs tests" - continueOnError: ${{ parameters.asan }} + ${{ if or(ne(variables['Build.Reason'], 'PullRequest'), eq(parameters.asan, true)) }}: + continueOnError: true - task: PublishTestResults@2 inputs: From 60fa682fcce68ef9100bb161a05b19cb5bed0c82 Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Thu, 30 Mar 2023 08:27:50 -0700 Subject: [PATCH 04/25] Update build pipeline to build for Bullseye (#1225) * Update build pipeline to build for Bullseye With the merge of sonic-net/sonic-buildimage#13294, docker-sonic-vs is now based on Bullseye. Switch to building for Bullseye to match that change. Signed-off-by: Saikrishna Arcot * Update .NET core repo URL Signed-off-by: Saikrishna Arcot * Fix dependencies Signed-off-by: Saikrishna Arcot * Fix up Dockerfile Signed-off-by: Saikrishna Arcot --------- Signed-off-by: Saikrishna Arcot --- .azure-pipelines/build-swss-template.yml | 15 ++++++--------- .azure-pipelines/build-template.yml | 11 ++++------- .azure-pipelines/docker-sonic-vs/Dockerfile | 20 ++++++++------------ azure-pipelines.yml | 2 +- 4 files changed, 19 insertions(+), 29 deletions(-) diff --git a/.azure-pipelines/build-swss-template.yml b/.azure-pipelines/build-swss-template.yml index 90850974a..1ffa621a6 100644 --- a/.azure-pipelines/build-swss-template.yml +++ b/.azure-pipelines/build-swss-template.yml @@ -60,15 +60,12 @@ jobs: - script: | set -ex sudo apt-get update - sudo apt-get install -y libhiredis0.14 libhiredis-dev - sudo apt-get install -y libzmq5 libzmq3-dev - sudo apt-get install -qq -y \ - libhiredis-dev \ - swig3.0 - sudo apt-get install -y libdbus-1-3 - sudo apt-get install -y libteam-dev \ - libteam5 \ - libteamdctl0 + sudo apt-get install -y \ + libhiredis-dev \ + libzmq3-dev \ + swig4.0 \ + libdbus-1-dev \ + libteam-dev displayName: "Install dependencies" - task: DownloadPipelineArtifact@2 inputs: diff --git a/.azure-pipelines/build-template.yml b/.azure-pipelines/build-template.yml index a243bb179..41bda68c0 100644 --- a/.azure-pipelines/build-template.yml +++ b/.azure-pipelines/build-template.yml @@ -74,21 +74,18 @@ jobs: sudo apt-get update sudo apt-get install -qq -y \ qtbase5-dev \ - libdbus-glib-1-2 \ libdbus-glib-1-dev \ libpcsclite-dev \ docbook-to-man \ docbook-utils \ aspell-en \ - libhiredis0.14 \ libhiredis-dev \ libnl-3-dev \ libnl-genl-3-dev \ libnl-route-3-dev \ libnl-nf-3-dev \ libnl-cli-3-dev \ - swig3.0 \ - libpython2.7-dev \ + swig4.0 \ libzmq5 \ libzmq3-dev \ autoconf-archive @@ -161,7 +158,7 @@ jobs: if [ '${{ parameters.asan }}' == True ]; then extraflags='--enable-asan' fi - DEB_BUILD_OPTIONS=nocheck fakeroot debian/rules DEB_CONFIGURE_EXTRA_FLAGS=$extraflags CFLAGS="" CXXFLAGS="" binary-syncd-vs + DEB_BUILD_OPTIONS=nocheck fakeroot debian/rules DEB_CONFIGURE_EXTRA_FLAGS=$extraflags DEB_BUILD_PROFILES=nopython2 CFLAGS="" CXXFLAGS="" binary-syncd-vs mv ../*.deb . displayName: "Compile sonic sairedis with coverage enabled" - script: | @@ -196,9 +193,9 @@ jobs: set -ex # Install .NET CORE curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - - sudo apt-add-repository https://packages.microsoft.com/debian/10/prod + sudo apt-add-repository https://packages.microsoft.com/debian/11/prod sudo apt-get update - sudo apt-get install -y dotnet-sdk-5.0 + sudo apt-get install -y dotnet-sdk-7.0 displayName: "Install .NET CORE" - task: PublishCodeCoverageResults@1 inputs: diff --git a/.azure-pipelines/docker-sonic-vs/Dockerfile b/.azure-pipelines/docker-sonic-vs/Dockerfile index 1a9984fcb..636baa44b 100644 --- a/.azure-pipelines/docker-sonic-vs/Dockerfile +++ b/.azure-pipelines/docker-sonic-vs/Dockerfile @@ -5,17 +5,13 @@ ARG need_dbg ADD ["debs", "/debs"] -RUN dpkg --purge python-swsscommon python3-swsscommon swss libsairedis sonic-db-cli libswsscommon libsaimetadata libsaivs syncd-vs +RUN dpkg -i /debs/libswsscommon_1.0.0_amd64.deb \ + /debs/python3-swsscommon_1.0.0_amd64.deb \ + /debs/sonic-db-cli_1.0.0_amd64.deb \ + /debs/libsaimetadata_1.0.0_amd64.deb \ + /debs/libsairedis_1.0.0_amd64.deb \ + /debs/libsaivs_1.0.0_amd64.deb \ + /debs/syncd-vs_1.0.0_amd64.deb \ + /debs/swss_1.0.0_amd64.deb -RUN dpkg -i /debs/libswsscommon_1.0.0_amd64.deb -RUN dpkg -i /debs/python-swsscommon_1.0.0_amd64.deb -RUN dpkg -i /debs/python3-swsscommon_1.0.0_amd64.deb -RUN dpkg -i /debs/sonic-db-cli_1.0.0_amd64.deb - -RUN dpkg -i /debs/libsaimetadata_1.0.0_amd64.deb -RUN dpkg -i /debs/libsairedis_1.0.0_amd64.deb -RUN dpkg -i /debs/libsaivs_1.0.0_amd64.deb -RUN dpkg -i /debs/syncd-vs_1.0.0_amd64.deb RUN if [ "$need_dbg" = "y" ] ; then dpkg -i /debs/syncd-vs-dbg_1.0.0_amd64.deb ; fi - -RUN dpkg -i /debs/swss_1.0.0_amd64.deb diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1786681e4..620be7e5d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -37,7 +37,7 @@ resources: parameters: - name: debian_version type: string - default: buster + default: bullseye variables: - name: BUILD_BRANCH ${{ if eq(variables['Build.Reason'], 'PullRequest') }}: From e31158717ebc62c475197f43dd93a11a4fa15683 Mon Sep 17 00:00:00 2001 From: Stepan Blyshchak <38952541+stepanblyschak@users.noreply.github.com> Date: Tue, 11 Apr 2023 03:23:12 +0300 Subject: [PATCH 05/25] [nvidia] extend syncd start script to pick extra SAI profile values (#1229) * In order to achive functionality that allows other applications to write additional parameters to sai.profile to customize it's behaviour per need. --- syncd/scripts/syncd_init_common.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/syncd/scripts/syncd_init_common.sh b/syncd/scripts/syncd_init_common.sh index 849221975..19b1d620c 100644 --- a/syncd/scripts/syncd_init_common.sh +++ b/syncd/scripts/syncd_init_common.sh @@ -228,6 +228,11 @@ config_syncd_mlnx() if [ ! -d "$SDK_DUMP_PATH" ]; then mkdir -p "$SDK_DUMP_PATH" fi + + # Pick extra SAI profile parameters generated by other applications + if [[ -f /tmp/sai_extra.profile ]]; then + cat /tmp/sai_extra.profile >> /tmp/sai.profile + fi } config_syncd_centec() From dc93d4c7c5744bce4ad252a7b54681567821f981 Mon Sep 17 00:00:00 2001 From: Lawrence Lee Date: Wed, 19 Apr 2023 15:38:45 -0700 Subject: [PATCH 06/25] Use SAI_STATUS_ITEM_NOT_FOUND when key not found (#1224) * Use SAI_STATUS_ITEM_NOT_FOUND when key not found * Add unit tests for Meta SAI validation * generate coverage info for Meta.cpp Signed-off-by: Lawrence Lee --- .azure-pipelines/build-template.yml | 9 +- meta/Meta.cpp | 36 +-- unittest/meta/TestMeta.cpp | 438 +++++++++++++++++++++++++++- 3 files changed, 463 insertions(+), 20 deletions(-) diff --git a/.azure-pipelines/build-template.yml b/.azure-pipelines/build-template.yml index 41bda68c0..4193faa90 100644 --- a/.azure-pipelines/build-template.yml +++ b/.azure-pipelines/build-template.yml @@ -183,7 +183,14 @@ jobs: make check gcovr --version find SAI/meta -name "*.gc*" | xargs rm -vf - gcovr -r ./ -e ".*/SAI/.*" -e ".+/json.hpp" -e "swss/.+" -e ".*/.libs/.*" -e ".*/debian/.*" --exclude-unreachable-branches -x --xml-pretty -o coverage.xml + gcov_dirs=$(find . -path "*.libs*gcda" | xargs dirname | sort -u | cut -c"3-") + for dir in ${gcov_dirs}; do + source_dir=$(dirname $dir) + output_file="coverage-$source_dir.json" + gcovr --exclude-unreachable-branches --json-pretty -o $output_file --object-directory $source_dir $dir + done + gcovr -r ./ -e ".*/SAI/.*" -e ".+/json.hpp" -e "swss/.+" -e ".*/.libs/.*" -e ".*/debian/.*" --exclude-unreachable-branches --json-pretty -o coverage-all.json + gcovr -a "coverage-*.json" -x --xml-pretty -o coverage.xml displayName: "Run sonic sairedis unit tests" - publish: $(System.DefaultWorkingDirectory)/ artifact: ${{ parameters.artifact_name }} diff --git a/meta/Meta.cpp b/meta/Meta.cpp index 044b09c47..78330cc9a 100644 --- a/meta/Meta.cpp +++ b/meta/Meta.cpp @@ -3258,7 +3258,7 @@ sai_status_t Meta::meta_generic_validation_remove( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } auto info = sai_metadata_get_object_type_info(meta_key.objecttype); @@ -3540,7 +3540,7 @@ sai_status_t Meta::meta_sai_validate_oid( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_oid).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } return SAI_STATUS_SUCCESS; @@ -3883,7 +3883,7 @@ sai_status_t Meta::meta_sai_validate_mcast_fdb_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_bv).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } // check if fdb entry exists @@ -3910,7 +3910,7 @@ sai_status_t Meta::meta_sai_validate_mcast_fdb_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_fdb).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } // fdb entry is valid @@ -3980,7 +3980,7 @@ sai_status_t Meta::meta_sai_validate_neighbor_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_rif).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } sai_object_meta_key_t meta_key_neighbor = { .objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, .objectkey = { .key = { .neighbor_entry = *neighbor_entry } } }; @@ -4005,7 +4005,7 @@ sai_status_t Meta::meta_sai_validate_neighbor_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_neighbor).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } // neighbor entry is valid @@ -4087,7 +4087,7 @@ sai_status_t Meta::meta_sai_validate_route_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_vr).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } // check if route entry exists @@ -4114,7 +4114,7 @@ sai_status_t Meta::meta_sai_validate_route_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_route).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } return SAI_STATUS_SUCCESS; @@ -4210,7 +4210,7 @@ sai_status_t Meta::meta_sai_validate_l2mc_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_bv).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } // check if l2mc entry exists @@ -4237,7 +4237,7 @@ sai_status_t Meta::meta_sai_validate_l2mc_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_route).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } return SAI_STATUS_SUCCESS; @@ -4333,7 +4333,7 @@ sai_status_t Meta::meta_sai_validate_ipmc_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_bv).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } // check if ipmc entry exists @@ -4360,7 +4360,7 @@ sai_status_t Meta::meta_sai_validate_ipmc_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_route).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } return SAI_STATUS_SUCCESS; @@ -4416,7 +4416,7 @@ sai_status_t Meta::meta_sai_validate_nat_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_vr).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } // check if NAT entry exists @@ -4441,7 +4441,7 @@ sai_status_t Meta::meta_sai_validate_nat_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_nat).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } return SAI_STATUS_SUCCESS; @@ -4515,7 +4515,7 @@ sai_status_t Meta::meta_sai_validate_my_sid_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_vr).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } // check if my_sid_entry exists @@ -4540,7 +4540,7 @@ sai_status_t Meta::meta_sai_validate_my_sid_entry( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key_my_sid_entry).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } return SAI_STATUS_SUCCESS; @@ -5722,7 +5722,7 @@ sai_status_t Meta::meta_generic_validation_set( META_LOG_ERROR(md, "object key %s doesn't exist", sai_serialize_object_meta_key(meta_key).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } // object exists in DB so we can do "set" operation @@ -6034,7 +6034,7 @@ sai_status_t Meta::meta_generic_validation_get( SWSS_LOG_ERROR("object key %s doesn't exist", sai_serialize_object_meta_key(meta_key).c_str()); - return SAI_STATUS_INVALID_PARAMETER; + return SAI_STATUS_ITEM_NOT_FOUND; } auto info = sai_metadata_get_object_type_info(meta_key.objecttype); diff --git a/unittest/meta/TestMeta.cpp b/unittest/meta/TestMeta.cpp index eebc4f5d2..3f2c14234 100644 --- a/unittest/meta/TestMeta.cpp +++ b/unittest/meta/TestMeta.cpp @@ -3,18 +3,454 @@ #include "MetaTestSaiInterface.h" #include +#include #include #include +#define VLAN_ID 2 + using namespace saimeta; +class MetaTest : public ::testing::Test +{ + protected: + sai_object_id_t m_switch_id, m_vlan_id, m_vr_id, m_port_id, m_rif_id; + std::vector m_attrs; + sai_attribute_t m_attr; + Meta *m_meta; + + void SetupMeta() + { + SWSS_LOG_ENTER(); + m_attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + m_attr.value.booldata = true; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_meta->create(SAI_OBJECT_TYPE_SWITCH, &m_switch_id, SAI_NULL_OBJECT_ID, 1, &m_attr)); + + m_attr.id = SAI_VLAN_ATTR_VLAN_ID; + m_attr.value.u16 = VLAN_ID; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_meta->create(SAI_OBJECT_TYPE_VLAN, &m_vlan_id, m_switch_id, 1, &m_attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_meta->create(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, &m_vr_id, m_switch_id, 0, &m_attr)); + } + void CreatePort() + { + SWSS_LOG_ENTER(); + std::vector attrs; + sai_attribute_t attr; + + uint32_t list[1] = { 2 }; + + attr.id = SAI_PORT_ATTR_HW_LANE_LIST; + attr.value.u32list.count = 1; + attr.value.u32list.list = list; + attrs.push_back(attr); + + attr.id = SAI_PORT_ATTR_SPEED; + attr.value.u32 = 10000; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_meta->create(SAI_OBJECT_TYPE_PORT, &m_port_id, m_switch_id, (uint32_t)attrs.size(), attrs.data())); + } + void CreateRif() + { + SWSS_LOG_ENTER(); + std::vector attrs; + sai_attribute_t attr; + + attr.id = SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID; + attr.value.oid = m_vr_id; + attrs.push_back(attr); + + attr.id = SAI_ROUTER_INTERFACE_ATTR_TYPE; + attr.value.s32 = SAI_ROUTER_INTERFACE_TYPE_PORT; + attrs.push_back(attr); + + attr.id = SAI_ROUTER_INTERFACE_ATTR_PORT_ID; + attr.value.oid = m_port_id; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_meta->create(SAI_OBJECT_TYPE_ROUTER_INTERFACE, &m_rif_id, m_switch_id, (uint32_t)attrs.size(), attrs.data())); + } + sai_fdb_entry_t GenFdbEntry() + { + SWSS_LOG_ENTER(); + m_attrs.clear(); + + sai_fdb_entry_t fdb_entry; + memset(&fdb_entry, 0, sizeof(fdb_entry)); + fdb_entry.switch_id = m_switch_id; + fdb_entry.bv_id = m_vlan_id; + + m_attr.id = SAI_FDB_ENTRY_ATTR_TYPE; + m_attr.value.s32 = SAI_FDB_ENTRY_TYPE_STATIC; + m_attrs.push_back(m_attr); + return fdb_entry; + } + sai_mcast_fdb_entry_t GenMcastFdbEntry() + { + SWSS_LOG_ENTER(); + m_attrs.clear(); + sai_object_id_t l2mc_group_id = 0; + m_meta->create(SAI_OBJECT_TYPE_L2MC_GROUP, &l2mc_group_id, m_switch_id, 0, 0); + + sai_mcast_fdb_entry_t mcast_fdb_entry; + memset(&mcast_fdb_entry, 0, sizeof(mcast_fdb_entry)); + mcast_fdb_entry.bv_id = m_vlan_id; + mcast_fdb_entry.switch_id = m_switch_id; + + m_attr.id = SAI_MCAST_FDB_ENTRY_ATTR_GROUP_ID; + m_attr.value.oid = l2mc_group_id; + m_attrs.push_back(m_attr); + + m_attr.id = SAI_MCAST_FDB_ENTRY_ATTR_PACKET_ACTION; + m_attr.value.s32 = SAI_PACKET_ACTION_FORWARD; + m_attrs.push_back(m_attr); + return mcast_fdb_entry; + } + sai_neighbor_entry_t GenNeighEntry() + { + SWSS_LOG_ENTER(); + CreatePort(); + CreateRif(); + + sai_neighbor_entry_t neigh_entry; + memset(&neigh_entry, 0, sizeof(neigh_entry)); + neigh_entry.switch_id = m_switch_id; + neigh_entry.ip_address.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, std::string("1.1.1.1").c_str(), &neigh_entry.ip_address.addr.ip4); + neigh_entry.rif_id = m_rif_id; + + m_attrs.clear(); + sai_mac_t mac = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + m_attr.id = SAI_NEIGHBOR_ENTRY_ATTR_DST_MAC_ADDRESS; + memcpy(m_attr.value.mac, mac, 6); + m_attrs.push_back(m_attr); + + m_attr.id = SAI_NEIGHBOR_ENTRY_ATTR_PACKET_ACTION; + m_attr.value.s32 = SAI_PACKET_ACTION_FORWARD; + m_attrs.push_back(m_attr); + + return neigh_entry; + } + sai_route_entry_t GenRouteEntry() + { + SWSS_LOG_ENTER(); + m_attrs.clear(); + sai_route_entry_t route_entry; + memset(&route_entry, 0, sizeof(route_entry)); + + route_entry.switch_id = m_switch_id; + + route_entry.vr_id = m_vr_id; + + route_entry.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, std::string("255.255.255.255").c_str(), &route_entry.destination.mask.ip4); + inet_pton(AF_INET, std::string("1.1.1.1").c_str(), &route_entry.destination.addr.ip4); + return route_entry; + } + sai_l2mc_entry_t GenL2MCEntry() + { + SWSS_LOG_ENTER(); + m_attrs.clear(); + sai_l2mc_entry_t l2mc_entry; + memset(&l2mc_entry, 0, sizeof(l2mc_entry)); + + l2mc_entry.bv_id = m_vlan_id; + l2mc_entry.switch_id = m_switch_id; + + m_attr.id = SAI_L2MC_ENTRY_ATTR_PACKET_ACTION; + m_attr.value.s32 = SAI_PACKET_ACTION_FORWARD; + m_attrs.push_back(m_attr); + + return l2mc_entry; + + } + sai_ipmc_entry_t GenIPMCEntry() + { + SWSS_LOG_ENTER(); + m_attrs.clear(); + sai_object_id_t rpfGroupId = 0; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_meta->create(SAI_OBJECT_TYPE_RPF_GROUP, &rpfGroupId, m_switch_id, 0, m_attrs.data())); + + sai_ipmc_entry_t ipmc_entry; + memset(&ipmc_entry, 0, sizeof(ipmc_entry)); + + ipmc_entry.switch_id = m_switch_id; + ipmc_entry.vr_id = m_vr_id; + + m_attr.id = SAI_IPMC_ENTRY_ATTR_PACKET_ACTION; + m_attr.value.s32 = SAI_PACKET_ACTION_FORWARD; + m_attrs.push_back(m_attr); + + m_attr.id = SAI_IPMC_ENTRY_ATTR_RPF_GROUP_ID; + m_attr.value.oid = rpfGroupId; + m_attrs.push_back(m_attr); + + return ipmc_entry; + } + sai_nat_entry_t GenNATEntry() + { + SWSS_LOG_ENTER(); + m_attrs.clear(); + + sai_nat_entry_t nat_entry; + + memset(&nat_entry, 0, sizeof(nat_entry)); + + nat_entry.switch_id = m_switch_id; + nat_entry.vr_id = m_vr_id; + + m_attr.id = SAI_NAT_ENTRY_ATTR_NAT_TYPE; + m_attr.value.s32 = SAI_NAT_TYPE_NONE; + m_attrs.push_back(m_attr); + + return nat_entry; + } + sai_my_sid_entry_t GenMySIDEntry() + { + SWSS_LOG_ENTER(); + m_attrs.clear(); + + sai_my_sid_entry_t my_sid_entry; + + memset(&my_sid_entry, 0, sizeof(my_sid_entry)); + + my_sid_entry.switch_id = m_switch_id; + my_sid_entry.vr_id = m_vr_id; + + m_attr.id = SAI_MY_SID_ENTRY_ATTR_ENDPOINT_BEHAVIOR; + m_attr.value.s32 = SAI_MY_SID_ENTRY_ENDPOINT_BEHAVIOR_E; + m_attrs.push_back(m_attr); + + return my_sid_entry; + } + void SetUp() override + { + m_meta = new Meta(std::make_shared()); + SetupMeta(); + } + void TearDown() override + { + m_attrs.clear(); + } +}; + +TEST_F(MetaTest, create_duplicate_fdb_entry) +{ + sai_fdb_entry_t fdb_entry = GenFdbEntry(); + sai_status_t status = m_meta->create(&fdb_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + status = m_meta->create(&fdb_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_ALREADY_EXISTS, status); +} + +TEST_F(MetaTest, remove_nonexistent_fdb_entry) +{ + sai_fdb_entry_t fdb_entry = GenFdbEntry(); + sai_status_t status = m_meta->remove(&fdb_entry); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, create_duplicate_mcast_fdb_entry) +{ + sai_mcast_fdb_entry_t mcast_fdb_entry = GenMcastFdbEntry(); + sai_status_t status = m_meta->create(&mcast_fdb_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + status = m_meta->create(&mcast_fdb_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_ALREADY_EXISTS, status); +} + +TEST_F(MetaTest, create_mcast_fdb_entry_with_nonexistent_vlan) +{ + sai_status_t status = m_meta->remove(SAI_OBJECT_TYPE_VLAN, m_vlan_id); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + sai_mcast_fdb_entry_t mcast_fdb_entry = GenMcastFdbEntry(); + status = m_meta->create(&mcast_fdb_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, remove_nonexistent_mcast_fdb_entry) +{ + sai_mcast_fdb_entry_t mcast_fdb_entry = GenMcastFdbEntry(); + sai_status_t status = m_meta->remove(&mcast_fdb_entry); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, create_duplicate_neigh_entry) +{ + sai_neighbor_entry_t neigh_entry = GenNeighEntry(); + sai_status_t status = m_meta->create(&neigh_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + status = m_meta->create(&neigh_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_ALREADY_EXISTS, status); +} + +TEST_F(MetaTest, create_neigh_entry_with_nonexistent_rif) +{ + // GenNeighEntry() is responsible for creating the RIF, so we must call it before trying to remove the RIF + sai_neighbor_entry_t neigh_entry = GenNeighEntry(); + sai_status_t status = m_meta->remove(SAI_OBJECT_TYPE_ROUTER_INTERFACE, m_rif_id); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + status = m_meta->create(&neigh_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, remove_nonexistent_neigh_entry) +{ + sai_neighbor_entry_t neigh_entry = GenNeighEntry(); + sai_status_t status = m_meta->remove(&neigh_entry); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, create_duplicate_route_entry) +{ + sai_route_entry_t route_entry = GenRouteEntry(); + sai_status_t status = m_meta->create(&route_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + status = m_meta->create(&route_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_ALREADY_EXISTS, status); +} + +TEST_F(MetaTest, remove_nonexistent_route_entry) +{ + sai_route_entry_t route_entry = GenRouteEntry(); + sai_status_t status = m_meta->remove(&route_entry); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, create_duplicate_l2mc_entry) +{ + sai_l2mc_entry_t l2mc_entry = GenL2MCEntry(); + sai_status_t status = m_meta->create(&l2mc_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + status = m_meta->create(&l2mc_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_ALREADY_EXISTS, status); +} + +TEST_F(MetaTest, create_l2mc_entry_with_nonexistent_vlan) +{ + sai_status_t status = m_meta->remove(SAI_OBJECT_TYPE_VLAN, m_vlan_id); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + sai_l2mc_entry_t l2mc_entry = GenL2MCEntry(); + status = m_meta->create(&l2mc_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, remove_nonexistent_l2mc_entry) +{ + sai_l2mc_entry_t l2mc_entry = GenL2MCEntry(); + sai_status_t status = m_meta->remove(&l2mc_entry); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, create_duplicate_ipmc_entry) +{ + sai_ipmc_entry_t ipmc_entry = GenIPMCEntry(); + sai_status_t status = m_meta->create(&ipmc_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + status = m_meta->create(&ipmc_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_ALREADY_EXISTS, status); +} + +TEST_F(MetaTest, create_ipmc_entry_with_nonexistent_vr) +{ + sai_status_t status = m_meta->remove(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, m_vr_id); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + sai_ipmc_entry_t ipmc_entry = GenIPMCEntry(); + status = m_meta->create(&ipmc_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, remove_nonexistent_ipmc_entry) +{ + sai_ipmc_entry_t ipmc_entry = GenIPMCEntry(); + sai_status_t status = m_meta->remove(&ipmc_entry); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, create_duplicate_nat_entry) +{ + sai_nat_entry_t nat_entry = GenNATEntry(); + sai_status_t status = m_meta->create(&nat_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + status = m_meta->create(&nat_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_ALREADY_EXISTS, status); +} + +TEST_F(MetaTest, create_nat_entry_with_nonexistent_vr) +{ + sai_status_t status = m_meta->remove(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, m_vr_id); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + sai_nat_entry_t nat_entry = GenNATEntry(); + status = m_meta->create(&nat_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, remove_nonexistent_nat_entry) +{ + sai_nat_entry_t nat_entry = GenNATEntry(); + sai_status_t status = m_meta->remove(&nat_entry); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, create_duplicate_my_sid_entry) +{ + sai_my_sid_entry_t my_sid_entry = GenMySIDEntry(); + sai_status_t status = m_meta->create(&my_sid_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + status = m_meta->create(&my_sid_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_ALREADY_EXISTS, status); +} + +TEST_F(MetaTest, create_my_sid_entry_with_nonexistent_vr) +{ + sai_status_t status = m_meta->remove(SAI_OBJECT_TYPE_VIRTUAL_ROUTER, m_vr_id); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + sai_my_sid_entry_t my_sid_entry = GenMySIDEntry(); + status = m_meta->create(&my_sid_entry, (uint32_t)m_attrs.size(), m_attrs.data()); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, remove_nonexistent_my_sid_entry) +{ + sai_my_sid_entry_t my_sid_entry = GenMySIDEntry(); + sai_status_t status = m_meta->remove(&my_sid_entry); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + +TEST_F(MetaTest, remove_nonexistent_generic_object) +{ + sai_attribute_t attr; + sai_object_id_t vlan_id; + attr.id = SAI_VLAN_ATTR_VLAN_ID; + attr.value.u16 = 99; + + sai_status_t status = m_meta->create(SAI_OBJECT_TYPE_VLAN, &vlan_id, m_switch_id, 1, &attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + status = m_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan_id); + EXPECT_EQ(SAI_STATUS_SUCCESS, status); + + status = m_meta->remove(SAI_OBJECT_TYPE_VLAN, vlan_id); + EXPECT_EQ(SAI_STATUS_ITEM_NOT_FOUND, status); +} + TEST(Meta, initialize) { Meta m(std::make_shared()); - EXPECT_EQ(SAI_STATUS_SUCCESS, m.initialize(0,0)); + EXPECT_EQ(SAI_STATUS_SUCCESS, m.initialize(0, 0)); } TEST(Meta, uninitialize) From c22374228edcb6c1b721c9c95e50ad1bc017e2bf Mon Sep 17 00:00:00 2001 From: Jiahua Wang Date: Mon, 24 Apr 2023 12:02:32 -0700 Subject: [PATCH 07/25] Add mdio IPC client library (#1230) Signed-off-by: Jiahua Wang Why I did it The syncd has a MDIO IPC server to help the access of external PHYs on the NPU MDIO bus. A MDIO IPC client library is required to communicate to the MDIO IPC server. The gbsyncd will pass the function pointers for the function in the client library to the PAI. How I did it MDIO IPC client functions are added to connect to the MDIO IPC server socket, to send request and to wait for response IPC messages. The client functions are made into a .so library. The .so library is packaged in the syncd debian package. How to verify it The client functions are also available in as a .a library. The unit test code can use the code to test both IPC server and client. --- .azure-pipelines/build-template.yml | 3 + debian/syncd.dirs | 1 + debian/syncd.install | 1 + debian/syncd.links | 2 + meta/DummySaiInterface.cpp | 48 +++++ meta/DummySaiInterface.h | 28 +++ syncd/Makefile.am | 15 +- syncd/MdioIpcClient.cpp | 251 +++++++++++++++++++++++ syncd/MdioIpcClient.h | 21 ++ syncd/MdioIpcCommon.h | 9 + syncd/MdioIpcServer.cpp | 73 +++++-- syncd/MdioIpcServer.h | 4 + tests/aspell.en.pws | 1 + unittest/syncd/Makefile.am | 4 +- unittest/syncd/MockableSaiInterface.cpp | 65 +++++- unittest/syncd/MockableSaiInterface.h | 36 ++++ unittest/syncd/TestMdioIpcServer.cpp | 258 ++++++++++++++++++++++++ 17 files changed, 795 insertions(+), 25 deletions(-) create mode 100755 debian/syncd.links create mode 100644 syncd/MdioIpcClient.cpp create mode 100644 syncd/MdioIpcClient.h create mode 100644 syncd/MdioIpcCommon.h create mode 100644 unittest/syncd/TestMdioIpcServer.cpp diff --git a/.azure-pipelines/build-template.yml b/.azure-pipelines/build-template.yml index 4193faa90..4567435a6 100644 --- a/.azure-pipelines/build-template.yml +++ b/.azure-pipelines/build-template.yml @@ -95,6 +95,7 @@ jobs: sudo sed -ri 's/^unixsocketperm .../unixsocketperm 777/' /etc/redis/redis.conf sudo sed -ri 's/redis-server.sock/redis.sock/' /etc/redis/redis.conf sudo service redis-server start + sudo mkdir -m 755 /var/run/sswsyncd sudo apt-get install -y rsyslog sudo service rsyslog start @@ -180,6 +181,8 @@ jobs: set -ex # Add SYS_TIME capability for settimeofday ok in syncd test sudo setcap "cap_sys_time=eip" syncd/.libs/syncd_tests + # Add CAP_DAC_OVERRIDE capability for system directory creation in syncd unittest + sudo setcap "cap_dac_override,cap_ipc_lock,cap_ipc_owner,cap_sys_time=eip" unittest/syncd/.libs/tests make check gcovr --version find SAI/meta -name "*.gc*" | xargs rm -vf diff --git a/debian/syncd.dirs b/debian/syncd.dirs index e77248175..527b78f2d 100644 --- a/debian/syncd.dirs +++ b/debian/syncd.dirs @@ -1 +1,2 @@ usr/bin +usr/lib diff --git a/debian/syncd.install b/debian/syncd.install index bdf0f4c8d..c559f1fea 100644 --- a/debian/syncd.install +++ b/debian/syncd.install @@ -5,3 +5,4 @@ usr/bin/saidiscovery usr/bin/saiasiccmp usr/bin/syncd* syncd/scripts/* usr/bin +usr/lib/*/libMdioIpcClient.so.* diff --git a/debian/syncd.links b/debian/syncd.links new file mode 100755 index 000000000..6f5af02f6 --- /dev/null +++ b/debian/syncd.links @@ -0,0 +1,2 @@ +#! /usr/bin/dh-exec +/usr/lib/${DEB_HOST_MULTIARCH}/libMdioIpcClient.so.0 /usr/lib/${DEB_HOST_MULTIARCH}/libMdioIpcClient.so diff --git a/meta/DummySaiInterface.cpp b/meta/DummySaiInterface.cpp index d09d8d233..8c86349ea 100644 --- a/meta/DummySaiInterface.cpp +++ b/meta/DummySaiInterface.cpp @@ -131,6 +131,54 @@ sai_status_t DummySaiInterface::flushFdbEntries( return m_status; } +sai_status_t DummySaiInterface::switchMdioRead( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + + return m_status; +} + +sai_status_t DummySaiInterface::switchMdioWrite( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + + return m_status; +} + +sai_status_t DummySaiInterface::switchMdioCl22Read( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + + return m_status; +} + +sai_status_t DummySaiInterface::switchMdioCl22Write( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + + return m_status; +} + sai_status_t DummySaiInterface::objectTypeGetAvailability( _In_ sai_object_id_t switchId, _In_ sai_object_type_t objectType, diff --git a/meta/DummySaiInterface.h b/meta/DummySaiInterface.h index 2cb9db43e..8cef2ecff 100644 --- a/meta/DummySaiInterface.h +++ b/meta/DummySaiInterface.h @@ -145,6 +145,34 @@ namespace saimeta _In_ uint32_t attrCount, _In_ const sai_attribute_t *attrList) override; + virtual sai_status_t switchMdioRead( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) override; + + virtual sai_status_t switchMdioWrite( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) override; + + virtual sai_status_t switchMdioCl22Read( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) override; + + virtual sai_status_t switchMdioCl22Write( + _In_ sai_object_id_t switch_id, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) override; + public: // SAI API virtual sai_status_t objectTypeGetAvailability( diff --git a/syncd/Makefile.am b/syncd/Makefile.am index 4b0acb829..62d5d8be0 100644 --- a/syncd/Makefile.am +++ b/syncd/Makefile.am @@ -10,7 +10,9 @@ endif bin_PROGRAMS = syncd syncd_request_shutdown syncd_tests -noinst_LIBRARIES = libSyncd.a libSyncdRequestShutdown.a +lib_LTLIBRARIES = libMdioIpcClient.la + +noinst_LIBRARIES = libSyncd.a libSyncdRequestShutdown.a libMdioIpcClient.a libSyncd_a_SOURCES = \ AsicOperation.cpp \ @@ -91,6 +93,17 @@ syncd_request_shutdown_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) syncd_request_shutdown_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS) syncd_request_shutdown_LDADD = libSyncdRequestShutdown.a $(top_srcdir)/lib/libSaiRedis.a -lhiredis -lswsscommon -lpthread $(CODE_COVERAGE_LIBS) +libMdioIpcClient_a_SOURCES = MdioIpcClient.cpp + +libMdioIpcClient_la_SOURCES = MdioIpcClient.cpp + +libMdioIpcClient_a_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) -Wno-format-truncation +libMdioIpcClient_a_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS) + +libMdioIpcClient_la_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) -Wno-format-truncation +libMdioIpcClient_la_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS) +libMdioIpcClient_la_LIBADD = -lswsscommon $(CODE_COVERAGE_LIBS) + syncd_tests_SOURCES = tests.cpp syncd_tests_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) syncd_tests_LDFLAGS = -Wl,-rpath,$(top_srcdir)/lib/.libs -Wl,-rpath,$(top_srcdir)/meta/.libs diff --git a/syncd/MdioIpcClient.cpp b/syncd/MdioIpcClient.cpp new file mode 100644 index 000000000..015d6e4ae --- /dev/null +++ b/syncd/MdioIpcClient.cpp @@ -0,0 +1,251 @@ +/* Includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "MdioIpcClient.h" +#include "MdioIpcCommon.h" + +#include "swss/logger.h" + +static std::mutex ipcMutex; + +/* Global variables */ + +static int syncd_mdio_ipc_command(char *cmd, char *resp) +{ + // SWSS_LOG_ENTER(); // disabled + + int fd; + ssize_t ret; + size_t len; + struct sockaddr_un saddr, caddr; + static int sock = 0; + static char path[128] = { 0 }; + static time_t timeout = 0; + + if (timeout < time(NULL)) + { + /* It might already be timed out at the server side, reconnect ... */ + if (sock > 0) + { + close(sock); + } + sock = 0; + } + + if (strlen(path) == 0) + { + strcpy(path, SYNCD_IPC_SOCK_SYNCD); + fd = open(path, O_DIRECTORY); + if (fd < 0) + { + SWSS_LOG_INFO("Program is not run on host\n"); + strcpy(path, SYNCD_IPC_SOCK_HOST); + fd = open(path, O_DIRECTORY); + if (fd < 0) + { + SWSS_LOG_ERROR("Unable to open the directory for IPC\n"); + return errno; + } + } + } + + if (sock <= 0) + { + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) + { + SWSS_LOG_ERROR("socket() :%s", strerror(errno)); + return errno; + } + + caddr.sun_family = AF_UNIX; + snprintf(caddr.sun_path, sizeof(caddr.sun_path), "%s/%s.cli.%d", path, SYNCD_IPC_SOCK_FILE, getpid()); + unlink(caddr.sun_path); + if (bind(sock, (struct sockaddr *)&caddr, sizeof(caddr)) < 0) + { + SWSS_LOG_ERROR("bind() :%s", strerror(errno)); + close(sock); + sock = 0; + return errno; + } + + saddr.sun_family = AF_UNIX; + snprintf(saddr.sun_path, sizeof(saddr.sun_path), "%s/%s.srv", path, SYNCD_IPC_SOCK_FILE); + if (connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) + { + SWSS_LOG_ERROR("connect() :%s", strerror(errno)); + close(sock); + sock = 0; + unlink(caddr.sun_path); + return errno; + } + } + + len = strlen(cmd); + ret = send(sock, cmd, len, 0); + if (ret < (ssize_t)len) + { + SWSS_LOG_ERROR("send failed, ret=%ld, expected=%ld\n", ret, len); + close(sock); + sock = 0; + unlink(caddr.sun_path); + return -EIO; + } + + ret = recv(sock, resp, SYNCD_IPC_BUFF_SIZE - 1, 0); + if (ret <= 0) + { + SWSS_LOG_ERROR("recv failed, ret=%ld\n", ret); + close(sock); + sock = 0; + unlink(caddr.sun_path); + return -EIO; + } + + timeout = time(NULL) + MDIO_CLIENT_TIMEOUT; + return (int)strtol(resp, NULL, 0); +} + + +/* Function to read data from MDIO interface */ +sai_status_t mdio_read(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr, + uint32_t number_of_registers, uint32_t *data) +{ + // SWSS_LOG_ENTER(); // disabled + + int rc = SAI_STATUS_FAILURE; + char cmd[SYNCD_IPC_BUFF_SIZE], resp[SYNCD_IPC_BUFF_SIZE]; + + if (number_of_registers > 1) + { + SWSS_LOG_ERROR("Multiple register reads are not supported, num_of_registers: %d\n", number_of_registers); + return SAI_STATUS_FAILURE; + } + + ipcMutex.lock(); + + sprintf(cmd, "mdio 0x%x 0x%x\n", mdio_addr, reg_addr); + rc = syncd_mdio_ipc_command(cmd, resp); + if (rc == 0) + { + *data = (uint32_t)strtoul(strchrnul(resp, ' ') + 1, NULL, 0); + rc = SAI_STATUS_SUCCESS; + } + else + { + SWSS_LOG_ERROR("syncd_mdio_ipc_command returns : %d\n", rc); + } + + ipcMutex.unlock(); + return rc; +} + +/* Function to write data to MDIO interface */ +sai_status_t mdio_write(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr, + uint32_t number_of_registers, const uint32_t *data) +{ + // SWSS_LOG_ENTER(); // disabled + + int rc = SAI_STATUS_FAILURE; + char cmd[SYNCD_IPC_BUFF_SIZE], resp[SYNCD_IPC_BUFF_SIZE]; + + if (number_of_registers > 1) + { + SWSS_LOG_ERROR("Multiple register reads are not supported, num_of_registers: %d\n", number_of_registers); + return SAI_STATUS_FAILURE; + } + + ipcMutex.lock(); + + sprintf(cmd, "mdio 0x%x 0x%x 0x%x\n", mdio_addr, reg_addr, *data); + rc = syncd_mdio_ipc_command(cmd, resp); + if (rc == 0) + { + rc = SAI_STATUS_SUCCESS; + } + else + { + SWSS_LOG_ERROR("syncd_mdio_ipc_command returns : %d\n", rc); + } + + ipcMutex.unlock(); + return rc; +} + +/* Function to read data using clause 22 from MDIO interface */ +sai_status_t mdio_read_cl22(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr, + uint32_t number_of_registers, uint32_t *data) +{ + // SWSS_LOG_ENTER(); // disabled + + int rc = SAI_STATUS_FAILURE; + char cmd[SYNCD_IPC_BUFF_SIZE], resp[SYNCD_IPC_BUFF_SIZE]; + + if (number_of_registers > 1) + { + SWSS_LOG_ERROR("Multiple register reads are not supported, num_of_registers: %d\n", number_of_registers); + return SAI_STATUS_FAILURE; + } + + ipcMutex.lock(); + + sprintf(cmd, "mdio-cl22 0x%x 0x%x\n", mdio_addr, reg_addr); + rc = syncd_mdio_ipc_command(cmd, resp); + if (rc == 0) + { + *data = (uint32_t)strtoul(strchrnul(resp, ' ') + 1, NULL, 0); + rc = SAI_STATUS_SUCCESS; + } + else + { + SWSS_LOG_ERROR("syncd_mdio_ipc_command returns : %d\n", rc); + } + + ipcMutex.unlock(); + return rc; +} + +/* Function to write data using clause 22 to MDIO interface */ +sai_status_t mdio_write_cl22(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr, + uint32_t number_of_registers, const uint32_t *data) +{ + // SWSS_LOG_ENTER(); // disabled + + int rc = SAI_STATUS_FAILURE; + char cmd[SYNCD_IPC_BUFF_SIZE], resp[SYNCD_IPC_BUFF_SIZE]; + + if (number_of_registers > 1) + { + SWSS_LOG_ERROR("Multiple register reads are not supported, num_of_registers: %d\n", number_of_registers); + return SAI_STATUS_FAILURE; + } + + ipcMutex.lock(); + + sprintf(cmd, "mdio-cl22 0x%x 0x%x 0x%x\n", mdio_addr, reg_addr, *data); + rc = syncd_mdio_ipc_command(cmd, resp); + if (rc == 0) + { + rc = SAI_STATUS_SUCCESS; + } + else + { + SWSS_LOG_ERROR("syncd_mdio_ipc_command returns : %d\n", rc); + } + + ipcMutex.unlock(); + return rc; +} diff --git a/syncd/MdioIpcClient.h b/syncd/MdioIpcClient.h new file mode 100644 index 000000000..908156203 --- /dev/null +++ b/syncd/MdioIpcClient.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +extern "C" { +#include "sai.h" +} + +/* Function declarations */ +extern "C" { +sai_status_t mdio_read(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr, + uint32_t number_of_registers, uint32_t *data); +sai_status_t mdio_write(uint64_t platform_context, uint32_t mdio_addr, + uint32_t reg_addr, uint32_t number_of_registers, const uint32_t *data); + +sai_status_t mdio_read_cl22(uint64_t platform_context, uint32_t mdio_addr, uint32_t reg_addr, + uint32_t number_of_registers, uint32_t *data); +sai_status_t mdio_write_cl22(uint64_t platform_context, uint32_t mdio_addr, + uint32_t reg_addr, uint32_t number_of_registers, const uint32_t *data); +} diff --git a/syncd/MdioIpcCommon.h b/syncd/MdioIpcCommon.h new file mode 100644 index 000000000..788de0e5e --- /dev/null +++ b/syncd/MdioIpcCommon.h @@ -0,0 +1,9 @@ +#define SYNCD_IPC_SOCK_SYNCD "/var/run/sswsyncd" +#define SYNCD_IPC_SOCK_HOST "/var/run/docker-syncd" +#define SYNCD_IPC_SOCK_FILE "mdio-ipc" +#define SYNCD_IPC_BUFF_SIZE 256 /* buffer size */ + +#define MDIO_SERVER_TIMEOUT 30 /* sec, connection timeout */ +#define MDIO_CLIENT_TIMEOUT 25 /* shorter than 30 sec on server side */ + +#define MDIO_CONN_MAX 18 /* max. number of connections */ diff --git a/syncd/MdioIpcServer.cpp b/syncd/MdioIpcServer.cpp index 452719055..7194332fb 100644 --- a/syncd/MdioIpcServer.cpp +++ b/syncd/MdioIpcServer.cpp @@ -13,6 +13,7 @@ #include #include "MdioIpcServer.h" +#include "MdioIpcCommon.h" #include "meta/sai_serialize.h" @@ -22,13 +23,6 @@ #include #include -#define SYNCD_IPC_SOCK_SYNCD "/var/run/sswsyncd" -#define SYNCD_IPC_SOCK_HOST "/var/run/docker-syncd" -#define SYNCD_IPC_SOCK_FILE "mdio-ipc" -#define SYNCD_IPC_BUFF_SIZE 256 /* buffer size */ - -#define CONN_TIMEOUT 30 /* sec, connection timeout */ -#define CONN_MAX 18 /* max. number of connections */ #ifndef COUNTOF #define COUNTOF(x) ((int)(sizeof((x)) / sizeof((x)[0]))) @@ -56,6 +50,11 @@ MdioIpcServer::MdioIpcServer( /* globalContext == 0 for syncd, globalContext > 0 for gbsyncd */ MdioIpcServer::m_syncdContext = (globalContext == 0); +#ifdef MDIO_ACCESS_USE_NPU + MdioIpcServer::m_accessUseNPU = true; +#else + MdioIpcServer::m_accessUseNPU = false; +#endif } MdioIpcServer::~MdioIpcServer() @@ -74,7 +73,12 @@ void MdioIpcServer::setSwitchId( { SWSS_LOG_ENTER(); -#ifdef MDIO_ACCESS_USE_NPU + /* Skip on any platform where MDIO access not using NPU */ + if (!m_accessUseNPU) + { + return; + } + /* MDIO switch id is only relevant in syncd but not in gbsyncd */ if (!MdioIpcServer::m_syncdContext) { @@ -91,6 +95,15 @@ void MdioIpcServer::setSwitchId( SWSS_LOG_NOTICE("Initialize mdio switch id with RID = %s", sai_serialize_object_id(m_switchRid).c_str()); +} + +void MdioIpcServer::setIpcTestMode() +{ + SWSS_LOG_ENTER(); + +#ifndef MDIO_ACCESS_USE_NPU + /* Allow unit test to start IPC server */ + MdioIpcServer::m_accessUseNPU = true; #endif } @@ -194,7 +207,7 @@ int MdioIpcServer::syncd_ipc_task_main() int sock_srv; int sock_cli; int sock_max; - syncd_mdio_ipc_conn_t conn[CONN_MAX]; + syncd_mdio_ipc_conn_t conn[MDIO_CONN_MAX]; struct sockaddr_un addr; char path[64]; fd_set rfds; @@ -236,7 +249,7 @@ int MdioIpcServer::syncd_ipc_task_main() } /* Listen for the upcoming client sockets */ - if (listen(sock_srv, CONN_MAX) < 0) + if (listen(sock_srv, MDIO_CONN_MAX) < 0) { SWSS_LOG_ERROR("listen() returns %d", errno); unlink(addr.sun_path); @@ -254,7 +267,7 @@ int MdioIpcServer::syncd_ipc_task_main() /* garbage collection */ now = time(NULL); - for (i = 0; i < CONN_MAX; ++i) + for (i = 0; i < MDIO_CONN_MAX; ++i) { if ((conn[i].fd > 0) && (conn[i].timeout < now)) { @@ -269,7 +282,7 @@ int MdioIpcServer::syncd_ipc_task_main() FD_ZERO(&rfds); FD_SET(sock_srv, &rfds); sock_max = sock_srv; - for (i = 0; i < CONN_MAX; ++i) + for (i = 0; i < MDIO_CONN_MAX; ++i) { if (conn[i].fd <= 0) { @@ -314,17 +327,17 @@ int MdioIpcServer::syncd_ipc_task_main() continue; } - for (i = 0; i < CONN_MAX; ++i) + for (i = 0; i < MDIO_CONN_MAX; ++i) { if (conn[i].fd <= 0) { break; } } - if (i < CONN_MAX) + if (i < MDIO_CONN_MAX) { conn[i].fd = sock_cli; - conn[i].timeout = now + CONN_TIMEOUT; + conn[i].timeout = now + MDIO_SERVER_TIMEOUT; } else { @@ -334,7 +347,7 @@ int MdioIpcServer::syncd_ipc_task_main() } /* Handle the client requests */ - for (i = 0; i < CONN_MAX; ++i) + for (i = 0; i < MDIO_CONN_MAX; ++i) { sai_status_t rc = SAI_STATUS_NOT_SUPPORTED; @@ -381,10 +394,18 @@ int MdioIpcServer::syncd_ipc_task_main() else if (strcmp("mdio", argv[0]) == 0) { rc = MdioIpcServer::syncd_ipc_cmd_mdio(resp, argc, argv); + if (rc != 0) + { + SWSS_LOG_ERROR("command %s returns %d", cmd, rc); + } } else if (strcmp("mdio-cl22", argv[0]) == 0) { rc = MdioIpcServer::syncd_ipc_cmd_mdio_cl22(resp, argc, argv); + if (rc != 0) + { + SWSS_LOG_ERROR("command %s returns %d", cmd, rc); + } } /* build the error message */ @@ -401,12 +422,12 @@ int MdioIpcServer::syncd_ipc_task_main() } /* update the connection timeout counter */ - conn[i].timeout = time(NULL) + CONN_TIMEOUT; + conn[i].timeout = time(NULL) + MDIO_SERVER_TIMEOUT; } } /* close socket descriptors */ - for (i = 0; i < CONN_MAX; ++i) + for (i = 0; i < MDIO_CONN_MAX; ++i) { if (conn[i].fd <= 0) { @@ -431,7 +452,12 @@ void MdioIpcServer::stopMdioThread(void) { SWSS_LOG_ENTER(); -#ifdef MDIO_ACCESS_USE_NPU + /* Skip on any platform where MDIO access not using NPU */ + if (!m_accessUseNPU) + { + return; + } + /* MDIO IPC server thread is only relevant in syncd but not in gbsyncd */ if (!MdioIpcServer::m_syncdContext) { @@ -441,14 +467,18 @@ void MdioIpcServer::stopMdioThread(void) m_taskAlive = 0; m_taskThread.join(); SWSS_LOG_NOTICE("IPC task thread is stopped\n"); -#endif } int MdioIpcServer::startMdioThread() { SWSS_LOG_ENTER(); -#ifdef MDIO_ACCESS_USE_NPU + /* Skip on any platform where MDIO access not using NPU */ + if (!m_accessUseNPU) + { + return SAI_STATUS_SUCCESS; + } + /* MDIO IPC server thread is only relevant in syncd but not in gbsyncd */ if (!MdioIpcServer::m_syncdContext) { @@ -467,6 +497,5 @@ int MdioIpcServer::startMdioThread() return SAI_STATUS_FAILURE; } } -#endif return SAI_STATUS_SUCCESS; } diff --git a/syncd/MdioIpcServer.h b/syncd/MdioIpcServer.h index 2da4e6c64..3e1dcac1a 100644 --- a/syncd/MdioIpcServer.h +++ b/syncd/MdioIpcServer.h @@ -25,6 +25,8 @@ namespace syncd void setSwitchId( _In_ sai_object_id_t switchRid); + void setIpcTestMode(); + int startMdioThread(); void stopMdioThread(); @@ -49,6 +51,8 @@ namespace syncd static bool m_syncdContext; + bool m_accessUseNPU; + std::shared_ptr m_vendorSai; sai_object_id_t m_switchRid; diff --git a/tests/aspell.en.pws b/tests/aspell.en.pws index 93bf80505..8368e2430 100644 --- a/tests/aspell.en.pws +++ b/tests/aspell.en.pws @@ -55,6 +55,7 @@ MCAST MTU Mellanox NHG +NPU OA OIDs ObjectAttrHash diff --git a/unittest/syncd/Makefile.am b/unittest/syncd/Makefile.am index 69ebd53f0..577614a19 100644 --- a/unittest/syncd/Makefile.am +++ b/unittest/syncd/Makefile.am @@ -14,9 +14,11 @@ tests_SOURCES = main.cpp \ TestNotificationQueue.cpp \ TestNotificationProcessor.cpp \ TestNotificationHandler.cpp \ + TestMdioIpcServer.cpp \ TestVendorSai.cpp tests_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) -tests_LDADD = $(LDADD_GTEST) $(top_srcdir)/syncd/libSyncd.a $(top_srcdir)/vslib/libSaiVS.a -lhiredis -lswsscommon -lnl-genl-3 -lnl-nf-3 -lnl-route-3 -lnl-3 -lpthread -L$(top_srcdir)/lib/.libs -lsairedis -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) +tests_LDFLAGS = -Wl,-rpath,$(top_srcdir)/lib/.libs -Wl,-rpath,$(top_srcdir)/meta/.libs +tests_LDADD = $(LDADD_GTEST) $(top_srcdir)/syncd/libSyncd.a $(top_srcdir)/vslib/libSaiVS.a $(top_srcdir)/syncd/libMdioIpcClient.a -lhiredis -lswsscommon -lnl-genl-3 -lnl-nf-3 -lnl-route-3 -lnl-3 -lpthread -L$(top_srcdir)/lib/.libs -lsairedis -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) TESTS = tests diff --git a/unittest/syncd/MockableSaiInterface.cpp b/unittest/syncd/MockableSaiInterface.cpp index e52b1dc58..79dac43b1 100644 --- a/unittest/syncd/MockableSaiInterface.cpp +++ b/unittest/syncd/MockableSaiInterface.cpp @@ -1,7 +1,6 @@ #include "MockableSaiInterface.h" #include "swss/logger.h" - MockableSaiInterface::MockableSaiInterface() { SWSS_LOG_ENTER(); @@ -253,6 +252,70 @@ sai_status_t MockableSaiInterface::flushFdbEntries( return SAI_STATUS_SUCCESS; } +sai_status_t MockableSaiInterface::switchMdioRead( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + if (mock_switchMdioRead) + { + return mock_switchMdioRead(switchId, device_addr, start_reg_addr, number_of_registers, reg_val); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::switchMdioWrite( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + if (mock_switchMdioWrite) + { + return mock_switchMdioWrite(switchId, device_addr, start_reg_addr, number_of_registers, reg_val); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::switchMdioCl22Read( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + if (mock_switchMdioCl22Read) + { + return mock_switchMdioCl22Read(switchId, device_addr, start_reg_addr, number_of_registers, reg_val); + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t MockableSaiInterface::switchMdioCl22Write( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + if (mock_switchMdioCl22Write) + { + return mock_switchMdioCl22Write(switchId, device_addr, start_reg_addr, number_of_registers, reg_val); + } + + return SAI_STATUS_SUCCESS; +} + sai_status_t MockableSaiInterface::objectTypeGetAvailability( _In_ sai_object_id_t switchId, _In_ sai_object_type_t objectType, diff --git a/unittest/syncd/MockableSaiInterface.h b/unittest/syncd/MockableSaiInterface.h index 0a17e4b22..c01b51206 100644 --- a/unittest/syncd/MockableSaiInterface.h +++ b/unittest/syncd/MockableSaiInterface.h @@ -154,6 +154,42 @@ class MockableSaiInterface: public saimeta::DummySaiInterface std::function mock_flushFdbEntries; + virtual sai_status_t switchMdioRead( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) override; + + std::function mock_switchMdioRead; + + virtual sai_status_t switchMdioWrite( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) override; + + std::function mock_switchMdioWrite; + + virtual sai_status_t switchMdioCl22Read( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) override; + + std::function mock_switchMdioCl22Read; + + virtual sai_status_t switchMdioCl22Write( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) override; + + std::function mock_switchMdioCl22Write; + public: // SAI API virtual sai_status_t objectTypeGetAvailability( diff --git a/unittest/syncd/TestMdioIpcServer.cpp b/unittest/syncd/TestMdioIpcServer.cpp new file mode 100644 index 000000000..2d99472fb --- /dev/null +++ b/unittest/syncd/TestMdioIpcServer.cpp @@ -0,0 +1,258 @@ +#include "MdioIpcServer.h" +#include "MdioIpcClient.h" +#include "MdioIpcCommon.h" +#include "MockableSaiInterface.h" +#include "swss/logger.h" + +#include +#include +#include +#include + +#include + +#define MDIO_MISSING_DEV_ADDR 0x1F +#define MDIO_MISSING_REG_ADDR 0xFFFF + +using namespace syncd; +using namespace std; + +static std::map mdioDevRegValMap; +static std::map mdioDevCl22RegValMap; + + +static sai_status_t MockMdioRead( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + uint64_t key = device_addr; + key <<= 32; + key |= start_reg_addr; + auto it = mdioDevRegValMap.find(key); + if (it == mdioDevRegValMap.end()) + { + *reg_val = 0; + return SAI_STATUS_FAILURE; + } + else + { + *reg_val = it->second; + } + return SAI_STATUS_SUCCESS; +} + +static sai_status_t MockMdioWrite( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + if (MDIO_MISSING_DEV_ADDR == device_addr) + { + return SAI_STATUS_FAILURE; + } + uint64_t key = device_addr; + key <<= 32; + key |= start_reg_addr; + mdioDevRegValMap[key] = *reg_val; + return SAI_STATUS_SUCCESS; +} + +static sai_status_t MockMdioCl22Read( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _Out_ uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + uint64_t key = device_addr; + key <<= 32; + key |= start_reg_addr; + auto it = mdioDevCl22RegValMap.find(key); + if (it == mdioDevCl22RegValMap.end()) + { + *reg_val = 0; + return SAI_STATUS_FAILURE; + } + else + { + *reg_val = it->second; + } + return SAI_STATUS_SUCCESS; +} + +static sai_status_t MockMdioCl22Write( + _In_ sai_object_id_t switchId, + _In_ uint32_t device_addr, + _In_ uint32_t start_reg_addr, + _In_ uint32_t number_of_registers, + _In_ const uint32_t *reg_val) +{ + SWSS_LOG_ENTER(); + if (MDIO_MISSING_DEV_ADDR == device_addr) + { + return SAI_STATUS_FAILURE; + } + uint64_t key = device_addr; + key <<= 32; + key |= start_reg_addr; + mdioDevCl22RegValMap[key] = *reg_val; + return SAI_STATUS_SUCCESS; +} + +TEST(MdioIpcServer, mdioAccess) +{ + SWSS_LOG_ENTER(); + std::shared_ptr mdio_sai(new MockableSaiInterface()); + mdio_sai->mock_switchMdioRead = MockMdioRead; + mdio_sai->mock_switchMdioWrite = MockMdioWrite; + mdio_sai->mock_switchMdioCl22Read = MockMdioCl22Read; + mdio_sai->mock_switchMdioCl22Write = MockMdioCl22Write; + char path[64]; + strcpy(path, SYNCD_IPC_SOCK_SYNCD); + if (open(path, O_DIRECTORY) < 0) + { + SWSS_LOG_NOTICE("Directory %s does not exist", SYNCD_IPC_SOCK_SYNCD); + if (mkdir(SYNCD_IPC_SOCK_SYNCD, 0755) < 0) + { + SWSS_LOG_WARN("Can not create directory %s", SYNCD_IPC_SOCK_SYNCD); + } + } + std::shared_ptr mdio_server(new MdioIpcServer(mdio_sai, 0)); + mdio_server->setIpcTestMode(); + mdio_server->setSwitchId(0x21000000000000); + mdio_server->startMdioThread(); + sleep(1); + + uint32_t data; + uint64_t key; + sai_status_t rc; + uint32_t data2[2]; + + /* MDIO read */ + mdioDevRegValMap.clear(); + data = 0; + key = 0x4; + key <<= 32; + key |= 0x1A; + mdioDevRegValMap[key] = 0xC0DE; + rc = mdio_read(0xF0F0F0F0F0F0F0F0, 0x4, 0x1A, 1, &data); + SWSS_LOG_NOTICE("rc = %d, data = %x", rc, data); + EXPECT_EQ(rc, SAI_STATUS_SUCCESS); + EXPECT_EQ(data, 0xC0DE); + + rc = mdio_read(0xF0F0F0F0F0F0F0F0, MDIO_MISSING_DEV_ADDR, MDIO_MISSING_REG_ADDR, 1, &data); + EXPECT_NE(rc, SAI_STATUS_SUCCESS); + + rc = mdio_read(0xF0F0F0F0F0F0F0F0, 0x4, 0x1A, 2, data2); + EXPECT_NE(rc, SAI_STATUS_SUCCESS); + + /* MDIO write */ + mdioDevRegValMap.clear(); + data = 0xBEEF; + rc = mdio_write(0xF0F0F0F0F0F0F0F0, 0x3, 0x1B, 1, &data); + SWSS_LOG_NOTICE("rc = %d", rc); + EXPECT_EQ(rc, SAI_STATUS_SUCCESS); + key = 0x3; + key <<= 32; + key |= 0x1B; + SWSS_LOG_NOTICE("reg = %x", mdioDevRegValMap[key]); + EXPECT_EQ(mdioDevRegValMap[key], 0xBEEF); + + rc = mdio_write(0xF0F0F0F0F0F0F0F0, MDIO_MISSING_DEV_ADDR, MDIO_MISSING_REG_ADDR, 1, &data); + EXPECT_NE(rc, SAI_STATUS_SUCCESS); + + rc = mdio_write(0xF0F0F0F0F0F0F0F0, 0x3, 0x1B, 2, data2); + EXPECT_NE(rc, SAI_STATUS_SUCCESS); + + /* MDIO CL22 read */ + mdioDevCl22RegValMap.clear(); + data = 0x0; + key = 0x2; + key <<= 32; + key |= 0x1C; + mdioDevCl22RegValMap[key] = 0xFEED; + rc = mdio_read_cl22(0xF0F0F0F0F0F0F0F0, 0x2, 0x1C, 1, &data); + SWSS_LOG_NOTICE("rc = %d, data = %x", rc, data); + EXPECT_EQ(rc, SAI_STATUS_SUCCESS); + EXPECT_EQ(data, 0xFEED); + + rc = mdio_read_cl22(0xF0F0F0F0F0F0F0F0, MDIO_MISSING_DEV_ADDR, MDIO_MISSING_REG_ADDR, 1, &data); + EXPECT_NE(rc, SAI_STATUS_SUCCESS); + + rc = mdio_read_cl22(0xF0F0F0F0F0F0F0F0, 0x2, 0x1C, 2, data2); + EXPECT_NE(rc, SAI_STATUS_SUCCESS); + + /* MDIO CL22 write */ + mdioDevCl22RegValMap.clear(); + data = 0xCAFE; + rc = mdio_write_cl22(0xF0F0F0F0F0F0F0F0, 0x1, 0x1D, 1, &data); + SWSS_LOG_NOTICE("rc = %d", rc); + EXPECT_EQ(rc, SAI_STATUS_SUCCESS); + key = 0x1; + key <<= 32; + key |= 0x1D; + SWSS_LOG_NOTICE("cl22 reg = %x", mdioDevCl22RegValMap[key]); + EXPECT_EQ(mdioDevCl22RegValMap[key], 0xCAFE); + + rc = mdio_write_cl22(0xF0F0F0F0F0F0F0F0, MDIO_MISSING_DEV_ADDR, MDIO_MISSING_REG_ADDR, 1, &data); + EXPECT_NE(rc, SAI_STATUS_SUCCESS); + + rc = mdio_write_cl22(0xF0F0F0F0F0F0F0F0, 0x1, 0x1D, 2, data2); + EXPECT_NE(rc, SAI_STATUS_SUCCESS); + + /* Test ipc client timeout */ + sleep(MDIO_CLIENT_TIMEOUT+1); + rc = mdio_read_cl22(0xF0F0F0F0F0F0F0F0, 0x1, 0x1D, 1, &data); + EXPECT_EQ(rc, SAI_STATUS_SUCCESS); + + mdio_server->stopMdioThread(); + sleep(MDIO_CLIENT_TIMEOUT+1); +} + +TEST(MdioIpcServer, mdioConnect) +{ + SWSS_LOG_ENTER(); + std::shared_ptr mdio_sai(new MockableSaiInterface()); + mdio_sai->mock_switchMdioRead = MockMdioRead; + mdio_sai->mock_switchMdioWrite = MockMdioWrite; + mdio_sai->mock_switchMdioCl22Read = MockMdioCl22Read; + mdio_sai->mock_switchMdioCl22Write = MockMdioCl22Write; + char path[64]; + strcpy(path, SYNCD_IPC_SOCK_SYNCD); + if (open(path, O_DIRECTORY) < 0) + { + SWSS_LOG_NOTICE("Directory %s does not exist", SYNCD_IPC_SOCK_SYNCD); + if (mkdir(SYNCD_IPC_SOCK_SYNCD, 0755) < 0) + { + SWSS_LOG_WARN("Can not create directory %s", SYNCD_IPC_SOCK_SYNCD); + } + } + std::shared_ptr mdio_server(new MdioIpcServer(mdio_sai, 0)); + mdio_server->setSwitchId(0x21000000000000); + mdio_server->startMdioThread(); + sleep(1); + + uint32_t data; + uint64_t key; + sai_status_t rc; + + /* ipc connect fail without setIpcTestMode() on non broadcom platform */ + mdioDevRegValMap.clear(); + data = 0; + key = 0x4; + key <<= 32; + key |= 0x1A; + mdioDevRegValMap[key] = 0xC0DE; + rc = mdio_read(0xF0F0F0F0F0F0F0F0, 0x4, 0x1A, 1, &data); + EXPECT_NE(rc, SAI_STATUS_SUCCESS); + + mdio_server->stopMdioThread(); +} From 3e19b2809cfcce241013c6fba88a009a0f7dbde7 Mon Sep 17 00:00:00 2001 From: Oleksandr Ivantsiv Date: Tue, 25 Apr 2023 17:55:02 +0200 Subject: [PATCH 08/25] Add macros for bulk API handlers generation. (#1226) * Add macros for bulk API handlers generation. --- lib/ClientSai.cpp | 514 +--- lib/Recorder.cpp | 12 +- lib/RedisRemoteSaiInterface.cpp | 499 +--- lib/sai_redis.h | 110 +- meta/DummySaiInterface.cpp | 315 +-- meta/Meta.cpp | 3375 ++++++-------------------- meta/Meta.h | 21 +- unittest/lib/TestClientServerSai.cpp | 50 +- vslib/VirtualSwitchSaiInterface.cpp | 481 +--- vslib/sai_vs.h | 114 +- 10 files changed, 1259 insertions(+), 4232 deletions(-) diff --git a/lib/ClientSai.cpp b/lib/ClientSai.cpp index c4b9397cd..809f50e73 100644 --- a/lib/ClientSai.cpp +++ b/lib/ClientSai.cpp @@ -302,7 +302,7 @@ sai_status_t ClientSai::create( \ SWSS_LOG_ENTER(); \ REDIS_CHECK_API_INITIALIZED(); \ return create( \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*ot), \ attr_count, \ attr_list); \ @@ -318,7 +318,7 @@ sai_status_t ClientSai::remove( \ SWSS_LOG_ENTER(); \ REDIS_CHECK_API_INITIALIZED(); \ return remove( \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*ot)); \ } @@ -333,7 +333,7 @@ sai_status_t ClientSai::set( \ SWSS_LOG_ENTER(); \ REDIS_CHECK_API_INITIALIZED(); \ return set( \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*ot), \ attr); \ } @@ -350,7 +350,7 @@ sai_status_t ClientSai::get( \ SWSS_LOG_ENTER(); \ REDIS_CHECK_API_INITIALIZED(); \ return get( \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*ot), \ attr_count, \ attr_list); \ @@ -358,6 +358,81 @@ sai_status_t ClientSai::get( \ SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_GET_ENTRY); +#define DECLARE_BULK_CREATE_ENTRY(OT,ot) \ +sai_status_t ClientSai::bulkCreate( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t *ot, \ + _In_ const uint32_t *attr_count, \ + _In_ const sai_attribute_t **attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + MUTEX(); \ + SWSS_LOG_ENTER(); \ + REDIS_CHECK_API_INITIALIZED(); \ + static PerformanceIntervalTimer timer("ClientSai::bulkCreate(" #ot ")"); \ + timer.start(); \ + std::vector serialized_object_ids; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + std::string str_object_id = sai_serialize_ ##ot (ot[idx]); \ + serialized_object_ids.push_back(str_object_id); \ + } \ + auto status = bulkCreate( \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + serialized_object_ids, \ + attr_count, \ + attr_list, \ + mode, \ + object_statuses); \ + timer.stop(); \ + timer.inc(object_count); \ + return status; \ +} + +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_CREATE_ENTRY) + +#define DECLARE_BULK_REMOVE_ENTRY(OT,ot) \ +sai_status_t ClientSai::bulkRemove( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t *ot, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + MUTEX(); \ + SWSS_LOG_ENTER(); \ + REDIS_CHECK_API_INITIALIZED(); \ + std::vector serializedObjectIds; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + serializedObjectIds.emplace_back(sai_serialize_ ##ot (ot[idx])); \ + } \ + return bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, serializedObjectIds, mode, object_statuses); \ +} + +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_REMOVE_ENTRY) + +#define DECLARE_BULK_SET_ENTRY(OT,ot) \ +sai_status_t ClientSai::bulkSet( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t *ot, \ + _In_ const sai_attribute_t *attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + MUTEX(); \ + SWSS_LOG_ENTER(); \ + REDIS_CHECK_API_INITIALIZED(); \ + std::vector serializedObjectIds; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + serializedObjectIds.emplace_back(sai_serialize_ ##ot (ot[idx])); \ + } \ + return bulkSet(SAI_OBJECT_TYPE_ROUTE_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); \ +} + +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_SET_ENTRY) + // QUAD API HELPERS sai_status_t ClientSai::create( @@ -1080,205 +1155,6 @@ sai_status_t ClientSai::bulkCreate( return status; } -sai_status_t ClientSai::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t* route_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - // TODO support mode - - static PerformanceIntervalTimer timer("ClientSai::bulkCreate(route_entry)"); - - timer.start(); - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_route_entry(route_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - auto status = bulkCreate( - SAI_OBJECT_TYPE_ROUTE_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); - - timer.stop(); - - timer.inc(object_count); - - return status; -} - -sai_status_t ClientSai::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t* fdb_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - // TODO support mode - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_fdb_entry(fdb_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - SAI_OBJECT_TYPE_FDB_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - -sai_status_t ClientSai::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t* inseg_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - // TODO support mode - - static PerformanceIntervalTimer timer("ClientSai::bulkCreate(inseg_entry)"); - - timer.start(); - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_inseg_entry(inseg_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - auto status = bulkCreate( - SAI_OBJECT_TYPE_INSEG_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); - - timer.stop(); - - timer.inc(object_count); - - return status; -} - -sai_status_t ClientSai::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t* nat_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - // TODO support mode - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_nat_entry(nat_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - SAI_OBJECT_TYPE_NAT_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - -sai_status_t ClientSai::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t* my_sid_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - // TODO support mode - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_my_sid_entry(my_sid_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - SAI_OBJECT_TYPE_MY_SID_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - -sai_status_t ClientSai::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - // TODO support mode - - return SAI_STATUS_NOT_IMPLEMENTED; -} - -// BULK CREATE HELPERS - sai_status_t ClientSai::bulkCreate( _In_ sai_object_type_t object_type, _In_ const std::vector &serialized_object_ids, @@ -1353,119 +1229,6 @@ sai_status_t ClientSai::bulkRemove( return bulkRemove(object_type, serializedObjectIds, mode, object_statuses); } -sai_status_t ClientSai::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_route_entry(route_entry[idx])); - } - - return bulkRemove(SAI_OBJECT_TYPE_ROUTE_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t ClientSai::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_nat_entry(nat_entry[idx])); - } - - return bulkRemove(SAI_OBJECT_TYPE_NAT_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t ClientSai::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_inseg_entry(inseg_entry[idx])); - } - - return bulkRemove(SAI_OBJECT_TYPE_INSEG_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t ClientSai::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_fdb_entry(fdb_entry[idx])); - } - - return bulkRemove(SAI_OBJECT_TYPE_FDB_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t ClientSai::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_my_sid_entry(my_sid_entry[idx])); - } - - return bulkRemove(SAI_OBJECT_TYPE_MY_SID_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t ClientSai::bulkRemove( - _In_ uint32_t object_count, - _In_ const _sai_neighbor_entry_t *neighbor_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - return SAI_STATUS_NOT_IMPLEMENTED; -} - // BULK REMOVE HELPERS sai_status_t ClientSai::bulkRemove( @@ -1532,125 +1295,6 @@ sai_status_t ClientSai::bulkSet( return bulkSet(object_type, serializedObjectIds, attr_list, mode, object_statuses); } -sai_status_t ClientSai::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_route_entry(route_entry[idx])); - } - - return bulkSet(SAI_OBJECT_TYPE_ROUTE_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t ClientSai::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_nat_entry(nat_entry[idx])); - } - - return bulkSet(SAI_OBJECT_TYPE_NAT_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t ClientSai::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_inseg_entry(inseg_entry[idx])); - } - - return bulkSet(SAI_OBJECT_TYPE_INSEG_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t ClientSai::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_fdb_entry(fdb_entry[idx])); - } - - return bulkSet(SAI_OBJECT_TYPE_FDB_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t ClientSai::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_my_sid_entry(my_sid_entry[idx])); - } - - return bulkSet(SAI_OBJECT_TYPE_MY_SID_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t ClientSai::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t *neighbor_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - MUTEX(); - SWSS_LOG_ENTER(); - REDIS_CHECK_API_INITIALIZED(); - - return SAI_STATUS_NOT_IMPLEMENTED; -} - // BULK SET HELPERS sai_status_t ClientSai::bulkSet( diff --git a/lib/Recorder.cpp b/lib/Recorder.cpp index 6f7162343..32bc2d0d8 100644 --- a/lib/Recorder.cpp +++ b/lib/Recorder.cpp @@ -869,7 +869,8 @@ void Recorder::recordRemove( \ _In_ const sai_ ## ot ## _t* ot) \ { \ SWSS_LOG_ENTER(); \ - recordRemove(SAI_OBJECT_TYPE_ ## OT, sai_serialize_ ## ot(*ot)); \ + recordRemove((sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + sai_serialize_ ## ot(*ot)); \ } SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_RECORD_REMOVE_ENTRY); @@ -881,7 +882,8 @@ void Recorder::recordCreate( _In_ const sai_attribute_t *attr_list) \ { \ SWSS_LOG_ENTER(); \ - recordCreate(SAI_OBJECT_TYPE_ ## OT, sai_serialize_ ## ot(*ot), attr_count, attr_list); \ + recordCreate((sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + sai_serialize_ ## ot(*ot), attr_count, attr_list); \ } SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_RECORD_CREATE_ENTRY); @@ -892,7 +894,8 @@ void Recorder::recordSet( _In_ const sai_attribute_t *attr) \ { \ SWSS_LOG_ENTER(); \ - recordSet(SAI_OBJECT_TYPE_ ## OT, sai_serialize_ ## ot(*ot), attr); \ + recordSet((sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + sai_serialize_ ## ot(*ot), attr); \ } SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_RECORD_SET_ENTRY); @@ -904,7 +907,8 @@ void Recorder::recordGet( _In_ const sai_attribute_t *attr_list) \ { \ SWSS_LOG_ENTER(); \ - recordGet(SAI_OBJECT_TYPE_ ## OT, sai_serialize_ ## ot(*ot), attr_count, attr_list); \ + recordGet((sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + sai_serialize_ ## ot(*ot), attr_count, attr_list); \ } SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_RECORD_GET_ENTRY); diff --git a/lib/RedisRemoteSaiInterface.cpp b/lib/RedisRemoteSaiInterface.cpp index ec69c4d4f..4e0e284b9 100644 --- a/lib/RedisRemoteSaiInterface.cpp +++ b/lib/RedisRemoteSaiInterface.cpp @@ -541,7 +541,7 @@ sai_status_t RedisRemoteSaiInterface::remove( \ { \ SWSS_LOG_ENTER(); \ return remove( \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*ot)); \ } @@ -555,7 +555,7 @@ sai_status_t RedisRemoteSaiInterface::create( \ { \ SWSS_LOG_ENTER(); \ return create( \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*ot), \ attr_count, \ attr_list); \ @@ -570,13 +570,82 @@ sai_status_t RedisRemoteSaiInterface::set( \ { \ SWSS_LOG_ENTER(); \ return set( \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*ot), \ attr); \ } SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_SET_ENTRY); +#define DECLARE_BULK_CREATE_ENTRY(OT,ot) \ +sai_status_t RedisRemoteSaiInterface::bulkCreate( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t *ot, \ + _In_ const uint32_t *attr_count, \ + _In_ const sai_attribute_t **attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + static PerformanceIntervalTimer timer("RedisRemoteSaiInterface::bulkCreate(" #ot ")"); \ + timer.start(); \ + std::vector serialized_object_ids; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + std::string str_object_id = sai_serialize_ ##ot (ot[idx]); \ + serialized_object_ids.push_back(str_object_id); \ + } \ + auto status = bulkCreate( \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + serialized_object_ids, \ + attr_count, \ + attr_list, \ + mode, \ + object_statuses); \ + timer.stop(); \ + timer.inc(object_count); \ + return status; \ +} + +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_CREATE_ENTRY); + +#define DECLARE_BULK_REMOVE_ENTRY(OT,ot) \ +sai_status_t RedisRemoteSaiInterface::bulkRemove( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t *ot, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + std::vector serializedObjectIds; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + serializedObjectIds.emplace_back(sai_serialize_ ##ot (ot[idx])); \ + } \ + return bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, serializedObjectIds, mode, object_statuses); \ +} + +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_REMOVE_ENTRY); + +#define DECLARE_BULK_SET_ENTRY(OT,ot) \ +sai_status_t RedisRemoteSaiInterface::bulkSet( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t *ot, \ + _In_ const sai_attribute_t *attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + std::vector serializedObjectIds; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + serializedObjectIds.emplace_back(sai_serialize_ ##ot (ot[idx])); \ + } \ + return bulkSet((sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, serializedObjectIds, attr_list, mode, object_statuses); \ +} + +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_SET_ENTRY); + sai_status_t RedisRemoteSaiInterface::create( _In_ sai_object_type_t object_type, _In_ const std::string& serializedObjectId, @@ -787,7 +856,7 @@ sai_status_t RedisRemoteSaiInterface::get( \ { \ SWSS_LOG_ENTER(); \ return get( \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*ot), \ attr_count, \ attr_list); \ @@ -1374,114 +1443,6 @@ sai_status_t RedisRemoteSaiInterface::bulkRemove( return bulkRemove(object_type, serializedObjectIds, mode, object_statuses); } -sai_status_t RedisRemoteSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_route_entry(route_entry[idx])); - } - - return bulkRemove(SAI_OBJECT_TYPE_ROUTE_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_nat_entry(nat_entry[idx])); - } - - return bulkRemove(SAI_OBJECT_TYPE_NAT_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_inseg_entry(inseg_entry[idx])); - } - - return bulkRemove(SAI_OBJECT_TYPE_INSEG_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_fdb_entry(fdb_entry[idx])); - } - - return bulkRemove(SAI_OBJECT_TYPE_FDB_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_my_sid_entry(my_sid_entry[idx])); - } - - return bulkRemove(SAI_OBJECT_TYPE_MY_SID_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t *neighbor_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_neighbor_entry(neighbor_entry[idx])); - } - - return bulkRemove(SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, serializedObjectIds, mode, object_statuses); -} - sai_status_t RedisRemoteSaiInterface::bulkSet( _In_ sai_object_type_t object_type, _In_ uint32_t object_count, @@ -1502,120 +1463,6 @@ sai_status_t RedisRemoteSaiInterface::bulkSet( return bulkSet(object_type, serializedObjectIds, attr_list, mode, object_statuses); } -sai_status_t RedisRemoteSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_route_entry(route_entry[idx])); - } - - return bulkSet(SAI_OBJECT_TYPE_ROUTE_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_nat_entry(nat_entry[idx])); - } - - return bulkSet(SAI_OBJECT_TYPE_NAT_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_inseg_entry(inseg_entry[idx])); - } - - return bulkSet(SAI_OBJECT_TYPE_INSEG_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_fdb_entry(fdb_entry[idx])); - } - - return bulkSet(SAI_OBJECT_TYPE_FDB_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_my_sid_entry(my_sid_entry[idx])); - } - - return bulkSet(SAI_OBJECT_TYPE_MY_SID_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t *neighbor_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_neighbor_entry(neighbor_entry[idx])); - } - - return bulkSet(SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - sai_status_t RedisRemoteSaiInterface::bulkSet( _In_ sai_object_type_t object_type, _In_ const std::vector &serialized_object_ids, @@ -1755,206 +1602,6 @@ sai_status_t RedisRemoteSaiInterface::bulkCreate( return waitForBulkResponse(SAI_COMMON_API_BULK_CREATE, (uint32_t)serialized_object_ids.size(), object_statuses); } -sai_status_t RedisRemoteSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t* route_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // TODO support mode - - static PerformanceIntervalTimer timer("RedisRemoteSaiInterface::bulkCreate(route_entry)"); - - timer.start(); - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_route_entry(route_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - auto status = bulkCreate( - SAI_OBJECT_TYPE_ROUTE_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); - - timer.stop(); - - timer.inc(object_count); - - return status; -} - -sai_status_t RedisRemoteSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t* fdb_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // TODO support mode - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_fdb_entry(fdb_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - SAI_OBJECT_TYPE_FDB_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t* inseg_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // TODO support mode - - static PerformanceIntervalTimer timer("RedisRemoteSaiInterface::bulkCreate(inseg_entry)"); - - timer.start(); - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_inseg_entry(inseg_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - auto status = bulkCreate( - SAI_OBJECT_TYPE_INSEG_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); - - timer.stop(); - - timer.inc(object_count); - - return status; -} - -sai_status_t RedisRemoteSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t* nat_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // TODO support mode - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_nat_entry(nat_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - SAI_OBJECT_TYPE_NAT_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t* my_sid_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // TODO support mode - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_my_sid_entry(my_sid_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - SAI_OBJECT_TYPE_MY_SID_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - -sai_status_t RedisRemoteSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // TODO support mode - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_neighbor_entry(neighbor_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - sai_status_t RedisRemoteSaiInterface::notifySyncd( _In_ sai_object_id_t switchId, _In_ sai_redis_notify_syncd_t redisNotifySyncd) diff --git a/lib/sai_redis.h b/lib/sai_redis.h index 9470b7a45..207ad1fc2 100644 --- a/lib/sai_redis.h +++ b/lib/sai_redis.h @@ -256,60 +256,60 @@ PRIVATE extern std::shared_ptr redis_sai; // BULK QUAD -#define REDIS_BULK_CREATE(OT,fname) \ - static sai_status_t redis_bulk_create_ ## fname(\ - _In_ sai_object_id_t switch_id, \ - _In_ uint32_t object_count, \ - _In_ const uint32_t *attr_count, \ - _In_ const sai_attribute_t **attr_list, \ - _In_ sai_bulk_op_error_mode_t mode, \ - _Out_ sai_object_id_t *object_id, \ - _Out_ sai_status_t *object_statuses) \ -{ \ - SWSS_LOG_ENTER(); \ - return redis_sai->bulkCreate( \ - SAI_OBJECT_TYPE_ ## OT, \ - switch_id, \ - object_count, \ - attr_count, \ - attr_list, \ - mode, \ - object_id, \ - object_statuses); \ +#define REDIS_BULK_CREATE(OT,fname) \ + static sai_status_t redis_bulk_create_ ## fname( \ + _In_ sai_object_id_t switch_id, \ + _In_ uint32_t object_count, \ + _In_ const uint32_t *attr_count, \ + _In_ const sai_attribute_t **attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_object_id_t *object_id, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + return redis_sai->bulkCreate( \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + switch_id, \ + object_count, \ + attr_count, \ + attr_list, \ + mode, \ + object_id, \ + object_statuses); \ } -#define REDIS_BULK_REMOVE(OT,fname) \ - static sai_status_t redis_bulk_remove_ ## fname(\ - _In_ uint32_t object_count, \ - _In_ const sai_object_id_t *object_id, \ - _In_ sai_bulk_op_error_mode_t mode, \ - _Out_ sai_status_t *object_statuses) \ -{ \ - SWSS_LOG_ENTER(); \ - return redis_sai->bulkRemove( \ - SAI_OBJECT_TYPE_ ## OT, \ - object_count, \ - object_id, \ - mode, \ - object_statuses); \ +#define REDIS_BULK_REMOVE(OT,fname) \ + static sai_status_t redis_bulk_remove_ ## fname( \ + _In_ uint32_t object_count, \ + _In_ const sai_object_id_t *object_id, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + return redis_sai->bulkRemove( \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + object_count, \ + object_id, \ + mode, \ + object_statuses); \ } -#define REDIS_BULK_SET(OT,fname) \ - static sai_status_t redis_bulk_set_ ## fname( \ - _In_ uint32_t object_count, \ - _In_ const sai_object_id_t *object_id, \ - _In_ const sai_attribute_t *attr_list, \ - _In_ sai_bulk_op_error_mode_t mode, \ - _Out_ sai_status_t *object_statuses) \ -{ \ - SWSS_LOG_ENTER(); \ - return redis_sai->bulkSet( \ - SAI_OBJECT_TYPE_ ## OT, \ - object_count, \ - object_id, \ - attr_list, \ - mode, \ - object_statuses); \ +#define REDIS_BULK_SET(OT,fname) \ + static sai_status_t redis_bulk_set_ ## fname( \ + _In_ uint32_t object_count, \ + _In_ const sai_object_id_t *object_id, \ + _In_ const sai_attribute_t *attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + return redis_sai->bulkSet( \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + object_count, \ + object_id, \ + attr_list, \ + mode, \ + object_statuses); \ } #define REDIS_BULK_GET(OT,fname) \ @@ -337,7 +337,10 @@ PRIVATE extern std::shared_ptr redis_sai; // BULK QUAD ENTRY #define REDIS_BULK_CREATE_ENTRY(OT,ot) \ - static sai_status_t redis_bulk_create_ ## ot( \ + REDIS_BULK_CREATE_ENTRY_EX(OT, ot, ot) + +#define REDIS_BULK_CREATE_ENTRY_EX(OT,ot,fname) \ + static sai_status_t redis_bulk_create_ ## fname(\ _In_ uint32_t object_count, \ _In_ const sai_ ## ot ## _t *entry, \ _In_ const uint32_t *attr_count, \ @@ -356,7 +359,10 @@ PRIVATE extern std::shared_ptr redis_sai; } #define REDIS_BULK_REMOVE_ENTRY(OT,ot) \ - static sai_status_t redis_bulk_remove_ ## ot( \ + REDIS_BULK_REMOVE_ENTRY_EX(OT, ot, ot) + +#define REDIS_BULK_REMOVE_ENTRY_EX(OT,ot,fname) \ + static sai_status_t redis_bulk_remove_ ## fname(\ _In_ uint32_t object_count, \ _In_ const sai_ ## ot ##_t *entry, \ _In_ sai_bulk_op_error_mode_t mode, \ diff --git a/meta/DummySaiInterface.cpp b/meta/DummySaiInterface.cpp index 8c86349ea..fa3ede4fe 100644 --- a/meta/DummySaiInterface.cpp +++ b/meta/DummySaiInterface.cpp @@ -116,10 +116,55 @@ sai_status_t DummySaiInterface::get( \ return m_status; \ } +#define DECLARE_BULK_CREATE_ENTRY(OT,ot) \ +sai_status_t DummySaiInterface::bulkCreate( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t* ot, \ + _In_ const uint32_t *attr_count, \ + _In_ const sai_attribute_t **attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + object_statuses[idx] = m_status; \ + return m_status; \ +} + +#define DECLARE_BULK_REMOVE_ENTRY(OT,ot) \ +sai_status_t DummySaiInterface::bulkRemove( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t* ot, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + object_statuses[idx] = m_status; \ + return m_status; \ +} + +#define DECLARE_BULK_SET_ENTRY(OT,ot) \ +sai_status_t DummySaiInterface::bulkSet( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t* ot, \ + _In_ const sai_attribute_t *attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + object_statuses[idx] = m_status; \ + return m_status; \ +} + SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_REMOVE_ENTRY); SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_CREATE_ENTRY); SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_SET_ENTRY); SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_GET_ENTRY); +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_CREATE_ENTRY); +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_REMOVE_ENTRY); +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_SET_ENTRY); sai_status_t DummySaiInterface::flushFdbEntries( _In_ sai_object_id_t switchId, @@ -309,90 +354,6 @@ sai_status_t DummySaiInterface::bulkRemove( return m_status; } -sai_status_t DummySaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t *neighbor_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - sai_status_t DummySaiInterface::bulkSet( _In_ sai_object_type_t object_type, _In_ uint32_t object_count, @@ -409,96 +370,6 @@ sai_status_t DummySaiInterface::bulkSet( return m_status; } -sai_status_t DummySaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t *neighbor_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - sai_status_t DummySaiInterface::bulkCreate( _In_ sai_object_type_t object_type, _In_ sai_object_id_t switch_id, @@ -517,102 +388,6 @@ sai_status_t DummySaiInterface::bulkCreate( return m_status; } -sai_status_t DummySaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - -sai_status_t DummySaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t *neighbor_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - for (uint32_t idx = 0; idx < object_count; idx++) - object_statuses[idx] = m_status; - - return m_status; -} - sai_object_type_t DummySaiInterface::objectTypeQuery( _In_ sai_object_id_t objectId) { diff --git a/meta/Meta.cpp b/meta/Meta.cpp index 78330cc9a..186790d29 100644 --- a/meta/Meta.cpp +++ b/meta/Meta.cpp @@ -38,6 +38,98 @@ { SWSS_LOG_DEBUG(msg " status: %s", sai_serialize_status(status).c_str()); } \ else { SWSS_LOG_ERROR(msg " status: %s", sai_serialize_status(status).c_str()); } +#define DECLARE_CREATE_ENTRY(OT,ot) \ +sai_status_t Meta::create( \ + _In_ const sai_ ## ot ## _t* ot, \ + _In_ uint32_t attr_count, \ + _In_ const sai_attribute_t *attr_list) \ +{ \ + SWSS_LOG_ENTER(); \ + sai_status_t status = meta_sai_validate_ ## ot (ot, true); \ + CHECK_STATUS_SUCCESS(status); \ + sai_object_meta_key_t meta_key = { \ + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + .objectkey = { .key = { .ot = *ot } } }; \ + status = meta_generic_validation_create(meta_key, ot->switch_id, \ + attr_count, attr_list); \ + CHECK_STATUS_SUCCESS(status); \ + status = m_implementation->create(ot, attr_count, attr_list); \ + META_LOG_STATUS(status, "create"); \ + if (status == SAI_STATUS_SUCCESS) \ + { \ + meta_generic_validation_post_create(meta_key, ot->switch_id, \ + attr_count, attr_list); \ + } \ + return status; \ +} + +#define DECLARE_REMOVE_ENTRY(OT,ot) \ +sai_status_t Meta::remove( \ + _In_ const sai_ ## ot ## _t* ot) \ +{ \ + SWSS_LOG_ENTER(); \ + sai_status_t status = meta_sai_validate_ ## ot (ot, false); \ + CHECK_STATUS_SUCCESS(status); \ + sai_object_meta_key_t meta_key = { \ + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + .objectkey = { .key = { .ot = *ot } } \ + }; \ + status = meta_generic_validation_remove(meta_key); \ + CHECK_STATUS_SUCCESS(status); \ + status = m_implementation->remove(ot); \ + META_LOG_STATUS(status, "remove"); \ + if (status == SAI_STATUS_SUCCESS) \ + { \ + meta_generic_validation_post_remove(meta_key); \ + } \ + return status; \ +} + +#define DECLARE_SET_ENTRY(OT,ot) \ +sai_status_t Meta::set( \ + _In_ const sai_ ## ot ## _t* ot, \ + _In_ const sai_attribute_t *attr) \ +{ \ + SWSS_LOG_ENTER(); \ + sai_status_t status = meta_sai_validate_ ## ot (ot, false); \ + CHECK_STATUS_SUCCESS(status); \ + sai_object_meta_key_t meta_key = { \ + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + .objectkey = { .key = { .ot = *ot } } }; \ + status = meta_generic_validation_set(meta_key, attr); \ + CHECK_STATUS_SUCCESS(status); \ + status = m_implementation->set(ot, attr); \ + META_LOG_STATUS(status, "set"); \ + if (status == SAI_STATUS_SUCCESS) \ + { \ + meta_generic_validation_post_set(meta_key, attr); \ + } \ + return status; \ +} + +#define DECLARE_GET_ENTRY(OT,ot) \ +sai_status_t Meta::get( \ + _In_ const sai_ ## ot ## _t* ot, \ + _In_ uint32_t attr_count, \ + _Inout_ sai_attribute_t *attr_list) \ +{ \ + SWSS_LOG_ENTER(); \ + sai_status_t status = meta_sai_validate_ ## ot (ot, false, true); \ + CHECK_STATUS_SUCCESS(status); \ + sai_object_meta_key_t meta_key = { \ + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + .objectkey = { .key = { .ot = *ot } } }; \ + status = meta_generic_validation_get(meta_key, attr_count, attr_list); \ + CHECK_STATUS_SUCCESS(status); \ + status = m_implementation->get(ot, attr_count, attr_list); \ + if (status == SAI_STATUS_SUCCESS) \ + { \ + meta_generic_validation_post_get(meta_key, ot->switch_id, \ + attr_count, attr_list); \ + } \ + return status; \ +} + using namespace saimeta; Meta::Meta( @@ -166,2815 +258,883 @@ sai_status_t Meta::remove( return status; } -sai_status_t Meta::remove( - _In_ const sai_fdb_entry_t* fdb_entry) +sai_status_t Meta::create( + _In_ sai_object_type_t object_type, + _Out_ sai_object_id_t* object_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { SWSS_LOG_ENTER(); - sai_status_t status = meta_sai_validate_fdb_entry(fdb_entry, false); + sai_status_t status = meta_sai_validate_oid(object_type, object_id, switch_id, true); CHECK_STATUS_SUCCESS(status) - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_FDB_ENTRY, .objectkey = { .key = { .fdb_entry = *fdb_entry } } }; + sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = SAI_NULL_OBJECT_ID } } }; - status = meta_generic_validation_remove(meta_key); + status = meta_generic_validation_create(meta_key, switch_id, attr_count, attr_list); CHECK_STATUS_SUCCESS(status) - status = m_implementation->remove(fdb_entry); + status = m_implementation->create(object_type, object_id, switch_id, attr_count, attr_list); - META_LOG_STATUS(status, "remove"); + META_LOG_STATUS(status, "create"); if (status == SAI_STATUS_SUCCESS) { - meta_generic_validation_post_remove(meta_key); + meta_key.objectkey.key.object_id = *object_id; + + if (meta_key.objecttype == SAI_OBJECT_TYPE_SWITCH) + { + /* + * We are creating switch object, so switch id must be the same as + * just created object. We could use SAI_NULL_OBJECT_ID in that + * case and do special switch inside post_create method. + */ + + switch_id = *object_id; + } + + meta_generic_validation_post_create(meta_key, switch_id, attr_count, attr_list); } return status; } -sai_status_t Meta::remove( - _In_ const sai_mcast_fdb_entry_t* mcast_fdb_entry) +sai_status_t Meta::set( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ const sai_attribute_t *attr) { SWSS_LOG_ENTER(); - sai_status_t status = meta_sai_validate_mcast_fdb_entry(mcast_fdb_entry, false); + sai_object_id_t switch_id = switchIdQuery(object_id); + + if (!m_oids.objectReferenceExists(switch_id)) + { + SWSS_LOG_ERROR("switch id %s doesn't exist", + sai_serialize_object_id(switch_id).c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_status_t status = meta_sai_validate_oid(object_type, &object_id, SAI_NULL_OBJECT_ID, false); CHECK_STATUS_SUCCESS(status) - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_MCAST_FDB_ENTRY, .objectkey = { .key = { .mcast_fdb_entry = *mcast_fdb_entry } } }; + sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = object_id } } }; - status = meta_generic_validation_remove(meta_key); + status = meta_generic_validation_set(meta_key, attr); CHECK_STATUS_SUCCESS(status) - status = m_implementation->remove(mcast_fdb_entry); + status = m_implementation->set(object_type, object_id, attr); - META_LOG_STATUS(status, "remove"); + META_LOG_STATUS(status, "set"); if (status == SAI_STATUS_SUCCESS) { - meta_generic_validation_post_remove(meta_key); + meta_generic_validation_post_set(meta_key, attr); } return status; } -sai_status_t Meta::remove( - _In_ const sai_neighbor_entry_t* neighbor_entry) +sai_status_t Meta::get( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t attr_count, + _Inout_ sai_attribute_t *attr_list) { SWSS_LOG_ENTER(); - sai_status_t status = meta_sai_validate_neighbor_entry(neighbor_entry, false); + sai_object_id_t switch_id = switchIdQuery(object_id); + + sai_status_t status = meta_sai_validate_oid(object_type, &object_id, SAI_NULL_OBJECT_ID, false); CHECK_STATUS_SUCCESS(status) - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, .objectkey = { .key = { .neighbor_entry = *neighbor_entry } } }; + sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = object_id } } }; - status = meta_generic_validation_remove(meta_key); + status = meta_generic_validation_get(meta_key, attr_count, attr_list); CHECK_STATUS_SUCCESS(status) - status = m_implementation->remove(neighbor_entry); - - META_LOG_STATUS(status, "remove"); + status = m_implementation->get(object_type, object_id, attr_count, attr_list); if (status == SAI_STATUS_SUCCESS) { - meta_generic_validation_post_remove(meta_key); + meta_generic_validation_post_get(meta_key, switch_id, attr_count, attr_list); } return status; } -sai_status_t Meta::remove( - _In_ const sai_route_entry_t* route_entry) +SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_REMOVE_ENTRY); +SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_CREATE_ENTRY); +SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_SET_ENTRY); +SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_GET_ENTRY); + +sai_status_t Meta::flushFdbEntries( + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) { SWSS_LOG_ENTER(); - sai_status_t status = meta_sai_validate_route_entry(route_entry, false); + if (attr_count > MAX_LIST_COUNT) + { + SWSS_LOG_ERROR("create attribute count %u > max list count %u", attr_count, MAX_LIST_COUNT); - CHECK_STATUS_SUCCESS(status) + return SAI_STATUS_INVALID_PARAMETER; + } - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY, .objectkey = { .key = { .route_entry = *route_entry } } }; + if (attr_count != 0 && attr_list == NULL) + { + SWSS_LOG_ERROR("attribute list is NULL"); - status = meta_generic_validation_remove(meta_key); + return SAI_STATUS_INVALID_PARAMETER; + } - CHECK_STATUS_SUCCESS(status) + sai_object_type_t swot = objectTypeQuery(switch_id); - status = m_implementation->remove(route_entry); + if (swot != SAI_OBJECT_TYPE_SWITCH) + { + SWSS_LOG_ERROR("object type for switch_id %s is %s", + sai_serialize_object_id(switch_id).c_str(), + sai_serialize_object_type(swot).c_str()); - META_LOG_STATUS(status, "remove"); + return SAI_STATUS_INVALID_PARAMETER; + } - if (status == SAI_STATUS_SUCCESS) + if (!m_oids.objectReferenceExists(switch_id)) { - meta_generic_validation_post_remove(meta_key); + SWSS_LOG_ERROR("switch id %s doesn't exist", + sai_serialize_object_id(switch_id).c_str()); + + return SAI_STATUS_INVALID_PARAMETER; } - return status; -} + // validate attributes + // - attribute list can be empty + // - validation is similar to "create" action but there is no + // post create step and no references are updated + // - fdb entries are updated in fdb notification -sai_status_t Meta::remove( - _In_ const sai_l2mc_entry_t* l2mc_entry) -{ - SWSS_LOG_ENTER(); + std::unordered_map attrs; - sai_status_t status = meta_sai_validate_l2mc_entry(l2mc_entry, false); + SWSS_LOG_DEBUG("attr count = %u", attr_count); - CHECK_STATUS_SUCCESS(status) + for (uint32_t idx = 0; idx < attr_count; ++idx) + { + const sai_attribute_t* attr = &attr_list[idx]; - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY, .objectkey = { .key = { .l2mc_entry = *l2mc_entry } } }; + auto mdp = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_FDB_FLUSH, attr->id); - status = meta_generic_validation_remove(meta_key); + if (mdp == NULL) + { + SWSS_LOG_ERROR("unable to find attribute metadata SAI_OBJECT_TYPE_FDB_FLUSH:%d", attr->id); - CHECK_STATUS_SUCCESS(status) + return SAI_STATUS_INVALID_PARAMETER; + } - status = m_implementation->remove(l2mc_entry); + const sai_attribute_value_t& value = attr->value; - META_LOG_STATUS(status, "remove"); + const sai_attr_metadata_t& md = *mdp; - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(meta_key); - } + META_LOG_DEBUG(md, "(fdbflush)"); - return status; -} + if (attrs.find(attr->id) != attrs.end()) + { + META_LOG_ERROR(md, "attribute id (%u) is defined on attr list multiple times", attr->id); -sai_status_t Meta::remove( - _In_ const sai_ipmc_entry_t* ipmc_entry) -{ - SWSS_LOG_ENTER(); + return SAI_STATUS_INVALID_PARAMETER; + } - sai_status_t status = meta_sai_validate_ipmc_entry(ipmc_entry, false); + attrs[attr->id] = attr; - CHECK_STATUS_SUCCESS(status) + // SAI metadata checks if + // - attribute is create only + // - is not conditional + // - is not valid only - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_IPMC_ENTRY, .objectkey = { .key = { .ipmc_entry = *ipmc_entry } } }; + switch (md.attrvaluetype) + { + case SAI_ATTR_VALUE_TYPE_INT32: - status = meta_generic_validation_remove(meta_key); + if (md.isenum && !sai_metadata_is_allowed_enum_value(&md, value.s32)) + { + META_LOG_ERROR(md, "is enum, but value %d not found on allowed values list", value.s32); - CHECK_STATUS_SUCCESS(status) + return SAI_STATUS_INVALID_PARAMETER; + } - status = m_implementation->remove(ipmc_entry); + break; - META_LOG_STATUS(status, "remove"); + case SAI_ATTR_VALUE_TYPE_OBJECT_ID: - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(meta_key); - } + { + sai_status_t status = meta_generic_validation_objlist(md, switch_id, 1, &value.oid); - return status; -} + CHECK_STATUS_SUCCESS(status) -sai_status_t Meta::remove( - _In_ const sai_nat_entry_t* nat_entry) -{ - SWSS_LOG_ENTER(); + break; + } - sai_status_t status = meta_sai_validate_nat_entry(nat_entry, false); + default: - CHECK_STATUS_SUCCESS(status) + META_LOG_THROW(md, "value type %s is not supported yet, FIXME", + sai_serialize_attr_value_type(md.attrvaluetype).c_str()); + } + } - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NAT_ENTRY, .objectkey = { .key = { .nat_entry = *nat_entry } } }; + // there are no mandatory attributes + // there are no conditional attributes - status = meta_generic_validation_remove(meta_key); + auto status = m_implementation->flushFdbEntries(switch_id, attr_count, attr_list); - CHECK_STATUS_SUCCESS(status) + if (status == SAI_STATUS_SUCCESS) + { + // use same logic as notification, so create notification event - status = m_implementation->remove(nat_entry); + std::vector types; - META_LOG_STATUS(status, "remove"); + auto *et = sai_metadata_get_attr_by_id(SAI_FDB_FLUSH_ATTR_ENTRY_TYPE, attr_count, attr_list); - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(meta_key); - } + if (et) + { + switch (et->value.s32) + { + case SAI_FDB_FLUSH_ENTRY_TYPE_DYNAMIC: + types.push_back(SAI_FDB_ENTRY_TYPE_DYNAMIC); + break; - return status; -} + case SAI_FDB_FLUSH_ENTRY_TYPE_STATIC: + types.push_back(SAI_FDB_ENTRY_TYPE_STATIC); + break; -sai_status_t Meta::remove( - _In_ const sai_inseg_entry_t* inseg_entry) -{ - SWSS_LOG_ENTER(); + default: + types.push_back(SAI_FDB_ENTRY_TYPE_DYNAMIC); + types.push_back(SAI_FDB_ENTRY_TYPE_STATIC); + break; + } + } + else + { + // no type specified so we need to flush dynamic only - sai_status_t status = meta_sai_validate_inseg_entry(inseg_entry, false); + types.push_back(SAI_FDB_ENTRY_TYPE_DYNAMIC); + } - CHECK_STATUS_SUCCESS(status) + for (auto type: types) + { + sai_fdb_event_notification_data_t data = {}; - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY, .objectkey = { .key = { .inseg_entry = *inseg_entry } } }; + auto *bv_id = sai_metadata_get_attr_by_id(SAI_FDB_FLUSH_ATTR_BV_ID, attr_count, attr_list); + auto *bp_id = sai_metadata_get_attr_by_id(SAI_FDB_FLUSH_ATTR_BRIDGE_PORT_ID, attr_count, attr_list); - status = meta_generic_validation_remove(meta_key); + sai_attribute_t list[2]; - CHECK_STATUS_SUCCESS(status) + list[0].id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; + list[0].value.oid = bp_id ? bp_id->value.oid : SAI_NULL_OBJECT_ID; - status = m_implementation->remove(inseg_entry); + list[1].id = SAI_FDB_ENTRY_ATTR_TYPE; + list[1].value.s32 = type; - META_LOG_STATUS(status, "remove"); + data.event_type = SAI_FDB_EVENT_FLUSHED; + data.fdb_entry.switch_id = switch_id; + data.fdb_entry.bv_id = (bv_id) ? bv_id->value.oid : SAI_NULL_OBJECT_ID; + data.attr_count = 2; + data.attr = list; - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(meta_key); + meta_sai_on_fdb_flush_event_consolidated(data); + } } return status; } -sai_status_t Meta::remove( - _In_ const sai_my_sid_entry_t* my_sid_entry) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_my_sid_entry(my_sid_entry, false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_MY_SID_ENTRY, .objectkey = { .key = { .my_sid_entry = *my_sid_entry } } }; - - status = meta_generic_validation_remove(meta_key); - - CHECK_STATUS_SUCCESS(status); - - status = m_implementation->remove(my_sid_entry); - - META_LOG_STATUS(status, "remove"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(meta_key); - } - - return status; -} - -sai_status_t Meta::create( - _In_ const sai_fdb_entry_t* fdb_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_fdb_entry(fdb_entry, true); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_FDB_ENTRY, .objectkey = { .key = { .fdb_entry = *fdb_entry } } }; - - status = meta_generic_validation_create(meta_key, fdb_entry->switch_id, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->create(fdb_entry, attr_count, attr_list); - - META_LOG_STATUS(status, "create"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(meta_key, fdb_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::create( - _In_ const sai_mcast_fdb_entry_t* mcast_fdb_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_mcast_fdb_entry(mcast_fdb_entry, true); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_MCAST_FDB_ENTRY, .objectkey = { .key = { .mcast_fdb_entry = *mcast_fdb_entry } } }; - - status = meta_generic_validation_create(meta_key, mcast_fdb_entry->switch_id, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->create(mcast_fdb_entry, attr_count, attr_list); - - META_LOG_STATUS(status, "create"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(meta_key, mcast_fdb_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::create( - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_neighbor_entry(neighbor_entry, true); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, .objectkey = { .key = { .neighbor_entry = *neighbor_entry } } }; - - status = meta_generic_validation_create(meta_key, neighbor_entry->switch_id, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->create(neighbor_entry, attr_count, attr_list); - - META_LOG_STATUS(status, "create"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(meta_key, neighbor_entry->switch_id, attr_count, attr_list); - } - - return status; -} -sai_status_t Meta::create( - _In_ const sai_route_entry_t* route_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_route_entry(route_entry, true); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY, .objectkey = { .key = { .route_entry = *route_entry } } }; - - status = meta_generic_validation_create(meta_key, route_entry->switch_id, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->create(route_entry, attr_count, attr_list); - - META_LOG_STATUS(status, "create"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(meta_key, route_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::create( - _In_ const sai_l2mc_entry_t* l2mc_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_l2mc_entry(l2mc_entry, true); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY, .objectkey = { .key = { .l2mc_entry = *l2mc_entry } } }; - - status = meta_generic_validation_create(meta_key, l2mc_entry->switch_id, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->create(l2mc_entry, attr_count, attr_list); - - META_LOG_STATUS(status, "create"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(meta_key, l2mc_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::create( - _In_ const sai_ipmc_entry_t* ipmc_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_ipmc_entry(ipmc_entry, true); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_IPMC_ENTRY, .objectkey = { .key = { .ipmc_entry = *ipmc_entry } } }; - - status = meta_generic_validation_create(meta_key, ipmc_entry->switch_id, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->create(ipmc_entry, attr_count, attr_list); - - META_LOG_STATUS(status, "create"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(meta_key, ipmc_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::create( - _In_ const sai_inseg_entry_t* inseg_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_inseg_entry(inseg_entry, true); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY, .objectkey = { .key = { .inseg_entry = *inseg_entry } } }; - - status = meta_generic_validation_create(meta_key, inseg_entry->switch_id, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->create(inseg_entry, attr_count, attr_list); - - META_LOG_STATUS(status, "create"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(meta_key, inseg_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::create( - _In_ const sai_nat_entry_t* nat_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_nat_entry(nat_entry, true); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NAT_ENTRY, .objectkey = { .key = { .nat_entry = *nat_entry } } }; - - status = meta_generic_validation_create(meta_key, nat_entry->switch_id, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->create(nat_entry, attr_count, attr_list); - - META_LOG_STATUS(status, "create"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(meta_key, nat_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::create( - _In_ const sai_my_sid_entry_t* my_sid_entry, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_my_sid_entry(my_sid_entry, true); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_MY_SID_ENTRY, .objectkey = { .key = { .my_sid_entry = *my_sid_entry } } }; - - status = meta_generic_validation_create(meta_key, my_sid_entry->switch_id, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status); - - status = m_implementation->create(my_sid_entry, attr_count, attr_list); - - META_LOG_STATUS(status, "create"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(meta_key, my_sid_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::set( - _In_ const sai_fdb_entry_t* fdb_entry, - _In_ const sai_attribute_t *attr) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_fdb_entry(fdb_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_FDB_ENTRY, .objectkey = { .key = { .fdb_entry = *fdb_entry } } }; - - status = meta_generic_validation_set(meta_key, attr); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->set(fdb_entry, attr); - - META_LOG_STATUS(status, "set"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(meta_key, attr); - } - - return status; -} - -sai_status_t Meta::set( - _In_ const sai_mcast_fdb_entry_t* mcast_fdb_entry, - _In_ const sai_attribute_t *attr) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_mcast_fdb_entry(mcast_fdb_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_MCAST_FDB_ENTRY, .objectkey = { .key = { .mcast_fdb_entry = *mcast_fdb_entry } } }; - - status = meta_generic_validation_set(meta_key, attr); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->set(mcast_fdb_entry, attr); - - META_LOG_STATUS(status, "set"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(meta_key, attr); - } - - return status; -} - -sai_status_t Meta::set( - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ const sai_attribute_t *attr) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_neighbor_entry(neighbor_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, .objectkey = { .key = { .neighbor_entry = *neighbor_entry } } }; - - status = meta_generic_validation_set(meta_key, attr); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->set(neighbor_entry, attr); - - META_LOG_STATUS(status, "set"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(meta_key, attr); - } - - return status; -} - -sai_status_t Meta::set( - _In_ const sai_route_entry_t* route_entry, - _In_ const sai_attribute_t *attr) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_route_entry(route_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY, .objectkey = { .key = { .route_entry = *route_entry } } }; - - status = meta_generic_validation_set(meta_key, attr); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->set(route_entry, attr); - - META_LOG_STATUS(status, "set"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(meta_key, attr); - } - - return status; -} - -sai_status_t Meta::set( - _In_ const sai_l2mc_entry_t* l2mc_entry, - _In_ const sai_attribute_t *attr) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_l2mc_entry(l2mc_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY, .objectkey = { .key = { .l2mc_entry = *l2mc_entry } } }; - - status = meta_generic_validation_set(meta_key, attr); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->set(l2mc_entry, attr); - - META_LOG_STATUS(status, "set"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(meta_key, attr); - } - - return status; -} - -sai_status_t Meta::set( - _In_ const sai_ipmc_entry_t* ipmc_entry, - _In_ const sai_attribute_t *attr) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_ipmc_entry(ipmc_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_IPMC_ENTRY, .objectkey = { .key = { .ipmc_entry = *ipmc_entry } } }; - - status = meta_generic_validation_set(meta_key, attr); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->set(ipmc_entry, attr); - - META_LOG_STATUS(status, "set"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(meta_key, attr); - } - - return status; -} - -sai_status_t Meta::set( - _In_ const sai_inseg_entry_t* inseg_entry, - _In_ const sai_attribute_t *attr) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_inseg_entry(inseg_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY, .objectkey = { .key = { .inseg_entry = *inseg_entry } } }; - - status = meta_generic_validation_set(meta_key, attr); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->set(inseg_entry, attr); - - META_LOG_STATUS(status, "set"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(meta_key, attr); - } - - return status; -} - -sai_status_t Meta::set( - _In_ const sai_nat_entry_t* nat_entry, - _In_ const sai_attribute_t *attr) -{ - SWSS_LOG_ENTER(); - sai_status_t status = meta_sai_validate_nat_entry(nat_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NAT_ENTRY, .objectkey = { .key = { .nat_entry = *nat_entry } } }; - - status = meta_generic_validation_set(meta_key, attr); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->set(nat_entry, attr); - - META_LOG_STATUS(status, "set"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(meta_key, attr); - } - - return status; -} - -sai_status_t Meta::set( - _In_ const sai_my_sid_entry_t* my_sid_entry, - _In_ const sai_attribute_t *attr) -{ - SWSS_LOG_ENTER(); - sai_status_t status = meta_sai_validate_my_sid_entry(my_sid_entry, false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_MY_SID_ENTRY, .objectkey = { .key = { .my_sid_entry = *my_sid_entry } } }; - - status = meta_generic_validation_set(meta_key, attr); - - CHECK_STATUS_SUCCESS(status); - - status = m_implementation->set(my_sid_entry, attr); - - META_LOG_STATUS(status, "set"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(meta_key, attr); - } - - return status; -} - -sai_status_t Meta::get( - _In_ const sai_fdb_entry_t* fdb_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - // NOTE: when doing get, entry may not exist on metadata db - - sai_status_t status = meta_sai_validate_fdb_entry(fdb_entry, false, true); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_FDB_ENTRY, .objectkey = { .key = { .fdb_entry = *fdb_entry } } }; - - status = meta_generic_validation_get(meta_key, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->get(fdb_entry, attr_count, attr_list); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_get(meta_key, fdb_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::get( - _In_ const sai_mcast_fdb_entry_t* mcast_fdb_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - // NOTE: when doing get, entry may not exist on metadata db - - sai_status_t status = meta_sai_validate_mcast_fdb_entry(mcast_fdb_entry, false, true); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_MCAST_FDB_ENTRY, .objectkey = { .key = { .mcast_fdb_entry = *mcast_fdb_entry } } }; - - status = meta_generic_validation_get(meta_key, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->get(mcast_fdb_entry, attr_count, attr_list); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_get(meta_key, mcast_fdb_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::get( - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_neighbor_entry(neighbor_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, .objectkey = { .key = { .neighbor_entry = *neighbor_entry } } }; - - status = meta_generic_validation_get(meta_key, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->get(neighbor_entry, attr_count, attr_list); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_get(meta_key, neighbor_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::get( - _In_ const sai_route_entry_t* route_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_route_entry(route_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY, .objectkey = { .key = { .route_entry = *route_entry } } }; - - status = meta_generic_validation_get(meta_key, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->get(route_entry, attr_count, attr_list); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_get(meta_key, route_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::get( - _In_ const sai_l2mc_entry_t* l2mc_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_l2mc_entry(l2mc_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY, .objectkey = { .key = { .l2mc_entry = *l2mc_entry } } }; - - status = meta_generic_validation_get(meta_key, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->get(l2mc_entry, attr_count, attr_list); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_get(meta_key, l2mc_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::get( - _In_ const sai_ipmc_entry_t* ipmc_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_ipmc_entry(ipmc_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_IPMC_ENTRY, .objectkey = { .key = { .ipmc_entry = *ipmc_entry } } }; - - status = meta_generic_validation_get(meta_key, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->get(ipmc_entry, attr_count, attr_list); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_get(meta_key, ipmc_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::get( - _In_ const sai_inseg_entry_t* inseg_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_inseg_entry(inseg_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY, .objectkey = { .key = { .inseg_entry = *inseg_entry } } }; - - status = meta_generic_validation_get(meta_key, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->get(inseg_entry, attr_count, attr_list); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_get(meta_key, inseg_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::get( - _In_ const sai_nat_entry_t* nat_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_nat_entry(nat_entry, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NAT_ENTRY, .objectkey = { .key = { .nat_entry = *nat_entry } } }; - - status = meta_generic_validation_get(meta_key, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->get(nat_entry, attr_count, attr_list); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_get(meta_key, nat_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::get( - _In_ const sai_my_sid_entry_t* my_sid_entry, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_my_sid_entry(my_sid_entry, false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_MY_SID_ENTRY, .objectkey = { .key = { .my_sid_entry = *my_sid_entry } } }; - - status = meta_generic_validation_get(meta_key, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status); - - status = m_implementation->get(my_sid_entry, attr_count, attr_list); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_get(meta_key, my_sid_entry->switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::create( - _In_ sai_object_type_t object_type, - _Out_ sai_object_id_t* object_id, - _In_ sai_object_id_t switch_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_status_t status = meta_sai_validate_oid(object_type, object_id, switch_id, true); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = SAI_NULL_OBJECT_ID } } }; - - status = meta_generic_validation_create(meta_key, switch_id, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->create(object_type, object_id, switch_id, attr_count, attr_list); - - META_LOG_STATUS(status, "create"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_key.objectkey.key.object_id = *object_id; - - if (meta_key.objecttype == SAI_OBJECT_TYPE_SWITCH) - { - /* - * We are creating switch object, so switch id must be the same as - * just created object. We could use SAI_NULL_OBJECT_ID in that - * case and do special switch inside post_create method. - */ - - switch_id = *object_id; - } - - meta_generic_validation_post_create(meta_key, switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::set( - _In_ sai_object_type_t object_type, - _In_ sai_object_id_t object_id, - _In_ const sai_attribute_t *attr) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t switch_id = switchIdQuery(object_id); - - if (!m_oids.objectReferenceExists(switch_id)) - { - SWSS_LOG_ERROR("switch id %s doesn't exist", - sai_serialize_object_id(switch_id).c_str()); - - return SAI_STATUS_INVALID_PARAMETER; - } - - sai_status_t status = meta_sai_validate_oid(object_type, &object_id, SAI_NULL_OBJECT_ID, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = object_id } } }; - - status = meta_generic_validation_set(meta_key, attr); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->set(object_type, object_id, attr); - - META_LOG_STATUS(status, "set"); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(meta_key, attr); - } - - return status; -} - -sai_status_t Meta::get( - _In_ sai_object_type_t object_type, - _In_ sai_object_id_t object_id, - _In_ uint32_t attr_count, - _Inout_ sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - sai_object_id_t switch_id = switchIdQuery(object_id); - - sai_status_t status = meta_sai_validate_oid(object_type, &object_id, SAI_NULL_OBJECT_ID, false); - - CHECK_STATUS_SUCCESS(status) - - sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = object_id } } }; - - status = meta_generic_validation_get(meta_key, attr_count, attr_list); - - CHECK_STATUS_SUCCESS(status) - - status = m_implementation->get(object_type, object_id, attr_count, attr_list); - - if (status == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_get(meta_key, switch_id, attr_count, attr_list); - } - - return status; -} - -sai_status_t Meta::flushFdbEntries( - _In_ sai_object_id_t switch_id, - _In_ uint32_t attr_count, - _In_ const sai_attribute_t *attr_list) -{ - SWSS_LOG_ENTER(); - - if (attr_count > MAX_LIST_COUNT) - { - SWSS_LOG_ERROR("create attribute count %u > max list count %u", attr_count, MAX_LIST_COUNT); - - return SAI_STATUS_INVALID_PARAMETER; - } - - if (attr_count != 0 && attr_list == NULL) - { - SWSS_LOG_ERROR("attribute list is NULL"); - - return SAI_STATUS_INVALID_PARAMETER; - } - - sai_object_type_t swot = objectTypeQuery(switch_id); - - if (swot != SAI_OBJECT_TYPE_SWITCH) - { - SWSS_LOG_ERROR("object type for switch_id %s is %s", - sai_serialize_object_id(switch_id).c_str(), - sai_serialize_object_type(swot).c_str()); - - return SAI_STATUS_INVALID_PARAMETER; - } - - if (!m_oids.objectReferenceExists(switch_id)) - { - SWSS_LOG_ERROR("switch id %s doesn't exist", - sai_serialize_object_id(switch_id).c_str()); - - return SAI_STATUS_INVALID_PARAMETER; - } - - // validate attributes - // - attribute list can be empty - // - validation is similar to "create" action but there is no - // post create step and no references are updated - // - fdb entries are updated in fdb notification - - std::unordered_map attrs; - - SWSS_LOG_DEBUG("attr count = %u", attr_count); - - for (uint32_t idx = 0; idx < attr_count; ++idx) - { - const sai_attribute_t* attr = &attr_list[idx]; - - auto mdp = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_FDB_FLUSH, attr->id); - - if (mdp == NULL) - { - SWSS_LOG_ERROR("unable to find attribute metadata SAI_OBJECT_TYPE_FDB_FLUSH:%d", attr->id); - - return SAI_STATUS_INVALID_PARAMETER; - } - - const sai_attribute_value_t& value = attr->value; - - const sai_attr_metadata_t& md = *mdp; - - META_LOG_DEBUG(md, "(fdbflush)"); - - if (attrs.find(attr->id) != attrs.end()) - { - META_LOG_ERROR(md, "attribute id (%u) is defined on attr list multiple times", attr->id); - - return SAI_STATUS_INVALID_PARAMETER; - } - - attrs[attr->id] = attr; - - // SAI metadata checks if - // - attribute is create only - // - is not conditional - // - is not valid only - - switch (md.attrvaluetype) - { - case SAI_ATTR_VALUE_TYPE_INT32: - - if (md.isenum && !sai_metadata_is_allowed_enum_value(&md, value.s32)) - { - META_LOG_ERROR(md, "is enum, but value %d not found on allowed values list", value.s32); - - return SAI_STATUS_INVALID_PARAMETER; - } - - break; - - case SAI_ATTR_VALUE_TYPE_OBJECT_ID: - - { - sai_status_t status = meta_generic_validation_objlist(md, switch_id, 1, &value.oid); - - CHECK_STATUS_SUCCESS(status) - - break; - } - - default: - - META_LOG_THROW(md, "value type %s is not supported yet, FIXME", - sai_serialize_attr_value_type(md.attrvaluetype).c_str()); - } - } - - // there are no mandatory attributes - // there are no conditional attributes - - auto status = m_implementation->flushFdbEntries(switch_id, attr_count, attr_list); - - if (status == SAI_STATUS_SUCCESS) - { - // use same logic as notification, so create notification event - - std::vector types; - - auto *et = sai_metadata_get_attr_by_id(SAI_FDB_FLUSH_ATTR_ENTRY_TYPE, attr_count, attr_list); - - if (et) - { - switch (et->value.s32) - { - case SAI_FDB_FLUSH_ENTRY_TYPE_DYNAMIC: - types.push_back(SAI_FDB_ENTRY_TYPE_DYNAMIC); - break; - - case SAI_FDB_FLUSH_ENTRY_TYPE_STATIC: - types.push_back(SAI_FDB_ENTRY_TYPE_STATIC); - break; - - default: - types.push_back(SAI_FDB_ENTRY_TYPE_DYNAMIC); - types.push_back(SAI_FDB_ENTRY_TYPE_STATIC); - break; - } - } - else - { - // no type specified so we need to flush dynamic only - - types.push_back(SAI_FDB_ENTRY_TYPE_DYNAMIC); - } - - for (auto type: types) - { - sai_fdb_event_notification_data_t data = {}; - - auto *bv_id = sai_metadata_get_attr_by_id(SAI_FDB_FLUSH_ATTR_BV_ID, attr_count, attr_list); - auto *bp_id = sai_metadata_get_attr_by_id(SAI_FDB_FLUSH_ATTR_BRIDGE_PORT_ID, attr_count, attr_list); - - sai_attribute_t list[2]; - - list[0].id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID; - list[0].value.oid = bp_id ? bp_id->value.oid : SAI_NULL_OBJECT_ID; - - list[1].id = SAI_FDB_ENTRY_ATTR_TYPE; - list[1].value.s32 = type; - - data.event_type = SAI_FDB_EVENT_FLUSHED; - data.fdb_entry.switch_id = switch_id; - data.fdb_entry.bv_id = (bv_id) ? bv_id->value.oid : SAI_NULL_OBJECT_ID; - data.attr_count = 2; - data.attr = list; - - meta_sai_on_fdb_flush_event_consolidated(data); - } - } - - return status; -} - -#define PARAMETER_CHECK_IF_NOT_NULL(param) { \ - if ((param) == nullptr) { \ - SWSS_LOG_ERROR("parameter " # param " is NULL"); \ - return SAI_STATUS_INVALID_PARAMETER; } } - -#define PARAMETER_CHECK_OID_OBJECT_TYPE(param, OT) { \ - sai_object_type_t _ot = objectTypeQuery(param); \ - if (_ot != (OT)) { \ - SWSS_LOG_ERROR("parameter " # param " %s object type is %s, but expected %s", \ - sai_serialize_object_id(param).c_str(), \ - sai_serialize_object_type(_ot).c_str(), \ - sai_serialize_object_type(OT).c_str()); \ - return SAI_STATUS_INVALID_PARAMETER; } } - -#define PARAMETER_CHECK_OBJECT_TYPE_VALID(ot) { \ - if (!sai_metadata_is_object_type_valid(ot)) { \ - SWSS_LOG_ERROR("parameter " # ot " object type %d is invalid", (ot)); \ - return SAI_STATUS_INVALID_PARAMETER; } } - -#define PARAMETER_CHECK_POSITIVE(param) { \ - if ((param) <= 0) { \ - SWSS_LOG_ERROR("parameter " #param " must be positive"); \ - return SAI_STATUS_INVALID_PARAMETER; } } - -#define PARAMETER_CHECK_OID_EXISTS(oid, OT) { \ - sai_object_meta_key_t _key = { \ - .objecttype = (OT), .objectkey = { .key = { .object_id = (oid) } } }; \ - if (!m_saiObjectCollection.objectExists(_key)) { \ - SWSS_LOG_ERROR("object %s don't exists", sai_serialize_object_id(oid).c_str()); } } - -sai_status_t Meta::objectTypeGetAvailability( - _In_ sai_object_id_t switchId, - _In_ sai_object_type_t objectType, - _In_ uint32_t attrCount, - _In_ const sai_attribute_t *attrList, - _Out_ uint64_t *count) -{ - SWSS_LOG_ENTER(); - - PARAMETER_CHECK_OID_OBJECT_TYPE(switchId, SAI_OBJECT_TYPE_SWITCH); - PARAMETER_CHECK_OID_EXISTS(switchId, SAI_OBJECT_TYPE_SWITCH); - PARAMETER_CHECK_OBJECT_TYPE_VALID(objectType); - - // When checking availability of a resource solely based on OBJECT_TYPE, attrCount is 0 - - if (attrCount) - { - PARAMETER_CHECK_IF_NOT_NULL(attrList); - } - - PARAMETER_CHECK_IF_NOT_NULL(count); - - auto info = sai_metadata_get_object_type_info(objectType); - - PARAMETER_CHECK_IF_NOT_NULL(info); - - std::set attrs; - - for (uint32_t idx = 0; idx < attrCount; idx++) - { - auto id = attrList[idx].id; - - auto mdp = sai_metadata_get_attr_metadata(objectType, id); - - if (mdp == nullptr) - { - SWSS_LOG_ERROR("can't find attribute %s:%d", - info->objecttypename, - attrList[idx].id); - - return SAI_STATUS_INVALID_PARAMETER; - } - - if (attrs.find(id) != attrs.end()) - { - SWSS_LOG_ERROR("attr %s already defined on list", mdp->attridname); - - return SAI_STATUS_INVALID_PARAMETER; - } - - attrs.insert(id); - - if (!mdp->isresourcetype) - { - SWSS_LOG_ERROR("attr %s is not resource type", mdp->attridname); - - return SAI_STATUS_INVALID_PARAMETER; - } - - switch (mdp->attrvaluetype) - { - case SAI_ATTR_VALUE_TYPE_INT32: - - if (mdp->isenum && !sai_metadata_is_allowed_enum_value(mdp, attrList[idx].value.s32)) - { - SWSS_LOG_ERROR("%s is enum, but value %d not found on allowed values list", - mdp->attridname, - attrList[idx].value.s32); - - return SAI_STATUS_INVALID_PARAMETER; - } - - break; - - default: - - META_LOG_THROW(*mdp, "value type %s not supported yet, FIXME!", - sai_serialize_attr_value_type(mdp->attrvaluetype).c_str()); - } - } - - auto status = m_implementation->objectTypeGetAvailability(switchId, objectType, attrCount, attrList, count); - - // no post validation required - - return status; -} - -sai_status_t Meta::queryAttributeCapability( - _In_ sai_object_id_t switchId, - _In_ sai_object_type_t objectType, - _In_ sai_attr_id_t attrId, - _Out_ sai_attr_capability_t *capability) -{ - SWSS_LOG_ENTER(); - - PARAMETER_CHECK_OID_OBJECT_TYPE(switchId, SAI_OBJECT_TYPE_SWITCH); - PARAMETER_CHECK_OID_EXISTS(switchId, SAI_OBJECT_TYPE_SWITCH); - PARAMETER_CHECK_OBJECT_TYPE_VALID(objectType); - - auto mdp = sai_metadata_get_attr_metadata(objectType, attrId); - - if (!mdp) - { - SWSS_LOG_ERROR("unable to find attribute: %s:%d", - sai_serialize_object_type(objectType).c_str(), - attrId); - - return SAI_STATUS_INVALID_PARAMETER; - } - - PARAMETER_CHECK_IF_NOT_NULL(capability); - - auto status = m_implementation->queryAttributeCapability(switchId, objectType, attrId, capability); - - // no post validation required - - return status; -} - -sai_status_t Meta::queryAattributeEnumValuesCapability( - _In_ sai_object_id_t switchId, - _In_ sai_object_type_t objectType, - _In_ sai_attr_id_t attrId, - _Inout_ sai_s32_list_t *enumValuesCapability) -{ - SWSS_LOG_ENTER(); - - PARAMETER_CHECK_OID_OBJECT_TYPE(switchId, SAI_OBJECT_TYPE_SWITCH); - PARAMETER_CHECK_OID_EXISTS(switchId, SAI_OBJECT_TYPE_SWITCH); - PARAMETER_CHECK_OBJECT_TYPE_VALID(objectType); - - auto mdp = sai_metadata_get_attr_metadata(objectType, attrId); - - if (!mdp) - { - SWSS_LOG_ERROR("unable to find attribute: %s:%d", - sai_serialize_object_type(objectType).c_str(), - attrId); - - return SAI_STATUS_INVALID_PARAMETER; - } - - if (!mdp->isenum && !mdp->isenumlist) - { - SWSS_LOG_ERROR("%s is not enum/enum list", mdp->attridname); - - return SAI_STATUS_INVALID_PARAMETER; - } - - PARAMETER_CHECK_IF_NOT_NULL(enumValuesCapability); - - if (meta_genetic_validation_list(*mdp, enumValuesCapability->count, enumValuesCapability->list) - != SAI_STATUS_SUCCESS) - { - return SAI_STATUS_INVALID_PARAMETER; - } - - auto status = m_implementation->queryAattributeEnumValuesCapability(switchId, objectType, attrId, enumValuesCapability); - - if (status == SAI_STATUS_SUCCESS) - { - if (enumValuesCapability->list) - { - // check if all returned values are members of defined enum - - for (uint32_t idx = 0; idx < enumValuesCapability->count; idx++) - { - int val = enumValuesCapability->list[idx]; - - if (!sai_metadata_is_allowed_enum_value(mdp, val)) - { - SWSS_LOG_ERROR("returned value %d is not allowed on %s", val, mdp->attridname); - } - } - } - } - - return status; -} - -#define META_COUNTERS_COUNT_MSB (0x80000000) - -sai_status_t Meta::meta_validate_stats( - _In_ sai_object_type_t object_type, - _In_ sai_object_id_t object_id, - _In_ uint32_t number_of_counters, - _In_ const sai_stat_id_t *counter_ids, - _Out_ uint64_t *counters, - _In_ sai_stats_mode_t mode) -{ - SWSS_LOG_ENTER(); - - /* - * If last bit of counters count is set to high, and unittests are enabled, - * then this api can be used to SET counter values by user for debugging purposes. - */ - - if (m_unittestsEnabled) - { - number_of_counters &= ~(META_COUNTERS_COUNT_MSB); - } - - PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); - PARAMETER_CHECK_OID_OBJECT_TYPE(object_id, object_type); - PARAMETER_CHECK_OID_EXISTS(object_id, object_type); - PARAMETER_CHECK_POSITIVE(number_of_counters); - PARAMETER_CHECK_IF_NOT_NULL(counter_ids); - PARAMETER_CHECK_IF_NOT_NULL(counters); - - sai_object_id_t switch_id = switchIdQuery(object_id); - - // checks also if object type is OID - sai_status_t status = meta_sai_validate_oid(object_type, &object_id, switch_id, false); - - CHECK_STATUS_SUCCESS(status); - - auto info = sai_metadata_get_object_type_info(object_type); - - PARAMETER_CHECK_IF_NOT_NULL(info); - - if (info->statenum == nullptr) - { - SWSS_LOG_ERROR("%s does not support stats", info->objecttypename); - - return SAI_STATUS_INVALID_PARAMETER; - } - - // check if all counter ids are in enum range - - for (uint32_t idx = 0; idx < number_of_counters; idx++) - { - if (sai_metadata_get_enum_value_name(info->statenum, counter_ids[idx]) == nullptr) - { - SWSS_LOG_ERROR("value %d is not in range on %s", counter_ids[idx], info->statenum->name); - - return SAI_STATUS_INVALID_PARAMETER; - } - } - - // check mode - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_stats_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_stats_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - return SAI_STATUS_SUCCESS; -} - -sai_status_t Meta::meta_validate_query_stats_capability( - _In_ sai_object_type_t object_type, - _In_ sai_object_id_t object_id) -{ - SWSS_LOG_ENTER(); - - PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); - PARAMETER_CHECK_OID_OBJECT_TYPE(object_id, object_type); - PARAMETER_CHECK_OID_EXISTS(object_id, object_type); - - sai_object_id_t switch_id = switchIdQuery(object_id); - - // checks also if object type is OID - sai_status_t status = meta_sai_validate_oid(object_type, &object_id, switch_id, false); - - CHECK_STATUS_SUCCESS(status); - - auto info = sai_metadata_get_object_type_info(object_type); - - PARAMETER_CHECK_IF_NOT_NULL(info); - - if (info->statenum == nullptr) - { - SWSS_LOG_ERROR("%s does not support stats", info->objecttypename); - - return SAI_STATUS_INVALID_PARAMETER; - } - - return SAI_STATUS_SUCCESS; -} - -sai_status_t Meta::getStats( - _In_ sai_object_type_t object_type, - _In_ sai_object_id_t object_id, - _In_ uint32_t number_of_counters, - _In_ const sai_stat_id_t *counter_ids, - _Out_ uint64_t *counters) -{ - SWSS_LOG_ENTER(); - - auto status = meta_validate_stats(object_type, object_id, number_of_counters, counter_ids, counters, SAI_STATS_MODE_READ); - - CHECK_STATUS_SUCCESS(status); - - status = m_implementation->getStats(object_type, object_id, number_of_counters, counter_ids, counters); - - // no post validation required - - return status; -} - -sai_status_t Meta::queryStatsCapability( - _In_ sai_object_id_t switchId, - _In_ sai_object_type_t objectType, - _Inout_ sai_stat_capability_list_t *stats_capability) -{ - SWSS_LOG_ENTER(); - - auto status = meta_validate_query_stats_capability(objectType, switchId); - - CHECK_STATUS_SUCCESS(status); - - status = m_implementation->queryStatsCapability(switchId, objectType, stats_capability); - - // no post validation required - - return status; -} - -sai_status_t Meta::getStatsExt( - _In_ sai_object_type_t object_type, - _In_ sai_object_id_t object_id, - _In_ uint32_t number_of_counters, - _In_ const sai_stat_id_t *counter_ids, - _In_ sai_stats_mode_t mode, - _Out_ uint64_t *counters) -{ - SWSS_LOG_ENTER(); - - auto status = meta_validate_stats(object_type, object_id, number_of_counters, counter_ids, counters, mode); - - CHECK_STATUS_SUCCESS(status); - - status = m_implementation->getStatsExt(object_type, object_id, number_of_counters, counter_ids, mode, counters); - - // no post validation required - - return status; -} - -sai_status_t Meta::clearStats( - _In_ sai_object_type_t object_type, - _In_ sai_object_id_t object_id, - _In_ uint32_t number_of_counters, - _In_ const sai_stat_id_t *counter_ids) -{ - SWSS_LOG_ENTER(); - - uint64_t counters; - auto status = meta_validate_stats(object_type, object_id, number_of_counters, counter_ids, &counters, SAI_STATS_MODE_READ); - - CHECK_STATUS_SUCCESS(status); - - status = m_implementation->clearStats(object_type, object_id, number_of_counters, counter_ids); - - // no post validation required - - return status; -} - -sai_status_t Meta::bulkGetStats( - _In_ sai_object_id_t switchId, - _In_ sai_object_type_t object_type, - _In_ uint32_t object_count, - _In_ const sai_object_key_t *object_key, - _In_ uint32_t number_of_counters, - _In_ const sai_stat_id_t *counter_ids, - _In_ sai_stats_mode_t mode, - _Inout_ sai_status_t *object_statuses, - _Out_ uint64_t *counters) -{ - SWSS_LOG_ENTER(); - - return SAI_STATUS_NOT_IMPLEMENTED; -} - -sai_status_t Meta::bulkClearStats( - _In_ sai_object_id_t switchId, - _In_ sai_object_type_t object_type, - _In_ uint32_t object_count, - _In_ const sai_object_key_t *object_key, - _In_ uint32_t number_of_counters, - _In_ const sai_stat_id_t *counter_ids, - _In_ sai_stats_mode_t mode, - _Inout_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - return SAI_STATUS_NOT_IMPLEMENTED; -} - -// for bulk operations actually we could make copy of current db and actually -// execute to see if all will succeed - -sai_status_t Meta::bulkRemove( - _In_ sai_object_type_t object_type, - _In_ uint32_t object_count, - _In_ const sai_object_id_t *object_id, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // all objects must be same type and come from the same switch - // TODO check multiple switches - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(object_id); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_oid(object_type, &object_id[idx], SAI_NULL_OBJECT_ID, false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = object_id[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_remove(meta_key); - - CHECK_STATUS_SUCCESS(status); - } - - auto status = m_implementation->bulkRemove(object_type, object_count, object_id, mode, object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(vmk[idx]); - } - } - - return status; -} - -sai_status_t Meta::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // all objects must be same type and come from the same switch - // TODO check multiple switches - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(route_entry); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_route_entry(&route_entry[idx], false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY, .objectkey = { .key = { .route_entry = route_entry[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_remove(meta_key); - - CHECK_STATUS_SUCCESS(status); - } - - auto status = m_implementation->bulkRemove(object_count, route_entry, mode, object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(vmk[idx]); - } - } - - return status; -} - -sai_status_t Meta::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // all objects must be same type and come from the same switch - // TODO check multiple switches - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(nat_entry); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_nat_entry(&nat_entry[idx], false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NAT_ENTRY, .objectkey = { .key = { .nat_entry = nat_entry[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_remove(meta_key); - - CHECK_STATUS_SUCCESS(status); - } - - auto status = m_implementation->bulkRemove(object_count, nat_entry, mode, object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(vmk[idx]); - } - } - - return status; -} - -sai_status_t Meta::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // all objects must be same type and come from the same switch - // TODO check multiple switches - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - //PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(my_sid_entry); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_my_sid_entry(&my_sid_entry[idx], false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_MY_SID_ENTRY, .objectkey = { .key = { .my_sid_entry = my_sid_entry[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_remove(meta_key); - - CHECK_STATUS_SUCCESS(status); - } - - auto status = m_implementation->bulkRemove(object_count, my_sid_entry, mode, object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(vmk[idx]); - } - } - - return status; -} - -sai_status_t Meta::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t *neighbor_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // all objects must be same type and come from the same switch - // TODO check multiple switches - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - //PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(neighbor_entry); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_neighbor_entry(&neighbor_entry[idx], false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, .objectkey = { .key = { .neighbor_entry = neighbor_entry[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_remove(meta_key); - - CHECK_STATUS_SUCCESS(status); - } - - auto status = m_implementation->bulkRemove(object_count, neighbor_entry, mode, object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(vmk[idx]); - } - } - - return status; -} - -sai_status_t Meta::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // all objects must be same type and come from the same switch - // TODO check multiple switches - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(fdb_entry); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_fdb_entry(&fdb_entry[idx], false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_FDB_ENTRY, .objectkey = { .key = { .fdb_entry = fdb_entry[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_remove(meta_key); - - CHECK_STATUS_SUCCESS(status); - } - - auto status = m_implementation->bulkRemove(object_count, fdb_entry, mode, object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(vmk[idx]); - } - } - - return status; -} - -sai_status_t Meta::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // all objects must be same type and come from the same switch - // TODO check multiple switches - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(inseg_entry); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_stats_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode vlaue %d is not in range on %s", mode, sai_metadata_enum_sai_stats_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_inseg_entry(&inseg_entry[idx], false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY, .objectkey = { .key = { .inseg_entry = inseg_entry[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_remove(meta_key); - - CHECK_STATUS_SUCCESS(status); - } - - auto status = m_implementation->bulkRemove(object_count, inseg_entry, mode, object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_remove(vmk[idx]); - } - } - - return status; -} - -sai_status_t Meta::bulkSet( - _In_ sai_object_type_t object_type, - _In_ uint32_t object_count, - _In_ const sai_object_id_t *object_id, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - // all objects must be same type and come from the same switch - // TODO check multiple switches - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(object_id); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_oid(object_type, &object_id[idx], SAI_NULL_OBJECT_ID, false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = object_id[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_set(meta_key, &attr_list[idx]); - - CHECK_STATUS_SUCCESS(status); - } - - auto status = m_implementation->bulkSet(object_type, object_count, object_id, attr_list, mode, object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(vmk[idx], &attr_list[idx]); - } - } - - return status; -} - -sai_status_t Meta::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(route_entry); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_route_entry(&route_entry[idx], false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY, .objectkey = { .key = { .route_entry = route_entry[idx] } } }; - - vmk.push_back(meta_key); +#define PARAMETER_CHECK_IF_NOT_NULL(param) { \ + if ((param) == nullptr) { \ + SWSS_LOG_ERROR("parameter " # param " is NULL"); \ + return SAI_STATUS_INVALID_PARAMETER; } } - status = meta_generic_validation_set(meta_key, &attr_list[idx]); +#define PARAMETER_CHECK_OID_OBJECT_TYPE(param, OT) { \ + sai_object_type_t _ot = objectTypeQuery(param); \ + if (_ot != (OT)) { \ + SWSS_LOG_ERROR("parameter " # param " %s object type is %s, but expected %s", \ + sai_serialize_object_id(param).c_str(), \ + sai_serialize_object_type(_ot).c_str(), \ + sai_serialize_object_type(OT).c_str()); \ + return SAI_STATUS_INVALID_PARAMETER; } } - CHECK_STATUS_SUCCESS(status); - } +#define PARAMETER_CHECK_OBJECT_TYPE_VALID(ot) { \ + if (!sai_metadata_is_object_type_valid(ot)) { \ + SWSS_LOG_ERROR("parameter " # ot " object type %d is invalid", (ot)); \ + return SAI_STATUS_INVALID_PARAMETER; } } - auto status = m_implementation->bulkSet(object_count, route_entry, attr_list, mode, object_statuses); +#define PARAMETER_CHECK_POSITIVE(param) { \ + if ((param) <= 0) { \ + SWSS_LOG_ERROR("parameter " #param " must be positive"); \ + return SAI_STATUS_INVALID_PARAMETER; } } - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(vmk[idx], &attr_list[idx]); - } - } +#define PARAMETER_CHECK_OID_EXISTS(oid, OT) { \ + sai_object_meta_key_t _key = { \ + .objecttype = (OT), .objectkey = { .key = { .object_id = (oid) } } }; \ + if (!m_saiObjectCollection.objectExists(_key)) { \ + SWSS_LOG_ERROR("object %s don't exists", sai_serialize_object_id(oid).c_str()); } } - return status; -} +#define DECLARE_BULK_CREATE_ENTRY(OT,ot) \ +sai_status_t Meta::bulkCreate( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t *ot, \ + _In_ const uint32_t *attr_count, \ + _In_ const sai_attribute_t **attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + PARAMETER_CHECK_IF_NOT_NULL(object_statuses); \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; \ + } \ + PARAMETER_CHECK_POSITIVE(object_count); \ + PARAMETER_CHECK_IF_NOT_NULL(ot); \ + PARAMETER_CHECK_IF_NOT_NULL(attr_count); \ + PARAMETER_CHECK_IF_NOT_NULL(attr_list); \ + if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) \ + { \ + SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); \ + return SAI_STATUS_INVALID_PARAMETER; \ + } \ + std::vector vmk; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + sai_status_t status = meta_sai_validate_ ##ot (&ot[idx], true); \ + CHECK_STATUS_SUCCESS(status); \ + sai_object_meta_key_t meta_key = { \ + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + .objectkey = { .key = { .ot = ot[idx] } } \ + }; \ + vmk.push_back(meta_key); \ + status = meta_generic_validation_create(meta_key, ot[idx].switch_id, attr_count[idx], attr_list[idx]); \ + CHECK_STATUS_SUCCESS(status); \ + } \ + auto status = m_implementation->bulkCreate(object_count, ot, attr_count, attr_list, mode, object_statuses); \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + if (object_statuses[idx] == SAI_STATUS_SUCCESS) \ + { \ + meta_generic_validation_post_create(vmk[idx], ot[idx].switch_id, attr_count[idx], attr_list[idx]); \ + } \ + } \ + return status; \ +} + +#define DECLARE_BULK_REMOVE_ENTRY(OT,ot) \ +sai_status_t Meta::bulkRemove( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t *ot, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + PARAMETER_CHECK_IF_NOT_NULL(object_statuses); \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; \ + } \ + PARAMETER_CHECK_POSITIVE(object_count); \ + PARAMETER_CHECK_IF_NOT_NULL(ot); \ + if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) \ + { \ + SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); \ + return SAI_STATUS_INVALID_PARAMETER; \ + } \ + std::vector vmk; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + sai_status_t status = meta_sai_validate_ ##ot (&ot[idx], false); \ + CHECK_STATUS_SUCCESS(status); \ + sai_object_meta_key_t meta_key = { \ + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + .objectkey = { .key = { .ot = ot[idx] } } \ + }; \ + vmk.push_back(meta_key); \ + status = meta_generic_validation_remove(meta_key); \ + CHECK_STATUS_SUCCESS(status); \ + } \ + auto status = m_implementation->bulkRemove(object_count, ot, mode, object_statuses); \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + if (object_statuses[idx] == SAI_STATUS_SUCCESS) \ + { \ + meta_generic_validation_post_remove(vmk[idx]); \ + } \ + } \ + return status; \ +} + +#define DECLARE_BULK_SET_ENTRY(OT,ot) \ +sai_status_t Meta::bulkSet( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t *ot, \ + _In_ const sai_attribute_t *attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + PARAMETER_CHECK_IF_NOT_NULL(object_statuses); \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; \ + } \ + PARAMETER_CHECK_POSITIVE(object_count); \ + PARAMETER_CHECK_IF_NOT_NULL(ot); \ + PARAMETER_CHECK_IF_NOT_NULL(attr_list); \ + if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) \ + { \ + SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); \ + return SAI_STATUS_INVALID_PARAMETER; \ + } \ + std::vector vmk; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + sai_status_t status = meta_sai_validate_ ##ot (&ot[idx], false); \ + CHECK_STATUS_SUCCESS(status); \ + sai_object_meta_key_t meta_key = { \ + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + .objectkey = { .key = { .ot = ot[idx] } } \ + }; \ + vmk.push_back(meta_key); \ + status = meta_generic_validation_set(meta_key, &attr_list[idx]); \ + CHECK_STATUS_SUCCESS(status); \ + } \ + auto status = m_implementation->bulkSet(object_count, ot, attr_list, mode, object_statuses); \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + if (object_statuses[idx] == SAI_STATUS_SUCCESS) \ + { \ + meta_generic_validation_post_set(vmk[idx], &attr_list[idx]); \ + } \ + } \ + return status; \ +} + +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_CREATE_ENTRY); +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_REMOVE_ENTRY); +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_SET_ENTRY); -sai_status_t Meta::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) +sai_status_t Meta::objectTypeGetAvailability( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t objectType, + _In_ uint32_t attrCount, + _In_ const sai_attribute_t *attrList, + _Out_ uint64_t *count) { SWSS_LOG_ENTER(); - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(nat_entry); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_nat_entry(&nat_entry[idx], false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NAT_ENTRY, .objectkey = { .key = { .nat_entry = nat_entry[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_set(meta_key, &attr_list[idx]); - - CHECK_STATUS_SUCCESS(status); - } - - auto status = m_implementation->bulkSet(object_count, nat_entry, attr_list, mode, object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(vmk[idx], &attr_list[idx]); - } - } - - return status; -} - -sai_status_t Meta::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); + PARAMETER_CHECK_OID_OBJECT_TYPE(switchId, SAI_OBJECT_TYPE_SWITCH); + PARAMETER_CHECK_OID_EXISTS(switchId, SAI_OBJECT_TYPE_SWITCH); + PARAMETER_CHECK_OBJECT_TYPE_VALID(objectType); - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); + // When checking availability of a resource solely based on OBJECT_TYPE, attrCount is 0 - for (uint32_t idx = 0; idx < object_count; idx++) + if (attrCount) { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; + PARAMETER_CHECK_IF_NOT_NULL(attrList); } - //PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(my_sid_entry); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); + PARAMETER_CHECK_IF_NOT_NULL(count); - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); + auto info = sai_metadata_get_object_type_info(objectType); - return SAI_STATUS_INVALID_PARAMETER; - } + PARAMETER_CHECK_IF_NOT_NULL(info); - std::vector vmk; + std::set attrs; - for (uint32_t idx = 0; idx < object_count; idx++) + for (uint32_t idx = 0; idx < attrCount; idx++) { - sai_status_t status = meta_sai_validate_my_sid_entry(&my_sid_entry[idx], false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_MY_SID_ENTRY, .objectkey = { .key = { .my_sid_entry = my_sid_entry[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_set(meta_key, &attr_list[idx]); - - CHECK_STATUS_SUCCESS(status); - } + auto id = attrList[idx].id; - auto status = m_implementation->bulkSet(object_count, my_sid_entry, attr_list, mode, object_statuses); + auto mdp = sai_metadata_get_attr_metadata(objectType, id); - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) + if (mdp == nullptr) { - meta_generic_validation_post_set(vmk[idx], &attr_list[idx]); - } - } - - return status; -} - -sai_status_t Meta::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t *neighbor_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - //PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(neighbor_entry); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); - - return SAI_STATUS_INVALID_PARAMETER; - } - - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_neighbor_entry(&neighbor_entry[idx], false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, .objectkey = { .key = { .neighbor_entry = neighbor_entry[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_set(meta_key, &attr_list[idx]); - - CHECK_STATUS_SUCCESS(status); - } - - auto status = m_implementation->bulkSet(object_count, neighbor_entry, attr_list, mode, object_statuses); + SWSS_LOG_ERROR("can't find attribute %s:%d", + info->objecttypename, + attrList[idx].id); - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(vmk[idx], &attr_list[idx]); + return SAI_STATUS_INVALID_PARAMETER; } - } - - return status; -} - -sai_status_t Meta::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } + if (attrs.find(id) != attrs.end()) + { + SWSS_LOG_ERROR("attr %s already defined on list", mdp->attridname); - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(fdb_entry); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); + return SAI_STATUS_INVALID_PARAMETER; + } - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); + attrs.insert(id); - return SAI_STATUS_INVALID_PARAMETER; - } + if (!mdp->isresourcetype) + { + SWSS_LOG_ERROR("attr %s is not resource type", mdp->attridname); - std::vector vmk; + return SAI_STATUS_INVALID_PARAMETER; + } - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_fdb_entry(&fdb_entry[idx], false); + switch (mdp->attrvaluetype) + { + case SAI_ATTR_VALUE_TYPE_INT32: - CHECK_STATUS_SUCCESS(status); + if (mdp->isenum && !sai_metadata_is_allowed_enum_value(mdp, attrList[idx].value.s32)) + { + SWSS_LOG_ERROR("%s is enum, but value %d not found on allowed values list", + mdp->attridname, + attrList[idx].value.s32); - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_FDB_ENTRY, .objectkey = { .key = { .fdb_entry = fdb_entry[idx] } } }; + return SAI_STATUS_INVALID_PARAMETER; + } - vmk.push_back(meta_key); + break; - status = meta_generic_validation_set(meta_key, &attr_list[idx]); + default: - CHECK_STATUS_SUCCESS(status); + META_LOG_THROW(*mdp, "value type %s not supported yet, FIXME!", + sai_serialize_attr_value_type(mdp->attrvaluetype).c_str()); + } } - auto status = m_implementation->bulkSet(object_count, fdb_entry, attr_list, mode, object_statuses); + auto status = m_implementation->objectTypeGetAvailability(switchId, objectType, attrCount, attrList, count); - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(vmk[idx], &attr_list[idx]); - } - } + // no post validation required return status; } -sai_status_t Meta::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) +sai_status_t Meta::queryAttributeCapability( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t objectType, + _In_ sai_attr_id_t attrId, + _Out_ sai_attr_capability_t *capability) { SWSS_LOG_ENTER(); - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } + PARAMETER_CHECK_OID_OBJECT_TYPE(switchId, SAI_OBJECT_TYPE_SWITCH); + PARAMETER_CHECK_OID_EXISTS(switchId, SAI_OBJECT_TYPE_SWITCH); + PARAMETER_CHECK_OBJECT_TYPE_VALID(objectType); - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(inseg_entry); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); + auto mdp = sai_metadata_get_attr_metadata(objectType, attrId); - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_stats_mode_t, mode) == nullptr) + if (!mdp) { - SWSS_LOG_ERROR("mode vlaue %d is not in range on %s", mode, sai_metadata_enum_sai_stats_mode_t.name); + SWSS_LOG_ERROR("unable to find attribute: %s:%d", + sai_serialize_object_type(objectType).c_str(), + attrId); return SAI_STATUS_INVALID_PARAMETER; } - std::vector vmk; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_inseg_entry(&inseg_entry[idx], false); - - CHECK_STATUS_SUCCESS(status); - - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY, .objectkey = { .key = { .inseg_entry = inseg_entry[idx] } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_set(meta_key, &attr_list[idx]); - - CHECK_STATUS_SUCCESS(status); - } + PARAMETER_CHECK_IF_NOT_NULL(capability); - auto status = m_implementation->bulkSet(object_count, inseg_entry, attr_list, mode, object_statuses); + auto status = m_implementation->queryAttributeCapability(switchId, objectType, attrId, capability); - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_set(vmk[idx], &attr_list[idx]); - } - } + // no post validation required return status; } -sai_status_t Meta::bulkCreate( - _In_ sai_object_type_t object_type, +sai_status_t Meta::queryAattributeEnumValuesCapability( _In_ sai_object_id_t switchId, - _In_ uint32_t object_count, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_object_id_t *object_id, - _Out_ sai_status_t *object_statuses) + _In_ sai_object_type_t objectType, + _In_ sai_attr_id_t attrId, + _Inout_ sai_s32_list_t *enumValuesCapability) { SWSS_LOG_ENTER(); - // all objects must be same type and come from the same switch - // TODO check multiple switches - - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); - - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } - - PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); PARAMETER_CHECK_OID_OBJECT_TYPE(switchId, SAI_OBJECT_TYPE_SWITCH); - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(attr_count); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); + PARAMETER_CHECK_OID_EXISTS(switchId, SAI_OBJECT_TYPE_SWITCH); + PARAMETER_CHECK_OBJECT_TYPE_VALID(objectType); - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (attr_list[idx] == nullptr) - { - SWSS_LOG_ERROR("pointer to attribute list at index %u is NULL", idx); + auto mdp = sai_metadata_get_attr_metadata(objectType, attrId); - return SAI_STATUS_INVALID_PARAMETER; - } + if (!mdp) + { + SWSS_LOG_ERROR("unable to find attribute: %s:%d", + sai_serialize_object_type(objectType).c_str(), + attrId); - if (object_type == SAI_OBJECT_TYPE_SWITCH) - { - SWSS_LOG_THROW("create bulk switch not supported"); - } + return SAI_STATUS_INVALID_PARAMETER; } - PARAMETER_CHECK_IF_NOT_NULL(object_id); - - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) + if (!mdp->isenum && !mdp->isenumlist) { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); + SWSS_LOG_ERROR("%s is not enum/enum list", mdp->attridname); return SAI_STATUS_INVALID_PARAMETER; } - std::vector vmk; + PARAMETER_CHECK_IF_NOT_NULL(enumValuesCapability); - for (uint32_t idx = 0; idx < object_count; idx++) + if (meta_genetic_validation_list(*mdp, enumValuesCapability->count, enumValuesCapability->list) + != SAI_STATUS_SUCCESS) { - sai_status_t status = meta_sai_validate_oid(object_type, &object_id[idx], switchId, true); - - CHECK_STATUS_SUCCESS(status); - - // this is create, oid's don't exist yet - - sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = SAI_NULL_OBJECT_ID } } }; - - vmk.push_back(meta_key); - - status = meta_generic_validation_create(meta_key, switchId, attr_count[idx], attr_list[idx]); - - CHECK_STATUS_SUCCESS(status); + return SAI_STATUS_INVALID_PARAMETER; } - auto status = m_implementation->bulkCreate(object_type, switchId, object_count, attr_count, attr_list, mode, object_id, object_statuses); + auto status = m_implementation->queryAattributeEnumValuesCapability(switchId, objectType, attrId, enumValuesCapability); - for (uint32_t idx = 0; idx < object_count; idx++) + if (status == SAI_STATUS_SUCCESS) { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) + if (enumValuesCapability->list) { - vmk[idx].objectkey.key.object_id = object_id[idx]; // assign new created object id + // check if all returned values are members of defined enum - meta_generic_validation_post_create(vmk[idx], switchId, attr_count[idx], attr_list[idx]); + for (uint32_t idx = 0; idx < enumValuesCapability->count; idx++) + { + int val = enumValuesCapability->list[idx]; + + if (!sai_metadata_is_allowed_enum_value(mdp, val)) + { + SWSS_LOG_ERROR("returned value %d is not allowed on %s", val, mdp->attridname); + } + } } } return status; } -sai_status_t Meta::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) +#define META_COUNTERS_COUNT_MSB (0x80000000) + +sai_status_t Meta::meta_validate_stats( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _Out_ uint64_t *counters, + _In_ sai_stats_mode_t mode) { SWSS_LOG_ENTER(); - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); + /* + * If last bit of counters count is set to high, and unittests are enabled, + * then this api can be used to SET counter values by user for debugging purposes. + */ - for (uint32_t idx = 0; idx < object_count; idx++) + if (m_unittestsEnabled) { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; + number_of_counters &= ~(META_COUNTERS_COUNT_MSB); } - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(route_entry); - PARAMETER_CHECK_IF_NOT_NULL(attr_count); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); + PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); + PARAMETER_CHECK_OID_OBJECT_TYPE(object_id, object_type); + PARAMETER_CHECK_OID_EXISTS(object_id, object_type); + PARAMETER_CHECK_POSITIVE(number_of_counters); + PARAMETER_CHECK_IF_NOT_NULL(counter_ids); + PARAMETER_CHECK_IF_NOT_NULL(counters); - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); + sai_object_id_t switch_id = switchIdQuery(object_id); - return SAI_STATUS_INVALID_PARAMETER; - } + // checks also if object type is OID + sai_status_t status = meta_sai_validate_oid(object_type, &object_id, switch_id, false); - std::vector vmk; + CHECK_STATUS_SUCCESS(status); - // TODO handle case when two 2 identical routes are created - it will throw, should return fail + auto info = sai_metadata_get_object_type_info(object_type); - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_route_entry(&route_entry[idx], true); + PARAMETER_CHECK_IF_NOT_NULL(info); - CHECK_STATUS_SUCCESS(status); + if (info->statenum == nullptr) + { + SWSS_LOG_ERROR("%s does not support stats", info->objecttypename); - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY, .objectkey = { .key = { .route_entry = route_entry[idx] } } }; + return SAI_STATUS_INVALID_PARAMETER; + } - vmk.push_back(meta_key); + // check if all counter ids are in enum range - status = meta_generic_validation_create(meta_key, route_entry[idx].switch_id, attr_count[idx], attr_list[idx]); + for (uint32_t idx = 0; idx < number_of_counters; idx++) + { + if (sai_metadata_get_enum_value_name(info->statenum, counter_ids[idx]) == nullptr) + { + SWSS_LOG_ERROR("value %d is not in range on %s", counter_ids[idx], info->statenum->name); - CHECK_STATUS_SUCCESS(status); + return SAI_STATUS_INVALID_PARAMETER; + } } - auto status = m_implementation->bulkCreate(object_count, route_entry, attr_count, attr_list, mode, object_statuses); + // check mode - for (uint32_t idx = 0; idx < object_count; idx++) + if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_stats_mode_t, mode) == nullptr) { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(vmk[idx], route_entry[idx].switch_id, attr_count[idx], attr_list[idx]); - } + SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_stats_mode_t.name); + + return SAI_STATUS_INVALID_PARAMETER; } - return status; + return SAI_STATUS_SUCCESS; } -sai_status_t Meta::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) +sai_status_t Meta::meta_validate_query_stats_capability( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id) { SWSS_LOG_ENTER(); - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); + PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); + PARAMETER_CHECK_OID_OBJECT_TYPE(object_id, object_type); + PARAMETER_CHECK_OID_EXISTS(object_id, object_type); + + sai_object_id_t switch_id = switchIdQuery(object_id); + + // checks also if object type is OID + sai_status_t status = meta_sai_validate_oid(object_type, &object_id, switch_id, false); + + CHECK_STATUS_SUCCESS(status); - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } + auto info = sai_metadata_get_object_type_info(object_type); - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(fdb_entry); - PARAMETER_CHECK_IF_NOT_NULL(attr_count); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); + PARAMETER_CHECK_IF_NOT_NULL(info); - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) + if (info->statenum == nullptr) { - SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); + SWSS_LOG_ERROR("%s does not support stats", info->objecttypename); return SAI_STATUS_INVALID_PARAMETER; } - std::vector vmk; + return SAI_STATUS_SUCCESS; +} - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_fdb_entry(&fdb_entry[idx], true); +sai_status_t Meta::getStats( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _Out_ uint64_t *counters) +{ + SWSS_LOG_ENTER(); - CHECK_STATUS_SUCCESS(status); + auto status = meta_validate_stats(object_type, object_id, number_of_counters, counter_ids, counters, SAI_STATS_MODE_READ); + + CHECK_STATUS_SUCCESS(status); - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_FDB_ENTRY, .objectkey = { .key = { .fdb_entry = fdb_entry[idx] } } }; + status = m_implementation->getStats(object_type, object_id, number_of_counters, counter_ids, counters); - vmk.push_back(meta_key); + // no post validation required - status = meta_generic_validation_create(meta_key, fdb_entry[idx].switch_id, attr_count[idx], attr_list[idx]); + return status; +} - CHECK_STATUS_SUCCESS(status); - } +sai_status_t Meta::queryStatsCapability( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t objectType, + _Inout_ sai_stat_capability_list_t *stats_capability) +{ + SWSS_LOG_ENTER(); - auto status = m_implementation->bulkCreate(object_count, fdb_entry, attr_count, attr_list, mode, object_statuses); + auto status = meta_validate_query_stats_capability(objectType, switchId); - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(vmk[idx], fdb_entry[idx].switch_id, attr_count[idx], attr_list[idx]); - } - } + CHECK_STATUS_SUCCESS(status); + + status = m_implementation->queryStatsCapability(switchId, objectType, stats_capability); + + // no post validation required return status; } -sai_status_t Meta::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) +sai_status_t Meta::getStatsExt( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _In_ sai_stats_mode_t mode, + _Out_ uint64_t *counters) { SWSS_LOG_ENTER(); - PARAMETER_CHECK_IF_NOT_NULL(object_statuses); + auto status = meta_validate_stats(object_type, object_id, number_of_counters, counter_ids, counters, mode); - for (uint32_t idx = 0; idx < object_count; idx++) - { - object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; - } + CHECK_STATUS_SUCCESS(status); - PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(inseg_entry); - PARAMETER_CHECK_IF_NOT_NULL(attr_count); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); + status = m_implementation->getStatsExt(object_type, object_id, number_of_counters, counter_ids, mode, counters); - if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_stats_mode_t, mode) == nullptr) - { - SWSS_LOG_ERROR("mode vlaue %d is not in range on %s", mode, sai_metadata_enum_sai_stats_mode_t.name); + // no post validation required - return SAI_STATUS_INVALID_PARAMETER; - } + return status; +} - std::vector vmk; +sai_status_t Meta::clearStats( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t object_id, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids) +{ + SWSS_LOG_ENTER(); - for (uint32_t idx = 0; idx < object_count; idx++) - { - sai_status_t status = meta_sai_validate_inseg_entry(&inseg_entry[idx], true); + uint64_t counters; + auto status = meta_validate_stats(object_type, object_id, number_of_counters, counter_ids, &counters, SAI_STATS_MODE_READ); - CHECK_STATUS_SUCCESS(status); + CHECK_STATUS_SUCCESS(status); - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY, .objectkey = { .key = { .inseg_entry = inseg_entry[idx] } } }; + status = m_implementation->clearStats(object_type, object_id, number_of_counters, counter_ids); - vmk.push_back(meta_key); + // no post validation required - status = meta_generic_validation_create(meta_key, inseg_entry[idx].switch_id, attr_count[idx], attr_list[idx]); + return status; +} - CHECK_STATUS_SUCCESS(status); - } +sai_status_t Meta::bulkGetStats( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t object_type, + _In_ uint32_t object_count, + _In_ const sai_object_key_t *object_key, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _In_ sai_stats_mode_t mode, + _Inout_ sai_status_t *object_statuses, + _Out_ uint64_t *counters) +{ + SWSS_LOG_ENTER(); - auto status = m_implementation->bulkCreate(object_count, inseg_entry, attr_count, attr_list, mode, object_statuses); + return SAI_STATUS_NOT_IMPLEMENTED; +} - for (uint32_t idx = 0; idx < object_count; idx++) - { - if (object_statuses[idx] == SAI_STATUS_SUCCESS) - { - meta_generic_validation_post_create(vmk[idx], inseg_entry[idx].switch_id, attr_count[idx], attr_list[idx]); - } - } +sai_status_t Meta::bulkClearStats( + _In_ sai_object_id_t switchId, + _In_ sai_object_type_t object_type, + _In_ uint32_t object_count, + _In_ const sai_object_key_t *object_key, + _In_ uint32_t number_of_counters, + _In_ const sai_stat_id_t *counter_ids, + _In_ sai_stats_mode_t mode, + _Inout_ sai_status_t *object_statuses) +{ + SWSS_LOG_ENTER(); - return status; + return SAI_STATUS_NOT_IMPLEMENTED; } -sai_status_t Meta::bulkCreate( +// for bulk operations actually we could make copy of current db and actually +// execute to see if all will succeed + +sai_status_t Meta::bulkRemove( + _In_ sai_object_type_t object_type, _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, + _In_ const sai_object_id_t *object_id, _In_ sai_bulk_op_error_mode_t mode, _Out_ sai_status_t *object_statuses) { SWSS_LOG_ENTER(); + // all objects must be same type and come from the same switch + // TODO check multiple switches + PARAMETER_CHECK_IF_NOT_NULL(object_statuses); for (uint32_t idx = 0; idx < object_count; idx++) @@ -2982,10 +1142,9 @@ sai_status_t Meta::bulkCreate( object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; } + PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(nat_entry); - PARAMETER_CHECK_IF_NOT_NULL(attr_count); - PARAMETER_CHECK_IF_NOT_NULL(attr_list); + PARAMETER_CHECK_IF_NOT_NULL(object_id); if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) { @@ -2998,42 +1157,45 @@ sai_status_t Meta::bulkCreate( for (uint32_t idx = 0; idx < object_count; idx++) { - sai_status_t status = meta_sai_validate_nat_entry(&nat_entry[idx], true); + sai_status_t status = meta_sai_validate_oid(object_type, &object_id[idx], SAI_NULL_OBJECT_ID, false); CHECK_STATUS_SUCCESS(status); - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NAT_ENTRY, .objectkey = { .key = { .nat_entry = nat_entry[idx] } } }; + sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = object_id[idx] } } }; vmk.push_back(meta_key); - status = meta_generic_validation_create(meta_key, nat_entry[idx].switch_id, attr_count[idx], attr_list[idx]); + status = meta_generic_validation_remove(meta_key); CHECK_STATUS_SUCCESS(status); } - auto status = m_implementation->bulkCreate(object_count, nat_entry, attr_count, attr_list, mode, object_statuses); + auto status = m_implementation->bulkRemove(object_type, object_count, object_id, mode, object_statuses); for (uint32_t idx = 0; idx < object_count; idx++) { if (object_statuses[idx] == SAI_STATUS_SUCCESS) { - meta_generic_validation_post_create(vmk[idx], nat_entry[idx].switch_id, attr_count[idx], attr_list[idx]); + meta_generic_validation_post_remove(vmk[idx]); } } return status; } -sai_status_t Meta::bulkCreate( +sai_status_t Meta::bulkSet( + _In_ sai_object_type_t object_type, _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, + _In_ const sai_object_id_t *object_id, + _In_ const sai_attribute_t *attr_list, _In_ sai_bulk_op_error_mode_t mode, _Out_ sai_status_t *object_statuses) { SWSS_LOG_ENTER(); + // all objects must be same type and come from the same switch + // TODO check multiple switches + PARAMETER_CHECK_IF_NOT_NULL(object_statuses); for (uint32_t idx = 0; idx < object_count; idx++) @@ -3041,10 +1203,9 @@ sai_status_t Meta::bulkCreate( object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; } - //PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); + PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(my_sid_entry); - PARAMETER_CHECK_IF_NOT_NULL(attr_count); + PARAMETER_CHECK_IF_NOT_NULL(object_id); PARAMETER_CHECK_IF_NOT_NULL(attr_list); if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) @@ -3058,26 +1219,26 @@ sai_status_t Meta::bulkCreate( for (uint32_t idx = 0; idx < object_count; idx++) { - sai_status_t status = meta_sai_validate_my_sid_entry(&my_sid_entry[idx], true); + sai_status_t status = meta_sai_validate_oid(object_type, &object_id[idx], SAI_NULL_OBJECT_ID, false); CHECK_STATUS_SUCCESS(status); - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_MY_SID_ENTRY, .objectkey = { .key = { .my_sid_entry = my_sid_entry[idx] } } }; + sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = object_id[idx] } } }; vmk.push_back(meta_key); - status = meta_generic_validation_create(meta_key, my_sid_entry[idx].switch_id, attr_count[idx], attr_list[idx]); + status = meta_generic_validation_set(meta_key, &attr_list[idx]); CHECK_STATUS_SUCCESS(status); } - auto status = m_implementation->bulkCreate(object_count, my_sid_entry, attr_count, attr_list, mode, object_statuses); + auto status = m_implementation->bulkSet(object_type, object_count, object_id, attr_list, mode, object_statuses); for (uint32_t idx = 0; idx < object_count; idx++) { if (object_statuses[idx] == SAI_STATUS_SUCCESS) { - meta_generic_validation_post_create(vmk[idx], my_sid_entry[idx].switch_id, attr_count[idx], attr_list[idx]); + meta_generic_validation_post_set(vmk[idx], &attr_list[idx]); } } @@ -3085,15 +1246,20 @@ sai_status_t Meta::bulkCreate( } sai_status_t Meta::bulkCreate( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t switchId, _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t *neighbor_entry, _In_ const uint32_t *attr_count, _In_ const sai_attribute_t **attr_list, _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_object_id_t *object_id, _Out_ sai_status_t *object_statuses) { SWSS_LOG_ENTER(); + // all objects must be same type and come from the same switch + // TODO check multiple switches + PARAMETER_CHECK_IF_NOT_NULL(object_statuses); for (uint32_t idx = 0; idx < object_count; idx++) @@ -3101,12 +1267,29 @@ sai_status_t Meta::bulkCreate( object_statuses[idx] = SAI_STATUS_NOT_EXECUTED; } - //PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); + PARAMETER_CHECK_OBJECT_TYPE_VALID(object_type); + PARAMETER_CHECK_OID_OBJECT_TYPE(switchId, SAI_OBJECT_TYPE_SWITCH); PARAMETER_CHECK_POSITIVE(object_count); - PARAMETER_CHECK_IF_NOT_NULL(neighbor_entry); PARAMETER_CHECK_IF_NOT_NULL(attr_count); PARAMETER_CHECK_IF_NOT_NULL(attr_list); + for (uint32_t idx = 0; idx < object_count; idx++) + { + if (attr_list[idx] == nullptr) + { + SWSS_LOG_ERROR("pointer to attribute list at index %u is NULL", idx); + + return SAI_STATUS_INVALID_PARAMETER; + } + + if (object_type == SAI_OBJECT_TYPE_SWITCH) + { + SWSS_LOG_THROW("create bulk switch not supported"); + } + } + + PARAMETER_CHECK_IF_NOT_NULL(object_id); + if (sai_metadata_get_enum_value_name(&sai_metadata_enum_sai_bulk_op_error_mode_t, mode) == nullptr) { SWSS_LOG_ERROR("mode value %d is not in range on %s", mode, sai_metadata_enum_sai_bulk_op_error_mode_t.name); @@ -3118,26 +1301,30 @@ sai_status_t Meta::bulkCreate( for (uint32_t idx = 0; idx < object_count; idx++) { - sai_status_t status = meta_sai_validate_neighbor_entry(&neighbor_entry[idx], true); + sai_status_t status = meta_sai_validate_oid(object_type, &object_id[idx], switchId, true); CHECK_STATUS_SUCCESS(status); - sai_object_meta_key_t meta_key = { .objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, .objectkey = { .key = { .neighbor_entry = neighbor_entry[idx] } } }; + // this is create, oid's don't exist yet + + sai_object_meta_key_t meta_key = { .objecttype = object_type, .objectkey = { .key = { .object_id = SAI_NULL_OBJECT_ID } } }; vmk.push_back(meta_key); - status = meta_generic_validation_create(meta_key, neighbor_entry[idx].switch_id, attr_count[idx], attr_list[idx]); + status = meta_generic_validation_create(meta_key, switchId, attr_count[idx], attr_list[idx]); CHECK_STATUS_SUCCESS(status); } - auto status = m_implementation->bulkCreate(object_count, neighbor_entry, attr_count, attr_list, mode, object_statuses); + auto status = m_implementation->bulkCreate(object_type, switchId, object_count, attr_count, attr_list, mode, object_id, object_statuses); for (uint32_t idx = 0; idx < object_count; idx++) { if (object_statuses[idx] == SAI_STATUS_SUCCESS) { - meta_generic_validation_post_create(vmk[idx], neighbor_entry[idx].switch_id, attr_count[idx], attr_list[idx]); + vmk[idx].objectkey.key.object_id = object_id[idx]; // assign new created object id + + meta_generic_validation_post_create(vmk[idx], switchId, attr_count[idx], attr_list[idx]); } } @@ -3680,6 +1867,7 @@ void Meta::meta_generic_validation_post_remove( case SAI_ATTR_VALUE_TYPE_INT32_RANGE: case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST: case SAI_ATTR_VALUE_TYPE_SEGMENT_LIST: + case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST: case SAI_ATTR_VALUE_TYPE_JSON: // no special action required break; @@ -3920,7 +2108,8 @@ sai_status_t Meta::meta_sai_validate_mcast_fdb_entry( sai_status_t Meta::meta_sai_validate_neighbor_entry( _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ bool create) + _In_ bool create, + _In_ bool get) { SWSS_LOG_ENTER(); @@ -4015,7 +2204,8 @@ sai_status_t Meta::meta_sai_validate_neighbor_entry( sai_status_t Meta::meta_sai_validate_route_entry( _In_ const sai_route_entry_t* route_entry, - _In_ bool create) + _In_ bool create, + _In_ bool get) { SWSS_LOG_ENTER(); @@ -4122,7 +2312,8 @@ sai_status_t Meta::meta_sai_validate_route_entry( sai_status_t Meta::meta_sai_validate_l2mc_entry( _In_ const sai_l2mc_entry_t* l2mc_entry, - _In_ bool create) + _In_ bool create, + _In_ bool get) { SWSS_LOG_ENTER(); @@ -4245,7 +2436,8 @@ sai_status_t Meta::meta_sai_validate_l2mc_entry( sai_status_t Meta::meta_sai_validate_ipmc_entry( _In_ const sai_ipmc_entry_t* ipmc_entry, - _In_ bool create) + _In_ bool create, + _In_ bool get) { SWSS_LOG_ENTER(); @@ -4368,7 +2560,8 @@ sai_status_t Meta::meta_sai_validate_ipmc_entry( sai_status_t Meta::meta_sai_validate_nat_entry( _In_ const sai_nat_entry_t* nat_entry, - _In_ bool create) + _In_ bool create, + _In_ bool get) { SWSS_LOG_ENTER(); @@ -4449,7 +2642,8 @@ sai_status_t Meta::meta_sai_validate_nat_entry( sai_status_t Meta::meta_sai_validate_inseg_entry( _In_ const sai_inseg_entry_t* inseg_entry, - _In_ bool create) + _In_ bool create, + _In_ bool get) { SWSS_LOG_ENTER(); @@ -4467,7 +2661,8 @@ sai_status_t Meta::meta_sai_validate_inseg_entry( sai_status_t Meta::meta_sai_validate_my_sid_entry( _In_ const sai_my_sid_entry_t* my_sid_entry, - _In_ bool create) + _In_ bool create, + _In_ bool get) { SWSS_LOG_ENTER(); @@ -4929,6 +3124,17 @@ sai_status_t Meta::meta_generic_validation_create( VALIDATION_LIST(md, value.segmentlist); break; + case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST: + VALIDATION_LIST(md, value.u16rangelist); + for (uint32_t i = 0; i < value.u16rangelist.count; i++) { + if (value.u16rangelist.list[i].min > value.u16rangelist.list[i].max) + { + META_LOG_ERROR(md, "invalid range %u .. %u", value.u16rangelist.list[i].min, value.u16rangelist.list[i].max); + return SAI_STATUS_INVALID_PARAMETER; + } + } + break; + case SAI_ATTR_VALUE_TYPE_JSON: VALIDATION_LIST(md, value.json.json); break; @@ -5586,6 +3792,17 @@ sai_status_t Meta::meta_generic_validation_set( VALIDATION_LIST(md, value.segmentlist); break; + case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST: + VALIDATION_LIST(md, value.u16rangelist); + for (uint32_t i = 0; i < value.u16rangelist.count; i++) { + if (value.u16rangelist.list[i].min > value.u16rangelist.list[i].max) + { + META_LOG_ERROR(md, "invalid range %u .. %u", value.u16rangelist.list[i].min, value.u16rangelist.list[i].max); + return SAI_STATUS_INVALID_PARAMETER; + } + } + break; + case SAI_ATTR_VALUE_TYPE_JSON: VALIDATION_LIST(md, value.json.json); break; @@ -6001,6 +4218,10 @@ sai_status_t Meta::meta_generic_validation_get( VALIDATION_LIST(md, value.segmentlist); break; + case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST: + VALIDATION_LIST(md, value.u16rangelist); + break; + case SAI_ATTR_VALUE_TYPE_JSON: VALIDATION_LIST(md, value.json.json); break; @@ -6251,6 +4472,16 @@ void Meta::meta_generic_validation_post_get( VALIDATION_LIST_GET(md, value.segmentlist); break; + case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST: + VALIDATION_LIST_GET(md, value.u16rangelist); + for (uint32_t i = 0; i < value.u16rangelist.count; i++) { + if (value.u16rangelist.list[i].min > value.u16rangelist.list[i].max) + { + META_LOG_ERROR(md, "invalid range %u .. %u", value.u16rangelist.list[i].min, value.u16rangelist.list[i].max); + } + } + break; + case SAI_ATTR_VALUE_TYPE_JSON: VALIDATION_LIST_GET(md, value.json.json); break; @@ -7153,6 +5384,7 @@ void Meta::meta_generic_validation_post_create( case SAI_ATTR_VALUE_TYPE_INT32_RANGE: case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST: case SAI_ATTR_VALUE_TYPE_SEGMENT_LIST: + case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST: case SAI_ATTR_VALUE_TYPE_JSON: // no special action required break; @@ -7394,6 +5626,7 @@ void Meta::meta_generic_validation_post_set( case SAI_ATTR_VALUE_TYPE_ACL_RESOURCE_LIST: case SAI_ATTR_VALUE_TYPE_ACL_CAPABILITY: case SAI_ATTR_VALUE_TYPE_SEGMENT_LIST: + case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST: case SAI_ATTR_VALUE_TYPE_JSON: // no special action required break; diff --git a/meta/Meta.h b/meta/Meta.h index dc66946f8..21131b5f4 100644 --- a/meta/Meta.h +++ b/meta/Meta.h @@ -453,31 +453,38 @@ namespace saimeta sai_status_t meta_sai_validate_neighbor_entry( _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ bool create); + _In_ bool create, + _In_ bool get = false); sai_status_t meta_sai_validate_route_entry( _In_ const sai_route_entry_t* route_entry, - _In_ bool create); + _In_ bool create, + _In_ bool get = false); sai_status_t meta_sai_validate_l2mc_entry( _In_ const sai_l2mc_entry_t* l2mc_entry, - _In_ bool create); + _In_ bool create, + _In_ bool get = false); sai_status_t meta_sai_validate_ipmc_entry( _In_ const sai_ipmc_entry_t* ipmc_entry, - _In_ bool create); + _In_ bool create, + _In_ bool get = false); sai_status_t meta_sai_validate_nat_entry( _In_ const sai_nat_entry_t* nat_entry, - _In_ bool create); + _In_ bool create, + _In_ bool get = false); sai_status_t meta_sai_validate_inseg_entry( _In_ const sai_inseg_entry_t* inseg_entry, - _In_ bool create); + _In_ bool create, + _In_ bool get = false); sai_status_t meta_sai_validate_my_sid_entry( _In_ const sai_my_sid_entry_t* my_sid_entry, - _In_ bool create); + _In_ bool create, + _In_ bool get = false); public: diff --git a/unittest/lib/TestClientServerSai.cpp b/unittest/lib/TestClientServerSai.cpp index 5ced528f2..52dac2499 100644 --- a/unittest/lib/TestClientServerSai.cpp +++ b/unittest/lib/TestClientServerSai.cpp @@ -172,18 +172,42 @@ TEST(ClientServerSai, bulkGetClearStats) nullptr)); } -TEST(ClientServerSai, bulk_neighbor_op) -{ - auto css = std::make_shared(); - sai_neighbor_entry_t e[2]; - EXPECT_EQ(SAI_STATUS_SUCCESS, css->initialize(0, &test_services)); - EXPECT_EQ(SAI_STATUS_INVALID_PARAMETER, css->bulkCreate(0, e, nullptr, nullptr, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); - EXPECT_EQ(SAI_STATUS_INVALID_PARAMETER, css->bulkSet(2, e, nullptr, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); - EXPECT_EQ(SAI_STATUS_INVALID_PARAMETER, css->bulkRemove(2, e, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); - css = std::make_shared(); - EXPECT_EQ(SAI_STATUS_SUCCESS, css->initialize(0, &test_client_services)); - EXPECT_EQ(SAI_STATUS_NOT_IMPLEMENTED, css->bulkCreate(0, e, nullptr, nullptr, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); - EXPECT_EQ(SAI_STATUS_NOT_IMPLEMENTED, css->bulkSet(2, e, nullptr, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); - EXPECT_EQ(SAI_STATUS_NOT_IMPLEMENTED, css->bulkRemove(2, e, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); +#define TEST_ENTRY(OT,ot) \ +TEST(ClientServerSai, OT) \ +{ \ + auto css = std::make_shared(); \ + sai_ ## ot ## _t e; \ + EXPECT_EQ(SAI_STATUS_SUCCESS, css->initialize(0, &test_services)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, css->create(&e, 0, nullptr)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, css->set(&e, nullptr)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, css->get(&e, 0, nullptr)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, css->remove(&e)); \ + \ + auto ss = std::make_shared(); \ + EXPECT_EQ(SAI_STATUS_SUCCESS, ss->initialize(0, &test_services)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, ss->create(&e, 0, nullptr)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, ss->set(&e, nullptr)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, ss->get(&e, 0, nullptr)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, ss->remove(&e)); \ +} +SAIREDIS_DECLARE_EVERY_ENTRY(TEST_ENTRY) + +#define TEST_BULK_ENTRY(OT,ot) \ +TEST(ClientServerSai, bulk_ ## OT) \ +{ \ + auto css = std::make_shared(); \ + sai_ ## ot ## _t e[2]; \ + EXPECT_EQ(SAI_STATUS_SUCCESS, css->initialize(0, &test_services)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, css->bulkCreate(0, e, nullptr, nullptr, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, css->bulkSet(2, e, nullptr, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, css->bulkRemove(2, e, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); \ + \ + auto ss = std::make_shared(); \ + EXPECT_EQ(SAI_STATUS_SUCCESS, ss->initialize(0, &test_client_services)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, ss->bulkCreate(0, e, nullptr, nullptr, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, ss->bulkSet(0, e, nullptr, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); \ + EXPECT_NE(SAI_STATUS_SUCCESS, ss->bulkRemove(0, e, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); \ } + +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(TEST_BULK_ENTRY) diff --git a/vslib/VirtualSwitchSaiInterface.cpp b/vslib/VirtualSwitchSaiInterface.cpp index d604e3544..1ac32accf 100644 --- a/vslib/VirtualSwitchSaiInterface.cpp +++ b/vslib/VirtualSwitchSaiInterface.cpp @@ -412,7 +412,7 @@ sai_status_t VirtualSwitchSaiInterface::remove( \ SWSS_LOG_ENTER(); \ return remove( \ entry->switch_id, \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*entry)); \ } @@ -430,7 +430,7 @@ sai_status_t VirtualSwitchSaiInterface::create( \ timer.start(); \ auto status = create( \ entry->switch_id, \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*entry), \ attr_count, \ attr_list); \ @@ -449,13 +449,89 @@ sai_status_t VirtualSwitchSaiInterface::set( \ SWSS_LOG_ENTER(); \ return set( \ entry->switch_id, \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*entry), \ attr); \ } SAIREDIS_DECLARE_EVERY_ENTRY(DECLARE_SET_ENTRY); +#define DECLARE_BULK_CREATE_ENTRY(OT,ot) \ +sai_status_t VirtualSwitchSaiInterface::bulkCreate( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t* ot, \ + _In_ const uint32_t *attr_count, \ + _In_ const sai_attribute_t **attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + std::vector serialized_object_ids; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + std::string str_object_id = sai_serialize_ ##ot (ot[idx]); \ + serialized_object_ids.push_back(str_object_id); \ + } \ + return bulkCreate( \ + ot->switch_id, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + serialized_object_ids, \ + attr_count, \ + attr_list, \ + mode, \ + object_statuses); \ +} + +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_CREATE_ENTRY); + +#define DECLARE_BULK_REMOVE_ENTRY(OT,ot) \ +sai_status_t VirtualSwitchSaiInterface::bulkRemove( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t* ot, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + std::vector serializedObjectIds; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + serializedObjectIds.emplace_back(sai_serialize_ ##ot (ot[idx])); \ + } \ + return bulkRemove( \ + ot->switch_id, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + serializedObjectIds, \ + mode, \ + object_statuses); \ +} + +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_REMOVE_ENTRY); + +#define DECLARE_BULK_SET_ENTRY(OT,ot) \ +sai_status_t VirtualSwitchSaiInterface::bulkSet( \ + _In_ uint32_t object_count, \ + _In_ const sai_ ## ot ## _t* ot, \ + _In_ const sai_attribute_t *attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + std::vector serializedObjectIds; \ + for (uint32_t idx = 0; idx < object_count; idx++) \ + { \ + serializedObjectIds.emplace_back(sai_serialize_ ##ot (ot[idx])); \ + } \ + return bulkSet( \ + ot->switch_id, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + serializedObjectIds, \ + attr_list, \ + mode, \ + object_statuses); \ +} + +SAIREDIS_DECLARE_EVERY_BULK_ENTRY(DECLARE_BULK_SET_ENTRY); + std::shared_ptr VirtualSwitchSaiInterface::init_switch( _In_ sai_object_id_t switch_id, _In_ std::shared_ptr config, @@ -715,7 +791,7 @@ sai_status_t VirtualSwitchSaiInterface::get( \ SWSS_LOG_ENTER(); \ return get( \ entry->switch_id, \ - SAI_OBJECT_TYPE_ ## OT, \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ sai_serialize_ ## ot(*entry), \ attr_count, \ attr_list); \ @@ -1027,114 +1103,6 @@ sai_status_t VirtualSwitchSaiInterface::bulkRemove( return bulkRemove(switchId, object_type, serializedObjectIds, mode, object_statuses); } -sai_status_t VirtualSwitchSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_route_entry(route_entry[idx])); - } - - return bulkRemove(route_entry->switch_id, SAI_OBJECT_TYPE_ROUTE_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_my_sid_entry(my_sid_entry[idx])); - } - - return bulkRemove(my_sid_entry->switch_id, SAI_OBJECT_TYPE_MY_SID_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t *neighbor_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_neighbor_entry(neighbor_entry[idx])); - } - - return bulkRemove(neighbor_entry->switch_id, SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_nat_entry(nat_entry[idx])); - } - - return bulkRemove(nat_entry->switch_id, SAI_OBJECT_TYPE_NAT_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_inseg_entry(inseg_entry[idx])); - } - - return bulkRemove(inseg_entry->switch_id, SAI_OBJECT_TYPE_INSEG_ENTRY, serializedObjectIds, mode, object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkRemove( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_fdb_entry(fdb_entry[idx])); - } - - return bulkRemove(fdb_entry->switch_id, SAI_OBJECT_TYPE_FDB_ENTRY, serializedObjectIds, mode, object_statuses); -} - sai_status_t VirtualSwitchSaiInterface::bulkSet( _In_ sai_object_type_t object_type, _In_ uint32_t object_count, @@ -1157,120 +1125,6 @@ sai_status_t VirtualSwitchSaiInterface::bulkSet( return bulkSet(switchId, object_type, serializedObjectIds, attr_list, mode, object_statuses); } -sai_status_t VirtualSwitchSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t *route_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_route_entry(route_entry[idx])); - } - - return bulkSet(route_entry->switch_id, SAI_OBJECT_TYPE_ROUTE_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t *my_sid_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_my_sid_entry(my_sid_entry[idx])); - } - - return bulkSet(my_sid_entry->switch_id, SAI_OBJECT_TYPE_MY_SID_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t *neighbor_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_neighbor_entry(neighbor_entry[idx])); - } - - return bulkSet(neighbor_entry->switch_id, SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t *nat_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_nat_entry(nat_entry[idx])); - } - - return bulkSet(nat_entry->switch_id, SAI_OBJECT_TYPE_NAT_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t *inseg_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_inseg_entry(inseg_entry[idx])); - } - - return bulkSet(inseg_entry->switch_id, SAI_OBJECT_TYPE_INSEG_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkSet( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t *fdb_entry, - _In_ const sai_attribute_t *attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serializedObjectIds; - - for (uint32_t idx = 0; idx < object_count; idx++) - { - serializedObjectIds.emplace_back(sai_serialize_fdb_entry(fdb_entry[idx])); - } - - return bulkSet(fdb_entry->switch_id, SAI_OBJECT_TYPE_FDB_ENTRY, serializedObjectIds, attr_list, mode, object_statuses); -} - sai_status_t VirtualSwitchSaiInterface::bulkSet( _In_ sai_object_id_t switchId, _In_ sai_object_type_t object_type, @@ -1309,6 +1163,7 @@ sai_status_t VirtualSwitchSaiInterface::bulkCreate( // on create vid is put in db by syncd for (uint32_t idx = 0; idx < object_count; idx++) { + object_id[idx] = m_realObjectIdManager->allocateNewObjectId(object_type, switch_id); std::string str_object_id = sai_serialize_object_id(object_id[idx]); serialized_object_ids.push_back(str_object_id); } @@ -1339,180 +1194,6 @@ sai_status_t VirtualSwitchSaiInterface::bulkCreate( return ss->bulkCreate(switchId, object_type, serialized_object_ids, attr_count, attr_list, mode, object_statuses);; } -sai_status_t VirtualSwitchSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_route_entry_t* route_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_route_entry(route_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - route_entry->switch_id, - SAI_OBJECT_TYPE_ROUTE_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_fdb_entry_t* fdb_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_fdb_entry(fdb_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - fdb_entry->switch_id, - SAI_OBJECT_TYPE_FDB_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_inseg_entry_t* inseg_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_inseg_entry(inseg_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - inseg_entry->switch_id, - SAI_OBJECT_TYPE_INSEG_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_my_sid_entry_t* my_sid_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_my_sid_entry(my_sid_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - my_sid_entry->switch_id, - SAI_OBJECT_TYPE_MY_SID_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_neighbor_entry_t* neighbor_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_neighbor_entry(neighbor_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - neighbor_entry->switch_id, - SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - -sai_status_t VirtualSwitchSaiInterface::bulkCreate( - _In_ uint32_t object_count, - _In_ const sai_nat_entry_t* nat_entry, - _In_ const uint32_t *attr_count, - _In_ const sai_attribute_t **attr_list, - _In_ sai_bulk_op_error_mode_t mode, - _Out_ sai_status_t *object_statuses) -{ - SWSS_LOG_ENTER(); - - std::vector serialized_object_ids; - - // on create vid is put in db by syncd - for (uint32_t idx = 0; idx < object_count; idx++) - { - std::string str_object_id = sai_serialize_nat_entry(nat_entry[idx]); - serialized_object_ids.push_back(str_object_id); - } - - return bulkCreate( - nat_entry->switch_id, - SAI_OBJECT_TYPE_NAT_ENTRY, - serialized_object_ids, - attr_count, - attr_list, - mode, - object_statuses); -} - sai_object_type_t VirtualSwitchSaiInterface::objectTypeQuery( _In_ sai_object_id_t objectId) { diff --git a/vslib/sai_vs.h b/vslib/sai_vs.h index f467d9451..37fa08269 100644 --- a/vslib/sai_vs.h +++ b/vslib/sai_vs.h @@ -256,60 +256,60 @@ PRIVATE extern std::shared_ptr vs_sai; // BULK QUAD -#define VS_BULK_CREATE(OT,fname) \ - static sai_status_t vs_bulk_create_ ## fname( \ - _In_ sai_object_id_t switch_id, \ - _In_ uint32_t object_count, \ - _In_ const uint32_t *attr_count, \ - _In_ const sai_attribute_t **attr_list, \ - _In_ sai_bulk_op_error_mode_t mode, \ - _Out_ sai_object_id_t *object_id, \ - _Out_ sai_status_t *object_statuses) \ -{ \ - SWSS_LOG_ENTER(); \ - return vs_sai->bulkCreate( \ - SAI_OBJECT_TYPE_ ## OT, \ - switch_id, \ - object_count, \ - attr_count, \ - attr_list, \ - mode, \ - object_id, \ - object_statuses); \ +#define VS_BULK_CREATE(OT,fname) \ + static sai_status_t vs_bulk_create_ ## fname( \ + _In_ sai_object_id_t switch_id, \ + _In_ uint32_t object_count, \ + _In_ const uint32_t *attr_count, \ + _In_ const sai_attribute_t **attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_object_id_t *object_id, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + return vs_sai->bulkCreate( \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + switch_id, \ + object_count, \ + attr_count, \ + attr_list, \ + mode, \ + object_id, \ + object_statuses); \ } -#define VS_BULK_REMOVE(OT,fname) \ - static sai_status_t vs_bulk_remove_ ## fname( \ - _In_ uint32_t object_count, \ - _In_ const sai_object_id_t *object_id, \ - _In_ sai_bulk_op_error_mode_t mode, \ - _Out_ sai_status_t *object_statuses) \ -{ \ - SWSS_LOG_ENTER(); \ - return vs_sai->bulkRemove( \ - SAI_OBJECT_TYPE_ ## OT, \ - object_count, \ - object_id, \ - mode, \ - object_statuses); \ +#define VS_BULK_REMOVE(OT,fname) \ + static sai_status_t vs_bulk_remove_ ## fname( \ + _In_ uint32_t object_count, \ + _In_ const sai_object_id_t *object_id, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + return vs_sai->bulkRemove( \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + object_count, \ + object_id, \ + mode, \ + object_statuses); \ } -#define VS_BULK_SET(OT,fname) \ - static sai_status_t vs_bulk_set_ ## fname( \ - _In_ uint32_t object_count, \ - _In_ const sai_object_id_t *object_id, \ - _In_ const sai_attribute_t *attr_list, \ - _In_ sai_bulk_op_error_mode_t mode, \ - _Out_ sai_status_t *object_statuses) \ -{ \ - SWSS_LOG_ENTER(); \ - return vs_sai->bulkSet( \ - SAI_OBJECT_TYPE_ ## OT, \ - object_count, \ - object_id, \ - attr_list, \ - mode, \ - object_statuses); \ +#define VS_BULK_SET(OT,fname) \ + static sai_status_t vs_bulk_set_ ## fname( \ + _In_ uint32_t object_count, \ + _In_ const sai_object_id_t *object_id, \ + _In_ const sai_attribute_t *attr_list, \ + _In_ sai_bulk_op_error_mode_t mode, \ + _Out_ sai_status_t *object_statuses) \ +{ \ + SWSS_LOG_ENTER(); \ + return vs_sai->bulkSet( \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT, \ + object_count, \ + object_id, \ + attr_list, \ + mode, \ + object_statuses); \ } #define VS_BULK_GET(OT,fname) \ @@ -336,8 +336,11 @@ PRIVATE extern std::shared_ptr vs_sai; // BULK QUAD ENTRY -#define VS_BULK_CREATE_ENTRY(OT,ot) \ - static sai_status_t vs_bulk_create_ ## ot( \ +#define VS_BULK_CREATE_ENTRY(OT,ot) \ + VS_BULK_CREATE_ENTRY_EX(OT,ot,ot) + +#define VS_BULK_CREATE_ENTRY_EX(OT,ot,fname) \ + static sai_status_t vs_bulk_create_ ## fname( \ _In_ uint32_t object_count, \ _In_ const sai_ ## ot ## _t *entry, \ _In_ const uint32_t *attr_count, \ @@ -355,8 +358,11 @@ PRIVATE extern std::shared_ptr vs_sai; object_statuses); \ } -#define VS_BULK_REMOVE_ENTRY(OT,ot) \ - static sai_status_t vs_bulk_remove_ ## ot( \ +#define VS_BULK_REMOVE_ENTRY(OT,ot) \ + VS_BULK_REMOVE_ENTRY_EX(OT, ot, ot) + +#define VS_BULK_REMOVE_ENTRY_EX(OT,ot,fname) \ + static sai_status_t vs_bulk_remove_ ## fname( \ _In_ uint32_t object_count, \ _In_ const sai_ ## ot ##_t *entry, \ _In_ sai_bulk_op_error_mode_t mode, \ From c1d8a8b60a3eefcf2b89fd00d225709cf016d467 Mon Sep 17 00:00:00 2001 From: Junchao-Mellanox <57339448+Junchao-Mellanox@users.noreply.github.com> Date: Fri, 28 Apr 2023 12:33:16 +0800 Subject: [PATCH 09/25] Revert "Ignore removing switch for mellanox platform due to known limitation (#1216)" (#1233) This commit introduces a race condition with would cause syncd crash. The issue happens when: Syncd.m_sn has been freed SAI send a port state change notification which will access Syncd.m_sn ===> causes crash --- configure.ac | 4 ---- syncd/Syncd.cpp | 11 +---------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/configure.ac b/configure.ac index e7ccb4ee2..409eccfba 100644 --- a/configure.ac +++ b/configure.ac @@ -17,10 +17,6 @@ AX_ADD_AM_MACRO_STATIC([]) AM_CONDITIONAL(SONIC_ASIC_PLATFORM_BAREFOOT, test x$CONFIGURED_PLATFORM = xbarefoot) AM_CONDITIONAL(SONIC_ASIC_PLATFORM_BROADCOM, test x$CONFIGURED_PLATFORM = xbroadcom) -AM_CONDITIONAL(SONIC_ASIC_PLATFORM_MELLANOX, test x$CONFIGURED_PLATFORM = xmellanox) - -AM_COND_IF([SONIC_ASIC_PLATFORM_MELLANOX], - AC_DEFINE([MELLANOX], [1], [Define to 1 on Mellanox Platform])) AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging], diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index f6ebd904f..78a1ea2d0 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -1,4 +1,3 @@ -#include "config.h" #include "Syncd.h" #include "VidManager.h" #include "NotificationHandler.h" @@ -4739,15 +4738,7 @@ void Syncd::run() m_mdioIpcServer->stopMdioThread(); - sai_status_t status = SAI_STATUS_SUCCESS; -#ifdef MELLANOX - if (shutdownType != SYNCD_RESTART_TYPE_COLD) - { - status = removeAllSwitches(); - } -#else - status = removeAllSwitches(); -#endif + sai_status_t status = removeAllSwitches(); // Stop notification thread after removing switch m_processor->stopNotificationsProcessingThread(); From 30eb32d49141c1d178845629a77a1ef8cbe73b8f Mon Sep 17 00:00:00 2001 From: Liu Shilong Date: Wed, 10 May 2023 23:51:23 +0800 Subject: [PATCH 10/25] Fix pipeline issue caused by urllib3 v2 *Fix pipeline issue caused by urllib3 v2 --- .azure-pipelines/test-docker-sonic-vs-template.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure-pipelines/test-docker-sonic-vs-template.yml b/.azure-pipelines/test-docker-sonic-vs-template.yml index 77e3b975f..c7e54932b 100644 --- a/.azure-pipelines/test-docker-sonic-vs-template.yml +++ b/.azure-pipelines/test-docker-sonic-vs-template.yml @@ -65,7 +65,7 @@ jobs: # install packages for vs test sudo apt-get install -y net-tools bridge-utils vlan sudo apt-get install -y python3-pip - sudo pip3 install pytest==4.6.2 attrs==19.1.0 exabgp==4.0.10 distro==1.5.0 docker==4.4.1 redis==3.3.4 flaky==3.7.0 + sudo pip3 install pytest==4.6.2 attrs==19.1.0 exabgp==4.0.10 distro==1.5.0 docker>=4.4.1 redis==3.3.4 flaky==3.7.0 displayName: "Install dependencies" - script: | From 654f0f3685e77a1db83056d15ddccb1f1327bd5b Mon Sep 17 00:00:00 2001 From: Oleksandr Ivantsiv Date: Fri, 12 May 2023 23:26:47 +0200 Subject: [PATCH 11/25] Add support for DASH, ARS, ARS profile APIs. (#1236) * [SAI submodule update] Enable support for SAI v1.12.0 - Add support for ars and ars_profile APIs. - Implement unit tests for ars and ars_profile APIs. - Implement DASH API - Implement DASH API unit tests --- .gitignore | 2 + SAI | 2 +- lib/Makefile.am | 13 +- lib/Recorder.h | 28 + lib/ServerSai.cpp | 250 ++- lib/sai_redis.h | 11 + lib/sai_redis_ars.cpp | 7 + lib/sai_redis_ars_profile.cpp | 8 + lib/sai_redis_dash_acl.cpp | 19 + lib/sai_redis_dash_direction_lookup.cpp | 11 + lib/sai_redis_dash_eni.cpp | 19 + lib/sai_redis_dash_inbound_routing.cpp | 11 + lib/sai_redis_dash_outbound_ca_to_pa.cpp | 11 + lib/sai_redis_dash_outbound_routing.cpp | 11 + lib/sai_redis_dash_pa_validation.cpp | 11 + lib/sai_redis_dash_vip.cpp | 11 + lib/sai_redis_dash_vnet.cpp | 11 + lib/sai_redis_interfacequery.cpp | 11 + lib/sai_redis_srv6.cpp | 4 + meta/Meta.cpp | 350 ++++ meta/Meta.h | 35 + meta/MetaKeyHasher.cpp | 316 ++++ meta/MetaTestSaiInterface.cpp | 20 + meta/MetaTestSaiInterface.h | 10 + meta/SaiInterface.cpp | 92 +- meta/SaiInterface.h | 50 +- meta/SaiSerialize.cpp | 558 +++++- meta/sai_serialize.h | 49 + saiplayer/SaiPlayer.cpp | 621 ++++++- saiplayer/SaiPlayer.h | 42 + syncd/Syncd.cpp | 324 +++- syncd/VendorSai.cpp | 499 ++++- syncd/tests/Makefile.am | 2 +- syncd/tests/TestSyncdNvdaBf.cpp | 1340 ++++++++++++++ syncd/tests/TestSyncdNvdaBf.h | 47 + syncd/tests/nvda-bf/lanemap.ini | 2 + syncd/tests/nvda-bf/sai.profile | 5 + tests/Makefile.am | 12 +- tests/NVDAMBF2H536C.pl | 30 + tests/NVDAMBF2H536C/client_switch.rec | 7 + tests/NVDAMBF2H536C/dashapis.rec | 312 ++++ tests/NVDAMBF2H536C/vsprofile.ini | 3 + tests/TestClient.cpp | 405 ++++ tests/TestClient.h | 74 + tests/TestDash.cpp | 1645 +++++++++++++++++ tests/TestDashEnv.cpp | 140 ++ tests/TestDashEnv.h | 32 + tests/TestDashMain.cpp | 16 + tests/testclient.cpp | 512 +---- tests/utils.pm | 21 +- unittest/lib/Makefile.am | 13 +- unittest/lib/TestClientServerSai.cpp | 4 +- unittest/lib/test_sai_redis_ars.cpp | 23 + unittest/lib/test_sai_redis_ars_profile.cpp | 23 + unittest/lib/test_sai_redis_dash_acl.cpp | 33 + .../test_sai_redis_dash_direction_lookup.cpp | 24 + unittest/lib/test_sai_redis_dash_eni.cpp | 33 + .../test_sai_redis_dash_inbound_routing.cpp | 24 + .../test_sai_redis_dash_outbound_ca_to_pa.cpp | 24 + .../test_sai_redis_dash_outbound_routing.cpp | 24 + .../lib/test_sai_redis_dash_pa_validation.cpp | 24 + unittest/lib/test_sai_redis_dash_vip.cpp | 24 + unittest/lib/test_sai_redis_dash_vnet.cpp | 24 + unittest/meta/Makefile.am | 3 +- unittest/meta/TestMeta.cpp | 104 ++ unittest/meta/TestMetaDash.cpp | 1331 +++++++++++++ unittest/meta/TestSaiInterface.cpp | 97 +- unittest/syncd/TestVendorSai.cpp | 1106 +++++++++++ unittest/vslib/Makefile.am | 14 +- unittest/vslib/TestSwitchNvdaMBF2H536C.cpp | 47 + unittest/vslib/TestTrafficForwarder.cpp | 2 + unittest/vslib/test_sai_vs_ars.cpp | 23 + unittest/vslib/test_sai_vs_ars_profile.cpp | 23 + unittest/vslib/test_sai_vs_dash_acl.cpp | 33 + .../test_sai_vs_dash_direction_lookup.cpp | 24 + unittest/vslib/test_sai_vs_dash_eni.cpp | 33 + .../test_sai_vs_dash_inbound_routing.cpp | 24 + .../test_sai_vs_dash_outbound_ca_to_pa.cpp | 24 + .../test_sai_vs_dash_outbound_routing.cpp | 24 + .../vslib/test_sai_vs_dash_pa_validation.cpp | 24 + unittest/vslib/test_sai_vs_dash_vip.cpp | 24 + unittest/vslib/test_sai_vs_dash_vnet.cpp | 24 + vslib/Makefile.am | 14 +- vslib/SwitchConfig.cpp | 4 + vslib/SwitchConfig.h | 2 + vslib/SwitchNvdaMBF2H536C.cpp | 59 + vslib/SwitchNvdaMBF2H536C.h | 34 + vslib/VirtualSwitchSaiInterface.cpp | 6 + vslib/sai_vs.h | 11 + vslib/sai_vs_ars.cpp | 7 + vslib/sai_vs_ars_profile.cpp | 7 + vslib/sai_vs_dash_acl.cpp | 19 + vslib/sai_vs_dash_direction_lookup.cpp | 11 + vslib/sai_vs_dash_eni.cpp | 19 + vslib/sai_vs_dash_inbound_routing.cpp | 11 + vslib/sai_vs_dash_outbound_ca_to_pa.cpp | 11 + vslib/sai_vs_dash_outbound_routing.cpp | 11 + vslib/sai_vs_dash_pa_validation.cpp | 11 + vslib/sai_vs_dash_vip.cpp | 11 + vslib/sai_vs_dash_vnet.cpp | 11 + vslib/sai_vs_interfacequery.cpp | 11 + vslib/sai_vs_srv6.cpp | 4 + vslib/saivs.h | 11 +- 103 files changed, 10885 insertions(+), 703 deletions(-) create mode 100644 lib/sai_redis_ars.cpp create mode 100644 lib/sai_redis_ars_profile.cpp create mode 100644 lib/sai_redis_dash_acl.cpp create mode 100644 lib/sai_redis_dash_direction_lookup.cpp create mode 100644 lib/sai_redis_dash_eni.cpp create mode 100644 lib/sai_redis_dash_inbound_routing.cpp create mode 100644 lib/sai_redis_dash_outbound_ca_to_pa.cpp create mode 100644 lib/sai_redis_dash_outbound_routing.cpp create mode 100644 lib/sai_redis_dash_pa_validation.cpp create mode 100644 lib/sai_redis_dash_vip.cpp create mode 100644 lib/sai_redis_dash_vnet.cpp create mode 100644 syncd/tests/TestSyncdNvdaBf.cpp create mode 100644 syncd/tests/TestSyncdNvdaBf.h create mode 100644 syncd/tests/nvda-bf/lanemap.ini create mode 100644 syncd/tests/nvda-bf/sai.profile create mode 100755 tests/NVDAMBF2H536C.pl create mode 100644 tests/NVDAMBF2H536C/client_switch.rec create mode 100644 tests/NVDAMBF2H536C/dashapis.rec create mode 100644 tests/NVDAMBF2H536C/vsprofile.ini create mode 100644 tests/TestClient.cpp create mode 100644 tests/TestClient.h create mode 100644 tests/TestDash.cpp create mode 100644 tests/TestDashEnv.cpp create mode 100644 tests/TestDashEnv.h create mode 100644 tests/TestDashMain.cpp create mode 100644 unittest/lib/test_sai_redis_ars.cpp create mode 100644 unittest/lib/test_sai_redis_ars_profile.cpp create mode 100644 unittest/lib/test_sai_redis_dash_acl.cpp create mode 100644 unittest/lib/test_sai_redis_dash_direction_lookup.cpp create mode 100644 unittest/lib/test_sai_redis_dash_eni.cpp create mode 100644 unittest/lib/test_sai_redis_dash_inbound_routing.cpp create mode 100644 unittest/lib/test_sai_redis_dash_outbound_ca_to_pa.cpp create mode 100644 unittest/lib/test_sai_redis_dash_outbound_routing.cpp create mode 100644 unittest/lib/test_sai_redis_dash_pa_validation.cpp create mode 100644 unittest/lib/test_sai_redis_dash_vip.cpp create mode 100644 unittest/lib/test_sai_redis_dash_vnet.cpp create mode 100644 unittest/meta/TestMetaDash.cpp create mode 100644 unittest/vslib/TestSwitchNvdaMBF2H536C.cpp create mode 100644 unittest/vslib/test_sai_vs_ars.cpp create mode 100644 unittest/vslib/test_sai_vs_ars_profile.cpp create mode 100644 unittest/vslib/test_sai_vs_dash_acl.cpp create mode 100644 unittest/vslib/test_sai_vs_dash_direction_lookup.cpp create mode 100644 unittest/vslib/test_sai_vs_dash_eni.cpp create mode 100644 unittest/vslib/test_sai_vs_dash_inbound_routing.cpp create mode 100644 unittest/vslib/test_sai_vs_dash_outbound_ca_to_pa.cpp create mode 100644 unittest/vslib/test_sai_vs_dash_outbound_routing.cpp create mode 100644 unittest/vslib/test_sai_vs_dash_pa_validation.cpp create mode 100644 unittest/vslib/test_sai_vs_dash_vip.cpp create mode 100644 unittest/vslib/test_sai_vs_dash_vnet.cpp create mode 100644 vslib/SwitchNvdaMBF2H536C.cpp create mode 100644 vslib/SwitchNvdaMBF2H536C.h create mode 100644 vslib/sai_vs_ars.cpp create mode 100644 vslib/sai_vs_ars_profile.cpp create mode 100644 vslib/sai_vs_dash_acl.cpp create mode 100644 vslib/sai_vs_dash_direction_lookup.cpp create mode 100644 vslib/sai_vs_dash_eni.cpp create mode 100644 vslib/sai_vs_dash_inbound_routing.cpp create mode 100644 vslib/sai_vs_dash_outbound_ca_to_pa.cpp create mode 100644 vslib/sai_vs_dash_outbound_routing.cpp create mode 100644 vslib/sai_vs_dash_pa_validation.cpp create mode 100644 vslib/sai_vs_dash_vip.cpp create mode 100644 vslib/sai_vs_dash_vnet.cpp diff --git a/.gitignore b/.gitignore index b2d89ccfe..f2dceea04 100644 --- a/.gitignore +++ b/.gitignore @@ -101,6 +101,8 @@ syncd/syncd_tests syncd/tests/tests tests/syncd tests/testclient +tests/testclient_dash +tests/testdash_gtest tests/tests tests/vssyncd unittest/lib/tests diff --git a/SAI b/SAI index 00314701a..3ff228a7e 160000 --- a/SAI +++ b/SAI @@ -1 +1 @@ -Subproject commit 00314701afdc4a1ceff13bed8dee17c599b664a2 +Subproject commit 3ff228a7e5619a56e3c169966cb1a8631705768a diff --git a/lib/Makefile.am b/lib/Makefile.am index faa34a77e..ba6594d88 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -35,6 +35,15 @@ libsairedis_la_SOURCES = \ sai_redis_bridge.cpp \ sai_redis_buffer.cpp \ sai_redis_counter.cpp \ + sai_redis_dash_vip.cpp \ + sai_redis_dash_pa_validation.cpp \ + sai_redis_dash_vnet.cpp \ + sai_redis_dash_outbound_routing.cpp \ + sai_redis_dash_outbound_ca_to_pa.cpp \ + sai_redis_dash_inbound_routing.cpp \ + sai_redis_dash_eni.cpp \ + sai_redis_dash_direction_lookup.cpp \ + sai_redis_dash_acl.cpp \ sai_redis_debug_counter.cpp \ sai_redis_dtel.cpp \ sai_redis_fdb.cpp \ @@ -77,7 +86,9 @@ libsairedis_la_SOURCES = \ sai_redis_vlan.cpp \ sai_redis_wred.cpp \ sai_redis_ipsec.cpp \ - sai_redis_my_mac.cpp + sai_redis_my_mac.cpp \ + sai_redis_ars.cpp \ + sai_redis_ars_profile.cpp libSaiRedis_a_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) libSaiRedis_a_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS) diff --git a/lib/Recorder.h b/lib/Recorder.h index 3d55dbf12..ccda2bacb 100644 --- a/lib/Recorder.h +++ b/lib/Recorder.h @@ -171,6 +171,13 @@ namespace sairedis SAI_REDIS_RECORDER_DECLARE_RECORD_CREATE(route_entry); SAI_REDIS_RECORDER_DECLARE_RECORD_CREATE(nat_entry); SAI_REDIS_RECORDER_DECLARE_RECORD_CREATE(my_sid_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_CREATE(direction_lookup_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_CREATE(eni_ether_address_map_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_CREATE(vip_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_CREATE(inbound_routing_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_CREATE(pa_validation_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_CREATE(outbound_routing_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_CREATE(outbound_ca_to_pa_entry); public: // remove ENTRY @@ -183,6 +190,13 @@ namespace sairedis SAI_REDIS_RECORDER_DECLARE_RECORD_REMOVE(route_entry); SAI_REDIS_RECORDER_DECLARE_RECORD_REMOVE(nat_entry); SAI_REDIS_RECORDER_DECLARE_RECORD_REMOVE(my_sid_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_REMOVE(direction_lookup_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_REMOVE(eni_ether_address_map_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_REMOVE(vip_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_REMOVE(inbound_routing_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_REMOVE(pa_validation_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_REMOVE(outbound_routing_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_REMOVE(outbound_ca_to_pa_entry); public: // set ENTRY @@ -195,6 +209,13 @@ namespace sairedis SAI_REDIS_RECORDER_DECLARE_RECORD_SET(route_entry); SAI_REDIS_RECORDER_DECLARE_RECORD_SET(nat_entry); SAI_REDIS_RECORDER_DECLARE_RECORD_SET(my_sid_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_SET(direction_lookup_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_SET(eni_ether_address_map_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_SET(vip_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_SET(inbound_routing_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_SET(pa_validation_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_SET(outbound_routing_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_SET(outbound_ca_to_pa_entry); public: // get ENTRY @@ -207,6 +228,13 @@ namespace sairedis SAI_REDIS_RECORDER_DECLARE_RECORD_GET(route_entry); SAI_REDIS_RECORDER_DECLARE_RECORD_GET(nat_entry); SAI_REDIS_RECORDER_DECLARE_RECORD_GET(my_sid_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_GET(direction_lookup_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_GET(eni_ether_address_map_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_GET(vip_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_GET(inbound_routing_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_GET(pa_validation_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_GET(outbound_routing_entry); + SAI_REDIS_RECORDER_DECLARE_RECORD_GET(outbound_ca_to_pa_entry); public: // SAI stats API diff --git a/lib/ServerSai.cpp b/lib/ServerSai.cpp index fc434c138..24bd4043a 100644 --- a/lib/ServerSai.cpp +++ b/lib/ServerSai.cpp @@ -1237,7 +1237,7 @@ sai_status_t ServerSai::processBulkCreateEntry( attr_lists[idx] = attributes[idx]->get_attr_list(); } - switch (objectType) + switch ((int)objectType) { case SAI_OBJECT_TYPE_ROUTE_ENTRY: { @@ -1334,6 +1334,139 @@ sai_status_t ServerSai::processBulkCreateEntry( } break; + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_direction_lookup_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_eni_ether_address_map_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_VIP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_vip_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_inbound_routing_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_pa_validation_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_routing_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_ca_to_pa_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + default: return SAI_STATUS_NOT_SUPPORTED; } @@ -1354,7 +1487,7 @@ sai_status_t ServerSai::processBulkRemoveEntry( sai_bulk_op_error_mode_t mode = SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR; - switch (objectType) + switch ((int)objectType) { case SAI_OBJECT_TYPE_ROUTE_ENTRY: { @@ -1441,6 +1574,119 @@ sai_status_t ServerSai::processBulkRemoveEntry( } break; + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_direction_lookup_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_eni_ether_address_map_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_VIP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_vip_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_inbound_routing_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_pa_validation_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_routing_entry(objectIds[it], entries[it]); + } + status = m_sai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_ca_to_pa_entry(objectIds[it], entries[it]); + } + + status = m_sai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + } + break; + default: return SAI_STATUS_NOT_SUPPORTED; } diff --git a/lib/sai_redis.h b/lib/sai_redis.h index 207ad1fc2..eb03c331d 100644 --- a/lib/sai_redis.h +++ b/lib/sai_redis.h @@ -14,12 +14,23 @@ extern "C" { #define PRIVATE __attribute__((visibility("hidden"))) PRIVATE extern const sai_acl_api_t redis_acl_api; +PRIVATE extern const sai_ars_api_t redis_ars_api; +PRIVATE extern const sai_ars_profile_api_t redis_ars_profile_api; PRIVATE extern const sai_bfd_api_t redis_bfd_api; PRIVATE extern const sai_bmtor_api_t redis_bmtor_api; PRIVATE extern const sai_generic_programmable_api_t redis_generic_programmable_api; PRIVATE extern const sai_bridge_api_t redis_bridge_api; PRIVATE extern const sai_buffer_api_t redis_buffer_api; PRIVATE extern const sai_counter_api_t redis_counter_api; +PRIVATE extern const sai_dash_vip_api_t redis_dash_vip_api; +PRIVATE extern const sai_dash_pa_validation_api_t redis_dash_pa_validation_api; +PRIVATE extern const sai_dash_vnet_api_t redis_dash_vnet_api; +PRIVATE extern const sai_dash_outbound_routing_api_t redis_dash_outbound_routing_api; +PRIVATE extern const sai_dash_outbound_ca_to_pa_api_t redis_dash_outbound_ca_to_pa_api; +PRIVATE extern const sai_dash_inbound_routing_api_t redis_dash_inbound_routing_api; +PRIVATE extern const sai_dash_eni_api_t redis_dash_eni_api; +PRIVATE extern const sai_dash_direction_lookup_api_t redis_dash_direction_lookup_api; +PRIVATE extern const sai_dash_acl_api_t redis_dash_acl_api; PRIVATE extern const sai_debug_counter_api_t redis_debug_counter_api; PRIVATE extern const sai_dtel_api_t redis_dtel_api; PRIVATE extern const sai_fdb_api_t redis_fdb_api; diff --git a/lib/sai_redis_ars.cpp b/lib/sai_redis_ars.cpp new file mode 100644 index 000000000..5fd6f812a --- /dev/null +++ b/lib/sai_redis_ars.cpp @@ -0,0 +1,7 @@ +#include "sai_redis.h" + +REDIS_GENERIC_QUAD(ARS, ars); + +const sai_ars_api_t redis_ars_api = { + REDIS_GENERIC_QUAD_API(ars) +}; diff --git a/lib/sai_redis_ars_profile.cpp b/lib/sai_redis_ars_profile.cpp new file mode 100644 index 000000000..ffef33354 --- /dev/null +++ b/lib/sai_redis_ars_profile.cpp @@ -0,0 +1,8 @@ +#include "sai_redis.h" + + +REDIS_GENERIC_QUAD(ARS_PROFILE, ars_profile); + +const sai_ars_profile_api_t redis_ars_profile_api = { + REDIS_GENERIC_QUAD_API(ars_profile) +}; diff --git a/lib/sai_redis_dash_acl.cpp b/lib/sai_redis_dash_acl.cpp new file mode 100644 index 000000000..69440cb3e --- /dev/null +++ b/lib/sai_redis_dash_acl.cpp @@ -0,0 +1,19 @@ +#include "sai_redis.h" + +REDIS_GENERIC_QUAD(DASH_ACL_GROUP, dash_acl_group); +REDIS_BULK_CREATE(DASH_ACL_GROUP, dash_acl_groups); +REDIS_BULK_REMOVE(DASH_ACL_GROUP, dash_acl_groups); + +REDIS_GENERIC_QUAD(DASH_ACL_RULE, dash_acl_rule); +REDIS_BULK_CREATE(DASH_ACL_RULE, dash_acl_rules); +REDIS_BULK_REMOVE(DASH_ACL_RULE, dash_acl_rules); + +const sai_dash_acl_api_t redis_dash_acl_api = { + REDIS_GENERIC_QUAD_API(dash_acl_group) + redis_bulk_create_dash_acl_groups, + redis_bulk_remove_dash_acl_groups, + + REDIS_GENERIC_QUAD_API(dash_acl_rule) + redis_bulk_create_dash_acl_rules, + redis_bulk_remove_dash_acl_rules, +}; diff --git a/lib/sai_redis_dash_direction_lookup.cpp b/lib/sai_redis_dash_direction_lookup.cpp new file mode 100644 index 000000000..4d691dffc --- /dev/null +++ b/lib/sai_redis_dash_direction_lookup.cpp @@ -0,0 +1,11 @@ +#include "sai_redis.h" + +REDIS_GENERIC_QUAD_ENTRY(DIRECTION_LOOKUP_ENTRY, direction_lookup_entry); +REDIS_BULK_CREATE_ENTRY_EX(DIRECTION_LOOKUP_ENTRY, direction_lookup_entry, direction_lookup_entries); +REDIS_BULK_REMOVE_ENTRY_EX(DIRECTION_LOOKUP_ENTRY, direction_lookup_entry, direction_lookup_entries); + +const sai_dash_direction_lookup_api_t redis_dash_direction_lookup_api = { + REDIS_GENERIC_QUAD_API(direction_lookup_entry) + redis_bulk_create_direction_lookup_entries, + redis_bulk_remove_direction_lookup_entries, +}; diff --git a/lib/sai_redis_dash_eni.cpp b/lib/sai_redis_dash_eni.cpp new file mode 100644 index 000000000..9f21bda71 --- /dev/null +++ b/lib/sai_redis_dash_eni.cpp @@ -0,0 +1,19 @@ +#include "sai_redis.h" + +REDIS_GENERIC_QUAD_ENTRY(ENI_ETHER_ADDRESS_MAP_ENTRY, eni_ether_address_map_entry); +REDIS_BULK_CREATE_ENTRY_EX(ENI_ETHER_ADDRESS_MAP_ENTRY, eni_ether_address_map_entry, eni_ether_address_map_entries); +REDIS_BULK_REMOVE_ENTRY_EX(ENI_ETHER_ADDRESS_MAP_ENTRY, eni_ether_address_map_entry, eni_ether_address_map_entries); + +REDIS_GENERIC_QUAD(ENI, eni); +REDIS_BULK_CREATE(ENI, enis); +REDIS_BULK_REMOVE(ENI, enis); + +const sai_dash_eni_api_t redis_dash_eni_api = { + REDIS_GENERIC_QUAD_API(eni_ether_address_map_entry) + redis_bulk_create_eni_ether_address_map_entries, + redis_bulk_remove_eni_ether_address_map_entries, + + REDIS_GENERIC_QUAD_API(eni) + redis_bulk_create_enis, + redis_bulk_remove_enis, +}; diff --git a/lib/sai_redis_dash_inbound_routing.cpp b/lib/sai_redis_dash_inbound_routing.cpp new file mode 100644 index 000000000..30d4e7644 --- /dev/null +++ b/lib/sai_redis_dash_inbound_routing.cpp @@ -0,0 +1,11 @@ +#include "sai_redis.h" + +REDIS_GENERIC_QUAD_ENTRY(INBOUND_ROUTING_ENTRY, inbound_routing_entry); +REDIS_BULK_CREATE_ENTRY_EX(INBOUND_ROUTING_ENTRY, inbound_routing_entry, inbound_routing_entries); +REDIS_BULK_REMOVE_ENTRY_EX(INBOUND_ROUTING_ENTRY, inbound_routing_entry, inbound_routing_entries); + +const sai_dash_inbound_routing_api_t redis_dash_inbound_routing_api = { + REDIS_GENERIC_QUAD_API(inbound_routing_entry) + redis_bulk_create_inbound_routing_entries, + redis_bulk_remove_inbound_routing_entries, +}; diff --git a/lib/sai_redis_dash_outbound_ca_to_pa.cpp b/lib/sai_redis_dash_outbound_ca_to_pa.cpp new file mode 100644 index 000000000..6f3bd9267 --- /dev/null +++ b/lib/sai_redis_dash_outbound_ca_to_pa.cpp @@ -0,0 +1,11 @@ +#include "sai_redis.h" + +REDIS_GENERIC_QUAD_ENTRY(OUTBOUND_CA_TO_PA_ENTRY, outbound_ca_to_pa_entry); +REDIS_BULK_CREATE_ENTRY_EX(OUTBOUND_CA_TO_PA_ENTRY, outbound_ca_to_pa_entry, outbound_ca_to_pa_entries); +REDIS_BULK_REMOVE_ENTRY_EX(OUTBOUND_CA_TO_PA_ENTRY, outbound_ca_to_pa_entry, outbound_ca_to_pa_entries); + +const sai_dash_outbound_ca_to_pa_api_t redis_dash_outbound_ca_to_pa_api = { + REDIS_GENERIC_QUAD_API(outbound_ca_to_pa_entry) + redis_bulk_create_outbound_ca_to_pa_entries, + redis_bulk_remove_outbound_ca_to_pa_entries, +}; diff --git a/lib/sai_redis_dash_outbound_routing.cpp b/lib/sai_redis_dash_outbound_routing.cpp new file mode 100644 index 000000000..4fe8b9aa9 --- /dev/null +++ b/lib/sai_redis_dash_outbound_routing.cpp @@ -0,0 +1,11 @@ +#include "sai_redis.h" + +REDIS_GENERIC_QUAD_ENTRY(OUTBOUND_ROUTING_ENTRY, outbound_routing_entry); +REDIS_BULK_CREATE_ENTRY_EX(OUTBOUND_ROUTING_ENTRY, outbound_routing_entry, outbound_routing_entries); +REDIS_BULK_REMOVE_ENTRY_EX(OUTBOUND_ROUTING_ENTRY, outbound_routing_entry, outbound_routing_entries); + +const sai_dash_outbound_routing_api_t redis_dash_outbound_routing_api = { + REDIS_GENERIC_QUAD_API(outbound_routing_entry) + redis_bulk_create_outbound_routing_entries, + redis_bulk_remove_outbound_routing_entries, +}; diff --git a/lib/sai_redis_dash_pa_validation.cpp b/lib/sai_redis_dash_pa_validation.cpp new file mode 100644 index 000000000..24ca4373e --- /dev/null +++ b/lib/sai_redis_dash_pa_validation.cpp @@ -0,0 +1,11 @@ +#include "sai_redis.h" + +REDIS_GENERIC_QUAD_ENTRY(PA_VALIDATION_ENTRY, pa_validation_entry); +REDIS_BULK_CREATE_ENTRY_EX(PA_VALIDATION_ENTRY, pa_validation_entry, pa_validation_entries); +REDIS_BULK_REMOVE_ENTRY_EX(PA_VALIDATION_ENTRY, pa_validation_entry, pa_validation_entries); + +const sai_dash_pa_validation_api_t redis_dash_pa_validation_api = { + REDIS_GENERIC_QUAD_API(pa_validation_entry) + redis_bulk_create_pa_validation_entries, + redis_bulk_remove_pa_validation_entries, +}; diff --git a/lib/sai_redis_dash_vip.cpp b/lib/sai_redis_dash_vip.cpp new file mode 100644 index 000000000..5992a83f7 --- /dev/null +++ b/lib/sai_redis_dash_vip.cpp @@ -0,0 +1,11 @@ +#include "sai_redis.h" + +REDIS_GENERIC_QUAD_ENTRY(VIP_ENTRY, vip_entry); +REDIS_BULK_CREATE_ENTRY_EX(VIP_ENTRY, vip_entry, vip_entries); +REDIS_BULK_REMOVE_ENTRY_EX(VIP_ENTRY, vip_entry, vip_entries); + +const sai_dash_vip_api_t redis_dash_vip_api = { + REDIS_GENERIC_QUAD_API(vip_entry) + redis_bulk_create_vip_entries, + redis_bulk_remove_vip_entries, +}; diff --git a/lib/sai_redis_dash_vnet.cpp b/lib/sai_redis_dash_vnet.cpp new file mode 100644 index 000000000..536785bcc --- /dev/null +++ b/lib/sai_redis_dash_vnet.cpp @@ -0,0 +1,11 @@ +#include "sai_redis.h" + +REDIS_GENERIC_QUAD(VNET, vnet); +REDIS_BULK_CREATE(VNET, vnets); +REDIS_BULK_REMOVE(VNET, vnets); + +const sai_dash_vnet_api_t redis_dash_vnet_api = { + REDIS_GENERIC_QUAD_API(vnet) + redis_bulk_create_vnets, + redis_bulk_remove_vnets, +}; diff --git a/lib/sai_redis_interfacequery.cpp b/lib/sai_redis_interfacequery.cpp index 46890ae74..0525c1105 100644 --- a/lib/sai_redis_interfacequery.cpp +++ b/lib/sai_redis_interfacequery.cpp @@ -80,7 +80,18 @@ static sai_apis_t redis_apis = { API(my_mac), API(ipsec), API(generic_programmable), + API(ars), + API(ars_profile), API(bmtor), + API(dash_acl), + API(dash_direction_lookup), + API(dash_eni), + API(dash_inbound_routing), + API(dash_outbound_ca_to_pa), + API(dash_outbound_routing), + API(dash_vnet), + API(dash_pa_validation), + API(dash_vip), }; static_assert((sizeof(sai_apis_t)/sizeof(void*)) == (SAI_API_EXTENSIONS_MAX - 1)); diff --git a/lib/sai_redis_srv6.cpp b/lib/sai_redis_srv6.cpp index d31e887f5..293a35ac8 100644 --- a/lib/sai_redis_srv6.cpp +++ b/lib/sai_redis_srv6.cpp @@ -13,6 +13,10 @@ const sai_srv6_api_t redis_srv6_api = { redis_bulk_create_srv6_sidlist, redis_bulk_remove_srv6_sidlist, + NULL, + NULL, + NULL, + REDIS_GENERIC_QUAD_API(my_sid_entry) REDIS_BULK_QUAD_API(my_sid_entry) }; diff --git a/meta/Meta.cpp b/meta/Meta.cpp index 186790d29..b844c6f7a 100644 --- a/meta/Meta.cpp +++ b/meta/Meta.cpp @@ -1884,6 +1884,10 @@ void Meta::meta_generic_validation_post_remove( // no special action required break; + case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST: + // no special action required + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); } @@ -2741,6 +2745,328 @@ sai_status_t Meta::meta_sai_validate_my_sid_entry( return SAI_STATUS_SUCCESS; } +sai_status_t Meta::meta_sai_validate_direction_lookup_entry( + _In_ const sai_direction_lookup_entry_t* direction_lookup_entry, + _In_ bool create, + _In_ bool get) +{ + SWSS_LOG_ENTER(); + + if (direction_lookup_entry == NULL) + { + SWSS_LOG_ERROR("direction_lookup_entry pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_meta_key_t meta_key_direction_lookup_entry = { + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY, + .objectkey = { + .key = { .direction_lookup_entry = *direction_lookup_entry } + } + }; + + if (create) + { + if (m_saiObjectCollection.objectExists(meta_key_direction_lookup_entry)) + { + SWSS_LOG_ERROR("object key %s already exists", + sai_serialize_object_meta_key(meta_key_direction_lookup_entry).c_str()); + + return SAI_STATUS_ITEM_ALREADY_EXISTS; + } + + return SAI_STATUS_SUCCESS; + } + + // set, get, remove + if (!m_saiObjectCollection.objectExists(meta_key_direction_lookup_entry)) + { + SWSS_LOG_ERROR("object key %s doesn't exist", + sai_serialize_object_meta_key(meta_key_direction_lookup_entry).c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t Meta::meta_sai_validate_eni_ether_address_map_entry( + _In_ const sai_eni_ether_address_map_entry_t* eni_ether_address_map_entry, + _In_ bool create, + _In_ bool get) +{ + SWSS_LOG_ENTER(); + + if (eni_ether_address_map_entry == NULL) + { + SWSS_LOG_ERROR("eni_ether_address_map_entry pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_meta_key_t meta_key_eni_ether_address_map_entry = { + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY, + .objectkey = { + .key = { .eni_ether_address_map_entry = *eni_ether_address_map_entry } + } + }; + + if (create) + { + if (m_saiObjectCollection.objectExists(meta_key_eni_ether_address_map_entry)) + { + SWSS_LOG_ERROR("object key %s already exists", + sai_serialize_object_meta_key(meta_key_eni_ether_address_map_entry).c_str()); + + return SAI_STATUS_ITEM_ALREADY_EXISTS; + } + + return SAI_STATUS_SUCCESS; + } + + // set, get, remove + if (!m_saiObjectCollection.objectExists(meta_key_eni_ether_address_map_entry)) + { + SWSS_LOG_ERROR("object key %s doesn't exist", + sai_serialize_object_meta_key(meta_key_eni_ether_address_map_entry).c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t Meta::meta_sai_validate_vip_entry( + _In_ const sai_vip_entry_t* vip_entry, + _In_ bool create, + _In_ bool get) +{ + SWSS_LOG_ENTER(); + + if (vip_entry == NULL) + { + SWSS_LOG_ERROR("vip_entry pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_meta_key_t meta_key_vip_entry = { + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_VIP_ENTRY, + .objectkey = { + .key = { .vip_entry = *vip_entry } + } + }; + + if (create) + { + if (m_saiObjectCollection.objectExists(meta_key_vip_entry)) + { + SWSS_LOG_ERROR("object key %s already exists", + sai_serialize_object_meta_key(meta_key_vip_entry).c_str()); + + return SAI_STATUS_ITEM_ALREADY_EXISTS; + } + + return SAI_STATUS_SUCCESS; + } + + // set, get, remove + if (!m_saiObjectCollection.objectExists(meta_key_vip_entry)) + { + SWSS_LOG_ERROR("object key %s doesn't exist", + sai_serialize_object_meta_key(meta_key_vip_entry).c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t Meta::meta_sai_validate_inbound_routing_entry( + _In_ const sai_inbound_routing_entry_t* inbound_routing_entry, + _In_ bool create, + _In_ bool get) +{ + SWSS_LOG_ENTER(); + + if (inbound_routing_entry == NULL) + { + SWSS_LOG_ERROR("inbound_routing_entry pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_meta_key_t meta_key_inbound_routing_entry = { + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY, + .objectkey = { + .key = { .inbound_routing_entry = *inbound_routing_entry } + } + }; + + if (create) + { + if (m_saiObjectCollection.objectExists(meta_key_inbound_routing_entry)) + { + SWSS_LOG_ERROR("object key %s already exists", + sai_serialize_object_meta_key(meta_key_inbound_routing_entry).c_str()); + + return SAI_STATUS_ITEM_ALREADY_EXISTS; + } + + return SAI_STATUS_SUCCESS; + } + + // set, get, remove + if (!m_saiObjectCollection.objectExists(meta_key_inbound_routing_entry)) + { + SWSS_LOG_ERROR("object key %s doesn't exist", + sai_serialize_object_meta_key(meta_key_inbound_routing_entry).c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t Meta::meta_sai_validate_pa_validation_entry( + _In_ const sai_pa_validation_entry_t* pa_validation_entry, + _In_ bool create, + _In_ bool get) +{ + SWSS_LOG_ENTER(); + + if (pa_validation_entry == NULL) + { + SWSS_LOG_ERROR("pa_validation_entry pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_meta_key_t meta_key_pa_validation_entry = { + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY, + .objectkey = { + .key = { .pa_validation_entry = *pa_validation_entry } + } + }; + + if (create) + { + if (m_saiObjectCollection.objectExists(meta_key_pa_validation_entry)) + { + SWSS_LOG_ERROR("object key %s already exists", + sai_serialize_object_meta_key(meta_key_pa_validation_entry).c_str()); + + return SAI_STATUS_ITEM_ALREADY_EXISTS; + } + + return SAI_STATUS_SUCCESS; + } + + // set, get, remove + if (!m_saiObjectCollection.objectExists(meta_key_pa_validation_entry)) + { + SWSS_LOG_ERROR("object key %s doesn't exist", + sai_serialize_object_meta_key(meta_key_pa_validation_entry).c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t Meta::meta_sai_validate_outbound_routing_entry( + _In_ const sai_outbound_routing_entry_t* outbound_routing_entry, + _In_ bool create, + _In_ bool get) +{ + SWSS_LOG_ENTER(); + + if (outbound_routing_entry == NULL) + { + SWSS_LOG_ERROR("outbound_routing_entry pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_meta_key_t meta_key_outbound_routing_entry = { + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY, + .objectkey = { + .key = { .outbound_routing_entry = *outbound_routing_entry } + } + }; + + if (create) + { + if (m_saiObjectCollection.objectExists(meta_key_outbound_routing_entry)) + { + SWSS_LOG_ERROR("object key %s already exists", + sai_serialize_object_meta_key(meta_key_outbound_routing_entry).c_str()); + + return SAI_STATUS_ITEM_ALREADY_EXISTS; + } + + return SAI_STATUS_SUCCESS; + } + + // set, get, remove + if (!m_saiObjectCollection.objectExists(meta_key_outbound_routing_entry)) + { + SWSS_LOG_ERROR("object key %s doesn't exist", + sai_serialize_object_meta_key(meta_key_outbound_routing_entry).c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + +sai_status_t Meta::meta_sai_validate_outbound_ca_to_pa_entry( + _In_ const sai_outbound_ca_to_pa_entry_t* outbound_ca_to_pa_entry, + _In_ bool create, + _In_ bool get) +{ + SWSS_LOG_ENTER(); + + if (outbound_ca_to_pa_entry == NULL) + { + SWSS_LOG_ERROR("outbound_ca_to_pa_entry pointer is NULL"); + + return SAI_STATUS_INVALID_PARAMETER; + } + + sai_object_meta_key_t meta_key_outbound_ca_to_pa_entry = { + .objecttype = (sai_object_type_t)SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY, + .objectkey = { + .key = { .outbound_ca_to_pa_entry = *outbound_ca_to_pa_entry } + } + }; + + if (create) + { + if (m_saiObjectCollection.objectExists(meta_key_outbound_ca_to_pa_entry)) + { + SWSS_LOG_ERROR("object key %s already exists", + sai_serialize_object_meta_key(meta_key_outbound_ca_to_pa_entry).c_str()); + + return SAI_STATUS_ITEM_ALREADY_EXISTS; + } + + return SAI_STATUS_SUCCESS; + } + + // set, get, remove + if (!m_saiObjectCollection.objectExists(meta_key_outbound_ca_to_pa_entry)) + { + SWSS_LOG_ERROR("object key %s doesn't exist", + sai_serialize_object_meta_key(meta_key_outbound_ca_to_pa_entry).c_str()); + + return SAI_STATUS_INVALID_PARAMETER; + } + + return SAI_STATUS_SUCCESS; +} + sai_status_t Meta::meta_generic_validation_create( _In_ const sai_object_meta_key_t& meta_key, _In_ sai_object_id_t switch_id, @@ -3194,6 +3520,10 @@ sai_status_t Meta::meta_generic_validation_create( case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG: break; + case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST: + VALIDATION_LIST(md, value.ipprefixlist); + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); @@ -3859,6 +4189,10 @@ sai_status_t Meta::meta_generic_validation_set( case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG: break; + case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST: + VALIDATION_LIST(md, value.ipprefixlist); + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); @@ -4242,6 +4576,10 @@ sai_status_t Meta::meta_generic_validation_get( VALIDATION_LIST(md, value.sysportconfiglist); break; + case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST: + VALIDATION_LIST(md, value.ipprefixlist); + break; + default: // acl capability will is more complex since is in/out we need to check stage @@ -4511,6 +4849,10 @@ void Meta::meta_generic_validation_post_get( VALIDATION_LIST_GET(md, value.sysportconfiglist); break; + case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST: + VALIDATION_LIST_GET(md, value.ipprefixlist); + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); @@ -5401,6 +5743,10 @@ void Meta::meta_generic_validation_post_create( // no special action required break; + case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST: + // no special action required + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); @@ -5636,6 +5982,10 @@ void Meta::meta_generic_validation_post_set( // no special action required break; + case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST: + // no special action required + break; + default: META_LOG_THROW(md, "serialization type is not supported yet FIXME"); } diff --git a/meta/Meta.h b/meta/Meta.h index 21131b5f4..0eae42b51 100644 --- a/meta/Meta.h +++ b/meta/Meta.h @@ -486,6 +486,41 @@ namespace saimeta _In_ bool create, _In_ bool get = false); + sai_status_t meta_sai_validate_direction_lookup_entry( + _In_ const sai_direction_lookup_entry_t* direction_lookup_entry, + _In_ bool create, + _In_ bool get = false); + + sai_status_t meta_sai_validate_eni_ether_address_map_entry( + _In_ const sai_eni_ether_address_map_entry_t* eni_ether_address_map_entry, + _In_ bool create, + _In_ bool get = false); + + sai_status_t meta_sai_validate_vip_entry( + _In_ const sai_vip_entry_t* vip_entry, + _In_ bool create, + _In_ bool get = false); + + sai_status_t meta_sai_validate_inbound_routing_entry( + _In_ const sai_inbound_routing_entry_t* inbound_routing_entry, + _In_ bool create, + _In_ bool get = false); + + sai_status_t meta_sai_validate_pa_validation_entry( + _In_ const sai_pa_validation_entry_t* pa_validation_entry, + _In_ bool create, + _In_ bool get = false); + + sai_status_t meta_sai_validate_outbound_routing_entry( + _In_ const sai_outbound_routing_entry_t* outbound_routing_entry, + _In_ bool create, + _In_ bool get = false); + + sai_status_t meta_sai_validate_outbound_ca_to_pa_entry( + _In_ const sai_outbound_ca_to_pa_entry_t* outbound_ca_to_pa_entry, + _In_ bool create, + _In_ bool get = false); + public: /* diff --git a/meta/MetaKeyHasher.cpp b/meta/MetaKeyHasher.cpp index cebdd67ed..61247c39c 100644 --- a/meta/MetaKeyHasher.cpp +++ b/meta/MetaKeyHasher.cpp @@ -4,9 +4,55 @@ #include "swss/logger.h" #include +#include using namespace saimeta; +static bool operator==( + _In_ const sai_ip_address_t& a, + _In_ const sai_ip_address_t& b) +{ + if (a.addr_family != b.addr_family) + { + return false; + } + + if (a.addr_family == SAI_IP_ADDR_FAMILY_IPV4) + { + return a.addr.ip4 == b.addr.ip4; + } + + if (a.addr_family == SAI_IP_ADDR_FAMILY_IPV6) + { + return memcmp(a.addr.ip6, b.addr.ip6, sizeof(a.addr.ip6)) == 0; + } + + SWSS_LOG_THROW("unknown IP addr family= %d", a.addr_family); +} + +static bool operator==( + _In_ const sai_ip_prefix_t& a, + _In_ const sai_ip_prefix_t& b) +{ + if (a.addr_family != b.addr_family) + { + return false; + } + + if (a.addr_family == SAI_IP_ADDR_FAMILY_IPV4) + { + return a.addr.ip4 == b.addr.ip4 && a.mask.ip4 == b.mask.ip4; + } + + if (a.addr_family == SAI_IP_ADDR_FAMILY_IPV6) + { + return memcmp(a.addr.ip6, b.addr.ip6, sizeof(a.addr.ip6)) == 0 && + memcmp(a.mask.ip6, b.mask.ip6, sizeof(a.mask.ip6)) == 0; + } + + SWSS_LOG_THROW("unknown IP addr family= %d", a.addr_family); +} + static bool operator==( _In_ const sai_fdb_entry_t& a, _In_ const sai_fdb_entry_t& b) @@ -207,6 +253,74 @@ static bool operator==( return part && memcmp(a.sid, b.sid, sizeof(a.sid)) == 0; } +static bool operator==( + _In_ const sai_direction_lookup_entry_t& a, + _In_ const sai_direction_lookup_entry_t& b) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + return a.switch_id == b.switch_id && a.vni == b.vni; +} + +static bool operator==( + _In_ const sai_eni_ether_address_map_entry_t& a, + _In_ const sai_eni_ether_address_map_entry_t& b) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + return a.switch_id == b.switch_id && memcmp(a.address, b.address, sizeof(a.address)) == 0; +} + +static bool operator==( + _In_ const sai_vip_entry_t& a, + _In_ const sai_vip_entry_t& b) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + return a.switch_id == b.switch_id && a.vip == b.vip; +} + +static bool operator==( + _In_ const sai_inbound_routing_entry_t& a, + _In_ const sai_inbound_routing_entry_t& b) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + return a.switch_id == b.switch_id && + a.eni_id == b.eni_id && + a.vni == b.vni && + a.sip == b.sip && + a.sip_mask == b.sip_mask && + a.priority == b.priority; +} + +static bool operator==( + _In_ const sai_pa_validation_entry_t& a, + _In_ const sai_pa_validation_entry_t& b) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + return a.switch_id == b.switch_id && a.vnet_id == b.vnet_id && a.sip == b.sip; +} + +static bool operator==( + _In_ const sai_outbound_routing_entry_t& a, + _In_ const sai_outbound_routing_entry_t& b) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + return a.switch_id == b.switch_id && a.eni_id == b.eni_id && a.destination == b.destination; +} + +static bool operator==( + _In_ const sai_outbound_ca_to_pa_entry_t& a, + _In_ const sai_outbound_ca_to_pa_entry_t& b) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + return a.switch_id == b.switch_id && a.dst_vnet_id == b.dst_vnet_id && a.dip == b.dip; +} + bool MetaKeyHasher::operator()( _In_ const sai_object_meta_key_t& a, _In_ const sai_object_meta_key_t& b) const @@ -248,6 +362,26 @@ bool MetaKeyHasher::operator()( if (a.objecttype == SAI_OBJECT_TYPE_IPMC_ENTRY) return a.objectkey.key.ipmc_entry == b.objectkey.key.ipmc_entry; + if ((sai_object_type_extensions_t)a.objecttype == SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY) + return a.objectkey.key.direction_lookup_entry == b.objectkey.key.direction_lookup_entry; + + if ((sai_object_type_extensions_t)a.objecttype == SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY) + return a.objectkey.key.eni_ether_address_map_entry == b.objectkey.key.eni_ether_address_map_entry; + + if ((sai_object_type_extensions_t)a.objecttype == SAI_OBJECT_TYPE_VIP_ENTRY) + return a.objectkey.key.vip_entry == b.objectkey.key.vip_entry; + + if ((sai_object_type_extensions_t)a.objecttype == SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY) + return a.objectkey.key.inbound_routing_entry == b.objectkey.key.inbound_routing_entry; + + if ((sai_object_type_extensions_t)a.objecttype == SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY) + return a.objectkey.key.pa_validation_entry == b.objectkey.key.pa_validation_entry; + + if ((sai_object_type_extensions_t)a.objecttype == SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY) + return a.objectkey.key.outbound_routing_entry == b.objectkey.key.outbound_routing_entry; + + if ((sai_object_type_extensions_t)a.objecttype == SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY) + return a.objectkey.key.outbound_ca_to_pa_entry == b.objectkey.key.outbound_ca_to_pa_entry; SWSS_LOG_THROW("not implemented: %s", sai_serialize_object_meta_key(a).c_str()); @@ -255,6 +389,69 @@ bool MetaKeyHasher::operator()( static_assert(sizeof(std::size_t) >= sizeof(uint32_t), "size_t must be at least 32 bits"); +static inline std::size_t sai_get_hash( + _In_ const sai_ip_address_t& addr) +{ + // SWSS_LOG_ENTER(); // disabled for performance reason + + size_t hash = 0; + + if (addr.addr_family == SAI_IP_ADDR_FAMILY_IPV4) + { + boost::hash_combine(hash, addr.addr.ip4); + + return hash; + } + else if (addr.addr_family == SAI_IP_ADDR_FAMILY_IPV6) + { + uint32_t ip6[4]; + memcpy(ip6, addr.addr.ip6, sizeof(ip6)); + boost::hash_combine(hash, ip6[0]); + boost::hash_combine(hash, ip6[1]); + boost::hash_combine(hash, ip6[2]); + boost::hash_combine(hash, ip6[3]); + + return hash; + } + + SWSS_LOG_THROW("unknown IP addr family: %d", addr.addr_family); +} + +static inline std::size_t sai_get_hash( + _In_ const sai_ip_prefix_t& prefix) +{ + // SWSS_LOG_ENTER(); // disabled for performance reason + + size_t hash = 0; + + if (prefix.addr_family == SAI_IP_ADDR_FAMILY_IPV4) + { + boost::hash_combine(hash, prefix.addr.ip4); + boost::hash_combine(hash, prefix.mask.ip4); + + return hash; + } + else if (prefix.addr_family == SAI_IP_ADDR_FAMILY_IPV6) + { + uint32_t ip6[4]; + memcpy(ip6, prefix.addr.ip6, sizeof(ip6)); + boost::hash_combine(hash, ip6[0]); + boost::hash_combine(hash, ip6[1]); + boost::hash_combine(hash, ip6[2]); + boost::hash_combine(hash, ip6[3]); + + memcpy(ip6, prefix.mask.ip6, sizeof(ip6)); + boost::hash_combine(hash, ip6[0]); + boost::hash_combine(hash, ip6[1]); + boost::hash_combine(hash, ip6[2]); + boost::hash_combine(hash, ip6[3]); + + return hash; + } + + SWSS_LOG_THROW("unknown IP addr family: %d", prefix.addr_family); +} + static inline std::size_t sai_get_hash( _In_ const sai_route_entry_t& re) { @@ -402,6 +599,98 @@ static inline std::size_t sai_get_hash( SWSS_LOG_THROW("unknown ipmc entry IP addr family: %d", ie.destination.addr_family); } +static inline std::size_t sai_get_hash( + _In_ const sai_direction_lookup_entry_t& de) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + size_t hash = 0; + boost::hash_combine(hash, de.vni); + + return hash; +} + +static inline std::size_t sai_get_hash( + _In_ const sai_eni_ether_address_map_entry_t & ee) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + std::size_t hash = 0; + + boost::hash_combine(hash, ee.address[0]); + boost::hash_combine(hash, ee.address[1]); + boost::hash_combine(hash, ee.address[2]); + boost::hash_combine(hash, ee.address[3]); + boost::hash_combine(hash, ee.address[4]); + boost::hash_combine(hash, ee.address[5]); + + return hash; +} + +static inline std::size_t sai_get_hash( + _In_ const sai_vip_entry_t & ve) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + std::size_t hash = 0; + + boost::hash_combine(hash, sai_get_hash(ve.vip)); + + return hash; +} + +static inline std::size_t sai_get_hash( + _In_ const sai_inbound_routing_entry_t & re) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + size_t hash = 0; + boost::hash_combine(hash, sai_get_hash(re.sip)); + boost::hash_combine(hash, sai_get_hash(re.sip_mask)); + boost::hash_combine(hash, re.eni_id); + boost::hash_combine(hash, re.vni); + boost::hash_combine(hash, re.priority); + + return hash; +} + +static inline std::size_t sai_get_hash( + _In_ const sai_pa_validation_entry_t & pe) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + std::size_t hash = 0; + + boost::hash_combine(hash, pe.vnet_id); + boost::hash_combine(hash, sai_get_hash(pe.sip)); + + return hash; +} + +static inline std::size_t sai_get_hash( + _In_ const sai_outbound_routing_entry_t & oe) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + std::size_t hash = 0; + boost::hash_combine(hash, oe.eni_id); + boost::hash_combine(hash, sai_get_hash(oe.destination)); + + return hash; +} + +static inline std::size_t sai_get_hash( + _In_ const sai_outbound_ca_to_pa_entry_t & oe) +{ + // SWSS_LOG_ENTER(); // disabled for performance reasons + + std::size_t hash = 0; + boost::hash_combine(hash, oe.dst_vnet_id); + boost::hash_combine(hash, sai_get_hash(oe.dip)); + + return hash; +} + std::size_t MetaKeyHasher::operator()( _In_ const sai_object_meta_key_t& k) const { @@ -443,6 +732,33 @@ std::size_t MetaKeyHasher::operator()( case SAI_OBJECT_TYPE_IPMC_ENTRY: return sai_get_hash(k.objectkey.key.ipmc_entry); + default: + // Do nothing. Go to extensions + break; + } + + switch ((sai_object_type_extensions_t)k.objecttype) + { + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + return sai_get_hash(k.objectkey.key.direction_lookup_entry); + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + return sai_get_hash(k.objectkey.key.eni_ether_address_map_entry); + + case SAI_OBJECT_TYPE_VIP_ENTRY: + return sai_get_hash(k.objectkey.key.vip_entry); + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + return sai_get_hash(k.objectkey.key.inbound_routing_entry); + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + return sai_get_hash(k.objectkey.key.pa_validation_entry); + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + return sai_get_hash(k.objectkey.key.outbound_routing_entry); + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + return sai_get_hash(k.objectkey.key.outbound_ca_to_pa_entry); default: SWSS_LOG_THROW("not handled: %s", sai_serialize_object_type(k.objecttype).c_str()); diff --git a/meta/MetaTestSaiInterface.cpp b/meta/MetaTestSaiInterface.cpp index 84b3c8639..25c3c3228 100644 --- a/meta/MetaTestSaiInterface.cpp +++ b/meta/MetaTestSaiInterface.cpp @@ -71,6 +71,26 @@ sai_status_t MetaTestSaiInterface::create( return SAI_STATUS_SUCCESS; } +sai_status_t MetaTestSaiInterface::bulkCreate( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t switch_id, + _In_ uint32_t object_count, + _In_ const uint32_t *attr_count, + _In_ const sai_attribute_t **attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_object_id_t *object_id, + _Out_ sai_status_t *object_statuses) +{ + SWSS_LOG_ENTER(); + + for (uint32_t idx = 0; idx < object_count; ++idx) + { + object_statuses[idx] = create(object_type, &object_id[idx], switch_id, attr_count[idx], attr_list[idx]); + } + + return SAI_STATUS_SUCCESS; +} + sai_object_type_t MetaTestSaiInterface::objectTypeQuery( _In_ sai_object_id_t objectId) { diff --git a/meta/MetaTestSaiInterface.h b/meta/MetaTestSaiInterface.h index 0594bbad6..0dbd52f77 100644 --- a/meta/MetaTestSaiInterface.h +++ b/meta/MetaTestSaiInterface.h @@ -26,6 +26,16 @@ namespace saimeta _In_ uint32_t attr_count, _In_ const sai_attribute_t *attr_list) override; + virtual sai_status_t bulkCreate( + _In_ sai_object_type_t object_type, + _In_ sai_object_id_t switch_id, + _In_ uint32_t object_count, + _In_ const uint32_t *attr_count, + _In_ const sai_attribute_t **attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_object_id_t *object_id, + _Out_ sai_status_t *object_statuses) override; + public: virtual sai_object_type_t objectTypeQuery( diff --git a/meta/SaiInterface.cpp b/meta/SaiInterface.cpp index b268f7890..538896a6b 100644 --- a/meta/SaiInterface.cpp +++ b/meta/SaiInterface.cpp @@ -26,7 +26,7 @@ sai_status_t SaiInterface::create( return create(metaKey.objecttype, &metaKey.objectkey.key.object_id, switch_id, attr_count, attr_list); } - switch (info->objecttype) + switch ((int)info->objecttype) { case SAI_OBJECT_TYPE_FDB_ENTRY: return create(&metaKey.objectkey.key.fdb_entry, attr_count, attr_list); @@ -46,6 +46,27 @@ sai_status_t SaiInterface::create( case SAI_OBJECT_TYPE_MY_SID_ENTRY: return create(&metaKey.objectkey.key.my_sid_entry, attr_count, attr_list); + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + return create(&metaKey.objectkey.key.direction_lookup_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + return create(&metaKey.objectkey.key.eni_ether_address_map_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_VIP_ENTRY: + return create(&metaKey.objectkey.key.vip_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + return create(&metaKey.objectkey.key.inbound_routing_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + return create(&metaKey.objectkey.key.pa_validation_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + return create(&metaKey.objectkey.key.outbound_routing_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + return create(&metaKey.objectkey.key.outbound_ca_to_pa_entry, attr_count, attr_list); + default: SWSS_LOG_ERROR("object type %s not implemented, FIXME", info->objecttypename); @@ -73,7 +94,7 @@ sai_status_t SaiInterface::remove( return remove(metaKey.objecttype, metaKey.objectkey.key.object_id); } - switch (info->objecttype) + switch ((int)info->objecttype) { case SAI_OBJECT_TYPE_FDB_ENTRY: return remove(&metaKey.objectkey.key.fdb_entry); @@ -93,6 +114,27 @@ sai_status_t SaiInterface::remove( case SAI_OBJECT_TYPE_MY_SID_ENTRY: return remove(&metaKey.objectkey.key.my_sid_entry); + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + return remove(&metaKey.objectkey.key.direction_lookup_entry); + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + return remove(&metaKey.objectkey.key.eni_ether_address_map_entry); + + case SAI_OBJECT_TYPE_VIP_ENTRY: + return remove(&metaKey.objectkey.key.vip_entry); + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + return remove(&metaKey.objectkey.key.inbound_routing_entry); + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + return remove(&metaKey.objectkey.key.pa_validation_entry); + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + return remove(&metaKey.objectkey.key.outbound_routing_entry); + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + return remove(&metaKey.objectkey.key.outbound_ca_to_pa_entry); + default: SWSS_LOG_ERROR("object type %s not implemented, FIXME", info->objecttypename); @@ -121,7 +163,7 @@ sai_status_t SaiInterface::set( return set(metaKey.objecttype, metaKey.objectkey.key.object_id, attr); } - switch (info->objecttype) + switch ((int)info->objecttype) { case SAI_OBJECT_TYPE_FDB_ENTRY: return set(&metaKey.objectkey.key.fdb_entry, attr); @@ -141,6 +183,27 @@ sai_status_t SaiInterface::set( case SAI_OBJECT_TYPE_MY_SID_ENTRY: return set(&metaKey.objectkey.key.my_sid_entry, attr); + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + return set(&metaKey.objectkey.key.direction_lookup_entry, attr); + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + return set(&metaKey.objectkey.key.eni_ether_address_map_entry, attr); + + case SAI_OBJECT_TYPE_VIP_ENTRY: + return set(&metaKey.objectkey.key.vip_entry, attr); + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + return set(&metaKey.objectkey.key.inbound_routing_entry, attr); + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + return set(&metaKey.objectkey.key.pa_validation_entry, attr); + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + return set(&metaKey.objectkey.key.outbound_routing_entry, attr); + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + return set(&metaKey.objectkey.key.outbound_ca_to_pa_entry, attr); + default: SWSS_LOG_ERROR("object type %s not implemented, FIXME", info->objecttypename); @@ -170,7 +233,7 @@ sai_status_t SaiInterface::get( return get(metaKey.objecttype, metaKey.objectkey.key.object_id, attr_count, attr_list); } - switch (info->objecttype) + switch ((int)info->objecttype) { case SAI_OBJECT_TYPE_FDB_ENTRY: return get(&metaKey.objectkey.key.fdb_entry, attr_count, attr_list); @@ -190,6 +253,27 @@ sai_status_t SaiInterface::get( case SAI_OBJECT_TYPE_MY_SID_ENTRY: return get(&metaKey.objectkey.key.my_sid_entry, attr_count, attr_list); + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + return get(&metaKey.objectkey.key.direction_lookup_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + return get(&metaKey.objectkey.key.eni_ether_address_map_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_VIP_ENTRY: + return get(&metaKey.objectkey.key.vip_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + return get(&metaKey.objectkey.key.inbound_routing_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + return get(&metaKey.objectkey.key.pa_validation_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + return get(&metaKey.objectkey.key.outbound_routing_entry, attr_count, attr_list); + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + return get(&metaKey.objectkey.key.outbound_ca_to_pa_entry, attr_count, attr_list); + default: SWSS_LOG_ERROR("object type %s not implemented, FIXME", info->objecttypename); diff --git a/meta/SaiInterface.h b/meta/SaiInterface.h index 114f8bae6..ba9b16e9a 100644 --- a/meta/SaiInterface.h +++ b/meta/SaiInterface.h @@ -5,24 +5,38 @@ extern "C" { #include "saimetadata.h" } -#define SAIREDIS_DECLARE_EVERY_ENTRY(_X) \ - _X(FDB_ENTRY,fdb_entry); \ - _X(INSEG_ENTRY,inseg_entry); \ - _X(IPMC_ENTRY,ipmc_entry); \ - _X(L2MC_ENTRY,l2mc_entry); \ - _X(MCAST_FDB_ENTRY,mcast_fdb_entry); \ - _X(NEIGHBOR_ENTRY,neighbor_entry); \ - _X(ROUTE_ENTRY,route_entry); \ - _X(NAT_ENTRY,nat_entry); \ - _X(MY_SID_ENTRY,my_sid_entry); \ - -#define SAIREDIS_DECLARE_EVERY_BULK_ENTRY(_X) \ - _X(FDB_ENTRY,fdb_entry); \ - _X(INSEG_ENTRY,inseg_entry); \ - _X(NAT_ENTRY,nat_entry); \ - _X(ROUTE_ENTRY,route_entry); \ - _X(MY_SID_ENTRY,my_sid_entry); \ - _X(NEIGHBOR_ENTRY,neighbor_entry); \ +#define SAIREDIS_DECLARE_EVERY_ENTRY(_X) \ + _X(FDB_ENTRY,fdb_entry); \ + _X(INSEG_ENTRY,inseg_entry); \ + _X(IPMC_ENTRY,ipmc_entry); \ + _X(L2MC_ENTRY,l2mc_entry); \ + _X(MCAST_FDB_ENTRY,mcast_fdb_entry); \ + _X(NEIGHBOR_ENTRY,neighbor_entry); \ + _X(ROUTE_ENTRY,route_entry); \ + _X(NAT_ENTRY,nat_entry); \ + _X(MY_SID_ENTRY,my_sid_entry); \ + _X(DIRECTION_LOOKUP_ENTRY,direction_lookup_entry); \ + _X(ENI_ETHER_ADDRESS_MAP_ENTRY,eni_ether_address_map_entry); \ + _X(VIP_ENTRY,vip_entry); \ + _X(INBOUND_ROUTING_ENTRY,inbound_routing_entry); \ + _X(PA_VALIDATION_ENTRY,pa_validation_entry); \ + _X(OUTBOUND_ROUTING_ENTRY,outbound_routing_entry); \ + _X(OUTBOUND_CA_TO_PA_ENTRY,outbound_ca_to_pa_entry); \ + +#define SAIREDIS_DECLARE_EVERY_BULK_ENTRY(_X) \ + _X(FDB_ENTRY,fdb_entry); \ + _X(INSEG_ENTRY,inseg_entry); \ + _X(NAT_ENTRY,nat_entry); \ + _X(ROUTE_ENTRY,route_entry); \ + _X(MY_SID_ENTRY,my_sid_entry); \ + _X(NEIGHBOR_ENTRY,neighbor_entry); \ + _X(DIRECTION_LOOKUP_ENTRY,direction_lookup_entry); \ + _X(ENI_ETHER_ADDRESS_MAP_ENTRY,eni_ether_address_map_entry); \ + _X(VIP_ENTRY,vip_entry); \ + _X(INBOUND_ROUTING_ENTRY,inbound_routing_entry); \ + _X(PA_VALIDATION_ENTRY,pa_validation_entry); \ + _X(OUTBOUND_ROUTING_ENTRY,outbound_routing_entry); \ + _X(OUTBOUND_CA_TO_PA_ENTRY,outbound_ca_to_pa_entry); \ #define SAIREDIS_SAIINTERFACE_DECLARE_QUAD_ENTRY_VIRTUAL(OT,ot) \ virtual sai_status_t create( \ diff --git a/meta/SaiSerialize.cpp b/meta/SaiSerialize.cpp index 37316c010..7b865360d 100644 --- a/meta/SaiSerialize.cpp +++ b/meta/SaiSerialize.cpp @@ -241,6 +241,10 @@ sai_status_t transfer_attribute( // transfer_primitive(src_attr.value.s32range, dst_attr.value.s32range); // break; + case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST: + RETURN_ON_ERROR(transfer_list(src_attr.value.u16rangelist, dst_attr.value.u16rangelist, countOnly)); + break; + case SAI_ATTR_VALUE_TYPE_TIMESPEC: transfer_primitive(src_attr.value.timespec, dst_attr.value.timespec); break; @@ -484,6 +488,10 @@ sai_status_t transfer_attribute( RETURN_ON_ERROR(transfer_list(src_attr.value.sysportconfiglist, dst_attr.value.sysportconfiglist, countOnly)); break; + case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST: + RETURN_ON_ERROR(transfer_list(src_attr.value.ipprefixlist, dst_attr.value.ipprefixlist, countOnly)); + break; + default: SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(serialization_type).c_str()); } @@ -1233,6 +1241,15 @@ std::string sai_serialize_ip_address_list( return sai_serialize_list(list, countOnly, [&](sai_ip_address_t item) { return sai_serialize_ip_address(item);} ); } +std::string sai_serialize_ip_prefix_list( + _In_ const sai_ip_prefix_list_t& list, + _In_ bool countOnly) +{ + SWSS_LOG_ENTER(); + + return sai_serialize_list(list, countOnly, [&](sai_ip_prefix_t item) { return sai_serialize_ip_prefix(item);} ); +} + std::string sai_serialize_enum_list( _In_ const sai_s32_list_t& list, _In_ const sai_enum_metadata_t* meta, @@ -1492,6 +1509,15 @@ std::string sai_serialize_range( return sai_serialize_number(range.min) + "," + sai_serialize_number(range.max); } +std::string sai_serialize_u16_range_list( + _In_ const sai_u16_range_list_t& list, + _In_ bool countOnly) +{ + SWSS_LOG_ENTER(); + + return sai_serialize_list(list, countOnly, [&](sai_u16_range_t item) { return sai_serialize_range(item);} ); +} + std::string sai_serialize_acl_action( _In_ const sai_attr_metadata_t& meta, _In_ const sai_acl_action_data_t& action, @@ -1653,6 +1679,104 @@ std::string sai_serialize_hex_binary( return s; } +std::string sai_serialize_direction_lookup_entry( + _In_ const sai_direction_lookup_entry_t &direction_lookup_entry) +{ + SWSS_LOG_ENTER(); + + json j; + + j["switch_id"] = sai_serialize_object_id(direction_lookup_entry.switch_id); + j["vni"] = sai_serialize_number(direction_lookup_entry.vni); + + return j.dump(); +} + +std::string sai_serialize_eni_ether_address_map_entry( + _In_ const sai_eni_ether_address_map_entry_t &eni_ether_address_map_entry) +{ + SWSS_LOG_ENTER(); + + json j; + + j["switch_id"] = sai_serialize_object_id(eni_ether_address_map_entry.switch_id); + j["address"] = sai_serialize_mac(eni_ether_address_map_entry.address); + + return j.dump(); +} + +std::string sai_serialize_vip_entry( + _In_ const sai_vip_entry_t &vip_entry) +{ + SWSS_LOG_ENTER(); + + json j; + + j["switch_id"] = sai_serialize_object_id(vip_entry.switch_id); + j["vip"] = sai_serialize_ip_address(vip_entry.vip); + + return j.dump(); +} + +std::string sai_serialize_inbound_routing_entry( + _In_ const sai_inbound_routing_entry_t &inbound_routing_entry) +{ + SWSS_LOG_ENTER(); + + json j; + + j["switch_id"] = sai_serialize_object_id(inbound_routing_entry.switch_id); + j["eni_id"] = sai_serialize_object_id(inbound_routing_entry.eni_id); + j["vni"] = sai_serialize_number(inbound_routing_entry.vni); + j["sip"] = sai_serialize_ip_address(inbound_routing_entry.sip); + j["sip_mask"] = sai_serialize_ip_address(inbound_routing_entry.sip_mask); + j["priority"] = sai_serialize_number(inbound_routing_entry.priority); + + return j.dump(); +} + +std::string sai_serialize_pa_validation_entry( + _In_ const sai_pa_validation_entry_t &pa_validation_entry) +{ + SWSS_LOG_ENTER(); + + json j; + + j["switch_id"] = sai_serialize_object_id(pa_validation_entry.switch_id); + j["vnet_id"] = sai_serialize_object_id(pa_validation_entry.vnet_id); + j["sip"] = sai_serialize_ip_address(pa_validation_entry.sip); + + return j.dump(); +} + +std::string sai_serialize_outbound_routing_entry( + _In_ const sai_outbound_routing_entry_t &outbound_routing_entry) +{ + SWSS_LOG_ENTER(); + + json j; + + j["switch_id"] = sai_serialize_object_id(outbound_routing_entry.switch_id); + j["eni_id"] = sai_serialize_object_id(outbound_routing_entry.eni_id); + j["destination"] = sai_serialize_ip_prefix(outbound_routing_entry.destination); + + return j.dump(); +} + +std::string sai_serialize_outbound_ca_to_pa_entry( + _In_ const sai_outbound_ca_to_pa_entry_t &outbound_ca_to_pa_entry) +{ + SWSS_LOG_ENTER(); + + json j; + + j["switch_id"] = sai_serialize_object_id(outbound_ca_to_pa_entry.switch_id); + j["dst_vnet_id"] = sai_serialize_object_id(outbound_ca_to_pa_entry.dst_vnet_id); + j["dip"] = sai_serialize_ip_address(outbound_ca_to_pa_entry.dip); + + return j.dump(); +} + std::string sai_serialize_system_port_config( _In_ const sai_attr_metadata_t &meta, _In_ const sai_system_port_config_t &sysportconfig) @@ -1861,6 +1985,9 @@ std::string sai_serialize_attr_value( // case SAI_ATTR_VALUE_TYPE_INT32_RANGE: // return sai_serialize_range(attr.value.s32range); + case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST: + return sai_serialize_u16_range_list(attr.value.u16rangelist, countOnly); + case SAI_ATTR_VALUE_TYPE_VLAN_LIST: return sai_serialize_number_list(attr.value.vlanlist, countOnly); @@ -1940,6 +2067,9 @@ std::string sai_serialize_attr_value( case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG_LIST: return sai_serialize_system_port_config_list(meta, attr.value.sysportconfiglist, countOnly); + case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST: + return sai_serialize_ip_prefix_list(attr.value.ipprefixlist, countOnly); + default: SWSS_LOG_THROW("sai attr value type %s is not implemented, FIXME", sai_serialize_attr_value_type(meta.attrvaluetype).c_str()); } @@ -2272,68 +2402,121 @@ std::string sai_serialize_my_sid_entry( return j.dump(); } -std::string sai_serialize_object_meta_key( - _In_ const sai_object_meta_key_t& meta_key) +static bool sai_serialize_object_entry( + _In_ const sai_object_type_t objecttype, + _In_ const sai_object_key_entry_t& key_entry, + _Out_ std::string& key) { SWSS_LOG_ENTER(); - std::string key; - - if (!sai_metadata_is_object_type_valid(meta_key.objecttype)) - { - SWSS_LOG_THROW("invalid object type value %s", sai_serialize_object_type(meta_key.objecttype).c_str()); - } - - const auto& meta = sai_metadata_get_object_type_info(meta_key.objecttype); - - switch (meta_key.objecttype) + switch (objecttype) { case SAI_OBJECT_TYPE_FDB_ENTRY: - key = sai_serialize_fdb_entry(meta_key.objectkey.key.fdb_entry); - break; + key = sai_serialize_fdb_entry(key_entry.fdb_entry); + return true; case SAI_OBJECT_TYPE_ROUTE_ENTRY: - key = sai_serialize_route_entry(meta_key.objectkey.key.route_entry); - break; + key = sai_serialize_route_entry(key_entry.route_entry); + return true; case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY: - key = sai_serialize_neighbor_entry(meta_key.objectkey.key.neighbor_entry); - break; + key = sai_serialize_neighbor_entry(key_entry.neighbor_entry); + return true; case SAI_OBJECT_TYPE_NAT_ENTRY: - key = sai_serialize_nat_entry(meta_key.objectkey.key.nat_entry); - break; + key = sai_serialize_nat_entry(key_entry.nat_entry); + return true; case SAI_OBJECT_TYPE_INSEG_ENTRY: - key = sai_serialize_inseg_entry(meta_key.objectkey.key.inseg_entry); - break; + key = sai_serialize_inseg_entry(key_entry.inseg_entry); + return true; case SAI_OBJECT_TYPE_MY_SID_ENTRY: - key = sai_serialize_my_sid_entry(meta_key.objectkey.key.my_sid_entry); - break; + key = sai_serialize_my_sid_entry(key_entry.my_sid_entry); + return true; case SAI_OBJECT_TYPE_L2MC_ENTRY: - key = sai_serialize_l2mc_entry(meta_key.objectkey.key.l2mc_entry); - break; + key = sai_serialize_l2mc_entry(key_entry.l2mc_entry); + return true; case SAI_OBJECT_TYPE_IPMC_ENTRY: - key = sai_serialize_ipmc_entry(meta_key.objectkey.key.ipmc_entry); - break; + key = sai_serialize_ipmc_entry(key_entry.ipmc_entry); + return true; case SAI_OBJECT_TYPE_MCAST_FDB_ENTRY: - key = sai_serialize_mcast_fdb_entry(meta_key.objectkey.key.mcast_fdb_entry); - break; + key = sai_serialize_mcast_fdb_entry(key_entry.mcast_fdb_entry); + return true; default: + return false; + } +} - if (meta->isnonobjectid) - { - SWSS_LOG_THROW("object %s is non object id, not supported yet, FIXME", - sai_serialize_object_type(meta->objecttype).c_str()); - } +static bool sai_serialize_object_extension_entry( + _In_ const sai_object_type_extensions_t objecttype, + _In_ const sai_object_key_entry_t& key_entry, + _Out_ std::string& key) +{ + SWSS_LOG_ENTER(); - key = sai_serialize_object_id(meta_key.objectkey.key.object_id); - break; + switch (objecttype) + { + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + key = sai_serialize_direction_lookup_entry(key_entry.direction_lookup_entry); + return true; + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + key = sai_serialize_eni_ether_address_map_entry(key_entry.eni_ether_address_map_entry); + return true; + + case SAI_OBJECT_TYPE_VIP_ENTRY: + key = sai_serialize_vip_entry(key_entry.vip_entry); + return true; + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + key = sai_serialize_inbound_routing_entry(key_entry.inbound_routing_entry); + return true; + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + key = sai_serialize_pa_validation_entry(key_entry.pa_validation_entry); + return true; + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + key = sai_serialize_outbound_routing_entry(key_entry.outbound_routing_entry); + return true; + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + key = sai_serialize_outbound_ca_to_pa_entry(key_entry.outbound_ca_to_pa_entry); + return true; + + default: + return false; + } +} + +std::string sai_serialize_object_meta_key( + _In_ const sai_object_meta_key_t& meta_key) +{ + SWSS_LOG_ENTER(); + + std::string key; + + if (!sai_metadata_is_object_type_valid(meta_key.objecttype)) + { + SWSS_LOG_THROW("invalid object type value %s", sai_serialize_object_type(meta_key.objecttype).c_str()); + } + + if (!sai_serialize_object_entry(meta_key.objecttype, meta_key.objectkey.key, key) && + !sai_serialize_object_extension_entry((sai_object_type_extensions_t)meta_key.objecttype, meta_key.objectkey.key, key)) + { + const auto& meta = sai_metadata_get_object_type_info(meta_key.objecttype); + if (meta->isnonobjectid) + { + SWSS_LOG_THROW("object %s is non object id, not supported yet, FIXME", + sai_serialize_object_type(meta->objecttype).c_str()); + } + + key = sai_serialize_object_id(meta_key.objectkey.key.object_id); } key = sai_serialize_object_type(meta_key.objecttype) + ":" + key; @@ -2987,6 +3170,16 @@ void sai_deserialize_ip_address_list( sai_deserialize_list(s, list, countOnly, [&](const std::string sitem, sai_ip_address_t& item) { sai_deserialize_ip_address(sitem, item);} ); } +void sai_deserialize_ip_prefix_list( + _In_ const std::string& s, + _Out_ sai_ip_prefix_list_t& list, + _In_ bool countOnly) +{ + SWSS_LOG_ENTER(); + + sai_deserialize_list(s, list, countOnly, [&](const std::string sitem, sai_ip_prefix_t& item) { sai_deserialize_ip_prefix(sitem, item);} ); +} + void sai_deserialize_segment_list( _In_ const std::string& s, _Out_ sai_segment_list_t& list, @@ -3052,6 +3245,56 @@ void sai_deserialize_range( sai_deserialize_number(tokens[1], range.max); } +void sai_deserialize_u16_range_list( + _In_ const std::string& s, + _Out_ sai_u16_range_list_t& list, + _In_ bool countOnly) +{ + SWSS_LOG_ENTER(); + + if (countOnly) + { + sai_deserialize_number(s, list.count); + return; + } + + auto pos = s.find(":"); + + if (pos == std::string::npos) + { + SWSS_LOG_THROW("invalid list %s", s.c_str()); + } + + std::string scount = s.substr(0, pos); + + sai_deserialize_number(scount, list.count); + + std::string slist = s.substr(pos + 1); + + if (slist == "null") + { + list.list = NULL; + return; + } + + auto tokens = swss::tokenize(slist, ','); + + if (tokens.size() != list.count * 2) + { + SWSS_LOG_THROW("invalid u16_range_list count %lu != %u", tokens.size(), list.count * 2); + } + + list.list = sai_alloc_n_of_ptr_type(list.count, list.list); + + for (uint32_t i = 0; i < list.count * 2; i+=2) + { + std::ostringstream range; + range << tokens[i] << "," << tokens[i+1]; + + sai_deserialize_range(range.str(), list.list[i/2]); + } +} + void sai_deserialize_acl_field( _In_ const std::string& s, _In_ const sai_attr_metadata_t& meta, @@ -3533,6 +3776,9 @@ void sai_deserialize_attr_value( // case SAI_ATTR_VALUE_TYPE_INT32_RANGE: // return sai_deserialize_range(s, attr.value.s32range); + case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST: + return sai_deserialize_u16_range_list(s, attr.value.u16rangelist, countOnly); + case SAI_ATTR_VALUE_TYPE_VLAN_LIST: return sai_deserialize_number_list(s, attr.value.vlanlist, countOnly); @@ -3610,6 +3856,9 @@ void sai_deserialize_attr_value( case SAI_ATTR_VALUE_TYPE_SYSTEM_PORT_CONFIG_LIST: return sai_deserialize_system_port_config_list(s, attr.value.sysportconfiglist, countOnly); + case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST: + return sai_deserialize_ip_prefix_list(s, attr.value.ipprefixlist, countOnly); + default: SWSS_LOG_THROW("deserialize type %d is not supported yet FIXME", meta.attrvaluetype); } @@ -3977,6 +4226,97 @@ void sai_deserialize_mcast_fdb_entry( sai_deserialize_mac(j["mac_address"], mcast_fdb_entry.mac_address); } +void sai_deserialize_direction_lookup_entry( + _In_ const std::string &s, + _Out_ sai_direction_lookup_entry_t& direction_lookup_entry) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + sai_deserialize_object_id(j["switch_id"], direction_lookup_entry.switch_id); + sai_deserialize_number(j["vni"], direction_lookup_entry.vni); +} + +void sai_deserialize_eni_ether_address_map_entry( + _In_ const std::string &s, + _Out_ sai_eni_ether_address_map_entry_t& eni_ether_address_map_entry) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + sai_deserialize_object_id(j["switch_id"], eni_ether_address_map_entry.switch_id); + sai_deserialize_mac(j["address"], eni_ether_address_map_entry.address); +} + +void sai_deserialize_vip_entry( + _In_ const std::string &s, + _Out_ sai_vip_entry_t& vip_entry) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + sai_deserialize_object_id(j["switch_id"], vip_entry.switch_id); + sai_deserialize_ip_address(j["vip"], vip_entry.vip); +} + +void sai_deserialize_inbound_routing_entry( + _In_ const std::string &s, + _Out_ sai_inbound_routing_entry_t& inbound_routing_entry) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + sai_deserialize_object_id(j["switch_id"], inbound_routing_entry.switch_id); + sai_deserialize_object_id(j["eni_id"], inbound_routing_entry.eni_id); + sai_deserialize_number(j["vni"], inbound_routing_entry.vni); + sai_deserialize_ip_address(j["sip"], inbound_routing_entry.sip); + sai_deserialize_ip_address(j["sip_mask"], inbound_routing_entry.sip_mask); + sai_deserialize_number(j["priority"], inbound_routing_entry.priority); +} + +void sai_deserialize_pa_validation_entry( + _In_ const std::string &s, + _Out_ sai_pa_validation_entry_t& pa_validation_entry) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + sai_deserialize_object_id(j["switch_id"], pa_validation_entry.switch_id); + sai_deserialize_object_id(j["vnet_id"], pa_validation_entry.vnet_id); + sai_deserialize_ip_address(j["sip"], pa_validation_entry.sip); +} + +void sai_deserialize_outbound_routing_entry( + _In_ const std::string &s, + _Out_ sai_outbound_routing_entry_t& outbound_routing_entry) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + sai_deserialize_object_id(j["switch_id"], outbound_routing_entry.switch_id); + sai_deserialize_object_id(j["eni_id"], outbound_routing_entry.eni_id); + sai_deserialize_ip_prefix(j["destination"], outbound_routing_entry.destination); +} + +void sai_deserialize_outbound_ca_to_pa_entry( + _In_ const std::string &s, + _Out_ sai_outbound_ca_to_pa_entry_t& outbound_ca_to_pa_entry) +{ + SWSS_LOG_ENTER(); + + json j = json::parse(s); + + sai_deserialize_object_id(j["switch_id"], outbound_ca_to_pa_entry.switch_id); + sai_deserialize_object_id(j["dst_vnet_id"], outbound_ca_to_pa_entry.dst_vnet_id); + sai_deserialize_ip_address(j["dip"], outbound_ca_to_pa_entry.dip); +} + void sai_deserialize_attr_id( _In_ const std::string& s, _Out_ const sai_attr_metadata_t** meta) @@ -4017,74 +4357,126 @@ void sai_deserialize_attr_id( attrid = meta->attrid; } -void sai_deserialize_object_meta_key( - _In_ const std::string &s, - _Out_ sai_object_meta_key_t& meta_key) +bool sai_deserialize_object_entry( + _In_ const std::string object_id, + _Inout_ sai_object_meta_key_t& meta_key) { SWSS_LOG_ENTER(); - SWSS_LOG_DEBUG("%s", s.c_str()); - - const std::string &str_object_type = s.substr(0, s.find(":")); - const std::string &str_object_id = s.substr(s.find(":") + 1); - - sai_deserialize_object_type(str_object_type, meta_key.objecttype); - - if (!sai_metadata_is_object_type_valid(meta_key.objecttype)) - { - SWSS_LOG_THROW("invalid object type value %s", sai_serialize_object_type(meta_key.objecttype).c_str()); - } - - const auto& meta = sai_metadata_get_object_type_info(meta_key.objecttype); - switch (meta_key.objecttype) { case SAI_OBJECT_TYPE_FDB_ENTRY: - sai_deserialize_fdb_entry(str_object_id, meta_key.objectkey.key.fdb_entry); - break; + sai_deserialize_fdb_entry(object_id, meta_key.objectkey.key.fdb_entry); + return true; case SAI_OBJECT_TYPE_ROUTE_ENTRY: - sai_deserialize_route_entry(str_object_id, meta_key.objectkey.key.route_entry); - break; + sai_deserialize_route_entry(object_id, meta_key.objectkey.key.route_entry); + return true; case SAI_OBJECT_TYPE_NEIGHBOR_ENTRY: - sai_deserialize_neighbor_entry(str_object_id, meta_key.objectkey.key.neighbor_entry); - break; + sai_deserialize_neighbor_entry(object_id, meta_key.objectkey.key.neighbor_entry); + return true; case SAI_OBJECT_TYPE_NAT_ENTRY: - sai_deserialize_nat_entry(str_object_id, meta_key.objectkey.key.nat_entry); - break; + sai_deserialize_nat_entry(object_id, meta_key.objectkey.key.nat_entry); + return true; case SAI_OBJECT_TYPE_INSEG_ENTRY: - sai_deserialize_inseg_entry(str_object_id, meta_key.objectkey.key.inseg_entry); - break; + sai_deserialize_inseg_entry(object_id, meta_key.objectkey.key.inseg_entry); + return true; case SAI_OBJECT_TYPE_MY_SID_ENTRY: - sai_deserialize_my_sid_entry(str_object_id, meta_key.objectkey.key.my_sid_entry); - break; + sai_deserialize_my_sid_entry(object_id, meta_key.objectkey.key.my_sid_entry); + return true; case SAI_OBJECT_TYPE_L2MC_ENTRY: - sai_deserialize_l2mc_entry(str_object_id, meta_key.objectkey.key.l2mc_entry); - break; + sai_deserialize_l2mc_entry(object_id, meta_key.objectkey.key.l2mc_entry); + return true; case SAI_OBJECT_TYPE_IPMC_ENTRY: - sai_deserialize_ipmc_entry(str_object_id, meta_key.objectkey.key.ipmc_entry); - break; + sai_deserialize_ipmc_entry(object_id, meta_key.objectkey.key.ipmc_entry); + return true; case SAI_OBJECT_TYPE_MCAST_FDB_ENTRY: - sai_deserialize_mcast_fdb_entry(str_object_id, meta_key.objectkey.key.mcast_fdb_entry); - break; + sai_deserialize_mcast_fdb_entry(object_id, meta_key.objectkey.key.mcast_fdb_entry); + return true; default: + return false; + } +} - if (meta->isnonobjectid) - { - SWSS_LOG_THROW("object %s is non object id, not supported yet, FIXME", - sai_serialize_object_type(meta->objecttype).c_str()); - } +bool sai_deserialize_object_extension_entry( + _In_ const std::string object_id, + _Inout_ sai_object_meta_key_t& meta_key) +{ + SWSS_LOG_ENTER(); - sai_deserialize_object_id(str_object_id, meta_key.objectkey.key.object_id); - break; + switch ((sai_object_type_extensions_t)meta_key.objecttype) + { + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + sai_deserialize_direction_lookup_entry(object_id, meta_key.objectkey.key.direction_lookup_entry); + return true; + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + sai_deserialize_eni_ether_address_map_entry(object_id, meta_key.objectkey.key.eni_ether_address_map_entry); + return true; + + case SAI_OBJECT_TYPE_VIP_ENTRY: + sai_deserialize_vip_entry(object_id, meta_key.objectkey.key.vip_entry); + return true; + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + sai_deserialize_inbound_routing_entry(object_id, meta_key.objectkey.key.inbound_routing_entry); + return true; + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + sai_deserialize_pa_validation_entry(object_id, meta_key.objectkey.key.pa_validation_entry); + return true; + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + sai_deserialize_outbound_routing_entry(object_id, meta_key.objectkey.key.outbound_routing_entry); + return true; + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + sai_deserialize_outbound_ca_to_pa_entry(object_id, meta_key.objectkey.key.outbound_ca_to_pa_entry); + return true; + + default: + return false; + } +} + +void sai_deserialize_object_meta_key( + _In_ const std::string &s, + _Out_ sai_object_meta_key_t& meta_key) +{ + SWSS_LOG_ENTER(); + + SWSS_LOG_DEBUG("%s", s.c_str()); + + const std::string &str_object_type = s.substr(0, s.find(":")); + const std::string &str_object_id = s.substr(s.find(":") + 1); + + sai_deserialize_object_type(str_object_type, meta_key.objecttype); + + if (!sai_metadata_is_object_type_valid(meta_key.objecttype)) + { + SWSS_LOG_THROW("invalid object type value %s", sai_serialize_object_type(meta_key.objecttype).c_str()); + } + + if (!sai_deserialize_object_entry(str_object_id, meta_key) && + !sai_deserialize_object_extension_entry(str_object_id, meta_key)) + { + const auto& meta = sai_metadata_get_object_type_info(meta_key.objecttype); + + if (meta->isnonobjectid) + { + SWSS_LOG_THROW("object %s is non object id, not supported yet, FIXME", + sai_serialize_object_type(meta->objecttype).c_str()); + } + + sai_deserialize_object_id(str_object_id, meta_key.objectkey.key.object_id); } } @@ -4304,6 +4696,10 @@ void sai_deserialize_free_attribute_value( case SAI_ATTR_VALUE_TYPE_INT32_RANGE: break; + case SAI_ATTR_VALUE_TYPE_UINT16_RANGE_LIST: + sai_free_list(attr.value.u16rangelist); + break; + case SAI_ATTR_VALUE_TYPE_VLAN_LIST: sai_free_list(attr.value.vlanlist); break; @@ -4400,6 +4796,10 @@ void sai_deserialize_free_attribute_value( sai_free_list(attr.value.sysportconfiglist); break; + case SAI_ATTR_VALUE_TYPE_IP_PREFIX_LIST: + sai_free_list(attr.value.ipprefixlist); + break; + default: SWSS_LOG_THROW("sai attr value %s is not implemented, FIXME", sai_serialize_attr_value_type(type).c_str()); } diff --git a/meta/sai_serialize.h b/meta/sai_serialize.h index 7c2827b0c..ea6a52404 100644 --- a/meta/sai_serialize.h +++ b/meta/sai_serialize.h @@ -138,6 +138,27 @@ std::string sai_serialize_hex_binary( _In_ const void *buffer, _In_ size_t length); +std::string sai_serialize_direction_lookup_entry( + _In_ const sai_direction_lookup_entry_t &direction_lookup_entry); + +std::string sai_serialize_eni_ether_address_map_entry( + _In_ const sai_eni_ether_address_map_entry_t &eni_ether_address_map_entry); + +std::string sai_serialize_vip_entry( + _In_ const sai_vip_entry_t &vip_entry); + +std::string sai_serialize_inbound_routing_entry( + _In_ const sai_inbound_routing_entry_t &inbound_routing_entry); + +std::string sai_serialize_pa_validation_entry( + _In_ const sai_pa_validation_entry_t &pa_validation_entry); + +std::string sai_serialize_outbound_routing_entry( + _In_ const sai_outbound_routing_entry_t &outbound_routing_entry); + +std::string sai_serialize_outbound_ca_to_pa_entry( + _In_ const sai_outbound_ca_to_pa_entry_t &outbound_ca_to_pa_entry); + void sai_deserialize_system_port_config_list( _In_ const std::string& s, _Out_ sai_system_port_config_list_t& sysportconfiglist, @@ -348,6 +369,34 @@ void sai_deserialize_vlan_id( _In_ const std::string& s, _In_ sai_vlan_id_t& vlan_id); +void sai_deserialize_direction_lookup_entry( + _In_ const std::string &s, + _Out_ sai_direction_lookup_entry_t& direction_lookup_entry); + +void sai_deserialize_eni_ether_address_map_entry( + _In_ const std::string &s, + _Out_ sai_eni_ether_address_map_entry_t& eni_ether_address_map_entry); + +void sai_deserialize_vip_entry( + _In_ const std::string &s, + _Out_ sai_vip_entry_t& vip_entry); + +void sai_deserialize_inbound_routing_entry( + _In_ const std::string &s, + _Out_ sai_inbound_routing_entry_t& inbound_routing_entry); + +void sai_deserialize_pa_validation_entry( + _In_ const std::string &s, + _Out_ sai_pa_validation_entry_t& pa_validation_entry); + +void sai_deserialize_outbound_routing_entry( + _In_ const std::string &s, + _Out_ sai_outbound_routing_entry_t& outbound_routing_entry); + +void sai_deserialize_outbound_ca_to_pa_entry( + _In_ const std::string &s, + _Out_ sai_outbound_ca_to_pa_entry_t& outbound_ca_to_pa_entry); + void sai_deserialize_attr_value( _In_ const std::string& s, _In_ const sai_attr_metadata_t& meta, diff --git a/saiplayer/SaiPlayer.cpp b/saiplayer/SaiPlayer.cpp index f9cb6dc0f..6e22de110 100644 --- a/saiplayer/SaiPlayer.cpp +++ b/saiplayer/SaiPlayer.cpp @@ -681,6 +681,234 @@ sai_status_t SaiPlayer::handle_inseg( } } +sai_status_t SaiPlayer::handle_dash_direction_lookup( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + sai_direction_lookup_entry_t entry; + sai_deserialize_direction_lookup_entry(str_object_id, entry); + + entry.switch_id = translate_local_to_redis(entry.switch_id); + + switch (api) + { + case SAI_COMMON_API_CREATE: + return m_sai->create(&entry, attr_count, attr_list); + + case SAI_COMMON_API_REMOVE: + return m_sai->remove(&entry); + + case SAI_COMMON_API_SET: + return m_sai->set(&entry, attr_list); + + case SAI_COMMON_API_GET: + return m_sai->get(&entry, attr_count, attr_list); + + default: + SWSS_LOG_THROW("DASH direction_lookup other apis not implemented"); + } +} + +sai_status_t SaiPlayer::handle_dash_eni_ether_address_map( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + sai_eni_ether_address_map_entry_t entry; + sai_deserialize_eni_ether_address_map_entry(str_object_id, entry); + + entry.switch_id = translate_local_to_redis(entry.switch_id); + + switch (api) + { + case SAI_COMMON_API_CREATE: + return m_sai->create(&entry, attr_count, attr_list); + + case SAI_COMMON_API_REMOVE: + return m_sai->remove(&entry); + + case SAI_COMMON_API_SET: + return m_sai->set(&entry, attr_list); + + case SAI_COMMON_API_GET: + return m_sai->get(&entry, attr_count, attr_list); + + default: + SWSS_LOG_THROW("DASH eni_ether_address_map_entry other apis not implemented"); + } +} + +sai_status_t SaiPlayer::handle_dash_vip( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + sai_vip_entry_t entry; + sai_deserialize_vip_entry(str_object_id, entry); + + entry.switch_id = translate_local_to_redis(entry.switch_id); + + switch (api) + { + case SAI_COMMON_API_CREATE: + return m_sai->create(&entry, attr_count, attr_list); + + case SAI_COMMON_API_REMOVE: + return m_sai->remove(&entry); + + case SAI_COMMON_API_SET: + return m_sai->set(&entry, attr_list); + + case SAI_COMMON_API_GET: + return m_sai->get(&entry, attr_count, attr_list); + + default: + SWSS_LOG_THROW("DASH vip other apis not implemented"); + } +} + +sai_status_t SaiPlayer::handle_dash_inbound_routing( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + sai_inbound_routing_entry_t entry; + sai_deserialize_inbound_routing_entry(str_object_id, entry); + + entry.switch_id = translate_local_to_redis(entry.switch_id); + entry.eni_id = translate_local_to_redis(entry.eni_id); + + switch (api) + { + case SAI_COMMON_API_CREATE: + return m_sai->create(&entry, attr_count, attr_list); + + case SAI_COMMON_API_REMOVE: + return m_sai->remove(&entry); + + case SAI_COMMON_API_SET: + return m_sai->set(&entry, attr_list); + + case SAI_COMMON_API_GET: + return m_sai->get(&entry, attr_count, attr_list); + + default: + SWSS_LOG_THROW("DASH inbound_routing other apis not implemented"); + } +} + +sai_status_t SaiPlayer::handle_dash_pa_validation( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + sai_pa_validation_entry_t entry; + sai_deserialize_pa_validation_entry(str_object_id, entry); + + entry.switch_id = translate_local_to_redis(entry.switch_id); + entry.vnet_id = translate_local_to_redis(entry.vnet_id); + + switch (api) + { + case SAI_COMMON_API_CREATE: + return m_sai->create(&entry, attr_count, attr_list); + + case SAI_COMMON_API_REMOVE: + return m_sai->remove(&entry); + + case SAI_COMMON_API_SET: + return m_sai->set(&entry, attr_list); + + case SAI_COMMON_API_GET: + return m_sai->get(&entry, attr_count, attr_list); + + default: + SWSS_LOG_THROW("DASH pa_validation other apis not implemented"); + } +} + +sai_status_t SaiPlayer::handle_dash_outbound_routing( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + sai_outbound_routing_entry_t entry; + sai_deserialize_outbound_routing_entry(str_object_id, entry); + + entry.switch_id = translate_local_to_redis(entry.switch_id); + entry.eni_id = translate_local_to_redis(entry.eni_id); + + switch (api) + { + case SAI_COMMON_API_CREATE: + return m_sai->create(&entry, attr_count, attr_list); + + case SAI_COMMON_API_REMOVE: + return m_sai->remove(&entry); + + case SAI_COMMON_API_SET: + return m_sai->set(&entry, attr_list); + + case SAI_COMMON_API_GET: + return m_sai->get(&entry, attr_count, attr_list); + + default: + SWSS_LOG_THROW("DASH outbound_routing other apis not implemented"); + } +} + +sai_status_t SaiPlayer::handle_dash_outbound_ca_to_pa( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + sai_outbound_ca_to_pa_entry_t entry; + sai_deserialize_outbound_ca_to_pa_entry(str_object_id, entry); + + entry.switch_id = translate_local_to_redis(entry.switch_id); + entry.dst_vnet_id = translate_local_to_redis(entry.dst_vnet_id); + + switch (api) + { + case SAI_COMMON_API_CREATE: + return m_sai->create(&entry, attr_count, attr_list); + + case SAI_COMMON_API_REMOVE: + return m_sai->remove(&entry); + + case SAI_COMMON_API_SET: + return m_sai->set(&entry, attr_list); + + case SAI_COMMON_API_GET: + return m_sai->get(&entry, attr_count, attr_list); + + default: + SWSS_LOG_THROW("DASH outbound_ca_to_pa other apis not implemented"); + } +} + void SaiPlayer::update_notifications_pointers( _In_ uint32_t attr_count, _Inout_ sai_attribute_t *attr_list) @@ -1426,7 +1654,7 @@ sai_status_t SaiPlayer::handle_bulk_entry( attr_lists[idx] = attributes[idx]->get_attr_list(); } - switch (object_type) + switch ((int)object_type) { case SAI_OBJECT_TYPE_ROUTE_ENTRY: { @@ -1481,13 +1709,129 @@ sai_status_t SaiPlayer::handle_bulk_entry( } break; + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_direction_lookup_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + } + + CALL_BULK_CREATE_API_WITH_TIMER("direction_lookup_entry"); + + } + break; + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_eni_ether_address_map_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + } + + CALL_BULK_CREATE_API_WITH_TIMER("eni_ether_address_map_entry"); + + } + break; + + case SAI_OBJECT_TYPE_VIP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_vip_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + } + + CALL_BULK_CREATE_API_WITH_TIMER("vip_entry"); + + } + break; + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_inbound_routing_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].eni_id = translate_local_to_redis(entries[it].eni_id); + } + + CALL_BULK_CREATE_API_WITH_TIMER("inbound_routing_entry"); + + } + break; + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_pa_validation_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].vnet_id = translate_local_to_redis(entries[it].vnet_id); + } + + CALL_BULK_CREATE_API_WITH_TIMER("pa_validation_entry"); + + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_routing_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].eni_id = translate_local_to_redis(entries[it].eni_id); + } + + CALL_BULK_CREATE_API_WITH_TIMER("outbound_routing_entry"); + + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_ca_to_pa_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].dst_vnet_id = translate_local_to_redis(entries[it].dst_vnet_id); + } + + CALL_BULK_CREATE_API_WITH_TIMER("outbound_ca_to_pa_entry"); + + } + break; + default: SWSS_LOG_THROW("api %s is not supported in bulk", sai_serialize_common_api(api).c_str()); } } else if (api == SAI_COMMON_API_BULK_REMOVE) { - switch (object_type) + switch ((int)object_type) { case SAI_OBJECT_TYPE_ROUTE_ENTRY: { @@ -1543,6 +1887,122 @@ sai_status_t SaiPlayer::handle_bulk_entry( } break; + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_direction_lookup_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + } + + CALL_BULK_REMOVE_API_WITH_TIMER("direction_lookup_entry"); + + } + break; + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_eni_ether_address_map_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + } + + CALL_BULK_REMOVE_API_WITH_TIMER("eni_ether_address_map_entry"); + + } + break; + + case SAI_OBJECT_TYPE_VIP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_vip_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + } + + CALL_BULK_REMOVE_API_WITH_TIMER("vip_entry"); + + } + break; + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_inbound_routing_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].eni_id = translate_local_to_redis(entries[it].eni_id); + } + + CALL_BULK_REMOVE_API_WITH_TIMER("inbound_routing_entry"); + + } + break; + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_pa_validation_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].vnet_id = translate_local_to_redis(entries[it].vnet_id); + } + + CALL_BULK_REMOVE_API_WITH_TIMER("pa_validation_entry"); + + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_routing_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].eni_id = translate_local_to_redis(entries[it].eni_id); + } + + CALL_BULK_REMOVE_API_WITH_TIMER("outbound_routing_entry"); + + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_ca_to_pa_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].dst_vnet_id = translate_local_to_redis(entries[it].dst_vnet_id); + } + + CALL_BULK_REMOVE_API_WITH_TIMER("outbound_ca_to_pa_entry"); + + } + break; + default: SWSS_LOG_THROW("api %s is not supported in bulk", sai_serialize_common_api(api).c_str()); @@ -1556,7 +2016,7 @@ sai_status_t SaiPlayer::handle_bulk_entry( { attr_lists.push_back(attributes[it]->get_attr_list()[0]); } - switch (object_type) + switch ((int)object_type) { case SAI_OBJECT_TYPE_ROUTE_ENTRY: { @@ -1612,6 +2072,122 @@ sai_status_t SaiPlayer::handle_bulk_entry( } break; + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_direction_lookup_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + } + + CALL_BULK_SET_API_WITH_TIMER("direction_lookup_entry"); + + } + break; + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_eni_ether_address_map_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + } + + CALL_BULK_SET_API_WITH_TIMER("eni_ether_address_map_entry"); + + } + break; + + case SAI_OBJECT_TYPE_VIP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_vip_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + } + + CALL_BULK_SET_API_WITH_TIMER("vip_entry"); + + } + break; + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_inbound_routing_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].eni_id = translate_local_to_redis(entries[it].eni_id); + } + + CALL_BULK_SET_API_WITH_TIMER("inbound_routing_entry"); + + } + break; + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_pa_validation_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].vnet_id = translate_local_to_redis(entries[it].vnet_id); + } + + CALL_BULK_SET_API_WITH_TIMER("pa_validation_entry"); + + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_routing_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].eni_id = translate_local_to_redis(entries[it].eni_id); + } + + CALL_BULK_SET_API_WITH_TIMER("outbound_routing_entry"); + + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_ca_to_pa_entry(object_ids[it], entries[it]); + + entries[it].switch_id = translate_local_to_redis(entries[it].switch_id); + entries[it].dst_vnet_id = translate_local_to_redis(entries[it].dst_vnet_id); + } + + CALL_BULK_SET_API_WITH_TIMER("outbound_ca_to_pa_entry"); + + } + break; + default: SWSS_LOG_THROW("api %s is not supported in bulk", sai_serialize_common_api(api).c_str()); } @@ -1848,11 +2424,18 @@ void SaiPlayer::processBulk( auto info = sai_metadata_get_object_type_info(object_type); - switch (object_type) + switch ((int)object_type) { case SAI_OBJECT_TYPE_ROUTE_ENTRY: case SAI_OBJECT_TYPE_FDB_ENTRY: case SAI_OBJECT_TYPE_NAT_ENTRY: + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + case SAI_OBJECT_TYPE_VIP_ENTRY: + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: status = handle_bulk_entry(object_ids, object_type, api, attributes, statuses); break; @@ -2034,7 +2617,7 @@ int SaiPlayer::replay() auto info = sai_metadata_get_object_type_info(object_type); - switch (object_type) + switch ((int)object_type) { case SAI_OBJECT_TYPE_FDB_ENTRY: status = handle_fdb(str_object_id, api, attr_count, attr_list); @@ -2052,6 +2635,34 @@ int SaiPlayer::replay() status = handle_inseg(str_object_id, api, attr_count, attr_list); break; + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + status = handle_dash_direction_lookup(str_object_id, api, attr_count, attr_list); + break; + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + status = handle_dash_eni_ether_address_map(str_object_id, api, attr_count, attr_list); + break; + + case SAI_OBJECT_TYPE_VIP_ENTRY: + status = handle_dash_vip(str_object_id, api, attr_count, attr_list); + break; + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + status = handle_dash_inbound_routing(str_object_id, api, attr_count, attr_list); + break; + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + status = handle_dash_pa_validation(str_object_id, api, attr_count, attr_list); + break; + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + status = handle_dash_outbound_routing(str_object_id, api, attr_count, attr_list); + break; + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + status = handle_dash_outbound_ca_to_pa(str_object_id, api, attr_count, attr_list); + break; + default: if (info->isnonobjectid) diff --git a/saiplayer/SaiPlayer.h b/saiplayer/SaiPlayer.h index efd1f03ba..fe7f91119 100644 --- a/saiplayer/SaiPlayer.h +++ b/saiplayer/SaiPlayer.h @@ -123,6 +123,48 @@ namespace saiplayer _In_ uint32_t attr_count, _In_ sai_attribute_t *attr_list); + sai_status_t handle_dash_direction_lookup( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list); + + sai_status_t handle_dash_eni_ether_address_map( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list); + + sai_status_t handle_dash_vip( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list); + + sai_status_t handle_dash_inbound_routing( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list); + + sai_status_t handle_dash_pa_validation( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list); + + sai_status_t handle_dash_outbound_routing( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list); + + sai_status_t handle_dash_outbound_ca_to_pa( + _In_ const std::string &str_object_id, + _In_ sai_common_api_t api, + _In_ uint32_t attr_count, + _In_ sai_attribute_t *attr_list); + void match_redis_with_rec( _In_ sai_object_type_t object_type, _In_ uint32_t get_attr_count, diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index 78a1ea2d0..1bcf85146 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -951,7 +951,7 @@ sai_status_t Syncd::processBulkCreateEntry( attr_lists[idx] = attributes[idx]->get_attr_list(); } - switch (objectType) + switch ((int)objectType) { case SAI_OBJECT_TYPE_ROUTE_ENTRY: { @@ -1069,6 +1069,157 @@ sai_status_t Syncd::processBulkCreateEntry( } break; + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_direction_lookup_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + } + + status = m_vendorSai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_eni_ether_address_map_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + } + + status = m_vendorSai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_VIP_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_vip_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + } + + status = m_vendorSai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_inbound_routing_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + entries[it].eni_id = m_translator->translateVidToRid(entries[it].eni_id); + } + + status = m_vendorSai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_pa_validation_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + entries[it].vnet_id = m_translator->translateVidToRid(entries[it].vnet_id); + } + + status = m_vendorSai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_routing_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + entries[it].eni_id = m_translator->translateVidToRid(entries[it].eni_id); + } + + status = m_vendorSai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + { + std::vector entries(object_count); + + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_ca_to_pa_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + entries[it].dst_vnet_id = m_translator->translateVidToRid(entries[it].dst_vnet_id); + } + + status = m_vendorSai->bulkCreate( + object_count, + entries.data(), + attr_counts.data(), + attr_lists.data(), + mode, + statuses.data()); + } + break; + default: return SAI_STATUS_NOT_SUPPORTED; } @@ -1095,7 +1246,7 @@ sai_status_t Syncd::processBulkRemoveEntry( sai_bulk_op_error_mode_t mode = SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR; - switch (objectType) + switch ((int)objectType) { case SAI_OBJECT_TYPE_ROUTE_ENTRY: { @@ -1196,6 +1347,143 @@ sai_status_t Syncd::processBulkRemoveEntry( } break; + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_direction_lookup_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + } + + status = m_vendorSai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + + } + break; + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_eni_ether_address_map_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + } + + status = m_vendorSai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + + } + break; + + case SAI_OBJECT_TYPE_VIP_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_vip_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + } + + status = m_vendorSai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + + } + break; + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_inbound_routing_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + entries[it].eni_id = m_translator->translateVidToRid(entries[it].eni_id); + } + + status = m_vendorSai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + + } + break; + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_pa_validation_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + entries[it].vnet_id = m_translator->translateVidToRid(entries[it].vnet_id); + } + + status = m_vendorSai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_routing_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + entries[it].eni_id = m_translator->translateVidToRid(entries[it].eni_id); + } + + status = m_vendorSai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + + } + break; + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + { + std::vector entries(object_count); + for (uint32_t it = 0; it < object_count; it++) + { + sai_deserialize_outbound_ca_to_pa_entry(objectIds[it], entries[it]); + + entries[it].switch_id = m_translator->translateVidToRid(entries[it].switch_id); + entries[it].dst_vnet_id = m_translator->translateVidToRid(entries[it].dst_vnet_id); + } + + status = m_vendorSai->bulkRemove( + object_count, + entries.data(), + mode, + statuses.data()); + + } + break; + default: return SAI_STATUS_NOT_SUPPORTED; } @@ -1230,7 +1518,7 @@ sai_status_t Syncd::processBulkSetEntry( attr_lists.push_back(attributes[it]->get_attr_list()[0]); } - switch (objectType) + switch ((int)objectType) { case SAI_OBJECT_TYPE_ROUTE_ENTRY: { @@ -1403,7 +1691,7 @@ sai_status_t Syncd::processBulkEntry( metaKey.objecttype = objectType; - switch (objectType) + switch ((int)objectType) { case SAI_OBJECT_TYPE_ROUTE_ENTRY: sai_deserialize_route_entry(objectIds[idx], metaKey.objectkey.key.route_entry); @@ -1421,6 +1709,34 @@ sai_status_t Syncd::processBulkEntry( sai_deserialize_inseg_entry(objectIds[idx], metaKey.objectkey.key.inseg_entry); break; + case SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY: + sai_deserialize_direction_lookup_entry(objectIds[idx], metaKey.objectkey.key.direction_lookup_entry); + break; + + case SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY: + sai_deserialize_eni_ether_address_map_entry(objectIds[idx], metaKey.objectkey.key.eni_ether_address_map_entry); + break; + + case SAI_OBJECT_TYPE_VIP_ENTRY: + sai_deserialize_vip_entry(objectIds[idx], metaKey.objectkey.key.vip_entry); + break; + + case SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY: + sai_deserialize_inbound_routing_entry(objectIds[idx], metaKey.objectkey.key.inbound_routing_entry); + break; + + case SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY: + sai_deserialize_pa_validation_entry(objectIds[idx], metaKey.objectkey.key.pa_validation_entry); + break; + + case SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY: + sai_deserialize_outbound_routing_entry(objectIds[idx], metaKey.objectkey.key.outbound_routing_entry); + break; + + case SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY: + sai_deserialize_outbound_ca_to_pa_entry(objectIds[idx], metaKey.objectkey.key.outbound_ca_to_pa_entry); + break; + default: SWSS_LOG_THROW("object %s not implemented, FIXME", sai_serialize_object_type(objectType).c_str()); } diff --git a/syncd/VendorSai.cpp b/syncd/VendorSai.cpp index 5ee669c41..f57c8ec23 100644 --- a/syncd/VendorSai.cpp +++ b/syncd/VendorSai.cpp @@ -307,7 +307,8 @@ sai_status_t VendorSai::create( \ MUTEX(); \ SWSS_LOG_ENTER(); \ VENDOR_CHECK_API_INITIALIZED(); \ - auto info = sai_metadata_get_object_type_info(SAI_OBJECT_TYPE_ ## OT); \ + auto info = sai_metadata_get_object_type_info( \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT); \ sai_object_meta_key_t mk = { .objecttype = info->objecttype, \ .objectkey = { .key = { .ot = *entry } } }; \ return info->create(&mk, 0, attr_count, attr_list); \ @@ -322,7 +323,8 @@ sai_status_t VendorSai::remove( \ MUTEX(); \ SWSS_LOG_ENTER(); \ VENDOR_CHECK_API_INITIALIZED(); \ - auto info = sai_metadata_get_object_type_info(SAI_OBJECT_TYPE_ ## OT); \ + auto info = sai_metadata_get_object_type_info( \ + (sai_object_type_t)SAI_OBJECT_TYPE_ ## OT); \ sai_object_meta_key_t mk = { .objecttype = info->objecttype, \ .objectkey = { .key = { .ot = *entry } } }; \ return info->remove(&mk); \ @@ -338,7 +340,8 @@ sai_status_t VendorSai::set( \ MUTEX(); \ SWSS_LOG_ENTER(); \ VENDOR_CHECK_API_INITIALIZED(); \ - auto info = sai_metadata_get_object_type_info(SAI_OBJECT_TYPE_ ## OT); \ + auto info = sai_metadata_get_object_type_info( \ + (sai_object_type_t) SAI_OBJECT_TYPE_ ## OT); \ sai_object_meta_key_t mk = { .objecttype = info->objecttype, \ .objectkey = { .key = { .ot = *entry } } }; \ return info->set(&mk, attr); \ @@ -355,7 +358,8 @@ sai_status_t VendorSai::get( \ MUTEX(); \ SWSS_LOG_ENTER(); \ VENDOR_CHECK_API_INITIALIZED(); \ - auto info = sai_metadata_get_object_type_info(SAI_OBJECT_TYPE_ ## OT); \ + auto info = sai_metadata_get_object_type_info( \ + (sai_object_type_t) SAI_OBJECT_TYPE_ ## OT); \ sai_object_meta_key_t mk = { .objecttype = info->objecttype, \ .objectkey = { .key = { .ot = *entry } } }; \ return info->get(&mk, attr_count, attr_list); \ @@ -732,7 +736,7 @@ sai_status_t VendorSai::bulkCreate( _Out_ sai_object_id_t *object_id, _Out_ sai_status_t *object_statuses); - switch (object_type) + switch ((int)object_type) { case SAI_OBJECT_TYPE_PORT: ptr = m_apis.port_api->create_ports; @@ -758,6 +762,22 @@ sai_status_t VendorSai::bulkCreate( ptr = m_apis.vlan_api->create_vlan_members; break; + case SAI_OBJECT_TYPE_ENI: + ptr = m_apis.dash_eni_api->create_enis; + break; + + case SAI_OBJECT_TYPE_VNET: + ptr = m_apis.dash_vnet_api->create_vnets; + break; + + case SAI_OBJECT_TYPE_DASH_ACL_GROUP: + ptr = m_apis.dash_acl_api->create_dash_acl_groups; + break; + + case SAI_OBJECT_TYPE_DASH_ACL_RULE: + ptr = m_apis.dash_acl_api->create_dash_acl_rules; + break; + default: SWSS_LOG_ERROR("not implemented %s, FIXME", sai_serialize_object_type(object_type).c_str()); return SAI_STATUS_NOT_IMPLEMENTED; @@ -795,7 +815,7 @@ sai_status_t VendorSai::bulkRemove( _In_ sai_bulk_op_error_mode_t mode, _Out_ sai_status_t *object_statuses); - switch (object_type) + switch ((int)object_type) { case SAI_OBJECT_TYPE_PORT: ptr = m_apis.port_api->remove_ports; @@ -821,6 +841,22 @@ sai_status_t VendorSai::bulkRemove( ptr = m_apis.vlan_api->remove_vlan_members; break; + case SAI_OBJECT_TYPE_ENI: + ptr = m_apis.dash_eni_api->remove_enis; + break; + + case SAI_OBJECT_TYPE_VNET: + ptr = m_apis.dash_vnet_api->remove_vnets; + break; + + case SAI_OBJECT_TYPE_DASH_ACL_GROUP: + ptr = m_apis.dash_acl_api->remove_dash_acl_groups; + break; + + case SAI_OBJECT_TYPE_DASH_ACL_RULE: + ptr = m_apis.dash_acl_api->remove_dash_acl_rules; + break; + default: SWSS_LOG_ERROR("not implemented %s, FIXME", sai_serialize_object_type(object_type).c_str()); return SAI_STATUS_NOT_IMPLEMENTED; @@ -1015,6 +1051,196 @@ sai_status_t VendorSai::bulkCreate( mode, object_statuses); } + +sai_status_t VendorSai::bulkCreate( + _In_ uint32_t object_count, + _In_ const sai_direction_lookup_entry_t* entries, + _In_ const uint32_t *attr_count, + _In_ const sai_attribute_t **attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_direction_lookup_api->create_direction_lookup_entries) + { + SWSS_LOG_INFO("create_direction_lookup_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_direction_lookup_api->create_direction_lookup_entries( + object_count, + entries, + attr_count, + attr_list, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkCreate( + _In_ uint32_t object_count, + _In_ const sai_eni_ether_address_map_entry_t* entries, + _In_ const uint32_t *attr_count, + _In_ const sai_attribute_t **attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_eni_api->create_eni_ether_address_map_entries) + { + SWSS_LOG_INFO("create_eni_ether_address_map_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_eni_api->create_eni_ether_address_map_entries( + object_count, + entries, + attr_count, + attr_list, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkCreate( + _In_ uint32_t object_count, + _In_ const sai_vip_entry_t* entries, + _In_ const uint32_t *attr_count, + _In_ const sai_attribute_t **attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_vip_api->create_vip_entries) + { + SWSS_LOG_INFO("create_vip_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_vip_api->create_vip_entries( + object_count, + entries, + attr_count, + attr_list, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkCreate( + _In_ uint32_t object_count, + _In_ const sai_inbound_routing_entry_t* entries, + _In_ const uint32_t *attr_count, + _In_ const sai_attribute_t **attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_inbound_routing_api->create_inbound_routing_entries) + { + SWSS_LOG_INFO("create_inbound_routing_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_inbound_routing_api->create_inbound_routing_entries( + object_count, + entries, + attr_count, + attr_list, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkCreate( + _In_ uint32_t object_count, + _In_ const sai_pa_validation_entry_t* entries, + _In_ const uint32_t *attr_count, + _In_ const sai_attribute_t **attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_pa_validation_api->create_pa_validation_entries) + { + SWSS_LOG_INFO("create_pa_validation_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_pa_validation_api->create_pa_validation_entries( + object_count, + entries, + attr_count, + attr_list, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkCreate( + _In_ uint32_t object_count, + _In_ const sai_outbound_routing_entry_t* entries, + _In_ const uint32_t *attr_count, + _In_ const sai_attribute_t **attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_outbound_routing_api->create_outbound_routing_entries) + { + SWSS_LOG_INFO("create_outbound_routing_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_outbound_routing_api->create_outbound_routing_entries( + object_count, + entries, + attr_count, + attr_list, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkCreate( + _In_ uint32_t object_count, + _In_ const sai_outbound_ca_to_pa_entry_t* entries, + _In_ const uint32_t *attr_count, + _In_ const sai_attribute_t **attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_outbound_ca_to_pa_api->create_outbound_ca_to_pa_entries) + { + SWSS_LOG_INFO("create_outbound_ca_to_pa_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_outbound_ca_to_pa_api->create_outbound_ca_to_pa_entries( + object_count, + entries, + attr_count, + attr_list, + mode, + object_statuses); +} + // BULK REMOVE sai_status_t VendorSai::bulkRemove( @@ -1155,6 +1381,168 @@ sai_status_t VendorSai::bulkRemove( mode, object_statuses); } + +sai_status_t VendorSai::bulkRemove( + _In_ uint32_t object_count, + _In_ const sai_direction_lookup_entry_t *entries, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_direction_lookup_api->remove_direction_lookup_entries) + { + SWSS_LOG_INFO("remove_direction_lookup_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_direction_lookup_api->remove_direction_lookup_entries( + object_count, + entries, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkRemove( + _In_ uint32_t object_count, + _In_ const sai_eni_ether_address_map_entry_t *entries, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_eni_api->remove_eni_ether_address_map_entries) + { + SWSS_LOG_INFO("remove_eni_ether_address_map_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_eni_api->remove_eni_ether_address_map_entries( + object_count, + entries, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkRemove( + _In_ uint32_t object_count, + _In_ const sai_vip_entry_t *entries, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_vip_api->remove_vip_entries) + { + SWSS_LOG_INFO("remove_vip_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_vip_api->remove_vip_entries( + object_count, + entries, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkRemove( + _In_ uint32_t object_count, + _In_ const sai_inbound_routing_entry_t *entries, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_inbound_routing_api->remove_inbound_routing_entries) + { + SWSS_LOG_INFO("remove_inbound_routing_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_inbound_routing_api->remove_inbound_routing_entries( + object_count, + entries, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkRemove( + _In_ uint32_t object_count, + _In_ const sai_pa_validation_entry_t *entries, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_pa_validation_api->remove_pa_validation_entries) + { + SWSS_LOG_INFO("remove_pa_validation_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_pa_validation_api->remove_pa_validation_entries( + object_count, + entries, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkRemove( + _In_ uint32_t object_count, + _In_ const sai_outbound_routing_entry_t *entries, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_outbound_routing_api->remove_outbound_routing_entries) + { + SWSS_LOG_INFO("remove_outbound_routing_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_outbound_routing_api->remove_outbound_routing_entries( + object_count, + entries, + mode, + object_statuses); +} + +sai_status_t VendorSai::bulkRemove( + _In_ uint32_t object_count, + _In_ const sai_outbound_ca_to_pa_entry_t *entries, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + if (!m_apis.dash_outbound_ca_to_pa_api->remove_outbound_ca_to_pa_entries) + { + SWSS_LOG_INFO("remove_outbound_ca_to_pa_entries is not supported"); + return SAI_STATUS_NOT_SUPPORTED; + } + + return m_apis.dash_outbound_ca_to_pa_api->remove_outbound_ca_to_pa_entries( + object_count, + entries, + mode, + object_statuses); +} + // BULK SET sai_status_t VendorSai::bulkSet( @@ -1306,6 +1694,105 @@ sai_status_t VendorSai::bulkSet( mode, object_statuses); } + +sai_status_t VendorSai::bulkSet( + _In_ uint32_t object_count, + _In_ const sai_direction_lookup_entry_t *entries, + _In_ const sai_attribute_t *attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + return SAI_STATUS_NOT_SUPPORTED; +} + +sai_status_t VendorSai::bulkSet( + _In_ uint32_t object_count, + _In_ const sai_eni_ether_address_map_entry_t *entries, + _In_ const sai_attribute_t *attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + return SAI_STATUS_NOT_SUPPORTED; +} + +sai_status_t VendorSai::bulkSet( + _In_ uint32_t object_count, + _In_ const sai_vip_entry_t *entries, + _In_ const sai_attribute_t *attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + return SAI_STATUS_NOT_SUPPORTED; +} + +sai_status_t VendorSai::bulkSet( + _In_ uint32_t object_count, + _In_ const sai_inbound_routing_entry_t *entries, + _In_ const sai_attribute_t *attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + return SAI_STATUS_NOT_SUPPORTED; +} + +sai_status_t VendorSai::bulkSet( + _In_ uint32_t object_count, + _In_ const sai_pa_validation_entry_t *entries, + _In_ const sai_attribute_t *attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + return SAI_STATUS_NOT_SUPPORTED; +} + +sai_status_t VendorSai::bulkSet( + _In_ uint32_t object_count, + _In_ const sai_outbound_routing_entry_t *entries, + _In_ const sai_attribute_t *attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + return SAI_STATUS_NOT_SUPPORTED; +} + +sai_status_t VendorSai::bulkSet( + _In_ uint32_t object_count, + _In_ const sai_outbound_ca_to_pa_entry_t *entries, + _In_ const sai_attribute_t *attr_list, + _In_ sai_bulk_op_error_mode_t mode, + _Out_ sai_status_t *object_statuses) +{ + MUTEX(); + SWSS_LOG_ENTER(); + VENDOR_CHECK_API_INITIALIZED(); + + return SAI_STATUS_NOT_SUPPORTED; +} + // NON QUAD API sai_status_t VendorSai::flushFdbEntries( diff --git a/syncd/tests/Makefile.am b/syncd/tests/Makefile.am index 5cb1adea8..25c114334 100644 --- a/syncd/tests/Makefile.am +++ b/syncd/tests/Makefile.am @@ -5,7 +5,7 @@ LDADD_GTEST = -L/usr/src/gtest -lgtest -lgtest_main bin_PROGRAMS = tests tests_SOURCES = \ - main.cpp TestSyncdBrcm.cpp TestSyncdMlnx.cpp TestSyncdLib.cpp + main.cpp TestSyncdBrcm.cpp TestSyncdMlnx.cpp TestSyncdNvdaBf.cpp TestSyncdLib.cpp tests_CXXFLAGS = \ $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) tests_LDADD = \ diff --git a/syncd/tests/TestSyncdNvdaBf.cpp b/syncd/tests/TestSyncdNvdaBf.cpp new file mode 100644 index 000000000..33c1d1227 --- /dev/null +++ b/syncd/tests/TestSyncdNvdaBf.cpp @@ -0,0 +1,1340 @@ +#include "TestSyncdNvdaBf.h" + +using namespace syncd; + +static const char* profile_get_value( + _In_ sai_switch_profile_id_t profile_id, + _In_ const char* variable) +{ + SWSS_LOG_ENTER(); + + return NULL; +} + +static int profile_get_next_value( + _In_ sai_switch_profile_id_t profile_id, + _Out_ const char** variable, + _Out_ const char** value) +{ + SWSS_LOG_ENTER(); + + if (value == NULL) + { + SWSS_LOG_INFO("resetting profile map iterator"); + return 0; + } + + if (variable == NULL) + { + SWSS_LOG_WARN("variable is null"); + return -1; + } + + SWSS_LOG_INFO("iterator reached end"); + return -1; +} + +static sai_service_method_table_t test_services = { + profile_get_value, + profile_get_next_value +}; + + +template +static bool compare_lists(L la, L lb) +{ + // SWSS_LOG_ENTER(); // disabled + + if (la.count != lb.count) { + return false; + } + + return std::equal(la.list, la.list + la.count, lb.list); +} + +static bool operator==(sai_ip_address_t a, sai_ip_address_t b) +{ + if (a.addr_family != b.addr_family) { + return false; + } + + switch (a.addr_family) { + case SAI_IP_ADDR_FAMILY_IPV4: + return a.addr.ip4 == b.addr.ip4; + case SAI_IP_ADDR_FAMILY_IPV6: + return memcmp(a.addr.ip6, b.addr.ip6, sizeof(a.addr.ip6)) == 0; + default: + return false; + } +} + +static bool operator==(sai_ip_prefix_t a, sai_ip_prefix_t b) +{ + if (a.addr_family != b.addr_family) { + return false; + } + + switch (a.addr_family) { + case SAI_IP_ADDR_FAMILY_IPV4: + return a.addr.ip4 == b.addr.ip4 && a.mask.ip4 == b.mask.ip4; + case SAI_IP_ADDR_FAMILY_IPV6: + return memcmp(a.addr.ip6, b.addr.ip6, sizeof(a.addr.ip6)) == 0 && + memcmp(a.mask.ip6, b.mask.ip6, sizeof(a.mask.ip6)) == 0; + default: + return false; + } +} + +static bool operator==(sai_u16_range_t a, sai_u16_range_t b) +{ + return (a.min == b.min) && (a.max == b.max); +} + +void syncdNvdaBfWorkerThread() +{ + SWSS_LOG_ENTER(); + + swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_NOTICE); + MetadataLogger::initialize(); + + auto vendorSai = std::make_shared(); + auto commandLineOptions = std::make_shared(); + auto isWarmStart = false; + + commandLineOptions->m_enableSyncMode= true; + commandLineOptions->m_enableTempView = false; + commandLineOptions->m_disableExitSleep = true; + commandLineOptions->m_enableUnittests = false; + commandLineOptions->m_enableSaiBulkSupport = true; + commandLineOptions->m_startType = SAI_START_TYPE_COLD_BOOT; + commandLineOptions->m_redisCommunicationMode = SAI_REDIS_COMMUNICATION_MODE_REDIS_SYNC; + commandLineOptions->m_profileMapFile = "./nvda-bf/sai.profile"; + + auto syncd = std::make_shared(vendorSai, commandLineOptions, isWarmStart); + syncd->run(); + + SWSS_LOG_NOTICE("Started syncd worker"); +} + +void SyncdNvdaBfTest::SetUp() +{ + SWSS_LOG_ENTER(); + + // flush ASIC DB + + flushAsicDb(); + + // start syncd worker + + m_worker = std::make_shared(syncdNvdaBfWorkerThread); + + // initialize SAI redis + + m_sairedis = std::make_shared(); + + auto status = m_sairedis->initialize(0, &test_services); + ASSERT_EQ(status, SAI_STATUS_SUCCESS); + + // set communication mode + + sai_attribute_t attr; + + attr.id = SAI_REDIS_SWITCH_ATTR_REDIS_COMMUNICATION_MODE; + attr.value.s32 = SAI_REDIS_COMMUNICATION_MODE_REDIS_SYNC; + + status = m_sairedis->set(SAI_OBJECT_TYPE_SWITCH, SAI_NULL_OBJECT_ID, &attr); + ASSERT_EQ(status, SAI_STATUS_SUCCESS); + + // enable recording + + attr.id = SAI_REDIS_SWITCH_ATTR_RECORD; + attr.value.booldata = true; + + status = m_sairedis->set(SAI_OBJECT_TYPE_SWITCH, SAI_NULL_OBJECT_ID, &attr); + ASSERT_EQ(status, SAI_STATUS_SUCCESS); + + // create switch + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + status = m_sairedis->create(SAI_OBJECT_TYPE_SWITCH, &m_switchId, SAI_NULL_OBJECT_ID, 1, &attr); + ASSERT_EQ(status, SAI_STATUS_SUCCESS); +} + +void SyncdNvdaBfTest::TearDown() +{ + SWSS_LOG_ENTER(); + + // uninitialize SAI redis + + auto status = m_sairedis->uninitialize(); + ASSERT_EQ(status, SAI_STATUS_SUCCESS); + + // stop syncd worker + + sendSyncdShutdownNotification(); + m_worker->join(); +} + +sai_object_id_t SyncdNvdaBfTest::CreateCounter() +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create(SAI_OBJECT_TYPE_COUNTER, &oid, m_switchId, 0, nullptr)); + + return oid; +} + +void SyncdNvdaBfTest::RemoveCounter(sai_object_id_t counter) +{ + SWSS_LOG_ENTER(); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove((sai_object_type_t)SAI_OBJECT_TYPE_COUNTER, counter)); +} + +sai_object_id_t SyncdNvdaBfTest::CreateVnet(uint32_t vni) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + sai_attribute_t attr; + + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = vni; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_VNET, &oid, m_switchId, 1, &attr)); + + return oid; +} + +void SyncdNvdaBfTest::RemoveVnet(sai_object_id_t vnet) +{ + SWSS_LOG_ENTER(); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnet)); +} + +sai_object_id_t SyncdNvdaBfTest::CreateEni(sai_object_id_t vnet) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + sai_attribute_t attr; + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_ENI, &oid, m_switchId, 1, &attr)); + + return oid; +} + +void SyncdNvdaBfTest::RemoveEni(sai_object_id_t eni) +{ + SWSS_LOG_ENTER(); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni)); +} + +TEST_F(SyncdNvdaBfTest, dashDirectionLookup) +{ + sai_attribute_t attr; + + sai_direction_lookup_entry_t entry; + + entry.switch_id = m_switchId; + entry.vni = 1; + + std::vector attrs; + + attr.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create(&entry, (uint32_t)attrs.size(), attrs.data())); + + attr.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set(&entry, &attr)); + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get(&entry, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.s32, SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove(&entry)); +} + +TEST_F(SyncdNvdaBfTest, dashDirectionLookupBulk) +{ + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 1; + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_direction_lookup_entry_t entries[entries_count] = { + { .switch_id = m_switchId, .vni = 10}, + { .switch_id = m_switchId, .vni = 20}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST_F(SyncdNvdaBfTest, dashEniEtherAddressMapEntry) +{ + sai_attribute_t attr; + + sai_object_id_t vnet = CreateVnet(100); + sai_object_id_t eni = CreateEni(vnet); + + sai_eni_ether_address_map_entry_t entry = { .switch_id = m_switchId, .address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }}; + + std::vector attrs; + attr.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID; + attr.value.oid = eni; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get(&entry, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.oid, eni); + + attr.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID; + attr.value.oid = eni; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set(&entry, &attr)); + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get(&entry, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.oid, eni); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove(&entry)); + RemoveEni(eni); + RemoveVnet(vnet); +} + +TEST_F(SyncdNvdaBfTest, dashEniEtherAddressMapEntryBulk) +{ + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 1; + + sai_object_id_t vnet0 = CreateVnet(100); + sai_object_id_t eni0 = CreateEni(vnet0); + + sai_object_id_t vnet1 = CreateVnet(200); + sai_object_id_t eni1 = CreateEni(vnet1); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID, .value = (sai_attribute_value_t){.oid = eni0}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID, .value = (sai_attribute_value_t){.oid = eni1}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_eni_ether_address_map_entry_t entries[entries_count] = { + { .switch_id = m_switchId, .address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }}, + { .switch_id = m_switchId, .address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06 }}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + RemoveEni(eni0); + RemoveEni(eni1); + RemoveVnet(vnet0); + RemoveVnet(vnet1); +} + +TEST_F(SyncdNvdaBfTest, dashEni) +{ + sai_attribute_t attr; + + sai_ip_address_t uip4, uip6; + uip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &uip4.addr.ip4); + uip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &uip6.addr.ip6); + + sai_object_id_t vnet = CreateVnet(101); + + std::vector attrs; + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_ADMIN_STATE; + attr.value.booldata = true; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_VM_VNI; + attr.value.u32 = 123; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_CPS; + attr.value.u32 = 10; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_PPS; + attr.value.u32 = 20; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_FLOWS; + attr.value.u32 = 30; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP; + attr.value.ipaddr = uip4; + attrs.push_back(attr); + + sai_object_id_t eni; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_ENI, &eni, m_switchId, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.oid, vnet); + EXPECT_TRUE(attrs[1].value.booldata); + EXPECT_EQ(attrs[2].value.u32, 123); + EXPECT_EQ(attrs[3].value.u32, 10); + EXPECT_EQ(attrs[4].value.u32, 20); + EXPECT_EQ(attrs[5].value.u32, 30); + EXPECT_EQ(attrs[6].value.ipaddr.addr.ip4, uip4.addr.ip4); + + attr.id = SAI_ENI_ATTR_CPS; + attr.value.u32 = 10; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, &attr)); + attr.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP; + attr.value.ipaddr = uip6; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, &attr)); + + RemoveEni(eni); + RemoveVnet(vnet); +} + +TEST_F(SyncdNvdaBfTest, dashEniBulk) +{ + const uint32_t enis_count = 2; + const uint32_t eni_attrs_count = 6; + + sai_object_id_t vnet0 = CreateVnet(101); + sai_object_id_t vnet1 = CreateVnet(102); + + sai_ip_address_t ipaddr0, ipaddr1; + ipaddr0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ipaddr0.addr.ip4); + + ipaddr1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.1.1", &ipaddr1.addr.ip4); + + sai_attribute_t attrs0[] = { + {.id = SAI_ENI_ATTR_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + {.id = SAI_ENI_ATTR_ADMIN_STATE, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_ENI_ATTR_VM_VNI, .value = (sai_attribute_value_t){.u32 = 123}}, + {.id = SAI_ENI_ATTR_CPS, .value = (sai_attribute_value_t){.u32 = 10}}, + {.id = SAI_ENI_ATTR_FLOWS, .value = (sai_attribute_value_t){.u32 = 20}}, + {.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = ipaddr0}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_ENI_ATTR_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + {.id = SAI_ENI_ATTR_ADMIN_STATE, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_ENI_ATTR_VM_VNI, .value = (sai_attribute_value_t){.u32 = 124}}, + {.id = SAI_ENI_ATTR_CPS, .value = (sai_attribute_value_t){.u32 = 11}}, + {.id = SAI_ENI_ATTR_FLOWS, .value = (sai_attribute_value_t){.u32 = 21}}, + {.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = ipaddr1}}, + }; + + const sai_attribute_t *attr_list[enis_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[enis_count] = {eni_attrs_count, eni_attrs_count}; + sai_object_id_t enis[enis_count] = {}; + sai_status_t statuses[enis_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_ENI, m_switchId, enis_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, enis, statuses)); + for (uint32_t i = 0; i < enis_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_ENI, enis_count, enis, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < enis_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + RemoveVnet(vnet0); + RemoveVnet(vnet1); +} + +TEST_F(SyncdNvdaBfTest, dashEniAcl) +{ + sai_attribute_t attr; + + std::vector acl_attrs = { + SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID, + }; + + std::vector attrs; + std::vector acl_groups, acl_groups_new; + for (auto at : acl_attrs) { + sai_object_id_t acl_group; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &acl_group, m_switchId, 0, nullptr)); + acl_groups.push_back(acl_group); + + attr.id = at; + attr.value.oid = acl_group; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &acl_group, m_switchId, 0, nullptr)); + acl_groups_new.push_back(acl_group); + } + + sai_object_id_t eni; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_ENI, &eni, m_switchId, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, (uint32_t)attrs.size(), attrs.data())); + for (size_t i = 0; i < attrs.size(); i++) { + attr.id = attrs[i].id; + attr.value.oid = acl_groups_new[i]; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, &attr)); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni)); +} + +TEST_F(SyncdNvdaBfTest, dashVip) +{ + sai_attribute_t attr; + + std::vector attrs; + + attr.id = SAI_VIP_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT; + attrs.push_back(attr); + + sai_ip_address_t vip_addr; + vip_addr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &vip_addr.addr.ip4); + + sai_vip_entry_t vip = { .switch_id = m_switchId, .vip = vip_addr }; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create(&vip, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get(&vip, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.s32, SAI_VIP_ENTRY_ACTION_ACCEPT); + + attr.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID; + attr.value.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set(&vip, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove(&vip)); +} + +TEST_F(SyncdNvdaBfTest, dashVipBulk) +{ + const uint32_t vips_count = 2; + const uint32_t vip_attrs_count = 1; + + sai_attribute_t attrs0[] = { + {.id = SAI_VIP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_VIP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT}}, + }; + + const sai_attribute_t *attr_list[vips_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[vips_count] = {vip_attrs_count, vip_attrs_count}; + sai_status_t statuses[vips_count] = {}; + + sai_ip_address_t vip_addr0, vip_addr1; + vip_addr0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &vip_addr0.addr.ip4); + vip_addr1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &vip_addr1.addr.ip6); + + sai_vip_entry_t vips[vips_count] = { + {.switch_id = m_switchId, .vip = vip_addr0}, + {.switch_id = m_switchId, .vip = vip_addr1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkCreate(vips_count, vips, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vips_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkRemove(vips_count, vips, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vips_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST_F(SyncdNvdaBfTest, dashAclGroup) +{ + sai_attribute_t attr; + + std::vector attrs; + + attr.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY; + attr.value.s32 = SAI_IP_ADDR_FAMILY_IPV4; + attrs.push_back(attr); + + sai_object_id_t acl_group; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &acl_group, m_switchId, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, acl_group, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.s32, SAI_IP_ADDR_FAMILY_IPV4); + + attr.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY; + attr.value.s32 = SAI_IP_ADDR_FAMILY_IPV6; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, acl_group, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, acl_group)); +} + +TEST_F(SyncdNvdaBfTest, dashAclGroupBulk) +{ + const uint32_t acls_count = 2; + const uint32_t acl_attrs_count = 1; + + sai_attribute_t attrs0[acl_attrs_count] = { + {.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY, .value = (sai_attribute_value_t){.s32 = SAI_IP_ADDR_FAMILY_IPV4}}, + }; + + sai_attribute_t attrs1[acl_attrs_count] = { + {.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY, .value = (sai_attribute_value_t){.s32 = SAI_IP_ADDR_FAMILY_IPV6}}, + }; + + const sai_attribute_t *attr_list[acls_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[acls_count] = {acl_attrs_count, acl_attrs_count}; + sai_object_id_t acls[acls_count]; + sai_status_t statuses[acls_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, m_switchId, acls_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, acls, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, acls_count, acls, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST_F(SyncdNvdaBfTest, dashAclRule) +{ + sai_attribute_t attr; + + sai_object_id_t group; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &group, m_switchId, 0, nullptr)); + + sai_object_id_t counter = CreateCounter(); + + sai_ip_prefix_t ip_addr_list[2] = {}; + + ip_addr_list[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ip_addr_list[0].addr.ip4); + inet_pton(AF_INET, "255.255.0.0", &ip_addr_list[0].mask.ip4); + ip_addr_list[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &ip_addr_list[1].addr.ip6); + inet_pton(AF_INET6, "ffff:fff0::", &ip_addr_list[1].mask.ip6); + sai_ip_prefix_list_t ip_prefix_list0 = {.count = 2, .list = ip_addr_list}; + sai_ip_prefix_list_t ip_prefix_list1 = {.count = 1, .list = ip_addr_list}; + + uint8_t protos[2] = {0xAA, 0xBB}; + sai_u8_list_t protos_list = {.count=2, .list = protos}; + + sai_u16_range_t port_ranges[2] = {{.min = 10, .max = 20}, {.min = 30, .max = 40}}; + sai_u16_range_list_t port_ranges_list0 = {.count=2, .list = port_ranges}; + sai_u16_range_list_t port_ranges_list1 = {.count=1, .list = port_ranges}; + + std::vector attrs; + + attr.id = SAI_DASH_ACL_RULE_ATTR_ACTION; + attr.value.s32 = SAI_DASH_ACL_RULE_ACTION_PERMIT; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID; + attr.value.oid = group; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DIP; + attr.value.ipprefixlist = ip_prefix_list0; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_SIP; + attr.value.ipprefixlist = ip_prefix_list1; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL; + attr.value.u8list = protos_list; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT; + attr.value.u16rangelist = port_ranges_list0; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT; + attr.value.u16rangelist = port_ranges_list1; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY; + attr.value.u32 = 1; + attrs.push_back(attr); + + sai_object_id_t acl; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, &acl, m_switchId, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, acl, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.s32, SAI_DASH_ACL_RULE_ACTION_PERMIT); + EXPECT_EQ(attrs[1].value.oid, group); + ASSERT_TRUE(compare_lists(attrs[2].value.ipprefixlist, ip_prefix_list0)); + ASSERT_TRUE(compare_lists(attrs[3].value.ipprefixlist, ip_prefix_list1)); + ASSERT_TRUE(compare_lists(attrs[4].value.u8list, protos_list)); + ASSERT_TRUE(compare_lists(attrs[5].value.u16rangelist, port_ranges_list0)); + ASSERT_TRUE(compare_lists(attrs[6].value.u16rangelist, port_ranges_list1)); + EXPECT_EQ(attrs[7].value.oid, counter); + EXPECT_EQ(attrs[8].value.u32, 1); + + attr.id = SAI_DASH_ACL_RULE_ATTR_ACTION; + attr.value.s32 = SAI_DASH_ACL_RULE_ACTION_DENY_AND_CONTINUE; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, acl, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, acl)); + RemoveCounter(counter); + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, group)); +} + +TEST_F(SyncdNvdaBfTest, dashAclRuleBulk) +{ + const uint32_t acls_count = 2; + const uint32_t acl_attrs_count = 9; + + sai_object_id_t counter0 = CreateCounter(); + sai_object_id_t counter1 = CreateCounter(); + + sai_object_id_t group0; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &group0, m_switchId, 0, nullptr)); + + sai_object_id_t group1; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &group1, m_switchId, 0, nullptr)); + + sai_ip_prefix_t ip_prefix_arr0[2] = {}; + ip_prefix_arr0[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ip_prefix_arr0[0].addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &ip_prefix_arr0[0].mask.ip4); + ip_prefix_arr0[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &ip_prefix_arr0[1].addr.ip6); + inet_pton(AF_INET6, "ffff::", &ip_prefix_arr0[1].mask.ip6); + + sai_ip_prefix_t ip_prefix_arr1[2] = {}; + ip_prefix_arr1[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.2", &ip_prefix_arr1[0].addr.ip4); + inet_pton(AF_INET, "255.255.0.0", &ip_prefix_arr1[0].mask.ip4); + ip_prefix_arr1[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:fffe", &ip_prefix_arr1[1].addr.ip6); + inet_pton(AF_INET6, "ffff::", &ip_prefix_arr1[1].mask.ip6); + + sai_ip_prefix_list_t ip_prefix_list0 = {.count = 1, .list = ip_prefix_arr0}; + sai_ip_prefix_list_t ip_prefix_list1 = {.count = 1, .list = ip_prefix_arr1}; + + uint8_t protos0[2] = {0xAA, 0xBB}; + uint8_t protos1[2] = {0xCC, 0xDD}; + sai_u8_list_t protos_list0 = {.count=2, .list = protos0}; + sai_u8_list_t protos_list1 = {.count=2, .list = protos1}; + + sai_u16_range_t port_ranges0[2] = {{.min = 10, .max = 20}, {.min = 30, .max = 40}}; + sai_u16_range_t port_ranges1[2] = {{.min = 50, .max = 60}, {.min = 70, .max = 80}}; + sai_u16_range_list_t u16_range_list0 = {.count=2, .list = port_ranges0}; + sai_u16_range_list_t u16_range_list1 = {.count=2, .list = port_ranges1}; + + sai_attribute_t attrs0[acl_attrs_count] = { + {.id = SAI_DASH_ACL_RULE_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DASH_ACL_RULE_ACTION_PERMIT_AND_CONTINUE}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID, .value = (sai_attribute_value_t){.oid = group0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL, .value = (sai_attribute_value_t){.u8list = protos_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY, .value = (sai_attribute_value_t){.u32 = 1}}, + }; + + sai_attribute_t attrs1[acl_attrs_count] = { + {.id = SAI_DASH_ACL_RULE_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DASH_ACL_RULE_ACTION_DENY}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID, .value = (sai_attribute_value_t){.oid = group1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL, .value = (sai_attribute_value_t){.u8list = protos_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY, .value = (sai_attribute_value_t){.u32 = 2}}, + }; + + const sai_attribute_t *attr_list[acls_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[acls_count] = {acl_attrs_count, acl_attrs_count}; + sai_object_id_t acls[acls_count]; + sai_status_t statuses[acls_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, m_switchId, acls_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, acls, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, acls_count, acls, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, group0)); + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, group1)); + RemoveCounter(counter0); + RemoveCounter(counter1); +} + +TEST_F(SyncdNvdaBfTest, dashVnet) +{ + sai_attribute_t attr; + + sai_object_id_t vnet; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 10; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create((sai_object_type_t)SAI_OBJECT_TYPE_VNET, &vnet, m_switchId, 1, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnet, 1, &attr)); + EXPECT_EQ(attr.value.u32, 10); + + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 20; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnet, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnet)); +} + +TEST_F(SyncdNvdaBfTest, dashVnetBulk) +{ + const uint32_t vnets_count = 2; + const uint32_t vnet_attrs_count = 1; + + sai_attribute_t attrs0[] = { + {.id = SAI_VNET_ATTR_VNI, .value = (sai_attribute_value_t){.u32 = 10}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_VNET_ATTR_VNI, .value = (sai_attribute_value_t){.u32 = 20}}, + }; + + const sai_attribute_t *attr_list[vnets_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[vnets_count] = {vnet_attrs_count, vnet_attrs_count}; + sai_object_id_t vnets[vnets_count]; + sai_status_t statuses[vnets_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_VNET, m_switchId, vnets_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, vnets, statuses)); + for (uint32_t i = 0; i < vnets_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnets_count, vnets, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vnets_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST_F(SyncdNvdaBfTest, dashInboundRoutingEntry) +{ + sai_attribute_t attr; + + sai_object_id_t vnet = CreateVnet(10); + sai_object_id_t eni = CreateEni(vnet); + + sai_ip_address_t sip, sip_mask; + sip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &sip.addr.ip4); + sip_mask.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.255.0", &sip_mask.addr.ip4); + + sai_inbound_routing_entry_t entry = { .switch_id = m_switchId, .eni_id = eni, .vni = 10, .sip = sip, .sip_mask = sip_mask, .priority = 1}; + + std::vector attrs; + attr.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE; + attrs.push_back(attr); + + attr.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get(&entry, (uint32_t)attrs.size(), attrs.data())); + + attr.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set(&entry, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove(&entry)); + RemoveEni(eni); + RemoveVnet(vnet); +} + +TEST_F(SyncdNvdaBfTest, dashInboundRoutingEntryBulk) +{ + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 2; + + sai_object_id_t vnet0 = CreateVnet(101); + sai_object_id_t eni0 = CreateEni(vnet0); + + sai_object_id_t vnet1 = CreateVnet(102); + sai_object_id_t eni1 = CreateEni(vnet0); + + sai_ip_address_t sip0, sip_mask0; + sai_ip_address_t sip1, sip_mask1; + sip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &sip0.addr.ip4); + sip_mask0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.255.0", &sip_mask0.addr.ip4); + sip1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.2", &sip1.addr.ip4); + sip_mask1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.0.0", &sip_mask1.addr.ip4); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP}}, + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP}}, + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_inbound_routing_entry_t entries[entries_count] = { + { .switch_id = m_switchId, .eni_id = eni0, .vni = 10, .sip = sip0, .sip_mask = sip_mask0, .priority = 1}, + { .switch_id = m_switchId, .eni_id = eni1, .vni = 100, .sip = sip1, .sip_mask = sip_mask1, .priority = 2} + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + RemoveEni(eni0); + RemoveEni(eni1); + RemoveVnet(vnet0); + RemoveVnet(vnet1); +} + +TEST_F(SyncdNvdaBfTest, dashPaValidation) +{ + sai_attribute_t attr; + + sai_object_id_t vnet = CreateVnet(10); + + sai_pa_validation_entry_t entry; + entry.switch_id = m_switchId; + entry.vnet_id = vnet; + entry.sip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.3.3.3", &entry.sip.addr.ip4); + + std::vector attrs; + attr.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get(&entry, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.s32, SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT); + + attr.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set(&entry, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove(&entry)); + RemoveVnet(vnet); +} + +TEST_F(SyncdNvdaBfTest, dashPaValidationBulk) +{ + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 1; + + sai_object_id_t vnet0 = CreateVnet(10); + sai_object_id_t vnet1 = CreateVnet(20); + + sai_ip_address_t sip0 = {}; + sai_ip_address_t sip1 = {}; + sip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + sip1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET, "192.1.1.1", &sip0.addr.ip4); + inet_pton(AF_INET6, "ffff::", &sip1.addr.ip6); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_pa_validation_entry_t entries[entries_count] = { + { .switch_id = m_switchId, .vnet_id = vnet0, .sip = sip0}, + { .switch_id = m_switchId, .vnet_id = vnet1, .sip = sip1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + RemoveVnet(vnet0); + RemoveVnet(vnet1); +} + +TEST_F(SyncdNvdaBfTest, dashOutboundRoutingEntry) +{ + sai_attribute_t attr; + + sai_object_id_t counter = CreateCounter(); + sai_object_id_t vnet = CreateVnet(101); + sai_object_id_t eni = CreateEni(vnet); + + sai_ip_address_t oip6; + oip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "ffff::", &oip6.addr); + + sai_outbound_routing_entry_t entry0; + entry0.switch_id = m_switchId; + entry0.eni_id = eni; + entry0.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.1.0", &entry0.destination.addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &entry0.destination.mask.ip4); + + std::vector attrs; + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.u32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP; + attr.value.ipaddr = oip6; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create(&entry0, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get(&entry0, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.u32, SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET); + EXPECT_EQ(attrs[1].value.oid, vnet); + EXPECT_EQ(attrs[2].value.ipaddr, oip6); + EXPECT_EQ(attrs[3].value.oid, counter); + + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.u32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_DIRECT; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set(&entry0, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove(&entry0)); + + RemoveEni(eni); + RemoveVnet(vnet); + RemoveCounter(counter); +} + +TEST_F(SyncdNvdaBfTest, dashOutboundRoutingEntryBulk) +{ + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 4; + + sai_object_id_t counter0 = CreateCounter(); + sai_object_id_t counter1 = CreateCounter(); + + sai_ip_address_t oip4, oip6; + oip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "1.2.3.4", &oip4.addr); + oip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "ffff::", &oip6.addr); + + sai_object_id_t vnet0 = CreateVnet(101); + sai_object_id_t vnet1 = CreateVnet(102); + sai_object_id_t eni0 = CreateEni(vnet0); + sai_object_id_t eni1 = CreateEni(vnet1); + + sai_ip_prefix_t dst0 = {}; + sai_ip_prefix_t dst1 = {}; + dst0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + dst1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET, "192.1.1.1", &dst0.addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &dst0.mask.ip4); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe0", &dst1.addr.ip6); + inet_pton(AF_INET6, "ffff:ffff::", &dst1.mask.ip6); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP, .value = (sai_attribute_value_t){.ipaddr = oip4}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP, .value = (sai_attribute_value_t){.ipaddr = oip6}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_outbound_routing_entry_t entries[entries_count] = { + { .switch_id = m_switchId, .eni_id = eni0, .destination = dst0}, + { .switch_id = m_switchId, .eni_id = eni1, .destination = dst1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + RemoveEni(eni0); + RemoveEni(eni1); + RemoveVnet(vnet0); + RemoveVnet(vnet1); + RemoveCounter(counter0); + RemoveCounter(counter1); +} + +TEST_F(SyncdNvdaBfTest, dashOutboundCaToPaEntry) +{ + sai_object_id_t counter = CreateCounter(); + + sai_ip_address_t uip4; + uip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &uip4.addr.ip4); + + sai_object_id_t vnet = CreateVnet(10); + + sai_outbound_ca_to_pa_entry_t entry; + entry.switch_id = m_switchId; + entry.dst_vnet_id = vnet; + entry.dip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &entry.dip.addr.ip4); + + sai_attribute_t attr; + std::vector attrs; + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP; + attr.value.ipaddr = uip4; + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC; + sai_mac_t dmac = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + memcpy(attr.value.mac, dmac, 6); + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI; + attr.value.booldata = true; + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->get(&entry, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.ipaddr, uip4); + EXPECT_EQ(memcmp(attrs[1].value.mac, dmac, sizeof(dmac)), 0); + EXPECT_EQ(attrs[2].value.booldata, true); + EXPECT_EQ(attrs[3].value.oid, counter); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI; + attr.value.booldata = true; + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->set(&entry, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->remove(&entry)); + + RemoveVnet(vnet); + RemoveCounter(counter); +} + +TEST_F(SyncdNvdaBfTest, dashOutboundCaToPaEntryBulk) +{ + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 4; + + sai_object_id_t counter0 = CreateCounter(); + sai_object_id_t counter1 = CreateCounter(); + + sai_object_id_t vnet0 = CreateVnet(10); + sai_object_id_t vnet1 = CreateVnet(20); + + sai_ip_address_t dip0 = {}; + sai_ip_address_t dip1 = {}; + sai_ip_address_t udip0 = {}; + sai_ip_address_t udip1 = {}; + dip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + dip1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + udip0.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + udip1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.1.1.1", &dip0.addr.ip4); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe0", &dip1.addr.ip6); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe1", &udip0.addr.ip6); + inet_pton(AF_INET, "192.1.1.2", &udip1.addr.ip4); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = udip0}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC, .value = (sai_attribute_value_t){.mac = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}} + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = udip1}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC, .value = (sai_attribute_value_t){.mac = {0x00, 0x11, 0x22, 0x33, 0x44, 0x56}}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI, .value = (sai_attribute_value_t){.booldata = false}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}} + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_outbound_ca_to_pa_entry_t entries[entries_count] = { + { .switch_id = m_switchId, .dst_vnet_id = vnet0, .dip = dip0}, + { .switch_id = m_switchId, .dst_vnet_id = vnet1, .dip = dip1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m_sairedis->bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + RemoveVnet(vnet0); + RemoveVnet(vnet1); + RemoveCounter(counter0); + RemoveCounter(counter1); +} diff --git a/syncd/tests/TestSyncdNvdaBf.h b/syncd/tests/TestSyncdNvdaBf.h new file mode 100644 index 000000000..fa8e547b9 --- /dev/null +++ b/syncd/tests/TestSyncdNvdaBf.h @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include "Sai.h" +#include "Syncd.h" +#include "MetadataLogger.h" + +#include "TestSyncdLib.h" + +class SyncdNvdaBfTest : public ::testing::Test +{ +public: + SyncdNvdaBfTest() = default; + virtual ~SyncdNvdaBfTest() = default; + +public: + virtual void SetUp() override; + + virtual void TearDown() override; + + sai_object_id_t CreateCounter(); + void RemoveCounter(sai_object_id_t counter); + + sai_object_id_t CreateVnet(uint32_t vni); + void RemoveVnet(sai_object_id_t vnet); + + sai_object_id_t CreateEni(sai_object_id_t vnet); + void RemoveEni(sai_object_id_t eni); + +protected: + std::shared_ptr m_worker; + std::shared_ptr m_sairedis; + + sai_object_id_t m_switchId = SAI_NULL_OBJECT_ID; +}; diff --git a/syncd/tests/nvda-bf/lanemap.ini b/syncd/tests/nvda-bf/lanemap.ini new file mode 100644 index 000000000..0967d7eb6 --- /dev/null +++ b/syncd/tests/nvda-bf/lanemap.ini @@ -0,0 +1,2 @@ +eth1:0,1,2,3 +eth2:4,5,6,7 diff --git a/syncd/tests/nvda-bf/sai.profile b/syncd/tests/nvda-bf/sai.profile new file mode 100644 index 000000000..2f77fa8e4 --- /dev/null +++ b/syncd/tests/nvda-bf/sai.profile @@ -0,0 +1,5 @@ +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_NVDA_MBF2H536C +SAI_VS_HOSTIF_USE_TAP_DEVICE=false +SAI_VS_INTERFACE_LANE_MAP_FILE=./nvda-bf/lanemap.ini +SAI_WARM_BOOT_READ_FILE=./sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=./sai_warmboot.bin diff --git a/tests/Makefile.am b/tests/Makefile.am index 14b8902d2..7405bab0d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,6 @@ AM_CXXFLAGS = $(SAIINC) -I$(top_srcdir)/lib -I$(top_srcdir)/vslib -bin_PROGRAMS = vssyncd tests testclient +bin_PROGRAMS = vssyncd tests testclient testdash_gtest SAILIB=-L$(top_srcdir)/vslib/.libs -lsaivs @@ -21,10 +21,16 @@ tests_LDADD = -lhiredis -lswsscommon -lpthread \ $(top_srcdir)/lib/libsairedis.la $(top_srcdir)/syncd/libSyncd.a \ -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) -testclient_SOURCES = testclient.cpp +testclient_SOURCES = TestClient.cpp testclient.cpp testclient_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) testclient_LDADD = -lhiredis -lswsscommon -lpthread \ $(top_srcdir)/lib/libsairedis.la $(top_srcdir)/syncd/libSyncd.a \ -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) -TESTS = aspellcheck.pl conflictnames.pl swsslogentercheck.sh checkwhitespace.sh tests BCM56850.pl MLNX2700.pl BCM56971B0.pl +testdash_gtest_SOURCES = TestDashMain.cpp TestDash.cpp TestDashEnv.cpp +testdash_gtest_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) +testdash_gtest_LDADD = -lgtest -lhiredis -lswsscommon -lpthread \ + $(top_srcdir)/lib/libsairedis.la $(top_srcdir)/syncd/libSyncd.a \ + -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) + +TESTS = aspellcheck.pl conflictnames.pl swsslogentercheck.sh checkwhitespace.sh tests BCM56850.pl MLNX2700.pl BCM56971B0.pl NVDAMBF2H536C.pl testdash_gtest diff --git a/tests/NVDAMBF2H536C.pl b/tests/NVDAMBF2H536C.pl new file mode 100755 index 000000000..f0dc64f57 --- /dev/null +++ b/tests/NVDAMBF2H536C.pl @@ -0,0 +1,30 @@ +#!/usr/bin/perl + +BEGIN { push @INC,'.'; } + +use strict; +use warnings; +use diagnostics; + +use utils; + +sub test_dashapi_replay +{ + fresh_start; + + play "dashapis.rec"; +} + +sub test_dashapi_replay_bulk +{ + fresh_start_bulk; + + play "dashapis.rec"; +} + +# RUN + +test_dashapi_replay; +test_dashapi_replay_bulk; + +kill_syncd; diff --git a/tests/NVDAMBF2H536C/client_switch.rec b/tests/NVDAMBF2H536C/client_switch.rec new file mode 100644 index 000000000..368458f0c --- /dev/null +++ b/tests/NVDAMBF2H536C/client_switch.rec @@ -0,0 +1,7 @@ +2020-12-31.21:34:31.861834|a|INIT_VIEW +2020-12-31.21:34:31.862379|A|SAI_STATUS_SUCCESS +2020-12-31.21:34:31.864591|c|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_INIT_SWITCH=true +2020-12-31.21:34:41.215885|a|APPLY_VIEW +2020-12-31.21:34:41.216326|A|SAI_STATUS_SUCCESS +2020-12-31.21:34:41.216326|#|give 5 seconds to client to connect to existing switch +2020-12-31.21:34:41.216326|@|5000 diff --git a/tests/NVDAMBF2H536C/dashapis.rec b/tests/NVDAMBF2H536C/dashapis.rec new file mode 100644 index 000000000..d0638864e --- /dev/null +++ b/tests/NVDAMBF2H536C/dashapis.rec @@ -0,0 +1,312 @@ +2022-11-17.15:01:04.063626|#|recording on: ./sairedis.rec +2022-11-17.15:01:04.063714|a|INIT_VIEW +2022-11-17.15:01:04.125841|A|SAI_STATUS_SUCCESS +2022-11-17.15:01:04.127125|c|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_INIT_SWITCH=true +2022-11-17.15:01:04.187654|a|APPLY_VIEW +2022-11-17.15:01:04.188010|A|SAI_STATUS_SUCCESS +2022-11-17.15:01:04.188195|c|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:{"switch_id":"oid:0x21000000000000","vni":"1"}|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION +2022-11-17.15:01:04.188645|s|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:{"switch_id":"oid:0x21000000000000","vni":"1"}|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION +2022-11-17.15:01:04.189089|g|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:{"switch_id":"oid:0x21000000000000","vni":"1"}|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION +2022-11-17.15:01:04.189552|G|SAI_STATUS_SUCCESS|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION +2022-11-17.15:01:04.189590|r|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:{"switch_id":"oid:0x21000000000000","vni":"1"} +2022-11-17.15:01:04.190026|c|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:{"switch_id":"oid:0x21000000000000","vni":"1"}|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION +2022-11-17.15:01:04.190408|r|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:{"switch_id":"oid:0x21000000000000","vni":"1"} +2022-11-17.15:01:04.190857|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000067|SAI_VNET_ATTR_VNI=100 +2022-11-17.15:01:04.191389|c|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000068|SAI_ENI_ATTR_VNET_ID=oid:0x71000000000067 +2022-11-17.15:01:04.191905|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000069|SAI_VNET_ATTR_VNI=200 +2022-11-17.15:01:04.192404|c|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000006a|SAI_ENI_ATTR_VNET_ID=oid:0x71000000000069 +2022-11-17.15:01:04.192985|c|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"}|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x6d000000000068 +2022-11-17.15:01:04.193406|g|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"}|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x0 +2022-11-17.15:01:04.193906|G|SAI_STATUS_SUCCESS|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x6d000000000068 +2022-11-17.15:01:04.193955|s|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"}|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x6d00000000006a +2022-11-17.15:01:04.194346|g|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"}|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x0 +2022-11-17.15:01:04.194823|G|SAI_STATUS_SUCCESS|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x6d00000000006a +2022-11-17.15:01:04.194856|r|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.195220|r|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000068 +2022-11-17.15:01:04.195652|r|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000006a +2022-11-17.15:01:04.196064|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000067 +2022-11-17.15:01:04.196471|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000069 +2022-11-17.15:01:04.196980|c|SAI_OBJECT_TYPE_VNET:oid:0x7100000000006b|SAI_VNET_ATTR_VNI=100 +2022-11-17.15:01:04.197476|c|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000006c|SAI_ENI_ATTR_VNET_ID=oid:0x7100000000006b +2022-11-17.15:01:04.197971|c|SAI_OBJECT_TYPE_VNET:oid:0x7100000000006d|SAI_VNET_ATTR_VNI=200 +2022-11-17.15:01:04.198523|c|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000006e|SAI_ENI_ATTR_VNET_ID=oid:0x7100000000006d +2022-11-17.15:01:04.199006|c|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"}|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x6d00000000006c +2022-11-17.15:01:04.199395|r|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.199777|r|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000006c +2022-11-17.15:01:04.200183|r|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000006e +2022-11-17.15:01:04.200596|r|SAI_OBJECT_TYPE_VNET:oid:0x7100000000006b +2022-11-17.15:01:04.201031|r|SAI_OBJECT_TYPE_VNET:oid:0x7100000000006d +2022-11-17.15:01:04.201524|c|SAI_OBJECT_TYPE_VNET:oid:0x7100000000006f|SAI_VNET_ATTR_VNI=101 +2022-11-17.15:01:04.202047|c|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000070|SAI_ENI_ATTR_VNET_ID=oid:0x7100000000006f|SAI_ENI_ATTR_ADMIN_STATE=true|SAI_ENI_ATTR_VM_VNI=123|SAI_ENI_ATTR_CPS=10|SAI_ENI_ATTR_FLOWS=30|SAI_ENI_ATTR_VM_UNDERLAY_DIP=192.168.0.1 +2022-11-17.15:01:04.202581|g|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000070|SAI_ENI_ATTR_VNET_ID=oid:0x0|SAI_ENI_ATTR_ADMIN_STATE=true|SAI_ENI_ATTR_VM_VNI=123|SAI_ENI_ATTR_CPS=10|SAI_ENI_ATTR_FLOWS=30|SAI_ENI_ATTR_VM_UNDERLAY_DIP=192.168.0.1 +2022-11-17.15:01:04.203367|G|SAI_STATUS_SUCCESS|SAI_ENI_ATTR_VNET_ID=oid:0x7100000000006f|SAI_ENI_ATTR_ADMIN_STATE=true|SAI_ENI_ATTR_VM_VNI=123|SAI_ENI_ATTR_CPS=10|SAI_ENI_ATTR_FLOWS=30|SAI_ENI_ATTR_VM_UNDERLAY_DIP=192.168.0.1 +2022-11-17.15:01:04.203399|s|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000070|SAI_ENI_ATTR_CPS=40 +2022-11-17.15:01:04.203768|g|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000070|SAI_ENI_ATTR_VNET_ID=oid:0x0|SAI_ENI_ATTR_ADMIN_STATE=true|SAI_ENI_ATTR_VM_VNI=123|SAI_ENI_ATTR_CPS=10|SAI_ENI_ATTR_FLOWS=30|SAI_ENI_ATTR_VM_UNDERLAY_DIP=192.168.0.1 +2022-11-17.15:01:04.204467|G|SAI_STATUS_SUCCESS|SAI_ENI_ATTR_VNET_ID=oid:0x7100000000006f|SAI_ENI_ATTR_ADMIN_STATE=true|SAI_ENI_ATTR_VM_VNI=123|SAI_ENI_ATTR_CPS=40|SAI_ENI_ATTR_FLOWS=30|SAI_ENI_ATTR_VM_UNDERLAY_DIP=192.168.0.1 +2022-11-17.15:01:04.204491|r|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000070 +2022-11-17.15:01:04.204992|r|SAI_OBJECT_TYPE_VNET:oid:0x7100000000006f +2022-11-17.15:01:04.205493|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000071|SAI_VNET_ATTR_VNI=101 +2022-11-17.15:01:04.206000|c|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000072|SAI_ENI_ATTR_VNET_ID=oid:0x71000000000071|SAI_ENI_ATTR_ADMIN_STATE=true|SAI_ENI_ATTR_VM_VNI=123|SAI_ENI_ATTR_CPS=10|SAI_ENI_ATTR_FLOWS=30|SAI_ENI_ATTR_VM_UNDERLAY_DIP=192.168.0.1 +2022-11-17.15:01:04.206501|r|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000072 +2022-11-17.15:01:04.207013|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000071 +2022-11-17.15:01:04.207479|c|SAI_OBJECT_TYPE_VIP_ENTRY:{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"}|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.207891|g|SAI_OBJECT_TYPE_VIP_ENTRY:{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"}|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.208331|G|SAI_STATUS_SUCCESS|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.208372|s|SAI_OBJECT_TYPE_VIP_ENTRY:{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"}|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.208755|g|SAI_OBJECT_TYPE_VIP_ENTRY:{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"}|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.209202|G|SAI_STATUS_SUCCESS|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.209234|r|SAI_OBJECT_TYPE_VIP_ENTRY:{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"} +2022-11-17.15:01:04.209637|c|SAI_OBJECT_TYPE_VIP_ENTRY:{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"}|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.210020|r|SAI_OBJECT_TYPE_VIP_ENTRY:{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"} +2022-11-17.15:01:04.210521|c|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000073|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV4 +2022-11-17.15:01:04.210985|g|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000073|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV4 +2022-11-17.15:01:04.211381|G|SAI_STATUS_SUCCESS|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV4 +2022-11-17.15:01:04.211409|s|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000073|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV6 +2022-11-17.15:01:04.211760|g|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000073|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV4 +2022-11-17.15:01:04.212162|G|SAI_STATUS_SUCCESS|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV6 +2022-11-17.15:01:04.212184|r|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000073 +2022-11-17.15:01:04.212676|c|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000074|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV4 +2022-11-17.15:01:04.213141|r|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000074 +2022-11-17.15:01:04.213638|c|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000075|NULL=NULL +2022-11-17.15:01:04.214156|c|SAI_OBJECT_TYPE_DASH_ACL_RULE:oid:0x6a000000000076|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_PERMIT|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x69000000000075|SAI_DASH_ACL_RULE_ATTR_DIP=2:192.168.0.1/16,100::ffff:ffff:ffff:ffff/28|SAI_DASH_ACL_RULE_ATTR_SIP=2:192.168.0.1/16,100::ffff:ffff:ffff:ffff/28|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:170,187|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_PRIORITY=1 +2022-11-17.15:01:04.214932|g|SAI_OBJECT_TYPE_DASH_ACL_RULE:oid:0x6a000000000076|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_PERMIT|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x0|SAI_DASH_ACL_RULE_ATTR_DIP=2:192.168.0.1/16,100::ffff:ffff:ffff:ffff/28|SAI_DASH_ACL_RULE_ATTR_SIP=2:192.168.0.1/16,100::ffff:ffff:ffff:ffff/28|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:170,187|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_PRIORITY=1 +2022-11-17.15:01:04.215950|G|SAI_STATUS_SUCCESS|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_PERMIT|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x69000000000075|SAI_DASH_ACL_RULE_ATTR_DIP=2:192.168.0.1/16,100::ffff:ffff:ffff:ffff/28|SAI_DASH_ACL_RULE_ATTR_SIP=2:192.168.0.1/16,100::ffff:ffff:ffff:ffff/28|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:170,187|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_PRIORITY=1 +2022-11-17.15:01:04.215984|s|SAI_OBJECT_TYPE_DASH_ACL_RULE:oid:0x6a000000000076|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_DENY_AND_CONTINUE +2022-11-17.15:01:04.216353|g|SAI_OBJECT_TYPE_DASH_ACL_RULE:oid:0x6a000000000076|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_PERMIT +2022-11-17.15:01:04.216753|G|SAI_STATUS_SUCCESS|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_DENY_AND_CONTINUE +2022-11-17.15:01:04.216786|r|SAI_OBJECT_TYPE_DASH_ACL_RULE:oid:0x6a000000000076 +2022-11-17.15:01:04.217280|r|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000075 +2022-11-17.15:01:04.217776|c|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000077|NULL=NULL +2022-11-17.15:01:04.218277|c|SAI_OBJECT_TYPE_DASH_ACL_RULE:oid:0x6a000000000078|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_PERMIT|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x69000000000077|SAI_DASH_ACL_RULE_ATTR_DIP=2:192.168.0.1/16,100::ffff:ffff:ffff:ffff/28|SAI_DASH_ACL_RULE_ATTR_SIP=2:192.168.0.1/16,100::ffff:ffff:ffff:ffff/28|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:170,187|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_PRIORITY=1 +2022-11-17.15:01:04.218968|r|SAI_OBJECT_TYPE_DASH_ACL_RULE:oid:0x6a000000000078 +2022-11-17.15:01:04.219520|r|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000077 +2022-11-17.15:01:04.220009|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000079|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.220462|g|SAI_OBJECT_TYPE_VNET:oid:0x71000000000079|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.220882|G|SAI_STATUS_SUCCESS|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.220912|s|SAI_OBJECT_TYPE_VNET:oid:0x71000000000079|SAI_VNET_ATTR_VNI=20 +2022-11-17.15:01:04.221276|g|SAI_OBJECT_TYPE_VNET:oid:0x71000000000079|SAI_VNET_ATTR_VNI=20 +2022-11-17.15:01:04.221675|G|SAI_STATUS_SUCCESS|SAI_VNET_ATTR_VNI=20 +2022-11-17.15:01:04.221697|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000079 +2022-11-17.15:01:04.222193|c|SAI_OBJECT_TYPE_VNET:oid:0x7100000000007a|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.222660|r|SAI_OBJECT_TYPE_VNET:oid:0x7100000000007a +2022-11-17.15:01:04.223220|c|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000007b|NULL=NULL +2022-11-17.15:01:04.223690|c|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:{"eni_id":"oid:0x6d00000000007b","priority":"1","sip":"192.168.0.1","sip_mask":"255.255.255.0","switch_id":"oid:0x21000000000000","vni":"10"}|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP +2022-11-17.15:01:04.224138|s|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:{"eni_id":"oid:0x6d00000000007b","priority":"1","sip":"192.168.0.1","sip_mask":"255.255.255.0","switch_id":"oid:0x21000000000000","vni":"10"}|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE +2022-11-17.15:01:04.224560|g|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:{"eni_id":"oid:0x6d00000000007b","priority":"1","sip":"192.168.0.1","sip_mask":"255.255.255.0","switch_id":"oid:0x21000000000000","vni":"10"}|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP +2022-11-17.15:01:04.225037|G|SAI_STATUS_SUCCESS|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE +2022-11-17.15:01:04.225075|r|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:{"eni_id":"oid:0x6d00000000007b","priority":"1","sip":"192.168.0.1","sip_mask":"255.255.255.0","switch_id":"oid:0x21000000000000","vni":"10"} +2022-11-17.15:01:04.225461|r|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000007b +2022-11-17.15:01:04.225958|c|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000007c|NULL=NULL +2022-11-17.15:01:04.226413|c|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:{"eni_id":"oid:0x6d00000000007c","priority":"1","sip":"192.168.0.1","sip_mask":"255.255.255.0","switch_id":"oid:0x21000000000000","vni":"10"}|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP +2022-11-17.15:01:04.226816|r|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:{"eni_id":"oid:0x6d00000000007c","priority":"1","sip":"192.168.0.1","sip_mask":"255.255.255.0","switch_id":"oid:0x21000000000000","vni":"10"} +2022-11-17.15:01:04.227204|r|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000007c +2022-11-17.15:01:04.227701|c|SAI_OBJECT_TYPE_VNET:oid:0x7100000000007d|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.228179|c|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:{"sip":"192.3.3.3","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x7100000000007d"}|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT +2022-11-17.15:01:04.228599|s|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:{"sip":"192.3.3.3","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x7100000000007d"}|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT +2022-11-17.15:01:04.229083|g|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:{"sip":"192.3.3.3","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x7100000000007d"}|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT +2022-11-17.15:01:04.229527|G|SAI_STATUS_SUCCESS|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT +2022-11-17.15:01:04.229560|r|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:{"sip":"192.3.3.3","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x7100000000007d"} +2022-11-17.15:01:04.229928|r|SAI_OBJECT_TYPE_VNET:oid:0x7100000000007d +2022-11-17.15:01:04.230429|c|SAI_OBJECT_TYPE_VNET:oid:0x7100000000007e|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.230903|c|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:{"sip":"192.3.3.3","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x7100000000007e"}|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT +2022-11-17.15:01:04.231296|r|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:{"sip":"192.3.3.3","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x7100000000007e"} +2022-11-17.15:01:04.231665|r|SAI_OBJECT_TYPE_VNET:oid:0x7100000000007e +2022-11-17.15:01:04.232160|c|SAI_OBJECT_TYPE_VNET:oid:0x7100000000007f|SAI_VNET_ATTR_VNI=101 +2022-11-17.15:01:04.232663|c|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000080|SAI_ENI_ATTR_VNET_ID=oid:0x7100000000007f +2022-11-17.15:01:04.233159|c|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:{"destination":"192.168.1.0/24","eni_id":"oid:0x6d000000000080","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x7100000000007f +2022-11-17.15:01:04.233627|g|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:{"destination":"192.168.1.0/24","eni_id":"oid:0x6d000000000080","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x0 +2022-11-17.15:01:04.234212|G|SAI_STATUS_SUCCESS|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x7100000000007f +2022-11-17.15:01:04.234260|s|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:{"destination":"192.168.1.0/24","eni_id":"oid:0x6d000000000080","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_DIRECT +2022-11-17.15:01:04.234724|g|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:{"destination":"192.168.1.0/24","eni_id":"oid:0x6d000000000080","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x0 +2022-11-17.15:01:04.235311|G|SAI_STATUS_SUCCESS|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_DIRECT|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x7100000000007f +2022-11-17.15:01:04.235346|r|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:{"destination":"192.168.1.0/24","eni_id":"oid:0x6d000000000080","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.235726|r|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000080 +2022-11-17.15:01:04.236151|r|SAI_OBJECT_TYPE_VNET:oid:0x7100000000007f +2022-11-17.15:01:04.236650|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000081|SAI_VNET_ATTR_VNI=101 +2022-11-17.15:01:04.237179|c|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000082|SAI_ENI_ATTR_VNET_ID=oid:0x71000000000081 +2022-11-17.15:01:04.237663|c|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:{"destination":"192.168.1.0/24","eni_id":"oid:0x6d000000000082","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x71000000000081 +2022-11-17.15:01:04.238082|r|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:{"destination":"192.168.1.0/24","eni_id":"oid:0x6d000000000082","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.238459|r|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000082 +2022-11-17.15:01:04.238878|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000081 +2022-11-17.15:01:04.239377|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000083|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.239866|c|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"192.168.0.1","dst_vnet_id":"oid:0x71000000000083","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=192.168.0.1|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:01:02:03:04:05|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=false +2022-11-17.15:01:04.240326|s|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"192.168.0.1","dst_vnet_id":"oid:0x71000000000083","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=true +2022-11-17.15:01:04.240798|g|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"192.168.0.1","dst_vnet_id":"oid:0x71000000000083","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=true +2022-11-17.15:01:04.241242|G|SAI_STATUS_SUCCESS|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=true +2022-11-17.15:01:04.241275|r|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"192.168.0.1","dst_vnet_id":"oid:0x71000000000083","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.241645|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000083 +2022-11-17.15:01:04.242149|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000084|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.242628|c|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"192.168.0.1","dst_vnet_id":"oid:0x71000000000084","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=192.168.0.1|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:01:02:03:04:05|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=false +2022-11-17.15:01:04.243067|r|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"192.168.0.1","dst_vnet_id":"oid:0x71000000000084","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.243454|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000084 +2022-11-17.15:01:04.243961|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000085|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.244441|c|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"fe80::886a:feff:fe31:bfe0","dst_vnet_id":"oid:0x71000000000085","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=fe80::886a:feff:fe31:bfe0|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:02:03:04:05:06|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=true +2022-11-17.15:01:04.244900|s|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"fe80::886a:feff:fe31:bfe0","dst_vnet_id":"oid:0x71000000000085","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=true +2022-11-17.15:01:04.245305|g|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"fe80::886a:feff:fe31:bfe0","dst_vnet_id":"oid:0x71000000000085","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=true +2022-11-17.15:01:04.245743|G|SAI_STATUS_SUCCESS|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=true +2022-11-17.15:01:04.245773|r|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"fe80::886a:feff:fe31:bfe0","dst_vnet_id":"oid:0x71000000000085","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.246207|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000085 +2022-11-17.15:01:04.246717|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000086|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.247197|c|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"fe80::886a:feff:fe31:bfe0","dst_vnet_id":"oid:0x71000000000086","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=fe80::886a:feff:fe31:bfe0|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:02:03:04:05:06|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=true +2022-11-17.15:01:04.247631|r|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"fe80::886a:feff:fe31:bfe0","dst_vnet_id":"oid:0x71000000000086","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.248027|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000086 +2022-11-17.15:01:04.248552|C|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY||{"switch_id":"oid:0x21000000000000","vni":"10"}|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION||{"switch_id":"oid:0x21000000000000","vni":"20"}|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION +2022-11-17.15:01:04.249058|g|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:{"switch_id":"oid:0x21000000000000","vni":"10"}|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION +2022-11-17.15:01:04.249516|G|SAI_STATUS_SUCCESS|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION +2022-11-17.15:01:04.249555|g|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY:{"switch_id":"oid:0x21000000000000","vni":"20"}|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION +2022-11-17.15:01:04.249974|G|SAI_STATUS_SUCCESS|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION +2022-11-17.15:01:04.250018|R|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY||{"switch_id":"oid:0x21000000000000","vni":"10"}||{"switch_id":"oid:0x21000000000000","vni":"20"} +2022-11-17.15:01:04.250494|C|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY||{"switch_id":"oid:0x21000000000000","vni":"10"}|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION||{"switch_id":"oid:0x21000000000000","vni":"20"}|SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION=SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION +2022-11-17.15:01:04.250955|R|SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY||{"switch_id":"oid:0x21000000000000","vni":"10"}||{"switch_id":"oid:0x21000000000000","vni":"20"} +2022-11-17.15:01:04.251475|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000087|SAI_VNET_ATTR_VNI=100 +2022-11-17.15:01:04.251989|c|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000088|SAI_ENI_ATTR_VNET_ID=oid:0x71000000000087 +2022-11-17.15:01:04.252562|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000089|SAI_VNET_ATTR_VNI=200 +2022-11-17.15:01:04.253077|c|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000008a|SAI_ENI_ATTR_VNET_ID=oid:0x71000000000089 +2022-11-17.15:01:04.253561|C|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY||{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"}|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x6d000000000088||{"address":"00:01:02:03:04:06","switch_id":"oid:0x21000000000000"}|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x6d00000000008a +2022-11-17.15:01:04.254039|g|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"}|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x0 +2022-11-17.15:01:04.254534|G|SAI_STATUS_SUCCESS|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x6d000000000088 +2022-11-17.15:01:04.254576|g|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY:{"address":"00:01:02:03:04:06","switch_id":"oid:0x21000000000000"}|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x0 +2022-11-17.15:01:04.255050|G|SAI_STATUS_SUCCESS|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x6d00000000008a +2022-11-17.15:01:04.255091|R|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY||{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"}||{"address":"00:01:02:03:04:06","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.255529|r|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000088 +2022-11-17.15:01:04.255965|r|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000008a +2022-11-17.15:01:04.256370|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000087 +2022-11-17.15:01:04.256794|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000089 +2022-11-17.15:01:04.257299|c|SAI_OBJECT_TYPE_VNET:oid:0x7100000000008b|SAI_VNET_ATTR_VNI=100 +2022-11-17.15:01:04.257795|c|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000008c|SAI_ENI_ATTR_VNET_ID=oid:0x7100000000008b +2022-11-17.15:01:04.258351|c|SAI_OBJECT_TYPE_VNET:oid:0x7100000000008d|SAI_VNET_ATTR_VNI=200 +2022-11-17.15:01:04.258843|c|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000008e|SAI_ENI_ATTR_VNET_ID=oid:0x7100000000008d +2022-11-17.15:01:04.259321|C|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY||{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"}|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x6d00000000008c||{"address":"00:01:02:03:04:06","switch_id":"oid:0x21000000000000"}|SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID=oid:0x6d00000000008e +2022-11-17.15:01:04.259787|R|SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY||{"address":"00:01:02:03:04:05","switch_id":"oid:0x21000000000000"}||{"address":"00:01:02:03:04:06","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.260227|r|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000008c +2022-11-17.15:01:04.260664|r|SAI_OBJECT_TYPE_ENI:oid:0x6d00000000008e +2022-11-17.15:01:04.261091|r|SAI_OBJECT_TYPE_VNET:oid:0x7100000000008b +2022-11-17.15:01:04.261501|r|SAI_OBJECT_TYPE_VNET:oid:0x7100000000008d +2022-11-17.15:01:04.261991|c|SAI_OBJECT_TYPE_VNET:oid:0x7100000000008f|SAI_VNET_ATTR_VNI=101 +2022-11-17.15:01:04.262483|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000090|SAI_VNET_ATTR_VNI=102 +2022-11-17.15:01:04.263040|C|SAI_OBJECT_TYPE_ENI||oid:0x6d000000000091|SAI_ENI_ATTR_VNET_ID=oid:0x7100000000008f|SAI_ENI_ATTR_ADMIN_STATE=true|SAI_ENI_ATTR_VM_VNI=123|SAI_ENI_ATTR_CPS=10|SAI_ENI_ATTR_FLOWS=20|SAI_ENI_ATTR_VM_UNDERLAY_DIP=192.168.0.1||oid:0x6d000000000092|SAI_ENI_ATTR_VNET_ID=oid:0x71000000000090|SAI_ENI_ATTR_ADMIN_STATE=true|SAI_ENI_ATTR_VM_VNI=124|SAI_ENI_ATTR_CPS=11|SAI_ENI_ATTR_FLOWS=21|SAI_ENI_ATTR_VM_UNDERLAY_DIP=192.168.1.1 +2022-11-17.15:01:04.263711|g|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000091|SAI_ENI_ATTR_VNET_ID=oid:0x0 +2022-11-17.15:01:04.264183|G|SAI_STATUS_SUCCESS|SAI_ENI_ATTR_VNET_ID=oid:0x7100000000008f +2022-11-17.15:01:04.264213|g|SAI_OBJECT_TYPE_ENI:oid:0x6d000000000092|SAI_ENI_ATTR_VNET_ID=oid:0x0 +2022-11-17.15:01:04.264715|G|SAI_STATUS_SUCCESS|SAI_ENI_ATTR_VNET_ID=oid:0x71000000000090 +2022-11-17.15:01:04.264757|R|SAI_OBJECT_TYPE_ENI||oid:0x6d000000000091||oid:0x6d000000000092 +2022-11-17.15:01:04.265313|r|SAI_OBJECT_TYPE_VNET:oid:0x7100000000008f +2022-11-17.15:01:04.265761|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000090 +2022-11-17.15:01:04.266260|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000093|SAI_VNET_ATTR_VNI=101 +2022-11-17.15:01:04.266752|c|SAI_OBJECT_TYPE_VNET:oid:0x71000000000094|SAI_VNET_ATTR_VNI=102 +2022-11-17.15:01:04.267304|C|SAI_OBJECT_TYPE_ENI||oid:0x6d000000000095|SAI_ENI_ATTR_VNET_ID=oid:0x71000000000093|SAI_ENI_ATTR_ADMIN_STATE=true|SAI_ENI_ATTR_VM_VNI=123|SAI_ENI_ATTR_CPS=10|SAI_ENI_ATTR_FLOWS=20|SAI_ENI_ATTR_VM_UNDERLAY_DIP=192.168.0.1||oid:0x6d000000000096|SAI_ENI_ATTR_VNET_ID=oid:0x71000000000094|SAI_ENI_ATTR_ADMIN_STATE=true|SAI_ENI_ATTR_VM_VNI=124|SAI_ENI_ATTR_CPS=11|SAI_ENI_ATTR_FLOWS=21|SAI_ENI_ATTR_VM_UNDERLAY_DIP=192.168.1.1 +2022-11-17.15:01:04.267965|R|SAI_OBJECT_TYPE_ENI||oid:0x6d000000000095||oid:0x6d000000000096 +2022-11-17.15:01:04.268525|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000093 +2022-11-17.15:01:04.268989|r|SAI_OBJECT_TYPE_VNET:oid:0x71000000000094 +2022-11-17.15:01:04.269469|C|SAI_OBJECT_TYPE_VIP_ENTRY||{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"}|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT||{"switch_id":"oid:0x21000000000000","vip":"192.168.1.1"}|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.269937|g|SAI_OBJECT_TYPE_VIP_ENTRY:{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"}|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.270372|G|SAI_STATUS_SUCCESS|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.270412|g|SAI_OBJECT_TYPE_VIP_ENTRY:{"switch_id":"oid:0x21000000000000","vip":"192.168.1.1"}|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.270890|G|SAI_STATUS_SUCCESS|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.270928|R|SAI_OBJECT_TYPE_VIP_ENTRY||{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"}||{"switch_id":"oid:0x21000000000000","vip":"192.168.1.1"} +2022-11-17.15:01:04.271410|C|SAI_OBJECT_TYPE_VIP_ENTRY||{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"}|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT||{"switch_id":"oid:0x21000000000000","vip":"192.168.1.1"}|SAI_VIP_ENTRY_ATTR_ACTION=SAI_VIP_ENTRY_ACTION_ACCEPT +2022-11-17.15:01:04.271868|R|SAI_OBJECT_TYPE_VIP_ENTRY||{"switch_id":"oid:0x21000000000000","vip":"192.168.0.1"}||{"switch_id":"oid:0x21000000000000","vip":"192.168.1.1"} +2022-11-17.15:01:04.272410|C|SAI_OBJECT_TYPE_DASH_ACL_GROUP||oid:0x69000000000097|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV4||oid:0x69000000000098|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV6 +2022-11-17.15:01:04.273012|g|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000097|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV4 +2022-11-17.15:01:04.273432|G|SAI_STATUS_SUCCESS|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV4 +2022-11-17.15:01:04.273459|g|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x69000000000098|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV4 +2022-11-17.15:01:04.273843|G|SAI_STATUS_SUCCESS|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV6 +2022-11-17.15:01:04.273869|R|SAI_OBJECT_TYPE_DASH_ACL_GROUP||oid:0x69000000000097||oid:0x69000000000098 +2022-11-17.15:01:04.274512|C|SAI_OBJECT_TYPE_DASH_ACL_GROUP||oid:0x69000000000099|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV4||oid:0x6900000000009a|SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY=SAI_IP_ADDR_FAMILY_IPV6 +2022-11-17.15:01:04.275089|R|SAI_OBJECT_TYPE_DASH_ACL_GROUP||oid:0x69000000000099||oid:0x6900000000009a +2022-11-17.15:01:04.275719|c|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x6900000000009b|NULL=NULL +2022-11-17.15:01:04.276197|c|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x6900000000009c|NULL=NULL +2022-11-17.15:01:04.276753|C|SAI_OBJECT_TYPE_DASH_ACL_RULE||oid:0x6a00000000009d|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_PERMIT_AND_CONTINUE|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x6900000000009b|SAI_DASH_ACL_RULE_ATTR_DIP=2:192.168.0.1/24,100::ffff:ffff:ffff:ffff/16|SAI_DASH_ACL_RULE_ATTR_SIP=2:192.168.0.2/16,100::ffff:ffff:ffff:fffe/16|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:170,187|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:50,60,70,80|SAI_DASH_ACL_RULE_ATTR_PRIORITY=1||oid:0x6a00000000009e|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_DENY|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x6900000000009c|SAI_DASH_ACL_RULE_ATTR_DIP=2:192.168.0.1/24,100::ffff:ffff:ffff:ffff/16|SAI_DASH_ACL_RULE_ATTR_SIP=2:192.168.0.2/16,100::ffff:ffff:ffff:fffe/16|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:204,221|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:50,60,70,80|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_PRIORITY=2 +2022-11-17.15:01:04.277815|g|SAI_OBJECT_TYPE_DASH_ACL_RULE:oid:0x6a00000000009d|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_PERMIT|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x0|SAI_DASH_ACL_RULE_ATTR_DIP=2:0.0.0.0/0,0.0.0.0/0|SAI_DASH_ACL_RULE_ATTR_SIP=2:0.0.0.0/0,0.0.0.0/0|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:0,0|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:0,0,0,0|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:0,0,0,0|SAI_DASH_ACL_RULE_ATTR_PRIORITY=0 +2022-11-17.15:01:04.278838|G|SAI_STATUS_SUCCESS|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_PERMIT_AND_CONTINUE|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x6900000000009b|SAI_DASH_ACL_RULE_ATTR_DIP=2:192.168.0.1/24,100::ffff:ffff:ffff:ffff/16|SAI_DASH_ACL_RULE_ATTR_SIP=2:192.168.0.2/16,100::ffff:ffff:ffff:fffe/16|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:170,187|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:50,60,70,80|SAI_DASH_ACL_RULE_ATTR_PRIORITY=1 +2022-11-17.15:01:04.278886|g|SAI_OBJECT_TYPE_DASH_ACL_RULE:oid:0x6a00000000009e|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_PERMIT|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x0|SAI_DASH_ACL_RULE_ATTR_DIP=2:0.0.0.0/0,0.0.0.0/0|SAI_DASH_ACL_RULE_ATTR_SIP=2:0.0.0.0/0,0.0.0.0/0|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:0,0|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:0,0,0,0|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:0,0,0,0|SAI_DASH_ACL_RULE_ATTR_PRIORITY=0 +2022-11-17.15:01:04.279797|G|SAI_STATUS_SUCCESS|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_DENY|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x6900000000009c|SAI_DASH_ACL_RULE_ATTR_DIP=2:192.168.0.1/24,100::ffff:ffff:ffff:ffff/16|SAI_DASH_ACL_RULE_ATTR_SIP=2:192.168.0.2/16,100::ffff:ffff:ffff:fffe/16|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:204,221|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:50,60,70,80|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_PRIORITY=2 +2022-11-17.15:01:04.279827|R|SAI_OBJECT_TYPE_DASH_ACL_RULE||oid:0x6a00000000009d||oid:0x6a00000000009e +2022-11-17.15:01:04.280381|r|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x6900000000009b +2022-11-17.15:01:04.280849|r|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x6900000000009c +2022-11-17.15:01:04.281342|c|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x6900000000009f|NULL=NULL +2022-11-17.15:01:04.281814|c|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x690000000000a0|NULL=NULL +2022-11-17.15:01:04.282359|C|SAI_OBJECT_TYPE_DASH_ACL_RULE||oid:0x6a0000000000a1|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_PERMIT_AND_CONTINUE|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x6900000000009f|SAI_DASH_ACL_RULE_ATTR_DIP=2:192.168.0.1/24,100::ffff:ffff:ffff:ffff/16|SAI_DASH_ACL_RULE_ATTR_SIP=2:192.168.0.2/16,100::ffff:ffff:ffff:fffe/16|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:170,187|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:50,60,70,80|SAI_DASH_ACL_RULE_ATTR_PRIORITY=1||oid:0x6a0000000000a2|SAI_DASH_ACL_RULE_ATTR_ACTION=SAI_DASH_ACL_RULE_ACTION_DENY|SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID=oid:0x690000000000a0|SAI_DASH_ACL_RULE_ATTR_DIP=2:192.168.0.1/24,100::ffff:ffff:ffff:ffff/16|SAI_DASH_ACL_RULE_ATTR_SIP=2:192.168.0.2/16,100::ffff:ffff:ffff:fffe/16|SAI_DASH_ACL_RULE_ATTR_PROTOCOL=2:204,221|SAI_DASH_ACL_RULE_ATTR_SRC_PORT=2:50,60,70,80|SAI_DASH_ACL_RULE_ATTR_DST_PORT=2:10,20,30,40|SAI_DASH_ACL_RULE_ATTR_PRIORITY=2 +2022-11-17.15:01:04.283376|R|SAI_OBJECT_TYPE_DASH_ACL_RULE||oid:0x6a0000000000a1||oid:0x6a0000000000a2 +2022-11-17.15:01:04.283949|r|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x6900000000009f +2022-11-17.15:01:04.284384|r|SAI_OBJECT_TYPE_DASH_ACL_GROUP:oid:0x690000000000a0 +2022-11-17.15:01:04.284929|C|SAI_OBJECT_TYPE_VNET||oid:0x710000000000a3|SAI_VNET_ATTR_VNI=10||oid:0x710000000000a4|SAI_VNET_ATTR_VNI=20 +2022-11-17.15:01:04.285511|g|SAI_OBJECT_TYPE_VNET:oid:0x710000000000a3|SAI_VNET_ATTR_VNI=0 +2022-11-17.15:01:04.285999|G|SAI_STATUS_SUCCESS|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.286027|g|SAI_OBJECT_TYPE_VNET:oid:0x710000000000a4|SAI_VNET_ATTR_VNI=0 +2022-11-17.15:01:04.286418|G|SAI_STATUS_SUCCESS|SAI_VNET_ATTR_VNI=20 +2022-11-17.15:01:04.286444|R|SAI_OBJECT_TYPE_VNET||oid:0x710000000000a3||oid:0x710000000000a4 +2022-11-17.15:01:04.287168|C|SAI_OBJECT_TYPE_VNET||oid:0x710000000000a5|SAI_VNET_ATTR_VNI=10||oid:0x710000000000a6|SAI_VNET_ATTR_VNI=20 +2022-11-17.15:01:04.287755|R|SAI_OBJECT_TYPE_VNET||oid:0x710000000000a5||oid:0x710000000000a6 +2022-11-17.15:01:04.288377|c|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000a7|NULL=NULL +2022-11-17.15:01:04.288881|c|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000a8|NULL=NULL +2022-11-17.15:01:04.289355|C|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY||{"eni_id":"oid:0x6d0000000000a7","priority":"1","sip":"192.168.0.1","sip_mask":"255.255.255.0","switch_id":"oid:0x21000000000000","vni":"10"}|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP||{"eni_id":"oid:0x6d0000000000a8","priority":"2","sip":"192.168.0.2","sip_mask":"255.255.0.0","switch_id":"oid:0x21000000000000","vni":"11"}|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE +2022-11-17.15:01:04.289878|g|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:{"eni_id":"oid:0x6d0000000000a7","priority":"1","sip":"192.168.0.1","sip_mask":"255.255.255.0","switch_id":"oid:0x21000000000000","vni":"10"}|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP +2022-11-17.15:01:04.290355|G|SAI_STATUS_SUCCESS|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP +2022-11-17.15:01:04.290404|g|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY:{"eni_id":"oid:0x6d0000000000a8","priority":"2","sip":"192.168.0.2","sip_mask":"255.255.0.0","switch_id":"oid:0x21000000000000","vni":"11"}|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP +2022-11-17.15:01:04.290856|G|SAI_STATUS_SUCCESS|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE +2022-11-17.15:01:04.290905|R|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY||{"eni_id":"oid:0x6d0000000000a7","priority":"1","sip":"192.168.0.1","sip_mask":"255.255.255.0","switch_id":"oid:0x21000000000000","vni":"10"}||{"eni_id":"oid:0x6d0000000000a8","priority":"2","sip":"192.168.0.2","sip_mask":"255.255.0.0","switch_id":"oid:0x21000000000000","vni":"11"} +2022-11-17.15:01:04.291375|r|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000a7 +2022-11-17.15:01:04.291800|r|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000a8 +2022-11-17.15:01:04.292287|c|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000a9|NULL=NULL +2022-11-17.15:01:04.292853|c|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000aa|NULL=NULL +2022-11-17.15:01:04.293328|C|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY||{"eni_id":"oid:0x6d0000000000a9","priority":"1","sip":"192.168.0.1","sip_mask":"255.255.255.0","switch_id":"oid:0x21000000000000","vni":"10"}|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP||{"eni_id":"oid:0x6d0000000000aa","priority":"2","sip":"192.168.0.2","sip_mask":"255.255.0.0","switch_id":"oid:0x21000000000000","vni":"11"}|SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE +2022-11-17.15:01:04.293821|R|SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY||{"eni_id":"oid:0x6d0000000000a9","priority":"1","sip":"192.168.0.1","sip_mask":"255.255.255.0","switch_id":"oid:0x21000000000000","vni":"10"}||{"eni_id":"oid:0x6d0000000000aa","priority":"2","sip":"192.168.0.2","sip_mask":"255.255.0.0","switch_id":"oid:0x21000000000000","vni":"11"} +2022-11-17.15:01:04.294325|r|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000a9 +2022-11-17.15:01:04.294750|r|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000aa +2022-11-17.15:01:04.295244|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000ab|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.295732|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000ac|SAI_VNET_ATTR_VNI=20 +2022-11-17.15:01:04.296208|C|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY||{"sip":"192.1.1.1","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x710000000000ab"}|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT||{"sip":"192.2.2.2","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x710000000000ac"}|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT +2022-11-17.15:01:04.296691|g|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:{"sip":"192.1.1.1","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x710000000000ab"}|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT +2022-11-17.15:01:04.297159|G|SAI_STATUS_SUCCESS|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT +2022-11-17.15:01:04.297203|g|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY:{"sip":"192.2.2.2","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x710000000000ac"}|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT +2022-11-17.15:01:04.297632|G|SAI_STATUS_SUCCESS|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT +2022-11-17.15:01:04.297675|R|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY||{"sip":"192.1.1.1","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x710000000000ab"}||{"sip":"192.2.2.2","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x710000000000ac"} +2022-11-17.15:01:04.298108|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000ab +2022-11-17.15:01:04.298604|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000ac +2022-11-17.15:01:04.299110|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000ad|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.299600|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000ae|SAI_VNET_ATTR_VNI=20 +2022-11-17.15:01:04.300070|C|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY||{"sip":"192.1.1.1","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x710000000000ad"}|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT||{"sip":"192.2.2.2","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x710000000000ae"}|SAI_PA_VALIDATION_ENTRY_ATTR_ACTION=SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT +2022-11-17.15:01:04.300539|R|SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY||{"sip":"192.1.1.1","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x710000000000ad"}||{"sip":"192.2.2.2","switch_id":"oid:0x21000000000000","vnet_id":"oid:0x710000000000ae"} +2022-11-17.15:01:04.301009|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000ad +2022-11-17.15:01:04.301434|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000ae +2022-11-17.15:01:04.301926|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000af|SAI_VNET_ATTR_VNI=101 +2022-11-17.15:01:04.302418|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b0|SAI_VNET_ATTR_VNI=102 +2022-11-17.15:01:04.302911|c|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000b1|SAI_ENI_ATTR_VNET_ID=oid:0x710000000000af +2022-11-17.15:01:04.303405|c|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000b2|SAI_ENI_ATTR_VNET_ID=oid:0x710000000000b0 +2022-11-17.15:01:04.303897|C|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY||{"destination":"192.1.1.1/24","eni_id":"oid:0x6d0000000000b1","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x710000000000af||{"destination":"fe80::886a:feff:fe31:bfe0/32","eni_id":"oid:0x6d0000000000b2","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x710000000000b0 +2022-11-17.15:01:04.304429|g|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:{"destination":"192.1.1.1/24","eni_id":"oid:0x6d0000000000b1","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x0 +2022-11-17.15:01:04.305140|G|SAI_STATUS_SUCCESS|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x710000000000af +2022-11-17.15:01:04.305194|g|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY:{"destination":"fe80::886a:feff:fe31:bfe0/32","eni_id":"oid:0x6d0000000000b2","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x0 +2022-11-17.15:01:04.305774|G|SAI_STATUS_SUCCESS|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x710000000000b0 +2022-11-17.15:01:04.305822|R|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY||{"destination":"192.1.1.1/24","eni_id":"oid:0x6d0000000000b1","switch_id":"oid:0x21000000000000"}||{"destination":"fe80::886a:feff:fe31:bfe0/32","eni_id":"oid:0x6d0000000000b2","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.306284|r|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000b1 +2022-11-17.15:01:04.306706|r|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000b2 +2022-11-17.15:01:04.307119|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000af +2022-11-17.15:01:04.307526|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b0 +2022-11-17.15:01:04.308017|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b3|SAI_VNET_ATTR_VNI=101 +2022-11-17.15:01:04.308505|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b4|SAI_VNET_ATTR_VNI=102 +2022-11-17.15:01:04.309013|c|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000b5|SAI_ENI_ATTR_VNET_ID=oid:0x710000000000b3 +2022-11-17.15:01:04.309511|c|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000b6|SAI_ENI_ATTR_VNET_ID=oid:0x710000000000b4 +2022-11-17.15:01:04.310006|C|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY||{"destination":"192.1.1.1/24","eni_id":"oid:0x6d0000000000b5","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x710000000000b3||{"destination":"fe80::886a:feff:fe31:bfe0/32","eni_id":"oid:0x6d0000000000b6","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION=SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET|SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID=oid:0x710000000000b4 +2022-11-17.15:01:04.310513|R|SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY||{"destination":"192.1.1.1/24","eni_id":"oid:0x6d0000000000b5","switch_id":"oid:0x21000000000000"}||{"destination":"fe80::886a:feff:fe31:bfe0/32","eni_id":"oid:0x6d0000000000b6","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.311049|r|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000b5 +2022-11-17.15:01:04.311483|r|SAI_OBJECT_TYPE_ENI:oid:0x6d0000000000b6 +2022-11-17.15:01:04.311891|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b3 +2022-11-17.15:01:04.312295|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b4 +2022-11-17.15:01:04.312788|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b7|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.313295|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b8|SAI_VNET_ATTR_VNI=20 +2022-11-17.15:01:04.313783|C|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY||{"dip":"192.1.1.1","dst_vnet_id":"oid:0x710000000000b7","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=fe80::886a:feff:fe31:bfe1|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:11:22:33:44:55|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=true||{"dip":"fe80::886a:feff:fe31:bfe0","dst_vnet_id":"oid:0x710000000000b8","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=192.1.1.2|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:11:22:33:44:56|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=false +2022-11-17.15:01:04.314326|g|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"192.1.1.1","dst_vnet_id":"oid:0x710000000000b7","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=0.0.0.0|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:00:00:00:00:00|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=false +2022-11-17.15:01:04.314936|G|SAI_STATUS_SUCCESS|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=fe80::886a:feff:fe31:bfe1|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:11:22:33:44:55|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=true +2022-11-17.15:01:04.314997|g|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY:{"dip":"fe80::886a:feff:fe31:bfe0","dst_vnet_id":"oid:0x710000000000b8","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=0.0.0.0|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:00:00:00:00:00|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=false +2022-11-17.15:01:04.315593|G|SAI_STATUS_SUCCESS|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=192.1.1.2|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:11:22:33:44:56|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=false +2022-11-17.15:01:04.315635|R|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY||{"dip":"192.1.1.1","dst_vnet_id":"oid:0x710000000000b7","switch_id":"oid:0x21000000000000"}||{"dip":"fe80::886a:feff:fe31:bfe0","dst_vnet_id":"oid:0x710000000000b8","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.316091|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b7 +2022-11-17.15:01:04.316517|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b8 +2022-11-17.15:01:04.317026|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b9|SAI_VNET_ATTR_VNI=10 +2022-11-17.15:01:04.317585|c|SAI_OBJECT_TYPE_VNET:oid:0x710000000000ba|SAI_VNET_ATTR_VNI=20 +2022-11-17.15:01:04.318068|C|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY||{"dip":"192.1.1.1","dst_vnet_id":"oid:0x710000000000b9","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=fe80::886a:feff:fe31:bfe1|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:11:22:33:44:55|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=true||{"dip":"fe80::886a:feff:fe31:bfe0","dst_vnet_id":"oid:0x710000000000ba","switch_id":"oid:0x21000000000000"}|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP=192.1.1.2|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC=00:11:22:33:44:56|SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI=false +2022-11-17.15:01:04.318591|R|SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY||{"dip":"192.1.1.1","dst_vnet_id":"oid:0x710000000000b9","switch_id":"oid:0x21000000000000"}||{"dip":"fe80::886a:feff:fe31:bfe0","dst_vnet_id":"oid:0x710000000000ba","switch_id":"oid:0x21000000000000"} +2022-11-17.15:01:04.319049|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000b9 +2022-11-17.15:01:04.319471|r|SAI_OBJECT_TYPE_VNET:oid:0x710000000000ba diff --git a/tests/NVDAMBF2H536C/vsprofile.ini b/tests/NVDAMBF2H536C/vsprofile.ini new file mode 100644 index 000000000..188a9d927 --- /dev/null +++ b/tests/NVDAMBF2H536C/vsprofile.ini @@ -0,0 +1,3 @@ +SAI_WARM_BOOT_READ_FILE=./sai_warmboot.bin +SAI_WARM_BOOT_WRITE_FILE=./sai_warmboot.bin +SAI_VS_SWITCH_TYPE=SAI_VS_SWITCH_TYPE_NVDA_MBF2H536C diff --git a/tests/TestClient.cpp b/tests/TestClient.cpp new file mode 100644 index 000000000..c7b24f019 --- /dev/null +++ b/tests/TestClient.cpp @@ -0,0 +1,405 @@ +#include "TestClient.h" + +using namespace std; +using namespace std::placeholders; + +TestClient::TestClient() +{ + SWSS_LOG_ENTER(); + + // empty intentionally +} + +TestClient::~TestClient() +{ + SWSS_LOG_ENTER(); + + // empty intentionally +} + +const char* TestClient::profileGetValue( + _In_ sai_switch_profile_id_t profile_id, + _In_ const char* variable) +{ + SWSS_LOG_ENTER(); + + if (variable == NULL) + { + SWSS_LOG_WARN("variable is null"); + return NULL; + } + + auto it = m_profileMap.find(variable); + + if (it == m_profileMap.end()) + { + SWSS_LOG_NOTICE("%s: NULL", variable); + return NULL; + } + + SWSS_LOG_NOTICE("%s: %s", variable, it->second.c_str()); + + return it->second.c_str(); +} + +int TestClient::profileGetNextValue( + _In_ sai_switch_profile_id_t profile_id, + _Out_ const char** variable, + _Out_ const char** value) +{ + SWSS_LOG_ENTER(); + + if (value == NULL) + { + SWSS_LOG_INFO("resetting profile map iterator"); + + m_profileIter = m_profileMap.begin(); + return 0; + } + + if (variable == NULL) + { + SWSS_LOG_WARN("variable is null"); + return -1; + } + + if (m_profileIter == m_profileMap.end()) + { + SWSS_LOG_INFO("iterator reached end"); + return -1; + } + + *variable = m_profileIter->first.c_str(); + *value = m_profileIter->second.c_str(); + + SWSS_LOG_INFO("key: %s:%s", *variable, *value); + + m_profileIter++; + + return 0; +} + +void TestClient::setup() +{ + SWSS_LOG_ENTER(); + + m_profileMap.clear(); + + m_profileMap[SAI_REDIS_KEY_ENABLE_CLIENT] = "true"; // act as a client + + m_profileIter = m_profileMap.begin(); + + m_smt.profileGetValue = std::bind(&TestClient::profileGetValue, this, _1, _2); + m_smt.profileGetNextValue = std::bind(&TestClient::profileGetNextValue, this, _1, _2, _3); + + m_test_services = m_smt.getServiceMethodTable(); + + ASSERT_SUCCESS(sai_api_initialize(0, &m_test_services)); + + sai_switch_api_t* switch_api; + + ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api)); + + sai_attribute_t attr; + + // connect to existing switch + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = false; + + m_switch_id = SAI_NULL_OBJECT_ID; + + ASSERT_SUCCESS(switch_api->create_switch(&m_switch_id, 1, &attr)); + + ASSERT_TRUE(m_switch_id != SAI_NULL_OBJECT_ID); + + SWSS_LOG_NOTICE("switchId: %s", sai_serialize_object_id(m_switch_id).c_str()); +} + +void TestClient::teardown() +{ + SWSS_LOG_ENTER(); + + m_switch_id = SAI_NULL_OBJECT_ID; + + ASSERT_SUCCESS(sai_api_uninitialize()); +} + +void TestClient::test_create_switch() +{ + SWSS_LOG_ENTER(); + + m_profileMap.clear(); + + m_profileMap[SAI_REDIS_KEY_ENABLE_CLIENT] = "true"; // act as a client + + m_profileIter = m_profileMap.begin(); + + m_smt.profileGetValue = std::bind(&TestClient::profileGetValue, this, _1, _2); + m_smt.profileGetNextValue = std::bind(&TestClient::profileGetNextValue, this, _1, _2, _3); + + m_test_services = m_smt.getServiceMethodTable(); + + ASSERT_SUCCESS(sai_api_initialize(0, &m_test_services)); + + sai_switch_api_t* switch_api; + + ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api)); + + sai_attribute_t attr; + + // connect to existing switch + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = false; + + sai_object_id_t switch_id = SAI_NULL_OBJECT_ID; + + ASSERT_SUCCESS(switch_api->create_switch(&switch_id, 1, &attr)); + + ASSERT_TRUE(switch_id != SAI_NULL_OBJECT_ID); + + SWSS_LOG_NOTICE("switchId: %s", sai_serialize_object_id(switch_id).c_str()); + + ASSERT_SUCCESS(sai_api_uninitialize()); +} + +void TestClient::test_create_vlan() +{ + SWSS_LOG_ENTER(); + + setup(); + + SWSS_LOG_NOTICE("switchId: %s", sai_serialize_object_id(m_switch_id).c_str()); + + sai_switch_api_t* switch_api; + + ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api)); + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; + + ASSERT_SUCCESS(switch_api->get_switch_attribute(m_switch_id, 1, &attr)); + + SWSS_LOG_NOTICE("got VRID: %s", sai_serialize_object_id(attr.value.oid).c_str()); + + sai_vlan_api_t* vlan_api; + + ASSERT_SUCCESS(sai_api_query(SAI_API_VLAN, (void**)&vlan_api)); + + attr.id = SAI_VLAN_ATTR_VLAN_ID; + attr.value.u16 = 200; + + sai_object_id_t vlan_id; + + ASSERT_SUCCESS(vlan_api->create_vlan(&vlan_id, m_switch_id, 1, &attr)); + + ASSERT_TRUE(vlan_id != SAI_NULL_OBJECT_ID); + + ASSERT_SUCCESS(vlan_api->remove_vlan(vlan_id)); + + teardown(); +} + +void TestClient::test_bulk_create_vlan() +{ + SWSS_LOG_ENTER(); + + setup(); + + sai_switch_api_t* switch_api; + + ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api)); + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; + + ASSERT_SUCCESS(switch_api->get_switch_attribute(m_switch_id, 1, &attr)); + + SWSS_LOG_NOTICE("got VRID: %s", sai_serialize_object_id(attr.value.oid).c_str()); + + attr.id = SAI_SWITCH_ATTR_DEFAULT_1Q_BRIDGE_ID; + + ASSERT_SUCCESS(switch_api->get_switch_attribute(m_switch_id, 1, &attr)); + + sai_object_id_t bridge_id = attr.value.oid; + + sai_bridge_api_t* bridge_api; + + ASSERT_SUCCESS(sai_api_query(SAI_API_BRIDGE, (void**)&bridge_api)); + + sai_object_id_t ports[128]; + + attr.id = SAI_BRIDGE_ATTR_PORT_LIST; + attr.value.objlist.count = 128; + attr.value.objlist.list = ports; + + ASSERT_SUCCESS(bridge_api->get_bridge_attribute(bridge_id, 1, &attr)); + + sai_vlan_api_t* vlan_api; + + ASSERT_SUCCESS(sai_api_query(SAI_API_VLAN, (void**)&vlan_api)); + + // create vlan + + attr.id = SAI_VLAN_ATTR_VLAN_ID; + attr.value.u16 = 200; + + sai_object_id_t vlan_id; + + ASSERT_SUCCESS(vlan_api->create_vlan(&vlan_id, m_switch_id, 1, &attr)); + + ASSERT_TRUE(vlan_id != SAI_NULL_OBJECT_ID); + + // bulk create vlan members + + uint32_t attr_count[2] = { 2, 2 }; + + const sai_attribute_t* attr_list[2]; + + sai_attribute_t attr0[2]; + + attr0[0].id = SAI_VLAN_MEMBER_ATTR_VLAN_ID; + attr0[0].value.oid = vlan_id; + + attr0[1].id = SAI_VLAN_MEMBER_ATTR_BRIDGE_PORT_ID; + attr0[1].value.oid = ports[0]; + + attr_list[0] = attr0; + + sai_attribute_t attr1[2]; + + attr1[0].id = SAI_VLAN_MEMBER_ATTR_VLAN_ID; + attr1[0].value.oid = vlan_id; + + attr1[1].id = SAI_VLAN_MEMBER_ATTR_BRIDGE_PORT_ID; + attr1[1].value.oid = ports[1]; + + attr_list[1] = attr1; + + sai_object_id_t members[2] = { SAI_NULL_OBJECT_ID, SAI_NULL_OBJECT_ID }; + sai_status_t statuses[2]; + + auto status = vlan_api->create_vlan_members( + m_switch_id, + 2, + attr_count, + attr_list, + SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, + members, + statuses); + + ASSERT_SUCCESS(status); + + ASSERT_SUCCESS(statuses[0]); + ASSERT_SUCCESS(statuses[1]); + + ASSERT_TRUE(members[0] != SAI_NULL_OBJECT_ID); + ASSERT_TRUE(members[1] != SAI_NULL_OBJECT_ID); + + SWSS_LOG_NOTICE("members: %s, %s", + sai_serialize_object_id(members[0]).c_str(), + sai_serialize_object_id(members[1]).c_str()); + + // bulk remove vlan members + + status = vlan_api->remove_vlan_members( + 2, + members, + SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, + statuses); + + ASSERT_SUCCESS(status); + + ASSERT_SUCCESS(statuses[0]); + ASSERT_SUCCESS(statuses[1]); + + // remove vlan + + ASSERT_SUCCESS(vlan_api->remove_vlan(vlan_id)); + + teardown(); +} + +void TestClient::test_query_api() +{ + SWSS_LOG_ENTER(); + + setup(); + + sai_attr_capability_t cap; + + SWSS_LOG_NOTICE(" * sai_query_attribute_capability"); + + ASSERT_SUCCESS(sai_query_attribute_capability( + m_switch_id, + SAI_OBJECT_TYPE_SWITCH, + SAI_SWITCH_ATTR_INIT_SWITCH, + &cap)); + + int32_t vec[3]; + sai_s32_list_t list; + + list.count = 3; + list.list = vec; + + SWSS_LOG_NOTICE(" * sai_query_attribute_enum_values_capability"); + + ASSERT_SUCCESS(sai_query_attribute_enum_values_capability( + m_switch_id, + SAI_OBJECT_TYPE_DEBUG_COUNTER, + SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST, + &list)); + + uint64_t count; + + SWSS_LOG_NOTICE(" * sai_object_type_get_availability"); + + ASSERT_SUCCESS(sai_object_type_get_availability( + m_switch_id, + SAI_OBJECT_TYPE_DEBUG_COUNTER, + 0, + NULL, + &count)); + + teardown(); +} + +void TestClient::test_fdb_flush() +{ + SWSS_LOG_ENTER(); + + setup(); + + sai_fdb_api_t* fdb_api; + + ASSERT_SUCCESS(sai_api_query(SAI_API_FDB, (void**)&fdb_api)); + + ASSERT_SUCCESS(fdb_api->flush_fdb_entries(m_switch_id, 0, NULL)); + + teardown(); +} + +void TestClient::test_stats() +{ + SWSS_LOG_ENTER(); + + setup(); + + sai_switch_api_t* switch_api; + + ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api)); + + uint64_t counters[1]; + sai_stat_id_t counter_ids[1] = { SAI_SWITCH_STAT_ECC_DROP }; + + SWSS_LOG_NOTICE(" * get_switch_stats"); + + ASSERT_SUCCESS(switch_api->get_switch_stats(m_switch_id, 1, counter_ids, counters)); + + SWSS_LOG_NOTICE(" * clear_switch_stats"); + + ASSERT_SUCCESS(switch_api->clear_switch_stats(m_switch_id, 1, counter_ids)); + + teardown(); +} diff --git a/tests/TestClient.h b/tests/TestClient.h new file mode 100644 index 000000000..dbbd2b876 --- /dev/null +++ b/tests/TestClient.h @@ -0,0 +1,74 @@ +#pragma once + +#include +#include +#include + +#include "sairedis.h" +#include "syncd/ServiceMethodTable.h" +#include "meta/sai_serialize.h" + +#define ASSERT_TRUE(x) \ + if (!(x)) \ +{\ + SWSS_LOG_THROW("assert true failed '%s', line: %d", # x, __LINE__);\ +} + +#define ASSERT_SUCCESS(x) \ + if (x != SAI_STATUS_SUCCESS) \ +{\ + SWSS_LOG_THROW("expected success, line: %d, got: %s", __LINE__, sai_serialize_status(x).c_str());\ +} + +class TestClient +{ + public: + + TestClient(); + + virtual ~TestClient(); + + public: + + void test_create_switch(); + + void test_create_vlan(); + + void test_bulk_create_vlan(); + + void test_query_api(); + + void test_fdb_flush(); + + void test_stats(); + + protected: + + int profileGetNextValue( + _In_ sai_switch_profile_id_t profile_id, + _Out_ const char** variable, + _Out_ const char** value); + + const char* profileGetValue( + _In_ sai_switch_profile_id_t profile_id, + _In_ const char* variable); + + protected: + + void setup(); + + void teardown(); + + protected: + + std::map m_profileMap; + + std::map::iterator m_profileIter; + + syncd::ServiceMethodTable m_smt; + + sai_service_method_table_t m_test_services; + + sai_object_id_t m_switch_id; +}; + diff --git a/tests/TestDash.cpp b/tests/TestDash.cpp new file mode 100644 index 000000000..1e1ec5057 --- /dev/null +++ b/tests/TestDash.cpp @@ -0,0 +1,1645 @@ +#include "TestDashEnv.h" + +#include "swss/logger.h" + +#include +#include +#include + +using std::vector; + +#define ASSERT_SUCCESS(e) ASSERT_EQ((e), SAI_STATUS_SUCCESS) + +template +static bool compare_lists(L la, L lb) +{ + // SWSS_LOG_ENTER(); // disabled + + if (la.count != lb.count) { + return false; + } + + return std::equal(la.list, la.list + la.count, lb.list); +} + +static bool operator==(sai_ip_address_t a, sai_ip_address_t b) +{ + if (a.addr_family != b.addr_family) { + return false; + } + + switch (a.addr_family) { + case SAI_IP_ADDR_FAMILY_IPV4: + return a.addr.ip4 == b.addr.ip4; + case SAI_IP_ADDR_FAMILY_IPV6: + return memcmp(a.addr.ip6, b.addr.ip6, sizeof(a.addr.ip6)) == 0; + default: + return false; + } +} + +static bool operator==(sai_ip_prefix_t a, sai_ip_prefix_t b) +{ + if (a.addr_family != b.addr_family) { + return false; + } + + switch (a.addr_family) { + case SAI_IP_ADDR_FAMILY_IPV4: + return a.addr.ip4 == b.addr.ip4 && a.mask.ip4 == b.mask.ip4; + case SAI_IP_ADDR_FAMILY_IPV6: + return memcmp(a.addr.ip6, b.addr.ip6, sizeof(a.addr.ip6)) == 0 && + memcmp(a.mask.ip6, b.mask.ip6, sizeof(a.mask.ip6)) == 0; + default: + return false; + } +} + +static bool operator==(sai_u16_range_t a, sai_u16_range_t b) +{ + return (a.min == b.min) && (a.max == b.max); +} + +TEST(API, direction_lookup) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_direction_lookup_api_t *dash_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_DIRECTION_LOOKUP, (void**)&dash_api)); + + sai_direction_lookup_entry_t entry; + + entry.switch_id = switchid; + entry.vni = 1; + + sai_attribute_t attr; + vector attrs; + + attr.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION; + attrs.push_back(attr); + + ASSERT_SUCCESS(dash_api->create_direction_lookup_entry(&entry, (uint32_t)attrs.size(), attrs.data())); + + attr.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION; + ASSERT_SUCCESS(dash_api->set_direction_lookup_entry_attribute(&entry, &attr)); + ASSERT_SUCCESS(dash_api->get_direction_lookup_entry_attribute(&entry, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.s32, SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION); + + ASSERT_SUCCESS(dash_api->remove_direction_lookup_entry(&entry)); +} + +TEST(APIBulk, direction_lookup) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 1; + + sai_dash_direction_lookup_api_t *dash_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_DIRECTION_LOOKUP, (void**)&dash_api)); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_direction_lookup_entry_t entries[entries_count] = { + { .switch_id = switchid, .vni = 10}, + { .switch_id = switchid, .vni = 20}, + }; + + ASSERT_SUCCESS(dash_api->create_direction_lookup_entries(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + for (uint32_t i = 0; i < entries_count; i++) { + sai_attribute_t attr = {}; + attr.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION; + ASSERT_SUCCESS(dash_api->get_direction_lookup_entry_attribute(&entries[i], 1, &attr)); + ASSERT_EQ(attr.value.s32, attr_list[i][0].value.s32); + } + + ASSERT_SUCCESS(dash_api->remove_direction_lookup_entries(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } +} + +TEST(API, eni_ether_address_map_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_eni_api_t *dash_api = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ENI, (void**)&dash_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + + sai_attribute_t attr; + sai_object_id_t eni0, vnet0; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 100; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet0, switchid, 1, &attr)); + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet0; + ASSERT_SUCCESS(dash_api->create_eni(&eni0, switchid, 1, &attr)); + + sai_object_id_t eni1, vnet1; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 200; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet1, switchid, 1, &attr)); + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet1; + ASSERT_SUCCESS(dash_api->create_eni(&eni1, switchid, 1, &attr)); + + sai_eni_ether_address_map_entry_t entry = { .switch_id = switchid, .address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }}; + + vector attrs; + attr.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID; + attr.value.oid = eni0; + attrs.push_back(attr); + + ASSERT_SUCCESS(dash_api->create_eni_ether_address_map_entry(&entry, (uint32_t)attrs.size(), attrs.data())); + + ASSERT_SUCCESS(dash_api->get_eni_ether_address_map_entry_attribute(&entry, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.oid, eni0); + attr.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID; + attr.value.oid = eni1; + ASSERT_SUCCESS(dash_api->set_eni_ether_address_map_entry_attribute(&entry, &attr)); + ASSERT_SUCCESS(dash_api->get_eni_ether_address_map_entry_attribute(&entry, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.oid, eni1); + + ASSERT_SUCCESS(dash_api->remove_eni_ether_address_map_entry(&entry)); + ASSERT_SUCCESS(dash_api->remove_eni(eni0)); + ASSERT_SUCCESS(dash_api->remove_eni(eni1)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet0)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet1)); +} + +TEST(APIBulk, eni_ether_address_map_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 1; + + sai_dash_eni_api_t *dash_api = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ENI, (void**)&dash_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + + sai_attribute_t attr; + sai_object_id_t eni0, vnet0; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 100; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet0, switchid, 1, &attr)); + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet0; + ASSERT_SUCCESS(dash_api->create_eni(&eni0, switchid, 1, &attr)); + + sai_object_id_t eni1, vnet1; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 200; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet1, switchid, 1, &attr)); + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet1; + ASSERT_SUCCESS(dash_api->create_eni(&eni1, switchid, 1, &attr)); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID, .value = (sai_attribute_value_t){.oid = eni0}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID, .value = (sai_attribute_value_t){.oid = eni1}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_eni_ether_address_map_entry_t entries[entries_count] = { + { .switch_id = switchid, .address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }}, + { .switch_id = switchid, .address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06 }}, + }; + + ASSERT_SUCCESS(dash_api->create_eni_ether_address_map_entries(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + for (uint32_t i = 0; i < entries_count; i++) { + attr.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION; + ASSERT_SUCCESS(dash_api->get_eni_ether_address_map_entry_attribute(&entries[i], 1, &attr)); + ASSERT_EQ(attr.value.oid, attr_list[i][0].value.oid); + } + + ASSERT_SUCCESS(dash_api->remove_eni_ether_address_map_entries(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + ASSERT_SUCCESS(dash_api->remove_eni(eni0)); + ASSERT_SUCCESS(dash_api->remove_eni(eni1)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet0)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet1)); +} + +TEST(API, eni) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_eni_api_t *dash_api = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ENI, (void**)&dash_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + + sai_ip_address_t uip4, uip6; + uip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &uip4.addr.ip4); + uip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &uip6.addr.ip6); + + sai_attribute_t attr; + sai_object_id_t vnet; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 101; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet, switchid, 1, &attr)); + + vector attrs; + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_ADMIN_STATE; + attr.value.booldata = true; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_VM_VNI; + attr.value.u32 = 123; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_CPS; + attr.value.u32 = 10; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_PPS; + attr.value.u32 = 20; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_FLOWS; + attr.value.u32 = 30; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP; + attr.value.ipaddr = uip4; + attrs.push_back(attr); + + sai_object_id_t eni; + ASSERT_SUCCESS(dash_api->create_eni(&eni, switchid, (uint32_t)attrs.size(), attrs.data())); + + ASSERT_SUCCESS(dash_api->get_eni_attribute(eni, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.oid, vnet); + ASSERT_TRUE(attrs[1].value.booldata); + ASSERT_EQ(attrs[2].value.u32, 123); + ASSERT_EQ(attrs[3].value.u32, 10); + ASSERT_EQ(attrs[4].value.u32, 20); + ASSERT_EQ(attrs[5].value.u32, 30); + ASSERT_EQ(attrs[6].value.ipaddr.addr.ip4, uip4.addr.ip4); + attr.id = SAI_ENI_ATTR_CPS; + attr.value.u32 = 40; + ASSERT_SUCCESS(dash_api->set_eni_attribute(eni, &attr)); + attr.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP; + attr.value.ipaddr = uip6; + ASSERT_SUCCESS(dash_api->set_eni_attribute(eni, &attr)); + ASSERT_SUCCESS(dash_api->get_eni_attribute(eni, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.oid, vnet); + ASSERT_TRUE(attrs[1].value.booldata); + ASSERT_EQ(attrs[2].value.u32, 123); + ASSERT_EQ(attrs[3].value.u32, 40); + ASSERT_EQ(attrs[4].value.u32, 20); + ASSERT_EQ(attrs[5].value.u32, 30); + ASSERT_TRUE(memcmp(attrs[6].value.ipaddr.addr.ip6, uip6.addr.ip6, sizeof(uip6.addr.ip6)) == 0); + + ASSERT_SUCCESS(dash_api->remove_eni(eni)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet)); +} + +TEST(API, eni_acl) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_eni_api_t *dash_api = nullptr; + sai_dash_acl_api_t *dash_acl_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ENI, (void**)&dash_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ACL, (void**)&dash_acl_api)); + + vector acl_attrs = { + SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID, + }; + + sai_attribute_t attr; + vector attrs; + vector acl_groups, acl_groups_new; + for (auto at : acl_attrs) { + sai_object_id_t acl_group; + ASSERT_SUCCESS(dash_acl_api->create_dash_acl_group(&acl_group, switchid, 0, nullptr)); + acl_groups.push_back(acl_group); + + attr.id = at; + attr.value.oid = acl_group; + attrs.push_back(attr); + + ASSERT_SUCCESS(dash_acl_api->create_dash_acl_group(&acl_group, switchid, 0, nullptr)); + acl_groups_new.push_back(acl_group); + } + + sai_object_id_t eni; + ASSERT_SUCCESS(dash_api->create_eni(&eni, switchid, (uint32_t)attrs.size(), attrs.data())); + + ASSERT_SUCCESS(dash_api->get_eni_attribute(eni, (uint32_t)attrs.size(), attrs.data())); + for (size_t i = 0; i < attrs.size(); i++) { + ASSERT_EQ(attrs[i].value.oid, acl_groups[i]); + attr.id = attrs[i].id; + attr.value.oid = acl_groups_new[i]; + ASSERT_SUCCESS(dash_api->set_eni_attribute(eni, &attr)); + } + + ASSERT_SUCCESS(dash_api->get_eni_attribute(eni, (uint32_t)attrs.size(), attrs.data())); + for (size_t i = 0; i < attrs.size(); i++) { + ASSERT_EQ(attrs[i].value.oid, acl_groups_new[i]); + } + + ASSERT_SUCCESS(dash_api->remove_eni(eni)); +} + +TEST(APIBulk, eni) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + const uint32_t enis_count = 2; + const uint32_t eni_attrs_count = 6; + + sai_dash_eni_api_t *dash_api = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ENI, (void**)&dash_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + + sai_attribute_t attr; + sai_object_id_t vnet0, vnet1; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 101; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet0, switchid, 1, &attr)); + + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 102; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet1, switchid, 1, &attr)); + + sai_ip_address_t ipaddr0, ipaddr1; + ipaddr0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ipaddr0.addr.ip4); + + ipaddr1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.1.1", &ipaddr1.addr.ip4); + + sai_attribute_t attrs0[] = { + {.id = SAI_ENI_ATTR_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + {.id = SAI_ENI_ATTR_ADMIN_STATE, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_ENI_ATTR_VM_VNI, .value = (sai_attribute_value_t){.u32 = 123}}, + {.id = SAI_ENI_ATTR_CPS, .value = (sai_attribute_value_t){.u32 = 10}}, + {.id = SAI_ENI_ATTR_FLOWS, .value = (sai_attribute_value_t){.u32 = 20}}, + {.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = ipaddr0}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_ENI_ATTR_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + {.id = SAI_ENI_ATTR_ADMIN_STATE, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_ENI_ATTR_VM_VNI, .value = (sai_attribute_value_t){.u32 = 124}}, + {.id = SAI_ENI_ATTR_CPS, .value = (sai_attribute_value_t){.u32 = 11}}, + {.id = SAI_ENI_ATTR_FLOWS, .value = (sai_attribute_value_t){.u32 = 21}}, + {.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = ipaddr1}}, + }; + + const sai_attribute_t *attr_list[enis_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[enis_count] = {eni_attrs_count, eni_attrs_count}; + sai_object_id_t enis[enis_count]; + sai_status_t statuses[enis_count] = {}; + + ASSERT_SUCCESS(dash_api->create_enis(switchid, enis_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, enis, statuses)); + for (uint32_t i = 0; i < enis_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + for (uint32_t i = 0; i < enis_count; i++) { + attr.id = SAI_ENI_ATTR_VNET_ID; + ASSERT_SUCCESS(dash_api->get_eni_attribute(enis[i], 1, &attr)); + ASSERT_EQ(attr.value.oid, attr_list[i][0].value.oid); + } + + ASSERT_SUCCESS(dash_api->remove_enis(enis_count, enis, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < enis_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet0)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet1)); +} + +TEST(API, vip_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_vip_api_t *dash_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VIP, (void**)&dash_api)); + + sai_attribute_t attr; + vector attrs; + + attr.id = SAI_VIP_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT; + attrs.push_back(attr); + + sai_ip_address_t vip_addr; + vip_addr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &vip_addr.addr.ip4); + + sai_vip_entry_t vip = { .switch_id = switchid, .vip = vip_addr }; + ASSERT_SUCCESS(dash_api->create_vip_entry(&vip, (uint32_t)attrs.size(), attrs.data())); + + ASSERT_SUCCESS(dash_api->get_vip_entry_attribute(&vip, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.s32, SAI_VIP_ENTRY_ACTION_ACCEPT); + attr.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID; + attr.value.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT; + ASSERT_SUCCESS(dash_api->set_vip_entry_attribute(&vip, &attr)); + ASSERT_SUCCESS(dash_api->get_vip_entry_attribute(&vip, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.s32, SAI_VIP_ENTRY_ACTION_ACCEPT); + + ASSERT_SUCCESS(dash_api->remove_vip_entry(&vip)); +} + +TEST(APIBulk, vip_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_vip_api_t *dash_api = nullptr; + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VIP, (void**)&dash_api)); + + const uint32_t vips_count = 2; + const uint32_t vip_attrs_count = 1; + + sai_attribute_t attrs0[] = { + {.id = SAI_VIP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_VIP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT}}, + }; + + const sai_attribute_t *attr_list[vips_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[vips_count] = {vip_attrs_count, vip_attrs_count}; + sai_status_t statuses[vips_count] = {}; + + sai_ip_address_t vip_addr0, vip_addr1; + vip_addr0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &vip_addr0.addr.ip4); + vip_addr1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &vip_addr1.addr.ip6); + + sai_vip_entry_t vips[vips_count] = { + {.switch_id = switchid, .vip = vip_addr0}, + {.switch_id = switchid, .vip = vip_addr1}, + }; + + ASSERT_SUCCESS(dash_api->create_vip_entries(vips_count, vips, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vips_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + for (uint32_t i = 0; i < vips_count; i++) { + sai_attribute_t attr = {}; + attr.id = SAI_VIP_ENTRY_ATTR_ACTION; + ASSERT_SUCCESS(dash_api->get_vip_entry_attribute(&vips[i], 1, &attr)); + ASSERT_EQ(attr.value.s32, attr_list[i][0].value.s32); + } + + ASSERT_SUCCESS(dash_api->remove_vip_entries(vips_count, vips, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vips_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } +} + +TEST(API, acl_group) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_acl_api_t *dash_acl_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ACL, (void**)&dash_acl_api)); + + sai_attribute_t attr; + vector attrs; + + attr.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY; + attr.value.s32 = SAI_IP_ADDR_FAMILY_IPV4; + attrs.push_back(attr); + + sai_object_id_t acl_group; + ASSERT_SUCCESS(dash_acl_api->create_dash_acl_group(&acl_group, switchid, (uint32_t)attrs.size(), attrs.data())); + + ASSERT_SUCCESS(dash_acl_api->get_dash_acl_group_attribute(acl_group, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.s32, SAI_IP_ADDR_FAMILY_IPV4); + attr.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY; + attr.value.s32 = SAI_IP_ADDR_FAMILY_IPV6; + ASSERT_SUCCESS(dash_acl_api->set_dash_acl_group_attribute(acl_group, &attr)); + ASSERT_SUCCESS(dash_acl_api->get_dash_acl_group_attribute(acl_group, 1, &attr)); + ASSERT_EQ(attr.value.s32, SAI_IP_ADDR_FAMILY_IPV6); + + ASSERT_SUCCESS(dash_acl_api->remove_dash_acl_group(acl_group)); +} + +TEST(APIBulk, acl_group) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + const uint32_t acls_count = 2; + const uint32_t acl_attrs_count = 1; + + sai_dash_acl_api_t *dash_acl_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ACL, (void**)&dash_acl_api)); + + sai_attribute_t attrs0[acl_attrs_count] = { + {.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY, .value = (sai_attribute_value_t){.s32 = SAI_IP_ADDR_FAMILY_IPV4}}, + }; + + sai_attribute_t attrs1[acl_attrs_count] = { + {.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY, .value = (sai_attribute_value_t){.s32 = SAI_IP_ADDR_FAMILY_IPV6}}, + }; + + const sai_attribute_t *attr_list[acls_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[acls_count] = {acl_attrs_count, acl_attrs_count}; + sai_object_id_t acls[acls_count]; + sai_status_t statuses[acls_count] = {}; + + ASSERT_SUCCESS(dash_acl_api->create_dash_acl_groups(switchid, acls_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, acls, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + for (uint32_t i = 0; i < acls_count; i++) { + sai_attribute_t attrs[acl_attrs_count] = { + {.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY, .value = {}}, + }; + ASSERT_SUCCESS(dash_acl_api->get_dash_acl_group_attribute(acls[i], acl_attrs_count, attrs)); + ASSERT_EQ(attrs[0].value.s32, attr_list[i][0].value.s32); + } + + ASSERT_SUCCESS(dash_acl_api->remove_dash_acl_groups(acls_count, acls, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } +} + +TEST(API, acl_rule) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_acl_api_t *dash_acl_api = nullptr; + sai_counter_api_t *counter_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ACL, (void**)&dash_acl_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_COUNTER, (void**)&counter_api)); + + sai_object_id_t group; + ASSERT_SUCCESS(dash_acl_api->create_dash_acl_group(&group, switchid, 0, nullptr)); + + sai_object_id_t counter; + ASSERT_SUCCESS(counter_api->create_counter(&counter, switchid, 0, nullptr)); + + sai_ip_prefix_t ip_addr_list[2] = {}; + + ip_addr_list[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ip_addr_list[0].addr.ip4); + inet_pton(AF_INET, "255.255.0.0", &ip_addr_list[0].mask.ip4); + ip_addr_list[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &ip_addr_list[1].addr.ip6); + inet_pton(AF_INET6, "ffff:fff0::", &ip_addr_list[1].mask.ip6); + sai_ip_prefix_list_t ip_prefix_list0 = {.count = 2, .list = ip_addr_list}; + sai_ip_prefix_list_t ip_prefix_list1 = {.count = 1, .list = ip_addr_list}; + + uint8_t protos[2] = {0xAA, 0xBB}; + sai_u8_list_t protos_list = {.count=2, .list = protos}; + + sai_u16_range_t port_ranges[2] = {{.min = 10, .max = 20}, {.min = 30, .max = 40}}; + sai_u16_range_list_t port_ranges_list0 = {.count=2, .list = port_ranges}; + sai_u16_range_list_t port_ranges_list1 = {.count=1, .list = port_ranges}; + + sai_attribute_t attr; + vector attrs; + + attr.id = SAI_DASH_ACL_RULE_ATTR_ACTION; + attr.value.s32 = SAI_DASH_ACL_RULE_ACTION_PERMIT; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID; + attr.value.oid = group; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DIP; + attr.value.ipprefixlist = ip_prefix_list0; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_SIP; + attr.value.ipprefixlist = ip_prefix_list1; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL; + attr.value.u8list = protos_list; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT; + attr.value.u16rangelist = port_ranges_list0; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT; + attr.value.u16rangelist = port_ranges_list1; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY; + attr.value.u32 = 1; + attrs.push_back(attr); + + sai_object_id_t acl; + ASSERT_SUCCESS(dash_acl_api->create_dash_acl_rule(&acl, switchid, (uint32_t)attrs.size(), attrs.data())); + + ASSERT_SUCCESS(dash_acl_api->get_dash_acl_rule_attribute(acl, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.s32, SAI_DASH_ACL_RULE_ACTION_PERMIT); + ASSERT_EQ(attrs[1].value.oid, group); + ASSERT_TRUE(compare_lists(attrs[2].value.ipprefixlist, ip_prefix_list0)); + ASSERT_TRUE(compare_lists(attrs[3].value.ipprefixlist, ip_prefix_list1)); + ASSERT_TRUE(compare_lists(attrs[4].value.u8list, protos_list)); + ASSERT_TRUE(compare_lists(attrs[5].value.u16rangelist, port_ranges_list0)); + ASSERT_TRUE(compare_lists(attrs[6].value.u16rangelist, port_ranges_list1)); + ASSERT_EQ(attrs[7].value.oid, counter); + ASSERT_EQ(attrs[8].value.u32, 1); + + attr.id = SAI_DASH_ACL_RULE_ATTR_ACTION; + attr.value.s32 = SAI_DASH_ACL_RULE_ACTION_DENY_AND_CONTINUE; + ASSERT_SUCCESS(dash_acl_api->set_dash_acl_rule_attribute(acl, &attr)); + + ASSERT_SUCCESS(dash_acl_api->get_dash_acl_rule_attribute(acl, 1, &attr)); + ASSERT_EQ(attr.value.s32, SAI_DASH_ACL_RULE_ACTION_DENY_AND_CONTINUE); + + ASSERT_SUCCESS(dash_acl_api->remove_dash_acl_rule(acl)); + + ASSERT_SUCCESS(counter_api->remove_counter(counter)); + ASSERT_SUCCESS(dash_acl_api->remove_dash_acl_group(group)); +} + +TEST(APIBulk, acl_rule) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + const uint32_t acls_count = 2; + const uint32_t acl_attrs_count = 9; + + sai_dash_acl_api_t *dash_acl_api = nullptr; + sai_counter_api_t *counter_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ACL, (void**)&dash_acl_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_COUNTER, (void**)&counter_api)); + + sai_object_id_t counter0; + ASSERT_SUCCESS(counter_api->create_counter(&counter0, switchid, 0, nullptr)); + + sai_object_id_t counter1; + ASSERT_SUCCESS(counter_api->create_counter(&counter1, switchid, 0, nullptr)); + + sai_object_id_t group0; + ASSERT_SUCCESS(dash_acl_api->create_dash_acl_group(&group0, switchid, 0, nullptr)); + + sai_object_id_t group1; + ASSERT_SUCCESS(dash_acl_api->create_dash_acl_group(&group1, switchid, 0, nullptr)); + + sai_ip_prefix_t ip_prefix_arr0[2] = {}; + ip_prefix_arr0[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ip_prefix_arr0[0].addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &ip_prefix_arr0[0].mask.ip4); + ip_prefix_arr0[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &ip_prefix_arr0[1].addr.ip6); + inet_pton(AF_INET6, "ffff::", &ip_prefix_arr0[1].mask.ip6); + + sai_ip_prefix_t ip_prefix_arr1[2] = {}; + ip_prefix_arr1[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.2", &ip_prefix_arr1[0].addr.ip4); + inet_pton(AF_INET, "255.255.0.0", &ip_prefix_arr1[0].mask.ip4); + ip_prefix_arr1[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:fffe", &ip_prefix_arr1[1].addr.ip6); + inet_pton(AF_INET6, "ffff::", &ip_prefix_arr1[1].mask.ip6); + + sai_ip_prefix_list_t ip_prefix_list0 = {.count = 1, .list = ip_prefix_arr0}; + sai_ip_prefix_list_t ip_prefix_list1 = {.count = 1, .list = ip_prefix_arr1}; + + uint8_t protos0[2] = {0xAA, 0xBB}; + uint8_t protos1[2] = {0xCC, 0xDD}; + sai_u8_list_t protos_list0 = {.count=2, .list = protos0}; + sai_u8_list_t protos_list1 = {.count=2, .list = protos1}; + + sai_u16_range_t port_ranges0[2] = {{.min = 10, .max = 20}, {.min = 30, .max = 40}}; + sai_u16_range_t port_ranges1[2] = {{.min = 50, .max = 60}, {.min = 70, .max = 80}}; + sai_u16_range_list_t u16_range_list0 = {.count=2, .list = port_ranges0}; + sai_u16_range_list_t u16_range_list1 = {.count=2, .list = port_ranges1}; + + sai_attribute_t attrs0[acl_attrs_count] = { + {.id = SAI_DASH_ACL_RULE_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DASH_ACL_RULE_ACTION_PERMIT_AND_CONTINUE}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID, .value = (sai_attribute_value_t){.oid = group0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL, .value = (sai_attribute_value_t){.u8list = protos_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY, .value = (sai_attribute_value_t){.u32 = 1}}, + }; + + sai_attribute_t attrs1[acl_attrs_count] = { + {.id = SAI_DASH_ACL_RULE_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DASH_ACL_RULE_ACTION_DENY}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID, .value = (sai_attribute_value_t){.oid = group1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL, .value = (sai_attribute_value_t){.u8list = protos_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY, .value = (sai_attribute_value_t){.u32 = 2}}, + }; + + const sai_attribute_t *attr_list[acls_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[acls_count] = {acl_attrs_count, acl_attrs_count}; + sai_object_id_t acls[acls_count]; + sai_status_t statuses[acls_count] = {}; + + ASSERT_SUCCESS(dash_acl_api->create_dash_acl_rules(switchid, acls_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, acls, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + for (uint32_t i = 0; i < acls_count; i++) { + sai_ip_prefix_t dip_ip_prefixes[2] = {}; + sai_ip_prefix_t sip_ip_prefixes[2] = {}; + sai_u16_range_t src_port_ranges[2] = {}; + sai_u16_range_t dst_port_ranges[2] = {}; + uint8_t protos[2] = {}; + sai_ip_prefix_list_t dip_ip_prefix_list = {.count = 2, .list = dip_ip_prefixes}; + sai_ip_prefix_list_t sip_ip_prefix_list = {.count = 2, .list = sip_ip_prefixes}; + sai_u8_list_t protos_list = {.count=2, .list = protos}; + sai_u16_range_list_t src_port_ranges_list = {.count=2, .list = src_port_ranges}; + sai_u16_range_list_t dst_port_ranges_list = {.count=2, .list = dst_port_ranges}; + + sai_attribute_t attrs[acl_attrs_count] = { + {.id = SAI_DASH_ACL_RULE_ATTR_ACTION, .value = {}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID, .value = {}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DIP, .value = (sai_attribute_value_t){.ipprefixlist = dip_ip_prefix_list}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SIP, .value = (sai_attribute_value_t){.ipprefixlist = sip_ip_prefix_list}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL, .value = (sai_attribute_value_t){.u8list = protos_list}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT, .value = (sai_attribute_value_t){.u16rangelist = src_port_ranges_list}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT, .value = (sai_attribute_value_t){.u16rangelist = dst_port_ranges_list}}, + {.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID, .value = {}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY, .value = {}}, + }; + + ASSERT_SUCCESS(dash_acl_api->get_dash_acl_rule_attribute(acls[i], acl_attrs_count, attrs)); + ASSERT_EQ(attrs[0].value.s32, attr_list[i][0].value.s32); + ASSERT_EQ(attrs[1].value.oid, attr_list[i][1].value.oid); + ASSERT_TRUE(compare_lists(attrs[2].value.ipprefixlist, attr_list[i][2].value.ipprefixlist)); + ASSERT_TRUE(compare_lists(attrs[3].value.ipprefixlist, attr_list[i][3].value.ipprefixlist)); + ASSERT_TRUE(compare_lists(attrs[4].value.u8list, attr_list[i][4].value.u8list)); + ASSERT_TRUE(compare_lists(attrs[5].value.u16rangelist, attr_list[i][5].value.u16rangelist)); + ASSERT_TRUE(compare_lists(attrs[6].value.u16rangelist, attr_list[i][6].value.u16rangelist)); + ASSERT_EQ(attrs[7].value.oid, attr_list[i][7].value.oid); + ASSERT_EQ(attrs[8].value.u32, attr_list[i][8].value.u32); + } + + ASSERT_SUCCESS(dash_acl_api->remove_dash_acl_rules(acls_count, acls, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + ASSERT_SUCCESS(dash_acl_api->remove_dash_acl_group(group0)); + ASSERT_SUCCESS(dash_acl_api->remove_dash_acl_group(group1)); + ASSERT_SUCCESS(counter_api->remove_counter(counter0)); + ASSERT_SUCCESS(counter_api->remove_counter(counter1)); +} + +TEST(API, vnet) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + + sai_object_id_t vnet; + sai_attribute_t attr; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 10; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet, switchid, 1, &attr)); + + ASSERT_SUCCESS(dash_vnet_api->get_vnet_attribute(vnet, 1, &attr)); + ASSERT_EQ(attr.value.u32, 10); + + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 20; + ASSERT_SUCCESS(dash_vnet_api->set_vnet_attribute(vnet, &attr)); + + ASSERT_SUCCESS(dash_vnet_api->get_vnet_attribute(vnet, 1, &attr)); + ASSERT_EQ(attr.value.u32, 20); + + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet)); +} + +TEST(APIBulk, vnet) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + const uint32_t vnets_count = 2; + const uint32_t vnet_attrs_count = 1; + + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + + sai_attribute_t attrs0[] = { + {.id = SAI_VNET_ATTR_VNI, .value = (sai_attribute_value_t){.u32 = 10}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_VNET_ATTR_VNI, .value = (sai_attribute_value_t){.u32 = 20}}, + }; + + const sai_attribute_t *attr_list[vnets_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[vnets_count] = {vnet_attrs_count, vnet_attrs_count}; + sai_object_id_t vnets[vnets_count]; + sai_status_t statuses[vnets_count] = {}; + + ASSERT_SUCCESS(dash_vnet_api->create_vnets(switchid, vnets_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, vnets, statuses)); + for (uint32_t i = 0; i < vnets_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + for (uint32_t i = 0; i < vnets_count; i++) { + sai_attribute_t attr = {}; + attr.id = SAI_VNET_ATTR_VNI; + ASSERT_SUCCESS(dash_vnet_api->get_vnet_attribute(vnets[i], 1, &attr)); + ASSERT_EQ(attr.value.u32, attr_list[i][0].value.u32); + } + + ASSERT_SUCCESS(dash_vnet_api->remove_vnets(vnets_count, vnets, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vnets_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } +} + +TEST(API, inbound_routing_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_eni_api_t *dash_api_eni = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + sai_dash_inbound_routing_api_t *dash_in_routing_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ENI, (void**)&dash_api_eni)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_INBOUND_ROUTING, (void**)&dash_in_routing_api)); + + sai_object_id_t vnet; + sai_attribute_t attr; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 10; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet, switchid, 1, &attr)); + + sai_object_id_t eni; + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet; + ASSERT_SUCCESS(dash_api_eni->create_eni(&eni, switchid, 1, &attr)); + + sai_ip_address_t sip, sip_mask; + sip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &sip.addr.ip4); + sip_mask.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.255.0", &sip_mask.addr.ip4); + + sai_inbound_routing_entry_t entry = { .switch_id = switchid, .eni_id = eni, .vni = 10, .sip = sip, .sip_mask = sip_mask, .priority = 1}; + + vector attrs; + attr.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE; + attrs.push_back(attr); + + attr.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + + ASSERT_SUCCESS(dash_in_routing_api->create_inbound_routing_entry(&entry, (uint32_t)attrs.size(), attrs.data())); + + ASSERT_SUCCESS(dash_in_routing_api->get_inbound_routing_entry_attribute(&entry, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.s32, SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE); + ASSERT_EQ(attrs[1].value.oid, vnet); + + attr.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP; + ASSERT_SUCCESS(dash_in_routing_api->set_inbound_routing_entry_attribute(&entry, &attr)); + + ASSERT_SUCCESS(dash_in_routing_api->get_inbound_routing_entry_attribute(&entry, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.s32, SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP); + ASSERT_EQ(attrs[1].value.oid, vnet); + + ASSERT_SUCCESS(dash_in_routing_api->remove_inbound_routing_entry(&entry)); + ASSERT_SUCCESS(dash_api_eni->remove_eni(eni)); +} + +TEST(APIBulk, inbound_routing_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 2; + + sai_dash_eni_api_t *dash_api_eni = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + sai_dash_inbound_routing_api_t *dash_in_routing_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ENI, (void**)&dash_api_eni)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_INBOUND_ROUTING, (void**)&dash_in_routing_api)); + + sai_object_id_t vnet0, vnet1; + sai_attribute_t attr; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 10; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet0, switchid, 1, &attr)); + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 100; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet1, switchid, 1, &attr)); + + sai_object_id_t eni0, eni1; + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet0; + ASSERT_SUCCESS(dash_api_eni->create_eni(&eni0, switchid, 1, &attr)); + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet0; + ASSERT_SUCCESS(dash_api_eni->create_eni(&eni1, switchid, 1, &attr)); + + sai_ip_address_t sip0, sip_mask0; + sai_ip_address_t sip1, sip_mask1; + sip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &sip0.addr.ip4); + sip_mask0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.255.0", &sip_mask0.addr.ip4); + sip1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.2", &sip1.addr.ip4); + sip_mask1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.0.0", &sip_mask1.addr.ip4); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP}}, + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP}}, + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_inbound_routing_entry_t entries[entries_count] = { + { .switch_id = switchid, .eni_id = eni0, .vni = 10, .sip = sip0, .sip_mask = sip_mask0, .priority = 1}, + { .switch_id = switchid, .eni_id = eni1, .vni = 100, .sip = sip1, .sip_mask = sip_mask1, .priority = 2} + }; + + ASSERT_SUCCESS(dash_in_routing_api->create_inbound_routing_entries(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + for (uint32_t i = 0; i < entries_count; i++) { + sai_attribute_t attrs[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = {}}, + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID, .value = {}}, + }; + + ASSERT_SUCCESS(dash_in_routing_api->get_inbound_routing_entry_attribute(&entries[i], entry_attrs_count, attrs)); + ASSERT_EQ(attrs[0].value.s32, attr_list[i][0].value.s32); + ASSERT_EQ(attrs[1].value.oid, attr_list[i][1].value.oid); + } + + ASSERT_SUCCESS(dash_in_routing_api->remove_inbound_routing_entries(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + ASSERT_SUCCESS(dash_api_eni->remove_eni(eni0)); + ASSERT_SUCCESS(dash_api_eni->remove_eni(eni1)); +} + +TEST(API, pa_validation_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_pa_validation_api_t *dash_api = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_PA_VALIDATION, (void**)&dash_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + + sai_attribute_t attr; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 10; + + sai_object_id_t vnet; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet, switchid, 1, &attr)); + + sai_pa_validation_entry_t entry; + entry.switch_id = switchid; + entry.vnet_id = vnet; + entry.sip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.3.3.3", &entry.sip.addr.ip4); + + vector attrs; + attr.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT; + attrs.push_back(attr); + + ASSERT_SUCCESS(dash_api->create_pa_validation_entry(&entry, (uint32_t)attrs.size(), attrs.data())); + + attr.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT; + ASSERT_SUCCESS(dash_api->set_pa_validation_entry_attribute(&entry, &attr)); + + ASSERT_SUCCESS(dash_api->get_pa_validation_entry_attribute(&entry, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.s32, SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT); + + ASSERT_SUCCESS(dash_api->remove_pa_validation_entry(&entry)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet)); +} + +TEST(APIBulk, pa_validation_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 1; + + sai_dash_pa_validation_api_t *dash_api = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_PA_VALIDATION, (void**)&dash_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + + sai_attribute_t vnetattr; + vnetattr.id = SAI_VNET_ATTR_VNI; + + sai_object_id_t vnet0, vnet1; + vnetattr.value.u32 = 10; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet0, switchid, 1, &vnetattr)); + vnetattr.value.u32 = 20; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet1, switchid, 1, &vnetattr)); + + sai_ip_address_t sip0 = {}; + sai_ip_address_t sip1 = {}; + sip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + sip1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET, "192.1.1.1", &sip0.addr.ip4); + inet_pton(AF_INET6, "ffff::", &sip1.addr.ip6); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_pa_validation_entry_t entries[entries_count] = { + { .switch_id = switchid, .vnet_id = vnet0, .sip = sip0}, + { .switch_id = switchid, .vnet_id = vnet1, .sip = sip1}, + }; + + ASSERT_SUCCESS(dash_api->create_pa_validation_entries(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + for (uint32_t i = 0; i < entries_count; i++) { + sai_attribute_t attr = {}; + attr.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION; + ASSERT_SUCCESS(dash_api->get_pa_validation_entry_attribute(&entries[i], 1, &attr)); + ASSERT_EQ(attr.value.s32, attr_list[i][0].value.s32); + } + + ASSERT_SUCCESS(dash_api->remove_pa_validation_entries(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet0)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet1)); +} + +TEST(API, outbound_routing_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_eni_api_t *dash_eni_api = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + sai_counter_api_t *counter_api = nullptr; + sai_dash_outbound_routing_api_t *dash_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ENI, (void**)&dash_eni_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_COUNTER, (void**)&counter_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_OUTBOUND_ROUTING, (void**)&dash_api)); + + sai_object_id_t counter; + ASSERT_SUCCESS(counter_api->create_counter(&counter, switchid, 0, nullptr)); + + sai_attribute_t attr; + sai_object_id_t eni, vnet; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 101; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet, switchid, 1, &attr)); + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet; + ASSERT_SUCCESS(dash_eni_api->create_eni(&eni, switchid, 1, &attr)); + + sai_ip_address_t oip6; + oip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "ffff::", &oip6.addr); + + sai_outbound_routing_entry_t entry0; + entry0.switch_id = switchid; + entry0.eni_id = eni; + entry0.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.1.0", &entry0.destination.addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &entry0.destination.mask.ip4); + + vector attrs; + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.u32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP; + attr.value.ipaddr = oip6; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + ASSERT_SUCCESS(dash_api->create_outbound_routing_entry(&entry0, (uint32_t)attrs.size(), attrs.data())); + + ASSERT_SUCCESS(dash_api->get_outbound_routing_entry_attribute(&entry0, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.u32, SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET); + ASSERT_EQ(attrs[1].value.oid, vnet); + ASSERT_EQ(attrs[2].value.ipaddr, oip6); + ASSERT_EQ(attrs[3].value.oid, counter); + + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.u32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_DIRECT; + ASSERT_SUCCESS(dash_api->set_outbound_routing_entry_attribute(&entry0, &attr)); + + ASSERT_SUCCESS(dash_api->get_outbound_routing_entry_attribute(&entry0, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.u32, SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_DIRECT); + ASSERT_EQ(attrs[1].value.oid, vnet); + ASSERT_EQ(attrs[2].value.ipaddr, oip6); + ASSERT_EQ(attrs[3].value.oid, counter); + + ASSERT_SUCCESS(dash_api->remove_outbound_routing_entry(&entry0)); + + ASSERT_SUCCESS(dash_eni_api->remove_eni(eni)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet)); + ASSERT_SUCCESS(counter_api->remove_counter(counter)); +} + +TEST(APIBulk, outbound_routing_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 4; + + sai_dash_eni_api_t *dash_eni_api = nullptr; + sai_dash_outbound_routing_api_t *dash_api = nullptr; + sai_counter_api_t *counter_api = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_ENI, (void**)&dash_eni_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_COUNTER, (void**)&counter_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_OUTBOUND_ROUTING, (void**)&dash_api)); + + sai_object_id_t counter0, counter1; + ASSERT_SUCCESS(counter_api->create_counter(&counter0, switchid, 0, nullptr)); + ASSERT_SUCCESS(counter_api->create_counter(&counter1, switchid, 0, nullptr)); + + sai_ip_address_t oip4, oip6; + oip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "1.2.3.4", &oip4.addr); + oip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "ffff::", &oip6.addr); + + sai_attribute_t attr; + sai_object_id_t vnet0, vnet1; + sai_object_id_t eni0, eni1; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 101; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet0, switchid, 1, &attr)); + + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 102; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet1, switchid, 1, &attr)); + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet0; + ASSERT_SUCCESS(dash_eni_api->create_eni(&eni0, switchid, 1, &attr)); + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet1; + ASSERT_SUCCESS(dash_eni_api->create_eni(&eni1, switchid, 1, &attr)); + + sai_ip_prefix_t dst0 = {}; + sai_ip_prefix_t dst1 = {}; + dst0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + dst1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET, "192.1.1.1", &dst0.addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &dst0.mask.ip4); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe0", &dst1.addr.ip6); + inet_pton(AF_INET6, "ffff:ffff::", &dst1.mask.ip6); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP, .value = (sai_attribute_value_t){.ipaddr = oip4}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP, .value = (sai_attribute_value_t){.ipaddr = oip6}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_outbound_routing_entry_t entries[entries_count] = { + { .switch_id = switchid, .eni_id = eni0, .destination = dst0}, + { .switch_id = switchid, .eni_id = eni1, .destination = dst1}, + }; + + ASSERT_SUCCESS(dash_api->create_outbound_routing_entries(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + for (uint32_t i = 0; i < entries_count; i++) { + sai_attribute_t attrs[entry_attrs_count] = { + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = {}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID, .value = {}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP, .value = {}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID, .value = {}}, + }; + + ASSERT_SUCCESS(dash_api->get_outbound_routing_entry_attribute(&entries[i], entry_attrs_count, attrs)); + ASSERT_EQ(attrs[0].value.s32, attr_list[i][0].value.s32); + ASSERT_EQ(attrs[1].value.oid, attr_list[i][1].value.oid); + ASSERT_EQ(attrs[2].value.ipaddr, attr_list[i][2].value.ipaddr); + ASSERT_EQ(attrs[3].value.oid, attr_list[i][3].value.oid); + } + + ASSERT_SUCCESS(dash_api->remove_outbound_routing_entries(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + ASSERT_SUCCESS(dash_eni_api->remove_eni(eni0)); + ASSERT_SUCCESS(dash_eni_api->remove_eni(eni1)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet0)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet1)); + ASSERT_SUCCESS(counter_api->remove_counter(counter0)); + ASSERT_SUCCESS(counter_api->remove_counter(counter1)); +} + +TEST(API, outbound_ca_to_pa_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + sai_dash_outbound_ca_to_pa_api_t *dash_api = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + sai_counter_api_t *counter_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_OUTBOUND_CA_TO_PA, (void**)&dash_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_COUNTER, (void**)&counter_api)); + + sai_object_id_t counter; + ASSERT_SUCCESS(counter_api->create_counter(&counter, switchid, 0, nullptr)); + + sai_ip_address_t uip4; + uip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &uip4.addr.ip4); + + sai_attribute_t vnetattr; + vnetattr.id = SAI_VNET_ATTR_VNI; + vnetattr.value.u32 = 10; + + sai_object_id_t vnet; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet, switchid, 1, &vnetattr)); + + sai_outbound_ca_to_pa_entry_t entry; + entry.switch_id = switchid; + entry.dst_vnet_id = vnet; + entry.dip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &entry.dip.addr.ip4); + + sai_attribute_t attr; + vector attrs; + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP; + attr.value.ipaddr = uip4; + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC; + sai_mac_t dmac = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + memcpy(attr.value.mac, dmac, 6); + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI; + attr.value.booldata = false; + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + + ASSERT_SUCCESS(dash_api->create_outbound_ca_to_pa_entry(&entry, (uint32_t)attrs.size(), attrs.data())); + + ASSERT_SUCCESS(dash_api->get_outbound_ca_to_pa_entry_attribute(&entry, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.ipaddr, uip4); + ASSERT_TRUE(memcmp(attrs[1].value.mac, dmac, sizeof(dmac)) == 0); + ASSERT_EQ(attrs[2].value.booldata, false); + ASSERT_EQ(attrs[3].value.oid, counter); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI; + attr.value.booldata = true; + ASSERT_SUCCESS(dash_api->set_outbound_ca_to_pa_entry_attribute(&entry, &attr)); + + ASSERT_SUCCESS(dash_api->get_outbound_ca_to_pa_entry_attribute(&entry, (uint32_t)attrs.size(), attrs.data())); + ASSERT_EQ(attrs[0].value.ipaddr, uip4); + ASSERT_TRUE(memcmp(attrs[1].value.mac, dmac, sizeof(dmac)) == 0); + ASSERT_EQ(attrs[2].value.booldata, true); + ASSERT_EQ(attrs[3].value.oid, counter); + + ASSERT_SUCCESS(dash_api->remove_outbound_ca_to_pa_entry(&entry)); + + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet)); + ASSERT_SUCCESS(counter_api->remove_counter(counter)); +} + +TEST(APIBulk, outbound_ca_to_pa_entry) +{ + SWSS_LOG_ENTER(); + + auto switchid = TestDashEnv::instance()->getSwitchOid(); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 4; + + sai_dash_outbound_ca_to_pa_api_t *dash_api = nullptr; + sai_dash_vnet_api_t *dash_vnet_api = nullptr; + sai_counter_api_t *counter_api = nullptr; + + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_OUTBOUND_CA_TO_PA, (void**)&dash_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&dash_vnet_api)); + ASSERT_SUCCESS(sai_api_query((sai_api_t)SAI_API_COUNTER, (void**)&counter_api)); + + sai_object_id_t counter0, counter1; + ASSERT_SUCCESS(counter_api->create_counter(&counter0, switchid, 0, nullptr)); + ASSERT_SUCCESS(counter_api->create_counter(&counter1, switchid, 0, nullptr)); + + sai_attribute_t vnetattr; + vnetattr.id = SAI_VNET_ATTR_VNI; + + sai_object_id_t vnet0, vnet1; + vnetattr.value.u32 = 10; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet0, switchid, 1, &vnetattr)); + vnetattr.value.u32 = 20; + ASSERT_SUCCESS(dash_vnet_api->create_vnet(&vnet1, switchid, 1, &vnetattr)); + + sai_ip_address_t dip0 = {}; + sai_ip_address_t dip1 = {}; + sai_ip_address_t udip0 = {}; + sai_ip_address_t udip1 = {}; + dip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + dip1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + udip0.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + udip1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.1.1.1", &dip0.addr.ip4); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe0", &dip1.addr.ip6); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe1", &udip0.addr.ip6); + inet_pton(AF_INET, "192.1.1.2", &udip1.addr.ip4); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = udip0}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC, .value = (sai_attribute_value_t){.mac = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}} + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = udip1}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC, .value = (sai_attribute_value_t){.mac = {0x00, 0x11, 0x22, 0x33, 0x44, 0x56}}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI, .value = (sai_attribute_value_t){.booldata = false}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}} + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_outbound_ca_to_pa_entry_t entries[entries_count] = { + { .switch_id = switchid, .dst_vnet_id = vnet0, .dip = dip0}, + { .switch_id = switchid, .dst_vnet_id = vnet1, .dip = dip1}, + }; + + ASSERT_SUCCESS(dash_api->create_outbound_ca_to_pa_entries(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + for (uint32_t i = 0; i < entries_count; i++) { + sai_attribute_t attrs[entry_attrs_count] = { + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP, .value = {}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC, .value = {}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI, .value = {}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID, .value = {}}, + }; + + ASSERT_SUCCESS(dash_api->get_outbound_ca_to_pa_entry_attribute(&entries[i], entry_attrs_count, attrs)); + ASSERT_EQ(attrs[0].value.ipaddr, attr_list[i][0].value.ipaddr); + ASSERT_TRUE(memcmp(attrs[1].value.mac, attr_list[i][1].value.mac, sizeof(attrs[1].value.mac)) == 0); + ASSERT_EQ(attrs[2].value.booldata, attr_list[i][2].value.booldata); + ASSERT_EQ(attrs[3].value.oid, attr_list[i][3].value.oid); + } + + ASSERT_SUCCESS(dash_api->remove_outbound_ca_to_pa_entries(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + ASSERT_SUCCESS(statuses[i]); + } + + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet0)); + ASSERT_SUCCESS(dash_vnet_api->remove_vnet(vnet1)); + ASSERT_SUCCESS(counter_api->remove_counter(counter0)); + ASSERT_SUCCESS(counter_api->remove_counter(counter1)); +} diff --git a/tests/TestDashEnv.cpp b/tests/TestDashEnv.cpp new file mode 100644 index 000000000..78f3e04e7 --- /dev/null +++ b/tests/TestDashEnv.cpp @@ -0,0 +1,140 @@ +#include "TestDashEnv.h" + +#include "sairedis.h" +#include "syncd/ServiceMethodTable.h" + +#define ASSERT_SUCCESS(e) ASSERT_EQ((e), SAI_STATUS_SUCCESS) + +static int profileGetNextValue( + _In_ sai_switch_profile_id_t profile_id, + _Out_ const char **variable, + _Out_ const char **value) +{ + // SWSS_LOG_ENTER(); // disabled + + return 0; +} + +static const char* profileGetValue( + _In_ sai_switch_profile_id_t profile_id, + _In_ const char *variable, + _In_ bool is_client) +{ + // SWSS_LOG_ENTER(); // disabled + + if (is_client && !std::string(variable).compare(SAI_REDIS_KEY_ENABLE_CLIENT)) { + return "true"; + } + + return NULL; +} + +TestDashEnv* TestDashEnv::instance() +{ + // SWSS_LOG_ENTER(); // disabled + + static TestDashEnv* env = new TestDashEnv(); + + return env; +} + +void TestDashEnv::StopSyncd() +{ + SWSS_LOG_ENTER(); + + int rc = std::system("killall -q -9 syncd vssyncd"); + ASSERT_TRUE(rc == 0 || rc == 256); +} + +void TestDashEnv::StartSyncd() +{ + SWSS_LOG_ENTER(); + + int rc = std::system("./vssyncd -SUu -p \"NVDAMBF2H536C/vsprofile.ini\" -z redis_sync &"); + ASSERT_EQ(rc, 0); +} + +void TestDashEnv::FlushRedis() +{ + SWSS_LOG_ENTER(); + + int rc = std::system("redis-cli flushall"); + ASSERT_EQ(rc, 0); +} + +void TestDashEnv::CreateSwitch() +{ + SWSS_LOG_ENTER(); + + using namespace std::placeholders; + + syncd::ServiceMethodTable smt; + smt.profileGetValue = std::bind(profileGetValue, _1, _2, !m_manage_syncd); + smt.profileGetNextValue = profileGetNextValue; + auto sai_smt = smt.getServiceMethodTable(); + + ASSERT_EQ(sai_api_initialize(0, &sai_smt), SAI_STATUS_SUCCESS); + + sai_switch_api_t *switch_api; + ASSERT_EQ(sai_api_query(SAI_API_SWITCH, (void **)&switch_api), SAI_STATUS_SUCCESS); + + sai_attribute_t attr; + + if (m_manage_syncd) + { + attr.id = SAI_REDIS_SWITCH_ATTR_RECORD; + attr.value.booldata = true; + ASSERT_EQ(switch_api->set_switch_attribute(SAI_NULL_OBJECT_ID, &attr), SAI_STATUS_SUCCESS); + + attr.id = SAI_REDIS_SWITCH_ATTR_NOTIFY_SYNCD; + attr.value.s32 = SAI_REDIS_NOTIFY_SYNCD_INIT_VIEW; + ASSERT_EQ(switch_api->set_switch_attribute(SAI_NULL_OBJECT_ID, &attr), SAI_STATUS_SUCCESS); + + attr.id = SAI_REDIS_SWITCH_ATTR_REDIS_COMMUNICATION_MODE; + attr.value.s32 = SAI_REDIS_COMMUNICATION_MODE_REDIS_SYNC; + ASSERT_EQ(switch_api->set_switch_attribute(SAI_NULL_OBJECT_ID, &attr), SAI_STATUS_SUCCESS); + } + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = m_manage_syncd; + ASSERT_EQ(switch_api->create_switch(&m_switch_id, 1, &attr), SAI_STATUS_SUCCESS); + + ASSERT_NE(m_switch_id, SAI_NULL_OBJECT_ID); + + if (m_manage_syncd) + { + attr.id = SAI_REDIS_SWITCH_ATTR_NOTIFY_SYNCD; + attr.value.s32 = SAI_REDIS_NOTIFY_SYNCD_APPLY_VIEW; + ASSERT_EQ(switch_api->set_switch_attribute(m_switch_id, &attr), SAI_STATUS_SUCCESS); + } +} + +TestDashEnv::TestDashEnv() +{ + m_manage_syncd = getenv(ENV_CLIENT_MODE_OPT) == nullptr; +} + +void TestDashEnv::SetUp() +{ + SWSS_LOG_ENTER(); + + if (m_manage_syncd) { + StopSyncd(); + FlushRedis(); + StartSyncd(); + } + + CreateSwitch(); +} + +void TestDashEnv::TearDown() +{ + SWSS_LOG_ENTER(); + + auto status = sai_api_uninitialize(); + ASSERT_EQ(status, SAI_STATUS_SUCCESS); + + if (m_manage_syncd) { + StopSyncd(); + } +} diff --git a/tests/TestDashEnv.h b/tests/TestDashEnv.h new file mode 100644 index 000000000..f93421660 --- /dev/null +++ b/tests/TestDashEnv.h @@ -0,0 +1,32 @@ +#pragma once + +extern "C" { + #include + #include +} + +#include "gtest/gtest.h" + +#define ENV_CLIENT_MODE_OPT "TESTDASH_CLIENT_MODE" + +class TestDashEnv : public ::testing::Environment +{ +public: + static TestDashEnv* instance(); + + virtual void SetUp() override; + + virtual void TearDown() override; + + sai_object_id_t getSwitchOid() const { return m_switch_id; } + +private: + void StopSyncd(); + void StartSyncd(); + void FlushRedis(); + void CreateSwitch(); + TestDashEnv(); + + sai_object_id_t m_switch_id = SAI_NULL_OBJECT_ID; + bool m_manage_syncd = true; +}; diff --git a/tests/TestDashMain.cpp b/tests/TestDashMain.cpp new file mode 100644 index 000000000..1765eecea --- /dev/null +++ b/tests/TestDashMain.cpp @@ -0,0 +1,16 @@ +#include "TestDashEnv.h" + +#include "swss/logger.h" + +int main(int argc, char **argv) +{ + SWSS_LOG_ENTER(); + + swss::Logger::getInstance().setMinPrio(swss::Logger::SWSS_NOTICE); + + testing::InitGoogleTest(&argc, argv); + + testing::AddGlobalTestEnvironment(TestDashEnv::instance()); + + return RUN_ALL_TESTS(); +} diff --git a/tests/testclient.cpp b/tests/testclient.cpp index 47f3c1763..2b0ff3a59 100644 --- a/tests/testclient.cpp +++ b/tests/testclient.cpp @@ -1,512 +1,4 @@ -#include "sairedis.h" - -#include "syncd/ServiceMethodTable.h" - -#include "meta/sai_serialize.h" - -#include -#include - -using namespace std::placeholders; - -class TestClient -{ - public: - - TestClient(); - - virtual ~TestClient(); - - public: - - void test_create_vlan(); - - void test_bulk_create_vlan(); - - void test_query_api(); - - void test_fdb_flush(); - - void test_stats(); - - private: - - int profileGetNextValue( - _In_ sai_switch_profile_id_t profile_id, - _Out_ const char** variable, - _Out_ const char** value); - - const char* profileGetValue( - _In_ sai_switch_profile_id_t profile_id, - _In_ const char* variable); - - private: - - std::map m_profileMap; - - std::map::iterator m_profileIter; - - syncd::ServiceMethodTable m_smt; - - sai_service_method_table_t m_test_services; -}; - -TestClient::TestClient() -{ - SWSS_LOG_ENTER(); - - // empty intentionally -} - -TestClient::~TestClient() -{ - SWSS_LOG_ENTER(); - - // empty intentionally -} - -const char* TestClient::profileGetValue( - _In_ sai_switch_profile_id_t profile_id, - _In_ const char* variable) -{ - SWSS_LOG_ENTER(); - - if (variable == NULL) - { - SWSS_LOG_WARN("variable is null"); - return NULL; - } - - auto it = m_profileMap.find(variable); - - if (it == m_profileMap.end()) - { - SWSS_LOG_NOTICE("%s: NULL", variable); - return NULL; - } - - SWSS_LOG_NOTICE("%s: %s", variable, it->second.c_str()); - - return it->second.c_str(); -} - -int TestClient::profileGetNextValue( - _In_ sai_switch_profile_id_t profile_id, - _Out_ const char** variable, - _Out_ const char** value) -{ - SWSS_LOG_ENTER(); - - if (value == NULL) - { - SWSS_LOG_INFO("resetting profile map iterator"); - - m_profileIter = m_profileMap.begin(); - return 0; - } - - if (variable == NULL) - { - SWSS_LOG_WARN("variable is null"); - return -1; - } - - if (m_profileIter == m_profileMap.end()) - { - SWSS_LOG_INFO("iterator reached end"); - return -1; - } - - *variable = m_profileIter->first.c_str(); - *value = m_profileIter->second.c_str(); - - SWSS_LOG_INFO("key: %s:%s", *variable, *value); - - m_profileIter++; - - return 0; -} - -#define ASSERT_TRUE(x) \ - if (!(x)) \ -{\ - SWSS_LOG_THROW("assert true failed '%s', line: %d", # x, __LINE__);\ -} - -#define ASSERT_SUCCESS(x) \ - if (x != SAI_STATUS_SUCCESS) \ -{\ - SWSS_LOG_THROW("expected success, line: %d, got: %s", __LINE__, sai_serialize_status(x).c_str());\ -} - -void TestClient::test_create_vlan() -{ - SWSS_LOG_ENTER(); - - m_profileMap.clear(); - - m_profileMap[SAI_REDIS_KEY_ENABLE_CLIENT] = "true"; // act as a client - - m_profileIter = m_profileMap.begin(); - - m_smt.profileGetValue = std::bind(&TestClient::profileGetValue, this, _1, _2); - m_smt.profileGetNextValue = std::bind(&TestClient::profileGetNextValue, this, _1, _2, _3); - - m_test_services = m_smt.getServiceMethodTable(); - - ASSERT_SUCCESS(sai_api_initialize(0, &m_test_services)); - - sai_switch_api_t* switch_api; - - ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api)); - - sai_attribute_t attr; - - // connect to existing switch - attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; - attr.value.booldata = false; - - sai_object_id_t switch_id = SAI_NULL_OBJECT_ID; - - ASSERT_SUCCESS(switch_api->create_switch(&switch_id, 1, &attr)); - - ASSERT_TRUE(switch_id != SAI_NULL_OBJECT_ID); - - SWSS_LOG_NOTICE("switchId: %s", sai_serialize_object_id(switch_id).c_str()); - - attr.id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; - - ASSERT_SUCCESS(switch_api->get_switch_attribute(switch_id, 1, &attr)); - - SWSS_LOG_NOTICE("got VRID: %s", sai_serialize_object_id(attr.value.oid).c_str()); - - sai_vlan_api_t* vlan_api; - - ASSERT_SUCCESS(sai_api_query(SAI_API_VLAN, (void**)&vlan_api)); - - attr.id = SAI_VLAN_ATTR_VLAN_ID; - attr.value.u16 = 200; - - sai_object_id_t vlan_id; - - ASSERT_SUCCESS(vlan_api->create_vlan(&vlan_id, switch_id, 1, &attr)); - - ASSERT_TRUE(vlan_id != SAI_NULL_OBJECT_ID); - - ASSERT_SUCCESS(vlan_api->remove_vlan(vlan_id)); - - ASSERT_SUCCESS(sai_api_uninitialize()); -} - -void TestClient::test_bulk_create_vlan() -{ - SWSS_LOG_ENTER(); - - m_profileMap.clear(); - - m_profileMap[SAI_REDIS_KEY_ENABLE_CLIENT] = "true"; // act as a client - - m_profileIter = m_profileMap.begin(); - - m_smt.profileGetValue = std::bind(&TestClient::profileGetValue, this, _1, _2); - m_smt.profileGetNextValue = std::bind(&TestClient::profileGetNextValue, this, _1, _2, _3); - - m_test_services = m_smt.getServiceMethodTable(); - - ASSERT_SUCCESS(sai_api_initialize(0, &m_test_services)); - - sai_switch_api_t* switch_api; - - ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api)); - - sai_attribute_t attr; - - // connect to existing switch - attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; - attr.value.booldata = false; - - sai_object_id_t switch_id = SAI_NULL_OBJECT_ID; - - ASSERT_SUCCESS(switch_api->create_switch(&switch_id, 1, &attr)); - - ASSERT_TRUE(switch_id != SAI_NULL_OBJECT_ID); - - SWSS_LOG_NOTICE("switchId: %s", sai_serialize_object_id(switch_id).c_str()); - - attr.id = SAI_SWITCH_ATTR_DEFAULT_VIRTUAL_ROUTER_ID; - - ASSERT_SUCCESS(switch_api->get_switch_attribute(switch_id, 1, &attr)); - - SWSS_LOG_NOTICE("got VRID: %s", sai_serialize_object_id(attr.value.oid).c_str()); - - attr.id = SAI_SWITCH_ATTR_DEFAULT_1Q_BRIDGE_ID; - - ASSERT_SUCCESS(switch_api->get_switch_attribute(switch_id, 1, &attr)); - - sai_object_id_t bridge_id = attr.value.oid; - - sai_bridge_api_t* bridge_api; - - ASSERT_SUCCESS(sai_api_query(SAI_API_BRIDGE, (void**)&bridge_api)); - - sai_object_id_t ports[128]; - - attr.id = SAI_BRIDGE_ATTR_PORT_LIST; - attr.value.objlist.count = 128; - attr.value.objlist.list = ports; - - ASSERT_SUCCESS(bridge_api->get_bridge_attribute(bridge_id, 1, &attr)); - - sai_vlan_api_t* vlan_api; - - ASSERT_SUCCESS(sai_api_query(SAI_API_VLAN, (void**)&vlan_api)); - - // create vlan - - attr.id = SAI_VLAN_ATTR_VLAN_ID; - attr.value.u16 = 200; - - sai_object_id_t vlan_id; - - ASSERT_SUCCESS(vlan_api->create_vlan(&vlan_id, switch_id, 1, &attr)); - - ASSERT_TRUE(vlan_id != SAI_NULL_OBJECT_ID); - - // bulk create vlan members - - uint32_t attr_count[2] = { 2, 2 }; - - const sai_attribute_t* attr_list[2]; - - sai_attribute_t attr0[2]; - - attr0[0].id = SAI_VLAN_MEMBER_ATTR_VLAN_ID; - attr0[0].value.oid = vlan_id; - - attr0[1].id = SAI_VLAN_MEMBER_ATTR_BRIDGE_PORT_ID; - attr0[1].value.oid = ports[0]; - - attr_list[0] = attr0; - - sai_attribute_t attr1[2]; - - attr1[0].id = SAI_VLAN_MEMBER_ATTR_VLAN_ID; - attr1[0].value.oid = vlan_id; - - attr1[1].id = SAI_VLAN_MEMBER_ATTR_BRIDGE_PORT_ID; - attr1[1].value.oid = ports[1]; - - attr_list[1] = attr1; - - sai_object_id_t members[2] = { SAI_NULL_OBJECT_ID, SAI_NULL_OBJECT_ID }; - sai_status_t statuses[2]; - - auto status = vlan_api->create_vlan_members( - switch_id, - 2, - attr_count, - attr_list, - SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, - members, - statuses); - - ASSERT_SUCCESS(status); - - ASSERT_SUCCESS(statuses[0]); - ASSERT_SUCCESS(statuses[1]); - - ASSERT_TRUE(members[0] != SAI_NULL_OBJECT_ID); - ASSERT_TRUE(members[1] != SAI_NULL_OBJECT_ID); - - SWSS_LOG_NOTICE("members: %s, %s", - sai_serialize_object_id(members[0]).c_str(), - sai_serialize_object_id(members[1]).c_str()); - - // bulk remove vlan members - - status = vlan_api->remove_vlan_members( - 2, - members, - SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, - statuses); - - ASSERT_SUCCESS(status); - - ASSERT_SUCCESS(statuses[0]); - ASSERT_SUCCESS(statuses[1]); - - // remove vlan - - ASSERT_SUCCESS(vlan_api->remove_vlan(vlan_id)); - - ASSERT_SUCCESS(sai_api_uninitialize()); -} - -void TestClient::test_query_api() -{ - SWSS_LOG_ENTER(); - - m_profileMap.clear(); - - m_profileMap[SAI_REDIS_KEY_ENABLE_CLIENT] = "true"; // act as a client - - m_profileIter = m_profileMap.begin(); - - m_smt.profileGetValue = std::bind(&TestClient::profileGetValue, this, _1, _2); - m_smt.profileGetNextValue = std::bind(&TestClient::profileGetNextValue, this, _1, _2, _3); - - m_test_services = m_smt.getServiceMethodTable(); - - ASSERT_SUCCESS(sai_api_initialize(0, &m_test_services)); - - sai_switch_api_t* switch_api; - - ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api)); - - sai_attribute_t attr; - - // connect to existing switch - attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; - attr.value.booldata = false; - - sai_object_id_t switch_id = SAI_NULL_OBJECT_ID; - - ASSERT_SUCCESS(switch_api->create_switch(&switch_id, 1, &attr)); - - ASSERT_TRUE(switch_id != SAI_NULL_OBJECT_ID); - - SWSS_LOG_NOTICE("switchId: %s", sai_serialize_object_id(switch_id).c_str()); - - sai_attr_capability_t cap; - - SWSS_LOG_NOTICE(" * sai_query_attribute_capability"); - - ASSERT_SUCCESS(sai_query_attribute_capability( - switch_id, - SAI_OBJECT_TYPE_SWITCH, - SAI_SWITCH_ATTR_INIT_SWITCH, - &cap)); - - int32_t vec[3]; - sai_s32_list_t list; - - list.count = 3; - list.list = vec; - - SWSS_LOG_NOTICE(" * sai_query_attribute_enum_values_capability"); - - ASSERT_SUCCESS(sai_query_attribute_enum_values_capability( - switch_id, - SAI_OBJECT_TYPE_DEBUG_COUNTER, - SAI_DEBUG_COUNTER_ATTR_IN_DROP_REASON_LIST, - &list)); - - uint64_t count; - - SWSS_LOG_NOTICE(" * sai_object_type_get_availability"); - - ASSERT_SUCCESS(sai_object_type_get_availability( - switch_id, - SAI_OBJECT_TYPE_DEBUG_COUNTER, - 0, - NULL, - &count)); - - ASSERT_SUCCESS(sai_api_uninitialize()); -} - -void TestClient::test_fdb_flush() -{ - SWSS_LOG_ENTER(); - - m_profileMap.clear(); - - m_profileMap[SAI_REDIS_KEY_ENABLE_CLIENT] = "true"; // act as a client - - m_profileIter = m_profileMap.begin(); - - m_smt.profileGetValue = std::bind(&TestClient::profileGetValue, this, _1, _2); - m_smt.profileGetNextValue = std::bind(&TestClient::profileGetNextValue, this, _1, _2, _3); - - m_test_services = m_smt.getServiceMethodTable(); - - ASSERT_SUCCESS(sai_api_initialize(0, &m_test_services)); - - sai_switch_api_t* switch_api; - - ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api)); - - sai_attribute_t attr; - - // connect to existing switch - attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; - attr.value.booldata = false; - - sai_object_id_t switch_id = SAI_NULL_OBJECT_ID; - - ASSERT_SUCCESS(switch_api->create_switch(&switch_id, 1, &attr)); - - ASSERT_TRUE(switch_id != SAI_NULL_OBJECT_ID); - - SWSS_LOG_NOTICE("switchId: %s", sai_serialize_object_id(switch_id).c_str()); - - sai_fdb_api_t* fdb_api; - - ASSERT_SUCCESS(sai_api_query(SAI_API_FDB, (void**)&fdb_api)); - - ASSERT_SUCCESS(fdb_api->flush_fdb_entries(switch_id, 0, NULL)); - - ASSERT_SUCCESS(sai_api_uninitialize()); -} - -void TestClient::test_stats() -{ - SWSS_LOG_ENTER(); - - m_profileMap.clear(); - - m_profileMap[SAI_REDIS_KEY_ENABLE_CLIENT] = "true"; // act as a client - - m_profileIter = m_profileMap.begin(); - - m_smt.profileGetValue = std::bind(&TestClient::profileGetValue, this, _1, _2); - m_smt.profileGetNextValue = std::bind(&TestClient::profileGetNextValue, this, _1, _2, _3); - - m_test_services = m_smt.getServiceMethodTable(); - - ASSERT_SUCCESS(sai_api_initialize(0, &m_test_services)); - - sai_switch_api_t* switch_api; - - ASSERT_SUCCESS(sai_api_query(SAI_API_SWITCH, (void**)&switch_api)); - - sai_attribute_t attr; - - // connect to existing switch - attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; - attr.value.booldata = false; - - sai_object_id_t switch_id = SAI_NULL_OBJECT_ID; - - ASSERT_SUCCESS(switch_api->create_switch(&switch_id, 1, &attr)); - - ASSERT_TRUE(switch_id != SAI_NULL_OBJECT_ID); - - SWSS_LOG_NOTICE("switchId: %s", sai_serialize_object_id(switch_id).c_str()); - - uint64_t counters[1]; - sai_stat_id_t counter_ids[1] = { SAI_SWITCH_STAT_ECC_DROP }; - - SWSS_LOG_NOTICE(" * get_switch_stats"); - - ASSERT_SUCCESS(switch_api->get_switch_stats(switch_id, 1, counter_ids, counters)); - - SWSS_LOG_NOTICE(" * clear_switch_stats"); - - ASSERT_SUCCESS(switch_api->clear_switch_stats(switch_id, 1, counter_ids)); - - ASSERT_SUCCESS(sai_api_uninitialize()); -} +#include "TestClient.h" int main() { @@ -518,6 +10,8 @@ int main() TestClient tc; + tc.test_create_switch(); + tc.test_create_vlan(); tc.test_bulk_create_vlan(); diff --git a/tests/utils.pm b/tests/utils.pm index 23cd72d20..489e5bb5a 100644 --- a/tests/utils.pm +++ b/tests/utils.pm @@ -51,6 +51,12 @@ sub start_syncd `./vssyncd -SUu -p "$DIR/vsprofile.ini" @_ >/dev/null 2>/dev/null &`; } +sub start_syncd_bulk +{ + print color('bright_blue') . "Starting syncd bulk" . color('reset') . "\n"; + `./vssyncd -SUul -p "$DIR/vsprofile.ini" @_ >/dev/null 2>/dev/null &`; +} + sub start_syncd_warm { print color('bright_blue') . "Starting syncd warm" . color('reset') . "\n"; @@ -163,6 +169,19 @@ sub fresh_start start_syncd @_; } +sub fresh_start_bulk +{ + my $caller = GetCaller(); + + `rm -f applyview.log`; + + print "$caller: " . color('bright_blue') . "Fresh start with bulk" . color('reset') . "\n"; + + kill_syncd; + flush_redis; + start_syncd_bulk @_; +} + sub sync_fresh_start { my $caller = GetCaller(); @@ -181,7 +200,7 @@ BEGIN { our @ISA = qw(Exporter); our @EXPORT = qw/ color - kill_syncd flush_redis start_syncd play fresh_start start_syncd_warm request_warm_shutdown + kill_syncd flush_redis start_syncd play fresh_start fresh_start_bulk start_syncd_warm request_warm_shutdown sync_start_syncd sync_fresh_start sync_start_syncd_warm sync_start_syncd sync_play /; diff --git a/unittest/lib/Makefile.am b/unittest/lib/Makefile.am index 9d385f2dc..11384eee0 100644 --- a/unittest/lib/Makefile.am +++ b/unittest/lib/Makefile.am @@ -34,6 +34,15 @@ testslibsairedis_SOURCES = main_libsairedis.cpp \ test_sai_redis_bridge.cpp \ test_sai_redis_buffer.cpp \ test_sai_redis_counter.cpp \ + test_sai_redis_dash_vip.cpp \ + test_sai_redis_dash_pa_validation.cpp \ + test_sai_redis_dash_vnet.cpp \ + test_sai_redis_dash_outbound_routing.cpp \ + test_sai_redis_dash_outbound_ca_to_pa.cpp \ + test_sai_redis_dash_inbound_routing.cpp \ + test_sai_redis_dash_eni.cpp \ + test_sai_redis_dash_direction_lookup.cpp \ + test_sai_redis_dash_acl.cpp \ test_sai_redis_debug_counter.cpp \ test_sai_redis_dtel.cpp \ test_sai_redis_fdb.cpp \ @@ -74,7 +83,9 @@ testslibsairedis_SOURCES = main_libsairedis.cpp \ test_sai_redis_virtual_router.cpp \ test_sai_redis_vlan.cpp \ test_sai_redis_hostif.cpp \ - test_sai_redis_wred.cpp + test_sai_redis_wred.cpp \ + test_sai_redis_ars.cpp \ + test_sai_redis_ars_profile.cpp testslibsairedis_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) testslibsairedis_LDADD = $(LDADD_GTEST) -L$(top_srcdir)/lib/.libs -lsairedis -lhiredis -lswsscommon -lpthread -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) diff --git a/unittest/lib/TestClientServerSai.cpp b/unittest/lib/TestClientServerSai.cpp index 52dac2499..67894f7c2 100644 --- a/unittest/lib/TestClientServerSai.cpp +++ b/unittest/lib/TestClientServerSai.cpp @@ -176,7 +176,7 @@ TEST(ClientServerSai, bulkGetClearStats) TEST(ClientServerSai, OT) \ { \ auto css = std::make_shared(); \ - sai_ ## ot ## _t e; \ + sai_ ## ot ## _t e = {}; \ EXPECT_EQ(SAI_STATUS_SUCCESS, css->initialize(0, &test_services)); \ EXPECT_NE(SAI_STATUS_SUCCESS, css->create(&e, 0, nullptr)); \ EXPECT_NE(SAI_STATUS_SUCCESS, css->set(&e, nullptr)); \ @@ -197,7 +197,7 @@ SAIREDIS_DECLARE_EVERY_ENTRY(TEST_ENTRY) TEST(ClientServerSai, bulk_ ## OT) \ { \ auto css = std::make_shared(); \ - sai_ ## ot ## _t e[2]; \ + sai_ ## ot ## _t e[2] = {}; \ EXPECT_EQ(SAI_STATUS_SUCCESS, css->initialize(0, &test_services)); \ EXPECT_NE(SAI_STATUS_SUCCESS, css->bulkCreate(0, e, nullptr, nullptr, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); \ EXPECT_NE(SAI_STATUS_SUCCESS, css->bulkSet(2, e, nullptr, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, nullptr)); \ diff --git a/unittest/lib/test_sai_redis_ars.cpp b/unittest/lib/test_sai_redis_ars.cpp new file mode 100644 index 000000000..79befdb48 --- /dev/null +++ b/unittest/lib/test_sai_redis_ars.cpp @@ -0,0 +1,23 @@ +#include + +extern "C" { +#include "sai.h" +} + +#include "swss/logger.h" + +TEST(libsairedis, ars) +{ + sai_ars_api_t *api = nullptr; + + sai_api_query(SAI_API_ARS, (void**)&api); + + EXPECT_NE(api, nullptr); + + sai_object_id_t id; + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_ars(&id,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_ars(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_ars_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_ars_attribute(0,0,0)); +} diff --git a/unittest/lib/test_sai_redis_ars_profile.cpp b/unittest/lib/test_sai_redis_ars_profile.cpp new file mode 100644 index 000000000..3cb586d12 --- /dev/null +++ b/unittest/lib/test_sai_redis_ars_profile.cpp @@ -0,0 +1,23 @@ +#include + +extern "C" { +#include "sai.h" +} + +#include "swss/logger.h" + +TEST(libsairedis, ars_profile) +{ + sai_ars_profile_api_t *api = nullptr; + + sai_api_query(SAI_API_ARS_PROFILE, (void**)&api); + + EXPECT_NE(api, nullptr); + + sai_object_id_t id; + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_ars_profile(&id,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_ars_profile(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_ars_profile_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_ars_profile_attribute(0,0,0)); +} diff --git a/unittest/lib/test_sai_redis_dash_acl.cpp b/unittest/lib/test_sai_redis_dash_acl.cpp new file mode 100644 index 000000000..f54435572 --- /dev/null +++ b/unittest/lib/test_sai_redis_dash_acl.cpp @@ -0,0 +1,33 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsairedis, dash_acl) +{ + sai_dash_acl_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_ACL, (void**)&api); + + EXPECT_NE(api, nullptr); + + sai_object_id_t id; + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_dash_acl_group(&id,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_dash_acl_group(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_dash_acl_group_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_dash_acl_group_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_dash_acl_groups(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_dash_acl_groups(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_dash_acl_rule(&id,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_dash_acl_rule(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_dash_acl_rule_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_dash_acl_rule_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_dash_acl_rules(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_dash_acl_rules(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/lib/test_sai_redis_dash_direction_lookup.cpp b/unittest/lib/test_sai_redis_dash_direction_lookup.cpp new file mode 100644 index 000000000..4ecd63a1b --- /dev/null +++ b/unittest/lib/test_sai_redis_dash_direction_lookup.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsairedis, dash_direction_lookup) +{ + sai_dash_direction_lookup_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_DIRECTION_LOOKUP, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_direction_lookup_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_direction_lookup_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_direction_lookup_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_direction_lookup_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_direction_lookup_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_direction_lookup_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/lib/test_sai_redis_dash_eni.cpp b/unittest/lib/test_sai_redis_dash_eni.cpp new file mode 100644 index 000000000..5949762c6 --- /dev/null +++ b/unittest/lib/test_sai_redis_dash_eni.cpp @@ -0,0 +1,33 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsairedis, dash_eni) +{ + sai_dash_eni_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_ENI, (void**)&api); + + EXPECT_NE(api, nullptr); + + sai_object_id_t id; + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_eni_ether_address_map_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_eni_ether_address_map_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_eni_ether_address_map_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_eni_ether_address_map_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_eni_ether_address_map_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_eni_ether_address_map_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_eni(&id,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_eni(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_eni_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_eni_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_enis(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_enis(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/lib/test_sai_redis_dash_inbound_routing.cpp b/unittest/lib/test_sai_redis_dash_inbound_routing.cpp new file mode 100644 index 000000000..132e014eb --- /dev/null +++ b/unittest/lib/test_sai_redis_dash_inbound_routing.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsairedis, dash_inbound_routing) +{ + sai_dash_inbound_routing_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_INBOUND_ROUTING, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_inbound_routing_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_inbound_routing_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_inbound_routing_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_inbound_routing_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_inbound_routing_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_inbound_routing_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/lib/test_sai_redis_dash_outbound_ca_to_pa.cpp b/unittest/lib/test_sai_redis_dash_outbound_ca_to_pa.cpp new file mode 100644 index 000000000..91671cce5 --- /dev/null +++ b/unittest/lib/test_sai_redis_dash_outbound_ca_to_pa.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsairedis, dash_ca_to_pa) +{ + sai_dash_outbound_ca_to_pa_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_OUTBOUND_CA_TO_PA, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_outbound_ca_to_pa_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_outbound_ca_to_pa_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_outbound_ca_to_pa_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_outbound_ca_to_pa_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_outbound_ca_to_pa_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_outbound_ca_to_pa_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/lib/test_sai_redis_dash_outbound_routing.cpp b/unittest/lib/test_sai_redis_dash_outbound_routing.cpp new file mode 100644 index 000000000..87791668d --- /dev/null +++ b/unittest/lib/test_sai_redis_dash_outbound_routing.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsairedis, dash_outbound_routing) +{ + sai_dash_outbound_routing_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_OUTBOUND_ROUTING, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_outbound_routing_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_outbound_routing_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_outbound_routing_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_outbound_routing_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_outbound_routing_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_outbound_routing_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/lib/test_sai_redis_dash_pa_validation.cpp b/unittest/lib/test_sai_redis_dash_pa_validation.cpp new file mode 100644 index 000000000..ff8ea16b3 --- /dev/null +++ b/unittest/lib/test_sai_redis_dash_pa_validation.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsairedis, dash_pa_validation) +{ + sai_dash_pa_validation_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_PA_VALIDATION, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_pa_validation_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_pa_validation_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_pa_validation_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_pa_validation_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_pa_validation_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_pa_validation_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/lib/test_sai_redis_dash_vip.cpp b/unittest/lib/test_sai_redis_dash_vip.cpp new file mode 100644 index 000000000..67337fcc6 --- /dev/null +++ b/unittest/lib/test_sai_redis_dash_vip.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsairedis, dash_vip) +{ + sai_dash_vip_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_VIP, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_vip_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_vip_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_vip_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_vip_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_vip_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_vip_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/lib/test_sai_redis_dash_vnet.cpp b/unittest/lib/test_sai_redis_dash_vnet.cpp new file mode 100644 index 000000000..61c4d694a --- /dev/null +++ b/unittest/lib/test_sai_redis_dash_vnet.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsairedis, dash_vnet) +{ + sai_dash_vnet_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_vnet(0,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_vnet(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_vnet_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_vnet_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_vnets(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_vnets(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/meta/Makefile.am b/unittest/meta/Makefile.am index 49a10f265..3b51294d3 100644 --- a/unittest/meta/Makefile.am +++ b/unittest/meta/Makefile.am @@ -41,7 +41,8 @@ tests_SOURCES = \ TestLegacyRouteEntry.cpp \ TestLegacyOther.cpp \ TestZeroMQSelectableChannel.cpp \ - TestMeta.cpp + TestMeta.cpp \ + TestMetaDash.cpp tests_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) tests_LDADD = $(LDADD_GTEST) -lhiredis -lswsscommon -lpthread -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) diff --git a/unittest/meta/TestMeta.cpp b/unittest/meta/TestMeta.cpp index 3f2c14234..63427e6c2 100644 --- a/unittest/meta/TestMeta.cpp +++ b/unittest/meta/TestMeta.cpp @@ -1699,3 +1699,107 @@ TEST(Meta, bulkGetClearStats) SAI_STATS_MODE_BULK_CLEAR, nullptr)); } + +TEST(Meta, quad_ars) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchId = 0; + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_SWITCH, &switchId, SAI_NULL_OBJECT_ID, 1, &attr)); + + sai_object_id_t ars; + + std::vector attrs; + + attr.id = SAI_ARS_ATTR_MODE; + attr.value.u32 = SAI_ARS_MODE_FLOWLET_QUALITY; + attrs.push_back(attr); + + attr.id = SAI_ARS_ATTR_IDLE_TIME; + attr.value.u32 = 100; + attrs.push_back(attr); + + attr.id = SAI_ARS_ATTR_MAX_FLOWS; + attr.value.u32 = 500; + attrs.push_back(attr); + + attr.id = SAI_ARS_ATTR_MON_ENABLE; + attr.value.booldata = true; + attrs.push_back(attr); + + attr.id = SAI_ARS_ATTR_SAMPLEPACKET_ENABLE; + attr.value.oid = SAI_NULL_OBJECT_ID; + attrs.push_back(attr); + + attr.id = SAI_ARS_ATTR_MAX_ALT_MEMEBERS_PER_GROUP; + attr.value.u32 = 15; + attrs.push_back(attr); + + attr.id = SAI_ARS_ATTR_MAX_PRIMARY_MEMEBERS_PER_GROUP; + attr.value.u32 = 14; + attrs.push_back(attr); + + attr.id = SAI_ARS_ATTR_PRIMARY_PATH_QUALITY_THRESHOLD; + attr.value.u32 = 14; + attrs.push_back(attr); + + attr.id = SAI_ARS_ATTR_ALTERNATE_PATH_COST; + attr.value.u32 = 1; + attrs.push_back(attr); + + attr.id = SAI_ARS_ATTR_ALTERNATE_PATH_BIAS; + attr.value.u32 = 1; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_ARS, &ars, switchId, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(SAI_OBJECT_TYPE_ARS, ars, (uint32_t)attrs.size(), attrs.data())); + + attr.id = SAI_ARS_ATTR_ALTERNATE_PATH_BIAS; + attr.value.u32 = 1; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(SAI_OBJECT_TYPE_ARS, ars, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(SAI_OBJECT_TYPE_ARS, ars)); +} + +TEST(Meta, quad_ars_profile) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchId = 0; + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_SWITCH, &switchId, SAI_NULL_OBJECT_ID, 1, &attr)); + + sai_object_id_t ars_profile; + + std::vector attrs; + + attr.id = SAI_ARS_PROFILE_ATTR_ALGO; + attr.value.u32 = SAI_ARS_PROFILE_ALGO_EWMA; + attrs.push_back(attr); + + attr.id = SAI_ARS_PROFILE_ATTR_SAMPLING_INTERVAL; + attr.value.u32 = 15; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_ARS_PROFILE, &ars_profile, switchId, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(SAI_OBJECT_TYPE_ARS_PROFILE, ars_profile, (uint32_t)attrs.size(), attrs.data())); + + attr.id = SAI_ARS_PROFILE_ATTR_ARS_RANDOM_SEED; + attr.value.u32 = 1; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(SAI_OBJECT_TYPE_ARS_PROFILE, ars_profile, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(SAI_OBJECT_TYPE_ARS_PROFILE, ars_profile)); +} diff --git a/unittest/meta/TestMetaDash.cpp b/unittest/meta/TestMetaDash.cpp new file mode 100644 index 000000000..2a25c1b50 --- /dev/null +++ b/unittest/meta/TestMetaDash.cpp @@ -0,0 +1,1331 @@ +#include "Meta.h" +#include "MockMeta.h" +#include "MetaTestSaiInterface.h" + +#include +#include + +#include + +#include + +using namespace saimeta; + +template +static bool compare_lists(L la, L lb) +{ + // SWSS_LOG_ENTER(); // disabled + + if (la.count != lb.count) { + return false; + } + + return std::equal(la.list, la.list + la.count, lb.list); +} + +static bool operator==(sai_ip_address_t a, sai_ip_address_t b) +{ + if (a.addr_family != b.addr_family) { + return false; + } + + switch (a.addr_family) { + case SAI_IP_ADDR_FAMILY_IPV4: + return a.addr.ip4 == b.addr.ip4; + case SAI_IP_ADDR_FAMILY_IPV6: + return memcmp(a.addr.ip6, b.addr.ip6, sizeof(a.addr.ip6)) == 0; + default: + return false; + } +} + +static bool operator==(sai_ip_prefix_t a, sai_ip_prefix_t b) +{ + if (a.addr_family != b.addr_family) { + return false; + } + + switch (a.addr_family) { + case SAI_IP_ADDR_FAMILY_IPV4: + return a.addr.ip4 == b.addr.ip4 && a.mask.ip4 == b.mask.ip4; + case SAI_IP_ADDR_FAMILY_IPV6: + return memcmp(a.addr.ip6, b.addr.ip6, sizeof(a.addr.ip6)) == 0 && + memcmp(a.mask.ip6, b.mask.ip6, sizeof(a.mask.ip6)) == 0; + default: + return false; + } +} + +static bool operator==(sai_u16_range_t a, sai_u16_range_t b) +{ + return (a.min == b.min) && (a.max == b.max); +} + +static sai_object_id_t create_switch(Meta &m) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_SWITCH, &oid, SAI_NULL_OBJECT_ID, 1, &attr)); + + return oid; +} + +static sai_object_id_t create_counter(Meta &m, sai_object_id_t switchid) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(SAI_OBJECT_TYPE_COUNTER, &oid, switchid, 0, nullptr)); + + return oid; +} + +static void remove_counter(Meta &m, sai_object_id_t counter) +{ + SWSS_LOG_ENTER(); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove((sai_object_type_t)SAI_OBJECT_TYPE_COUNTER, counter)); +} + +static sai_object_id_t create_vnet(Meta &m, sai_object_id_t switchid, uint32_t vni) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + sai_attribute_t attr; + + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = vni; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_VNET, &oid, switchid, 1, &attr)); + + return oid; +} + +static void remove_vnet(Meta &m, sai_object_id_t vnet) +{ + SWSS_LOG_ENTER(); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnet)); +} + +static sai_object_id_t create_eni(Meta &m, sai_object_id_t switchid, sai_object_id_t vnet) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + sai_attribute_t attr; + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_ENI, &oid, switchid, 1, &attr)); + + return oid; +} + +static void remove_eni(Meta &m, sai_object_id_t eni) +{ + SWSS_LOG_ENTER(); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni)); +} + +TEST(Meta, quad_dash_direction_lookup) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_attribute_t attr; + + sai_direction_lookup_entry_t entry; + + entry.switch_id = switchid; + entry.vni = 1; + + std::vector attrs; + + attr.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&entry, (uint32_t)attrs.size(), attrs.data())); + + attr.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&entry, &attr)); + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&entry, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.s32, SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&entry)); +} + +TEST(Meta, bulk_dash_direction_lookup) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 1; + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_direction_lookup_entry_t entries[entries_count] = { + { .switch_id = switchid, .vni = 10}, + { .switch_id = switchid, .vni = 20}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST(Meta, quad_dash_eni_ether_address_map_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_attribute_t attr; + + sai_object_id_t vnet = create_vnet(m, switchid, 100); + sai_object_id_t eni = create_eni(m, switchid, vnet); + + sai_eni_ether_address_map_entry_t entry = { .switch_id = switchid, .address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }}; + + std::vector attrs; + attr.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID; + attr.value.oid = eni; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&entry, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.oid, eni); + + attr.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID; + attr.value.oid = eni; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&entry, &attr)); + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&entry, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.oid, eni); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&entry)); + remove_eni(m, eni); + remove_vnet(m, vnet); +} + +TEST(Meta, bulk_dash_eni_ether_address_map_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 1; + + sai_object_id_t vnet0 = create_vnet(m, switchid, 100); + sai_object_id_t eni0 = create_eni(m, switchid, vnet0); + + sai_object_id_t vnet1 = create_vnet(m, switchid, 200); + sai_object_id_t eni1 = create_eni(m, switchid, vnet1); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID, .value = (sai_attribute_value_t){.oid = eni0}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID, .value = (sai_attribute_value_t){.oid = eni1}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_eni_ether_address_map_entry_t entries[entries_count] = { + { .switch_id = switchid, .address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }}, + { .switch_id = switchid, .address = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06 }}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + remove_eni(m, eni0); + remove_eni(m, eni1); + remove_vnet(m, vnet0); + remove_vnet(m, vnet1); +} + +TEST(Meta, quad_dash_eni) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_attribute_t attr; + + sai_ip_address_t uip4, uip6; + uip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &uip4.addr.ip4); + uip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &uip6.addr.ip6); + + sai_object_id_t vnet = create_vnet(m, switchid, 101); + + std::vector attrs; + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_ADMIN_STATE; + attr.value.booldata = true; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_VM_VNI; + attr.value.u32 = 123; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_CPS; + attr.value.u32 = 10; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_PPS; + attr.value.u32 = 20; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_FLOWS; + attr.value.u32 = 30; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP; + attr.value.ipaddr = uip4; + attrs.push_back(attr); + + sai_object_id_t eni; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_ENI, &eni, switchid, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.oid, vnet); + EXPECT_TRUE(attrs[1].value.booldata); + EXPECT_EQ(attrs[2].value.u32, 123); + EXPECT_EQ(attrs[3].value.u32, 10); + EXPECT_EQ(attrs[4].value.u32, 20); + EXPECT_EQ(attrs[5].value.u32, 30); + EXPECT_EQ(attrs[6].value.ipaddr.addr.ip4, uip4.addr.ip4); + + attr.id = SAI_ENI_ATTR_CPS; + attr.value.u32 = 10; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, &attr)); + attr.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP; + attr.value.ipaddr = uip6; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, &attr)); + + remove_eni(m, eni); + remove_vnet(m, vnet); +} + +TEST(Meta, bulk_dash_eni) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + const uint32_t enis_count = 2; + const uint32_t eni_attrs_count = 6; + + sai_object_id_t vnet0 = create_vnet(m, switchid, 101); + sai_object_id_t vnet1 = create_vnet(m, switchid, 102); + + sai_ip_address_t ipaddr0, ipaddr1; + ipaddr0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ipaddr0.addr.ip4); + + ipaddr1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.1.1", &ipaddr1.addr.ip4); + + sai_attribute_t attrs0[] = { + {.id = SAI_ENI_ATTR_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + {.id = SAI_ENI_ATTR_ADMIN_STATE, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_ENI_ATTR_VM_VNI, .value = (sai_attribute_value_t){.u32 = 123}}, + {.id = SAI_ENI_ATTR_CPS, .value = (sai_attribute_value_t){.u32 = 10}}, + {.id = SAI_ENI_ATTR_FLOWS, .value = (sai_attribute_value_t){.u32 = 20}}, + {.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = ipaddr0}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_ENI_ATTR_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + {.id = SAI_ENI_ATTR_ADMIN_STATE, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_ENI_ATTR_VM_VNI, .value = (sai_attribute_value_t){.u32 = 124}}, + {.id = SAI_ENI_ATTR_CPS, .value = (sai_attribute_value_t){.u32 = 11}}, + {.id = SAI_ENI_ATTR_FLOWS, .value = (sai_attribute_value_t){.u32 = 21}}, + {.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = ipaddr1}}, + }; + + const sai_attribute_t *attr_list[enis_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[enis_count] = {eni_attrs_count, eni_attrs_count}; + sai_object_id_t enis[enis_count] = {}; + sai_status_t statuses[enis_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_ENI, switchid, enis_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, enis, statuses)); + for (uint32_t i = 0; i < enis_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_ENI, enis_count, enis, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < enis_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + remove_vnet(m, vnet0); + remove_vnet(m, vnet1); +} + +TEST(Meta, quad_dash_eni_acl) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_attribute_t attr; + + std::vector acl_attrs = { + SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID, + }; + + std::vector attrs; + std::vector acl_groups, acl_groups_new; + for (auto at : acl_attrs) { + sai_object_id_t acl_group; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &acl_group, switchid, 0, nullptr)); + acl_groups.push_back(acl_group); + + attr.id = at; + attr.value.oid = acl_group; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &acl_group, switchid, 0, nullptr)); + acl_groups_new.push_back(acl_group); + } + + sai_object_id_t eni; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_ENI, &eni, switchid, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, (uint32_t)attrs.size(), attrs.data())); + for (size_t i = 0; i < attrs.size(); i++) { + attr.id = attrs[i].id; + attr.value.oid = acl_groups_new[i]; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, &attr)); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni)); +} + +TEST(Meta, quad_dash_vip) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_attribute_t attr; + + std::vector attrs; + + attr.id = SAI_VIP_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT; + attrs.push_back(attr); + + sai_ip_address_t vip_addr; + vip_addr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &vip_addr.addr.ip4); + + sai_vip_entry_t vip = { .switch_id = switchid, .vip = vip_addr }; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&vip, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&vip, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.s32, SAI_VIP_ENTRY_ACTION_ACCEPT); + + attr.id = SAI_ENI_ETHER_ADDRESS_MAP_ENTRY_ATTR_ENI_ID; + attr.value.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&vip, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&vip)); +} + +TEST(Meta, bulk_dash_vip) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + const uint32_t vips_count = 2; + const uint32_t vip_attrs_count = 1; + + sai_attribute_t attrs0[] = { + {.id = SAI_VIP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_VIP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT}}, + }; + + const sai_attribute_t *attr_list[vips_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[vips_count] = {vip_attrs_count, vip_attrs_count}; + sai_status_t statuses[vips_count] = {}; + + sai_ip_address_t vip_addr0, vip_addr1; + vip_addr0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &vip_addr0.addr.ip4); + vip_addr1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &vip_addr1.addr.ip6); + + sai_vip_entry_t vips[vips_count] = { + {.switch_id = switchid, .vip = vip_addr0}, + {.switch_id = switchid, .vip = vip_addr1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkCreate(vips_count, vips, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vips_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkRemove(vips_count, vips, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vips_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST(Meta, quad_dash_acl_group) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_attribute_t attr; + + std::vector attrs; + + attr.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY; + attr.value.s32 = SAI_IP_ADDR_FAMILY_IPV4; + attrs.push_back(attr); + + sai_object_id_t acl_group; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &acl_group, switchid, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, acl_group, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.s32, SAI_IP_ADDR_FAMILY_IPV4); + + attr.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY; + attr.value.s32 = SAI_IP_ADDR_FAMILY_IPV6; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, acl_group, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, acl_group)); +} + +TEST(Meta, bulk_dash_acl_group) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + const uint32_t acls_count = 2; + const uint32_t acl_attrs_count = 1; + + sai_attribute_t attrs0[acl_attrs_count] = { + {.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY, .value = (sai_attribute_value_t){.s32 = SAI_IP_ADDR_FAMILY_IPV4}}, + }; + + sai_attribute_t attrs1[acl_attrs_count] = { + {.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY, .value = (sai_attribute_value_t){.s32 = SAI_IP_ADDR_FAMILY_IPV6}}, + }; + + const sai_attribute_t *attr_list[acls_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[acls_count] = {acl_attrs_count, acl_attrs_count}; + sai_object_id_t acls[acls_count]; + sai_status_t statuses[acls_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, switchid, acls_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, acls, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, acls_count, acls, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST(Meta, quad_dash_acl_rule) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_attribute_t attr; + + sai_object_id_t group; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &group, switchid, 0, nullptr)); + + sai_object_id_t counter = create_counter(m, switchid); + + sai_ip_prefix_t ip_addr_list[2] = {}; + + ip_addr_list[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ip_addr_list[0].addr.ip4); + inet_pton(AF_INET, "255.255.0.0", &ip_addr_list[0].mask.ip4); + ip_addr_list[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &ip_addr_list[1].addr.ip6); + inet_pton(AF_INET6, "ffff:fff0::", &ip_addr_list[1].mask.ip6); + sai_ip_prefix_list_t ip_prefix_list0 = {.count = 2, .list = ip_addr_list}; + sai_ip_prefix_list_t ip_prefix_list1 = {.count = 1, .list = ip_addr_list}; + + uint8_t protos[2] = {0xAA, 0xBB}; + sai_u8_list_t protos_list = {.count=2, .list = protos}; + + sai_u16_range_t port_ranges[2] = {{.min = 10, .max = 20}, {.min = 30, .max = 40}}; + sai_u16_range_list_t port_ranges_list0 = {.count=2, .list = port_ranges}; + sai_u16_range_list_t port_ranges_list1 = {.count=1, .list = port_ranges}; + + std::vector attrs; + + attr.id = SAI_DASH_ACL_RULE_ATTR_ACTION; + attr.value.s32 = SAI_DASH_ACL_RULE_ACTION_PERMIT; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID; + attr.value.oid = group; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DIP; + attr.value.ipprefixlist = ip_prefix_list0; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_SIP; + attr.value.ipprefixlist = ip_prefix_list1; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL; + attr.value.u8list = protos_list; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT; + attr.value.u16rangelist = port_ranges_list0; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT; + attr.value.u16rangelist = port_ranges_list1; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY; + attr.value.u32 = 1; + attrs.push_back(attr); + + sai_object_id_t acl; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, &acl, switchid, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, acl, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.s32, SAI_DASH_ACL_RULE_ACTION_PERMIT); + EXPECT_EQ(attrs[1].value.oid, group); + ASSERT_TRUE(compare_lists(attrs[2].value.ipprefixlist, ip_prefix_list0)); + ASSERT_TRUE(compare_lists(attrs[3].value.ipprefixlist, ip_prefix_list1)); + ASSERT_TRUE(compare_lists(attrs[4].value.u8list, protos_list)); + ASSERT_TRUE(compare_lists(attrs[5].value.u16rangelist, port_ranges_list0)); + ASSERT_TRUE(compare_lists(attrs[6].value.u16rangelist, port_ranges_list1)); + EXPECT_EQ(attrs[7].value.oid, counter); + EXPECT_EQ(attrs[8].value.u32, 1); + + attr.id = SAI_DASH_ACL_RULE_ATTR_ACTION; + attr.value.s32 = SAI_DASH_ACL_RULE_ACTION_DENY_AND_CONTINUE; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, acl, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, acl)); + remove_counter(m, counter); + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, group)); +} + +TEST(Meta, bulk_dash_acl_rule) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + const uint32_t acls_count = 2; + const uint32_t acl_attrs_count = 9; + + sai_object_id_t counter0 = create_counter(m, switchid); + sai_object_id_t counter1 = create_counter(m, switchid); + + sai_object_id_t group0; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &group0, switchid, 0, nullptr)); + + sai_object_id_t group1; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &group1, switchid, 0, nullptr)); + + sai_ip_prefix_t ip_prefix_arr0[2] = {}; + ip_prefix_arr0[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ip_prefix_arr0[0].addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &ip_prefix_arr0[0].mask.ip4); + ip_prefix_arr0[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &ip_prefix_arr0[1].addr.ip6); + inet_pton(AF_INET6, "ffff::", &ip_prefix_arr0[1].mask.ip6); + + sai_ip_prefix_t ip_prefix_arr1[2] = {}; + ip_prefix_arr1[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.2", &ip_prefix_arr1[0].addr.ip4); + inet_pton(AF_INET, "255.255.0.0", &ip_prefix_arr1[0].mask.ip4); + ip_prefix_arr1[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:fffe", &ip_prefix_arr1[1].addr.ip6); + inet_pton(AF_INET6, "ffff::", &ip_prefix_arr1[1].mask.ip6); + + sai_ip_prefix_list_t ip_prefix_list0 = {.count = 1, .list = ip_prefix_arr0}; + sai_ip_prefix_list_t ip_prefix_list1 = {.count = 1, .list = ip_prefix_arr1}; + + uint8_t protos0[2] = {0xAA, 0xBB}; + uint8_t protos1[2] = {0xCC, 0xDD}; + sai_u8_list_t protos_list0 = {.count=2, .list = protos0}; + sai_u8_list_t protos_list1 = {.count=2, .list = protos1}; + + sai_u16_range_t port_ranges0[2] = {{.min = 10, .max = 20}, {.min = 30, .max = 40}}; + sai_u16_range_t port_ranges1[2] = {{.min = 50, .max = 60}, {.min = 70, .max = 80}}; + sai_u16_range_list_t u16_range_list0 = {.count=2, .list = port_ranges0}; + sai_u16_range_list_t u16_range_list1 = {.count=2, .list = port_ranges1}; + + sai_attribute_t attrs0[acl_attrs_count] = { + {.id = SAI_DASH_ACL_RULE_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DASH_ACL_RULE_ACTION_PERMIT_AND_CONTINUE}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID, .value = (sai_attribute_value_t){.oid = group0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL, .value = (sai_attribute_value_t){.u8list = protos_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY, .value = (sai_attribute_value_t){.u32 = 1}}, + }; + + sai_attribute_t attrs1[acl_attrs_count] = { + {.id = SAI_DASH_ACL_RULE_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DASH_ACL_RULE_ACTION_DENY}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID, .value = (sai_attribute_value_t){.oid = group1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL, .value = (sai_attribute_value_t){.u8list = protos_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY, .value = (sai_attribute_value_t){.u32 = 2}}, + }; + + const sai_attribute_t *attr_list[acls_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[acls_count] = {acl_attrs_count, acl_attrs_count}; + sai_object_id_t acls[acls_count]; + sai_status_t statuses[acls_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, switchid, acls_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, acls, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, acls_count, acls, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, group0)); + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, group1)); + remove_counter(m, counter0); + remove_counter(m, counter1); +} + +TEST(Meta, quad_dash_vnet) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_attribute_t attr; + + sai_object_id_t vnet; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 10; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create((sai_object_type_t)SAI_OBJECT_TYPE_VNET, &vnet, switchid, 1, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnet, 1, &attr)); + EXPECT_EQ(attr.value.u32, 10); + + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 20; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnet, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnet)); +} + +TEST(Meta, bulk_dash_vnet) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + const uint32_t vnets_count = 2; + const uint32_t vnet_attrs_count = 1; + + sai_attribute_t attrs0[] = { + {.id = SAI_VNET_ATTR_VNI, .value = (sai_attribute_value_t){.u32 = 10}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_VNET_ATTR_VNI, .value = (sai_attribute_value_t){.u32 = 20}}, + }; + + const sai_attribute_t *attr_list[vnets_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[vnets_count] = {vnet_attrs_count, vnet_attrs_count}; + sai_object_id_t vnets[vnets_count]; + sai_status_t statuses[vnets_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_VNET, switchid, vnets_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, vnets, statuses)); + for (uint32_t i = 0; i < vnets_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnets_count, vnets, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vnets_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST(Meta, quad_dash_inbound_routing_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_attribute_t attr; + + sai_object_id_t vnet = create_vnet(m, switchid, 10); + sai_object_id_t eni = create_eni(m, switchid, vnet); + + sai_ip_address_t sip, sip_mask; + sip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &sip.addr.ip4); + sip_mask.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.255.0", &sip_mask.addr.ip4); + + sai_inbound_routing_entry_t entry = { .switch_id = switchid, .eni_id = eni, .vni = 10, .sip = sip, .sip_mask = sip_mask, .priority = 1}; + + std::vector attrs; + attr.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE; + attrs.push_back(attr); + + attr.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&entry, (uint32_t)attrs.size(), attrs.data())); + + attr.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&entry, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&entry)); + remove_eni(m, eni); + remove_vnet(m, vnet); +} + +TEST(Meta, bulk_dash_inbound_routing_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 2; + + sai_object_id_t vnet0 = create_vnet(m, switchid, 101); + sai_object_id_t eni0 = create_eni(m, switchid, vnet0); + + sai_object_id_t vnet1 = create_vnet(m, switchid, 102); + sai_object_id_t eni1 = create_eni(m, switchid, vnet0); + + sai_ip_address_t sip0, sip_mask0; + sai_ip_address_t sip1, sip_mask1; + sip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &sip0.addr.ip4); + sip_mask0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.255.0", &sip_mask0.addr.ip4); + sip1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.2", &sip1.addr.ip4); + sip_mask1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.0.0", &sip_mask1.addr.ip4); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP}}, + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP}}, + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_inbound_routing_entry_t entries[entries_count] = { + { .switch_id = switchid, .eni_id = eni0, .vni = 10, .sip = sip0, .sip_mask = sip_mask0, .priority = 1}, + { .switch_id = switchid, .eni_id = eni1, .vni = 100, .sip = sip1, .sip_mask = sip_mask1, .priority = 2} + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + remove_eni(m, eni0); + remove_eni(m, eni1); + remove_vnet(m, vnet0); + remove_vnet(m, vnet1); +} + +TEST(Meta, quad_dash_pa_validation) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_attribute_t attr; + + sai_object_id_t vnet = create_vnet(m, switchid, 10); + + sai_pa_validation_entry_t entry; + entry.switch_id = switchid; + entry.vnet_id = vnet; + entry.sip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.3.3.3", &entry.sip.addr.ip4); + + std::vector attrs; + attr.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&entry, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.s32, SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT); + + attr.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&entry, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&entry)); + remove_vnet(m, vnet); +} + +TEST(Meta, bulk_dash_pa_validation) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 1; + + sai_object_id_t vnet0 = create_vnet(m, switchid, 10); + sai_object_id_t vnet1 = create_vnet(m, switchid, 20); + + sai_ip_address_t sip0 = {}; + sai_ip_address_t sip1 = {}; + sip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + sip1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET, "192.1.1.1", &sip0.addr.ip4); + inet_pton(AF_INET6, "ffff::", &sip1.addr.ip6); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_pa_validation_entry_t entries[entries_count] = { + { .switch_id = switchid, .vnet_id = vnet0, .sip = sip0}, + { .switch_id = switchid, .vnet_id = vnet1, .sip = sip1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + remove_vnet(m, vnet0); + remove_vnet(m, vnet1); +} + +TEST(Meta, quad_dash_outbound_routing_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_attribute_t attr; + + sai_object_id_t counter = create_counter(m, switchid); + sai_object_id_t vnet = create_vnet(m, switchid, 101); + sai_object_id_t eni = create_eni(m, switchid, vnet); + + sai_ip_address_t oip6; + oip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "ffff::", &oip6.addr); + + sai_outbound_routing_entry_t entry0; + entry0.switch_id = switchid; + entry0.eni_id = eni; + entry0.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.1.0", &entry0.destination.addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &entry0.destination.mask.ip4); + + std::vector attrs; + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.u32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP; + attr.value.ipaddr = oip6; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&entry0, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&entry0, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.u32, SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET); + EXPECT_EQ(attrs[1].value.oid, vnet); + EXPECT_EQ(attrs[2].value.ipaddr, oip6); + EXPECT_EQ(attrs[3].value.oid, counter); + + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.u32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_DIRECT; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&entry0, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&entry0)); + + remove_eni(m, eni); + remove_vnet(m, vnet); + remove_counter(m, counter); +} + +TEST(Meta, bulk_dash_outbound_routing_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 4; + + sai_object_id_t counter0 = create_counter(m, switchid); + sai_object_id_t counter1 = create_counter(m, switchid); + + sai_ip_address_t oip4, oip6; + oip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "1.2.3.4", &oip4.addr); + oip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "ffff::", &oip6.addr); + + sai_object_id_t vnet0 = create_vnet(m, switchid, 101); + sai_object_id_t vnet1 = create_vnet(m, switchid, 102); + sai_object_id_t eni0 = create_eni(m, switchid, vnet0); + sai_object_id_t eni1 = create_eni(m, switchid, vnet1); + + sai_ip_prefix_t dst0 = {}; + sai_ip_prefix_t dst1 = {}; + dst0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + dst1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET, "192.1.1.1", &dst0.addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &dst0.mask.ip4); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe0", &dst1.addr.ip6); + inet_pton(AF_INET6, "ffff:ffff::", &dst1.mask.ip6); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP, .value = (sai_attribute_value_t){.ipaddr = oip4}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP, .value = (sai_attribute_value_t){.ipaddr = oip6}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_outbound_routing_entry_t entries[entries_count] = { + { .switch_id = switchid, .eni_id = eni0, .destination = dst0}, + { .switch_id = switchid, .eni_id = eni1, .destination = dst1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + remove_eni(m, eni0); + remove_eni(m, eni1); + remove_vnet(m, vnet0); + remove_vnet(m, vnet1); + remove_counter(m, counter0); + remove_counter(m, counter1); +} + +TEST(Meta, quad_dash_outbound_ca_to_pa_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + sai_object_id_t counter = create_counter(m, switchid); + + sai_ip_address_t uip4; + uip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &uip4.addr.ip4); + + sai_object_id_t vnet = create_vnet(m, switchid, 10); + + sai_outbound_ca_to_pa_entry_t entry; + entry.switch_id = switchid; + entry.dst_vnet_id = vnet; + entry.dip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &entry.dip.addr.ip4); + + sai_attribute_t attr; + std::vector attrs; + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP; + attr.value.ipaddr = uip4; + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC; + sai_mac_t dmac = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + memcpy(attr.value.mac, dmac, 6); + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI; + attr.value.booldata = true; + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.get(&entry, (uint32_t)attrs.size(), attrs.data())); + EXPECT_EQ(attrs[0].value.ipaddr, uip4); + EXPECT_EQ(memcmp(attrs[1].value.mac, dmac, sizeof(dmac)), 0); + EXPECT_EQ(attrs[2].value.booldata, true); + EXPECT_EQ(attrs[3].value.oid, counter); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI; + attr.value.booldata = true; + EXPECT_EQ(SAI_STATUS_SUCCESS, m.set(&entry, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.remove(&entry)); + + remove_vnet(m, vnet); + remove_counter(m, counter); +} + +TEST(Meta, bulk_dash_outbound_ca_to_pa_entry) +{ + Meta m(std::make_shared()); + + sai_object_id_t switchid = create_switch(m); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 4; + + sai_object_id_t counter0 = create_counter(m, switchid); + sai_object_id_t counter1 = create_counter(m, switchid); + + sai_object_id_t vnet0 = create_vnet(m, switchid, 10); + sai_object_id_t vnet1 = create_vnet(m, switchid, 20); + + sai_ip_address_t dip0 = {}; + sai_ip_address_t dip1 = {}; + sai_ip_address_t udip0 = {}; + sai_ip_address_t udip1 = {}; + dip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + dip1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + udip0.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + udip1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.1.1.1", &dip0.addr.ip4); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe0", &dip1.addr.ip6); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe1", &udip0.addr.ip6); + inet_pton(AF_INET, "192.1.1.2", &udip1.addr.ip4); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = udip0}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC, .value = (sai_attribute_value_t){.mac = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}} + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = udip1}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC, .value = (sai_attribute_value_t){.mac = {0x00, 0x11, 0x22, 0x33, 0x44, 0x56}}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI, .value = (sai_attribute_value_t){.booldata = false}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}} + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_outbound_ca_to_pa_entry_t entries[entries_count] = { + { .switch_id = switchid, .dst_vnet_id = vnet0, .dip = dip0}, + { .switch_id = switchid, .dst_vnet_id = vnet1, .dip = dip1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, m.bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + remove_vnet(m, vnet0); + remove_vnet(m, vnet1); + remove_counter(m, counter0); + remove_counter(m, counter1); +} diff --git a/unittest/meta/TestSaiInterface.cpp b/unittest/meta/TestSaiInterface.cpp index b657aa77e..06b1255ef 100644 --- a/unittest/meta/TestSaiInterface.cpp +++ b/unittest/meta/TestSaiInterface.cpp @@ -5,9 +5,28 @@ #include +#include "swss/logger.h" + using namespace saimeta; using namespace sairedis; +static sai_object_type_t objects_types_to_verify[] { + SAI_OBJECT_TYPE_SWITCH, + SAI_OBJECT_TYPE_FDB_ENTRY, + SAI_OBJECT_TYPE_ROUTE_ENTRY, + SAI_OBJECT_TYPE_NEIGHBOR_ENTRY, + SAI_OBJECT_TYPE_NAT_ENTRY, + SAI_OBJECT_TYPE_INSEG_ENTRY, + SAI_OBJECT_TYPE_MY_SID_ENTRY, + (sai_object_type_t)SAI_OBJECT_TYPE_DIRECTION_LOOKUP_ENTRY, + (sai_object_type_t)SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY, + (sai_object_type_t)SAI_OBJECT_TYPE_VIP_ENTRY, + (sai_object_type_t)SAI_OBJECT_TYPE_INBOUND_ROUTING_ENTRY, + (sai_object_type_t)SAI_OBJECT_TYPE_PA_VALIDATION_ENTRY, + (sai_object_type_t)SAI_OBJECT_TYPE_OUTBOUND_ROUTING_ENTRY, + (sai_object_type_t)SAI_OBJECT_TYPE_OUTBOUND_CA_TO_PA_ENTRY, +}; + TEST(SaiInterface, create) { DummySaiInterface ds; @@ -16,19 +35,11 @@ TEST(SaiInterface, create) sai_object_meta_key_t mk = { .objecttype = SAI_OBJECT_TYPE_NULL, .objectkey = { .key = { .object_id = 0 } } }; - EXPECT_EQ(SAI_STATUS_FAILURE, sai->create(mk, 0, 0, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_SWITCH; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->create(mk, 0, 0, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_FDB_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->create(mk, 0, 0, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_NAT_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->create(mk, 0, 0, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->create(mk, 0, 0, nullptr)); + for (auto ot: objects_types_to_verify) + { + mk.objecttype = ot; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->create(mk, 0, 0, nullptr)); + } mk.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; EXPECT_EQ(SAI_STATUS_FAILURE, sai->create(mk, 0, 0, nullptr)); @@ -44,17 +55,11 @@ TEST(SaiInterface, remove) EXPECT_EQ(SAI_STATUS_FAILURE, sai->remove(mk)); - mk.objecttype = SAI_OBJECT_TYPE_SWITCH; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->remove(mk)); - - mk.objecttype = SAI_OBJECT_TYPE_FDB_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->remove(mk)); - - mk.objecttype = SAI_OBJECT_TYPE_NAT_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->remove(mk)); - - mk.objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->remove(mk)); + for (auto ot: objects_types_to_verify) + { + mk.objecttype = ot; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->remove(mk)); + } mk.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; EXPECT_EQ(SAI_STATUS_FAILURE, sai->remove(mk)); @@ -70,23 +75,11 @@ TEST(SaiInterface, set) EXPECT_EQ(SAI_STATUS_FAILURE, sai->set(mk, nullptr)); - mk.objecttype = SAI_OBJECT_TYPE_SWITCH; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_FDB_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_NAT_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); + for (auto ot: objects_types_to_verify) + { + mk.objecttype = ot; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->set(mk, nullptr)); + } mk.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; EXPECT_EQ(SAI_STATUS_FAILURE, sai->set(mk, nullptr)); @@ -102,23 +95,11 @@ TEST(SaiInterface, get) EXPECT_EQ(SAI_STATUS_FAILURE, sai->get(mk, 0, nullptr)); - mk.objecttype = SAI_OBJECT_TYPE_SWITCH; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_FDB_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_NAT_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_INSEG_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_ROUTE_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); - - mk.objecttype = SAI_OBJECT_TYPE_NEIGHBOR_ENTRY; - EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); + for (auto ot: objects_types_to_verify) + { + mk.objecttype = ot; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai->get(mk, 0, nullptr)); + } mk.objecttype = SAI_OBJECT_TYPE_L2MC_ENTRY; EXPECT_EQ(SAI_STATUS_FAILURE, sai->get(mk, 0, nullptr)); diff --git a/unittest/syncd/TestVendorSai.cpp b/unittest/syncd/TestVendorSai.cpp index 2d3fc6f97..f3efbc75d 100644 --- a/unittest/syncd/TestVendorSai.cpp +++ b/unittest/syncd/TestVendorSai.cpp @@ -299,3 +299,1109 @@ TEST(VendorSai, quad_bulk_neighbor_entry) EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkRemove(2, e, SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR, statuses)); } + +static sai_object_id_t create_switch(VendorSai &sai) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create(SAI_OBJECT_TYPE_SWITCH, &oid, SAI_NULL_OBJECT_ID, 1, &attr)); + + return oid; +} + +static sai_object_id_t create_counter(VendorSai &sai, sai_object_id_t switchid) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create(SAI_OBJECT_TYPE_COUNTER, &oid, switchid, 0, nullptr)); + + return oid; +} + +static void remove_counter(VendorSai &sai, sai_object_id_t counter) +{ + SWSS_LOG_ENTER(); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove((sai_object_type_t)SAI_OBJECT_TYPE_COUNTER, counter)); +} + +static sai_object_id_t create_vnet(VendorSai &sai, sai_object_id_t switchid, uint32_t vni) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + sai_attribute_t attr; + + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = vni; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_VNET, &oid, switchid, 1, &attr)); + + return oid; +} + +static void remove_vnet(VendorSai &sai, sai_object_id_t vnet) +{ + SWSS_LOG_ENTER(); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnet)); +} + +static sai_object_id_t create_eni(VendorSai &sai, sai_object_id_t switchid, sai_object_id_t vnet) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t oid; + sai_attribute_t attr; + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_ENI, &oid, switchid, 1, &attr)); + + return oid; +} + +static void remove_eni(VendorSai &sai, sai_object_id_t eni) +{ + SWSS_LOG_ENTER(); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni)); +} + +TEST(VendorSai, quad_dash_direction_lookup) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + sai_attribute_t attr; + + sai_direction_lookup_entry_t entry; + + entry.switch_id = switchid; + entry.vni = 1; + + std::vector attrs; + + attr.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove(&entry)); +} + +TEST(VendorSai, bulk_dash_direction_lookup) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 1; + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_DIRECTION_LOOKUP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DIRECTION_LOOKUP_ENTRY_ACTION_SET_OUTBOUND_DIRECTION}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_direction_lookup_entry_t entries[entries_count] = { + { .switch_id = switchid, .vni = 10}, + { .switch_id = switchid, .vni = 20}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST(VendorSai, quad_dash_eni) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + sai_attribute_t attr; + + sai_ip_address_t uip4, uip6; + uip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &uip4.addr.ip4); + uip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &uip6.addr.ip6); + + sai_object_id_t vnet = create_vnet(sai, switchid, 101); + + std::vector attrs; + + attr.id = SAI_ENI_ATTR_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_ADMIN_STATE; + attr.value.booldata = true; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_VM_VNI; + attr.value.u32 = 123; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_CPS; + attr.value.u32 = 10; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_PPS; + attr.value.u32 = 20; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_FLOWS; + attr.value.u32 = 30; + attrs.push_back(attr); + + attr.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP; + attr.value.ipaddr = uip4; + attrs.push_back(attr); + + sai_object_id_t eni; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_ENI, &eni, switchid, (uint32_t)attrs.size(), attrs.data())); + + remove_eni(sai, eni); + remove_vnet(sai, vnet); +} + +TEST(VendorSai, bulk_dash_eni) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + const uint32_t enis_count = 2; + const uint32_t eni_attrs_count = 6; + + sai_object_id_t vnet0 = create_vnet(sai, switchid, 101); + sai_object_id_t vnet1 = create_vnet(sai, switchid, 102); + + sai_ip_address_t ipaddr0, ipaddr1; + ipaddr0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ipaddr0.addr.ip4); + + ipaddr1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.1.1", &ipaddr1.addr.ip4); + + sai_attribute_t attrs0[] = { + {.id = SAI_ENI_ATTR_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + {.id = SAI_ENI_ATTR_ADMIN_STATE, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_ENI_ATTR_VM_VNI, .value = (sai_attribute_value_t){.u32 = 123}}, + {.id = SAI_ENI_ATTR_CPS, .value = (sai_attribute_value_t){.u32 = 10}}, + {.id = SAI_ENI_ATTR_FLOWS, .value = (sai_attribute_value_t){.u32 = 20}}, + {.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = ipaddr0}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_ENI_ATTR_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + {.id = SAI_ENI_ATTR_ADMIN_STATE, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_ENI_ATTR_VM_VNI, .value = (sai_attribute_value_t){.u32 = 124}}, + {.id = SAI_ENI_ATTR_CPS, .value = (sai_attribute_value_t){.u32 = 11}}, + {.id = SAI_ENI_ATTR_FLOWS, .value = (sai_attribute_value_t){.u32 = 21}}, + {.id = SAI_ENI_ATTR_VM_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = ipaddr1}}, + }; + + const sai_attribute_t *attr_list[enis_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[enis_count] = {eni_attrs_count, eni_attrs_count}; + sai_object_id_t enis[enis_count] = {}; + sai_status_t statuses[enis_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_ENI, switchid, enis_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, enis, statuses)); + for (uint32_t i = 0; i < enis_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_ENI, enis_count, enis, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < enis_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + remove_vnet(sai, vnet0); + remove_vnet(sai, vnet1); +} + +TEST(VendorSai, quad_dash_eni_acl) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + sai_attribute_t attr; + + std::vector acl_attrs = { + SAI_ENI_ATTR_INBOUND_V4_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V4_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_INBOUND_V6_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V4_STAGE5_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE1_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE2_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE3_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE4_DASH_ACL_GROUP_ID, + SAI_ENI_ATTR_OUTBOUND_V6_STAGE5_DASH_ACL_GROUP_ID, + }; + + std::vector attrs; + std::vector acl_groups, acl_groups_new; + for (auto at : acl_attrs) { + sai_object_id_t acl_group; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &acl_group, switchid, 0, nullptr)); + acl_groups.push_back(acl_group); + + attr.id = at; + attr.value.oid = acl_group; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &acl_group, switchid, 0, nullptr)); + acl_groups_new.push_back(acl_group); + } + + sai_object_id_t eni; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_ENI, &eni, switchid, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove((sai_object_type_t)SAI_OBJECT_TYPE_ENI, eni)); +} + +TEST(VendorSai, quad_dash_vip) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + sai_attribute_t attr; + + SWSS_LOG_ENTER(); + + std::vector attrs; + + attr.id = SAI_VIP_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT; + attrs.push_back(attr); + + sai_ip_address_t vip_addr; + vip_addr.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &vip_addr.addr.ip4); + + sai_vip_entry_t vip = { .switch_id = switchid, .vip = vip_addr }; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create(&vip, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove(&vip)); +} + +TEST(VendorSai, bulk_dash_vip) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + const uint32_t vips_count = 2; + const uint32_t vip_attrs_count = 1; + + sai_attribute_t attrs0[] = { + {.id = SAI_VIP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_VIP_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_VIP_ENTRY_ACTION_ACCEPT}}, + }; + + const sai_attribute_t *attr_list[vips_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[vips_count] = {vip_attrs_count, vip_attrs_count}; + sai_status_t statuses[vips_count] = {}; + + sai_ip_address_t vip_addr0, vip_addr1; + vip_addr0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &vip_addr0.addr.ip4); + vip_addr1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &vip_addr1.addr.ip6); + + sai_vip_entry_t vips[vips_count] = { + {.switch_id = switchid, .vip = vip_addr0}, + {.switch_id = switchid, .vip = vip_addr1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkCreate(vips_count, vips, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vips_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkRemove(vips_count, vips, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vips_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST(VendorSai, quad_dash_acl_group) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + sai_attribute_t attr; + + std::vector attrs; + + attr.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY; + attr.value.s32 = SAI_IP_ADDR_FAMILY_IPV4; + attrs.push_back(attr); + + sai_object_id_t acl_group; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &acl_group, switchid, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, acl_group)); +} + +TEST(VendorSai, bulk_dash_acl_group) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + const uint32_t acls_count = 2; + const uint32_t acl_attrs_count = 1; + + sai_attribute_t attrs0[acl_attrs_count] = { + {.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY, .value = (sai_attribute_value_t){.s32 = SAI_IP_ADDR_FAMILY_IPV4}}, + }; + + sai_attribute_t attrs1[acl_attrs_count] = { + {.id = SAI_DASH_ACL_GROUP_ATTR_IP_ADDR_FAMILY, .value = (sai_attribute_value_t){.s32 = SAI_IP_ADDR_FAMILY_IPV6}}, + }; + + const sai_attribute_t *attr_list[acls_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[acls_count] = {acl_attrs_count, acl_attrs_count}; + sai_object_id_t acls[acls_count]; + sai_status_t statuses[acls_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, switchid, acls_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, acls, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, acls_count, acls, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST(VendorSai, quad_dash_acl_rule) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + sai_attribute_t attr; + + sai_object_id_t group; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &group, switchid, 0, nullptr)); + + sai_object_id_t counter = create_counter(sai, switchid); + + sai_ip_prefix_t ip_addr_list[2] = {}; + + ip_addr_list[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ip_addr_list[0].addr.ip4); + inet_pton(AF_INET, "255.255.0.0", &ip_addr_list[0].mask.ip4); + ip_addr_list[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &ip_addr_list[1].addr.ip6); + inet_pton(AF_INET6, "ffff:fff0::", &ip_addr_list[1].mask.ip6); + sai_ip_prefix_list_t ip_prefix_list0 = {.count = 2, .list = ip_addr_list}; + sai_ip_prefix_list_t ip_prefix_list1 = {.count = 1, .list = ip_addr_list}; + + uint8_t protos[2] = {0xAA, 0xBB}; + sai_u8_list_t protos_list = {.count=2, .list = protos}; + + sai_u16_range_t port_ranges[2] = {{.min = 10, .max = 20}, {.min = 30, .max = 40}}; + sai_u16_range_list_t port_ranges_list0 = {.count=2, .list = port_ranges}; + sai_u16_range_list_t port_ranges_list1 = {.count=1, .list = port_ranges}; + + std::vector attrs; + + attr.id = SAI_DASH_ACL_RULE_ATTR_ACTION; + attr.value.s32 = SAI_DASH_ACL_RULE_ACTION_PERMIT; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID; + attr.value.oid = group; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DIP; + attr.value.ipprefixlist = ip_prefix_list0; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_SIP; + attr.value.ipprefixlist = ip_prefix_list1; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL; + attr.value.u8list = protos_list; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT; + attr.value.u16rangelist = port_ranges_list0; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT; + attr.value.u16rangelist = port_ranges_list1; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + + attr.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY; + attr.value.u32 = 1; + attrs.push_back(attr); + + sai_object_id_t acl; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, &acl, switchid, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, acl)); + remove_counter(sai, counter); + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, group)); +} + +TEST(VendorSai, bulk_dash_acl_rule) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + const uint32_t acls_count = 2; + const uint32_t acl_attrs_count = 9; + + sai_object_id_t counter0 = create_counter(sai, switchid); + sai_object_id_t counter1 = create_counter(sai, switchid); + + sai_object_id_t group0; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &group0, switchid, 0, nullptr)); + + sai_object_id_t group1; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, &group1, switchid, 0, nullptr)); + + sai_ip_prefix_t ip_prefix_arr0[2] = {}; + ip_prefix_arr0[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &ip_prefix_arr0[0].addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &ip_prefix_arr0[0].mask.ip4); + ip_prefix_arr0[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:ffff", &ip_prefix_arr0[1].addr.ip6); + inet_pton(AF_INET6, "ffff::", &ip_prefix_arr0[1].mask.ip6); + + sai_ip_prefix_t ip_prefix_arr1[2] = {}; + ip_prefix_arr1[0].addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.2", &ip_prefix_arr1[0].addr.ip4); + inet_pton(AF_INET, "255.255.0.0", &ip_prefix_arr1[0].mask.ip4); + ip_prefix_arr1[1].addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "100::ffff:ffff:ffff:fffe", &ip_prefix_arr1[1].addr.ip6); + inet_pton(AF_INET6, "ffff::", &ip_prefix_arr1[1].mask.ip6); + + sai_ip_prefix_list_t ip_prefix_list0 = {.count = 1, .list = ip_prefix_arr0}; + sai_ip_prefix_list_t ip_prefix_list1 = {.count = 1, .list = ip_prefix_arr1}; + + uint8_t protos0[2] = {0xAA, 0xBB}; + uint8_t protos1[2] = {0xCC, 0xDD}; + sai_u8_list_t protos_list0 = {.count=2, .list = protos0}; + sai_u8_list_t protos_list1 = {.count=2, .list = protos1}; + + sai_u16_range_t port_ranges0[2] = {{.min = 10, .max = 20}, {.min = 30, .max = 40}}; + sai_u16_range_t port_ranges1[2] = {{.min = 50, .max = 60}, {.min = 70, .max = 80}}; + sai_u16_range_list_t u16_range_list0 = {.count=2, .list = port_ranges0}; + sai_u16_range_list_t u16_range_list1 = {.count=2, .list = port_ranges1}; + + sai_attribute_t attrs0[acl_attrs_count] = { + {.id = SAI_DASH_ACL_RULE_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DASH_ACL_RULE_ACTION_PERMIT_AND_CONTINUE}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID, .value = (sai_attribute_value_t){.oid = group0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL, .value = (sai_attribute_value_t){.u8list = protos_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY, .value = (sai_attribute_value_t){.u32 = 1}}, + }; + + sai_attribute_t attrs1[acl_attrs_count] = { + {.id = SAI_DASH_ACL_RULE_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_DASH_ACL_RULE_ACTION_DENY}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DASH_ACL_GROUP_ID, .value = (sai_attribute_value_t){.oid = group1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SIP, .value = (sai_attribute_value_t){.ipprefixlist = ip_prefix_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PROTOCOL, .value = (sai_attribute_value_t){.u8list = protos_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_SRC_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_DST_PORT, .value = (sai_attribute_value_t){.u16rangelist = u16_range_list0}}, + {.id = SAI_DASH_ACL_RULE_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}}, + {.id = SAI_DASH_ACL_RULE_ATTR_PRIORITY, .value = (sai_attribute_value_t){.u32 = 2}}, + }; + + const sai_attribute_t *attr_list[acls_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[acls_count] = {acl_attrs_count, acl_attrs_count}; + sai_object_id_t acls[acls_count]; + sai_status_t statuses[acls_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, switchid, acls_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, acls, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_RULE, acls_count, acls, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < acls_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, group0)); + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove((sai_object_type_t)SAI_OBJECT_TYPE_DASH_ACL_GROUP, group1)); + remove_counter(sai, counter0); + remove_counter(sai, counter1); +} + +TEST(VendorSai, quad_dash_vnet) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + sai_attribute_t attr; + + sai_object_id_t vnet; + attr.id = SAI_VNET_ATTR_VNI; + attr.value.u32 = 10; + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create((sai_object_type_t)SAI_OBJECT_TYPE_VNET, &vnet, switchid, 1, &attr)); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnet)); +} + +TEST(VendorSai, bulk_dash_vnet) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + const uint32_t vnets_count = 2; + const uint32_t vnet_attrs_count = 1; + + sai_attribute_t attrs0[] = { + {.id = SAI_VNET_ATTR_VNI, .value = (sai_attribute_value_t){.u32 = 10}}, + }; + + sai_attribute_t attrs1[] = { + {.id = SAI_VNET_ATTR_VNI, .value = (sai_attribute_value_t){.u32 = 20}}, + }; + + const sai_attribute_t *attr_list[vnets_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[vnets_count] = {vnet_attrs_count, vnet_attrs_count}; + sai_object_id_t vnets[vnets_count]; + sai_status_t statuses[vnets_count] = {}; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkCreate((sai_object_type_t)SAI_OBJECT_TYPE_VNET, switchid, vnets_count, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, vnets, statuses)); + for (uint32_t i = 0; i < vnets_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkRemove((sai_object_type_t)SAI_OBJECT_TYPE_VNET, vnets_count, vnets, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < vnets_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } +} + +TEST(VendorSai, quad_dash_inbound_routing_entry) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + sai_attribute_t attr; + + sai_object_id_t vnet = create_vnet(sai, switchid, 10); + sai_object_id_t eni = create_eni(sai, switchid, vnet); + + sai_ip_address_t sip, sip_mask; + sip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &sip.addr.ip4); + sip_mask.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.255.0", &sip_mask.addr.ip4); + + sai_inbound_routing_entry_t entry = { .switch_id = switchid, .eni_id = eni, .vni = 10, .sip = sip, .sip_mask = sip_mask, .priority = 1}; + + std::vector attrs; + attr.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP_PA_VALIDATE; + attrs.push_back(attr); + + attr.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove(&entry)); + remove_eni(sai, eni); + remove_vnet(sai, vnet); +} + +TEST(VendorSai, bulk_dash_inbound_routing_entry) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 2; + + sai_object_id_t vnet0 = create_vnet(sai, switchid, 101); + sai_object_id_t eni0 = create_eni(sai, switchid, vnet0); + + sai_object_id_t vnet1 = create_vnet(sai, switchid, 102); + sai_object_id_t eni1 = create_eni(sai, switchid, vnet0); + + sai_ip_address_t sip0, sip_mask0; + sai_ip_address_t sip1, sip_mask1; + sip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &sip0.addr.ip4); + sip_mask0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.255.0", &sip_mask0.addr.ip4); + sip1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.2", &sip1.addr.ip4); + sip_mask1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "255.255.0.0", &sip_mask1.addr.ip4); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP}}, + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_INBOUND_ROUTING_ENTRY_ACTION_VXLAN_DECAP}}, + {.id = SAI_INBOUND_ROUTING_ENTRY_ATTR_SRC_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_inbound_routing_entry_t entries[entries_count] = { + { .switch_id = switchid, .eni_id = eni0, .vni = 10, .sip = sip0, .sip_mask = sip_mask0, .priority = 1}, + { .switch_id = switchid, .eni_id = eni1, .vni = 100, .sip = sip1, .sip_mask = sip_mask1, .priority = 2} + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + remove_eni(sai, eni0); + remove_eni(sai, eni1); + remove_vnet(sai, vnet0); + remove_vnet(sai, vnet1); +} + +TEST(VendorSai, quad_dash_pa_validation) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + sai_attribute_t attr; + + sai_object_id_t vnet = create_vnet(sai, switchid, 10); + + sai_pa_validation_entry_t entry; + entry.switch_id = switchid; + entry.vnet_id = vnet; + entry.sip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.3.3.3", &entry.sip.addr.ip4); + + std::vector attrs; + attr.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION; + attr.value.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove(&entry)); + remove_vnet(sai, vnet); +} + +TEST(VendorSai, bulk_dash_pa_validation) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 1; + + sai_object_id_t vnet0 = create_vnet(sai, switchid, 10); + sai_object_id_t vnet1 = create_vnet(sai, switchid, 20); + + sai_ip_address_t sip0 = {}; + sai_ip_address_t sip1 = {}; + sip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + sip1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET, "192.1.1.1", &sip0.addr.ip4); + inet_pton(AF_INET6, "ffff::", &sip1.addr.ip6); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_PA_VALIDATION_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_PA_VALIDATION_ENTRY_ACTION_PERMIT}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_pa_validation_entry_t entries[entries_count] = { + { .switch_id = switchid, .vnet_id = vnet0, .sip = sip0}, + { .switch_id = switchid, .vnet_id = vnet1, .sip = sip1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + remove_vnet(sai, vnet0); + remove_vnet(sai, vnet1); +} + +TEST(VendorSai, quad_dash_outbound_routing_entry) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + sai_attribute_t attr; + + sai_object_id_t counter = create_counter(sai, switchid); + sai_object_id_t vnet = create_vnet(sai, switchid, 101); + sai_object_id_t eni = create_eni(sai, switchid, vnet); + + sai_ip_address_t oip6; + oip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "ffff::", &oip6.addr); + + sai_outbound_routing_entry_t entry0; + entry0.switch_id = switchid; + entry0.eni_id = eni; + entry0.destination.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.1.0", &entry0.destination.addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &entry0.destination.mask.ip4); + + std::vector attrs; + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION; + attr.value.u32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID; + attr.value.oid = vnet; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP; + attr.value.ipaddr = oip6; + attrs.push_back(attr); + attr.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create(&entry0, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove(&entry0)); + + remove_eni(sai, eni); + remove_vnet(sai, vnet); + remove_counter(sai, counter); +} + +TEST(VendorSai, bulk_dash_outbound_routing_entry) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 4; + + sai_object_id_t counter0 = create_counter(sai, switchid); + sai_object_id_t counter1 = create_counter(sai, switchid); + + sai_ip_address_t oip4, oip6; + oip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "1.2.3.4", &oip4.addr); + oip6.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET6, "ffff::", &oip6.addr); + + sai_object_id_t vnet0 = create_vnet(sai, switchid, 101); + sai_object_id_t vnet1 = create_vnet(sai, switchid, 102); + sai_object_id_t eni0 = create_eni(sai, switchid, vnet0); + sai_object_id_t eni1 = create_eni(sai, switchid, vnet1); + + sai_ip_prefix_t dst0 = {}; + sai_ip_prefix_t dst1 = {}; + dst0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + dst1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + inet_pton(AF_INET, "192.1.1.1", &dst0.addr.ip4); + inet_pton(AF_INET, "255.255.255.0", &dst0.mask.ip4); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe0", &dst1.addr.ip6); + inet_pton(AF_INET6, "ffff:ffff::", &dst1.mask.ip6); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet0}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP, .value = (sai_attribute_value_t){.ipaddr = oip4}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}}, + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_ACTION, .value = (sai_attribute_value_t){.s32 = SAI_OUTBOUND_ROUTING_ENTRY_ACTION_ROUTE_VNET}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_DST_VNET_ID, .value = (sai_attribute_value_t){.oid = vnet1}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_OVERLAY_IP, .value = (sai_attribute_value_t){.ipaddr = oip6}}, + {.id = SAI_OUTBOUND_ROUTING_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}}, + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_outbound_routing_entry_t entries[entries_count] = { + { .switch_id = switchid, .eni_id = eni0, .destination = dst0}, + { .switch_id = switchid, .eni_id = eni1, .destination = dst1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + remove_eni(sai, eni0); + remove_eni(sai, eni1); + remove_vnet(sai, vnet0); + remove_vnet(sai, vnet1); + remove_counter(sai, counter0); + remove_counter(sai, counter1); +} + +TEST(VendorSai, quad_dash_outbound_ca_to_pa_entry) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + sai_object_id_t counter = create_counter(sai, switchid); + + sai_ip_address_t uip4; + uip4.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &uip4.addr.ip4); + + sai_object_id_t vnet = create_vnet(sai, switchid, 10); + + sai_outbound_ca_to_pa_entry_t entry; + entry.switch_id = switchid; + entry.dst_vnet_id = vnet; + entry.dip.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.168.0.1", &entry.dip.addr.ip4); + + sai_attribute_t attr; + std::vector attrs; + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP; + attr.value.ipaddr = uip4; + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC; + sai_mac_t dmac = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + memcpy(attr.value.mac, dmac, 6); + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI; + attr.value.booldata = true; + attrs.push_back(attr); + + attr.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID; + attr.value.oid = counter; + attrs.push_back(attr); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.create(&entry, (uint32_t)attrs.size(), attrs.data())); + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.remove(&entry)); + + remove_vnet(sai, vnet); + remove_counter(sai, counter); +} + +TEST(VendorSai, bulk_dash_outbound_ca_to_pa_entry) +{ + VendorSai sai; + sai.initialize(0, &test_services); + + sai_object_id_t switchid = create_switch(sai); + + const uint32_t entries_count = 2; + const uint32_t entry_attrs_count = 4; + + sai_object_id_t counter0 = create_counter(sai, switchid); + sai_object_id_t counter1 = create_counter(sai, switchid); + + sai_object_id_t vnet0 = create_vnet(sai, switchid, 10); + sai_object_id_t vnet1 = create_vnet(sai, switchid, 20); + + sai_ip_address_t dip0 = {}; + sai_ip_address_t dip1 = {}; + sai_ip_address_t udip0 = {}; + sai_ip_address_t udip1 = {}; + dip0.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + dip1.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + udip0.addr_family = SAI_IP_ADDR_FAMILY_IPV6; + udip1.addr_family = SAI_IP_ADDR_FAMILY_IPV4; + inet_pton(AF_INET, "192.1.1.1", &dip0.addr.ip4); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe0", &dip1.addr.ip6); + inet_pton(AF_INET6, "fe80::886a:feff:fe31:bfe1", &udip0.addr.ip6); + inet_pton(AF_INET, "192.1.1.2", &udip1.addr.ip4); + + sai_attribute_t attrs0[entry_attrs_count] = { + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = udip0}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC, .value = (sai_attribute_value_t){.mac = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI, .value = (sai_attribute_value_t){.booldata = true}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter0}} + }; + + sai_attribute_t attrs1[entry_attrs_count] = { + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_UNDERLAY_DIP, .value = (sai_attribute_value_t){.ipaddr = udip1}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_OVERLAY_DMAC, .value = (sai_attribute_value_t){.mac = {0x00, 0x11, 0x22, 0x33, 0x44, 0x56}}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_USE_DST_VNET_VNI, .value = (sai_attribute_value_t){.booldata = false}}, + {.id = SAI_OUTBOUND_CA_TO_PA_ENTRY_ATTR_COUNTER_ID, .value = (sai_attribute_value_t){.oid = counter1}} + }; + + const sai_attribute_t *attr_list[entries_count] = { + attrs0, + attrs1, + }; + + uint32_t attr_count[entries_count] = {entry_attrs_count, entry_attrs_count}; + sai_status_t statuses[entries_count] = {}; + + sai_outbound_ca_to_pa_entry_t entries[entries_count] = { + { .switch_id = switchid, .dst_vnet_id = vnet0, .dip = dip0}, + { .switch_id = switchid, .dst_vnet_id = vnet1, .dip = dip1}, + }; + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkCreate(entries_count, entries, attr_count, attr_list, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + EXPECT_EQ(SAI_STATUS_SUCCESS, sai.bulkRemove(entries_count, entries, SAI_BULK_OP_ERROR_MODE_STOP_ON_ERROR, statuses)); + for (uint32_t i = 0; i < entries_count; i++) { + EXPECT_EQ(SAI_STATUS_SUCCESS, statuses[i]); + } + + remove_vnet(sai, vnet0); + remove_vnet(sai, vnet1); + remove_counter(sai, counter0); + remove_counter(sai, counter1); +} diff --git a/unittest/vslib/Makefile.am b/unittest/vslib/Makefile.am index 24839c4e5..af3983260 100644 --- a/unittest/vslib/Makefile.am +++ b/unittest/vslib/Makefile.am @@ -39,6 +39,7 @@ tests_SOURCES = main.cpp \ TestSwitchContainer.cpp \ TestSwitch.cpp \ TestSwitchMLNX2700.cpp \ + TestSwitchNvdaMBF2H536C.cpp \ TestSwitchBCM56850.cpp \ TestSwitchBCM81724.cpp \ TestSwitchStateBaseMACsec.cpp \ @@ -57,6 +58,15 @@ testslibsaivs_SOURCES = main_libsaivs.cpp \ test_sai_vs_bridge.cpp \ test_sai_vs_buffer.cpp \ test_sai_vs_counter.cpp \ + test_sai_vs_dash_vip.cpp \ + test_sai_vs_dash_pa_validation.cpp \ + test_sai_vs_dash_vnet.cpp \ + test_sai_vs_dash_outbound_routing.cpp \ + test_sai_vs_dash_outbound_ca_to_pa.cpp \ + test_sai_vs_dash_inbound_routing.cpp \ + test_sai_vs_dash_eni.cpp \ + test_sai_vs_dash_direction_lookup.cpp \ + test_sai_vs_dash_acl.cpp \ test_sai_vs_debug_counter.cpp \ test_sai_vs_dtel.cpp \ test_sai_vs_fdb.cpp \ @@ -97,7 +107,9 @@ testslibsaivs_SOURCES = main_libsaivs.cpp \ test_sai_vs_virtual_router.cpp \ test_sai_vs_vlan.cpp \ test_sai_vs_hostif.cpp \ - test_sai_vs_wred.cpp + test_sai_vs_wred.cpp \ + test_sai_vs_ars.cpp \ + test_sai_vs_ars_profile.cpp testslibsaivs_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) testslibsaivs_LDADD = $(LDADD_GTEST) -L$(top_srcdir)/vslib/.libs -lsaivs -lhiredis -lswsscommon -lpthread -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta -lzmq $(CODE_COVERAGE_LIBS) diff --git a/unittest/vslib/TestSwitchNvdaMBF2H536C.cpp b/unittest/vslib/TestSwitchNvdaMBF2H536C.cpp new file mode 100644 index 000000000..7c654a218 --- /dev/null +++ b/unittest/vslib/TestSwitchNvdaMBF2H536C.cpp @@ -0,0 +1,47 @@ +#include "SwitchNvdaMBF2H536C.h" + +#include "meta/sai_serialize.h" + +#include + +#include + +using namespace saivs; + +TEST(SwitchNvdaMBF2H536C, ctr) +{ + auto sc = std::make_shared(0, ""); + auto signal = std::make_shared(); + auto eventQueue = std::make_shared(signal); + + // TODO: Should the switch type be changed when new API is available? + sc->m_saiSwitchType = SAI_SWITCH_TYPE_NPU; + sc->m_switchType = SAI_VS_SWITCH_TYPE_NVDA_MBF2H536C; + sc->m_bootType = SAI_VS_BOOT_TYPE_COLD; + sc->m_useTapDevice = false; + sc->m_laneMap = LaneMap::getDefaultLaneMap(0); + sc->m_eventQueue = eventQueue; + + auto scc = std::make_shared(); + + scc->insert(sc); + + SwitchNvdaMBF2H536C sw( + 0x2100000000, + std::make_shared(0, scc), + sc); + + SwitchNvdaMBF2H536C sw2( + 0x2100000000, + std::make_shared(0, scc), + sc, + nullptr); + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_INIT_SWITCH; + attr.value.booldata = true; + + EXPECT_EQ(sw.initialize_default_objects(1, &attr), SAI_STATUS_SUCCESS); +} + diff --git a/unittest/vslib/TestTrafficForwarder.cpp b/unittest/vslib/TestTrafficForwarder.cpp index 127209cf4..058b1c64f 100644 --- a/unittest/vslib/TestTrafficForwarder.cpp +++ b/unittest/vslib/TestTrafficForwarder.cpp @@ -16,6 +16,8 @@ typedef union _control static_assert(sizeof(cmsghdr) >= 8, "header must be at leasts 8 bytes"); static_assert(sizeof(control) >= (sizeof(cmsghdr) + sizeof(tpacket_auxdata)), "control must at least include both"); +#pragma GCC diagnostic ignored "-Wcast-align" + TEST(TrafficForwarder, addVlanTag) { uint8_t buffer[ETH_FRAME_BUFFER_SIZE]; diff --git a/unittest/vslib/test_sai_vs_ars.cpp b/unittest/vslib/test_sai_vs_ars.cpp new file mode 100644 index 000000000..6ae0d2eae --- /dev/null +++ b/unittest/vslib/test_sai_vs_ars.cpp @@ -0,0 +1,23 @@ +#include + +extern "C" { +#include "sai.h" +} + +#include "swss/logger.h" + +TEST(libsaivs, ars) +{ + sai_ars_api_t *api = nullptr; + + sai_api_query(SAI_API_ARS, (void**)&api); + + EXPECT_NE(api, nullptr); + + sai_object_id_t id; + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_ars(&id,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_ars(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_ars_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_ars_attribute(0,0,0)); +} diff --git a/unittest/vslib/test_sai_vs_ars_profile.cpp b/unittest/vslib/test_sai_vs_ars_profile.cpp new file mode 100644 index 000000000..f10e421ed --- /dev/null +++ b/unittest/vslib/test_sai_vs_ars_profile.cpp @@ -0,0 +1,23 @@ +#include + +extern "C" { +#include "sai.h" +} + +#include "swss/logger.h" + +TEST(libsaivs, ars_profile) +{ + sai_ars_profile_api_t *api = nullptr; + + sai_api_query(SAI_API_ARS_PROFILE, (void**)&api); + + EXPECT_NE(api, nullptr); + + sai_object_id_t id; + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_ars_profile(&id,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_ars_profile(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_ars_profile_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_ars_profile_attribute(0,0,0)); +} diff --git a/unittest/vslib/test_sai_vs_dash_acl.cpp b/unittest/vslib/test_sai_vs_dash_acl.cpp new file mode 100644 index 000000000..b5da844d0 --- /dev/null +++ b/unittest/vslib/test_sai_vs_dash_acl.cpp @@ -0,0 +1,33 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsaivs, dash_acl) +{ + sai_dash_acl_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_ACL, (void**)&api); + + EXPECT_NE(api, nullptr); + + sai_object_id_t id; + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_dash_acl_group(&id,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_dash_acl_group(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_dash_acl_group_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_dash_acl_group_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_dash_acl_groups(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_dash_acl_groups(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_dash_acl_rule(&id,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_dash_acl_rule(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_dash_acl_rule_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_dash_acl_rule_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_dash_acl_rules(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_dash_acl_rules(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/vslib/test_sai_vs_dash_direction_lookup.cpp b/unittest/vslib/test_sai_vs_dash_direction_lookup.cpp new file mode 100644 index 000000000..6c0735796 --- /dev/null +++ b/unittest/vslib/test_sai_vs_dash_direction_lookup.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsaivs, dash_direction_lookup) +{ + sai_dash_direction_lookup_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_DIRECTION_LOOKUP, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_direction_lookup_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_direction_lookup_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_direction_lookup_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_direction_lookup_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_direction_lookup_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_direction_lookup_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/vslib/test_sai_vs_dash_eni.cpp b/unittest/vslib/test_sai_vs_dash_eni.cpp new file mode 100644 index 000000000..c40c7d724 --- /dev/null +++ b/unittest/vslib/test_sai_vs_dash_eni.cpp @@ -0,0 +1,33 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsaivs, dash_eni) +{ + sai_dash_eni_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_ENI, (void**)&api); + + EXPECT_NE(api, nullptr); + + sai_object_id_t id; + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_eni_ether_address_map_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_eni_ether_address_map_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_eni_ether_address_map_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_eni_ether_address_map_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_eni_ether_address_map_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_eni_ether_address_map_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_eni(&id,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_eni(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_eni_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_eni_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_enis(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_enis(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/vslib/test_sai_vs_dash_inbound_routing.cpp b/unittest/vslib/test_sai_vs_dash_inbound_routing.cpp new file mode 100644 index 000000000..7e45d141c --- /dev/null +++ b/unittest/vslib/test_sai_vs_dash_inbound_routing.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsaivs, dash_inbound_routing) +{ + sai_dash_inbound_routing_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_INBOUND_ROUTING, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_inbound_routing_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_inbound_routing_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_inbound_routing_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_inbound_routing_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_inbound_routing_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_inbound_routing_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/vslib/test_sai_vs_dash_outbound_ca_to_pa.cpp b/unittest/vslib/test_sai_vs_dash_outbound_ca_to_pa.cpp new file mode 100644 index 000000000..a6778cf82 --- /dev/null +++ b/unittest/vslib/test_sai_vs_dash_outbound_ca_to_pa.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsaivs, dash_ca_to_pa) +{ + sai_dash_outbound_ca_to_pa_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_OUTBOUND_CA_TO_PA, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_outbound_ca_to_pa_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_outbound_ca_to_pa_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_outbound_ca_to_pa_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_outbound_ca_to_pa_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_outbound_ca_to_pa_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_outbound_ca_to_pa_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/vslib/test_sai_vs_dash_outbound_routing.cpp b/unittest/vslib/test_sai_vs_dash_outbound_routing.cpp new file mode 100644 index 000000000..e77838975 --- /dev/null +++ b/unittest/vslib/test_sai_vs_dash_outbound_routing.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsaivs, dash_outbound_routing) +{ + sai_dash_outbound_routing_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_OUTBOUND_ROUTING, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_outbound_routing_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_outbound_routing_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_outbound_routing_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_outbound_routing_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_outbound_routing_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_outbound_routing_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/vslib/test_sai_vs_dash_pa_validation.cpp b/unittest/vslib/test_sai_vs_dash_pa_validation.cpp new file mode 100644 index 000000000..911dda16b --- /dev/null +++ b/unittest/vslib/test_sai_vs_dash_pa_validation.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsaivs, dash_pa_validation) +{ + sai_dash_pa_validation_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_PA_VALIDATION, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_pa_validation_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_pa_validation_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_pa_validation_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_pa_validation_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_pa_validation_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_pa_validation_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/vslib/test_sai_vs_dash_vip.cpp b/unittest/vslib/test_sai_vs_dash_vip.cpp new file mode 100644 index 000000000..b6cdcc5d1 --- /dev/null +++ b/unittest/vslib/test_sai_vs_dash_vip.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsaivs, dash_vip) +{ + sai_dash_vip_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_VIP, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_vip_entry(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_vip_entry(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_vip_entry_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_vip_entry_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_vip_entries(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_vip_entries(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/unittest/vslib/test_sai_vs_dash_vnet.cpp b/unittest/vslib/test_sai_vs_dash_vnet.cpp new file mode 100644 index 000000000..b2c390db2 --- /dev/null +++ b/unittest/vslib/test_sai_vs_dash_vnet.cpp @@ -0,0 +1,24 @@ +#include + +extern "C" { +#include "sai.h" +#include "saiextensions.h" +} + +#include "swss/logger.h" + +TEST(libsaivs, dash_vnet) +{ + sai_dash_vnet_api_t *api = nullptr; + + sai_api_query((sai_api_t)SAI_API_DASH_VNET, (void**)&api); + + EXPECT_NE(api, nullptr); + + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_vnet(0,0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_vnet(0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->set_vnet_attribute(0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->get_vnet_attribute(0,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->create_vnets(0,0,0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0,0)); + EXPECT_NE(SAI_STATUS_SUCCESS, api->remove_vnets(0,0,SAI_BULK_OP_ERROR_MODE_IGNORE_ERROR,0)); +} diff --git a/vslib/Makefile.am b/vslib/Makefile.am index 2aeade3be..9c24689c9 100644 --- a/vslib/Makefile.am +++ b/vslib/Makefile.am @@ -49,6 +49,7 @@ libSaiVS_a_SOURCES = \ SwitchContainer.cpp \ Switch.cpp \ SwitchMLNX2700.cpp \ + SwitchNvdaMBF2H536C.cpp \ SwitchStateBase.cpp \ SwitchStateBaseFdb.cpp \ SwitchStateBaseHostif.cpp \ @@ -67,6 +68,15 @@ libsaivs_la_SOURCES = \ sai_vs_bridge.cpp \ sai_vs_buffer.cpp \ sai_vs_counter.cpp \ + sai_vs_dash_vip.cpp \ + sai_vs_dash_pa_validation.cpp \ + sai_vs_dash_vnet.cpp \ + sai_vs_dash_outbound_routing.cpp \ + sai_vs_dash_outbound_ca_to_pa.cpp \ + sai_vs_dash_inbound_routing.cpp \ + sai_vs_dash_eni.cpp \ + sai_vs_dash_direction_lookup.cpp \ + sai_vs_dash_acl.cpp \ sai_vs_debug_counter.cpp\ sai_vs_dtel.cpp \ sai_vs_fdb.cpp \ @@ -109,7 +119,9 @@ libsaivs_la_SOURCES = \ sai_vs_vlan.cpp \ sai_vs_wred.cpp \ sai_vs_my_mac.cpp \ - sai_vs_ipsec.cpp + sai_vs_ipsec.cpp \ + sai_vs_ars.cpp \ + sai_vs_ars_profile.cpp libSaiVS_a_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) libSaiVS_a_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS) diff --git a/vslib/SwitchConfig.cpp b/vslib/SwitchConfig.cpp index 7d45fceb3..fad8d468d 100644 --- a/vslib/SwitchConfig.cpp +++ b/vslib/SwitchConfig.cpp @@ -75,6 +75,10 @@ bool SwitchConfig::parseSwitchType( { switchType = SAI_VS_SWITCH_TYPE_MLNX2700; } + else if (st == SAI_VALUE_VS_SWITCH_TYPE_NVDA_MBF2H536C) + { + switchType = SAI_VS_SWITCH_TYPE_NVDA_MBF2H536C; + } else { SWSS_LOG_ERROR("unknown switch type: '%s', expected (%s|%s|%s|%s)", diff --git a/vslib/SwitchConfig.h b/vslib/SwitchConfig.h index 1a62524d0..8509eabf3 100644 --- a/vslib/SwitchConfig.h +++ b/vslib/SwitchConfig.h @@ -26,6 +26,8 @@ namespace saivs SAI_VS_SWITCH_TYPE_MLNX2700, + SAI_VS_SWITCH_TYPE_NVDA_MBF2H536C, + } sai_vs_switch_type_t; typedef enum _sai_vs_boot_type_t diff --git a/vslib/SwitchNvdaMBF2H536C.cpp b/vslib/SwitchNvdaMBF2H536C.cpp new file mode 100644 index 000000000..2417dfec5 --- /dev/null +++ b/vslib/SwitchNvdaMBF2H536C.cpp @@ -0,0 +1,59 @@ +#include "SwitchNvdaMBF2H536C.h" + +#include "swss/logger.h" +#include "meta/sai_serialize.h" + +using namespace saivs; + +SwitchNvdaMBF2H536C::SwitchNvdaMBF2H536C( + _In_ sai_object_id_t switch_id, + _In_ std::shared_ptr manager, + _In_ std::shared_ptr config): + SwitchStateBase(switch_id, manager, config) +{ + SWSS_LOG_ENTER(); + + // empty +} + +SwitchNvdaMBF2H536C::SwitchNvdaMBF2H536C( + _In_ sai_object_id_t switch_id, + _In_ std::shared_ptr manager, + _In_ std::shared_ptr config, + _In_ std::shared_ptr warmBootState): + SwitchStateBase(switch_id, manager, config, warmBootState) +{ + SWSS_LOG_ENTER(); + + // empty +} + +void SwitchNvdaMBF2H536C::processFdbEntriesForAging() +{ + SWSS_LOG_ENTER(); + + // empty +} + +sai_status_t SwitchNvdaMBF2H536C::initialize_default_objects( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + CHECK_STATUS(set_switch_mac_address()); + CHECK_STATUS(create_cpu_port()); + CHECK_STATUS(create_default_vlan()); + CHECK_STATUS(create_default_virtual_router()); + CHECK_STATUS(create_default_stp_instance()); + CHECK_STATUS(create_default_1q_bridge()); + CHECK_STATUS(create_default_trap_group()); + CHECK_STATUS(create_ports()); + CHECK_STATUS(set_port_list()); + CHECK_STATUS(create_bridge_ports()); + CHECK_STATUS(create_vlan_members()); + CHECK_STATUS(set_switch_default_attributes()); + CHECK_STATUS(set_static_crm_values()); + + return SAI_STATUS_SUCCESS; +} diff --git a/vslib/SwitchNvdaMBF2H536C.h b/vslib/SwitchNvdaMBF2H536C.h new file mode 100644 index 000000000..21fd56dac --- /dev/null +++ b/vslib/SwitchNvdaMBF2H536C.h @@ -0,0 +1,34 @@ +#pragma once + +#include "SwitchStateBase.h" + +namespace saivs +{ + class SwitchNvdaMBF2H536C: + public SwitchStateBase + { + public: + + SwitchNvdaMBF2H536C( + _In_ sai_object_id_t switch_id, + _In_ std::shared_ptr manager, + _In_ std::shared_ptr config); + + SwitchNvdaMBF2H536C( + _In_ sai_object_id_t switch_id, + _In_ std::shared_ptr manager, + _In_ std::shared_ptr config, + _In_ std::shared_ptr warmBootState); + + virtual ~SwitchNvdaMBF2H536C() = default; + + public: + + void processFdbEntriesForAging(); + + virtual sai_status_t initialize_default_objects( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + + }; +} diff --git a/vslib/VirtualSwitchSaiInterface.cpp b/vslib/VirtualSwitchSaiInterface.cpp index 1ac32accf..3adbb122c 100644 --- a/vslib/VirtualSwitchSaiInterface.cpp +++ b/vslib/VirtualSwitchSaiInterface.cpp @@ -14,6 +14,7 @@ #include "SwitchBCM56850.h" #include "SwitchBCM56971B0.h" #include "SwitchMLNX2700.h" +#include "SwitchNvdaMBF2H536C.h" #include @@ -577,6 +578,11 @@ std::shared_ptr VirtualSwitchSaiInterface::init_switch( break; + case SAI_VS_SWITCH_TYPE_NVDA_MBF2H536C: + + m_switchStateMap[switch_id] = std::make_shared(switch_id, m_realObjectIdManager, config, warmBootState); + break; + default: SWSS_LOG_WARN("unknown switch type: %d", config->m_switchType); diff --git a/vslib/sai_vs.h b/vslib/sai_vs.h index 37fa08269..58aea859a 100644 --- a/vslib/sai_vs.h +++ b/vslib/sai_vs.h @@ -14,12 +14,23 @@ extern "C" { #define PRIVATE __attribute__((visibility("hidden"))) PRIVATE extern const sai_acl_api_t vs_acl_api; +PRIVATE extern const sai_ars_api_t vs_ars_api; +PRIVATE extern const sai_ars_profile_api_t vs_ars_profile_api; PRIVATE extern const sai_bfd_api_t vs_bfd_api; PRIVATE extern const sai_bmtor_api_t vs_bmtor_api; PRIVATE extern const sai_generic_programmable_api_t vs_generic_programmable_api; PRIVATE extern const sai_bridge_api_t vs_bridge_api; PRIVATE extern const sai_buffer_api_t vs_buffer_api; PRIVATE extern const sai_counter_api_t vs_counter_api; +PRIVATE extern const sai_dash_vip_api_t vs_dash_vip_api; +PRIVATE extern const sai_dash_pa_validation_api_t vs_dash_pa_validation_api; +PRIVATE extern const sai_dash_vnet_api_t vs_dash_vnet_api; +PRIVATE extern const sai_dash_outbound_routing_api_t vs_dash_outbound_routing_api; +PRIVATE extern const sai_dash_outbound_ca_to_pa_api_t vs_dash_outbound_ca_to_pa_api; +PRIVATE extern const sai_dash_inbound_routing_api_t vs_dash_inbound_routing_api; +PRIVATE extern const sai_dash_eni_api_t vs_dash_eni_api; +PRIVATE extern const sai_dash_direction_lookup_api_t vs_dash_direction_lookup_api; +PRIVATE extern const sai_dash_acl_api_t vs_dash_acl_api; PRIVATE extern const sai_debug_counter_api_t vs_debug_counter_api; PRIVATE extern const sai_dtel_api_t vs_dtel_api; PRIVATE extern const sai_fdb_api_t vs_fdb_api; diff --git a/vslib/sai_vs_ars.cpp b/vslib/sai_vs_ars.cpp new file mode 100644 index 000000000..961f7a508 --- /dev/null +++ b/vslib/sai_vs_ars.cpp @@ -0,0 +1,7 @@ +#include "sai_vs.h" + +VS_GENERIC_QUAD(ARS, ars); + +const sai_ars_api_t vs_ars_api = { + VS_GENERIC_QUAD_API(ars) +}; diff --git a/vslib/sai_vs_ars_profile.cpp b/vslib/sai_vs_ars_profile.cpp new file mode 100644 index 000000000..4adf53b90 --- /dev/null +++ b/vslib/sai_vs_ars_profile.cpp @@ -0,0 +1,7 @@ +#include "sai_vs.h" + +VS_GENERIC_QUAD(ARS_PROFILE, ars_profile); + +const sai_ars_profile_api_t vs_ars_profile_api = { + VS_GENERIC_QUAD_API(ars_profile) +}; diff --git a/vslib/sai_vs_dash_acl.cpp b/vslib/sai_vs_dash_acl.cpp new file mode 100644 index 000000000..f054d1d15 --- /dev/null +++ b/vslib/sai_vs_dash_acl.cpp @@ -0,0 +1,19 @@ +#include "sai_vs.h" + +VS_GENERIC_QUAD(DASH_ACL_GROUP, dash_acl_group); +VS_BULK_CREATE(DASH_ACL_GROUP, dash_acl_groups); +VS_BULK_REMOVE(DASH_ACL_GROUP, dash_acl_groups); + +VS_GENERIC_QUAD(DASH_ACL_RULE, dash_acl_rule); +VS_BULK_CREATE(DASH_ACL_RULE, dash_acl_rules); +VS_BULK_REMOVE(DASH_ACL_RULE, dash_acl_rules); + +const sai_dash_acl_api_t vs_dash_acl_api = { + VS_GENERIC_QUAD_API(dash_acl_group) + vs_bulk_create_dash_acl_groups, + vs_bulk_remove_dash_acl_groups, + + VS_GENERIC_QUAD_API(dash_acl_rule) + vs_bulk_create_dash_acl_rules, + vs_bulk_remove_dash_acl_rules, +}; diff --git a/vslib/sai_vs_dash_direction_lookup.cpp b/vslib/sai_vs_dash_direction_lookup.cpp new file mode 100644 index 000000000..1bb96c84b --- /dev/null +++ b/vslib/sai_vs_dash_direction_lookup.cpp @@ -0,0 +1,11 @@ +#include "sai_vs.h" + +VS_GENERIC_QUAD_ENTRY(DIRECTION_LOOKUP_ENTRY, direction_lookup_entry); +VS_BULK_CREATE_ENTRY_EX(DIRECTION_LOOKUP_ENTRY, direction_lookup_entry, direction_lookup_entries); +VS_BULK_REMOVE_ENTRY_EX(DIRECTION_LOOKUP_ENTRY, direction_lookup_entry, direction_lookup_entries); + +const sai_dash_direction_lookup_api_t vs_dash_direction_lookup_api = { + VS_GENERIC_QUAD_API(direction_lookup_entry) + vs_bulk_create_direction_lookup_entries, + vs_bulk_remove_direction_lookup_entries, +}; diff --git a/vslib/sai_vs_dash_eni.cpp b/vslib/sai_vs_dash_eni.cpp new file mode 100644 index 000000000..e79dad959 --- /dev/null +++ b/vslib/sai_vs_dash_eni.cpp @@ -0,0 +1,19 @@ +#include "sai_vs.h" + +VS_GENERIC_QUAD_ENTRY(ENI_ETHER_ADDRESS_MAP_ENTRY, eni_ether_address_map_entry); +VS_BULK_CREATE_ENTRY_EX(ENI_ETHER_ADDRESS_MAP_ENTRY, eni_ether_address_map_entry, eni_ether_address_map_entries); +VS_BULK_REMOVE_ENTRY_EX(ENI_ETHER_ADDRESS_MAP_ENTRY, eni_ether_address_map_entry, eni_ether_address_map_entries); + +VS_GENERIC_QUAD(ENI, eni); +VS_BULK_CREATE(ENI, enis); +VS_BULK_REMOVE(ENI, enis); + +const sai_dash_eni_api_t vs_dash_eni_api = { + VS_GENERIC_QUAD_API(eni_ether_address_map_entry) + vs_bulk_create_eni_ether_address_map_entries, + vs_bulk_remove_eni_ether_address_map_entries, + + VS_GENERIC_QUAD_API(eni) + vs_bulk_create_enis, + vs_bulk_remove_enis, +}; diff --git a/vslib/sai_vs_dash_inbound_routing.cpp b/vslib/sai_vs_dash_inbound_routing.cpp new file mode 100644 index 000000000..a017505df --- /dev/null +++ b/vslib/sai_vs_dash_inbound_routing.cpp @@ -0,0 +1,11 @@ +#include "sai_vs.h" + +VS_GENERIC_QUAD_ENTRY(INBOUND_ROUTING_ENTRY, inbound_routing_entry); +VS_BULK_CREATE_ENTRY_EX(INBOUND_ROUTING_ENTRY, inbound_routing_entry, inbound_routing_entries); +VS_BULK_REMOVE_ENTRY_EX(INBOUND_ROUTING_ENTRY, inbound_routing_entry, inbound_routing_entries); + +const sai_dash_inbound_routing_api_t vs_dash_inbound_routing_api = { + VS_GENERIC_QUAD_API(inbound_routing_entry) + vs_bulk_create_inbound_routing_entries, + vs_bulk_remove_inbound_routing_entries, +}; diff --git a/vslib/sai_vs_dash_outbound_ca_to_pa.cpp b/vslib/sai_vs_dash_outbound_ca_to_pa.cpp new file mode 100644 index 000000000..5cac21579 --- /dev/null +++ b/vslib/sai_vs_dash_outbound_ca_to_pa.cpp @@ -0,0 +1,11 @@ +#include "sai_vs.h" + +VS_GENERIC_QUAD_ENTRY(OUTBOUND_CA_TO_PA_ENTRY, outbound_ca_to_pa_entry); +VS_BULK_CREATE_ENTRY_EX(OUTBOUND_CA_TO_PA_ENTRY, outbound_ca_to_pa_entry, outbound_ca_to_pa_entries); +VS_BULK_REMOVE_ENTRY_EX(OUTBOUND_CA_TO_PA_ENTRY, outbound_ca_to_pa_entry, outbound_ca_to_pa_entries); + +const sai_dash_outbound_ca_to_pa_api_t vs_dash_outbound_ca_to_pa_api = { + VS_GENERIC_QUAD_API(outbound_ca_to_pa_entry) + vs_bulk_create_outbound_ca_to_pa_entries, + vs_bulk_remove_outbound_ca_to_pa_entries, +}; diff --git a/vslib/sai_vs_dash_outbound_routing.cpp b/vslib/sai_vs_dash_outbound_routing.cpp new file mode 100644 index 000000000..0582dc767 --- /dev/null +++ b/vslib/sai_vs_dash_outbound_routing.cpp @@ -0,0 +1,11 @@ +#include "sai_vs.h" + +VS_GENERIC_QUAD_ENTRY(OUTBOUND_ROUTING_ENTRY, outbound_routing_entry); +VS_BULK_CREATE_ENTRY_EX(OUTBOUND_ROUTING_ENTRY, outbound_routing_entry, outbound_routing_entries); +VS_BULK_REMOVE_ENTRY_EX(OUTBOUND_ROUTING_ENTRY, outbound_routing_entry, outbound_routing_entries); + +const sai_dash_outbound_routing_api_t vs_dash_outbound_routing_api = { + VS_GENERIC_QUAD_API(outbound_routing_entry) + vs_bulk_create_outbound_routing_entries, + vs_bulk_remove_outbound_routing_entries, +}; diff --git a/vslib/sai_vs_dash_pa_validation.cpp b/vslib/sai_vs_dash_pa_validation.cpp new file mode 100644 index 000000000..1b66811f1 --- /dev/null +++ b/vslib/sai_vs_dash_pa_validation.cpp @@ -0,0 +1,11 @@ +#include "sai_vs.h" + +VS_GENERIC_QUAD_ENTRY(PA_VALIDATION_ENTRY, pa_validation_entry); +VS_BULK_CREATE_ENTRY_EX(PA_VALIDATION_ENTRY, pa_validation_entry, pa_validation_entries); +VS_BULK_REMOVE_ENTRY_EX(PA_VALIDATION_ENTRY, pa_validation_entry, pa_validation_entries); + +const sai_dash_pa_validation_api_t vs_dash_pa_validation_api = { + VS_GENERIC_QUAD_API(pa_validation_entry) + vs_bulk_create_pa_validation_entries, + vs_bulk_remove_pa_validation_entries, +}; diff --git a/vslib/sai_vs_dash_vip.cpp b/vslib/sai_vs_dash_vip.cpp new file mode 100644 index 000000000..f3d4f46b1 --- /dev/null +++ b/vslib/sai_vs_dash_vip.cpp @@ -0,0 +1,11 @@ +#include "sai_vs.h" + +VS_GENERIC_QUAD_ENTRY(VIP_ENTRY, vip_entry); +VS_BULK_CREATE_ENTRY_EX(VIP_ENTRY, vip_entry, vip_entries); +VS_BULK_REMOVE_ENTRY_EX(VIP_ENTRY, vip_entry, vip_entries); + +const sai_dash_vip_api_t vs_dash_vip_api = { + VS_GENERIC_QUAD_API(vip_entry) + vs_bulk_create_vip_entries, + vs_bulk_remove_vip_entries, +}; diff --git a/vslib/sai_vs_dash_vnet.cpp b/vslib/sai_vs_dash_vnet.cpp new file mode 100644 index 000000000..83cd9973d --- /dev/null +++ b/vslib/sai_vs_dash_vnet.cpp @@ -0,0 +1,11 @@ +#include "sai_vs.h" + +VS_GENERIC_QUAD(VNET, vnet); +VS_BULK_CREATE(VNET, vnets); +VS_BULK_REMOVE(VNET, vnets); + +const sai_dash_vnet_api_t vs_dash_vnet_api = { + VS_GENERIC_QUAD_API(vnet) + vs_bulk_create_vnets, + vs_bulk_remove_vnets, +}; diff --git a/vslib/sai_vs_interfacequery.cpp b/vslib/sai_vs_interfacequery.cpp index 5cd4e5e3f..5a7167a61 100644 --- a/vslib/sai_vs_interfacequery.cpp +++ b/vslib/sai_vs_interfacequery.cpp @@ -78,7 +78,18 @@ static sai_apis_t vs_apis = { API(my_mac), API(ipsec), API(generic_programmable), + API(ars), + API(ars_profile), API(bmtor), + API(dash_acl), + API(dash_direction_lookup), + API(dash_eni), + API(dash_inbound_routing), + API(dash_outbound_ca_to_pa), + API(dash_outbound_routing), + API(dash_vnet), + API(dash_pa_validation), + API(dash_vip), }; static_assert((sizeof(sai_apis_t)/sizeof(void*)) == (SAI_API_EXTENSIONS_MAX - 1)); diff --git a/vslib/sai_vs_srv6.cpp b/vslib/sai_vs_srv6.cpp index 4a7f55f78..8d669251f 100644 --- a/vslib/sai_vs_srv6.cpp +++ b/vslib/sai_vs_srv6.cpp @@ -15,6 +15,10 @@ const sai_srv6_api_t vs_srv6_api = { vs_bulk_create_srv6_sidlists, vs_bulk_remove_srv6_sidlists, + NULL, + NULL, + NULL, + VS_GENERIC_QUAD_API(my_sid_entry) VS_BULK_QUAD_API(my_sid_entry) }; diff --git a/vslib/saivs.h b/vslib/saivs.h index 43c223bae..ba1928a67 100644 --- a/vslib/saivs.h +++ b/vslib/saivs.h @@ -84,12 +84,13 @@ extern "C" { * Optional. Should point to GUID value which is provided in context_config.json * by SAI_KEY_VS_CONTEXT_CONFIG. Default is 0. */ -#define SAI_KEY_VS_GLOBAL_CONTEXT "SAI_VS_GLOBAL_CONTEXT" +#define SAI_KEY_VS_GLOBAL_CONTEXT "SAI_VS_GLOBAL_CONTEXT" -#define SAI_VALUE_VS_SWITCH_TYPE_BCM56850 "SAI_VS_SWITCH_TYPE_BCM56850" -#define SAI_VALUE_VS_SWITCH_TYPE_BCM56971B0 "SAI_VS_SWITCH_TYPE_BCM56971B0" -#define SAI_VALUE_VS_SWITCH_TYPE_BCM81724 "SAI_VS_SWITCH_TYPE_BCM81724" -#define SAI_VALUE_VS_SWITCH_TYPE_MLNX2700 "SAI_VS_SWITCH_TYPE_MLNX2700" +#define SAI_VALUE_VS_SWITCH_TYPE_BCM56850 "SAI_VS_SWITCH_TYPE_BCM56850" +#define SAI_VALUE_VS_SWITCH_TYPE_BCM56971B0 "SAI_VS_SWITCH_TYPE_BCM56971B0" +#define SAI_VALUE_VS_SWITCH_TYPE_BCM81724 "SAI_VS_SWITCH_TYPE_BCM81724" +#define SAI_VALUE_VS_SWITCH_TYPE_MLNX2700 "SAI_VS_SWITCH_TYPE_MLNX2700" +#define SAI_VALUE_VS_SWITCH_TYPE_NVDA_MBF2H536C "SAI_VS_SWITCH_TYPE_NVDA_MBF2H536C" /* * Values for SAI_KEY_BOOT_TYPE (defined in saiswitch.h) From b299bb45b79f5784eae9bb682061e9c1c3b89901 Mon Sep 17 00:00:00 2001 From: Xu Chen <112069142+XuChen-MSFT@users.noreply.github.com> Date: Thu, 18 May 2023 16:25:36 +0800 Subject: [PATCH 12/25] advance SAI to latest v1.12 (#1242) --- SAI | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SAI b/SAI index 3ff228a7e..92875f930 160000 --- a/SAI +++ b/SAI @@ -1 +1 @@ -Subproject commit 3ff228a7e5619a56e3c169966cb1a8631705768a +Subproject commit 92875f93094af342e0e67cf2991255f98a0a9d62 From 606703e1fcaa501591c0c39beacac4797e9d6772 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Sat, 20 May 2023 06:50:57 +0200 Subject: [PATCH 13/25] [configure] Check for minimal SAI version (#1246) * [configure] Check for minimal SAI version since commit 8e1fb37 (v1.8.0) there is check enum binary backward compatibility so we are relaxing this check below, versions do not have to be equal but both need to be at least 2ebde24 (v1.9.0), this will make sure that enums are always ok, but since that commit some data structures changed and are not binary backwad compatible like next hop group api, acl_capability, structs are backward binary compatible from commit aed34c8, which closest tag version for it is commit 3ff228a (v1.12.0), so min version check should be set to (v1.12.0), but some production branches do not use that high SAI version yet, some use even version v1.7.0 which then it is impossible to provide even enum backward compatibility, check those links: https://github.com/opencomputeproject/SAI/pull/1297 (enums) https://github.com/opencomputeproject/SAI/pull/1795 (structs) * Fix condition --- configure.ac | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 409eccfba..b95367ef5 100644 --- a/configure.ac +++ b/configure.ac @@ -192,6 +192,7 @@ AC_MSG_CHECKING([SAI headers API version and library version check]) AC_TRY_RUN([ extern "C" { #include +#include } int main() { sai_api_version_t version; @@ -199,7 +200,24 @@ int main() { { return 1; } - return (version != SAI_API_VERSION); +/* +since commit 8e1fb37 (v1.8.0) there is check enum binary backward compatibility +so we are relaxing this check below, versions do not have to be equal but both +need to be at least 2ebde24 (v1.9.0), this will make sure that enums are always +ok, but since that commit some data structures changed and are not binary +backwad compatible like next hop group api, acl_capability, structs are +backward binary compatible from commit aed34c8, which closest tag version for +it is commit 3ff228a (v1.12.0), so min version check should be set to +(v1.12.0), but some production branches do not use that high SAI version yet, +some use even version v1.7.0 which then it is impossible to provide even enum +backward compatibility, check those links: +https://github.com/opencomputeproject/SAI/pull/1297 (enums) +https://github.com/opencomputeproject/SAI/pull/1795 (structs) +*/ + sai_api_version_t minversion = SAI_VERSION(1,9,0); + printf("min SAI version: %ld, sairedis SAI headers version: %ld, vendor lib SAI query api version: %ld\n", + minversion, SAI_API_VERSION, version); + return (version < minversion) || (SAI_API_VERSION < minversion); }], [AC_MSG_RESULT(ok)], [AC_MSG_RESULT(failed) From 03e7e02358d18c0eec8b2f1b6d02fa4dd252ed1e Mon Sep 17 00:00:00 2001 From: Sudharsan Dhamal Gopalarathnam Date: Tue, 23 May 2023 00:42:49 -0700 Subject: [PATCH 14/25] [ASAN] Increasing the watchdog timeout for ASAN builds (#1239) Currently, when testing builds with ASAN on lower CPU systems, it takes sometimes for switch init to complete due to the additional overhead associated with ASAN builds. Hence we start noticing errors as below. To overcome this increasing the watchdog timeout for ASAN builds. --- syncd/Makefile.am | 1 + syncd/Syncd.cpp | 8 +++++++- tests/aspell.en.pws | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/syncd/Makefile.am b/syncd/Makefile.am index 62d5d8be0..c0d15b9eb 100644 --- a/syncd/Makefile.am +++ b/syncd/Makefile.am @@ -63,6 +63,7 @@ libSyncd_a_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVER syncd_SOURCES = main.cpp if ASAN_ENABLED syncd_SOURCES += Asan.cpp +libSyncd_a_CXXFLAGS += -DASAN_ENABLED endif syncd_CPPFLAGS = $(CODE_COVERAGE_CPPFLAGS) syncd_CXXFLAGS = $(DBGFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) $(CODE_COVERAGE_CXXFLAGS) $(CFLAGS_ASAN) diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index 1bcf85146..cd053d5ab 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -42,6 +42,12 @@ using namespace saimeta; using namespace sairediscommon; using namespace std::placeholders; +#ifdef ASAN_ENABLED +#define WD_DELAY_FACTOR 2 +#else +#define WD_DELAY_FACTOR 1 +#endif + Syncd::Syncd( _In_ std::shared_ptr vendorSai, _In_ std::shared_ptr cmd, @@ -53,7 +59,7 @@ Syncd::Syncd( m_vendorSai(vendorSai), m_veryFirstRun(false), m_enableSyncMode(false), - m_timerWatchdog(30 * 1000000) // watch for executions over 30 seconds + m_timerWatchdog(30 * 1000000 * WD_DELAY_FACTOR) // watch for executions over 30 seconds or 60 seconds if ASAN enabled { SWSS_LOG_ENTER(); diff --git a/tests/aspell.en.pws b/tests/aspell.en.pws index 8368e2430..b5cda58be 100644 --- a/tests/aspell.en.pws +++ b/tests/aspell.en.pws @@ -5,6 +5,7 @@ ACLs AES API APIs +ASAN ASIC ASICs ATTR From 38c5aa02d0cbaa24bc8b06c0736a5425ee43f117 Mon Sep 17 00:00:00 2001 From: zitingguo-ms <736034564@qq.com> Date: Fri, 26 May 2023 18:14:42 +0800 Subject: [PATCH 15/25] Remove return failure when SAI version mismatch (#1248) * remove return failure when SAI version mismatch Signed-off-by: zitingguo-ms * remove the return Signed-off-by: zitingguo-ms --------- Signed-off-by: zitingguo-ms --- syncd/VendorSai.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/syncd/VendorSai.cpp b/syncd/VendorSai.cpp index f57c8ec23..d80014ff6 100644 --- a/syncd/VendorSai.cpp +++ b/syncd/VendorSai.cpp @@ -73,10 +73,8 @@ sai_status_t VendorSai::initialize( if (version != SAI_API_VERSION) { - SWSS_LOG_ERROR("SAI implementation API version %" PRId64 " does not match SAI headers API version %" PRId64, + SWSS_LOG_NOTICE("SAI implementation API version %" PRId64 " does not match SAI headers API version %" PRId64, version, SAI_API_VERSION); - - return SAI_STATUS_FAILURE; } #endif From 7430323afde022339d21476d8138fb97f34070c3 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Mon, 29 May 2023 14:54:30 +0200 Subject: [PATCH 16/25] Revert "Remove return failure when SAI version mismatch (#1248)" (#1249) This reverts commit 38c5aa02d0cbaa24bc8b06c0736a5425ee43f117. --- syncd/VendorSai.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/syncd/VendorSai.cpp b/syncd/VendorSai.cpp index d80014ff6..f57c8ec23 100644 --- a/syncd/VendorSai.cpp +++ b/syncd/VendorSai.cpp @@ -73,8 +73,10 @@ sai_status_t VendorSai::initialize( if (version != SAI_API_VERSION) { - SWSS_LOG_NOTICE("SAI implementation API version %" PRId64 " does not match SAI headers API version %" PRId64, + SWSS_LOG_ERROR("SAI implementation API version %" PRId64 " does not match SAI headers API version %" PRId64, version, SAI_API_VERSION); + + return SAI_STATUS_FAILURE; } #endif From 959b8426e7febce41f50289dc3c18cb3ded753aa Mon Sep 17 00:00:00 2001 From: Oleksandr Ivantsiv Date: Mon, 29 May 2023 18:42:15 +0200 Subject: [PATCH 17/25] [syncd] Add the possibility to overwrite the watchdog warning time span via the command line option. (#1243) This option is useful on the slower systems where the execution of SAI call might take more than a default time span (30 seconds). The default behavior is preserved if the option is not specified. --- syncd/CommandLineOptions.cpp | 3 ++ syncd/CommandLineOptions.h | 2 + syncd/CommandLineOptionsParser.cpp | 13 +++-- syncd/Syncd.cpp | 2 +- unittest/syncd/TestCommandLineOptions.cpp | 61 ++++++++++++++++++++++- 5 files changed, 76 insertions(+), 5 deletions(-) diff --git a/syncd/CommandLineOptions.cpp b/syncd/CommandLineOptions.cpp index 43ee2c2d4..3ad68b886 100644 --- a/syncd/CommandLineOptions.cpp +++ b/syncd/CommandLineOptions.cpp @@ -34,6 +34,8 @@ CommandLineOptions::CommandLineOptions() m_breakConfig = ""; + m_watchdogWarnTimeSpan = 30 * 1000000; + #ifdef SAITHRIFT m_runRPCServer = false; @@ -63,6 +65,7 @@ std::string CommandLineOptions::getCommandLineString() const ss << " GlobalContext=" << m_globalContext; ss << " ContextConfig=" << m_contextConfig; ss << " BreakConfig=" << m_breakConfig; + ss << " WatchdogWarnTimeSpan=" << m_watchdogWarnTimeSpan; #ifdef SAITHRIFT diff --git a/syncd/CommandLineOptions.h b/syncd/CommandLineOptions.h index 8c1e245cd..26adc5ec6 100644 --- a/syncd/CommandLineOptions.h +++ b/syncd/CommandLineOptions.h @@ -84,6 +84,8 @@ namespace syncd std::string m_breakConfig; + int64_t m_watchdogWarnTimeSpan; + #ifdef SAITHRIFT bool m_runRPCServer; std::string m_portMapFile; diff --git a/syncd/CommandLineOptionsParser.cpp b/syncd/CommandLineOptionsParser.cpp index f2bb90fc8..620e5383f 100644 --- a/syncd/CommandLineOptionsParser.cpp +++ b/syncd/CommandLineOptionsParser.cpp @@ -19,9 +19,9 @@ std::shared_ptr CommandLineOptionsParser::parseCommandLine( auto options = std::make_shared(); #ifdef SAITHRIFT - const char* const optstring = "dp:t:g:x:b:uSUCsz:lrm:h"; + const char* const optstring = "dp:t:g:x:b:w:uSUCsz:lrm:h"; #else - const char* const optstring = "dp:t:g:x:b:uSUCsz:lh"; + const char* const optstring = "dp:t:g:x:b:w:uSUCsz:lh"; #endif // SAITHRIFT while (true) @@ -41,6 +41,7 @@ std::shared_ptr CommandLineOptionsParser::parseCommandLine( { "globalContext", required_argument, 0, 'g' }, { "contextContig", required_argument, 0, 'x' }, { "breakConfig", required_argument, 0, 'b' }, + { "watchdogWarnTimeSpan", optional_argument, 0, 'w' }, #ifdef SAITHRIFT { "rpcserver", no_argument, 0, 'r' }, { "portmap", required_argument, 0, 'm' }, @@ -119,6 +120,10 @@ std::shared_ptr CommandLineOptionsParser::parseCommandLine( options->m_breakConfig = std::string(optarg); break; + case 'w': + options->m_watchdogWarnTimeSpan = (int64_t)std::stoll(optarg); + break; + #ifdef SAITHRIFT case 'r': options->m_runRPCServer = true; @@ -161,7 +166,7 @@ void CommandLineOptionsParser::printUsage() std::cout << " -p --profile profile" << std::endl; std::cout << " Provide profile map file" << std::endl; std::cout << " -t --startType type" << std::endl; - std::cout << " Specify start type (cold|warm|fast|fastfast) " << std::endl; + std::cout << " Specify start type (cold|warm|fast|fastfast)" << std::endl; std::cout << " -u --useTempView" << std::endl; std::cout << " Use temporary view between init and apply" << std::endl; std::cout << " -S --disableExitSleep" << std::endl; @@ -182,6 +187,8 @@ void CommandLineOptionsParser::printUsage() std::cout << " Context configuration file" << std::endl; std::cout << " -b --breakConfig" << std::endl; std::cout << " Comparison logic 'break before make' configuration file" << std::endl; + std::cout << " -w --watchdogWarnTimeSpan" << std::endl; + std::cout << " Watchdog time span (in microseconds) to watch for execution" << std::endl; #ifdef SAITHRIFT diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index cd053d5ab..0f331d334 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -59,7 +59,7 @@ Syncd::Syncd( m_vendorSai(vendorSai), m_veryFirstRun(false), m_enableSyncMode(false), - m_timerWatchdog(30 * 1000000 * WD_DELAY_FACTOR) // watch for executions over 30 seconds or 60 seconds if ASAN enabled + m_timerWatchdog(cmd->m_watchdogWarnTimeSpan * WD_DELAY_FACTOR) { SWSS_LOG_ENTER(); diff --git a/unittest/syncd/TestCommandLineOptions.cpp b/unittest/syncd/TestCommandLineOptions.cpp index d4a2faccf..a6d04676d 100644 --- a/unittest/syncd/TestCommandLineOptions.cpp +++ b/unittest/syncd/TestCommandLineOptions.cpp @@ -1,9 +1,45 @@ #include "CommandLineOptions.h" +#include "CommandLineOptionsParser.h" #include +#include using namespace syncd; +const std::string expected_usage = +R"(Usage: syncd [-d] [-p profile] [-t type] [-u] [-S] [-U] [-C] [-s] [-z mode] [-l] [-g idx] [-x contextConfig] [-b breakConfig] [-h] + -d --diag + Enable diagnostic shell + -p --profile profile + Provide profile map file + -t --startType type + Specify start type (cold|warm|fast|fastfast) + -u --useTempView + Use temporary view between init and apply + -S --disableExitSleep + Disable sleep when syncd crashes + -U --enableUnittests + Metadata enable unittests + -C --enableConsistencyCheck + Enable consisteny check DB vs ASIC after comparison logic + -s --syncMode + Enable synchronous mode (depreacated, use -z) + -z --redisCommunicationMode + Redis communication mode (redis_async|redis_sync|zmq_sync), default: redis_async + -l --enableBulk + Enable SAI Bulk support + -g --globalContext + Global context index to load from context config file + -x --contextConfig + Context configuration file + -b --breakConfig + Comparison logic 'break before make' configuration file + -w --watchdogWarnTimeSpan + Watchdog time span (in microseconds) to watch for execution + -h --help + Print out this message +)"; + TEST(CommandLineOptions, getCommandLineString) { syncd::CommandLineOptions opt; @@ -12,7 +48,8 @@ TEST(CommandLineOptions, getCommandLineString) EXPECT_EQ(str, " EnableDiagShell=NO EnableTempView=NO DisableExitSleep=NO EnableUnittests=NO" " EnableConsistencyCheck=NO EnableSyncMode=NO RedisCommunicationMode=redis_async" - " EnableSaiBulkSuport=NO StartType=cold ProfileMapFile= GlobalContext=0 ContextConfig= BreakConfig="); + " EnableSaiBulkSuport=NO StartType=cold ProfileMapFile= GlobalContext=0 ContextConfig= BreakConfig=" + " WatchdogWarnTimeSpan=30000000"); } TEST(CommandLineOptions, startTypeStringToStartType) @@ -21,3 +58,25 @@ TEST(CommandLineOptions, startTypeStringToStartType) EXPECT_EQ(st, SAI_START_TYPE_UNKNOWN); } + +TEST(CommandLineOptionsParser, printUsage) +{ + std::stringstream buffer; + std::streambuf *sbuf = std::cout.rdbuf(); + std::cout.rdbuf(buffer.rdbuf()); + syncd::CommandLineOptionsParser::printUsage(); + std::cout.rdbuf(sbuf); + + EXPECT_EQ(expected_usage, buffer.str()); +} + +TEST(CommandLineOptionsParser, parseCommandLine) +{ + char arg1[] = "test"; + char arg2[] = "-w"; + char arg3[] = "1000"; + std::vector args = {arg1, arg2, arg3}; + + auto opt = syncd::CommandLineOptionsParser::parseCommandLine((int)args.size(), args.data()); + EXPECT_EQ(opt->m_watchdogWarnTimeSpan, 1000); +} From d24190229687c3732e86525dbbdc3e48a25de8d1 Mon Sep 17 00:00:00 2001 From: Oleksandr Ivantsiv Date: Mon, 29 May 2023 18:42:49 +0200 Subject: [PATCH 18/25] [syncd] Extend syncd start script to start SYNCD on nvidia-bluefield. (#1244) --- syncd/scripts/syncd_init_common.sh | 35 ++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/syncd/scripts/syncd_init_common.sh b/syncd/scripts/syncd_init_common.sh index 19b1d620c..214d3b125 100644 --- a/syncd/scripts/syncd_init_common.sh +++ b/syncd/scripts/syncd_init_common.sh @@ -324,6 +324,39 @@ config_syncd_innovium() mkdir -p $II_ROOT } +config_syncd_nvidia_bluefield() +{ + # Read MAC addresses + base_mac="$(echo $SYNCD_VARS | jq -r '.mac')" + eth0_mac=$(cat /sys/class/net/Ethernet0/address) + eth4_mac=$(cat /sys/class/net/Ethernet4/address) + + cp $HWSKU_DIR/sai.profile /tmp/sai.profile + + # Update sai.profile with MAC_ADDRESS + echo "DEVICE_MAC_ADDRESS=$base_mac" >> /tmp/sai.profile + echo "PORT_1_MAC_ADDRESS=$eth0_mac" >> /tmp/sai.profile + echo "PORT_2_MAC_ADDRESS=$eth4_mac" >> /tmp/sai.profile + + CMD_ARGS+=" -l -p /tmp/sai.profile -w 180000000" + + echo 4096 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages + mkdir -p /mnt/huge + mount -t hugetlbfs pagesize=1GB /mnt/huge + + devlink dev eswitch set pci/0000:03:00.0 mode legacy + devlink dev eswitch set pci/0000:03:00.1 mode legacy + devlink dev eswitch set pci/0000:03:00.0 mode switchdev + devlink dev eswitch set pci/0000:03:00.1 mode switchdev + devlink dev param set pci/0000:03:00.0 name esw_multiport value 1 cmode runtime + devlink dev param set pci/0000:03:00.1 name esw_multiport value 1 cmode runtime + + ethtool -A Ethernet0 rx off tx off + ethtool -A Ethernet4 rx off tx off + + mlnx-sf --device 0000:03:00.0 --action create --sfnum 1 --hwaddr ${base_mac} -t +} + config_syncd_xsight() { SYS_MODE="asic" @@ -400,6 +433,8 @@ config_syncd() config_syncd_innovium elif [ "$SONIC_ASIC_TYPE" == "soda" ]; then config_syncd_soda + elif [ "$SONIC_ASIC_TYPE" == "nvidia-bluefield" ]; then + config_syncd_nvidia_bluefield elif [ "$SONIC_ASIC_TYPE" == "xsight" ]; then config_syncd_xsight else From af917ac72f2b268ae988260ede41bae93c9a4164 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Mon, 29 May 2023 20:50:40 +0200 Subject: [PATCH 19/25] [syncd] Check for minimal SAI version (#1247) since commit 8e1fb37 (v1.8.0) there is check enum binary backward compatibility so we are relaxing this check below, versions do not have to be equal but both need to be at least 2ebde24 (v1.9.0), this will make sure that enums are always ok, but since that commit some data structures changed and are not binary backwad compatible like next hop group api, acl_capability, structs are backward binary compatible from commit aed34c8, which closest tag version for it is commit 3ff228a (v1.12.0), so min version check should be set to (v1.12.0), but some production branches do not use that high SAI version yet, some use even version v1.7.0 which then it is impossible to provide even enum backward compatibility --- syncd/VendorSai.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/syncd/VendorSai.cpp b/syncd/VendorSai.cpp index f57c8ec23..80ed9218b 100644 --- a/syncd/VendorSai.cpp +++ b/syncd/VendorSai.cpp @@ -69,12 +69,18 @@ sai_status_t VendorSai::initialize( return api_status; } - SWSS_LOG_NOTICE("SAI API version: %" PRId64, version); + // please refer to https://github.com/sonic-net/sonic-sairedis/pull/1246 or commit 606703e1 - if (version != SAI_API_VERSION) + sai_api_version_t minversion = SAI_VERSION(1,9,0); + + SWSS_LOG_NOTICE("SAI API vendor version: %" PRId64, version); + SWSS_LOG_NOTICE("SAI API min version: %" PRId64, minversion); + SWSS_LOG_NOTICE("SAI API headers version: %" PRId64, SAI_API_VERSION); + + if ((version < minversion) || (SAI_API_VERSION < minversion)) { - SWSS_LOG_ERROR("SAI implementation API version %" PRId64 " does not match SAI headers API version %" PRId64, - version, SAI_API_VERSION); + SWSS_LOG_ERROR("SAI implementation API version %" PRId64 " or SAI headers API version %" PRId64 " does not meet minimum version requirements, min version required: %" PRId64, + version, SAI_API_VERSION, minversion); return SAI_STATUS_FAILURE; } From d6eee42106fa1faa1ab78ee76997a0df6893652b Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Thu, 8 Jun 2023 10:12:33 +0200 Subject: [PATCH 20/25] [syncd] Add pre match logic for acl entry (#1240) this will test scenario where we have 1 acl entry with counter and after warm boot 2 acl entries and 2 counters the same which could end up matching wrong acl counter and causing fail "object exist" on broadcom acl entry set, which will require improve pre match logic for acl entry --- syncd/BestCandidateFinder.cpp | 7 ++++ syncd/ComparisonLogic.cpp | 52 +++++++++++++++++++++++++++- syncd/ComparisonLogic.h | 5 +++ tests/BCM56850.pl | 27 +++++++++++++++ tests/BCM56850/acl_counter_match.rec | 24 +++++++++++++ 5 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 tests/BCM56850/acl_counter_match.rec diff --git a/syncd/BestCandidateFinder.cpp b/syncd/BestCandidateFinder.cpp index 9be164953..230be7993 100644 --- a/syncd/BestCandidateFinder.cpp +++ b/syncd/BestCandidateFinder.cpp @@ -3002,6 +3002,13 @@ std::shared_ptr BestCandidateFinder::getSaiAttrFromDefaultValue( return std::make_shared(meta.attridname, str_attr_value); } + case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT8: + case SAI_ATTR_VALUE_TYPE_ACL_FIELD_DATA_UINT16: + + // ACL field data don't have default values (disabled) + + return nullptr; + default: SWSS_LOG_ERROR("serialization type %s is not supported yet, FIXME", diff --git a/syncd/ComparisonLogic.cpp b/syncd/ComparisonLogic.cpp index 8ff9a174f..adb24930a 100644 --- a/syncd/ComparisonLogic.cpp +++ b/syncd/ComparisonLogic.cpp @@ -2806,6 +2806,53 @@ void ComparisonLogic::cretePreMatchForLagMembers( } } +void ComparisonLogic::cretePreMatchForAclEntries( + _In_ const AsicView& cur, + _Inout_ AsicView& tmp, + _Inout_ std::set& processed) +{ + SWSS_LOG_ENTER(); + + // match acl entries which have the same priority attribute + + auto cAclEntries = cur.getObjectsByObjectType(SAI_OBJECT_TYPE_ACL_ENTRY); + auto tAclEntries = tmp.getObjectsByObjectType(SAI_OBJECT_TYPE_ACL_ENTRY); + + for (auto& cAclEntry: cAclEntries) + { + if (processed.find(cAclEntry->m_str_object_id) != processed.end()) + continue; + + for (auto& tAclEntry: tAclEntries) + { + if (processed.find(tAclEntry->m_str_object_id) != processed.end()) + continue; + + auto cPrio = cAclEntry->getSaiAttr(SAI_ACL_ENTRY_ATTR_PRIORITY); + auto tPrio = tAclEntry->getSaiAttr(SAI_ACL_ENTRY_ATTR_PRIORITY); + + if (cPrio->getStrAttrValue() != tPrio->getStrAttrValue()) + { + continue; + } + + // at this point current and temporary acl entry share the same + // priority, then we can assume that those objects are the same + + SWSS_LOG_NOTICE("pre match Acl Entry: cur: %s, tmp: %s, using prio: %s", + cAclEntry->m_str_object_id.c_str(), + tAclEntry->m_str_object_id.c_str(), + cPrio->getStrAttrValue().c_str()); + + tmp.m_preMatchMap[tAclEntry->getVid()] = cAclEntry->getVid(); + + createPreMatchMapForObject(cur, tmp, cAclEntry, tAclEntry, processed); + + break; + } + } +} + void ComparisonLogic::createPreMatchMap( _In_ const AsicView& cur, _Inout_ AsicView& tmp) @@ -2926,6 +2973,8 @@ void ComparisonLogic::createPreMatchMap( count++; } + cretePreMatchForAclEntries(cur, tmp, processed); + SWSS_LOG_NOTICE("preMatch map size: %zu, tmp oid obj: %zu", tmp.m_preMatchMap.size(), count); @@ -3045,7 +3094,8 @@ void ComparisonLogic::applyViewTransition( { // TODO make generic list of root objects (or meta SAI for this) - if (obj.second->getObjectType() == SAI_OBJECT_TYPE_ACL_TABLE_GROUP) + if (obj.second->getObjectType() == SAI_OBJECT_TYPE_ACL_TABLE_GROUP || + obj.second->getObjectType() == SAI_OBJECT_TYPE_ACL_ENTRY) { if (temp.m_preMatchMap.find(obj.second->getVid()) == temp.m_preMatchMap.end()) { diff --git a/syncd/ComparisonLogic.h b/syncd/ComparisonLogic.h index 89f8a5b92..261088e3b 100644 --- a/syncd/ComparisonLogic.h +++ b/syncd/ComparisonLogic.h @@ -180,6 +180,11 @@ namespace syncd _Inout_ AsicView& tmp, _Inout_ std::set& processed); + void cretePreMatchForAclEntries( + _In_ const AsicView& cur, + _Inout_ AsicView& tmp, + _Inout_ std::set& processed); + sai_object_id_t asic_translate_vid_to_rid( _In_ const AsicView& current, _In_ const AsicView& temporary, diff --git a/tests/BCM56850.pl b/tests/BCM56850.pl index d3d0297ed..b3b371568 100755 --- a/tests/BCM56850.pl +++ b/tests/BCM56850.pl @@ -785,8 +785,35 @@ sub test_voq_switch_create play("-z", "redis_sync", "voq_switch_create.rec") } +sub test_acl_counter_match +{ + # this will test scenario where we have 1 acl entry with counter and after + # warm boot 2 acl entries and 2 counters the same which could end up + # matching wrong acl counter and causing fail "object exist" on broadcom + # acl entry set, which will require improve pre match logic for acl entry + + fresh_start; + + play "acl_counter_match.rec"; + + open (my $H, "<", "applyview.log") or die "failed to open applyview.log $!"; + + my $line = <$H>; + + close ($H); + + chomp$line; + + if (not $line =~ /ASIC_OPERATIONS: (\d+)/ or $1 != 2) + { + print color('red') . "expected 2 ASIC_OPERATIONS count on first line, but got: '$line'" . color('reset') . "\n"; + exit 1; + } +} + # RUN TESTS +test_acl_counter_match; test_neighbor_lag; test_lag_member; test_remove_port_serdes; diff --git a/tests/BCM56850/acl_counter_match.rec b/tests/BCM56850/acl_counter_match.rec new file mode 100644 index 000000000..3c7980cb6 --- /dev/null +++ b/tests/BCM56850/acl_counter_match.rec @@ -0,0 +1,24 @@ +2023-04-09.06:05:51.758572|a|INIT_VIEW +2023-04-09.06:05:54.894996|A|SAI_STATUS_SUCCESS +2023-04-09.06:05:54.898126|c|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_INIT_SWITCH=true|SAI_SWITCH_ATTR_FDB_EVENT_NOTIFY=0x55e3e3d2db30|SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY=0x55e3e3d2db40|SAI_SWITCH_ATTR_SWITCH_SHUTDOWN_REQUEST_NOTIFY=0x55e3e3d2db60|SAI_SWITCH_ATTR_SRC_MAC_ADDRESS=94:8E:D3:B8:D1:48 +2023-04-09.06:06:01.316781|g|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0 +2023-04-09.06:06:01.320955|G|SAI_STATUS_SUCCESS|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x1000000000002,oid:0x1000000000003,oid:0x1000000000004,oid:0x1000000000005,oid:0x1000000000006,oid:0x1000000000007,oid:0x1000000000008,oid:0x1000000000009,oid:0x100000000000a,oid:0x100000000000b,oid:0x100000000000c,oid:0x100000000000d,oid:0x100000000000e,oid:0x100000000000f,oid:0x1000000000010,oid:0x1000000000011,oid:0x1000000000012,oid:0x1000000000013,oid:0x1000000000014,oid:0x1000000000015,oid:0x1000000000016,oid:0x1000000000017,oid:0x1000000000018,oid:0x1000000000019,oid:0x100000000001a,oid:0x100000000001b,oid:0x100000000001c,oid:0x100000000001d,oid:0x100000000001e,oid:0x100000000001f,oid:0x1000000000020,oid:0x1000000000021 +2023-04-09.06:06:06.534280|c|SAI_OBJECT_TYPE_ACL_TABLE:oid:0x700000000069f|SAI_ACL_TABLE_ATTR_ACL_BIND_POINT_TYPE_LIST=2:SAI_ACL_BIND_POINT_TYPE_PORT,SAI_ACL_BIND_POINT_TYPE_LAG|SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_ID=true|SAI_ACL_TABLE_ATTR_FIELD_ACL_IP_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_SRC_IP=true|SAI_ACL_TABLE_ATTR_FIELD_DST_IP=true|SAI_ACL_TABLE_ATTR_FIELD_ICMP_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_ICMP_CODE=true|SAI_ACL_TABLE_ATTR_FIELD_IP_PROTOCOL=true|SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS=true|SAI_ACL_TABLE_ATTR_FIELD_SRC_IPV6=true|SAI_ACL_TABLE_ATTR_FIELD_DST_IPV6=true|SAI_ACL_TABLE_ATTR_FIELD_ICMPV6_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_ICMPV6_CODE=true|SAI_ACL_TABLE_ATTR_FIELD_IPV6_NEXT_HEADER=true|SAI_ACL_TABLE_ATTR_FIELD_L4_SRC_PORT=true|SAI_ACL_TABLE_ATTR_FIELD_L4_DST_PORT=true|SAI_ACL_TABLE_ATTR_FIELD_TCP_FLAGS=true|SAI_ACL_TABLE_ATTR_FIELD_ACL_RANGE_TYPE=2:SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE,SAI_ACL_RANGE_TYPE_L4_SRC_PORT_RANGE|SAI_ACL_TABLE_ATTR_ACL_STAGE=SAI_ACL_STAGE_INGRESS|SAI_ACL_TABLE_ATTR_FIELD_DSCP=true +2023-04-09.06:13:45.951630|c|SAI_OBJECT_TYPE_ACL_COUNTER:oid:0x90000000008fa|SAI_ACL_COUNTER_ATTR_TABLE_ID=oid:0x700000000069f|SAI_ACL_COUNTER_ATTR_ENABLE_BYTE_COUNT=true|SAI_ACL_COUNTER_ATTR_ENABLE_PACKET_COUNT=true +2023-04-09.06:13:42.965856|c|SAI_OBJECT_TYPE_MIRROR_SESSION:oid:0xe0000000008f9|SAI_MIRROR_SESSION_ATTR_MONITOR_PORT=oid:0x1000000000020|SAI_MIRROR_SESSION_ATTR_TYPE=SAI_MIRROR_SESSION_TYPE_ENHANCED_REMOTE|SAI_MIRROR_SESSION_ATTR_ERSPAN_ENCAPSULATION_TYPE=SAI_ERSPAN_ENCAPSULATION_TYPE_MIRROR_L3_GRE_TUNNEL|SAI_MIRROR_SESSION_ATTR_IPHDR_VERSION=4|SAI_MIRROR_SESSION_ATTR_TOS=32|SAI_MIRROR_SESSION_ATTR_TTL=255|SAI_MIRROR_SESSION_ATTR_SRC_IP_ADDRESS=10.1.0.32|SAI_MIRROR_SESSION_ATTR_DST_IP_ADDRESS=192.168.8.1|SAI_MIRROR_SESSION_ATTR_SRC_MAC_ADDRESS=94:8E:D3:B8:D1:48|SAI_MIRROR_SESSION_ATTR_DST_MAC_ADDRESS=3E:2F:91:12:89:AB|SAI_MIRROR_SESSION_ATTR_GRE_PROTOCOL_TYPE=35006 +2023-04-09.06:13:45.974778|c|SAI_OBJECT_TYPE_ACL_ENTRY:oid:0x80000000008fb|SAI_ACL_ENTRY_ATTR_TABLE_ID=oid:0x700000000069f|SAI_ACL_ENTRY_ATTR_PRIORITY=8888|SAI_ACL_ENTRY_ATTR_ADMIN_STATE=true|SAI_ACL_ENTRY_ATTR_ACTION_COUNTER=oid:0x90000000008fa|SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE=2054&mask:0xffff|SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS=1:oid:0xe0000000008f9 +2023-04-09.06:06:01.989510|a|APPLY_VIEW +2023-04-09.06:06:01.990574|A|SAI_STATUS_SUCCESS +2023-04-09.06:16:00.119350|a|INIT_VIEW +2023-04-09.06:16:10.264317|A|SAI_STATUS_SUCCESS +2023-04-09.06:16:10.268256|c|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_INIT_SWITCH=true|SAI_SWITCH_ATTR_FDB_EVENT_NOTIFY=0x5631fe2d0b30|SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY=0x5631fe2d0b40|SAI_SWITCH_ATTR_SWITCH_SHUTDOWN_REQUEST_NOTIFY=0x5631fe2d0b60|SAI_SWITCH_ATTR_SRC_MAC_ADDRESS=94:8E:D3:B8:D1:48 +2023-04-09.06:16:10.314901|g|SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0,oid:0x0 +2023-04-09.06:16:10.323831|G|SAI_STATUS_SUCCESS|SAI_SWITCH_ATTR_PORT_LIST=32:oid:0x1000000000002,oid:0x1000000000003,oid:0x1000000000004,oid:0x1000000000005,oid:0x1000000000006,oid:0x1000000000007,oid:0x1000000000008,oid:0x1000000000009,oid:0x100000000000a,oid:0x100000000000b,oid:0x100000000000c,oid:0x100000000000d,oid:0x100000000000e,oid:0x100000000000f,oid:0x1000000000010,oid:0x1000000000011,oid:0x1000000000012,oid:0x1000000000013,oid:0x1000000000014,oid:0x1000000000015,oid:0x1000000000016,oid:0x1000000000017,oid:0x1000000000018,oid:0x1000000000019,oid:0x100000000001a,oid:0x100000000001b,oid:0x100000000001c,oid:0x100000000001d,oid:0x100000000001e,oid:0x100000000001f,oid:0x1000000000020,oid:0x1000000000021 +2023-04-09.06:16:16.176451|c|SAI_OBJECT_TYPE_ACL_TABLE:oid:0x7000000000ba4|SAI_ACL_TABLE_ATTR_ACL_BIND_POINT_TYPE_LIST=2:SAI_ACL_BIND_POINT_TYPE_PORT,SAI_ACL_BIND_POINT_TYPE_LAG|SAI_ACL_TABLE_ATTR_FIELD_ETHER_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_OUTER_VLAN_ID=true|SAI_ACL_TABLE_ATTR_FIELD_ACL_IP_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_SRC_IP=true|SAI_ACL_TABLE_ATTR_FIELD_DST_IP=true|SAI_ACL_TABLE_ATTR_FIELD_ICMP_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_ICMP_CODE=true|SAI_ACL_TABLE_ATTR_FIELD_IP_PROTOCOL=true|SAI_ACL_TABLE_ATTR_FIELD_IN_PORTS=true|SAI_ACL_TABLE_ATTR_FIELD_SRC_IPV6=true|SAI_ACL_TABLE_ATTR_FIELD_DST_IPV6=true|SAI_ACL_TABLE_ATTR_FIELD_ICMPV6_TYPE=true|SAI_ACL_TABLE_ATTR_FIELD_ICMPV6_CODE=true|SAI_ACL_TABLE_ATTR_FIELD_IPV6_NEXT_HEADER=true|SAI_ACL_TABLE_ATTR_FIELD_L4_SRC_PORT=true|SAI_ACL_TABLE_ATTR_FIELD_L4_DST_PORT=true|SAI_ACL_TABLE_ATTR_FIELD_TCP_FLAGS=true|SAI_ACL_TABLE_ATTR_FIELD_ACL_RANGE_TYPE=2:SAI_ACL_RANGE_TYPE_L4_DST_PORT_RANGE,SAI_ACL_RANGE_TYPE_L4_SRC_PORT_RANGE|SAI_ACL_TABLE_ATTR_ACL_STAGE=SAI_ACL_STAGE_INGRESS|SAI_ACL_TABLE_ATTR_FIELD_DSCP=true +2023-04-09.06:16:19.208992|c|SAI_OBJECT_TYPE_MIRROR_SESSION:oid:0xe000000000be0|SAI_MIRROR_SESSION_ATTR_MONITOR_PORT=oid:0x1000000000020|SAI_MIRROR_SESSION_ATTR_TYPE=SAI_MIRROR_SESSION_TYPE_ENHANCED_REMOTE|SAI_MIRROR_SESSION_ATTR_ERSPAN_ENCAPSULATION_TYPE=SAI_ERSPAN_ENCAPSULATION_TYPE_MIRROR_L3_GRE_TUNNEL|SAI_MIRROR_SESSION_ATTR_IPHDR_VERSION=4|SAI_MIRROR_SESSION_ATTR_TOS=32|SAI_MIRROR_SESSION_ATTR_TTL=255|SAI_MIRROR_SESSION_ATTR_SRC_IP_ADDRESS=10.1.0.32|SAI_MIRROR_SESSION_ATTR_DST_IP_ADDRESS=192.168.8.1|SAI_MIRROR_SESSION_ATTR_SRC_MAC_ADDRESS=94:8E:D3:B8:D1:48|SAI_MIRROR_SESSION_ATTR_DST_MAC_ADDRESS=3E:2F:91:12:89:AB|SAI_MIRROR_SESSION_ATTR_GRE_PROTOCOL_TYPE=35006 +2023-04-09.06:16:19.210586|c|SAI_OBJECT_TYPE_ACL_COUNTER:oid:0x9000000000be1|SAI_ACL_COUNTER_ATTR_TABLE_ID=oid:0x7000000000ba4|SAI_ACL_COUNTER_ATTR_ENABLE_BYTE_COUNT=true|SAI_ACL_COUNTER_ATTR_ENABLE_PACKET_COUNT=true +2023-04-09.06:16:19.211547|c|SAI_OBJECT_TYPE_ACL_ENTRY:oid:0x8000000000be2|SAI_ACL_ENTRY_ATTR_TABLE_ID=oid:0x7000000000ba4|SAI_ACL_ENTRY_ATTR_PRIORITY=8887|SAI_ACL_ENTRY_ATTR_ADMIN_STATE=true|SAI_ACL_ENTRY_ATTR_ACTION_COUNTER=oid:0x9000000000be1|SAI_ACL_ENTRY_ATTR_FIELD_ICMPV6_TYPE=135&mask:0xff|SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS=1:oid:0xe000000000be0 +2023-04-09.06:16:19.212592|c|SAI_OBJECT_TYPE_ACL_COUNTER:oid:0x9000000000be3|SAI_ACL_COUNTER_ATTR_TABLE_ID=oid:0x7000000000ba4|SAI_ACL_COUNTER_ATTR_ENABLE_BYTE_COUNT=true|SAI_ACL_COUNTER_ATTR_ENABLE_PACKET_COUNT=true +2023-04-09.06:16:19.213400|c|SAI_OBJECT_TYPE_ACL_ENTRY:oid:0x8000000000be4|SAI_ACL_ENTRY_ATTR_TABLE_ID=oid:0x7000000000ba4|SAI_ACL_ENTRY_ATTR_PRIORITY=8888|SAI_ACL_ENTRY_ATTR_ADMIN_STATE=true|SAI_ACL_ENTRY_ATTR_ACTION_COUNTER=oid:0x9000000000be3|SAI_ACL_ENTRY_ATTR_FIELD_ETHER_TYPE=2054&mask:0xffff|SAI_ACL_ENTRY_ATTR_ACTION_MIRROR_INGRESS=1:oid:0xe000000000be0 +2023-04-09.06:16:19.214593|a|APPLY_VIEW +2023-04-09.06:16:21.919159|A|SAI_STATUS_SUCCESS From 00a953c6eafb8852d771c0f7a4f91db9f0965530 Mon Sep 17 00:00:00 2001 From: Mai Bui Date: Fri, 9 Jun 2023 09:34:05 -0400 Subject: [PATCH 21/25] docker prefer copy to add (#1250) Signed-off-by: Mai Bui #### Why I did it Docker best practices prefer COPY to ADD https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#add-or-copy ##### Work item tracking - Microsoft ADO **(number only)**: 17418730 #### How I did it Use the COPY command as opposed to ADD unless working with a tar file. --- .azure-pipelines/docker-sonic-vs/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.azure-pipelines/docker-sonic-vs/Dockerfile b/.azure-pipelines/docker-sonic-vs/Dockerfile index 636baa44b..deedf0265 100644 --- a/.azure-pipelines/docker-sonic-vs/Dockerfile +++ b/.azure-pipelines/docker-sonic-vs/Dockerfile @@ -3,7 +3,7 @@ FROM docker-sonic-vs ARG docker_container_name ARG need_dbg -ADD ["debs", "/debs"] +COPY ["debs", "/debs"] RUN dpkg -i /debs/libswsscommon_1.0.0_amd64.deb \ /debs/python3-swsscommon_1.0.0_amd64.deb \ From 321ce7467b1a1d45ec9de6ac81aac1acf0284f7d Mon Sep 17 00:00:00 2001 From: Konstantin Vasin <126960927+k-v1@users.noreply.github.com> Date: Mon, 19 Jun 2023 08:42:44 +0300 Subject: [PATCH 22/25] Disable GCC VTA for SWIG-generated file (#1253) Fix sonic-net/sonic-buildimage#13775 -fvar-tracking-assignments Annotate assignments to user variables early in the compilation and attempt to carry the annotations over throughout the compilation all the way to the end, in an attempt to improve debug information while optimizing. By default, this flag is enabled. There is no reason to use this flag for auto-generated code. --- pyext/pysairedis.i | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyext/pysairedis.i b/pyext/pysairedis.i index 8a980ca95..92ced0421 100644 --- a/pyext/pysairedis.i +++ b/pyext/pysairedis.i @@ -3,6 +3,8 @@ %include "carrays.i" %{ +#pragma GCC optimize("no-var-tracking-assignments") + #include "pysairedis.h" extern "C"{ From abb02a587f6178c81597f91270e7b3c74593437b Mon Sep 17 00:00:00 2001 From: Mai Bui Date: Tue, 20 Jun 2023 10:53:39 -0400 Subject: [PATCH 23/25] [actions] Support Semgrep by Github Actions (#1254) Signed-off-by: Mai Bui Why I did it Semgrep is a static analysis tool to find security vulnerabilities. When opening a PR or commtting to PR, Semgrep performs a diff-aware scanning, which scans changed files in PRs. When merging PR, Semgrep performs a full scan on master branch and report all findings. Ref: - Supported Language - Semgrep Rules How I did it Integrate Semgrep into this repository by committing a job configuration file --- .github/workflows/semgrep.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 .github/workflows/semgrep.yml diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 000000000..975769a50 --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,22 @@ +name: Semgrep + +on: + pull_request: {} + push: + branches: + - master + - '201[7-9][0-1][0-9]' + - '202[0-9][0-1][0-9]' + +jobs: + semgrep: + if: github.repository_owner == 'sonic-net' + name: Semgrep + runs-on: ubuntu-latest + container: + image: returntocorp/semgrep + steps: + - uses: actions/checkout@v3 + - run: semgrep ci + env: + SEMGREP_RULES: p/default From 14a863a6d8f2855a7cebf1b7e62bc46dbed76ff6 Mon Sep 17 00:00:00 2001 From: Jing Zhang Date: Wed, 21 Jun 2023 14:36:03 -0700 Subject: [PATCH 24/25] [warmboot] Add workaround for `INIT_VIEW` failure (#1252) why change is needed "SaiGetHardwareInfo" is now returning string "none" instead of empty string (""), which is causing INIT_VIEW failure: May 26 18:57:33.577868 NOTICE syncd#syncd: :- onSwitchCreateInInitViewMode: new switch oid:0x21000000000000 contains hardware info: '' May 26 18:57:33.577868 ERR syncd#syncd: :- onSwitchCreateInInitViewMode: hardware info mismatch: current 'none' vs new '' May 26 18:57:33.578017 ERR syncd#syncd: :- run: Runtime error: :- onSwitchCreateInInitViewMode: hardware info mismatch: current 'none' vs new '' Adding this change as a temp workaround before CSP is resolved with BRCM. how I verify Test syncd build on lab device, able to pass INIT_VIEW stage. sign-off: Jing Zhang zhangjing@microsoft.com --- syncd/Syncd.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/syncd/Syncd.cpp b/syncd/Syncd.cpp index 0f331d334..103d8820a 100644 --- a/syncd/Syncd.cpp +++ b/syncd/Syncd.cpp @@ -4309,6 +4309,13 @@ void Syncd::onSwitchCreateInInitViewMode( sai_serialize_object_id(switchVid).c_str(), newHw.c_str()); + /* + * The line below is added due to a behavior change of SAI call. + * + * TODO: remove the line when SAI vendor agrees fix on their end. + */ + currentHw = currentHw == "none"? "" : currentHw; + if (currentHw != newHw) { SWSS_LOG_THROW("hardware info mismatch: current '%s' vs new '%s'", currentHw.c_str(), newHw.c_str()); From a3f1f1a72e1a84be2f33ab847114f7acd97e61ea Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Fri, 30 Jun 2023 10:32:46 -0700 Subject: [PATCH 25/25] Reland 'Make changes to building and packaging sairedis (#1116)' (#1194) * Reland 'Make changes to building and packaging sairedis (#1116)' * Make changes to building and packaging sairedis This commit includes the following changes: 1. Use Debian build profiles instead of custom build targets to build different configurations of sairedis. Build profiles were designed for this purpose. This also makes the debian/rules file a bit cleaner. 2. Rely on the debug packages being automatically created, instead of us explicitly specifying it in debian/control. 3. Add actual support for excluding Python 2 binding during build. 4. Make sure the compile flags used for building Python 2 and Python 3 are actually correct. Signed-off-by: Saikrishna Arcot * Update pipeline file Signed-off-by: Saikrishna Arcot * Fix argument for profile Signed-off-by: Saikrishna Arcot * Exclude libsai package from the list of dependencies Signed-off-by: Saikrishna Arcot * Allow multiple syslog artifacts during tests Signed-off-by: Saikrishna Arcot * Fix debug poackage name in dockerfile Signed-off-by: Saikrishna Arcot * Fix armhf build due to python binary not existing Signed-off-by: Saikrishna Arcot --------- Signed-off-by: Saikrishna Arcot --- .azure-pipelines/build-template.yml | 4 +- .azure-pipelines/docker-sonic-vs/Dockerfile | 2 +- configure.ac | 28 +- debian/compat | 2 +- debian/control | 70 +---- debian/libsaimetadata-dev.install | 2 + debian/libsairedis-dev.install | 1 + debian/rules | 81 ++--- m4/ax_python3_devel.m4 | 327 ++++++++++++++++++++ meta/Makefile.am | 4 +- pyext/Makefile.am | 5 +- pyext/py2/Makefile.am | 4 +- pyext/py3/Makefile.am | 2 +- 13 files changed, 406 insertions(+), 126 deletions(-) create mode 100644 m4/ax_python3_devel.m4 diff --git a/.azure-pipelines/build-template.yml b/.azure-pipelines/build-template.yml index 4567435a6..84f839e83 100644 --- a/.azure-pipelines/build-template.yml +++ b/.azure-pipelines/build-template.yml @@ -159,7 +159,7 @@ jobs: if [ '${{ parameters.asan }}' == True ]; then extraflags='--enable-asan' fi - DEB_BUILD_OPTIONS=nocheck fakeroot debian/rules DEB_CONFIGURE_EXTRA_FLAGS=$extraflags DEB_BUILD_PROFILES=nopython2 CFLAGS="" CXXFLAGS="" binary-syncd-vs + DEB_BUILD_OPTIONS=nocheck DEB_CONFIGURE_EXTRA_FLAGS=$extraflags dpkg-buildpackage -us -uc -b -Psyncd,vs,nopython2 -j$(nproc) mv ../*.deb . displayName: "Compile sonic sairedis with coverage enabled" - script: | @@ -227,6 +227,6 @@ jobs: contents: 'syslog-all.tgz' targetFolder: $(Build.ArtifactStagingDirectory) - publish: $(Build.ArtifactStagingDirectory)/ - artifact: ${{ parameters.syslog_artifact_name }} + artifact: ${{ parameters.syslog_artifact_name }}@$(System.JobAttempt) displayName: "Publish syslog artifacts" condition: always() diff --git a/.azure-pipelines/docker-sonic-vs/Dockerfile b/.azure-pipelines/docker-sonic-vs/Dockerfile index deedf0265..9ca53f85a 100644 --- a/.azure-pipelines/docker-sonic-vs/Dockerfile +++ b/.azure-pipelines/docker-sonic-vs/Dockerfile @@ -14,4 +14,4 @@ RUN dpkg -i /debs/libswsscommon_1.0.0_amd64.deb \ /debs/syncd-vs_1.0.0_amd64.deb \ /debs/swss_1.0.0_amd64.deb -RUN if [ "$need_dbg" = "y" ] ; then dpkg -i /debs/syncd-vs-dbg_1.0.0_amd64.deb ; fi +RUN if [ "$need_dbg" = "y" ] ; then dpkg -i /debs/syncd-vs-dbgsym_1.0.0_amd64.deb ; fi diff --git a/configure.ac b/configure.ac index b95367ef5..1f664b490 100644 --- a/configure.ac +++ b/configure.ac @@ -10,8 +10,8 @@ AC_PROG_CC AC_PROG_CXX AC_PROG_LIBTOOL AC_HEADER_STDC -AM_PATH_PYTHON AM_PATH_PYTHON3 +AX_PYTHON3_DEVEL AX_CODE_COVERAGE AX_ADD_AM_MACRO_STATIC([]) @@ -101,6 +101,14 @@ AC_ARG_ENABLE(asan, *) AC_MSG_ERROR(bad value ${enableval} for --enable-asan) ;; esac],[asan_enabled=false]) +AC_ARG_ENABLE(python2, +[ --enable-python2 Generate Python 2 bindings], +[case "${enableval}" in + yes) python2=true ;; + no) python2=false ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-python2) ;; +esac],[python2=true]) + if test "x$asan_enabled" = "xtrue"; then CFLAGS_ASAN+=" -fsanitize=address" CFLAGS_ASAN+=" -DASAN_ENABLED" @@ -111,13 +119,31 @@ if test "x$asan_enabled" = "xtrue"; then AC_SUBST(LDFLAGS_ASAN) fi +if test "x$python2" = "xtrue"; then + m4_define_default([_AM_PYTHON_INTERPRETER_LIST], + [python2 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0]) + AM_PATH_PYTHON + AX_PYTHON_DEVEL([< '3']) + PYTHON2_CPPFLAGS=$PYTHON_CPPFLAGS + PYTHON2_LIBS=$PYTHON_LIBS + AC_SUBST(PYTHON2_CPPFLAGS) + AC_SUBST(PYTHON2_LIBS) +else + # The py-compile script either uses $PYTHON (which won't be set if we're not building python 2 bindings), + # or assumes a default of `python` (which may or may not exist as a symlink). Therefore, just assign + # PYTHON3 to PYTHON to make sure it always points to a valid binary. + PYTHON=$PYTHON3 +fi + AM_CONDITIONAL(ASAN_ENABLED, test x$asan_enabled = xtrue) +AM_CONDITIONAL(PYTHON2, test x$python2 = xtrue) AC_PATH_PROGS(SWIG, [swig3.0 swig]) CXXFLAGS_COMMON="" CXXFLAGS_COMMON+=" -ansi" CXXFLAGS_COMMON+=" -fPIC" +CXXFLAGS_COMMON+=" -pipe" CXXFLAGS_COMMON+=" -std=c++14" CXXFLAGS_COMMON+=" -Wall" CXXFLAGS_COMMON+=" -Wcast-align" diff --git a/debian/compat b/debian/compat index f599e28b8..48082f72f 100644 --- a/debian/compat +++ b/debian/compat @@ -1 +1 @@ -10 +12 diff --git a/debian/control b/debian/control index 5b5284e0b..a07ed6d80 100644 --- a/debian/control +++ b/debian/control @@ -2,17 +2,23 @@ Source: sonic Maintainer: Kamil Cudnik Section: net Priority: optional -Build-Depends: debhelper (>=9), autotools-dev, libzmq5-dev +Build-Depends: debhelper (>= 12), autotools-dev, libzmq5-dev Standards-Version: 1.0.0 Package: syncd Architecture: any +Build-Profiles: +Depends: ${misc:Pre-Depends} +Recommends: ${shlibs:Depends} Conflicts: syncd-rpc, syncd-vs Description: This package contains sync daemon for SONiC project. This sync daemon syncs the ASIC_DB in Redis database and the real ASIC via SAI. Package: syncd-rpc Architecture: any +Build-Profiles: +Depends: ${misc:Pre-Depends} +Recommends: ${shlibs:Depends} Conflicts: syncd, syncd-vs Description: This package contains sync daemon with rpc for SONiC project. This sync daemon syncs the ASIC_DB in Redis database and the real ASIC via SAI. @@ -20,6 +26,9 @@ Description: This package contains sync daemon with rpc for SONiC project. Package: syncd-vs Architecture: any +Build-Profiles: +Depends: ${misc:Pre-Depends} +Recommends: ${shlibs:Depends} Conflicts: syncd-rpc, syncd Description: This package contains sync daemon for SONiC project linked with virtual switch. This sync daemon syncs the ASIC_DB in Redis database and the real ASIC via SAI. @@ -38,6 +47,7 @@ Description: This package contains development files for SAI-Redis. Package: libsaivs Architecture: any +Depends: ${shlibs:Depends}, ${misc:Pre-Depends} Section: libs Description: This package contains SAI-VirtualSwitch implementation for SONiC project. @@ -49,6 +59,7 @@ Description: This package contains development files for SAI-VirtualSwitch. Package: libsaimetadata Architecture: any +Depends: ${shlibs:Depends}, ${misc:Pre-Depends} Section: libs Description: This package contains SAI-Metadata implementation for SONiC project. @@ -58,63 +69,6 @@ Depends: libsaimetadata (= ${binary:Version}) Section: libdevel Description: This package contains development files for SAI-Metadata. -Package: syncd-dbg -Architecture: any -Section: debug -Priority: extra -Conflicts: syncd-rpc-dbg, syncd-vs -Depends: - syncd (= ${binary:Version}), - ${misc:Depends} -Description: debugging symbols for syncd - -Package: syncd-rpc-dbg -Architecture: any -Section: debug -Priority: extra -Conflicts: syncd-dbg, syncd-vs -Depends: - syncd-rpc (= ${binary:Version}), - ${misc:Depends} -Description: debugging symbols for syncd-rpc - -Package: syncd-vs-dbg -Architecture: any -Section: debug -Priority: extra -Conflicts: syncd-dbg, syncd-rpc-dbg -Depends: - syncd-vs (= ${binary:Version}), - ${misc:Depends} -Description: debugging symbols for syncd-vs - -Package: libsairedis-dbg -Architecture: any -Section: debug -Priority: extra -Depends: - libsairedis (= ${binary:Version}), - ${misc:Depends} -Description: debugging symbols for libsairedis - -Package: libsaivs-dbg -Architecture: any -Section: debug -Priority: extra -Depends: - libsaivs (= ${binary:Version}), - ${misc:Depends} -Description: debugging symbols for libsaivs - -Package: libsaimetadata-dbg -Architecture: any -Section: debug -Priority: extra -Depends: - libsaimetadata (= ${binary:Version}), - ${misc:Depends} -Description: debugging symbols for libsaimetadata - Package: python-pysairedis Architecture: any Build-Profiles: diff --git a/debian/libsaimetadata-dev.install b/debian/libsaimetadata-dev.install index a79656b38..877842eeb 100644 --- a/debian/libsaimetadata-dev.install +++ b/debian/libsaimetadata-dev.install @@ -1,3 +1,5 @@ meta/sai*.h usr/include/sai meta/Sai*.h usr/include/sai SAI/meta/sai*.h usr/include/sai +usr/lib/*/libsaimetadata.so +usr/lib/*/libsaimeta.so diff --git a/debian/libsairedis-dev.install b/debian/libsairedis-dev.install index 21fa7340a..d5750f6dd 100644 --- a/debian/libsairedis-dev.install +++ b/debian/libsairedis-dev.install @@ -1 +1,2 @@ lib/sairedis.h usr/include/sai +usr/lib/*/libsairedis.so diff --git a/debian/rules b/debian/rules index 7568b68ca..c66761544 100755 --- a/debian/rules +++ b/debian/rules @@ -3,14 +3,6 @@ # output every command that modifies files on the build system. #export DH_VERBOSE = 1 -.ONESHELL: -SHELL = /bin/bash -.SHELLFLAGS += -ex - -# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* -DPKG_EXPORT_BUILDFLAGS = 1 -include /usr/share/dpkg/default.mk - ifneq (${SWSS_COMMON_INC},) SWSS_COMMON_CONFIG = "--with-swss-common-inc=${SWSS_COMMON_INC}" endif @@ -21,7 +13,7 @@ ifneq (${SWSS_COMMON_LIB},) endif # see FEATURE AREAS in dpkg-buildflags(1) -#export DEB_BUILD_MAINT_OPTIONS = hardening=+all +export DEB_BUILD_MAINT_OPTIONS = hardening=+all # see ENVIRONMENT in dpkg-buildflags(1) # package maintainers to append CFLAGS @@ -31,45 +23,32 @@ endif DOPACKAGES = $(shell dh_listpackages) +configure_opts = --disable-static +ifeq ($(ENABLE_ASAN), y) + configure_opts += --enable-asan +endif + # For Debian jessie, stretch, and buster, and Ubuntu bionic and focal, build # Python 2 bindings. This is controlled by the build profile being used. -ifneq (,$(filter python-pysairedis,$(DOPACKAGES))) +ifeq (,$(filter nopython2,$(DEB_BUILD_PROFILES))) configure_opts += --enable-python2 else configure_opts += --disable-python2 endif -clean: - dh $@ --with autotools-dev - -build: - echo build stage is skipped. Please use binary to generate debian packages - -binary: binary-syncd-rpc binary-syncd - -binary-sairedis: - echo '--enable-syncd=no' > /tmp/syncd-build - ENABLESYNCD=no dh clean --with autotools-dev - dh build -N syncd -N syncd-dbg -N syncd-rpc -N syncd-rpc-dbg -N syncd-vs -N syncd-vs-dbg --with autotools-dev - dh binary -N syncd -N syncd-dbg -N syncd-rpc -N syncd-rpc-dbg -N syncd-vs -N syncd-vs-dbg --with autotools-dev - -binary-syncd: - echo > /tmp/syncd-build - dh clean --with autotools-dev - dh build -N syncd-rpc -N syncd-rpc-dbg -N syncd-vs -N syncd-vs-dbg --with autotools-dev - dh binary -N syncd-rpc -N syncd-rpc-dbg -N syncd-vs -N syncd-vs-dbg --with autotools-dev - -binary-syncd-rpc: | binary-syncd - echo '--enable-rpcserver=yes' > /tmp/syncd-build - dh clean --with autotools-dev - dh build -N syncd -N syncd-dbg -N syncd-vs -N syncd-vs-dbg --with autotools-dev - dh binary -N syncd -N syncd-dbg -N syncd-vs -N syncd-vs-dbg --with autotools-dev +ifneq ($(filter syncd,$(DEB_BUILD_PROFILES)),) +ifneq ($(filter rpc,$(DEB_BUILD_PROFILES)),) +configure_opts += --enable-rpcserver +endif +ifneq ($(filter vs,$(DEB_BUILD_PROFILES)),) +configure_opts += --with-sai=vs +endif +else +configure_opts += --disable-syncd +endif -binary-syncd-vs: - echo '--with-sai=vs' > /tmp/syncd-build - dh clean --with autotools-dev - dh build -N syncd -N syncd-dbg -N syncd-rpc -N syncd-rpc-dbg --with autotools-dev - dh binary -N syncd -N syncd-dbg -N syncd-rpc -N syncd-rpc-dbg --with autotools-dev +%: + dh $@ # dh_make generated override targets # This is example for Cmake (See https://bugs.debian.org/641051 ) @@ -77,32 +56,20 @@ binary-syncd-vs: # dh_auto_configure -- \ # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) -configure_opts = -ifeq ($(ENABLE_ASAN), y) - configure_opts += --enable-asan -endif - override_dh_auto_configure: - ./autogen.sh - dh_auto_configure -- $(DEB_CONFIGURE_EXTRA_FLAGS) $(shell cat /tmp/syncd-build) ${SWSS_COMMON_CONFIG} $(configure_opts) + dh_auto_configure -- ${SWSS_COMMON_CONFIG} $(configure_opts) override_dh_install: dh_install # Note: escape $ with an extra $ symbol - if egrep -q '(^| )--enable-rpcserver=yes( |$$)' /tmp/syncd-build && [ -f debian/syncd-rpc/usr/bin/syncd_init_common.sh ] ; then +ifneq ($(filter rpc,$(DEB_BUILD_PROFILES)),) + if [ -f debian/syncd-rpc/usr/bin/syncd_init_common.sh ] ; then sed -i 's|ENABLE_SAITHRIFT=0|ENABLE_SAITHRIFT=1 # Add a comment to fix https://github.com/Azure/sonic-buildimage/issues/2694 |' debian/syncd-rpc/usr/bin/syncd_init_common.sh fi +endif override_dh_installinit: dh_installinit --init-script=syncd override_dh_shlibdeps: - $(LD_LIBRARY_PATH_CONFIG) dh_shlibdeps --dpkg-shlibdeps-params=--ignore-missing-info - -override_dh_strip: - dh_strip -psyncd-rpc --dbg-package=syncd-rpc-dbg - dh_strip -psyncd --dbg-package=syncd-dbg - dh_strip -psyncd-vs --dbg-package=syncd-vs-dbg - dh_strip -plibsairedis --dbg-package=libsairedis-dbg - dh_strip -plibsaivs --dbg-package=libsaivs-dbg - dh_strip -plibsaimetadata --dbg-package=libsaimetadata-dbg + $(LD_LIBRARY_PATH_CONFIG) dh_shlibdeps -- --ignore-missing-info -xlibsai diff --git a/m4/ax_python3_devel.m4 b/m4/ax_python3_devel.m4 new file mode 100644 index 000000000..d7df668c7 --- /dev/null +++ b/m4/ax_python3_devel.m4 @@ -0,0 +1,327 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_python_devel.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PYTHON3_DEVEL([version]) +# +# DESCRIPTION +# +# Note: Defines as a precious variable "PYTHON3_VERSION". Don't override it +# in your configure.ac. +# +# This macro checks for Python and tries to get the include path to +# 'Python.h'. It provides the $(PYTHON3_CPPFLAGS) and $(PYTHON3_LIBS) output +# variables. It also exports $(PYTHON3_EXTRA_LIBS) and +# $(PYTHON3_EXTRA_LDFLAGS) for embedding Python in your code. +# +# You can search for some particular version of Python by passing a +# parameter to this macro, for example ">= '2.3.1'", or "== '2.4'". Please +# note that you *have* to pass also an operator along with the version to +# match, and pay special attention to the single quotes surrounding the +# version number. Don't use "PYTHON3_VERSION" for this: that environment +# variable is declared as precious and thus reserved for the end-user. +# +# This macro should work for all versions of Python >= 2.1.0. As an end +# user, you can disable the check for the python version by setting the +# PYTHON3_NOVERSIONCHECK environment variable to something else than the +# empty string. +# +# If you need to use this macro for an older Python version, please +# contact the authors. We're always open for feedback. +# +# LICENSE +# +# Copyright (c) 2009 Sebastian Huber +# Copyright (c) 2009 Alan W. Irwin +# Copyright (c) 2009 Rafael Laboissiere +# Copyright (c) 2009 Andrew Collier +# Copyright (c) 2009 Matteo Settenvini +# Copyright (c) 2009 Horst Knorr +# Copyright (c) 2013 Daniel Mullner +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 21 + +AU_ALIAS([AC_PYTHON3_DEVEL], [AX_PYTHON3_DEVEL]) +AC_DEFUN([AX_PYTHON3_DEVEL],[ + # + # Allow the use of a (user set) custom python version + # + AC_ARG_VAR([PYTHON3_VERSION],[The installed Python + version to use, for example '2.3'. This string + will be appended to the Python interpreter + canonical name.]) + + AC_PATH_PROG([PYTHON3],[python[$PYTHON3_VERSION]]) + if test -z "$PYTHON3"; then + AC_MSG_ERROR([Cannot find python$PYTHON3_VERSION in your system path]) + PYTHON3_VERSION="" + fi + + # + # Check for a version of Python >= 3.0 + # + AC_MSG_CHECKING([for a version of Python >= '3.0']) + ac_supports_python_ver=`$PYTHON3 -c "import sys; \ + ver = sys.version.split ()[[0]]; \ + print (ver >= '3.0')"` + if test "$ac_supports_python_ver" != "True"; then + if test -z "$PYTHON3_NOVERSIONCHECK"; then + AC_MSG_RESULT([no]) + AC_MSG_FAILURE([ +This version of the AC@&t@_PYTHON3_DEVEL macro +is not for versions of Python before +3.0. You may need to re-run configure, setting the +variables PYTHON3_CPPFLAGS, PYTHON3_LIBS, PYTHON3_SITE_PKG, +PYTHON3_EXTRA_LIBS and PYTHON3_EXTRA_LDFLAGS by hand. +Moreover, to disable this check, set PYTHON3_NOVERSIONCHECK +to something else than an empty string. +]) + else + AC_MSG_RESULT([skip at user request]) + fi + else + AC_MSG_RESULT([yes]) + fi + + # + # if the macro parameter ``version'' is set, honour it + # + if test -n "$1"; then + AC_MSG_CHECKING([for a version of Python $1]) + ac_supports_python_ver=`$PYTHON3 -c "import sys; \ + ver = sys.version.split ()[[0]]; \ + print (ver $1)"` + if test "$ac_supports_python_ver" = "True"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([this package requires Python $1. +If you have it installed, but it isn't the default Python +interpreter in your system path, please pass the PYTHON3_VERSION +variable to configure. See ``configure --help'' for reference. +]) + PYTHON3_VERSION="" + fi + fi + + # + # Check if you have distutils, else fail + # + AC_MSG_CHECKING([for the distutils Python package]) + ac_distutils_result=`$PYTHON3 -c "import distutils" 2>&1` + if test $? -eq 0; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([cannot import Python module "distutils". +Please check your Python installation. The error was: +$ac_distutils_result]) + PYTHON3_VERSION="" + fi + + # + # Check for Python include path + # + AC_MSG_CHECKING([for Python include path]) + if test -z "$PYTHON3_CPPFLAGS"; then + python_path=`$PYTHON3 -c "import distutils.sysconfig; \ + print (distutils.sysconfig.get_python_inc ());"` + plat_python_path=`$PYTHON3 -c "import distutils.sysconfig; \ + print (distutils.sysconfig.get_python_inc (plat_specific=1));"` + if test -n "${python_path}"; then + if test "${plat_python_path}" != "${python_path}"; then + python_path="-I$python_path -I$plat_python_path" + else + python_path="-I$python_path" + fi + fi + PYTHON3_CPPFLAGS=$python_path + fi + AC_MSG_RESULT([$PYTHON3_CPPFLAGS]) + AC_SUBST([PYTHON3_CPPFLAGS]) + + # + # Check for Python library path + # + AC_MSG_CHECKING([for Python library path]) + if test -z "$PYTHON3_LIBS"; then + # (makes two attempts to ensure we've got a version number + # from the interpreter) + ac_python_version=`cat<]], + [[Py_Initialize();]]) + ],[pythonexists=yes],[pythonexists=no]) + AC_LANG_POP([C]) + # turn back to default flags + CPPFLAGS="$ac_save_CPPFLAGS" + LIBS="$ac_save_LIBS" + LDFLAGS="$ac_save_LDFLAGS" + + AC_MSG_RESULT([$pythonexists]) + + if test ! "x$pythonexists" = "xyes"; then + AC_MSG_FAILURE([ + Could not link test program to Python. Maybe the main Python library has been + installed in some non-standard library path. If so, pass it to configure, + via the LIBS environment variable. + Example: ./configure LIBS="-L/usr/non-standard-path/python/lib" + ============================================================================ + ERROR! + You probably have to install the development version of the Python package + for your distribution. The exact name of this package varies among them. + ============================================================================ + ]) + PYTHON3_VERSION="" + fi + + # + # all done! + # +]) diff --git a/meta/Makefile.am b/meta/Makefile.am index 0667fb4ba..c2de85b3f 100644 --- a/meta/Makefile.am +++ b/meta/Makefile.am @@ -8,10 +8,10 @@ BUILT_SOURCES = $(top_srcdir)/SAI/meta/saimetadata.c $(top_srcdir)/SAI/meta/saim $(top_srcdir)/SAI/meta/saimetadata.c $(top_srcdir)/SAI/meta/saimetadata.h: saimeta-gen saimeta-gen: - make -C $(top_srcdir)/SAI/meta saimetadata.c + $(MAKE) -C $(top_srcdir)/SAI/meta saimetadata.c clean-local: - make -C $(top_srcdir)/SAI/meta clean + $(MAKE) -C $(top_srcdir)/SAI/meta clean libsaimetadata_la_SOURCES = \ $(top_srcdir)/SAI/meta/saimetadata.c \ diff --git a/pyext/Makefile.am b/pyext/Makefile.am index ceeeba214..f7c1915f7 100644 --- a/pyext/Makefile.am +++ b/pyext/Makefile.am @@ -1,3 +1,6 @@ -SUBDIRS = py2 py3 +SUBDIRS = py3 +if PYTHON2 +SUBDIRS += py2 +endif ACLOCAL_AMFLAGS = -I m4 diff --git a/pyext/py2/Makefile.am b/pyext/py2/Makefile.am index 981971d79..6c6ed8ef6 100644 --- a/pyext/py2/Makefile.am +++ b/pyext/py2/Makefile.am @@ -9,7 +9,7 @@ AM_CXXFLAGS = $(SAIINC) -I$(top_srcdir)/lib -I.. BUILT_SOURCES = pysairedis_wrap.cpp _pysairedis_la_SOURCES = pysairedis_wrap.cpp $(SOURCES) -_pysairedis_la_CXXFLAGS = -I/usr/include/python$(PYTHON_VERSION) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) \ +_pysairedis_la_CXXFLAGS = $(PYTHON2_CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) \ -Wno-cast-qual -Wno-shadow -Wno-redundant-decls -Wno-conversion $(NO_CAST_FUNCTION_TYPE) _pysairedis_la_LDFLAGS = -module \ @@ -18,7 +18,7 @@ _pysairedis_la_LDFLAGS = -module \ -L$(top_srcdir)/meta/.libs -lsaimetadata -lsaimeta \ -lzmq -_pysairedis_la_LIBADD = -lpython$(PYTHON_VERSION) +_pysairedis_la_LIBADD = $(PYTHON2_LIBS) SWIG_FLAG = -Wall -c++ -python -keyword if ARCH64 diff --git a/pyext/py3/Makefile.am b/pyext/py3/Makefile.am index 4d93a416d..e3b936499 100644 --- a/pyext/py3/Makefile.am +++ b/pyext/py3/Makefile.am @@ -9,7 +9,7 @@ AM_CXXFLAGS = $(SAIINC) -I$(top_srcdir)/lib -I.. BUILT_SOURCES = pysairedis_wrap.cpp _pysairedis_la_SOURCES = pysairedis_wrap.cpp $(SOURCES) -_pysairedis_la_CXXFLAGS = -I/usr/include/python$(PYTHON3_VERSION) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) \ +_pysairedis_la_CXXFLAGS = $(PYTHON3_CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS_COMMON) \ -Wno-cast-qual -Wno-shadow -Wno-redundant-decls -Wno-conversion $(NO_CAST_FUNCTION_TYPE) _pysairedis_la_LDFLAGS = -module \