@@ -1052,13 +1052,21 @@ bool VNetRouteOrch::selectNextHopGroup(const string& vnet,
10521052 }
10531053 else
10541054 {
1055- if (it_route-> second . primary != nexthops_primary )
1055+ if (isCustomMonitorEndpointUpdated (vnet, ipPrefix, monitors) )
10561056 {
10571057 setEndpointMonitor (vnet, monitors, nexthops_primary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix);
1058+ setEndpointMonitor (vnet, monitors, nexthops_secondary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix);
10581059 }
1059- if (it_route-> second . secondary != nexthops_secondary)
1060+ else
10601061 {
1061- setEndpointMonitor (vnet, monitors, nexthops_secondary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix);
1062+ if (it_route->second .primary != nexthops_primary)
1063+ {
1064+ setEndpointMonitor (vnet, monitors, nexthops_primary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix);
1065+ }
1066+ if (it_route->second .secondary != nexthops_secondary)
1067+ {
1068+ setEndpointMonitor (vnet, monitors, nexthops_secondary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix);
1069+ }
10621070 }
10631071 nexthops_selected = it_route->second .nhg_key ;
10641072 return true ;
@@ -1173,6 +1181,16 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
11731181
11741182 if (op == SET_COMMAND)
11751183 {
1184+ bool custom_monitor_ep_updated = isCustomMonitorEndpointUpdated (vnet, ipPrefix, monitors);
1185+ std::map<NextHopKey, swss::IpAddress> origin_primary_monitors;
1186+ std::map<NextHopKey, swss::IpAddress> origin_secondary_monitors;
1187+ if (custom_monitor_ep_updated)
1188+ {
1189+ auto it_route = syncd_tunnel_routes_[vnet].find (ipPrefix);
1190+ getCustomMonitors (vnet, ipPrefix, it_route->second .primary , origin_primary_monitors);
1191+ getCustomMonitors (vnet, ipPrefix, it_route->second .secondary , origin_secondary_monitors);
1192+ }
1193+
11761194 sai_object_id_t nh_id = SAI_NULL_OBJECT_ID;
11771195 NextHopGroupKey active_nhg (" " , true );
11781196 if (!selectNextHopGroup (vnet, nexthops, nexthops_secondary, monitoring, rx_monitor_timer, tx_monitor_timer, ipPrefix, vrf_obj, active_nhg, monitors))
@@ -1250,63 +1268,73 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
12501268 }
12511269 bool route_updated = false ;
12521270 bool priority_route_updated = false ;
1253- if (it_route != syncd_tunnel_routes_[vnet].end () &&
1254- ((monitoring == " " && it_route->second .nhg_key != nexthops) ||
1255- ((monitoring == VNET_MONITORING_TYPE_CUSTOM || monitoring == VNET_MONITORING_TYPE_CUSTOM_BFD) && (it_route->second .primary != nexthops || it_route->second .secondary != nexthops_secondary))))
1256- {
1257- route_updated = true ;
1258- NextHopGroupKey nhg = it_route->second .nhg_key ;
1259- if (monitoring == VNET_MONITORING_TYPE_CUSTOM || monitoring == VNET_MONITORING_TYPE_CUSTOM_BFD)
1260- {
1261- // if the previously active NHG is same as the newly created active NHG.case of primary secondary swap or
1262- // when primary is active and secondary is changed or vice versa. In these cases we dont remove the NHG
1263- // but only remove the monitors for the set which has changed.
1264- if (it_route->second .primary != nexthops)
1265- {
1266- delEndpointMonitor (vnet, it_route->second .primary , ipPrefix);
1267- }
1268- if (it_route->second .secondary != nexthops_secondary)
1269- {
1270- delEndpointMonitor (vnet, it_route->second .secondary , ipPrefix);
1271- }
1272- if (monitor_info_[vnet][ipPrefix].empty ())
1273- {
1274- monitor_info_[vnet].erase (ipPrefix);
1275- }
1276- priority_route_updated = true ;
1271+ if (it_route != syncd_tunnel_routes_[vnet].end ())
1272+ {
1273+ if (custom_monitor_ep_updated)
1274+ {
1275+ route_updated = true ;
1276+
1277+ delEndpointMonitor (vnet, origin_primary_monitors, ipPrefix);
1278+ delEndpointMonitor (vnet, origin_secondary_monitors, ipPrefix);
12771279 }
1278- else
1280+ else if ((monitoring == " " && it_route->second .nhg_key != nexthops) ||
1281+ ((monitoring == VNET_MONITORING_TYPE_CUSTOM || monitoring == VNET_MONITORING_TYPE_CUSTOM_BFD) &&
1282+ (it_route->second .primary != nexthops || it_route->second .secondary != nexthops_secondary)))
12791283 {
1280- // In case of updating an existing route, decrease the reference count for the previous nexthop group
1281- if (--syncd_nexthop_groups_[vnet][nhg].ref_count == 0 )
1284+ route_updated = true ;
1285+ NextHopGroupKey nhg = it_route->second .nhg_key ;
1286+ if (monitoring == VNET_MONITORING_TYPE_CUSTOM || monitoring == VNET_MONITORING_TYPE_CUSTOM_BFD)
12821287 {
1283- if (nhg.getSize () > 1 )
1288+ // if the previously active NHG is same as the newly created active NHG.case of primary secondary swap or
1289+ // when primary is active and secondary is changed or vice versa. In these cases we dont remove the NHG
1290+ // but only remove the monitors for the set which has changed.
1291+ if (it_route->second .primary != nexthops)
12841292 {
1285- removeNextHopGroup (vnet, nhg, vrf_obj );
1293+ delEndpointMonitor (vnet, it_route-> second . primary , ipPrefix );
12861294 }
1287- else
1295+ if (it_route->second .secondary != nexthops_secondary)
1296+ {
1297+ delEndpointMonitor (vnet, it_route->second .secondary , ipPrefix);
1298+ }
1299+ if (monitor_info_[vnet][ipPrefix].empty ())
12881300 {
1289- syncd_nexthop_groups_[vnet].erase (nhg);
1290- if (nhg.getSize () == 1 )
1301+ monitor_info_[vnet].erase (ipPrefix);
1302+ }
1303+ priority_route_updated = true ;
1304+ }
1305+ else
1306+ {
1307+ // In case of updating an existing route, decrease the reference count for the previous nexthop group
1308+ if (--syncd_nexthop_groups_[vnet][nhg].ref_count == 0 )
1309+ {
1310+ if (nhg.getSize () > 1 )
12911311 {
1292- NextHopKey nexthop = *nhg.getNextHops ().begin ();
1293- if (!isLocalEndpoint (vnet, nexthop.ip_address ))
1312+ removeNextHopGroup (vnet, nhg, vrf_obj);
1313+ }
1314+ else
1315+ {
1316+ syncd_nexthop_groups_[vnet].erase (nhg);
1317+ if (nhg.getSize () == 1 )
12941318 {
1295- vrf_obj->removeTunnelNextHop (nexthop);
1319+ NextHopKey nexthop = *nhg.getNextHops ().begin ();
1320+ if (!isLocalEndpoint (vnet, nexthop.ip_address ))
1321+ {
1322+ vrf_obj->removeTunnelNextHop (nexthop);
1323+ }
12961324 }
12971325 }
1326+ if (monitoring != VNET_MONITORING_TYPE_CUSTOM && monitoring != VNET_MONITORING_TYPE_CUSTOM_BFD)
1327+ {
1328+ delEndpointMonitor (vnet, nhg, ipPrefix);
1329+ }
12981330 }
1299- if (monitoring != VNET_MONITORING_TYPE_CUSTOM && monitoring != VNET_MONITORING_TYPE_CUSTOM_BFD)
1331+ else
13001332 {
1301- delEndpointMonitor ( vnet, nhg, ipPrefix);
1333+ syncd_nexthop_groups_[ vnet][ nhg]. tunnel_routes . erase ( ipPrefix);
13021334 }
1335+ vrf_obj->removeRoute (ipPrefix);
1336+ vrf_obj->removeProfile (ipPrefix);
13031337 }
1304- else
1305- {
1306- syncd_nexthop_groups_[vnet][nhg].tunnel_routes .erase (ipPrefix);
1307- }
1308- vrf_obj->removeRoute (ipPrefix);
1309- vrf_obj->removeProfile (ipPrefix);
13101338 }
13111339 }
13121340 if (!profile.empty ())
@@ -1323,11 +1351,13 @@ bool VNetRouteOrch::doRouteTask<VNetVrfObject>(const string& vnet, IpPrefix& ipP
13231351 syncd_tunnel_routes_[vnet][ipPrefix] = tunnel_route_entry;
13241352 syncd_nexthop_groups_[vnet][active_nhg].ref_count ++;
13251353
1326- if (priority_route_updated)
1354+ if (priority_route_updated || custom_monitor_ep_updated )
13271355 {
13281356 MonitorUpdate update;
1357+ update.monitoring_type = monitoring;
13291358 update.prefix = ipPrefix;
13301359 update.state = MONITOR_SESSION_STATE_UNKNOWN;
1360+ update.custom_bfd_state = SAI_BFD_SESSION_STATE_INIT;
13311361 update.vnet = vnet;
13321362 updateVnetTunnelCustomMonitor (update);
13331363 return true ;
@@ -2203,6 +2233,11 @@ void VNetRouteOrch::removeMonitoringSession(const string& vnet, const NextHopKey
22032233 }
22042234
22052235 monitor_info_[vnet][ipPrefix].erase (monitor_addr);
2236+
2237+ if (monitor_info_[vnet][ipPrefix].empty ())
2238+ {
2239+ monitor_info_[vnet].erase (ipPrefix);
2240+ }
22062241}
22072242
22082243void VNetRouteOrch::setEndpointMonitor (const string& vnet, const map<NextHopKey, IpAddress>& monitors, NextHopGroupKey& nexthops, const string& monitoring, const int32_t rx_monitor_timer, const int32_t tx_monitor_timer, IpPrefix& ipPrefix)
@@ -2299,6 +2334,43 @@ void VNetRouteOrch::delEndpointMonitor(const string& vnet, NextHopGroupKey& next
22992334 }
23002335}
23012336
2337+ void VNetRouteOrch::delEndpointMonitor (const string& vnet, const std::map<NextHopKey, IpAddress>& monitors, IpPrefix& ipPrefix)
2338+ {
2339+ SWSS_LOG_ENTER ();
2340+
2341+ bool is_custom_monitoring = false ;
2342+ if (monitor_info_[vnet].find (ipPrefix) != monitor_info_[vnet].end ())
2343+ {
2344+ is_custom_monitoring = true ;
2345+ }
2346+ for (auto monitor : monitors)
2347+ {
2348+ NextHopKey nhk = monitor.first ;
2349+ IpAddress monitor_ip = monitor.second ;
2350+ if (is_custom_monitoring)
2351+ {
2352+ if (monitor_info_[vnet][ipPrefix].find (monitor_ip) != monitor_info_[vnet][ipPrefix].end () &&
2353+ monitor_info_[vnet][ipPrefix][monitor_ip].endpoint == nhk)
2354+ {
2355+ if (--monitor_info_[vnet][ipPrefix][monitor_ip].ref_count == 0 )
2356+ {
2357+ removeMonitoringSession (vnet, monitor_info_[vnet][ipPrefix][monitor_ip].endpoint , monitor_ip, ipPrefix);
2358+ }
2359+ }
2360+ }
2361+ else
2362+ {
2363+ if (nexthop_info_[vnet].find (nhk.ip_address ) != nexthop_info_[vnet].end ())
2364+ {
2365+ if (--nexthop_info_[vnet][nhk.ip_address ].ref_count == 0 )
2366+ {
2367+ removeBfdSession (vnet, nhk, monitor_ip);
2368+ }
2369+ }
2370+ }
2371+ }
2372+ }
2373+
23022374void VNetRouteOrch::updateCustomBfdState (const IpAddress& monitoring_ip, const string& state)
23032375{
23042376 SWSS_LOG_ENTER ();
@@ -2321,7 +2393,8 @@ void VNetRouteOrch::updateCustomBfdState(const IpAddress& monitoring_ip, const s
23212393 }
23222394 else
23232395 {
2324- SWSS_LOG_WARN (" Unknown BFD state: %s" , state.c_str ());
2396+ /* VNetRouteOrch only processes Up/Down states from MonitorOrch */
2397+ SWSS_LOG_DEBUG (" Ignoring BFD state: %s" , state.c_str ());
23252398 return ;
23262399 }
23272400
@@ -2812,7 +2885,15 @@ void VNetRouteOrch::updateVnetTunnelCustomMonitor(const MonitorUpdate& update)
28122885
28132886 if (monitoring_type == VNET_MONITORING_TYPE_CUSTOM_BFD)
28142887 {
2815- monitor_info_[vnet][prefix][monitor].custom_bfd_state = custom_bfd_state;
2888+ if (custom_bfd_state == SAI_BFD_SESSION_STATE_INIT)
2889+ {
2890+ updateRoute = true ;
2891+ config_update = true ;
2892+ }
2893+ else
2894+ {
2895+ monitor_info_[vnet][prefix][monitor].custom_bfd_state = custom_bfd_state;
2896+ }
28162897 }
28172898
28182899 auto route = syncd_tunnel_routes_[vnet].find (prefix);
@@ -3329,6 +3410,63 @@ bool VNetRouteOrch::isPartiallyLocal(const std::vector<swss::IpAddress>& ip_list
33293410 return !(all_true || all_false);
33303411}
33313412
3413+ bool VNetRouteOrch::isCustomMonitorEndpointUpdated (const string& vnet, IpPrefix& ipPrefix,
3414+ const std::map<NextHopKey, swss::IpAddress>& monitors)
3415+ {
3416+ SWSS_LOG_ENTER ();
3417+
3418+ if (monitor_info_.find (vnet) == monitor_info_.end () ||
3419+ monitor_info_[vnet].find (ipPrefix) == monitor_info_[vnet].end ())
3420+ {
3421+ return false ;
3422+ }
3423+
3424+ // If the nh endpoint exists in the monitor_info map but the monitor ip is different, then return true.
3425+ // Note that the key of monitor_info is monitoring endpoint ip address, while monitors is nexthop key
3426+ // to monitor endpoint ip mapping.
3427+ bool monitor_endpoint_updated = false ;
3428+ for (auto it = monitor_info_[vnet][ipPrefix].begin (); it != monitor_info_[vnet][ipPrefix].end (); it++)
3429+ {
3430+ if (it->second .monitoring_type != VNET_MONITORING_TYPE_CUSTOM_BFD)
3431+ {
3432+ continue ;
3433+ }
3434+
3435+ if (monitors.find (it->second .endpoint ) != monitors.end () &&
3436+ it->first != monitors.at (it->second .endpoint ))
3437+ {
3438+ monitor_endpoint_updated = true ;
3439+
3440+ SWSS_LOG_NOTICE (" Custom monitor endpoint updated for vnet %s, prefix %s, old monitor %s, new monitor %s" ,
3441+ vnet.c_str (), ipPrefix.to_string ().c_str (),
3442+ it->first .to_string ().c_str (),
3443+ monitors.at (it->second .endpoint ).to_string ().c_str ());
3444+
3445+ }
3446+ }
3447+
3448+ return monitor_endpoint_updated;
3449+ }
3450+
3451+ void VNetRouteOrch::getCustomMonitors (const string& vnet, const IpPrefix& ipPrefix, const NextHopGroupKey& nexthops,
3452+ std::map<NextHopKey, swss::IpAddress>& monitors)
3453+ {
3454+ if (monitor_info_.find (vnet) != monitor_info_.end () && monitor_info_[vnet].find (ipPrefix) != monitor_info_[vnet].end ())
3455+ {
3456+ for (auto nhk:nexthops.getNextHops ())
3457+ {
3458+ for (const auto & monitor : monitor_info_[vnet][ipPrefix])
3459+ {
3460+ if (monitor.second .endpoint == nhk && (monitor.second .monitoring_type == VNET_MONITORING_TYPE_CUSTOM ||
3461+ monitor.second .monitoring_type == VNET_MONITORING_TYPE_CUSTOM_BFD))
3462+ {
3463+ monitors[nhk] = monitor.first ;
3464+ break ;
3465+ }
3466+ }
3467+ }
3468+ }
3469+ }
33323470
33333471VNetCfgRouteOrch::VNetCfgRouteOrch (DBConnector *db, DBConnector *appDb, vector<string> &tableNames)
33343472 : Orch(db, tableNames),
0 commit comments