Skip to content

Commit 1be7d53

Browse files
authored
Merge branch 'master' into ntt_fpmsyncd_enhanced
2 parents f017e8c + 48908b2 commit 1be7d53

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2903
-454
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ tests/mock_tests/tests_portsyncd
8383

8484
# Test Files #
8585
##############
86+
*gcda
87+
*gcno
8688
tests/log
8789
tests/mock_tests/test-suite.log
8890
tests/mock_tests/tests.log
@@ -92,5 +94,3 @@ tests/tests.log
9294
tests/tests.trs
9395
tests/mock_tests/**/*log
9496
tests/mock_tests/**/*trs
95-
orchagent/p4orch/tests/**/*gcda
96-
orchagent/p4orch/tests/**/*gcno

cfgmgr/teammgr.cpp

Lines changed: 39 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <net/if.h>
1717
#include <sys/ioctl.h>
1818
#include <sys/stat.h>
19+
#include <sys/wait.h>
20+
#include <sys/types.h>
1921
#include <signal.h>
2022

2123

@@ -171,18 +173,29 @@ void TeamMgr::cleanTeamProcesses()
171173
SWSS_LOG_ENTER();
172174
SWSS_LOG_NOTICE("Cleaning up LAGs during shutdown...");
173175

174-
std::unordered_map<std::string, pid_t> aliasPidMap;
176+
std::unordered_map<std::string, int> aliasPidMap;
175177

176178
for (const auto& alias: m_lagList)
177179
{
178-
std::string res;
179180
pid_t pid;
181+
// Sleep for 10 milliseconds so as to not overwhelm the netlink
182+
// socket buffers with events about interfaces going down
183+
std::this_thread::sleep_for(std::chrono::milliseconds(10));
180184

181185
try
182186
{
183-
std::stringstream cmd;
184-
cmd << "cat " << shellquote("/var/run/teamd/" + alias + ".pid");
185-
EXEC_WITH_ERROR_THROW(cmd.str(), res);
187+
ifstream pidFile("/var/run/teamd/" + alias + ".pid");
188+
if (pidFile.is_open())
189+
{
190+
pidFile >> pid;
191+
aliasPidMap[alias] = pid;
192+
SWSS_LOG_INFO("Read port channel %s pid %d", alias.c_str(), pid);
193+
}
194+
else
195+
{
196+
SWSS_LOG_NOTICE("Unable to read pid file for %s, skipping...", alias.c_str());
197+
continue;
198+
}
186199
}
187200
catch (const std::exception &e)
188201
{
@@ -191,46 +204,28 @@ void TeamMgr::cleanTeamProcesses()
191204
continue;
192205
}
193206

194-
try
195-
{
196-
pid = static_cast<pid_t>(std::stoul(res, nullptr, 10));
197-
aliasPidMap[alias] = pid;
198-
199-
SWSS_LOG_INFO("Read port channel %s pid %d", alias.c_str(), pid);
200-
}
201-
catch (const std::exception &e)
207+
if (kill(pid, SIGTERM))
202208
{
203-
SWSS_LOG_ERROR("Failed to read port channel %s pid: %s", alias.c_str(), e.what());
204-
continue;
209+
SWSS_LOG_ERROR("Failed to send SIGTERM to port channel %s pid %d: %s", alias.c_str(), pid, strerror(errno));
210+
aliasPidMap.erase(alias);
205211
}
206-
207-
try
212+
else
208213
{
209-
std::stringstream cmd;
210-
cmd << "kill -TERM " << pid;
211-
EXEC_WITH_ERROR_THROW(cmd.str(), res);
212-
213214
SWSS_LOG_NOTICE("Sent SIGTERM to port channel %s pid %d", alias.c_str(), pid);
214215
}
215-
catch (const std::exception &e)
216-
{
217-
SWSS_LOG_ERROR("Failed to send SIGTERM to port channel %s pid %d: %s", alias.c_str(), pid, e.what());
218-
aliasPidMap.erase(alias);
219-
}
220216
}
221217

