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

ECMP acceleration for physical i/f down events #351

Merged
merged 6 commits into from
Mar 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 112 additions & 0 deletions orchagent/neighorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
#include "logger.h"
#include "swssnet.h"
#include "crmorch.h"
#include "routeorch.h"

extern sai_neighbor_api_t* sai_neighbor_api;
extern sai_next_hop_api_t* sai_next_hop_api;

extern PortsOrch *gPortsOrch;
extern sai_object_id_t gSwitchId;
extern CrmOrch *gCrmOrch;
extern RouteOrch *gRouteOrch;

NeighOrch::NeighOrch(DBConnector *db, string tableName, IntfsOrch *intfsOrch) :
Orch(db, tableName), m_intfsOrch(intfsOrch)
Expand Down Expand Up @@ -59,6 +61,8 @@ bool NeighOrch::addNextHop(IpAddress ipAddress, string alias)
NextHopEntry next_hop_entry;
next_hop_entry.next_hop_id = next_hop_id;
next_hop_entry.ref_count = 0;
next_hop_entry.nh_flags = 0;
next_hop_entry.if_alias = alias;
m_syncdNextHops[ipAddress] = next_hop_entry;

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

bool NeighOrch::setNextHopFlag(const IpAddress &ipaddr, const uint32_t nh_flag)
{
SWSS_LOG_ENTER();

auto nhop = m_syncdNextHops.find(ipaddr);
bool rc = false;

assert(nhop != m_syncdNextHops.end());

if (nhop->second.nh_flags & nh_flag)
{
return true;
}

nhop->second.nh_flags |= nh_flag;

switch (nh_flag)
{
case NHFLAGS_IFDOWN:
rc = gRouteOrch->invalidnexthopinNextHopGroup(ipaddr);
break;
default:
assert(0);
break;
}

return rc;
}

bool NeighOrch::clearNextHopFlag(const IpAddress &ipaddr, const uint32_t nh_flag)
{
SWSS_LOG_ENTER();

auto nhop = m_syncdNextHops.find(ipaddr);
bool rc = false;

assert(nhop != m_syncdNextHops.end());

if (!(nhop->second.nh_flags & nh_flag))
{
return true;
}

nhop->second.nh_flags &= ~nh_flag;

switch (nh_flag)
{
case NHFLAGS_IFDOWN:
rc = gRouteOrch->validnexthopinNextHopGroup(ipaddr);
break;
default:
assert(0);
break;
}

return rc;
}

bool NeighOrch::isNextHopFlagSet(const IpAddress &ipaddr, const uint32_t nh_flag)
{
SWSS_LOG_ENTER();

auto nhop = m_syncdNextHops.find(ipaddr);

assert(nhop != m_syncdNextHops.end());

if (nhop->second.nh_flags & nh_flag)
{
return true;
}

return false;
}

bool NeighOrch::ifChangeInformNextHop(const string &alias, bool if_up)
{
SWSS_LOG_ENTER();
bool rc = true;

for (auto nhop = m_syncdNextHops.begin(); nhop != m_syncdNextHops.end(); ++nhop)
{
if (nhop->second.if_alias != alias)
{
continue;
}

if (if_up)
{
rc = clearNextHopFlag(nhop->first, NHFLAGS_IFDOWN);
}
else
{
rc = setNextHopFlag(nhop->first, NHFLAGS_IFDOWN);
}

if (rc == true)
{
continue;
}
else
{
break;
}
}

return rc;
}

