Skip to content
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
357 changes: 297 additions & 60 deletions cfgmgr/teammgr.cpp

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions cfgmgr/teammgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ class TeamMgr : public Orch
const std::vector<TableConnector> &tables);

using Orch::doTask;
void ipcInitTeamd();
int sendIpcToTeamd(const std::string& command,
const std::vector<std::string>& args);
void cleanTeamProcesses();
void ipcCleanup();

private:
Table m_cfgMetadataTable; // To retrieve MAC address
Table m_cfgPortTable;
Table m_cfgLagTable;
Table m_cfgLagMemberTable;
Table m_cfgModeTable;
Table m_statePortTable;
Table m_stateLagTable;
Table m_stateMACsecIngressSATable;
Expand All @@ -33,6 +38,8 @@ class TeamMgr : public Orch
ProducerStateTable m_appLagTable;

std::set<std::string> m_lagList;
bool m_teamdUnifiedProcMode = false;
int sockfd;

MacAddress m_mac;

Expand Down Expand Up @@ -61,4 +68,7 @@ class TeamMgr : public Orch
uint16_t generateLacpKey(const std::string&);
};

#define TEAMD_MULTI_SOCK_PATH "/var/run/teamd/teamd-unified.sock"
#define TEAMD_IPC_REQ "REQUEST"

}
3 changes: 3 additions & 0 deletions cfgmgr/teammgrd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,13 @@ int main(int argc, char **argv)

TableConnector conf_lag_table(&conf_db, CFG_LAG_TABLE_NAME);
TableConnector conf_lag_member_table(&conf_db, CFG_LAG_MEMBER_TABLE_NAME);
TableConnector conf_teamd_mode_table(&conf_db, CFG_TEAMD_MODE_TABLE_NAME);
TableConnector state_port_table(&state_db, STATE_PORT_TABLE_NAME);

vector<TableConnector> tables = {
conf_lag_table,
conf_lag_member_table,
conf_teamd_mode_table,
state_port_table
};

