Skip to content
Closed
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
150 changes: 129 additions & 21 deletions orchagent/intfsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ sai_object_id_t IntfsOrch::getRouterIntfsId(const string &alias)
return port.m_rif_id;
}

sai_object_id_t IntfsOrch::getRouterIntfsIdForNewDependency(const string &alias)
{
if (m_removingIntfses.find(alias) != m_removingIntfses.end() ||
m_pendingVrfUpdates.find(alias) != m_pendingVrfUpdates.end())
{
return SAI_NULL_OBJECT_ID;
}

return getRouterIntfsId(alias);
}

bool IntfsOrch::isPrefixSubnet(const IpPrefix &ip_prefix, const string &alias)
{
if (m_syncdIntfses.find(alias) == m_syncdIntfses.end())
Expand Down Expand Up @@ -477,7 +488,8 @@ set<IpPrefix> IntfsOrch:: getSubnetRoutes()
}

bool IntfsOrch::setIntf(const string& alias, sai_object_id_t vrf_id, const IpPrefix *ip_prefix,
const bool adminUp, const uint32_t mtu, string loopbackAction)
const bool adminUp, const uint32_t mtu, string loopbackAction,
const bool vrfIdIsExplicit)

{
SWSS_LOG_ENTER();
Expand All @@ -487,6 +499,11 @@ bool IntfsOrch::setIntf(const string& alias, sai_object_id_t vrf_id, const IpPre
return false;
}

if (ip_prefix && m_pendingVrfUpdates.find(alias) != m_pendingVrfUpdates.end())
{
return false;
}

Port port;
gPortsOrch->getPort(alias, port);

Expand All @@ -500,8 +517,18 @@ bool IntfsOrch::setIntf(const string& alias, sai_object_id_t vrf_id, const IpPre
intfs_entry.ref_count = 0;
intfs_entry.proxy_arp = false;
intfs_entry.vrf_id = vrf_id;
if (port.m_mac)
{
intfs_entry.mac = port.m_mac;
}
else
{
intfs_entry.mac = gMacAddress;
}
intfs_entry.loopback_action = loopbackAction;
m_syncdIntfses[alias] = intfs_entry;
m_vrfOrch->increaseVrfRefCount(vrf_id);
m_pendingVrfUpdates.erase(alias);
}
else
{
Expand All @@ -510,30 +537,94 @@ bool IntfsOrch::setIntf(const string& alias, sai_object_id_t vrf_id, const IpPre
}
else
{
if (!ip_prefix && port.m_type == Port::SUBPORT)
// Treat an explicit VRF change as a RIF replacement and retain the SET
// until the old interface has no prefixes or dependent objects.
sai_object_id_t old_vrf_id = it_intfs->second.vrf_id;
if (!ip_prefix && vrfIdIsExplicit && old_vrf_id != vrf_id)
{
// port represents a sub interface
// Change sub interface config at run time
bool attrChanged = false;
if (mtu && port.m_mtu != mtu)
m_pendingVrfUpdates.insert(alias);
if (!it_intfs->second.ip_addresses.empty())
{
port.m_mtu = mtu;
attrChanged = true;
return false;
}

setRouterIntfsMtu(port);
IntfsEntry intfs_entry = it_intfs->second;
Port rehome_port = port;
rehome_port.m_mac = intfs_entry.mac;
if (rehome_port.m_type == Port::SUBPORT)
{
rehome_port.m_admin_state_up = adminUp;
if (mtu)
{
rehome_port.m_mtu = mtu;
}
}
if (!removeRouterIntfs(port))
{
return false;
}

if (port.m_admin_state_up != adminUp)
rehome_port.m_rif_id = SAI_NULL_OBJECT_ID;
rehome_port.m_vr_id = SAI_NULL_OBJECT_ID;
string rehome_loopback_action = loopbackAction.empty() ?
intfs_entry.loopback_action :
loopbackAction;
try
{
port.m_admin_state_up = adminUp;
attrChanged = true;
if (!addRouterIntfs(vrf_id, rehome_port, rehome_loopback_action))
{
return false;
}
}
catch (const std::exception&)
{
Port rollback_port = rehome_port;
rollback_port.m_rif_id = SAI_NULL_OBJECT_ID;
rollback_port.m_vr_id = SAI_NULL_OBJECT_ID;
addRouterIntfs(old_vrf_id, rollback_port, intfs_entry.loopback_action);
throw;
}

setRouterIntfsAdminStatus(port);
m_vrfOrch->decreaseVrfRefCount(old_vrf_id);
m_vrfOrch->increaseVrfRefCount(vrf_id);
intfs_entry.vrf_id = vrf_id;
intfs_entry.loopback_action = rehome_loopback_action;
m_syncdIntfses[alias] = intfs_entry;

m_pendingVrfUpdates.erase(alias);
}
else if (!ip_prefix)
{
if (vrfIdIsExplicit)
{
m_pendingVrfUpdates.erase(alias);
}

if (attrChanged)
if (port.m_type == Port::SUBPORT)
{
gPortsOrch->setPort(alias, port);
// port represents a sub interface
// Change sub interface config at run time
bool attrChanged = false;
if (mtu && port.m_mtu != mtu)
{
port.m_mtu = mtu;
attrChanged = true;

setRouterIntfsMtu(port);
}

if (port.m_admin_state_up != adminUp)
{
port.m_admin_state_up = adminUp;
attrChanged = true;

setRouterIntfsAdminStatus(port);
}

if (attrChanged)
{
gPortsOrch->setPort(alias, port);
}
}
}
}
Expand Down Expand Up @@ -638,6 +729,7 @@ bool IntfsOrch::removeIntf(const string& alias, sai_object_id_t vrf_id, const Ip
gPortsOrch->decreasePortRefCount(alias);
m_syncdIntfses.erase(alias);
m_vrfOrch->decreaseVrfRefCount(vrf_id);
m_pendingVrfUpdates.erase(alias);

if (port.m_type == Port::SUBPORT)
{
Expand Down Expand Up @@ -705,6 +797,8 @@ void IntfsOrch::doTask(Consumer &consumer)

const vector<FieldValueTuple>& data = kfvFieldsValues(t);
string vrf_name = "", vnet_name = "", nat_zone = "";
bool vrfNameIsExplicit = false;
bool mplsIsExplicit = false;
MacAddress mac;

uint32_t mtu = 0;
Expand All @@ -724,6 +818,7 @@ void IntfsOrch::doTask(Consumer &consumer)
if (field == "vrf_name")
{
vrf_name = value;
vrfNameIsExplicit = true;
}
else if (field == "vnet_name")
{
Expand All @@ -744,6 +839,7 @@ void IntfsOrch::doTask(Consumer &consumer)
else if (field == "mpls")
{
mpls = (value == "enable" ? true : false);
mplsIsExplicit = true;
}
else if (field == "nat_zone")
{
Expand Down Expand Up @@ -962,7 +1058,8 @@ void IntfsOrch::doTask(Consumer &consumer)
adminUp = port.m_admin_state_up;
}

if (!setIntf(alias, vrf_id, ip_prefix_in_key ? &ip_prefix : nullptr, adminUp, mtu, loopbackAction))
if (!setIntf(alias, vrf_id, ip_prefix_in_key ? &ip_prefix : nullptr, adminUp, mtu,
loopbackAction, vrfNameIsExplicit))
{
it++;
continue;
Expand All @@ -987,7 +1084,7 @@ void IntfsOrch::doTask(Consumer &consumer)
gPortsOrch->setPort(alias, port);
}
/* Set MPLS */
if ((!ip_prefix_in_key) && (port.m_mpls != mpls))
if (mplsIsExplicit && !ip_prefix_in_key && port.m_mpls != mpls)
{
port.m_mpls = mpls;

Expand All @@ -998,7 +1095,10 @@ void IntfsOrch::doTask(Consumer &consumer)
/* Set loopback action */
if (!loopbackAction.empty())
{
setIntfLoopbackAction(port, loopbackAction);
if (setIntfLoopbackAction(port, loopbackAction))
{
m_syncdIntfses[alias].loopback_action = loopbackAction;
}
}
}
}
Expand Down Expand Up @@ -1028,6 +1128,9 @@ void IntfsOrch::doTask(Consumer &consumer)
{
SWSS_LOG_NOTICE("Set router interface mac %s for port %s success",
mac.to_string().c_str(), port.m_alias.c_str());
m_syncdIntfses[alias].mac = mac;
port.m_mac = mac;
gPortsOrch->setPort(alias, port);
}
}
else
Expand Down Expand Up @@ -1129,12 +1232,18 @@ void IntfsOrch::doTask(Consumer &consumer)
{
if (removeIntf(alias, port.m_vr_id, ip_prefix_in_key ? &ip_prefix : nullptr))
{
m_removingIntfses.erase(alias);
if (!ip_prefix_in_key)
{
m_removingIntfses.erase(alias);
}
it = consumer.m_toSync.erase(it);
}
else
{
m_removingIntfses.insert(alias);
if (!ip_prefix_in_key)
{
m_removingIntfses.insert(alias);
}
it++;
continue;
}
Expand Down Expand Up @@ -1779,4 +1888,3 @@ void IntfsOrch::voqSyncIntfState(string &alias, bool isUp)
}

}

6 changes: 5 additions & 1 deletion orchagent/intfsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ struct IntfsEntry
int ref_count;
sai_object_id_t vrf_id;
bool proxy_arp;
MacAddress mac;
std::string loopback_action;
};

typedef map<string, IntfsEntry> IntfsTable;
Expand All @@ -36,6 +38,7 @@ class IntfsOrch : public Orch
IntfsOrch(DBConnector *db, string tableName, VRFOrch *vrf_orch, DBConnector *chassisAppDb);

sai_object_id_t getRouterIntfsId(const string&);
sai_object_id_t getRouterIntfsIdForNewDependency(const string&);
bool isPrefixSubnet(const IpPrefix&, const string&);
bool isInbandIntfInMgmtVrf(const string& alias);
string getRouterIntfsAlias(const IpAddress &ip, const string &vrf_name = "");
Expand All @@ -57,7 +60,7 @@ class IntfsOrch : public Orch

bool setIntfLoopbackAction(const Port &port, string actionStr);
bool getSaiLoopbackAction(const string &actionStr, sai_packet_action_t &action);
bool setIntf(const string& alias, sai_object_id_t vrf_id = gVirtualRouterId, const IpPrefix *ip_prefix = nullptr, const bool adminUp = true, const uint32_t mtu = 0, string loopbackAction = "");
bool setIntf(const string& alias, sai_object_id_t vrf_id = gVirtualRouterId, const IpPrefix *ip_prefix = nullptr, const bool adminUp = true, const uint32_t mtu = 0, string loopbackAction = "", const bool vrfIdIsExplicit = false);
bool removeIntf(const string& alias, sai_object_id_t vrf_id = gVirtualRouterId, const IpPrefix *ip_prefix = nullptr);

void addIp2MeRoute(sai_object_id_t vrf_id, const IpPrefix &ip_prefix);
Expand Down Expand Up @@ -92,6 +95,7 @@ class IntfsOrch : public Orch
unique_ptr<Table> m_vidToRidTable;

std::set<std::string> m_removingIntfses;
std::set<std::string> m_pendingVrfUpdates;

std::string getRifFlexCounterTableKey(std::string s);

Expand Down
9 changes: 7 additions & 2 deletions orchagent/neighorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,12 @@ bool NeighOrch::addNextHop(NeighborContext& ctx)
}

