Skip to content

Commit

Permalink
Merge pull request #39 from Azure/dev/arlakshm/code_sync
Browse files Browse the repository at this point in the history
[codesync] from sonic-net/sonic-swss/202405 to azure/sonic-swss.msft/202405
  • Loading branch information
arlakshm authored Feb 21, 2025
2 parents 463df23 + 9f176ab commit c3f2a83
Show file tree
Hide file tree
Showing 7 changed files with 289 additions and 80 deletions.
100 changes: 39 additions & 61 deletions cfgmgr/teammgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <signal.h>


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

std::unordered_map<std::string, pid_t> aliasPidMap;
std::unordered_map<std::string, int> aliasPidMap;

for (const auto& alias: m_lagList)
{
std::string res;
pid_t pid;
// Sleep for 10 milliseconds so as to not overwhelm the netlink
// socket buffers with events about interfaces going down
std::this_thread::sleep_for(std::chrono::milliseconds(10));

try
{
std::stringstream cmd;
cmd << "cat " << shellquote("/var/run/teamd/" + alias + ".pid");
EXEC_WITH_ERROR_THROW(cmd.str(), res);
ifstream pidFile("/var/run/teamd/" + alias + ".pid");
if (pidFile.is_open())
{
pidFile >> pid;
aliasPidMap[alias] = pid;
SWSS_LOG_INFO("Read port channel %s pid %d", alias.c_str(), pid);
}
else
{
SWSS_LOG_NOTICE("Unable to read pid file for %s, skipping...", alias.c_str());
continue;
}
}
catch (const std::exception &e)
{
Expand All @@ -191,46 +204,28 @@ void TeamMgr::cleanTeamProcesses()
continue;
}

try
{
pid = static_cast<pid_t>(std::stoul(res, nullptr, 10));
aliasPidMap[alias] = pid;

SWSS_LOG_INFO("Read port channel %s pid %d", alias.c_str(), pid);
}
catch (const std::exception &e)
if (kill(pid, SIGTERM))
{
SWSS_LOG_ERROR("Failed to read port channel %s pid: %s", alias.c_str(), e.what());
continue;
SWSS_LOG_ERROR("Failed to send SIGTERM to port channel %s pid %d: %s", alias.c_str(), pid, strerror(errno));
aliasPidMap.erase(alias);
}

try
else
{
std::stringstream cmd;
cmd << "kill -TERM " << pid;
EXEC_WITH_ERROR_THROW(cmd.str(), res);

SWSS_LOG_NOTICE("Sent SIGTERM to port channel %s pid %d", alias.c_str(), pid);
}
catch (const std::exception &e)
{
SWSS_LOG_ERROR("Failed to send SIGTERM to port channel %s pid %d: %s", alias.c_str(), pid, e.what());
aliasPidMap.erase(alias);
}
}

for (const auto& cit: aliasPidMap)
{
const auto &alias = cit.first;
const auto &pid = cit.second;

std::stringstream cmd;
std::string res;

SWSS_LOG_NOTICE("Waiting for port channel %s pid %d to stop...", alias.c_str(), pid);

cmd << "tail -f --pid=" << pid << " /dev/null";
EXEC_WITH_ERROR_THROW(cmd.str(), res);
while (!kill(pid, 0))
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}

