Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions syncd/BestCandidateFinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,75 @@ BestCandidateFinder::BestCandidateFinder(
// empty
}

std::shared_ptr<SaiObj> BestCandidateFinder::findCurrentBestMatchForVirtualRouter(
_In_ const std::shared_ptr<const SaiObj> &temporaryObj,
_In_ const std::vector<sai_object_compare_info_t> &candidateObjects)
{
SWSS_LOG_ENTER();

auto getVlanIds = [](
const AsicView& view,
sai_object_id_t virtualRouterId)
{
std::vector<sai_vlan_id_t> vlanIds;

for (const auto& rif: view.getObjectsByObjectType(SAI_OBJECT_TYPE_ROUTER_INTERFACE))
{
auto type = rif->tryGetSaiAttr(SAI_ROUTER_INTERFACE_ATTR_TYPE);
auto vr = rif->tryGetSaiAttr(SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID);
auto vlan = rif->tryGetSaiAttr(SAI_ROUTER_INTERFACE_ATTR_VLAN_ID);

if (type == nullptr || vr == nullptr || vlan == nullptr ||
type->getSaiAttr()->value.s32 != SAI_ROUTER_INTERFACE_TYPE_VLAN ||
vr->getOid() != virtualRouterId)
{
continue;
}

auto vlanObject = view.m_oOids.find(vlan->getOid());

if (vlanObject == view.m_oOids.end())
continue;

auto vlanId = vlanObject->second->tryGetSaiAttr(SAI_VLAN_ATTR_VLAN_ID);

if (vlanId != nullptr)
vlanIds.push_back(vlanId->getSaiAttr()->value.u16);
}

std::sort(vlanIds.begin(), vlanIds.end());

return vlanIds;
};

auto temporaryVlanIds = getVlanIds(m_temporaryView, temporaryObj->getVid());

if (temporaryVlanIds.empty())
return nullptr;

std::shared_ptr<SaiObj> match = nullptr;

for (const auto& candidate: candidateObjects)
{
if (getVlanIds(m_currentView, candidate.obj->getVid()) != temporaryVlanIds)
continue;

if (match != nullptr)
return nullptr;

match = candidate.obj;
}

if (match != nullptr)
{
SWSS_LOG_NOTICE("matched virtual router %s to %s by VLAN interfaces",
temporaryObj->m_str_object_id.c_str(),
match->m_str_object_id.c_str());
}

return match;
}

std::shared_ptr<SaiObj> BestCandidateFinder::findCurrentBestMatchForLag(
_In_ const std::shared_ptr<const SaiObj> &temporaryObj,
_In_ const std::vector<sai_object_compare_info_t> &candidateObjects)
Expand Down Expand Up @@ -1496,6 +1565,10 @@ std::shared_ptr<SaiObj> BestCandidateFinder::findCurrentBestMatchForGenericObjec

switch (temporaryObj->getObjectType())
{
case SAI_OBJECT_TYPE_VIRTUAL_ROUTER:
candidate = findCurrentBestMatchForVirtualRouter(temporaryObj, candidateObjects);
break;

case SAI_OBJECT_TYPE_LAG:
candidate = findCurrentBestMatchForLag(temporaryObj, candidateObjects);
break;
Expand Down
4 changes: 4 additions & 0 deletions syncd/BestCandidateFinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ namespace syncd
_In_ const std::shared_ptr<const SaiObj> &temporaryObj,
_In_ const std::vector<sai_object_compare_info_t> &candidateObjects);

std::shared_ptr<SaiObj> findCurrentBestMatchForVirtualRouter(
_In_ const std::shared_ptr<const SaiObj> &temporaryObj,
_In_ const std::vector<sai_object_compare_info_t> &candidateObjects);

std::shared_ptr<SaiObj> findCurrentBestMatchForNextHopGroup(
_In_ const std::shared_ptr<const SaiObj> &temporaryObj,
_In_ const std::vector<sai_object_compare_info_t> &candidateObjects);
Expand Down
105 changes: 105 additions & 0 deletions unittest/syncd/TestBestCandidateFinder.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "BestCandidateFinder.h"
#include "MockableSaiSwitchInterface.h"