bool NeighOrch::removeNextHop(IpAddress ipAddress, string alias)
{
SWSS_LOG_ENTER();
Expand Down
10 changes: 10 additions & 0 deletions orchagent/neighorch.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#include "ipaddress.h"

#define NHFLAGS_IFDOWN 0x1 // nexthop's outbound i/f is down

struct NeighborEntry
{
IpAddress ip_address; // neighbor IP address
Expand All @@ -33,6 +35,8 @@ struct NextHopEntry
{
sai_object_id_t next_hop_id; // next hop id
int ref_count; // reference count
uint32_t nh_flags; // flags
string if_alias; // i/f name alias
};

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

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

bool ifChangeInformNextHop(const string &, bool);
bool isNextHopFlagSet(const IpAddress &, const uint32_t);

private:
IntfsOrch *m_intfsOrch;

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

bool setNextHopFlag(const IpAddress &, const uint32_t);
bool clearNextHopFlag(const IpAddress &, const uint32_t);

void doTask(Consumer &consumer);
};

Expand Down
20 changes: 10 additions & 10 deletions orchagent/orchdaemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@ using namespace swss;
extern sai_switch_api_t* sai_switch_api;
extern sai_object_id_t gSwitchId;

/* Global variable gPortsOrch declared */
/*
* Global orch daemon variables
*/
PortsOrch *gPortsOrch;
/* Global variable gFdbOrch declared */
FdbOrch *gFdbOrch;
/*Global variable gAclOrch declared*/
NeighOrch *gNeighOrch;
RouteOrch *gRouteOrch;
AclOrch *gAclOrch;
/*Global variable gCrmOrch declared*/
CrmOrch *gCrmOrch;

OrchDaemon::OrchDaemon(DBConnector *applDb, DBConnector *configDb) :
m_applDb(applDb),
m_configDb(configDb)

{
SWSS_LOG_ENTER();
}
Expand Down Expand Up @@ -64,8 +64,8 @@ bool OrchDaemon::init()
gPortsOrch = new PortsOrch(m_applDb, ports_tables);
gFdbOrch = new FdbOrch(m_applDb, APP_FDB_TABLE_NAME, gPortsOrch);
IntfsOrch *intfs_orch = new IntfsOrch(m_applDb, APP_INTF_TABLE_NAME);
NeighOrch *neigh_orch = new NeighOrch(m_applDb, APP_NEIGH_TABLE_NAME, intfs_orch);
RouteOrch *route_orch = new RouteOrch(m_applDb, APP_ROUTE_TABLE_NAME, neigh_orch);
gNeighOrch = new NeighOrch(m_applDb, APP_NEIGH_TABLE_NAME, intfs_orch);
gRouteOrch = new RouteOrch(m_applDb, APP_ROUTE_TABLE_NAME, gNeighOrch);
CoppOrch *copp_orch = new CoppOrch(m_applDb, APP_COPP_TABLE_NAME);
TunnelDecapOrch *tunnel_decap_orch = new TunnelDecapOrch(m_applDb, APP_TUNNEL_DECAP_TABLE_NAME);

Expand Down Expand Up @@ -94,16 +94,16 @@ bool OrchDaemon::init()

TableConnector appDbMirrorSession(m_applDb, APP_MIRROR_SESSION_TABLE_NAME);
TableConnector confDbMirrorSession(m_configDb, CFG_MIRROR_SESSION_TABLE_NAME);
MirrorOrch *mirror_orch = new MirrorOrch(appDbMirrorSession, confDbMirrorSession, gPortsOrch, route_orch, neigh_orch, gFdbOrch);
MirrorOrch *mirror_orch = new MirrorOrch(appDbMirrorSession, confDbMirrorSession, gPortsOrch, gRouteOrch, gNeighOrch, gFdbOrch);
VRFOrch *vrf_orch = new VRFOrch(m_configDb, CFG_VRF_TABLE_NAME);

vector<string> acl_tables = {
CFG_ACL_TABLE_NAME,
CFG_ACL_RULE_TABLE_NAME
};
gAclOrch = new AclOrch(m_configDb, acl_tables, gPortsOrch, mirror_orch, neigh_orch, route_orch);
gAclOrch = new AclOrch(m_configDb, acl_tables, gPortsOrch, mirror_orch, gNeighOrch, gRouteOrch);

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 };
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 };
m_select = new Select();

vector<string> pfc_wd_tables = {
Expand Down
37 changes: 23 additions & 14 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "portsorch.h"
#include "neighorch.h"

#include <cassert>
#include <fstream>
Expand Down Expand Up @@ -27,6 +28,7 @@ extern sai_hostif_api_t* sai_hostif_api;
extern sai_acl_api_t* sai_acl_api;
extern sai_queue_api_t *sai_queue_api;
extern sai_object_id_t gSwitchId;
extern NeighOrch *gNeighOrch;
extern CrmOrch *gCrmOrch;

#define VLAN_PREFIX "Vlan"
Expand Down Expand Up @@ -852,23 +854,30 @@ bool PortsOrch::setHostIntfsOperStatus(sai_object_id_t port_id, bool up)

for (auto it = m_portList.begin(); it != m_portList.end(); it++)
{
if (it->second.m_port_id == port_id)
if (it->second.m_port_id != port_id)
{
sai_attribute_t attr;
attr.id = SAI_HOSTIF_ATTR_OPER_STATUS;
attr.value.booldata = up;
continue;
}

sai_status_t status = sai_hostif_api->set_hostif_attribute(it->second.m_hif_id, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_WARN("Failed to set operation status %s to host interface %s",
up ? "UP" : "DOWN", it->second.m_alias.c_str());
return false;
}
SWSS_LOG_NOTICE("Set operation status %s to host interface %s",
up ? "UP" : "DOWN", it->second.m_alias.c_str());
return true;
sai_attribute_t attr;
attr.id = SAI_HOSTIF_ATTR_OPER_STATUS;
attr.value.booldata = up;

sai_status_t status = sai_hostif_api->set_hostif_attribute(it->second.m_hif_id, &attr);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_WARN("Failed to set operation status %s to host interface %s",
up ? "UP" : "DOWN", it->second.m_alias.c_str());
return false;
}
SWSS_LOG_NOTICE("Set operation status %s to host interface %s",
up ? "UP" : "DOWN", it->second.m_alias.c_str());
if (gNeighOrch->ifChangeInformNextHop(it->second.m_alias, up) == false)
{
SWSS_LOG_WARN("Inform nexthop operation failed for interface %s",
it->second.m_alias.c_str());
}
return true;
}
return false;
}
Expand Down
Loading