222218
for (const auto& cit: aliasPidMap)
223219
{
224220
const auto &alias = cit.first;
225221
const auto &pid = cit.second;
226222

227-
std::stringstream cmd;
228-
std::string res;
229-
230223
SWSS_LOG_NOTICE("Waiting for port channel %s pid %d to stop...", alias.c_str(), pid);
231224

232-
cmd << "tail -f --pid=" << pid << " /dev/null";
233-
EXEC_WITH_ERROR_THROW(cmd.str(), res);
225+
while (!kill(pid, 0))
226+
{
227+
std::this_thread::sleep_for(std::chrono::milliseconds(10));
228+
}
234229
}
235230

236231
SWSS_LOG_NOTICE("LAGs cleanup is done");
@@ -658,42 +653,25 @@ bool TeamMgr::removeLag(const string &alias)
658653
{
659654
SWSS_LOG_ENTER();
660655

661-
stringstream cmd;
662-
string res;
663656
pid_t pid;
664657

665-
try
666-
{
667-
std::stringstream cmd;
668-
cmd << "cat " << shellquote("/var/run/teamd/" + alias + ".pid");
669-
EXEC_WITH_ERROR_THROW(cmd.str(), res);
670-
}
671-
catch (const std::exception &e)
672658
{
673-
SWSS_LOG_NOTICE("Failed to remove non-existent port channel %s pid...", alias.c_str());
674-
return false;
675-
}
676-
677-
try
678-
{
679-
pid = static_cast<pid_t>(std::stoul(res, nullptr, 10));
680-
SWSS_LOG_INFO("Read port channel %s pid %d", alias.c_str(), pid);
681-
}
682-
catch (const std::exception &e)
683-
{
684-
SWSS_LOG_ERROR("Failed to read port channel %s pid: %s", alias.c_str(), e.what());
685-
return false;
659+
ifstream pidfile("/var/run/teamd/" + alias + ".pid");
660+
if (pidfile.is_open())
661+
{
662+
pidfile >> pid;
663+
SWSS_LOG_INFO("Read port channel %s pid %d", alias.c_str(), pid);
664+
}
665+
else
666+
{
667+
SWSS_LOG_NOTICE("Failed to remove non-existent port channel %s pid...", alias.c_str());
668+
return false;
669+
}
686670
}
687671

688-
try
689-
{
690-
std::stringstream cmd;
691-
cmd << "kill -TERM " << pid;
692-
EXEC_WITH_ERROR_THROW(cmd.str(), res);
693-
}
694-
catch (const std::exception &e)
672+
if (kill(pid, SIGTERM))
695673
{
696-
SWSS_LOG_ERROR("Failed to send SIGTERM to port channel %s pid %d: %s", alias.c_str(), pid, e.what());
674+
SWSS_LOG_ERROR("Failed to send SIGTERM to port channel %s pid %d: %s", alias.c_str(), pid, strerror(errno));
697675
return false;
698676
}
699677

cfgmgr/vlanmgr.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,11 @@ VlanMgr::VlanMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
8383
// /sbin/ip link del dummy 2>/dev/null;
8484
// /sbin/ip link add dummy type dummy &&
8585
// /sbin/ip link set dummy master Bridge &&
86-
// /sbin/ip link set dummy up"
86+
// /sbin/ip link set dummy up;
87+
// /sbin/ip link set Bridge down &&
88+
// /sbin/ip link set Bridge up"
89+
// Note: We shutdown and start-up the Bridge at the end to ensure that its
90+
// link-local IPv6 address matches its MAC address.
8791

8892
const std::string cmds = std::string("")
8993
+ BASH_CMD + " -c \""
@@ -95,7 +99,9 @@ VlanMgr::VlanMgr(DBConnector *cfgDb, DBConnector *appDb, DBConnector *stateDb, c
9599
+ IP_CMD + " link del dev dummy 2>/dev/null; "
96100
+ IP_CMD + " link add dummy type dummy && "
97101
+ IP_CMD + " link set dummy master " + DOT1Q_BRIDGE_NAME + " && "
98-
+ IP_CMD + " link set dummy up" + "\"";
102+
+ IP_CMD + " link set dummy up; "
103+
+ IP_CMD + " link set " + DOT1Q_BRIDGE_NAME + " down && "
104+
+ IP_CMD + " link set " + DOT1Q_BRIDGE_NAME + " up\"";
99105

100106
std::string res;
101107
EXEC_WITH_ERROR_THROW(cmds, res);
@@ -193,15 +199,34 @@ bool VlanMgr::setHostVlanMac(int vlan_id, const string &mac)
193199
{
194200
SWSS_LOG_ENTER();
195201

202+
std::string res;
203+
204+
/*
205+
* Bring down the bridge before changing MAC addresses of the bridge and the VLAN interface.
206+
* This is done so that the IPv6 link-local addresses of the bridge and the VLAN interface
207+
* are updated after MAC change.
208+
* /sbin/ip link set Bridge down
209+
*/
210+
string bridge_down(IP_CMD " link set " DOT1Q_BRIDGE_NAME " down");
211+
EXEC_WITH_ERROR_THROW(bridge_down, res);
212+
196213
// The command should be generated as:
197-
// /sbin/ip link set Vlan{{vlan_id}} address {{mac}}
214+
// /sbin/ip link set Vlan{{vlan_id}} address {{mac}} &&
215+
// /sbin/ip link set Bridge address {{mac}}
198216
ostringstream cmds;
199217
cmds << IP_CMD " link set " VLAN_PREFIX + std::to_string(vlan_id) + " address " << shellquote(mac) << " && "
200218
IP_CMD " link set " DOT1Q_BRIDGE_NAME " address " << shellquote(mac);
201-
202-
std::string res;
219+
res.clear();
203220
EXEC_WITH_ERROR_THROW(cmds.str(), res);
204221

222+
/*
223+
* Start up the bridge again.
224+
* /sbin/ip link set Bridge up
225+
*/
226+
string bridge_up(IP_CMD " link set " DOT1Q_BRIDGE_NAME " up");
227+
res.clear();
228+
EXEC_WITH_ERROR_THROW(bridge_up, res);
229+
205230
return true;
206231
}
207232

debian/rules

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ override_dh_auto_install:
4444
ifeq ($(ENABLE_GCOV), y)
4545
mkdir -p debian/swss/tmp/gcov
4646
lcov -c --directory . --no-external --exclude "$(shell pwd)/tests/*" --exclude "$(shell pwd)/**/tests/*" --ignore-errors gcov --output-file coverage.info
47+
lcov --add-tracefile coverage.info -o coverage.info
4748
lcov_cobertura coverage.info -o coverage.xml
4849
find ./ -type f -regex '.*\.\(h\|cpp\|gcno\|info\)' | tar -cf debian/swss/tmp/gcov/gcov-source.tar -T -
4950
endif

orchagent/Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ orchagent_SOURCES += p4orch/p4orch.cpp \
138138

139139
orchagent_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) $(CFLAGS_ASAN)
140140
orchagent_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_SAI) $(CFLAGS_ASAN)
141-
orchagent_LDADD = $(LDFLAGS_ASAN) -lnl-3 -lnl-route-3 -lpthread -lsairedis -lsaimeta -lsaimetadata -lswsscommon -lzmq -lprotobuf -ldashapi
141+
orchagent_LDADD = $(LDFLAGS_ASAN) -lnl-3 -lnl-route-3 -lpthread -lsairedis -lsaimeta -lsaimetadata -lswsscommon -lzmq -lprotobuf -ldashapi -ljemalloc
142142

