Skip to content

Commit 640da98

Browse files
abdosimssonicbld
authored andcommitted
Added change not to create ECMP Group in SAI and program the route if none of ECMP members are active/link-up (#3394)
What I did: Added change not to create ECMP Group in SAI and program the route if none of the ECMP members are active/link-up. Also do not program the Temp Route if Neigh is not active (Link Down) Also as part of this change if Route is not programmed and if we remove that route than decrement VRF Reference count in removeRoute as removeRoutePost will not be called in this case. Why I did: In scale setup of T2 it's possible all links can go down simultaneously which case we can get Route messages with all nexthops being in down state. In such case we might create empty Nexthop Group in SAI for the given route which causes not needed SAI call for Nexthop Group creation and also create traffic blackhole for the route where that route can still forward traffic via default route if eligible/applicable. Also in this case no point to add Temp Route if neighbor is link down.
1 parent 227d1d6 commit 640da98

File tree

3 files changed

+54
-26
lines changed

3 files changed

+54
-26
lines changed

orchagent/routeorch.cpp

+21-5
Original file line numberDiff line numberDiff line change
@@ -1331,7 +1331,11 @@ bool RouteOrch::addNextHopGroup(const NextHopGroupKey &nexthops)
13311331
nhopgroup_shared_set[next_hop_id].insert(it);
13321332
}
13331333
}
1334-
1334+
if (!next_hop_ids.size())
1335+
{
1336+
SWSS_LOG_INFO("Skipping creation of nexthop group as none of nexthop are active");
1337+
return false;
1338+
}
13351339
sai_attribute_t nhg_attr;
13361340
vector<sai_attribute_t> nhg_attrs;
13371341

@@ -1716,9 +1720,15 @@ void RouteOrch::addTempRoute(RouteBulkContext& ctx, const NextHopGroupKey &nextH
17161720
SWSS_LOG_INFO("Failed to get next hop %s for %s",
17171721
(*it).to_string().c_str(), ipPrefix.to_string().c_str());
17181722
it = next_hop_set.erase(it);
1723+
continue;
17191724
}
1720-
else
1721-
it++;
1725+
if(m_neighOrch->isNextHopFlagSet(*it, NHFLAGS_IFDOWN))
1726+
{
1727+
SWSS_LOG_INFO("Interface down for NH %s, skip this NH", (*it).to_string().c_str());
1728+
it = next_hop_set.erase(it);
1729+
continue;
1730+
}
1731+
it++;
17221732
}
17231733

17241734
/* Return if next_hop_set is empty */
@@ -2421,8 +2431,14 @@ bool RouteOrch::removeRoute(RouteBulkContext& ctx)
24212431
size_t creating = gRouteBulker.creating_entries_count(route_entry);
24222432
if (it_route == it_route_table->second.end() && creating == 0)
24232433
{
2424-
SWSS_LOG_INFO("Failed to find route entry, vrf_id 0x%" PRIx64 ", prefix %s\n", vrf_id,
2425-
ipPrefix.to_string().c_str());
2434+
if (it_route_table->second.size() == 0)
2435+
{
2436+
m_syncdRoutes.erase(vrf_id);
2437+
m_vrfOrch->decreaseVrfRefCount(vrf_id);
2438+
}
2439+
SWSS_LOG_INFO("Failed to find route entry, vrf_id 0x%" PRIx64 ", prefix %s\n", vrf_id,
2440+
ipPrefix.to_string().c_str());
2441+
24262442
return true;
24272443
}
24282444

tests/mock_tests/routeorch_ut.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ namespace routeorch_test
281281
for (const auto &it : ports)
282282
{
283283
portTable.set(it.first, it.second);
284+
portTable.set(it.first, {{ "oper_status", "up" }});
284285
}
285286

286287
// Set PortConfigDone

tests/test_sub_port_intf.py

+32-21
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ def get_default_vrf_oid(self):
393393
assert len(oids) == 1, "Wrong # of default vrfs: %d, expected #: 1." % (len(oids))
394394
return oids[0]
395395

396-
def get_ip_prefix_nhg_oid(self, ip_prefix, vrf_oid=None):
396+
def get_ip_prefix_nhg_oid(self, ip_prefix, vrf_oid=None, prefix_present=True):
397397
if vrf_oid is None:
398398
vrf_oid = self.default_vrf_oid
399399

