Skip to content

Commit 8e635fd

Browse files
nikos-githublguohan
authored andcommitted
ECMP acceleration for physical i/f down events (sonic-net#351)
* ECMP acceleration for physical i/f down events * ECMP acceleration for physical i/f down events * ECMP acceleration for physical i/f down events * ECMP acceleration for physical i/f down events * add next hop group test Signed-off-by: Guohan Lu <[email protected]> * reformat the code to align with current style Signed-off-by: Guohan Lu <[email protected]>
1 parent ce78bf5 commit 8e635fd

File tree

7 files changed

+432
-53
lines changed

7 files changed

+432
-53
lines changed

orchagent/neighorch.cpp

+112
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
#include "logger.h"
44
#include "swssnet.h"
55
#include "crmorch.h"
6+
#include "routeorch.h"
67

78
extern sai_neighbor_api_t* sai_neighbor_api;
89
extern sai_next_hop_api_t* sai_next_hop_api;
910

1011
extern PortsOrch *gPortsOrch;
1112
extern sai_object_id_t gSwitchId;
1213
extern CrmOrch *gCrmOrch;
14+
extern RouteOrch *gRouteOrch;
1315

1416
NeighOrch::NeighOrch(DBConnector *db, string tableName, IntfsOrch *intfsOrch) :
1517
Orch(db, tableName), m_intfsOrch(intfsOrch)
@@ -59,6 +61,8 @@ bool NeighOrch::addNextHop(IpAddress ipAddress, string alias)
5961
NextHopEntry next_hop_entry;
6062
next_hop_entry.next_hop_id = next_hop_id;
6163
next_hop_entry.ref_count = 0;
64+
next_hop_entry.nh_flags = 0;
65+
next_hop_entry.if_alias = alias;
6266
m_syncdNextHops[ipAddress] = next_hop_entry;
6367

6468
m_intfsOrch->increaseRouterIntfsRefCount(alias);
@@ -75,6 +79,114 @@ bool NeighOrch::addNextHop(IpAddress ipAddress, string alias)
7579
return true;
7680
}
7781