#include "meta/sai_serialize.h"

#include <gtest/gtest.h>

using namespace syncd;
Expand All @@ -21,3 +23,106 @@
auto attr = BestCandidateFinder::getSaiAttrFromDefaultValue(av, sw, *meta);
EXPECT_NE(attr, nullptr);
}

TEST(BestCandidateFinder, matchVirtualRoutersByVlanInterfaces)
Comment thread
YairRaviv marked this conversation as resolved.
Dismissed
{
const sai_object_id_t switchId = 0x21000000000000;
const sai_object_id_t currentVrf1 = 0x3000000000001;
const sai_object_id_t currentVrf2 = 0x3000000000002;
const sai_object_id_t temporaryVrf1 = 0x3000000000101;
const sai_object_id_t temporaryVrf2 = 0x3000000000102;
const sai_object_id_t currentVlan1 = 0x26000000000001;
const sai_object_id_t currentVlan2 = 0x26000000000002;
const sai_object_id_t currentVlan3 = 0x26000000000003;
const sai_object_id_t currentVlan4 = 0x26000000000004;
const sai_object_id_t temporaryVlan1 = 0x26000000000101;
const sai_object_id_t temporaryVlan2 = 0x26000000000102;
const sai_object_id_t temporaryVlan3 = 0x26000000000103;
const sai_object_id_t temporaryVlan4 = 0x26000000000104;
const sai_object_id_t currentRif1 = 0x6000000000001;
const sai_object_id_t currentRif2 = 0x6000000000002;
const sai_object_id_t currentRif3 = 0x6000000000003;
const sai_object_id_t currentRif4 = 0x6000000000004;
const sai_object_id_t temporaryRif1 = 0x6000000000101;
const sai_object_id_t temporaryRif2 = 0x6000000000102;
const sai_object_id_t temporaryRif3 = 0x6000000000103;
const sai_object_id_t temporaryRif4 = 0x6000000000104;

auto key = [](const std::string& objectType, sai_object_id_t objectId)
{
return objectType + ":" + sai_serialize_object_id(objectId);
};

swss::TableDump current = {
{ key("SAI_OBJECT_TYPE_SWITCH", switchId), {} },
{ key("SAI_OBJECT_TYPE_VIRTUAL_ROUTER", currentVrf1), {} },
{ key("SAI_OBJECT_TYPE_VIRTUAL_ROUTER", currentVrf2), {} },
{ key("SAI_OBJECT_TYPE_VLAN", currentVlan1),
{ { "SAI_VLAN_ATTR_VLAN_ID", "1001" } } },
{ key("SAI_OBJECT_TYPE_VLAN", currentVlan2),
{ { "SAI_VLAN_ATTR_VLAN_ID", "1002" } } },
{ key("SAI_OBJECT_TYPE_VLAN", currentVlan3),
{ { "SAI_VLAN_ATTR_VLAN_ID", "2001" } } },
{ key("SAI_OBJECT_TYPE_VLAN", currentVlan4),
{ { "SAI_VLAN_ATTR_VLAN_ID", "2002" } } },
{ key("SAI_OBJECT_TYPE_ROUTER_INTERFACE", currentRif1), {
{ "SAI_ROUTER_INTERFACE_ATTR_TYPE", "SAI_ROUTER_INTERFACE_TYPE_VLAN" },
{ "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID", sai_serialize_object_id(currentVrf1) },
{ "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID", sai_serialize_object_id(currentVlan1) } } },
{ key("SAI_OBJECT_TYPE_ROUTER_INTERFACE", currentRif2), {
{ "SAI_ROUTER_INTERFACE_ATTR_TYPE", "SAI_ROUTER_INTERFACE_TYPE_VLAN" },
{ "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID", sai_serialize_object_id(currentVrf1) },
{ "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID", sai_serialize_object_id(currentVlan2) } } },
{ key("SAI_OBJECT_TYPE_ROUTER_INTERFACE", currentRif3), {
{ "SAI_ROUTER_INTERFACE_ATTR_TYPE", "SAI_ROUTER_INTERFACE_TYPE_VLAN" },
{ "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID", sai_serialize_object_id(currentVrf2) },
{ "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID", sai_serialize_object_id(currentVlan3) } } },
{ key("SAI_OBJECT_TYPE_ROUTER_INTERFACE", currentRif4), {
{ "SAI_ROUTER_INTERFACE_ATTR_TYPE", "SAI_ROUTER_INTERFACE_TYPE_VLAN" },
{ "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID", sai_serialize_object_id(currentVrf2) },
{ "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID", sai_serialize_object_id(currentVlan4) } } },
};

swss::TableDump temporary = {
{ key("SAI_OBJECT_TYPE_SWITCH", switchId), {} },
{ key("SAI_OBJECT_TYPE_VIRTUAL_ROUTER", temporaryVrf1), {} },
{ key("SAI_OBJECT_TYPE_VIRTUAL_ROUTER", temporaryVrf2), {} },
{ key("SAI_OBJECT_TYPE_VLAN", temporaryVlan1),
{ { "SAI_VLAN_ATTR_VLAN_ID", "1001" } } },
{ key("SAI_OBJECT_TYPE_VLAN", temporaryVlan2),
{ { "SAI_VLAN_ATTR_VLAN_ID", "1002" } } },
{ key("SAI_OBJECT_TYPE_VLAN", temporaryVlan3),
{ { "SAI_VLAN_ATTR_VLAN_ID", "2001" } } },
{ key("SAI_OBJECT_TYPE_VLAN", temporaryVlan4),
{ { "SAI_VLAN_ATTR_VLAN_ID", "2002" } } },
{ key("SAI_OBJECT_TYPE_ROUTER_INTERFACE", temporaryRif1), {
{ "SAI_ROUTER_INTERFACE_ATTR_TYPE", "SAI_ROUTER_INTERFACE_TYPE_VLAN" },
{ "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID", sai_serialize_object_id(temporaryVrf1) },
{ "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID", sai_serialize_object_id(temporaryVlan4) } } },
{ key("SAI_OBJECT_TYPE_ROUTER_INTERFACE", temporaryRif2), {
{ "SAI_ROUTER_INTERFACE_ATTR_TYPE", "SAI_ROUTER_INTERFACE_TYPE_VLAN" },
{ "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID", sai_serialize_object_id(temporaryVrf1) },
{ "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID", sai_serialize_object_id(temporaryVlan3) } } },
{ key("SAI_OBJECT_TYPE_ROUTER_INTERFACE", temporaryRif3), {
{ "SAI_ROUTER_INTERFACE_ATTR_TYPE", "SAI_ROUTER_INTERFACE_TYPE_VLAN" },
{ "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID", sai_serialize_object_id(temporaryVrf2) },
{ "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID", sai_serialize_object_id(temporaryVlan2) } } },
{ key("SAI_OBJECT_TYPE_ROUTER_INTERFACE", temporaryRif4), {
{ "SAI_ROUTER_INTERFACE_ATTR_TYPE", "SAI_ROUTER_INTERFACE_TYPE_VLAN" },
{ "SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID", sai_serialize_object_id(temporaryVrf2) },
{ "SAI_ROUTER_INTERFACE_ATTR_VLAN_ID", sai_serialize_object_id(temporaryVlan1) } } },
};

AsicView currentView(current);
AsicView temporaryView(temporary);
auto sw = std::make_shared<MockableSaiSwitchInterface>(0, 0);
BestCandidateFinder finder(currentView, temporaryView, sw);

auto match1 = finder.findCurrentBestMatch(temporaryView.m_oOids.at(temporaryVrf1));
auto match2 = finder.findCurrentBestMatch(temporaryView.m_oOids.at(temporaryVrf2));

ASSERT_NE(match1, nullptr);
ASSERT_NE(match2, nullptr);
EXPECT_EQ(match1->getVid(), currentVrf2);
EXPECT_EQ(match2->getVid(), currentVrf1);
}
Loading