Skip to content
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

[Mux] Route handling based on mux status, kernel tunnel support #1615

Merged
merged 2 commits into from
Feb 4, 2021

Conversation

prsunny
Copy link
Collaborator

@prsunny prsunny commented Jan 28, 2021

What I did

  1. Program/Reprogram routes to hardware based on Mux status
  2. Create tunnel interface (tun0) in kernel
  3. Add/remove tunnel routes in kernel

Why I did it
Support dual-tor SLB scenarios

How I verified it

Details if related

@prsunny
Copy link
Collaborator Author

prsunny commented Jan 29, 2021

retest vs please

cfgmgr/tunnelmgr.cpp Show resolved Hide resolved
cfgmgr/tunnelmgr.cpp Show resolved Hide resolved
cfgmgr/tunnelmgr.cpp Show resolved Hide resolved

if (it == m_tunnelCache.end())
{
SWSS_LOG_NOTICE("Tunnel %s not found", tunnelName.c_str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible that we can ever receive a delete request for a tunnel that is not there? If not, may have to set syslog with Error or Warning for the least...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to Error

cfgmgr/tunnelmgr.cpp Show resolved Hide resolved
/* Decrement ref count for ECMP NH members */
l_fn (nh_key, num_routes);

neigh = NeighborEntry(it->first, alias_);
if (!gNeighOrch->disableNeighbor(neigh))
{
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log error here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added

IpPrefix pfx = it->first.to_string();
if (create_route(pfx, it->second) != SAI_STATUS_SUCCESS)
{
return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log error here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

create_route has ERR log in case of failure

@@ -371,6 +374,7 @@ bool RouteOrch::invalidnexthopinNextHopGroup(const NextHopKey &nexthop)
return false;
}

++ count;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the purpose of this "count" variable? Does not look like it is being used?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the return value as part of function param.

orchagent/routeorch.cpp Show resolved Hide resolved
while(rt != it->second.end())
{
SWSS_LOG_INFO("Updating route %s", (*rt).prefix.to_string().c_str());
next_hop_id = m_neighOrch->getNextHopId(nextHop);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really intended? Doe not look like nexchop is modified in this while loop therefore next_hop_id will always be the same each loop?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, during mux state change, the nexthop id would have been changed to tunnel nexthop

@@ -333,6 +334,7 @@ bool RouteOrch::validnexthopinNextHopGroup(const NextHopKey &nexthop)
return false;
}

++ count;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove the space here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -250,11 +259,11 @@ bool NeighOrch::setNextHopFlag(const NextHopKey &nexthop, const uint32_t nh_flag
}

nhop->second.nh_flags |= nh_flag;

uint32_t count;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the purpose of this count here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only place where valid/invalid nexthop group is used and the API is modified to return number of nexthop groups that were modified. This is a no-op here. The caller can determine what to do with returned value

@@ -132,6 +150,7 @@ class RouteOrch : public Orch, public Subject

RouteTables m_syncdRoutes;
NextHopGroupTable m_syncdNextHopGroups;
NextHopRouteTable m_nextHops;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is better to explain what does the nexthop router table store? the nexthop -> route map? does this includes all the routes to T1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is mentioned at line 67. This is generic to be useful for other use-cases

RouteKey r_key = { vrf_id, ipPrefix };
auto nexthop = NextHopKey(nextHops.to_string());
addNextHopRoute(nexthop, r_key);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the purpose of add the <nexthop, r_key> ? is this used for track the nexthop change, so that we can find the route to be changed?

however, what about if there is a T1 route has only single nexthop?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, what is the implication if we have this nexthop route table on T1? feel it is totally unnecessary.


In reply to: 568514575 [](ancestors = 568514575)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a common data structure for holding Single NH -> Routes. It includes both T1 and Mux routes. I think it is hard to differentiate with T1 routes. Do you have a suggestion?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first, if the muxorch is not enabled, we should not enable this nexthop -> route tracking.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't true we will know which port has muxcable, and only track nexthop if it is pointing that port?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nexthop map is required for evpn case. Also to clarify, this does not contain T1 routes since in most cases its ECMP. This datastructure is only if a route has single nexthop all the time.

auto rt = it->second.begin();
while(rt != it->second.end())
{
SWSS_LOG_INFO("Updating route %s", (*rt).prefix.to_string().c_str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating route %s for what purpose? I think it is better to finish the sentence, it is unclear what do you update.


if (it == m_nextHops.end())
{
SWSS_LOG_INFO("No routes found for NH %s", nextHop.ip_address.to_string().c_str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this debug level info?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

auto it = neighbors_.getIpAddresses().begin();
while (it != neighbors_.getIpAddresses().end())
auto l_fn = [&] (NextHopKey nh_key, uint32_t val) {
SWSS_LOG_INFO("Inc ref for %s by %d", nh_key.ip_address.to_string().c_str(), val);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this debug level?

bool NeighOrch::hasNextHop(const NextHopKey &nexthop)
{
// First check if mux has NH
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why neighbor orch has to care if mux has NH or not?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When a route is programmed and if the neighbor is standby, then it will be a tunnel nexthop and not regular nexthop which will be owned by muxorch. So for mux neighbors, the nexthop management is by mux orch. For non-mux neighbor, it will follow the existing flow.

auto it = neighbors_.getIpAddresses().begin();
while (it != neighbors_.getIpAddresses().end())
auto l_fn = [&] (NextHopKey nh_key, uint32_t val) {
SWSS_LOG_INFO("Dec ref for %s by %d", nh_key.ip_address.to_string().c_str(), val);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

debug

for (uint32_t cnt = 0; cnt < val; ++cnt)
{
gNeighOrch->decreaseNextHopRefCount(nh_key);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of looping, can we just decrease the ref count by val refcount - val?

SWSS_LOG_INFO("Inc ref for %s by %d", nh_key.ip_address.to_string().c_str(), val);
for (uint32_t cnt = 0; cnt < val; ++cnt)
{
gNeighOrch->increaseNextHopRefCount(nh_key);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we increase the refcnt by value instead of looping here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is existing API and would need to define new if we have to increase by value. Also, considering the number of routes, prefer we can use this loop instead of defining new.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that will be cleaner, correct?

return false;
}

if (!gRouteOrch->validnexthopinNextHopGroup(nh_key, num_routes))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both line 574 and 580 has num_routes, this cause readability of the code.

i think it is more readable to get del_route_num in line 574 and get add_route_num in line 580, and you can get their substraction add_route_num - del_route_num as refcnt change.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In enable flow, it is moving from Tunnel NH -> Direct NH (Neighbor). In this case, the ref count must be incremented only for the Direct NH. Similarly for disable flow, ref count is decremented for Direct NH. However, there is no ref_cnt management for tunnel NH as it is one time created.

Copy link
Contributor

@lguohan lguohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🕐

SWSS_LOG_NOTICE("Remove overlay Nexthop %s", ol_nextHops.to_string().c_str());
removeOverlayNextHops(vrf_id, ol_nextHops);
}
else if (ol_nextHops.getSize() == 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is better to also check if the nexthop is pointing to the muxcable port or not.

const std::string & op = kfvOp(t);
TunnelInfo tunInfo;

for (auto idx : kfvFieldsValues(t))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: idx -> fieldValue

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

ret = cmdIpTunnelIfAddress(ipPrefix.to_string(), res);
if (ret != 0)
{
SWSS_LOG_WARN("Failed to assign IP addr for tun if %s", ipPrefix.to_string().c_str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe printout of res would help with debugging

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

ret = cmdIpTunnelRouteAdd(prefix, res);
if (ret != 0)
{
SWSS_LOG_WARN("Failed to add route %s", prefix.c_str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same regarding res here and throughout the PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

@@ -42,11 +42,15 @@ int main(int argc, char **argv)

try
{
vector<string> cfg_tun_tables = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: camelCase style

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

orchagent/muxorch.h Show resolved Hide resolved
@@ -94,7 +101,7 @@ class MuxCable
bool stateStandby();

bool aclHandler(sai_object_id_t, bool = true);
bool nbrHandler(bool = true);
bool nbrHandler(bool, bool = true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

args name would?? Documentation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed

orchagent/muxorch.h Show resolved Hide resolved
lguohan pushed a commit to sonic-net/sonic-utilities that referenced this pull request Feb 3, 2021
As part of dual-tor features, kernel tunnel interface (tun0) is being created. The routes over this is intended for kernel forwarding and not expected to be installed in ASIC.

Ref PR - sonic-net/sonic-swss#1615
@prsunny
Copy link
Collaborator Author

prsunny commented Feb 4, 2021

/Azurepipelines run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

Copy link
Contributor

@lguohan lguohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

@prsunny prsunny merged commit 0b0d24c into sonic-net:master Feb 4, 2021
@prsunny prsunny deleted the muxtunnel branch February 4, 2021 22:27
daall pushed a commit that referenced this pull request Feb 5, 2021
Program/Reprogram routes to hardware based on Mux status
Create tunnel interface (tun0) in kernel
Add/remove tunnel routes in kernel
daall pushed a commit to sonic-net/sonic-utilities that referenced this pull request Feb 6, 2021
As part of dual-tor features, kernel tunnel interface (tun0) is being created. The routes over this is intended for kernel forwarding and not expected to be installed in ASIC.

Ref PR - sonic-net/sonic-swss#1615
vmittal-msft pushed a commit to vmittal-msft/sonic-swss that referenced this pull request Feb 6, 2021
…c-net#1615)

Program/Reprogram routes to hardware based on Mux status
Create tunnel interface (tun0) in kernel
Add/remove tunnel routes in kernel
anand-kumar-subramanian pushed a commit to anand-kumar-subramanian/sonic-utilities that referenced this pull request Mar 2, 2021
As part of dual-tor features, kernel tunnel interface (tun0) is being created. The routes over this is intended for kernel forwarding and not expected to be installed in ASIC.

Ref PR - sonic-net/sonic-swss#1615
DavidZagury pushed a commit to DavidZagury/sonic-swss that referenced this pull request Mar 4, 2021
…c-net#1615)

Program/Reprogram routes to hardware based on Mux status
Create tunnel interface (tun0) in kernel
Add/remove tunnel routes in kernel
@prsunny prsunny restored the muxtunnel branch September 20, 2021 20:49
raphaelt-nvidia pushed a commit to raphaelt-nvidia/sonic-swss that referenced this pull request Oct 5, 2021
…c-net#1615)

Program/Reprogram routes to hardware based on Mux status
Create tunnel interface (tun0) in kernel
Add/remove tunnel routes in kernel
EdenGri pushed a commit to EdenGri/sonic-swss that referenced this pull request Feb 28, 2022
* [show] add support for muxcable metrics
What I did
Added support for show muxcable metrics. This essentially records what events came to different modules per se
for toggling the mux from one state to another.
for example

admin@sonic$ show muxcable metrics Ethernet0 --json

{
"linkmgrd_switch_active_start": "2021-May-13 10:00:21.420898",
"linkmgrd_switch_standby_end": "2021-May-13 10:01:15.696728",
"linkmgrd_switch_unknown_end": "2021-May-13 10:00:26.123319",
"xcvrd_switch_standby_end": "2021-May-13 10:01:15.696051",
"xcvrd_switch_standby_start": "2021-May-13 10:01:15.690835"
}

or

admin@sonic:$ show muxcable metrics Ethernet0

PORT EVENT TIME
--------- ---------------------------- ---------------------------
Ethernet0 linkmgrd_switch_active_start 2021-May-13 10:00:21.420898
Ethernet0 linkmgrd_switch_standby_end 2021-May-13 10:01:15.696728
Ethernet0 linkmgrd_switch_unknown_end 2021-May-13 10:00:26.123319
Ethernet0 xcvrd_switch_standby_end 2021-May-13 10:01:15.696051
Ethernet0 xcvrd_switch_standby_start 2021-May-13 10:01:15.690835

How I did it
added changes in show/muxcable.py by reading and publishing the state DB contents for the corresponding table


Signed-off-by: vaibhav-dahiya <vdahiya@microsoft.com>
malletvapid23 added a commit to malletvapid23/Sonic-Utility that referenced this pull request Aug 3, 2023
As part of dual-tor features, kernel tunnel interface (tun0) is being created. The routes over this is intended for kernel forwarding and not expected to be installed in ASIC.

Ref PR - sonic-net/sonic-swss#1615
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants