Skip to content

Commit

Permalink
[vnetorch]: Add VNET interface removal flow for Bitmap VNET implement… (
Browse files Browse the repository at this point in the history
sonic-net#820)

* [vnetorch]: Add VNET interface removal flow for Bitmap VNET implementation

* Fix review comments

Signed-off-by: Volodymyr Samotiy <volodymyrs@mellanox.com>
  • Loading branch information
Volodymyr Samotiy authored and prsunny committed Apr 18, 2019
1 parent f8be024 commit a64f9ad
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 29 deletions.
97 changes: 73 additions & 24 deletions orchagent/intfsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,46 @@ bool IntfsOrch::setIntf(const string& alias, sai_object_id_t vrf_id, const IpPre
return true;
}

bool IntfsOrch::removeIntf(const string& alias, sai_object_id_t vrf_id, const IpPrefix *ip_prefix)
{
SWSS_LOG_ENTER();

Port port;
if (!gPortsOrch->getPort(alias, port))
{
return false;
}

if (ip_prefix && m_syncdIntfses[alias].ip_addresses.count(*ip_prefix))
{
removeSubnetRoute(port, *ip_prefix);
removeIp2MeRoute(vrf_id, *ip_prefix);

if(port.m_type == Port::VLAN)
{
removeDirectedBroadcast(port, *ip_prefix);
}

m_syncdIntfses[alias].ip_addresses.erase(*ip_prefix);
}

/* Remove router interface that no IP addresses are associated with */
if (m_syncdIntfses[alias].ip_addresses.size() == 0)
{
if (removeRouterIntfs(port))
{
m_syncdIntfses.erase(alias);
return true;
}
else
{
return false;
}
}

return true;
}

void IntfsOrch::doTask(Consumer &consumer)
{
SWSS_LOG_ENTER();
Expand Down Expand Up @@ -379,41 +419,50 @@ void IntfsOrch::doTask(Consumer &consumer)
continue;
}

vrf_id = port.m_vr_id;
if (m_syncdIntfses.find(alias) != m_syncdIntfses.end())
if (m_syncdIntfses.find(alias) == m_syncdIntfses.end())
{
if (m_syncdIntfses[alias].ip_addresses.count(ip_prefix))
{
removeSubnetRoute(port, ip_prefix);
removeIp2MeRoute(vrf_id, ip_prefix);
/* Cannot locate the interface */
it = consumer.m_toSync.erase(it);
continue;
}

if(port.m_type == Port::VLAN)
{
removeDirectedBroadcast(port, ip_prefix);
}
if (m_vnetInfses.find(alias) != m_vnetInfses.end())
{
vnet_name = m_vnetInfses.at(alias);
}

m_syncdIntfses[alias].ip_addresses.erase(ip_prefix);
if (!vnet_name.empty())
{
VNetOrch* vnet_orch = gDirectory.get<VNetOrch*>();
if (!vnet_orch->isVnetExists(vnet_name))
{
it++;
continue;
}

/* Remove router interface that no IP addresses are associated with */
if (m_syncdIntfses[alias].ip_addresses.size() == 0)
if (vnet_orch->delIntf(alias, vnet_name, ip_prefix_in_key ? &ip_prefix : nullptr))
{
if (removeRouterIntfs(port))
{
m_syncdIntfses.erase(alias);
it = consumer.m_toSync.erase(it);
}
else
it++;
m_vnetInfses.erase(alias);
it = consumer.m_toSync.erase(it);
}
else
{
it = consumer.m_toSync.erase(it);
it++;
continue;
}
}
else
/* Cannot locate the interface */
it = consumer.m_toSync.erase(it);
{
if (removeIntf(alias, port.m_vr_id, ip_prefix_in_key ? &ip_prefix : nullptr))
{
it = consumer.m_toSync.erase(it);
}
else
{
it++;
continue;
}
}
}
}
}
Expand Down Expand Up @@ -833,4 +882,4 @@ void IntfsOrch::doTask(SelectableTimer &timer)
++it;
}
}
}
}
1 change: 1 addition & 0 deletions orchagent/intfsorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class IntfsOrch : public Orch
void removeRifFromFlexCounter(const string&, const string&);

