diff --git a/teamsyncd/Makefile.am b/teamsyncd/Makefile.am index bca200b6e03..522cd3fd468 100644 --- a/teamsyncd/Makefile.am +++ b/teamsyncd/Makefile.am @@ -12,4 +12,4 @@ teamsyncd_SOURCES = teamsyncd.cpp teamsync.cpp teamsyncd_CFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) teamsyncd_CPPFLAGS = $(DBGFLAGS) $(AM_CFLAGS) $(CFLAGS_COMMON) -teamsyncd_LDADD = -lnl-3 -lnl-route-3 -lhiredis -lswsscommon -lteam +teamsyncd_LDADD = -lnl-3 -lnl-route-3 -lhiredis -lswsscommon -lteam -lteamdctl diff --git a/teamsyncd/teamsync.cpp b/teamsyncd/teamsync.cpp index fc44ae4b23a..2e032009c28 100644 --- a/teamsyncd/teamsync.cpp +++ b/teamsyncd/teamsync.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "logger.h" #include "netmsg.h" #include "dbconnector.h" @@ -28,18 +29,27 @@ void TeamSync::onMsg(int nlmsg_type, struct nl_object *obj) if ((nlmsg_type != RTM_NEWLINK) && (nlmsg_type != RTM_DELLINK)) return; - string lagName = rtnl_link_get_name(link); + string intfName = rtnl_link_get_name(link); /* Listens to LAG messages */ char *type = rtnl_link_get_type(link); if (!type || (strcmp(type, TEAM_DRV_NAME) != 0)) + { + if (nlmsg_type == RTM_NEWLINK) + { + for (const auto& i : m_teamPorts) + { + i.second->syncMember(intfName); + } + } return; + } - bool tracked = m_teamPorts.find(lagName) != m_teamPorts.end(); + bool tracked = m_teamPorts.find(intfName) != m_teamPorts.end(); if ((nlmsg_type == RTM_DELLINK) && tracked) { /* Remove LAG ports and delete LAG */ - removeLag(lagName); + removeLag(intfName); return; } @@ -50,7 +60,7 @@ void TeamSync::onMsg(int nlmsg_type, struct nl_object *obj) * New LAG was dedcated for the first time. Sync admin and oper state since * portsyncd reflects only changes */ - addLag(lagName, rtnl_link_get_ifindex(link), + addLag(intfName, rtnl_link_get_ifindex(link), rtnl_link_get_flags(link) & IFF_UP, rtnl_link_get_flags(link) & IFF_LOWER_UP, rtnl_link_get_mtu(link)); @@ -119,6 +129,19 @@ TeamSync::TeamPortSync::TeamPortSync(const string &lagName, int ifindex, "Unable to register port change event"); } + m_tdc = teamdctl_alloc(); + + if (m_tdc == NULL) + { + SWSS_LOG_THROW("Failed to allocate teamdctl context."); + } + + err = teamdctl_connect(m_tdc, m_lagName.c_str(), NULL, NULL); + if (err) + { + SWSS_LOG_THROW("Failed to connect to %s teamdctl.", m_lagName.c_str()); + } + /* Sync LAG at first */ onChange(); } @@ -130,6 +153,12 @@ TeamSync::TeamPortSync::~TeamPortSync() team_change_handler_unregister(m_team, &gPortChangeHandler, this); team_free(m_team); } + + if (m_tdc) + { + teamdctl_disconnect(m_tdc); + teamdctl_free(m_tdc); + } } int TeamSync::TeamPortSync::onChange() @@ -207,3 +236,24 @@ void TeamSync::TeamPortSync::readMe() { team_handle_events(m_team); } + +void TeamSync::TeamPortSync::syncMember(const std::string& intfName) +{ + const std::string config(teamdctl_config_get_raw(m_tdc)); + const std::string intfNameStr("\"" + (intfName + "\"")); + + if (config.find(intfNameStr) == std::string::npos) + { + return; + } + + if (m_lagMembers.find(intfName) != m_lagMembers.end()) + { + return; + } + + if (teamdctl_port_add(m_tdc, intfName.c_str())) + { + SWSS_LOG_ERROR("Failed to add port %s to %s", intfName.c_str(), m_lagName.c_str()); + } +} diff --git a/teamsyncd/teamsync.h b/teamsyncd/teamsync.h index 8fb61fd1cbc..0b6a51c4a52 100644 --- a/teamsyncd/teamsync.h +++ b/teamsyncd/teamsync.h @@ -36,6 +36,7 @@ class TeamSync : public NetMsg virtual bool isMe(fd_set *fd); virtual int readCache(); virtual void readMe(); + void syncMember(const std::string& intfName); protected: int onChange(); @@ -45,6 +46,7 @@ class TeamSync : public NetMsg private: ProducerStateTable *m_lagTable; struct team_handle *m_team; + struct teamdctl *m_tdc; std::string m_lagName; int m_ifindex; std::map m_lagMembers; /* map[ifname] = status (enabled|disabled) */