-
Notifications
You must be signed in to change notification settings - Fork 539
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added Change for given Route ECMP to fallback on Default Route ECMP #3389
base: master
Are you sure you want to change the base?
Changes from 3 commits
72b5825
e3b48ae
9c5c2e7
126c201
4751f41
1fef1c2
de8e979
b374597
540dd52
de037d5
8d2d008
a90ba41
d9272ee
0c6ec8b
5985e34
780d69d
d65732d
a6d1c77
409b268
7718dfa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -381,6 +381,70 @@ void RouteOrch::detach(Observer *observer, const IpAddress& dstAddr, sai_object_ | |
} | ||
} | ||
|
||
void RouteOrch::updateDefaultRouteSwapSet(const NextHopGroupKey default_nhg_key, std::set<NextHopKey>& active_default_route_nhops) | ||
{ | ||
std::set<NextHopKey> current_default_route_nhops; | ||
current_default_route_nhops.clear(); | ||
|
||
if (default_nhg_key.getSize() == 1) | ||
{ | ||
current_default_route_nhops.insert(*default_nhg_key.getNextHops().begin()); | ||
} | ||
else | ||
{ | ||
auto nhgm = m_syncdNextHopGroups[default_nhg_key].nhopgroup_members; | ||
for (auto nhop = nhgm.begin(); nhop != nhgm.end(); ++nhop) | ||
{ | ||
current_default_route_nhops.insert(nhop->first); | ||
} | ||
} | ||
|
||
active_default_route_nhops.clear(); | ||
std::copy(current_default_route_nhops.begin(), current_default_route_nhops.end(), std::inserter(active_default_route_nhops, active_default_route_nhops.begin())); | ||
} | ||
|
||
bool RouteOrch::addDefaultRouteNexthopsInNextHopGroup(NextHopGroupEntry& original_next_hop_group, std::set<NextHopKey>& default_route_next_hop_set) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
sai_object_id_t nexthop_group_member_id; | ||
sai_status_t status; | ||
|
||
for (auto it : default_route_next_hop_set) | ||
{ | ||
vector<sai_attribute_t> nhgm_attrs; | ||
sai_attribute_t nhgm_attr; | ||
nhgm_attr.id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_GROUP_ID; | ||
nhgm_attr.value.oid = original_next_hop_group.next_hop_group_id; | ||
nhgm_attrs.push_back(nhgm_attr); | ||
|
||
nhgm_attr.id = SAI_NEXT_HOP_GROUP_MEMBER_ATTR_NEXT_HOP_ID; | ||
nhgm_attr.value.oid = m_neighOrch->getNextHopId(it); | ||
nhgm_attrs.push_back(nhgm_attr); | ||
|
||
status = sai_next_hop_group_api->create_next_hop_group_member(&nexthop_group_member_id, gSwitchId, | ||
(uint32_t)nhgm_attrs.size(), | ||
nhgm_attrs.data()); | ||
|
||
if (status != SAI_STATUS_SUCCESS) | ||
{ | ||
SWSS_LOG_ERROR("Default Route Swap Failed to add next hop member to group %" PRIx64 ": %d\n", | ||
original_next_hop_group.next_hop_group_id, status); | ||
task_process_status handle_status = handleSaiCreateStatus(SAI_API_NEXT_HOP_GROUP, status); | ||
if (handle_status != task_success) | ||
{ | ||
return parseHandleSaiStatusFailure(handle_status); | ||
} | ||
} | ||
// Increment the Default Route Active NH Reference Count | ||
m_neighOrch->increaseNextHopRefCount(it); | ||
gCrmOrch->incCrmResUsedCounter(CrmResourceType::CRM_NEXTHOP_GROUP_MEMBER); | ||
original_next_hop_group.default_route_nhopgroup_members[it].next_hop_id = nexthop_group_member_id; | ||
original_next_hop_group.default_route_nhopgroup_members[it].seq_id = 0; | ||
original_next_hop_group.is_default_route_nh_swap = true; | ||
} | ||
return true; | ||
} | ||
|
||
bool RouteOrch::validnexthopinNextHopGroup(const NextHopKey &nexthop, uint32_t& count) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
@@ -398,6 +462,13 @@ bool RouteOrch::validnexthopinNextHopGroup(const NextHopKey &nexthop, uint32_t& | |
continue; | ||
} | ||
|
||
// AZNG Route NHOP Group is swapped by default route nh memeber . do not add Nexthop again. | ||
// Wait for Nexthop Group Cleanup | ||
if (nhopgroup->second.is_default_route_nh_swap) | ||
{ | ||
continue; | ||
} | ||
|
||
vector<sai_attribute_t> nhgm_attrs; | ||
sai_attribute_t nhgm_attr; | ||
|
||
|
@@ -444,6 +515,7 @@ bool RouteOrch::validnexthopinNextHopGroup(const NextHopKey &nexthop, uint32_t& | |
++count; | ||
gCrmOrch->incCrmResUsedCounter(CrmResourceType::CRM_NEXTHOP_GROUP_MEMBER); | ||
nhopgroup->second.nhopgroup_members[nexthop].next_hop_id = nexthop_id; | ||
nhopgroup->second.nh_member_install_count++; | ||
} | ||
|
||
if (!m_fgNhgOrch->validNextHopInNextHopGroup(nexthop)) | ||
|
@@ -484,7 +556,22 @@ bool RouteOrch::invalidnexthopinNextHopGroup(const NextHopKey &nexthop, uint32_t | |
return parseHandleSaiStatusFailure(handle_status); | ||
} | ||
} | ||
|
||
if (nhopgroup->second.nh_member_install_count) | ||
{ | ||
nhopgroup->second.nh_member_install_count--; | ||
} | ||
|
||
if (nhopgroup->second.nh_member_install_count == 0 && nhopgroup->second.eligible_for_default_route_nh_swap && !nhopgroup->second.is_default_route_nh_swap) | ||
{ | ||
if(nexthop.ip_address.isV4()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if at this time the default route from bgp is not present. will the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @arlakshm : if no default route than existing behavior will happen where nexthop group will not have any members which will cause drop as expected. |
||
{ | ||
addDefaultRouteNexthopsInNextHopGroup(nhopgroup->second, v4_active_default_route_nhops); | ||
} | ||
else | ||
{ | ||
addDefaultRouteNexthopsInNextHopGroup(nhopgroup->second, v6_active_default_route_nhops); | ||
} | ||
} | ||
++count; | ||
gCrmOrch->decCrmResUsedCounter(CrmResourceType::CRM_NEXTHOP_GROUP_MEMBER); | ||
} | ||
|
@@ -632,6 +719,7 @@ void RouteOrch::doTask(Consumer& consumer) | |
string srv6_segments; | ||
string srv6_source; | ||
bool srv6_nh = false; | ||
bool fallback_to_default_route = false; | ||
|
||
for (auto i : kfvFieldsValues(t)) | ||
{ | ||
|
@@ -673,6 +761,10 @@ void RouteOrch::doTask(Consumer& consumer) | |
{ | ||
ctx.protocol = fvValue(i); | ||
} | ||
if (fvField(i) == "fallback_to_default_route") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. who sets this attribute? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is being done here: #3353 |
||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix indentation. mix of tabs and spaces #Closed |
||
fallback_to_default_route = fvValue(i) == "true"; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix indentation. mix of tabs and spaces #Closed |
||
} | ||
|
||
/* | ||
|
@@ -687,6 +779,7 @@ void RouteOrch::doTask(Consumer& consumer) | |
} | ||
|
||
ctx.nhg_index = nhg_index; | ||
ctx.fallback_to_default_route = fallback_to_default_route; | ||
|
||
/* | ||
* If the nexthop_group is empty, create the next hop group key | ||
|
@@ -975,6 +1068,8 @@ void RouteOrch::doTask(Consumer& consumer) | |
// Go through the bulker results | ||
auto it_prev = consumer.m_toSync.begin(); | ||
m_bulkNhgReducedRefCnt.clear(); | ||
NextHopGroupKey v4_default_nhg_key; | ||
NextHopGroupKey v6_default_nhg_key; | ||
while (it_prev != it) | ||
{ | ||
KeyOpFieldsValuesTuple t = it_prev->second; | ||
|
@@ -1032,6 +1127,18 @@ void RouteOrch::doTask(Consumer& consumer) | |
it_prev = consumer.m_toSync.erase(it_prev); | ||
else | ||
it_prev++; | ||
|
||
if (ip_prefix.isDefaultRoute() && vrf_id == gVirtualRouterId) | ||
{ | ||
if (ip_prefix.isV4()) | ||
Comment on lines
+1132
to
+1133
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: indentation #Resolved |
||
{ | ||
v4_default_nhg_key = getSyncdRouteNhgKey(gVirtualRouterId, ip_prefix); | ||
} | ||
else | ||
{ | ||
v6_default_nhg_key = getSyncdRouteNhgKey(gVirtualRouterId, ip_prefix); | ||
} | ||
} | ||
} | ||
} | ||
else if (op == DEL_COMMAND) | ||
|
@@ -1067,9 +1174,19 @@ void RouteOrch::doTask(Consumer& consumer) | |
} | ||
else if (m_syncdNextHopGroups[it_nhg.first].ref_count == 0) | ||
{ | ||
removeNextHopGroup(it_nhg.first); | ||
// Pass the flag to indicate if the NextHop Group as Default Route NH Members as swapped. | ||
removeNextHopGroup(it_nhg.first, m_syncdNextHopGroups[it_nhg.first].is_default_route_nh_swap); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix indentation #Resolved |
||
} | ||
} | ||
|
||
if (!(v4_default_nhg_key.getSize()) && !(v6_default_nhg_key.getSize())) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
return; | ||
|
||
if (v4_default_nhg_key.getSize()) | ||
updateDefaultRouteSwapSet(v4_default_nhg_key, v4_active_default_route_nhops); | ||
|
||
if (v6_default_nhg_key.getSize()) | ||
updateDefaultRouteSwapSet(v6_default_nhg_key, v6_active_default_route_nhops); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fix indentation #Resolved |
||
} | ||
} | ||
|
||
|
@@ -1363,6 +1480,7 @@ bool RouteOrch::addNextHopGroup(const NextHopGroupKey &nexthops) | |
|
||
NextHopGroupEntry next_hop_group_entry; | ||
next_hop_group_entry.next_hop_group_id = next_hop_group_id; | ||
next_hop_group_entry.nh_member_install_count = 0; | ||
|
||
size_t npid_count = next_hop_ids.size(); | ||
vector<sai_object_id_t> nhgm_ids(npid_count); | ||
|
@@ -1433,6 +1551,7 @@ bool RouteOrch::addNextHopGroup(const NextHopGroupKey &nexthops) | |
{ | ||
next_hop_group_entry.nhopgroup_members[nhopgroup_members_set.find(nhid)->second].next_hop_id = nhgm_id; | ||
next_hop_group_entry.nhopgroup_members[nhopgroup_members_set.find(nhid)->second].seq_id = ((uint32_t)i) + 1; | ||
next_hop_group_entry.nh_member_install_count++; | ||
} | ||
} | ||
|
||
|
@@ -1450,7 +1569,7 @@ bool RouteOrch::addNextHopGroup(const NextHopGroupKey &nexthops) | |
return true; | ||
} | ||
|
||
bool RouteOrch::removeNextHopGroup(const NextHopGroupKey &nexthops) | ||
bool RouteOrch::removeNextHopGroup(const NextHopGroupKey &nexthops, const bool is_default_route_nh_swap) | ||
{ | ||
SWSS_LOG_ENTER(); | ||
|
||
|
@@ -1471,10 +1590,10 @@ bool RouteOrch::removeNextHopGroup(const NextHopGroupKey &nexthops) | |
SWSS_LOG_NOTICE("Delete next hop group %s", nexthops.to_string().c_str()); | ||
|
||
vector<sai_object_id_t> next_hop_ids; | ||
auto& nhgm = next_hop_group_entry->second.nhopgroup_members; | ||
auto &nhgm = is_default_route_nh_swap ? next_hop_group_entry->second.default_route_nhopgroup_members : next_hop_group_entry->second.nhopgroup_members; | ||
for (auto nhop = nhgm.begin(); nhop != nhgm.end();) | ||
{ | ||
if (m_neighOrch->isNextHopFlagSet(nhop->first, NHFLAGS_IFDOWN)) | ||
if (m_neighOrch->isNextHopFlagSet(nhop->first, NHFLAGS_IFDOWN) && (!is_default_route_nh_swap)) | ||
{ | ||
SWSS_LOG_WARN("NHFLAGS_IFDOWN set for next hop group member %s with next_hop_id %" PRIx64, | ||
nhop->first.to_string().c_str(), nhop->second.next_hop_id); | ||
|
@@ -1565,6 +1684,16 @@ bool RouteOrch::removeNextHopGroup(const NextHopGroupKey &nexthops) | |
} | ||
} | ||
|
||
// Decrement Nexthop Reference Count for Default Route NH Member used as swapped | ||
if (is_default_route_nh_swap) | ||
{ | ||
auto& nhgm = next_hop_group_entry->second.default_route_nhopgroup_members; | ||
for (auto nhop = nhgm.begin(); nhop != nhgm.end(); ++nhop) | ||
{ | ||
m_neighOrch->decreaseNextHopRefCount(nhop->first); | ||
} | ||
} | ||
|
||
m_syncdNextHopGroups.erase(nexthops); | ||
|
||
return true; | ||
|
@@ -1717,6 +1846,11 @@ void RouteOrch::addTempRoute(RouteBulkContext& ctx, const NextHopGroupKey &nextH | |
(*it).to_string().c_str(), ipPrefix.to_string().c_str()); | ||
it = next_hop_set.erase(it); | ||
} | ||
else if(m_neighOrch->isNextHopFlagSet(*it, NHFLAGS_IFDOWN)) | ||
{ | ||
SWSS_LOG_INFO("Interface down for NH %s, skip this NH", (*it).to_string().c_str()); | ||
it = next_hop_set.erase(it); | ||
} | ||
else | ||
it++; | ||
} | ||
|
@@ -1949,6 +2083,11 @@ bool RouteOrch::addRoute(RouteBulkContext& ctx, const NextHopGroupKey &nextHops) | |
/* Return false since the original route is not successfully added */ | ||
return false; | ||
} | ||
else | ||
{ | ||
m_syncdNextHopGroups[nextHops].eligible_for_default_route_nh_swap = ctx.fallback_to_default_route; | ||
m_syncdNextHopGroups[nextHops].is_default_route_nh_swap = false; | ||
} | ||
} | ||
|
||
next_hop_id = m_syncdNextHopGroups[nextHops].next_hop_group_id; | ||
|
@@ -2504,6 +2643,11 @@ bool RouteOrch::removeRoutePost(const RouteBulkContext& ctx) | |
updateDefRouteState(ipPrefix.to_string()); | ||
|
||
SWSS_LOG_INFO("Set route %s next hop ID to NULL", ipPrefix.to_string().c_str()); | ||
|
||
if (ipPrefix.isV4()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
v4_active_default_route_nhops.clear(); | ||
else | ||
v6_active_default_route_nhops.clear(); | ||
} | ||
else | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,10 @@ struct NextHopGroupEntry | |
sai_object_id_t next_hop_group_id; // next hop group id | ||
int ref_count; // reference count | ||
NextHopGroupMembers nhopgroup_members; // ids of members indexed by <ip_address, if_alias> | ||
NextHopGroupMembers default_route_nhopgroup_members; // ids of members indexed by <ip_address, if_alias> | ||
uint32_t nh_member_install_count; | ||
bool eligible_for_default_route_nh_swap; | ||
bool is_default_route_nh_swap; | ||
}; | ||
|
||
struct NextHopUpdate | ||
|
@@ -122,13 +126,15 @@ struct RouteBulkContext | |
bool excp_intfs_flag; | ||
// using_temp_nhg will track if the NhgOrch's owned NHG is temporary or not | ||
bool using_temp_nhg; | ||
bool fallback_to_default_route; | ||
|
||
std::string key; // Key in database table | ||
std::string protocol; // Protocol string | ||
bool is_set; // True if set operation | ||
|
||
RouteBulkContext(const std::string& key, bool is_set) | ||
: key(key), excp_intfs_flag(false), using_temp_nhg(false), is_set(is_set) | ||
: key(key), excp_intfs_flag(false), using_temp_nhg(false), is_set(is_set), | ||
fallback_to_default_route(false) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. mix of tabs and spaces #Closed |
||
{ | ||
} | ||
|
||
|
@@ -146,6 +152,7 @@ struct RouteBulkContext | |
using_temp_nhg = false; | ||
key.clear(); | ||
protocol.clear(); | ||
fallback_to_default_route = false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove tabs #Closed |
||
} | ||
}; | ||
|
||
|
@@ -197,12 +204,13 @@ class RouteOrch : public Orch, public Subject | |
bool isRefCounterZero(const NextHopGroupKey&) const; | ||
|
||
bool addNextHopGroup(const NextHopGroupKey&); | ||
bool removeNextHopGroup(const NextHopGroupKey&); | ||
bool removeNextHopGroup(const NextHopGroupKey&, const bool is_default_route_nh_swap=false); | ||
|
||
void addNextHopRoute(const NextHopKey&, const RouteKey&); | ||
void removeNextHopRoute(const NextHopKey&, const RouteKey&); | ||
bool updateNextHopRoutes(const NextHopKey&, uint32_t&); | ||
bool getRoutesForNexthop(std::set<RouteKey>&, const NextHopKey&); | ||
bool swapnexthopinNextHopGroup(sai_object_id_t next_hop_group_id, sai_object_id_t default_next_hop_id); | ||
|
||
bool validnexthopinNextHopGroup(const NextHopKey&, uint32_t&); | ||
bool invalidnexthopinNextHopGroup(const NextHopKey&, uint32_t&); | ||
|
@@ -240,6 +248,8 @@ class RouteOrch : public Orch, public Subject | |
unsigned int m_maxNextHopGroupCount; | ||
bool m_resync; | ||
|
||
std::set<NextHopKey> v4_active_default_route_nhops; | ||
std::set<NextHopKey> v6_active_default_route_nhops; | ||
shared_ptr<DBConnector> m_stateDb; | ||
unique_ptr<swss::Table> m_stateDefaultRouteTb; | ||
|
||
|
@@ -286,6 +296,9 @@ class RouteOrch : public Orch, public Subject | |
bool isVipRoute(const IpPrefix &ipPrefix, const NextHopGroupKey &nextHops); | ||
void createVipRouteSubnetDecapTerm(const IpPrefix &ipPrefix); | ||
void removeVipRouteSubnetDecapTerm(const IpPrefix &ipPrefix); | ||
bool addDefaultRouteNexthopsInNextHopGroup(NextHopGroupEntry& original_next_hop_group, std::set<NextHopKey>& default_route_next_hop_set); | ||
void updateDefaultRouteSwapSet(const NextHopGroupKey default_nhg_key, std::set<NextHopKey>& active_default_route_nhops); | ||
|
||
}; | ||
|
||
#endif /* SWSS_ROUTEORCH_H */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: indentation #Closed