@@ -407,18 +407,24 @@ def _access_function():
407407
route_entry_found = True
408408
assert route_entry_key["vr"] == vrf_oid
409409
break
410-
411-
return (route_entry_found, raw_route_entry_key)
410+
if prefix_present:
411+
return (route_entry_found, raw_route_entry_key)
412+
else:
413+
return (not route_entry_found, None)
412414

413415
(route_entry_found, raw_route_entry_key) = wait_for_result(_access_function)
414416

415-
fvs = self.asic_db.get_entry(ASIC_ROUTE_ENTRY_TABLE, raw_route_entry_key)
417+
if not prefix_present:
418+
assert raw_route_entry_key == None
419+
return None
420+
else:
421+
fvs = self.asic_db.get_entry(ASIC_ROUTE_ENTRY_TABLE, raw_route_entry_key)
416422

417-
nhg_oid = fvs.get("SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID", "")
418-
assert nhg_oid != ""
419-
assert nhg_oid != "oid:0x0"
423+
nhg_oid = fvs.get("SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID", "")
424+
assert nhg_oid != ""
425+
assert nhg_oid != "oid:0x0"
420426

421-
return nhg_oid
427+
return nhg_oid
422428

423429
def check_sub_port_intf_key_existence(self, db, table_name, key):
424430
db.wait_for_matching_keys(table_name, [key])
@@ -1543,21 +1549,26 @@ def _test_sub_port_intf_oper_down_with_pending_neigh_route_tasks(self, dvs, sub_
15431549
self.add_route_appl_db(ip_prefix, nhop_ips, ifnames, vrf_name)
15441550

15451551
# Verify route entry created in ASIC_DB and get next hop group oid
1546-
nhg_oid = self.get_ip_prefix_nhg_oid(ip_prefix, vrf_oid)
1547-
1548-
# Verify next hop group of the specified oid created in ASIC_DB
1549-
self.check_sub_port_intf_key_existence(self.asic_db, ASIC_NEXT_HOP_GROUP_TABLE, nhg_oid)
1552+
nhg_oid = self.get_ip_prefix_nhg_oid(ip_prefix, vrf_oid, prefix_present = i < (nhop_num - 1))
15501553

1551-
# Verify next hop group member # created in ASIC_DB
1552-
nhg_member_oids = self.asic_db.wait_for_n_keys(ASIC_NEXT_HOP_GROUP_MEMBER_TABLE,
1553-
(nhop_num - 1) - i if create_intf_on_parent_port == False else ((nhop_num - 1) - i) * 2)
1554+
if i < (nhop_num - 1):
1555+
# Verify next hop group of the specified oid created in ASIC_DB
1556+
self.check_sub_port_intf_key_existence(self.asic_db, ASIC_NEXT_HOP_GROUP_TABLE, nhg_oid)
15541557

1555-
# Verify that next hop group members all belong to the next hop group of the specified oid
1556-
fv_dict = {
1557-
"SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID": nhg_oid,
1558-
}
1559-
for nhg_member_oid in nhg_member_oids:
1560-
self.check_sub_port_intf_fvs(self.asic_db, ASIC_NEXT_HOP_GROUP_MEMBER_TABLE, nhg_member_oid, fv_dict)
1558+
# Verify next hop group member # created in ASIC_DB
1559+
nhg_member_oids = self.asic_db.wait_for_n_keys(ASIC_NEXT_HOP_GROUP_MEMBER_TABLE,
1560+
(nhop_num - 1) - i if create_intf_on_parent_port == False \
1561+
else ((nhop_num - 1) - i) * 2)
1562+
1563+
# Verify that next hop group members all belong to the next hop group of the specified oid
1564+
fv_dict = {
1565+
"SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID": nhg_oid,
1566+
}
1567+
for nhg_member_oid in nhg_member_oids:
1568+
self.check_sub_port_intf_fvs(self.asic_db, ASIC_NEXT_HOP_GROUP_MEMBER_TABLE, nhg_member_oid, fv_dict)
1569+
else:
1570+
assert nhg_oid == None
1571+
self.asic_db.wait_for_n_keys(ASIC_NEXT_HOP_GROUP_MEMBER_TABLE, 0)
15611572

15621573
nhop_cnt = len(self.asic_db.get_keys(ASIC_NEXT_HOP_TABLE))
15631574
# Remove next hop objects on sub port interfaces

0 commit comments

Comments
 (0)