143143
routeresync_SOURCES = routeresync.cpp
144144
routeresync_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_ASAN)

orchagent/aclorch.cpp

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "timer.h"
1212
#include "crmorch.h"
1313
#include "sai_serialize.h"
14+
#include "directory.h"
1415

1516
using namespace std;
1617
using namespace swss;
@@ -30,6 +31,7 @@ extern PortsOrch* gPortsOrch;
3031
extern CrmOrch *gCrmOrch;
3132
extern SwitchOrch *gSwitchOrch;
3233
extern string gMySwitchType;
34+
extern Directory<Orch*> gDirectory;
3335

3436
#define MIN_VLAN_ID 1 // 0 is a reserved VLAN ID
3537
#define MAX_VLAN_ID 4095 // 4096 is a reserved VLAN ID
@@ -617,6 +619,35 @@ bool AclTableRangeMatch::validateAclRuleMatch(const AclRule& rule) const
617619
return true;
618620
}
619621

622+
void AclRule::TunnelNH::load(const std::string& target)
623+
{
624+
parse(target);
625+
626+
VxlanTunnelOrch* vxlan_orch = gDirectory.get<VxlanTunnelOrch*>();
627+
/* Only the first call creates the SAI object, further calls just increment the ref count */
628+
oid = vxlan_orch->createNextHopTunnel(tunnel_name, endpoint_ip, mac, vni);
629+
}
630+
631+
void AclRule::TunnelNH::parse(const std::string& target)
632+
{
633+
/* Supported Format: endpoint_ip@tunnel_name */
634+
auto at_pos = target.find('@');
635+
if (at_pos == std::string::npos)
636+
{
637+
throw std::logic_error("Invalid format for Tunnel Next Hop");
638+
}
639+
640+
endpoint_ip = swss::IpAddress(target.substr(0, at_pos));
641+
tunnel_name = target.substr(at_pos + 1);
642+
}
643+
644+
void AclRule::TunnelNH::clear()
645+
{
646+
oid = SAI_NULL_OBJECT_ID;
647+
VxlanTunnelOrch* vxlan_orch = gDirectory.get<VxlanTunnelOrch*>();
648+
vxlan_orch->removeNextHopTunnel(tunnel_name, endpoint_ip, mac, vni);
649+
}
650+
620651
string AclTableType::getName() const
621652
{
622653
return m_name;
@@ -1308,7 +1339,17 @@ void AclRule::decreaseNextHopRefCount()
13081339
}
13091340
m_redirect_target_next_hop_group.clear();
13101341
}
1311-
1342+
if (m_redirect_target_tun_nh.oid != SAI_NULL_OBJECT_ID)
1343+
{
1344+
try
1345+
{
1346+
m_redirect_target_tun_nh.clear();
1347+
}
1348+
catch (const std::runtime_error& e)
1349+
{
1350+
SWSS_LOG_ERROR("Failed to remove tunnel nh reference %s, ACL Rule: %s", e.what(), m_id.c_str());
1351+
}
1352+
}
13121353
return;
13131354
}
13141355