SWSS_LOG_NOTICE("LAGs cleanup is done");
Expand Down Expand Up @@ -654,42 +649,25 @@ bool TeamMgr::removeLag(const string &alias)
{
SWSS_LOG_ENTER();

stringstream cmd;
string res;
pid_t pid;

try
{
std::stringstream cmd;
cmd << "cat " << shellquote("/var/run/teamd/" + alias + ".pid");
EXEC_WITH_ERROR_THROW(cmd.str(), res);
}
catch (const std::exception &e)
{
SWSS_LOG_NOTICE("Failed to remove non-existent port channel %s pid...", alias.c_str());
return false;
}

try
{
pid = static_cast<pid_t>(std::stoul(res, nullptr, 10));
SWSS_LOG_INFO("Read port channel %s pid %d", alias.c_str(), pid);
}
catch (const std::exception &e)
{
SWSS_LOG_ERROR("Failed to read port channel %s pid: %s", alias.c_str(), e.what());
return false;
ifstream pidfile("/var/run/teamd/" + alias + ".pid");
if (pidfile.is_open())
{
pidfile >> pid;
SWSS_LOG_INFO("Read port channel %s pid %d", alias.c_str(), pid);
}
else
{
SWSS_LOG_NOTICE("Failed to remove non-existent port channel %s pid...", alias.c_str());
return false;
}
}

try
{
std::stringstream cmd;
cmd << "kill -TERM " << pid;
EXEC_WITH_ERROR_THROW(cmd.str(), res);
}
catch (const std::exception &e)
if (kill(pid, SIGTERM))
{
SWSS_LOG_ERROR("Failed to send SIGTERM to port channel %s pid %d: %s", alias.c_str(), pid, e.what());
SWSS_LOG_ERROR("Failed to send SIGTERM to port channel %s pid %d: %s", alias.c_str(), pid, strerror(errno));
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion orchagent/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ orchagent_SOURCES += p4orch/p4orch.cpp \

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

routeresync_SOURCES = routeresync.cpp
routeresync_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_ASAN)
Expand Down
18 changes: 13 additions & 5 deletions orchagent/routeorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2575,13 +2575,21 @@ bool RouteOrch::removeRoute(RouteBulkContext& ctx)
size_t creating = gRouteBulker.creating_entries_count(route_entry);
if (it_route == it_route_table->second.end() && creating == 0)
{
if (it_route_table->second.size() == 0)
{
/*
* Clean up the VRF routing table if
* 1. there is no routing entry in the VRF routing table and
* 2. there is no pending bulk creation routing entry in gRouteBulker
* The ideal way of the 2nd condition is to check pending bulk creation entries of a certain VRF.
* However, we can not do that unless going over all entries in gRouteBulker.
* So, we use above strict conditions here
*/
if (it_route_table->second.size() == 0 && gRouteBulker.creating_entries_count() == 0)
{
m_syncdRoutes.erase(vrf_id);
m_vrfOrch->decreaseVrfRefCount(vrf_id);
}
SWSS_LOG_INFO("Failed to find route entry, vrf_id 0x%" PRIx64 ", prefix %s\n", vrf_id,
ipPrefix.to_string().c_str());
}
SWSS_LOG_INFO("Failed to find route entry, vrf_id 0x%" PRIx64 ", prefix %s\n", vrf_id,
ipPrefix.to_string().c_str());

return true;
}
Expand Down
3 changes: 3 additions & 0 deletions orchagent/swssnet.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ inline static sai_ip_address_t& copy(sai_ip_address_t& dst, const IpAddress& src
switch(sip.family)
{
case AF_INET:
memset((void*)&dst.addr, 0, sizeof(dst.addr));
dst.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
dst.addr.ip4 = sip.ip_addr.ipv4_addr;
break;
Expand All @@ -41,6 +42,7 @@ inline static sai_ip_prefix_t& copy(sai_ip_prefix_t& dst, const IpPrefix& src)
switch(ia.family)
{
case AF_INET:
memset((void*)&dst, 0, sizeof(dst));
dst.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
dst.addr.ip4 = ia.ip_addr.ipv4_addr;
dst.mask.ip4 = ma.ip_addr.ipv4_addr;
Expand All @@ -62,6 +64,7 @@ inline static sai_ip_prefix_t& copy(sai_ip_prefix_t& dst, const IpAddress& src)
switch(sip.family)
{
case AF_INET:
memset((void*)&dst, 0, sizeof(dst));
dst.addr_family = SAI_IP_ADDR_FAMILY_IPV4;
dst.addr.ip4 = sip.ip_addr.ipv4_addr;
dst.mask.ip4 = 0xFFFFFFFF;
Expand Down
4 changes: 2 additions & 2 deletions tests/mock_tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ tests_teammgrd_SOURCES = teammgrd/teammgr_ut.cpp \
tests_teammgrd_INCLUDES = $(tests_INCLUDES) -I$(top_srcdir)/cfgmgr -I$(top_srcdir)/lib
tests_teammgrd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_GTEST) $(CFLAGS_SAI)
tests_teammgrd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) $(CFLAGS_GTEST) $(CFLAGS_SAI) $(tests_teammgrd_INCLUDES)
tests_teammgrd_LDADD = $(LDADD_GTEST) $(LDADD_SAI) -lnl-genl-3 -lhiredis -lhiredis \
-lswsscommon -lswsscommon -lyaml-cpp -lgtest -lgtest_main -lzmq -lnl-3 -lnl-route-3 -lpthread -lgmock -lgmock_main
tests_teammgrd_LDADD = $(LDADD_GTEST) $(LDADD_SAI) -ldl -lhiredis \
-lswsscommon -lgtest -lgtest_main -lzmq -lpthread -lgmock -lgmock_main

## fpmsyncd unit tests

Expand Down
31 changes: 31 additions & 0 deletions tests/mock_tests/routeorch_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,11 @@ namespace routeorch_test
{"mac_addr", "00:00:00:00:00:00" }});
intfTable.set("Ethernet4:11.0.0.1/32", { { "scope", "global" },
{ "family", "IPv4" }});
intfTable.set("Ethernet8", { {"NULL", "NULL" },
{"vrf_name", "Vrf1"},
{"mac_addr", "00:00:00:00:00:00" }});
intfTable.set("Ethernet8:20.0.0.1/24", { { "scope", "global" },
{ "family", "IPv4" }});
gIntfsOrch->addExistingData(&intfTable);
static_cast<Orch *>(gIntfsOrch)->doTask();

Expand Down Expand Up @@ -552,4 +557,30 @@ namespace routeorch_test
ASSERT_EQ(current_create_count, create_route_count);
ASSERT_EQ(current_set_count, set_route_count);
}

