From c5cbc69f20dee3f857b00e587c0b1eb1c0856e83 Mon Sep 17 00:00:00 2001 From: Shuotian Cheng Date: Thu, 13 Apr 2017 12:01:57 -0700 Subject: [PATCH] [orchagent]: Support LAG_MEMBER_TABLE (#187) * [orchagent]: Support LAG_MEMBER_TABLE - Add LAG_MEMBER_TABLE in teamsyncd - Add LAG_MEMBER_TABLE in orchagent * Handle invalid index before indexing * Replace KeyOpFieldValueTuples with auto & Signed-off-by: Shuotian Cheng --- orchagent/orchdaemon.cpp | 3 +- orchagent/portsorch.cpp | 214 ++++++++++++++++++++------------------- orchagent/portsorch.h | 1 + teamsyncd/teamsync.cpp | 17 ++-- teamsyncd/teamsync.h | 5 +- 5 files changed, 126 insertions(+), 114 deletions(-) diff --git a/orchagent/orchdaemon.cpp b/orchagent/orchdaemon.cpp index 12529a08554c..785031edb1d5 100644 --- a/orchagent/orchdaemon.cpp +++ b/orchagent/orchdaemon.cpp @@ -36,7 +36,8 @@ bool OrchDaemon::init() vector ports_tables = { APP_PORT_TABLE_NAME, APP_VLAN_TABLE_NAME, - APP_LAG_TABLE_NAME + APP_LAG_TABLE_NAME, + APP_LAG_MEMBER_TABLE_NAME }; gPortsOrch = new PortsOrch(m_applDb, ports_tables); diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index 9732787e5bec..1f4fc18fbcb5 100644 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -269,7 +269,7 @@ void PortsOrch::doPortTask(Consumer &consumer) auto it = consumer.m_toSync.begin(); while (it != consumer.m_toSync.end()) { - KeyOpFieldsValuesTuple t = it->second; + auto &t = it->second; string alias = kfvKey(t); string op = kfvOp(t); @@ -397,7 +397,7 @@ void PortsOrch::doVlanTask(Consumer &consumer) auto it = consumer.m_toSync.begin(); while (it != consumer.m_toSync.end()) { - KeyOpFieldsValuesTuple t = it->second; + auto &t = it->second; string key = kfvKey(t); @@ -527,144 +527,150 @@ void PortsOrch::doLagTask(Consumer &consumer) auto it = consumer.m_toSync.begin(); while (it != consumer.m_toSync.end()) { - KeyOpFieldsValuesTuple t = it->second; + auto &t = it->second; + string lag_alias = kfvKey(t); + string op = kfvOp(t); + + if (op == SET_COMMAND) + { + /* Duplicate entry */ + if (m_portList.find(lag_alias) != m_portList.end()) + { + it = consumer.m_toSync.erase(it); + continue; + } + + if (addLag(lag_alias)) + it = consumer.m_toSync.erase(it); + else + it++; + } + else if (op == DEL_COMMAND) + { + Port lag; + /* Cannot locate LAG */ + if (!getPort(lag_alias, lag)) + { + it = consumer.m_toSync.erase(it); + continue; + } + + if (removeLag(lag)) + it = consumer.m_toSync.erase(it); + else + it++; + } + else + { + SWSS_LOG_ERROR("Unknown operation type %s", op.c_str()); + it = consumer.m_toSync.erase(it); + } + } +} + +void PortsOrch::doLagMemberTask(Consumer &consumer) +{ + if (!isInitDone()) + return; + + auto it = consumer.m_toSync.begin(); + while (it != consumer.m_toSync.end()) + { + auto &t = it->second; + + /* Retrieve LAG alias and LAG member alias from key */ string key = kfvKey(t); size_t found = key.find(':'); - string lag_alias, port_alias; + /* Return if the format of key is wrong */ if (found == string::npos) - lag_alias = key; - else { - lag_alias = key.substr(0, found); - port_alias = key.substr(found+1); + SWSS_LOG_ERROR("Failed to parse %s", key.c_str()); + return; } + string lag_alias = key.substr(0, found); + string port_alias = key.substr(found+1); string op = kfvOp(t); - /* Manipulate LAG when port_alias is empty */ - if (port_alias == "") + Port lag, port; + if (!getPort(lag_alias, lag)) { - if (op == SET_COMMAND) + SWSS_LOG_INFO("Failed to locate LAG %s", lag_alias.c_str()); + it++; + continue; + } + + if (!getPort(port_alias, port)) + { + SWSS_LOG_ERROR("Failed to locate port %s", port_alias.c_str()); + it = consumer.m_toSync.erase(it); + continue; + } + + /* Update a LAG member */ + if (op == SET_COMMAND) + { + string status; + for (auto i : kfvFieldsValues(t)) + { + if (fvField(i) == "status") + status = fvValue(i); + } + + /* Sync an enabled member */ + if (status == "enabled") { /* Duplicate entry */ - if (m_portList.find(lag_alias) != m_portList.end()) + if (lag.m_members.find(port_alias) != lag.m_members.end()) { it = consumer.m_toSync.erase(it); continue; } - if (addLag(lag_alias)) + /* Assert the port doesn't belong to any LAG */ + assert(!port.m_lag_id && !port.m_lag_member_id); + + if (addLagMember(lag, port)) it = consumer.m_toSync.erase(it); else it++; } - else if (op == DEL_COMMAND) + /* Sync an disabled member */ + else /* status == "disabled" */ { - Port lag; - /* Cannot locate LAG */ - if (!getPort(lag_alias, lag)) + /* "status" is "disabled" at start when m_lag_id and + * m_lag_member_id are absent */ + if (!port.m_lag_id || !port.m_lag_member_id) { it = consumer.m_toSync.erase(it); continue; } - if (removeLag(lag)) + if (removeLagMember(lag, port)) it = consumer.m_toSync.erase(it); else it++; } - else - { - SWSS_LOG_ERROR("Unknown operation type %s", op.c_str()); - it = consumer.m_toSync.erase(it); - } } - /* Manipulate a LAG member */ - else + /* Remove a LAG member */ + else if (op == DEL_COMMAND) { - assert(m_portList.find(lag_alias) != m_portList.end()); - Port lag, port; + /* Assert the LAG member exists */ + assert(lag.m_members.find(port_alias) != lag.m_members.end()); - /* When LAG member is to be created before LAG is created */ - if (!getPort(lag_alias, lag)) - { - SWSS_LOG_INFO("Failed to locate LAG %s", lag_alias.c_str()); - it++; - continue; - } + /* Assert the port belongs to a LAG */ + assert(port.m_lag_id && port.m_lag_member_id); - if (!getPort(port_alias, port)) - { - SWSS_LOG_ERROR("Failed to locate port %s", port_alias.c_str()); + if (removeLagMember(lag, port)) it = consumer.m_toSync.erase(it); - continue; - } - - /* Add a LAG member */ - if (op == SET_COMMAND) - { - string status; - for (auto i : kfvFieldsValues(t)) - { - if (fvField(i) == "status") - status = fvValue(i); - } - - /* Sync an enabled member */ - if (status == "enabled") - { - /* Duplicate entry */ - if (lag.m_members.find(port_alias) != lag.m_members.end()) - { - it = consumer.m_toSync.erase(it); - continue; - } - - /* Assert the port doesn't belong to any LAG */ - assert(!port.m_lag_id && !port.m_lag_member_id); - - if (addLagMember(lag, port)) - it = consumer.m_toSync.erase(it); - else - it++; - } - /* Sync an disabled member */ - else /* status == "disabled" */ - { - /* "status" is "disabled" at start when m_lag_id and - * m_lag_member_id are absent */ - if (!port.m_lag_id || !port.m_lag_member_id) - { - it = consumer.m_toSync.erase(it); - continue; - } - - if (removeLagMember(lag, port)) - it = consumer.m_toSync.erase(it); - else - it++; - } - } - /* Remove a LAG member */ - else if (op == DEL_COMMAND) - { - /* Assert the LAG member exists */ - assert(lag.m_members.find(port_alias) != lag.m_members.end()); - - /* Assert the port belongs to a LAG */ - assert(port.m_lag_id && port.m_lag_member_id); - - if (removeLagMember(lag, port)) - it = consumer.m_toSync.erase(it); - else - it++; - } else - { - SWSS_LOG_ERROR("Unknown operation type %s", op.c_str()); - it = consumer.m_toSync.erase(it); - } + it++; + } + else + { + SWSS_LOG_ERROR("Unknown operation type %s", op.c_str()); + it = consumer.m_toSync.erase(it); } } } @@ -681,6 +687,8 @@ void PortsOrch::doTask(Consumer &consumer) doVlanTask(consumer); else if (table_name == APP_LAG_TABLE_NAME) doLagTask(consumer); + else if (table_name == APP_LAG_MEMBER_TABLE_NAME) + doLagMemberTask(consumer); } void PortsOrch::initializeQueues(Port &port) diff --git a/orchagent/portsorch.h b/orchagent/portsorch.h index f00ee1b362c1..fdf6d8d3cc94 100644 --- a/orchagent/portsorch.h +++ b/orchagent/portsorch.h @@ -52,6 +52,7 @@ class PortsOrch : public Orch, public Subject void doPortTask(Consumer &consumer); void doVlanTask(Consumer &consumer); void doLagTask(Consumer &consumer); + void doLagMemberTask(Consumer &consumer); bool initializePort(Port &port); void initializePriorityGroups(Port &port); diff --git a/teamsyncd/teamsync.cpp b/teamsyncd/teamsync.cpp index 23b0d1406d98..39a9337c7256 100644 --- a/teamsyncd/teamsync.cpp +++ b/teamsyncd/teamsync.cpp @@ -18,7 +18,8 @@ using namespace swss; TeamSync::TeamSync(DBConnector *db, Select *select) : m_select(select), - m_lagTable(db, APP_LAG_TABLE_NAME) + m_lagTable(db, APP_LAG_TABLE_NAME), + m_lagMemberTable(db, APP_LAG_MEMBER_TABLE_NAME) { } @@ -68,9 +69,9 @@ void TeamSync::addLag(const string &lagName, int ifindex, bool admin_state, return; /* Start track the team instance */ - TeamPortSync *sync = new TeamPortSync(lagName, ifindex, &m_lagTable); - m_select->addSelectable(sync); - m_teamPorts[lagName] = shared_ptr(sync); + auto sync = make_shared(lagName, ifindex, &m_lagMemberTable); + m_select->addSelectable(sync.get()); + m_teamPorts[lagName] = sync; } void TeamSync::removeLag(const string &lagName) @@ -95,8 +96,8 @@ const struct team_change_handler TeamSync::TeamPortSync::gPortChangeHandler = { }; TeamSync::TeamPortSync::TeamPortSync(const string &lagName, int ifindex, - ProducerStateTable *lagTable) : - m_lagTable(lagTable), + ProducerStateTable *lagMemberTable) : + m_lagMemberTable(lagMemberTable), m_lagName(lagName), m_ifindex(ifindex) { @@ -171,7 +172,7 @@ int TeamSync::TeamPortSync::onChange() vector v; FieldValueTuple l("status", it.second ? "enabled" : "disabled"); v.push_back(l); - m_lagTable->set(key, v); + m_lagMemberTable->set(key, v); } } @@ -180,7 +181,7 @@ int TeamSync::TeamPortSync::onChange() if (tmp_lag_members.find(it.first) == tmp_lag_members.end()) { string key = m_lagName + ":" + it.first; - m_lagTable->del(key); + m_lagMemberTable->del(key); } } diff --git a/teamsyncd/teamsync.h b/teamsyncd/teamsync.h index 8fb61fd1cbcc..3574ede4d640 100644 --- a/teamsyncd/teamsync.h +++ b/teamsyncd/teamsync.h @@ -29,7 +29,7 @@ class TeamSync : public NetMsg public: enum { MAX_IFNAME = 64 }; TeamPortSync(const std::string &lagName, int ifindex, - ProducerStateTable *lagTable); + ProducerStateTable *lagMemberTable); ~TeamPortSync(); virtual void addFd(fd_set *fd); @@ -43,7 +43,7 @@ class TeamSync : public NetMsg team_change_type_mask_t type_mask); static const struct team_change_handler gPortChangeHandler; private: - ProducerStateTable *m_lagTable; + ProducerStateTable *m_lagMemberTable; struct team_handle *m_team; std::string m_lagName; int m_ifindex; @@ -58,6 +58,7 @@ class TeamSync : public NetMsg private: Select *m_select; ProducerStateTable m_lagTable; + ProducerStateTable m_lagMemberTable; std::map > m_teamPorts; };