Skip to content

Commit 217f7f0

Browse files
authored
Cherry pick of #2589 (#2627)
1 parent 96180bf commit 217f7f0

3 files changed

Lines changed: 218 additions & 24 deletions

File tree

orchagent/vnetorch.cpp

Lines changed: 119 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@ bool VNetOrch::addOperation(const Request& request)
425425
uint32_t vni=0;
426426
string tunnel;
427427
string scope;
428+
swss::MacAddress overlay_dmac;
428429

429430
for (const auto& name: request.getAttrFieldNames())
430431
{
@@ -456,6 +457,10 @@ bool VNetOrch::addOperation(const Request& request)
456457
{
457458
advertise_prefix = request.getAttrBool("advertise_prefix");
458459
}
460+
else if (name == "overlay_dmac")
461+
{
462+
overlay_dmac = request.getAttrMacAddress("overlay_dmac");
463+
}
459464
else
460465
{
461466
SWSS_LOG_INFO("Unknown attribute: %s", name.c_str());
@@ -482,7 +487,7 @@ bool VNetOrch::addOperation(const Request& request)
482487

483488
if (it == std::end(vnet_table_))
484489
{
485-
VNetInfo vnet_info = { tunnel, vni, peer_list, scope, advertise_prefix };
490+
VNetInfo vnet_info = { tunnel, vni, peer_list, scope, advertise_prefix, overlay_dmac };
486491
obj = createObject<VNetVrfObject>(vnet_name, vnet_info, attrs);
487492
create = true;
488493

@@ -673,8 +678,11 @@ VNetRouteOrch::VNetRouteOrch(DBConnector *db, vector<string> &tableNames, VNetOr
673678
handler_map_.insert(handler_pair(APP_VNET_RT_TUNNEL_TABLE_NAME, &VNetRouteOrch::handleTunnel));
674679

675680
state_db_ = shared_ptr<DBConnector>(new DBConnector("STATE_DB", 0));
681+
app_db_ = shared_ptr<DBConnector>(new DBConnector("APPL_DB", 0));
682+
676683
state_vnet_rt_tunnel_table_ = unique_ptr<Table>(new Table(state_db_.get(), STATE_VNET_RT_TUNNEL_TABLE_NAME));
677684
state_vnet_rt_adv_table_ = unique_ptr<Table>(new Table(state_db_.get(), STATE_ADVERTISE_NETWORK_TABLE_NAME));
685+
monitor_session_producer_ = unique_ptr<Table>(new Table(app_db_.get(), APP_VNET_MONITOR_TABLE_NAME));
678686

679687
gBfdOrch->attach(this);
680688
}
@@ -843,6 +851,7 @@ bool VNetRouteOrch::removeNextHopGroup(const string& vnet, const NextHopGroupKey
843851
template<>
844852
bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipPrefix,
845853
NextHopGroupKey& nexthops, string& op, string& profile,
854+
const string& monitoring,
846855
const map<NextHopKey, IpAddress>& monitors)
847856
{
848857
SWSS_LOG_ENTER();
@@ -883,7 +892,7 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
883892
sai_object_id_t nh_id;
884893
if (!hasNextHopGroup(vnet, nexthops))
885894
{
886-
setEndpointMonitor(vnet, monitors, nexthops);
895+
setEndpointMonitor(vnet, monitors, nexthops, monitoring, ipPrefix);
887896
if (nexthops.getSize() == 1)
888897
{
889898
NextHopKey nexthop(nexthops.to_string(), true);
@@ -900,7 +909,7 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
900909
{
901910
if (!addNextHopGroup(vnet, nexthops, vrf_obj))
902911
{
903-
delEndpointMonitor(vnet, nexthops);
912+
delEndpointMonitor(vnet, nexthops, ipPrefix);
904913
SWSS_LOG_ERROR("Failed to create next hop group %s", nexthops.to_string().c_str());
905914
return false;
906915
}
@@ -974,7 +983,7 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
974983
NextHopKey nexthop(nhg.to_string(), true);
975984
vrf_obj->removeTunnelNextHop(nexthop);
976985
}
977-
delEndpointMonitor(vnet, nhg);
986+
delEndpointMonitor(vnet, nhg, ipPrefix);
978987
}
979988
else
980989
{
@@ -1034,7 +1043,7 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
10341043
NextHopKey nexthop(nhg.to_string(), true);
10351044
vrf_obj->removeTunnelNextHop(nexthop);
10361045
}
1037-
delEndpointMonitor(vnet, nhg);
1046+
delEndpointMonitor(vnet, nhg, ipPrefix);
10381047
}
10391048
else
10401049
{
@@ -1552,39 +1561,118 @@ void VNetRouteOrch::removeBfdSession(const string& vnet, const NextHopKey& endpo
15521561
bfd_sessions_.erase(monitor_addr);
15531562
}
15541563

1555-
void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops)
1564+
void VNetRouteOrch::createMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& monitor_addr, IpPrefix& ipPrefix)
1565+
{
1566+
SWSS_LOG_ENTER();
1567+
1568+
IpAddress endpoint_addr = endpoint.ip_address;
1569+
if (monitor_info_[vnet].find(ipPrefix) != monitor_info_[vnet].end() &&
1570+
monitor_info_[vnet][ipPrefix].find(endpoint) != monitor_info_[vnet][ipPrefix].end())
1571+
{
1572+
SWSS_LOG_NOTICE("Monitoring session for prefix %s endpoint %s already exist", ipPrefix.to_string().c_str(), endpoint_addr.to_string().c_str());
1573+
return;
1574+
}
1575+
else
1576+
{
1577+
vector<FieldValueTuple> data;
1578+
auto *vnet_obj = vnet_orch_->getTypePtr<VNetVrfObject>(vnet);
1579+
1580+
auto overlay_dmac = vnet_obj->getOverlayDMac();
1581+
string key = ipPrefix.to_string() + ":" + monitor_addr.to_string();
1582+
FieldValueTuple fvTuple1("packet_type", "vxlan");
1583+
data.push_back(fvTuple1);
1584+
1585+
FieldValueTuple fvTuple3("overlay_dmac", overlay_dmac.to_string());
1586+
data.push_back(fvTuple3);
1587+
1588+
monitor_session_producer_->set(key, data);
1589+
1590+
MonitorSessionInfo& info = monitor_info_[vnet][ipPrefix][endpoint];
1591+
info.monitor = monitor_addr;
1592+
info.state = MONITOR_SESSION_STATE::MONITOR_SESSION_STATE_DOWN;
1593+
}
1594+
}
1595+
1596+
void VNetRouteOrch::removeMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& monitor_addr, IpPrefix& ipPrefix)
1597+
{
1598+
SWSS_LOG_ENTER();
1599+
1600+
IpAddress endpoint_addr = endpoint.ip_address;
1601+
if (monitor_info_[vnet].find(ipPrefix) == monitor_info_[vnet].end() ||
1602+
monitor_info_[vnet][ipPrefix].find(endpoint) == monitor_info_[vnet][ipPrefix].end())
1603+
{
1604+
SWSS_LOG_NOTICE("Monitor session for prefix %s endpoint %s does not exist", ipPrefix.to_string().c_str(), endpoint_addr.to_string().c_str());
1605+
}
1606+
1607+
string key = ipPrefix.to_string() + ":" + monitor_addr.to_string();
1608+
monitor_session_producer_->del(key);
1609+
monitor_info_[vnet][ipPrefix].erase(endpoint);
1610+
}
1611+
1612+
void VNetRouteOrch::setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops, const string& monitoring, IpPrefix& ipPrefix)
15561613
{
15571614
SWSS_LOG_ENTER();
15581615

15591616
for (auto monitor : monitors)
15601617
{
15611618
NextHopKey nh = monitor.first;
15621619
IpAddress monitor_ip = monitor.second;
1563-
if (nexthop_info_[vnet].find(nh.ip_address) == nexthop_info_[vnet].end())
1620+
if (monitoring == "custom")
15641621
{
1565-
createBfdSession(vnet, nh, monitor_ip);
1622+
if (monitor_info_[vnet].find(ipPrefix) == monitor_info_[vnet].end() ||
1623+
monitor_info_[vnet][ipPrefix].find(nh) == monitor_info_[vnet][ipPrefix].end())
1624+
{
1625+
createMonitoringSession(vnet, nh, monitor_ip, ipPrefix);
1626+
}
1627+
}
1628+
else
1629+
{
1630+
if (nexthop_info_[vnet].find(nh.ip_address) == nexthop_info_[vnet].end())
1631+
{
1632+
createBfdSession(vnet, nh, monitor_ip);
1633+
}
1634+
nexthop_info_[vnet][nh.ip_address].ref_count++;
15661635
}
1567-
1568-
nexthop_info_[vnet][nh.ip_address].ref_count++;
15691636
}
15701637
}
15711638

1572-
void VNetRouteOrch::delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops)
1639+
void VNetRouteOrch::delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops, IpPrefix& ipPrefix)
15731640
{
15741641
SWSS_LOG_ENTER();
15751642

15761643
std::set<NextHopKey> nhks = nexthops.getNextHops();
1644+
bool is_custom_monitoring = false;
1645+
if (monitor_info_[vnet].find(ipPrefix) != monitor_info_[vnet].end())
1646+
{
1647+
is_custom_monitoring = true;
1648+
}
15771649
for (auto nhk: nhks)
15781650
{
15791651
IpAddress ip = nhk.ip_address;
1580-
if (nexthop_info_[vnet].find(ip) != nexthop_info_[vnet].end()) {
1581-
if (--nexthop_info_[vnet][ip].ref_count == 0)
1652+
if (is_custom_monitoring)
1653+
{
1654+
if ( monitor_info_[vnet][ipPrefix].find(nhk) != monitor_info_[vnet][ipPrefix].end())
15821655
{
1583-
IpAddress monitor_addr = nexthop_info_[vnet][ip].monitor_addr;
1584-
removeBfdSession(vnet, nhk, monitor_addr);
1656+
removeMonitoringSession(vnet, nhk, monitor_info_[vnet][ipPrefix][nhk].monitor, ipPrefix);
1657+
}
1658+
}
1659+
else
1660+
{
1661+
if (nexthop_info_[vnet].find(ip) != nexthop_info_[vnet].end()) {
1662+
if (--nexthop_info_[vnet][ip].ref_count == 0)
1663+
{
1664+
IpAddress monitor_addr = nexthop_info_[vnet][ip].monitor_addr;
1665+
{
1666+
removeBfdSession(vnet, nhk, monitor_addr);
1667+
}
1668+
}
15851669
}
15861670
}
15871671
}
1672+
if (is_custom_monitoring)
1673+
{
1674+
monitor_info_[vnet].erase(ipPrefix);
1675+
}
15881676
}
15891677

15901678
void VNetRouteOrch::postRouteState(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& profile)
@@ -1845,7 +1933,9 @@ bool VNetRouteOrch::handleTunnel(const Request& request)
18451933
vector<string> vni_list;
18461934
vector<IpAddress> monitor_list;
18471935
string profile = "";
1848-
1936+
vector<IpAddress> primary_list;
1937+
string monitoring;
1938+
swss::IpPrefix adv_prefix;
18491939
for (const auto& name: request.getAttrFieldNames())
18501940
{
18511941
if (name == "endpoint")
@@ -1870,6 +1960,18 @@ bool VNetRouteOrch::handleTunnel(const Request& request)
18701960
{
18711961
profile = request.getAttrString(name);
18721962
}
1963+
else if (name == "primary")
1964+
{
1965+
primary_list = request.getAttrIPList(name);
1966+
}
1967+
else if (name == "monitoring")
1968+
{
1969+
monitoring = request.getAttrString(name);
1970+
}
1971+
else if (name == "adv_prefix")
1972+
{
1973+
adv_prefix = request.getAttrIpPrefix(name);
1974+
}
18731975
else
18741976
{
18751977
SWSS_LOG_INFO("Unknown attribute: %s", name.c_str());
@@ -1933,7 +2035,7 @@ bool VNetRouteOrch::handleTunnel(const Request& request)
19332035

19342036
if (vnet_orch_->isVnetExecVrf())
19352037
{
1936-
return doRouteTask<VNetVrfObject>(vnet_name, ip_pfx, nhg, op, profile, monitors);
2038+
return doRouteTask<VNetVrfObject>(vnet_name, ip_pfx, nhg, op, profile, monitoring, monitors);
19372039
}
19382040

19392041
return true;

orchagent/vnetorch.h

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525

2626
extern sai_object_id_t gVirtualRouterId;
2727

28+
enum class MONITOR_SESSION_STATE
29+
{
30+
MONITOR_SESSION_STATE_UP,
31+
MONITOR_SESSION_STATE_DOWN,
32+
MONITOR_SESSION_STATE_UNKNOWN,
33+
};
2834
const request_description_t vnet_request_description = {
2935
{ REQ_T_STRING },
3036
{
@@ -35,6 +41,8 @@ const request_description_t vnet_request_description = {
3541
{ "guid", REQ_T_STRING },
3642
{ "scope", REQ_T_STRING },
3743
{ "advertise_prefix", REQ_T_BOOL},
44+
{ "overlay_dmac", REQ_T_MAC_ADDRESS},
45+
3846
},
3947
{ "vxlan_tunnel", "vni" } // mandatory attributes
4048
};
@@ -60,6 +68,7 @@ struct VNetInfo
6068
set<string> peers;
6169
string scope;
6270
bool advertise_prefix;
71+
swss::MacAddress overlay_dmac;
6372
};
6473

6574
typedef map<VR_TYPE, sai_object_id_t> vrid_list_t;
@@ -87,7 +96,8 @@ class VNetObject
8796
peer_list_(vnetInfo.peers),
8897
vni_(vnetInfo.vni),
8998
scope_(vnetInfo.scope),
90-
advertise_prefix_(vnetInfo.advertise_prefix)
99+
advertise_prefix_(vnetInfo.advertise_prefix),
100+
overlay_dmac_(vnetInfo.overlay_dmac)
91101
{ }
92102

93103
virtual bool updateObj(vector<sai_attribute_t>&) = 0;
@@ -122,6 +132,11 @@ class VNetObject
122132
return advertise_prefix_;
123133
}
124134

135+
swss::MacAddress getOverlayDMac() const
136+
{
137+
return overlay_dmac_;
138+
}
139+
125140
virtual ~VNetObject() noexcept(false) {};
126141

127142
private:
@@ -130,6 +145,7 @@ class VNetObject
130145
uint32_t vni_;
131146
string scope_;
132147
bool advertise_prefix_;
148+
swss::MacAddress overlay_dmac_;
133149
};
134150

135151
struct nextHop
@@ -277,6 +293,9 @@ const request_description_t vnet_route_description = {
277293
{ "mac_address", REQ_T_STRING },
278294
{ "endpoint_monitor", REQ_T_IP_LIST },
279295
{ "profile", REQ_T_STRING },
296+
{ "primary", REQ_T_IP_LIST },
297+
{ "monitoring", REQ_T_STRING },
298+
{ "adv_prefix", REQ_T_IP_PREFIX },
280299
},
281300
{ }
282301
};
@@ -321,9 +340,16 @@ struct BfdSessionInfo
321340
NextHopKey endpoint;
322341
};
323342