@@ -2001,21 +2042,38 @@ sai_object_id_t AclRulePacket::getRedirectObjectId(const string& redirect_value)
20012042
try
20022043
{
20032044
NextHopKey nh(target);
2004-
if (!m_pAclOrch->m_neighOrch->hasNextHop(nh))
2045+
if (m_pAclOrch->m_neighOrch->hasNextHop(nh))
20052046
{
2006-
SWSS_LOG_ERROR("ACL Redirect action target next hop ip: '%s' doesn't exist on the switch", nh.to_string().c_str());
2007-
return SAI_NULL_OBJECT_ID;
2047+
m_redirect_target_next_hop = target;
2048+
m_pAclOrch->m_neighOrch->increaseNextHopRefCount(nh);
2049+
return m_pAclOrch->m_neighOrch->getNextHopId(nh);
20082050
}
2009-
2010-
m_redirect_target_next_hop = target;
2011-
m_pAclOrch->m_neighOrch->increaseNextHopRefCount(nh);
2012-
return m_pAclOrch->m_neighOrch->getNextHopId(nh);
20132051
}
20142052
catch (...)
20152053
{
20162054
// no error, just try next variant
20172055
}
20182056

2057+
// Try to parse if this is a tunnel nexthop.
2058+
try
2059+
{
2060+
m_redirect_target_tun_nh.load(target);
2061+
if (SAI_NULL_OBJECT_ID != m_redirect_target_tun_nh.oid)
2062+
{
2063+
SWSS_LOG_INFO("Tunnel Next Hop Found: oid:0x%" PRIx64 ", target: %s", m_redirect_target_tun_nh.oid, target.c_str());
2064+
return m_redirect_target_tun_nh.oid;
2065+
}
2066+
}
2067+
catch (std::logic_error& e)
2068+
{
2069+
// no error, just try next variant
2070+
}
2071+
catch (const std::runtime_error& e)
2072+
{
2073+
SWSS_LOG_ERROR("Failed to create/fetch tunnel next hop, %s, err: %s", target.c_str(), e.what());
2074+
return SAI_NULL_OBJECT_ID;
2075+
}
2076+
20192077
// try to parse nh group the set of <ip address, interface name>
20202078
try
20212079
{

0 commit comments

Comments
 (0)