bool setIntf(const string& alias, sai_object_id_t vrf_id = gVirtualRouterId, const IpPrefix *ip_prefix = nullptr);
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);
void removeIp2MeRoute(sai_object_id_t vrf_id, const IpPrefix &ip_prefix);
Expand Down
117 changes: 112 additions & 5 deletions orchagent/vnetorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -640,12 +640,18 @@ bool VNetBitmapObject::addIntf(const string& alias, const IpPrefix *prefix)

if (gIntfsOrch->getSyncdIntfses().find(alias) == gIntfsOrch->getSyncdIntfses().end())
{
if (intfMap_.find(alias) != intfMap_.end())
{
SWSS_LOG_ERROR("VNET '%s' interface '%s' already exists", getVnetName().c_str(), alias.c_str());
return false;
}

if (!gIntfsOrch->setIntf(alias, gVirtualRouterId, nullptr))
{
return false;
}

sai_object_id_t vnetTableEntryId;
VnetIntfInfo intfInfo;

attr.id = SAI_TABLE_BITMAP_CLASSIFICATION_ENTRY_ATTR_ACTION;
attr.value.s32 = SAI_TABLE_BITMAP_CLASSIFICATION_ENTRY_ACTION_SET_METADATA;
Expand All @@ -660,7 +666,7 @@ bool VNetBitmapObject::addIntf(const string& alias, const IpPrefix *prefix)
vnet_attrs.push_back(attr);

status = sai_bmtor_api->create_table_bitmap_classification_entry(
&vnetTableEntryId,
&intfInfo.vnetTableEntryId,
gSwitchId,
(uint32_t)vnet_attrs.size(),
vnet_attrs.data());
Expand All @@ -670,11 +676,23 @@ bool VNetBitmapObject::addIntf(const string& alias, const IpPrefix *prefix)
SWSS_LOG_ERROR("Failed to create VNET table entry, SAI rc: %d", status);
throw std::runtime_error("VNet interface creation failed");
}

intfMap_.emplace(alias, intfInfo);
}

if (prefix)
{
sai_object_id_t tunnelRouteTableEntryId;
auto& intf = intfMap_.at(alias);

if (intf.pfxMap.find(*prefix) != intf.pfxMap.end())
{
SWSS_LOG_WARN("VNET '%s' interface '%s' prefix '%s' already exists",
getVnetName().c_str(), alias.c_str(), prefix->getIp().to_string().c_str());
return true;
}

RouteInfo intfPfxInfo;

sai_ip_prefix_t saiPrefix;
copy(saiPrefix, *prefix);

Expand All @@ -684,8 +702,9 @@ bool VNetBitmapObject::addIntf(const string& alias, const IpPrefix *prefix)
attr.value.s32 = SAI_TABLE_BITMAP_ROUTER_ENTRY_ACTION_TO_LOCAL;
route_attrs.push_back(attr);

intfPfxInfo.offset = getFreeTunnelRouteTableOffset();
attr.id = SAI_TABLE_BITMAP_ROUTER_ENTRY_ATTR_PRIORITY;
attr.value.u32 = getFreeTunnelRouteTableOffset();
attr.value.u32 = intfPfxInfo.offset;
route_attrs.push_back(attr);

attr.id = SAI_TABLE_BITMAP_ROUTER_ENTRY_ATTR_IN_RIF_METADATA_KEY;
Expand All @@ -705,7 +724,7 @@ bool VNetBitmapObject::addIntf(const string& alias, const IpPrefix *prefix)
route_attrs.push_back(attr);

status = sai_bmtor_api->create_table_bitmap_router_entry(
&tunnelRouteTableEntryId,
&intfPfxInfo.routeTableEntryId,
gSwitchId,
(uint32_t)route_attrs.size(),
route_attrs.data());
Expand All @@ -715,6 +734,67 @@ bool VNetBitmapObject::addIntf(const string& alias, const IpPrefix *prefix)
SWSS_LOG_ERROR("Failed to create local VNET route entry, SAI rc: %d", status);
throw std::runtime_error("VNet interface creation failed");
}

intf.pfxMap.emplace(*prefix, intfPfxInfo);
}

return true;
}