Expand Down Expand Up @@ -93,6 +95,7 @@ int main(int argc, char **argv)
c->execute();
}
teammgr.cleanTeamProcesses();
teammgr.ipcCleanup();
SWSS_LOG_NOTICE("Exiting");
}
catch (const exception &e)
Expand Down
17 changes: 14 additions & 3 deletions teamsyncd/teamsync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,13 @@ TeamSync::TeamPortSync::TeamPortSync(const string &lagName, int ifindex,
{
try
{
m_team = team_alloc();
m_nl = team_netlink_alloc();
if (!m_nl)
{
throw system_error(make_error_code(errc::address_not_available),
"Unable to allocate team netlink socket");
}
m_team = team_alloc(m_nl);
if (!m_team)
{
throw system_error(make_error_code(errc::address_not_available),
Expand All @@ -265,7 +271,9 @@ TeamSync::TeamPortSync::TeamPortSync(const string &lagName, int ifindex,
if (err)
{
team_free(m_team);
team_netlink_free(m_nl);
m_team = NULL;
m_nl = NULL;
throw system_error(make_error_code(errc::address_not_available),
"Unable to initialize team socket");
}
Expand All @@ -274,6 +282,8 @@ TeamSync::TeamPortSync::TeamPortSync(const string &lagName, int ifindex,
if (err)
{
team_free(m_team);
team_netlink_free(m_nl);
m_nl = NULL;
m_team = NULL;
throw system_error(make_error_code(errc::address_not_available),
"Unable to register port change event");
Expand Down Expand Up @@ -307,6 +317,7 @@ TeamSync::TeamPortSync::~TeamPortSync()
{
team_change_handler_unregister(m_team, &gPortChangeHandler, this);
team_free(m_team);
team_netlink_free(m_nl);
}
}

Expand Down Expand Up @@ -382,11 +393,11 @@ int TeamSync::TeamPortSync::teamdHandler(struct team_handle *team, void *arg,

int TeamSync::TeamPortSync::getFd()
{
return team_get_event_fd(m_team);
return team_get_event_fd(m_team, NULL);
}

uint64_t TeamSync::TeamPortSync::readData()
{
team_handle_events(m_team);
team_handle_events(m_team, NULL);
return 0;
}
1 change: 1 addition & 0 deletions teamsyncd/teamsync.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class TeamSync : public NetMsg
static const struct team_change_handler gPortChangeHandler;
private:
ProducerStateTable *m_lagMemberTable;
struct team_netlink *m_nl;
struct team_handle *m_team;
std::string m_lagName;
int m_ifindex;
Expand Down
7 changes: 7 additions & 0 deletions tests/mock_tests/teammgrd/teamd_ipc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once
#include <vector>
#include <string>
#include "orch.h"

// Weak declaration
__attribute__((weak)) int send_ipc_to_teamd(const std::string &method, const std::vector<std::string> &args);
43 changes: 43 additions & 0 deletions tests/mock_tests/teammgrd/teammgr_ut.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
#include "gtest/gtest.h"
#include <gmock/gmock.h>
#include "../mock_table.h"
#include "teammgr.h"
#include <dlfcn.h>
#include "teamd_ipc.h"

using ::testing::_;
using ::testing::Return;

using namespace testing; // <-- Needed to use EXPECT_CALL, DoAll, Return, etc.
using namespace boost::mpl::placeholders; // Optional, if using Boost placeholders

std::function<int(const std::string &, const std::vector<std::string> &)> g_mock_send_ipc_to_teamd;

extern int (*callback)(const std::string &cmd, std::string &stdout);
extern std::vector<std::string> mockCallArgs;
Expand All @@ -11,6 +21,11 @@ static std::map<std::string, std::FILE*> pidFiles;
static int (*callback_kill)(pid_t pid, int sig) = NULL;
static std::pair<bool, FILE*> (*callback_fopen)(const char *pathname, const char *mode) = NULL;

int send_ipc_to_teamd(const std::string &method, const std::vector<std::string> &args)
{
return g_mock_send_ipc_to_teamd(method, args);
}

static int cb_kill(pid_t pid, int sig)
{
mockKillCommands.push_back(std::make_pair(pid, sig));
Expand Down Expand Up @@ -146,6 +161,8 @@ namespace teammgr_ut
std::vector<swss::FieldValueTuple> vec;
vec.emplace_back("mac", "01:23:45:67:89:ab");
metadata_table.set("localhost", vec);
swss::Table cfg_mode_table = swss::Table(m_config_db.get(), CFG_TEAMD_MODE_TABLE_NAME);
cfg_mode_table.set("GLOBAL",{ {"mode","multi-process"} });

TableConnector conf_lag_table(m_config_db.get(), CFG_LAG_TABLE_NAME);
TableConnector conf_lag_member_table(m_config_db.get(), CFG_LAG_MEMBER_TABLE_NAME);
Expand Down Expand Up @@ -185,6 +202,7 @@ namespace teammgr_ut
teammgr.addExistingData(&cfg_lag_table);
teammgr.doTask();
ASSERT_NE(mockCallArgs.size(), 0);
ASSERT_FALSE(mockCallArgs.empty());
EXPECT_NE(mockCallArgs.front().find("/usr/bin/teamd -r -t PortChannel382"), std::string::npos);
EXPECT_EQ(mockCallArgs.size(), 1);
EXPECT_EQ(mockKillCommands.size(), 1);
Expand Down Expand Up @@ -264,4 +282,29 @@ namespace teammgr_ut
EXPECT_EQ(mockKillCommands.size(), 0);
EXPECT_GE(std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count(), 200);
}

TEST_F(TeamMgrTest, testIpcSendRetry)
{
swss::Table cfg_mode_table(m_config_db.get(), CFG_TEAMD_MODE_TABLE_NAME);
swss::Table cfg_lag_table(m_config_db.get(), CFG_LAG_TABLE_NAME);
cfg_mode_table.del("GLOBAL");
cfg_lag_table.set("PortChannel123", {
{"admin_status", "up"},
{"mtu", "9100"},
{"lacp_key", "auto"},
{"min_links", "1"}
});

g_mock_send_ipc_to_teamd = [](const std::string &method, const std::vector<std::string> &args) -> int {
if (method == "PortChannelAdd" && !args.empty() && args[0]== "PortChannel123")
{
return task_need_retry;
}
return task_success;
};

swss::TeamMgr teammgr(m_config_db.get(), m_app_db.get(), m_state_db.get(), cfg_lag_tables);
teammgr.addExistingData(&cfg_lag_table);
teammgr.doTask();
}
}
27 changes: 26 additions & 1 deletion tlm_teamd/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,39 @@ int main()
swss::Logger::linkToDbNative("tlm_teamd");
SWSS_LOG_NOTICE("Starting");
swss::DBConnector db("STATE_DB", 0);

ValuesStore values_store(&db);
TeamdCtlMgr teamdctl_mgr;

swss::Select s;
swss::Selectable * event;
swss::SubscriberStateTable sst_lag(&db, STATE_LAG_TABLE_NAME);
s.addSelectable(&sst_lag);
swss::DBConnector config_db("CONFIG_DB", 0);

swss::Table table(&config_db, "TEAMD");
std::vector<swss::FieldValueTuple> values;

std::string m_teamdMultiProcMode = "unified";
bool key_exists = table.get("GLOBAL", values);

if (key_exists && !values.empty())
{
for (const auto& fv : values)
{
if (fv.first == "mode" && fv.second == "multi-process")

{
m_teamdMultiProcMode = fv.second;
break;
}
}
}
if (m_teamdMultiProcMode == "multi-process") {
teamdctl_mgr.m_teamdUnifiedProcMode = false;
} else {
teamdctl_mgr.m_teamdUnifiedProcMode = true;
}


while (g_run && rc == 0)
{
Expand Down
Loading