assert(!hasNextHop(nexthop));
sai_object_id_t rif_id = m_intfsOrch->getRouterIntfsId(nh.alias);
sai_object_id_t rif_id = m_intfsOrch->getRouterIntfsIdForNewDependency(nh.alias);
if (rif_id == SAI_NULL_OBJECT_ID)
{
SWSS_LOG_INFO("Failed to get rif_id for %s", nh.alias.c_str());
return false;
}

vector<sai_attribute_t> next_hop_attrs;

Expand Down Expand Up @@ -1201,7 +1206,7 @@ bool NeighOrch::addNeighbor(NeighborContext& ctx)
string alias = neighborEntry.alias;
bool bulk_op = ctx.bulk_op;

sai_object_id_t rif_id = m_intfsOrch->getRouterIntfsId(alias);
sai_object_id_t rif_id = m_intfsOrch->getRouterIntfsIdForNewDependency(alias);
if (rif_id == SAI_NULL_OBJECT_ID)
{
SWSS_LOG_INFO("Failed to get rif_id for %s", alias.c_str());
Expand Down
12 changes: 9 additions & 3 deletions orchagent/routeorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1515,7 +1515,10 @@ bool RouteOrch::addNextHopGroup(const NextHopGroupKey &nexthops)
m_neighOrch->hasNextHop(NextHopKey(it.ip_address, it.alias)))
{
NeighborContext ctx = NeighborContext(it);
m_neighOrch->addNextHop(ctx);
if (!m_neighOrch->addNextHop(ctx))
{
return false;
}
next_hop_id = m_neighOrch->getNextHopId(it);
}
else
Expand Down Expand Up @@ -2091,7 +2094,7 @@ bool RouteOrch::addRoute(RouteBulkContext& ctx, const NextHopGroupKey &nextHops)
return true;
}

next_hop_id = m_intfsOrch->getRouterIntfsId(nexthop.alias);
next_hop_id = m_intfsOrch->getRouterIntfsIdForNewDependency(nexthop.alias);
/* rif is not created yet */
if (next_hop_id == SAI_NULL_OBJECT_ID)
{
Expand Down Expand Up @@ -2126,7 +2129,10 @@ bool RouteOrch::addRoute(RouteBulkContext& ctx, const NextHopGroupKey &nextHops)
{
/* since IP neighbor NH exists, neighbor is resolved, add MPLS NH */
NeighborContext ctx = NeighborContext(nexthop);
m_neighOrch->addNextHop(ctx);
if (!m_neighOrch->addNextHop(ctx))
{
return false;
}
next_hop_id = m_neighOrch->getNextHopId(nexthop);
}
/* IP neighbor is not yet resolved */
Expand Down
Loading
Loading