bool VNetBitmapObject::removeIntf(const string& alias, const IpPrefix *prefix)
{
SWSS_LOG_ENTER();

sai_status_t status;

if (intfMap_.find(alias) == intfMap_.end())
{
SWSS_LOG_ERROR("VNET '%s' interface '%s' doesn't exist", getVnetName().c_str(), alias.c_str());
return false;
}

auto& intf = intfMap_.at(alias);

if (prefix)
{
if (intf.pfxMap.find(*prefix) == intf.pfxMap.end())
{
SWSS_LOG_ERROR("VNET '%s' interface '%s' prefix '%s' doesn't exist",
getVnetName().c_str(), alias.c_str(), prefix->getIp().to_string().c_str());
return true;
}

auto& pfx = intf.pfxMap.at(*prefix);

status = sai_bmtor_api->remove_table_bitmap_router_entry(pfx.routeTableEntryId);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to remove VNET local route entry, SAI rc: %d", status);
throw std::runtime_error("VNET interface removal failed");
}

gIntfsOrch->removeIp2MeRoute(gVirtualRouterId, *prefix);

recycleTunnelRouteTableOffset(pfx.offset);

intf.pfxMap.erase(*prefix);
}

if (intf.pfxMap.size() == 0)
{
status = sai_bmtor_api->remove_table_bitmap_classification_entry(intf.vnetTableEntryId);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_ERROR("Failed to remove VNET table entry, SAI rc: %d", status);
throw std::runtime_error("VNET interface removal failed");
}

intfMap_.erase(alias);

if (!gIntfsOrch->removeIntf(alias, gVirtualRouterId, nullptr))
{
return false;
}
}

return true;
Expand Down Expand Up @@ -1164,6 +1244,33 @@ bool VNetOrch::setIntf(const string& alias, const string name, const IpPrefix *p

return false;
}

bool VNetOrch::delIntf(const string& alias, const string name, const IpPrefix *prefix)
{
SWSS_LOG_ENTER();

if (!isVnetExists(name))
{
SWSS_LOG_WARN("VNET %s doesn't exist", name.c_str());
return false;
}

if (isVnetExecVrf())
{
auto *vnet_obj = getTypePtr<VNetVrfObject>(name);
sai_object_id_t vrf_id = vnet_obj->getVRidIngress();

return gIntfsOrch->removeIntf(alias, vrf_id, prefix);
}
else
{
auto *vnet_obj = getTypePtr<VNetBitmapObject>(name);
return vnet_obj->removeIntf(alias, prefix);
}

return true;
}

bool VNetOrch::addOperation(const Request& request)
{
SWSS_LOG_ENTER();
Expand Down
9 changes: 9 additions & 0 deletions orchagent/vnetorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,19 @@ struct RouteInfo
uint32_t offset;
};

struct VnetIntfInfo
{
sai_object_id_t vnetTableEntryId;
map<IpPrefix, RouteInfo> pfxMap;
};

class VNetBitmapObject: public VNetObject
{
public:
VNetBitmapObject(const string& vnet, const VNetInfo& vnetInfo, vector<sai_attribute_t>& attrs);

bool addIntf(const string& alias, const IpPrefix *prefix);
bool removeIntf(const string& alias, const IpPrefix *prefix);

bool addTunnelRoute(IpPrefix& ipPrefix, tunnelEndpoint& endp);
bool removeTunnelRoute(IpPrefix& ipPrefix);
Expand Down Expand Up @@ -247,6 +254,7 @@ class VNetBitmapObject: public VNetObject

map<IpPrefix, RouteInfo> routeMap_;
map<IpPrefix, TunnelRouteInfo> tunnelRouteMap_;
map<string, VnetIntfInfo> intfMap_;

uint32_t vnet_id_;
string vnet_name_;
Expand All @@ -262,6 +270,7 @@ class VNetOrch : public Orch2
VNetOrch(DBConnector *db, const std::string&, VNET_EXEC op = VNET_EXEC::VNET_EXEC_VRF);

bool setIntf(const string& alias, const string name, const IpPrefix *prefix = nullptr);
bool delIntf(const string& alias, const string name, const IpPrefix *prefix = nullptr);

bool isVnetExists(const std::string& name) const
{
Expand Down

0 comments on commit a64f9ad

Please sign in to comment.