TEST_F(RouteOrchTest, RouteOrchTestVrfRoute)
{
std::deque<KeyOpFieldsValuesTuple> entries;
entries.push_back({"Vrf2", "SET", { {"vni", "500200"}}});
auto vrfConsumer = dynamic_cast<Consumer *>(gVrfOrch->getExecutor(APP_VRF_TABLE_NAME));
vrfConsumer->addToSync(entries);
static_cast<Orch *>(gVrfOrch)->doTask();
entries.clear();
entries.push_back({"Ethernet8", "SET", { {"vrf_name", "Vrf2"}}});
auto intfConsumer = dynamic_cast<Consumer *>(gIntfsOrch->getExecutor(APP_INTF_TABLE_NAME));
intfConsumer->addToSync(entries);
static_cast<Orch *>(gIntfsOrch)->doTask();
auto routeConsumer = dynamic_cast<Consumer *>(gRouteOrch->getExecutor(APP_ROUTE_TABLE_NAME));
entries.clear();
entries.push_back({"Vrf2:fe80::/64", "DEL", {}});
entries.push_back({"Vrf2:20.0.0.0/24", "DEL", {}});
entries.push_back({"Vrf2:fe80::/64", "SET", { {"protocol", "kernel"},
{"nexthop", "::"},
{"ifname", "Ethernet8"}}});
entries.push_back({"Vrf2:20.0.0.0/24", "SET", { {"protocol", "kernel"},
{"nexthop", "0.0.0.0"},
{"ifname", "Ethernet8"}}});
routeConsumer->addToSync(entries);
static_cast<Orch *>(gRouteOrch)->doTask();
}
}
Loading

0 comments on commit c3f2a83

Please sign in to comment.