343+
struct MonitorSessionInfo
344+
{
345+
MONITOR_SESSION_STATE state;
346+
IpAddress monitor;
347+
};
348+
324349
typedef std::map<NextHopGroupKey, NextHopGroupInfo> VNetNextHopGroupInfoTable;
325350
typedef std::map<IpPrefix, NextHopGroupKey> VNetTunnelRouteTable;
326351
typedef std::map<IpAddress, BfdSessionInfo> BfdSessionTable;
352+
typedef std::map<IpPrefix, std::map<NextHopKey, MonitorSessionInfo>> MonitorSessionTable;
327353
typedef std::map<IpAddress, VNetNextHopInfo> VNetEndpointInfoTable;
328354

329355
class VNetRouteOrch : public Orch2, public Subject, public Observer
@@ -356,8 +382,11 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer
356382

357383
void createBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr);
358384
void removeBfdSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr);
359-
void setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops);
360-
void delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops);
385+
void createMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr, IpPrefix& ipPrefix);
386+
void removeMonitoringSession(const string& vnet, const NextHopKey& endpoint, const IpAddress& ipAddr, IpPrefix& ipPrefix);
387+
void setEndpointMonitor(const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops,
388+
const string& monitoring, IpPrefix& ipPrefix);
389+
void delEndpointMonitor(const string& vnet, NextHopGroupKey& nexthops, IpPrefix& ipPrefix);
361390
void postRouteState(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& profile);
362391
void removeRouteState(const string& vnet, IpPrefix& ipPrefix);
363392
void addRouteAdvertisement(IpPrefix& ipPrefix, string& profile);
@@ -368,6 +397,7 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer
368397

369398
template<typename T>
370399
bool doRouteTask(const string& vnet, IpPrefix& ipPrefix, NextHopGroupKey& nexthops, string& op, string& profile,
400+
const string& monitoring,
371401
const std::map<NextHopKey, IpAddress>& monitors=std::map<NextHopKey, IpAddress>());
372402

373403
template<typename T>
@@ -382,9 +412,12 @@ class VNetRouteOrch : public Orch2, public Subject, public Observer
382412
std::map<std::string, VNetNextHopGroupInfoTable> syncd_nexthop_groups_;
383413
std::map<std::string, VNetTunnelRouteTable> syncd_tunnel_routes_;
384414
BfdSessionTable bfd_sessions_;
415+
std::map<std::string, MonitorSessionTable> monitor_info_;
385416
std::map<std::string, VNetEndpointInfoTable> nexthop_info_;
386417
ProducerStateTable bfd_session_producer_;
418+
unique_ptr<Table> monitor_session_producer_;
387419
shared_ptr<DBConnector> state_db_;
420+
shared_ptr<DBConnector> app_db_;
388421
unique_ptr<Table> state_vnet_rt_tunnel_table_;
389422
unique_ptr<Table> state_vnet_rt_adv_table_;
390423
};

0 commit comments

Comments
 (0)