From 8a3a89780c729febc8eae3142b2e56e804a85f5a Mon Sep 17 00:00:00 2001 From: Shu0T1an ChenG Date: Fri, 28 Sep 2018 10:51:24 -0700 Subject: [PATCH] [portsyncd]: Store eth0 oper status into state DB portsyncd listens to the netlink messages. In order for SNMP to get the current oper status of the managemnt interface, portsyncd will store eth0 oper status explicitly into the state database. Signed-off-by: Shu0T1an ChenG --- portsyncd/Makefile.am | 4 +-- portsyncd/linksync.cpp | 81 ++++++++++++++++++++++++++++++++++++------ portsyncd/linksync.h | 2 +- 3 files changed, 73 insertions(+), 14 deletions(-) diff --git a/portsyncd/Makefile.am b/portsyncd/Makefile.am index 1a1157033e..eea740f843 100644 --- a/portsyncd/Makefile.am +++ b/portsyncd/Makefile.am @@ -1,4 +1,4 @@ -INCLUDES = -I $(top_srcdir) -I $(top_srcdir)/warmrestart +INCLUDES = -I $(top_srcdir) -I $(top_srcdir)/warmrestart -I $(top_srcdir)/cfgmgr bin_PROGRAMS = portsyncd @@ -8,7 +8,7 @@ else DBGFLAGS = -g endif -portsyncd_SOURCES = portsyncd.cpp linksync.cpp $(top_srcdir)/warmrestart/warm_restart.cpp $(top_srcdir)/warmrestart/warm_restart.h +portsyncd_SOURCES = portsyncd.cpp linksync.cpp $(top_srcdir)/warmrestart/warm_restart.cpp $(top_srcdir)/warmrestart/warm_restart.h $(top_srcdir)/cfgmgr/shellcmd.h portsyncd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) portsyncd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) diff --git a/portsyncd/linksync.cpp b/portsyncd/linksync.cpp index 4cd5e6f00d..e505611ab2 100644 --- a/portsyncd/linksync.cpp +++ b/portsyncd/linksync.cpp @@ -14,6 +14,7 @@ #include "linkcache.h" #include "portsyncd/linksync.h" #include "warm_restart.h" +#include "shellcmd.h" #include #include @@ -24,6 +25,7 @@ using namespace swss; #define VLAN_DRV_NAME "bridge" #define TEAM_DRV_NAME "team" +const string MGMT_PREFIX = "eth"; const string INTFS_PREFIX = "Ethernet"; const string LAG_PREFIX = "PortChannel"; @@ -40,8 +42,56 @@ extern "C" { extern struct if_nameindex *if_nameindex (void) __THROW; } LinkSync::LinkSync(DBConnector *appl_db, DBConnector *state_db) : m_portTableProducer(appl_db, APP_PORT_TABLE_NAME), m_portTable(appl_db, APP_PORT_TABLE_NAME), - m_statePortTable(state_db, STATE_PORT_TABLE_NAME) + m_statePortTable(state_db, STATE_PORT_TABLE_NAME), + m_stateMgmtPortTable(state_db, STATE_MGMT_PORT_TABLE_NAME) { + struct if_nameindex *if_ni, *idx_p; + if_ni = if_nameindex(); + + for (idx_p = if_ni; + idx_p != NULL && idx_p->if_index != 0 && idx_p->if_name != NULL; + idx_p++) + { + string key = idx_p->if_name; + + /* Explicitly store management ports oper status into the state database. + * This piece of information is used by SNMP. */ + if (!key.compare(0, MGMT_PREFIX.length(), MGMT_PREFIX)) + { + string cmd, res; + cmd = "cat /sys/class/net/" + key + "/operstate"; + try + { + EXEC_WITH_ERROR_THROW(cmd, res); + } + catch (...) + { + SWSS_LOG_WARN("Failed to get %s oper status", key.c_str()); + continue; + } + + /* Remove the trailing newline */ + if (res.length() >= 1 && res.at(res.length() - 1) == '\n') + { + res.erase(res.length() - 1); + /* The value of operstate will be either up or down */ + if (res != "up" && res != "down") + { + SWSS_LOG_WARN("Unknown %s oper status %s", + key.c_str(), res.c_str()); + } + FieldValueTuple fv("oper_status", res); + vector fvs; + fvs.push_back(fv); + + m_stateMgmtPortTable.set(key, fvs); + SWSS_LOG_INFO("Store %s oper status %s to state DB", + key.c_str(), res.c_str()); + } + continue; + } + } + if (!WarmStart::isWarmStart()) { /* See the comments for g_portSet in portsyncd.cpp */ @@ -61,16 +111,13 @@ LinkSync::LinkSync(DBConnector *appl_db, DBConnector *state_db) : } } - struct if_nameindex *if_ni, *idx_p; - if_ni = if_nameindex(); - if (if_ni == NULL) - { - return; - } - - for (idx_p = if_ni; ! (idx_p->if_index == 0 && idx_p->if_name == NULL); idx_p++) + for (idx_p = if_ni; + idx_p != NULL && idx_p->if_index != 0 && idx_p->if_name != NULL; + idx_p++) { string key = idx_p->if_name; + + /* Skip all non-frontpanel ports */ if (key.compare(0, INTFS_PREFIX.length(), INTFS_PREFIX)) { continue; @@ -78,8 +125,8 @@ LinkSync::LinkSync(DBConnector *appl_db, DBConnector *state_db) : m_ifindexOldNameMap[idx_p->if_index] = key; - /* Bring down the existing kernel interfaces */ string cmd, res; + /* Bring down the existing kernel interfaces */ SWSS_LOG_INFO("Bring down old interface %s(%d)", key.c_str(), idx_p->if_index); cmd = "ip link set " + key + " down"; try @@ -106,7 +153,8 @@ void LinkSync::onMsg(int nlmsg_type, struct nl_object *obj) string key = rtnl_link_get_name(link); if (key.compare(0, INTFS_PREFIX.length(), INTFS_PREFIX) && - key.compare(0, LAG_PREFIX.length(), LAG_PREFIX)) + key.compare(0, LAG_PREFIX.length(), LAG_PREFIX) && + key.compare(0, MGMT_PREFIX.length(), MGMT_PREFIX)) { return; } @@ -133,6 +181,17 @@ void LinkSync::onMsg(int nlmsg_type, struct nl_object *obj) nlmsg_type, key.c_str(), admin, oper, addrStr, ifindex, master); } + if (!key.compare(0, MGMT_PREFIX.length(), MGMT_PREFIX)) + { + FieldValueTuple fv("oper_status", oper ? "up" : "down"); + vector fvs; + fvs.push_back(fv); + m_stateMgmtPortTable.set(key, fvs); + SWSS_LOG_INFO("Store %s oper status %s to state DB", + key.c_str(), oper ? "up" : "down"); + return; + } + /* teamd instances are dealt in teamsyncd */ if (type && !strcmp(type, TEAM_DRV_NAME)) { diff --git a/portsyncd/linksync.h b/portsyncd/linksync.h index 5b31ed9b3c..d72e1ba124 100644 --- a/portsyncd/linksync.h +++ b/portsyncd/linksync.h @@ -20,7 +20,7 @@ class LinkSync : public NetMsg private: ProducerStateTable m_portTableProducer; - Table m_portTable, m_statePortTable; + Table m_portTable, m_statePortTable, m_stateMgmtPortTable; std::map m_ifindexNameMap; std::map m_ifindexOldNameMap;