in syncd/BestCandidateFinder.cpp [652:844]
std::shared_ptr<SaiObj> BestCandidateFinder::findCurrentBestMatchForRouterInterface(
_In_ const std::shared_ptr<const SaiObj> &temporaryObj,
_In_ const std::vector<sai_object_compare_info_t> &candidateObjects)
{
SWSS_LOG_ENTER();
/*
* For router interface which is LOOPBACK, we could trace them to TUNNEL
* object on which they are used. It could be not obvious, when multiple
* tunnels will be used.
*/
const auto typeAttr = temporaryObj->getSaiAttr(SAI_ROUTER_INTERFACE_ATTR_TYPE);
if (typeAttr->getSaiAttr()->value.s32 != SAI_ROUTER_INTERFACE_TYPE_LOOPBACK)
{
SWSS_LOG_WARN("RIF %s is not LOOPBACK", temporaryObj->m_str_object_id.c_str());
return nullptr;
}
const auto tmpTunnels = m_temporaryView.getNotProcessedObjectsByObjectType(SAI_OBJECT_TYPE_TUNNEL);
for (auto tmpTunnel: tmpTunnels)
{
/*
* Try match tunnel by src encap IP address.
*/
if (!tmpTunnel->hasAttr(SAI_TUNNEL_ATTR_ENCAP_SRC_IP))
{
// not encap src attribute, skip
continue;
}
const std::string tmpSrcIP = tmpTunnel->getSaiAttr(SAI_TUNNEL_ATTR_ENCAP_SRC_IP)->getStrAttrValue();
const auto curTunnels = m_currentView.getNotProcessedObjectsByObjectType(SAI_OBJECT_TYPE_TUNNEL);
for (auto curTunnel: curTunnels)
{
if (!tmpTunnel->hasAttr(SAI_TUNNEL_ATTR_ENCAP_SRC_IP))
{
// not encap src attribute, skip
continue;
}
const std::string curSrcIP = tmpTunnel->getSaiAttr(SAI_TUNNEL_ATTR_ENCAP_SRC_IP)->getStrAttrValue();
if (curSrcIP != tmpSrcIP)
{
continue;
}
/*
* At this point we have both tunnels which ip matches.
*/
if (tmpTunnel->hasAttr(SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE) &&
curTunnel->hasAttr(SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE))
{
auto tmpRif = tmpTunnel->getSaiAttr(SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE);
auto curRif = curTunnel->getSaiAttr(SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE);
if (tmpRif->getSaiAttr()->value.oid == temporaryObj->getVid())
{
for (auto c: candidateObjects)
{
if (c.obj->getVid() != curRif->getSaiAttr()->value.oid)
continue;
SWSS_LOG_INFO("found best ROUTER_INTERFACE based on TUNNEL underlay interface %s", c.obj->m_str_object_id.c_str());
return c.obj;
}
}
}
if (tmpTunnel->hasAttr(SAI_TUNNEL_ATTR_OVERLAY_INTERFACE) &&
curTunnel->hasAttr(SAI_TUNNEL_ATTR_OVERLAY_INTERFACE))
{
auto tmpRif = tmpTunnel->getSaiAttr(SAI_TUNNEL_ATTR_OVERLAY_INTERFACE);
auto curRif = curTunnel->getSaiAttr(SAI_TUNNEL_ATTR_OVERLAY_INTERFACE);
if (tmpRif->getSaiAttr()->value.oid == temporaryObj->getVid())
{
for (auto c: candidateObjects)
{
if (c.obj->getVid() != curRif->getSaiAttr()->value.oid)
continue;
SWSS_LOG_INFO("found best ROUTER_INTERFACE based on TUNNEL overlay interface %s", c.obj->m_str_object_id.c_str());
return c.obj;
}
}
}
}
}
// try find tunnel by TUNNEL_TERM_TABLE_ENTRY using SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_DST_IP
for (auto tmpTunnel: tmpTunnels)
{
const auto curTunnels = m_currentView.getNotProcessedObjectsByObjectType(SAI_OBJECT_TYPE_TUNNEL);
for (auto curTunnel: curTunnels)
{
const auto tmpTunnelTermTableEtnries = m_temporaryView.getNotProcessedObjectsByObjectType(SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY);
for (auto tmpTunnelTermTableEntry: tmpTunnelTermTableEtnries)
{
auto tmpTunnelId = tmpTunnelTermTableEntry->tryGetSaiAttr(SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_ACTION_TUNNEL_ID);
if (tmpTunnelId == nullptr)
continue;
auto tmpDstIp = tmpTunnelTermTableEntry->tryGetSaiAttr(SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_DST_IP);
if (tmpDstIp == nullptr)
continue;
if (tmpTunnelId->getOid() != tmpTunnel->getVid()) // not this tunnel
continue;
const auto curTunnelTermTableEtnries = m_currentView.getNotProcessedObjectsByObjectType(SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY);
for (auto curTunnelTermTableEntry: curTunnelTermTableEtnries)
{
auto curTunnelId = curTunnelTermTableEntry->tryGetSaiAttr(SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_ACTION_TUNNEL_ID);
if (curTunnelId == nullptr)
continue;
auto curDstIp = curTunnelTermTableEntry->tryGetSaiAttr(SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_DST_IP);
if (curDstIp == nullptr)
continue;
if (curTunnelId->getOid() != curTunnel->getVid()) // not this tunnel
continue;
if (curDstIp->getStrAttrValue() != tmpDstIp->getStrAttrValue())
continue;
if (tmpTunnel->hasAttr(SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE) &&
curTunnel->hasAttr(SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE))
{
auto tmpRif = tmpTunnel->getSaiAttr(SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE);
auto curRif = curTunnel->getSaiAttr(SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE);
if (tmpRif->getSaiAttr()->value.oid == temporaryObj->getVid())
{
for (auto c: candidateObjects)
{
if (c.obj->getVid() != curRif->getSaiAttr()->value.oid)
continue;
SWSS_LOG_INFO("found best ROUTER_INTERFACE based on TUNNEL underlay interface %s", c.obj->m_str_object_id.c_str());
return c.obj;
}
}
}
if (tmpTunnel->hasAttr(SAI_TUNNEL_ATTR_OVERLAY_INTERFACE) &&
curTunnel->hasAttr(SAI_TUNNEL_ATTR_OVERLAY_INTERFACE))
{
auto tmpRif = tmpTunnel->getSaiAttr(SAI_TUNNEL_ATTR_OVERLAY_INTERFACE);
auto curRif = curTunnel->getSaiAttr(SAI_TUNNEL_ATTR_OVERLAY_INTERFACE);
if (tmpRif->getSaiAttr()->value.oid == temporaryObj->getVid())
{
for (auto c: candidateObjects)
{
if (c.obj->getVid() != curRif->getSaiAttr()->value.oid)
continue;
SWSS_LOG_INFO("found best ROUTER_INTERFACE based on TUNNEL overlay interface %s", c.obj->m_str_object_id.c_str());
return c.obj;
}
}
}
}
}
}
}
SWSS_LOG_NOTICE("failed to find best candidate for LOOPBACK ROUTER_INTERFACE using tunnel");
return nullptr;
}