Skip to content
Draft
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
167 changes: 144 additions & 23 deletions orchagent/intfsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,16 @@ sai_object_id_t IntfsOrch::getRouterIntfsId(const string &alias)
return port.m_rif_id;
}

bool IntfsOrch::isIntfRemovalPending(const string &alias) const
{
return m_removingIntfses.find(alias) != m_removingIntfses.end();
}

bool IntfsOrch::isIntfVrfUpdatePending(const string &alias) const
{
return m_pendingVrfUpdates.find(alias) != m_pendingVrfUpdates.end();
}

bool IntfsOrch::isPrefixSubnet(const IpPrefix &ip_prefix, const string &alias)
{
if (m_syncdIntfses.find(alias) == m_syncdIntfses.end())
Expand Down Expand Up @@ -478,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 @@ -488,6 +499,11 @@ bool IntfsOrch::setIntf(const string& alias, sai_object_id_t vrf_id, const IpPre
return false;
}

if (ip_prefix && isIntfVrfUpdatePending(alias))
{
return false;
}

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

Expand All @@ -512,8 +528,10 @@ bool IntfsOrch::setIntf(const string& alias, sai_object_id_t vrf_id, const IpPre
{
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 @@ -522,30 +540,107 @@ 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;
}

IntfsEntry intfs_entry = it_intfs->second;
if (intfs_entry.sag_enabled)
{
SWSS_LOG_WARN("Cannot move SAG-enabled interface %s between VRFs", alias.c_str());
return false;
}

setRouterIntfsMtu(port);
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
{
if (!addRouterIntfs(vrf_id, rehome_port, rehome_loopback_action))
{
return false;
}
}
catch (const std::exception& e)
{
port.m_admin_state_up = adminUp;
attrChanged = true;
Port rollback_port = rehome_port;
rollback_port.m_rif_id = SAI_NULL_OBJECT_ID;
rollback_port.m_vr_id = SAI_NULL_OBJECT_ID;
if (!addRouterIntfs(old_vrf_id, rollback_port, intfs_entry.loopback_action))
{
SWSS_LOG_ERROR("Failed to restore interface %s after VRF move failed: %s",
alias.c_str(), e.what());
throw;
}
SWSS_LOG_ERROR("Failed to move interface %s to VRF %s; restored the old RIF and will retry: %s",
alias.c_str(), m_vrfOrch->getVRFname(vrf_id).c_str(), e.what());
return false;
}

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;

setRouterIntfsAdminStatus(port);
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 @@ -658,6 +753,7 @@ bool IntfsOrch::removeIntf(const string& alias, sai_object_id_t vrf_id, const Ip

m_syncdIntfses.erase(alias);
m_vrfOrch->decreaseVrfRefCount(vrf_id);
m_pendingVrfUpdates.erase(alias);

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

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

uint32_t mtu = 0;
Expand Down Expand Up @@ -770,6 +869,7 @@ void IntfsOrch::doTask(Consumer &consumer)
if (field == "vrf_name")
{
vrf_name = value;
vrfNameIsExplicit = true;
}
else if (field == "vnet_name")
{
Expand All @@ -780,6 +880,7 @@ void IntfsOrch::doTask(Consumer &consumer)
try
{
mac = MacAddress(value);
macIsExplicit = true;
}
catch (const std::invalid_argument &e)
{
Expand All @@ -790,6 +891,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 @@ -1011,7 +1113,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 Down Expand Up @@ -1055,7 +1158,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 @@ -1066,18 +1169,21 @@ void IntfsOrch::doTask(Consumer &consumer)
/* Set loopback action */
if (!loopbackAction.empty())
{
setIntfLoopbackAction(port, loopbackAction);
if (setIntfLoopbackAction(port, loopbackAction))
{
m_syncdIntfses[alias].loopback_action = loopbackAction;
}
}
Comment thread
Xichen96 marked this conversation as resolved.
}
}

if (!mac)
if (macIsExplicit && !mac)
{
mac = gMacAddress;
}

// update mac if it is changed
if (m_syncdIntfses.find(alias) != m_syncdIntfses.end())
if (macIsExplicit && m_syncdIntfses.find(alias) != m_syncdIntfses.end())
{
if ((!ip_prefix_in_key) && (m_syncdIntfses[alias].mac != mac))
{
Expand Down Expand Up @@ -1105,6 +1211,8 @@ void IntfsOrch::doTask(Consumer &consumer)
SWSS_LOG_NOTICE("Set router interface mac %s for port %s success",
mac.to_string().c_str(), alias.c_str());
m_syncdIntfses[alias].mac = mac;
port.m_mac = mac;
gPortsOrch->setPort(alias, port);
}
}
else
Expand Down Expand Up @@ -1194,11 +1302,19 @@ void IntfsOrch::doTask(Consumer &consumer)

if (vnet_orch->delIntf(alias, vnet_name, ip_prefix_in_key ? &ip_prefix : nullptr))
{
if (!ip_prefix_in_key)
{
m_removingIntfses.erase(alias);
}
m_vnetInfses.erase(alias);
it = consumer.m_toSync.erase(it);
}
else
{
if (!ip_prefix_in_key)
{
m_removingIntfses.insert(alias);
}
it++;
continue;
}
Expand All @@ -1207,12 +1323,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 @@ -1975,4 +2097,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 @@ -28,6 +28,7 @@ struct IntfsEntry
bool proxy_arp;
bool sag_enabled = false;
MacAddress mac;
std::string loopback_action;
};

typedef map<string, IntfsEntry> IntfsTable;
Expand All @@ -39,6 +40,8 @@ class IntfsOrch : public Orch
static const int intfsorch_pri;

sai_object_id_t getRouterIntfsId(const string&);
bool isIntfRemovalPending(const string&) const;
bool isIntfVrfUpdatePending(const string&) const;
bool isPrefixSubnet(const IpPrefix&, const string&);
bool isInbandIntfInMgmtVrf(const string& alias);
string getRouterIntfsAlias(const IpAddress &ip, const string &vrf_name = "");
Expand All @@ -60,7 +63,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 @@ -99,6 +102,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
17 changes: 17 additions & 0 deletions orchagent/neighorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,14 @@ bool NeighOrch::addNextHop(NeighborContext& ctx)
}

assert(!hasNextHop(nexthop));
if (!m_intfsOrch->isRemoteSystemPortIntf(nh.alias) &&
(m_intfsOrch->isIntfRemovalPending(nh.alias) ||
m_intfsOrch->isIntfVrfUpdatePending(nh.alias)))
{
SWSS_LOG_INFO("Interface %s is pending removal or VRF update", nh.alias.c_str());
return false;
}
Comment thread
Xichen96 marked this conversation as resolved.

sai_object_id_t rif_id = m_intfsOrch->getRouterIntfsId(nh.alias);

vector<sai_attribute_t> next_hop_attrs;
Expand Down Expand Up @@ -1324,6 +1332,14 @@ bool NeighOrch::addNeighbor(NeighborContext& ctx)
string alias = neighborEntry.alias;
bool bulk_op = ctx.bulk_op;

if (!m_intfsOrch->isRemoteSystemPortIntf(alias) &&
(m_intfsOrch->isIntfRemovalPending(alias) ||
m_intfsOrch->isIntfVrfUpdatePending(alias)))
{
SWSS_LOG_INFO("Interface %s is pending removal or VRF update", alias.c_str());
return false;
}

sai_object_id_t rif_id = m_intfsOrch->getRouterIntfsId(alias);
if (rif_id == SAI_NULL_OBJECT_ID)
{
Expand Down Expand Up @@ -2065,6 +2081,7 @@ bool NeighOrch::enableNeighbors(std::list<NeighborContext>& bulk_ctx_list)
if(!addNeighbor(*ctx))
{
SWSS_LOG_ERROR("Neighbor %s create entry failed.", neighborEntry.ip_address.to_string().c_str());
ret = false;
continue;
}
}
Expand Down
Loading
Loading