@@ -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
843851template <>
844852bool 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
15901678void 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 ;
0 commit comments