82+
bool NeighOrch::setNextHopFlag(const IpAddress &ipaddr, const uint32_t nh_flag)
83+
{
84+
SWSS_LOG_ENTER();
85+
86+
auto nhop = m_syncdNextHops.find(ipaddr);
87+
bool rc = false;
88+
89+
assert(nhop != m_syncdNextHops.end());
90+
91+
if (nhop->second.nh_flags & nh_flag)
92+
{
93+
return true;
94+
}
95+
96+
nhop->second.nh_flags |= nh_flag;
97+
98+
switch (nh_flag)
99+
{
100+
case NHFLAGS_IFDOWN:
101+
rc = gRouteOrch->invalidnexthopinNextHopGroup(ipaddr);
102+
break;
103+
default:
104+
assert(0);
105+
break;
106+
}
107+
108+
return rc;
109+
}
110+
111+
bool NeighOrch::clearNextHopFlag(const IpAddress &ipaddr, const uint32_t nh_flag)
112+
{
113+
SWSS_LOG_ENTER();
114+
115+
auto nhop = m_syncdNextHops.find(ipaddr);
116+
bool rc = false;
117+
118+
assert(nhop != m_syncdNextHops.end());
119+
120+
if (!(nhop->second.nh_flags & nh_flag))
121+
{
122+
return true;
123+
}
124+
125+
nhop->second.nh_flags &= ~nh_flag;
126+
127+
switch (nh_flag)
128+
{
129+
case NHFLAGS_IFDOWN:
130+
rc = gRouteOrch->validnexthopinNextHopGroup(ipaddr);
131+
break;
132+
default:
133+
assert(0);
134+
break;
135+
}
136+
137+
return rc;
138+
}
139+
140+
bool NeighOrch::isNextHopFlagSet(const IpAddress &ipaddr, const uint32_t nh_flag)
141+
{
142+
SWSS_LOG_ENTER();
143+
144+
auto nhop = m_syncdNextHops.find(ipaddr);
145+
146+
assert(nhop != m_syncdNextHops.end());
147+
148+
if (nhop->second.nh_flags & nh_flag)
149+
{
150+
return true;
151+
}
152+
153+
return false;
154+
}
155+
156+
bool NeighOrch::ifChangeInformNextHop(const string &alias, bool if_up)
157+
{
158+
SWSS_LOG_ENTER();
159+
bool rc = true;
160+
161+
for (auto nhop = m_syncdNextHops.begin(); nhop != m_syncdNextHops.end(); ++nhop)
162+
{
163+
if (nhop->second.if_alias != alias)
164+
{
165+
continue;
166+
}
167+
168+
if (if_up)
169+
{
170+
rc = clearNextHopFlag(nhop->first, NHFLAGS_IFDOWN);
171+
}
172+
else
173+
{
174+
rc = setNextHopFlag(nhop->first, NHFLAGS_IFDOWN);
175+
}
176+
177+
if (rc == true)
178+
{
179+
continue;
180+
}
181+
else
182+
{
183+
break;
184+
}
185+
}
186+
187+
return rc;
188+
}
189+
78190
bool NeighOrch::removeNextHop(IpAddress ipAddress, string alias)
79191
{
80192
SWSS_LOG_ENTER();

orchagent/neighorch.h

+10
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include "ipaddress.h"
1010

11+
#define NHFLAGS_IFDOWN 0x1 // nexthop's outbound i/f is down
12+
1113
struct NeighborEntry
1214
{
1315
IpAddress ip_address; // neighbor IP address
@@ -33,6 +35,8 @@ struct NextHopEntry
3335
{
3436
sai_object_id_t next_hop_id; // next hop id
3537
int ref_count; // reference count
38+
uint32_t nh_flags; // flags
39+
string if_alias; // i/f name alias
3640
};
3741

3842
/* NeighborTable: NeighborEntry, neighbor MAC address */
@@ -62,6 +66,9 @@ class NeighOrch : public Orch, public Subject
6266

6367
bool getNeighborEntry(const IpAddress&, NeighborEntry&, MacAddress&);
6468

69+
bool ifChangeInformNextHop(const string &, bool);
70+
bool isNextHopFlagSet(const IpAddress &, const uint32_t);
71+
6572
private:
6673
IntfsOrch *m_intfsOrch;
6774

@@ -74,6 +81,9 @@ class NeighOrch : public Orch, public Subject
7481
bool addNeighbor(NeighborEntry, MacAddress);
7582
bool removeNeighbor(NeighborEntry);
7683

84+
bool setNextHopFlag(const IpAddress &, const uint32_t);
85+
bool clearNextHopFlag(const IpAddress &, const uint32_t);
86+
7787
void doTask(Consumer &consumer);
7888
};
7989

orchagent/orchdaemon.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,19 @@ using namespace swss;
1717
extern sai_switch_api_t* sai_switch_api;
1818
extern sai_object_id_t gSwitchId;
1919

20-
/* Global variable gPortsOrch declared */
20+
/*
21+
* Global orch daemon variables
22+
*/
2123
PortsOrch *gPortsOrch;
22-
/* Global variable gFdbOrch declared */
2324
FdbOrch *gFdbOrch;
24-
/*Global variable gAclOrch declared*/
25+
NeighOrch *gNeighOrch;
26+
RouteOrch *gRouteOrch;
2527
AclOrch *gAclOrch;
26-
/*Global variable gCrmOrch declared*/
2728
CrmOrch *gCrmOrch;
2829

2930
OrchDaemon::OrchDaemon(DBConnector *applDb, DBConnector *configDb) :
3031
m_applDb(applDb),
3132
m_configDb(configDb)
32-
3333
{
3434
SWSS_LOG_ENTER();
3535
}
@@ -64,8 +64,8 @@ bool OrchDaemon::init()
6464
gPortsOrch = new PortsOrch(m_applDb, ports_tables);
6565
gFdbOrch = new FdbOrch(m_applDb, APP_FDB_TABLE_NAME, gPortsOrch);
6666
IntfsOrch *intfs_orch = new IntfsOrch(m_applDb, APP_INTF_TABLE_NAME);
67-
NeighOrch *neigh_orch = new NeighOrch(m_applDb, APP_NEIGH_TABLE_NAME, intfs_orch);
68-
RouteOrch *route_orch = new RouteOrch(m_applDb, APP_ROUTE_TABLE_NAME, neigh_orch);
67+
gNeighOrch = new NeighOrch(m_applDb, APP_NEIGH_TABLE_NAME, intfs_orch);
68+
gRouteOrch = new RouteOrch(m_applDb, APP_ROUTE_TABLE_NAME, gNeighOrch);
6969
CoppOrch *copp_orch = new CoppOrch(m_applDb, APP_COPP_TABLE_NAME);
7070
TunnelDecapOrch *tunnel_decap_orch = new TunnelDecapOrch(m_applDb, APP_TUNNEL_DECAP_TABLE_NAME);
7171

@@ -94,16 +94,16 @@ bool OrchDaemon::init()
9494

9595
TableConnector appDbMirrorSession(m_applDb, APP_MIRROR_SESSION_TABLE_NAME);
9696
TableConnector confDbMirrorSession(m_configDb, CFG_MIRROR_SESSION_TABLE_NAME);
97-
MirrorOrch *mirror_orch = new MirrorOrch(appDbMirrorSession, confDbMirrorSession, gPortsOrch, route_orch, neigh_orch, gFdbOrch);
97+
MirrorOrch *mirror_orch = new MirrorOrch(appDbMirrorSession, confDbMirrorSession, gPortsOrch, gRouteOrch, gNeighOrch, gFdbOrch);
9898
VRFOrch *vrf_orch = new VRFOrch(m_configDb, CFG_VRF_TABLE_NAME);
9999

100100
vector<string> acl_tables = {
101101
CFG_ACL_TABLE_NAME,
102102
CFG_ACL_RULE_TABLE_NAME
103103
};
104-
gAclOrch = new AclOrch(m_configDb, acl_tables, gPortsOrch, mirror_orch, neigh_orch, route_orch);
104+
gAclOrch = new AclOrch(m_configDb, acl_tables, gPortsOrch, mirror_orch, gNeighOrch, gRouteOrch);
105105

106-
m_orchList = { switch_orch, gCrmOrch, gPortsOrch, intfs_orch, neigh_orch, route_orch, copp_orch, tunnel_decap_orch, qos_orch, buffer_orch, mirror_orch, gAclOrch, gFdbOrch, vrf_orch };
106+
m_orchList = { switch_orch, gCrmOrch, gPortsOrch, intfs_orch, gNeighOrch, gRouteOrch, copp_orch, tunnel_decap_orch, qos_orch, buffer_orch, mirror_orch, gAclOrch, gFdbOrch, vrf_orch };
107107
m_select = new Select();
108108

109109
vector<string> pfc_wd_tables = {

orchagent/portsorch.cpp

+23-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "portsorch.h"
2+
#include "neighorch.h"
23

34
#include <cassert>
45
#include <fstream>
@@ -27,6 +28,7 @@ extern sai_hostif_api_t* sai_hostif_api;
2728
extern sai_acl_api_t* sai_acl_api;
2829
extern sai_queue_api_t *sai_queue_api;
2930
extern sai_object_id_t gSwitchId;
31+
extern NeighOrch *gNeighOrch;
3032
extern CrmOrch *gCrmOrch;
3133

3234
#define VLAN_PREFIX "Vlan"
@@ -867,23 +869,30 @@ bool PortsOrch::setHostIntfsOperStatus(sai_object_id_t port_id, bool up)
867869

868870
for (auto it = m_portList.begin(); it != m_portList.end(); it++)
869871
{
870-
if (it->second.m_port_id == port_id)
872+
if (it->second.m_port_id != port_id)
871873
{
872-
sai_attribute_t attr;
873-
attr.id = SAI_HOSTIF_ATTR_OPER_STATUS;
874-
attr.value.booldata = up;
874+
continue;
875+
}
875876

876-
sai_status_t status = sai_hostif_api->set_hostif_attribute(it->second.m_hif_id, &attr);
877-
if (status != SAI_STATUS_SUCCESS)
878-
{
879-
SWSS_LOG_WARN("Failed to set operation status %s to host interface %s",
880-
up ? "UP" : "DOWN", it->second.m_alias.c_str());
881-
return false;
882-
}
883-
SWSS_LOG_NOTICE("Set operation status %s to host interface %s",
884-
up ? "UP" : "DOWN", it->second.m_alias.c_str());
885-
return true;
877+
sai_attribute_t attr;
878+
attr.id = SAI_HOSTIF_ATTR_OPER_STATUS;
879+
attr.value.booldata = up;
880+
881+
sai_status_t status = sai_hostif_api->set_hostif_attribute(it->second.m_hif_id, &attr);
882+
if (status != SAI_STATUS_SUCCESS)
883+
{
884+
SWSS_LOG_WARN("Failed to set operation status %s to host interface %s",
885+
up ? "UP" : "DOWN", it->second.m_alias.c_str());
886+
return false;
886887
}
888+
SWSS_LOG_NOTICE("Set operation status %s to host interface %s",
889+
up ? "UP" : "DOWN", it->second.m_alias.c_str());
890+
if (gNeighOrch->ifChangeInformNextHop(it->second.m_alias, up) == false)
891+
{
892+
SWSS_LOG_WARN("Inform nexthop operation failed for interface %s",
893+
it->second.m_alias.c_str());
894+
}
895+
return true;
887896
}
888897
return false;
889898
}

0 commit comments

Comments
 (0)