Skip to content

Commit

Permalink
teamsyncd: Add TEAM_OPTION_CHANGE 'enabled' to track LAG membership (s…
Browse files Browse the repository at this point in the history
…onic-net#157)

enabled is a more appropriate option/flag to be tracked and syncd
with the ASIC LAG state. Because 802.3ad LACP is used here, port will
only be put into distributing/collecting mode when it is enabled.

Update doc to replace 'linkup' with 'status'.
  • Loading branch information
Shuotian Cheng committed Jan 24, 2017
1 parent a6b541c commit 5d31f9d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 44 deletions.
6 changes: 3 additions & 3 deletions doc/swss-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ For example (reorder output)
speed

key = LAG_TABLE:lagname:ifname ; physical port member of LAG, fk to PORT_TABLE:ifname
oper_status = "down" / "up" ; Oper status (physical + 802.3ad state)
status = "enabled" / "disabled" ; selected + distributing/collecting (802.3ad)
speed = ; set by LAG application, must match PORT_TABLE.duplex
duplex = ; set by LAG application, must match PORT_TABLE.duplex

Expand All @@ -142,8 +142,8 @@ In addition for each team device, the teamsyncd listens to team events
and reflects the LAG ports into the redis under: `LAG_TABLE:<team0>:port`

127.0.0.1:6379> HGETALL "LAG_TABLE:team0:veth0"
1) "linkup"
2) "down"
1) "status"
2) "disabled"
3) "speed"
4) "0Mbit"
5) "duplex"
Expand Down
28 changes: 13 additions & 15 deletions orchagent/portsorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,25 +565,26 @@ void PortsOrch::doLagTask(Consumer &consumer)
it = consumer.m_toSync.erase(it);
}
}
/* Manipulate member */
/* Manipulate a LAG member */
else
{
assert(m_portList.find(lag_alias) != m_portList.end());
Port lag, port;
getPort(lag_alias, lag);
getPort(port_alias, port);

/* Add a LAG member */
if (op == SET_COMMAND)
{
string linkup_status;
string status;
for (auto i : kfvFieldsValues(t))
{
if (fvField(i) == "linkup")
linkup_status = fvValue(i);
if (fvField(i) == "status")
status = fvValue(i);
}

/* Add LAG member */
if (linkup_status == "up")
/* Sync an enabled member */
if (status == "enabled")
{
/* Duplicate entry */
if (lag.m_members.find(port_alias) != lag.m_members.end())
Expand All @@ -600,15 +601,11 @@ void PortsOrch::doLagTask(Consumer &consumer)
else
it++;
}
/* Remove LAG member */
else /* linkup_status == "down" */
/* Sync an disabled member */
else /* status == "disabled" */
{
assert(lag.m_members.find(port_alias) != lag.m_members.end());

/* Cannot locate LAG or LAG member
* This happens at the time when teamd starts. The linkup
* is set to down in the beginning.
*/
/* "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);
Expand All @@ -620,10 +617,11 @@ void PortsOrch::doLagTask(Consumer &consumer)
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 */
Expand Down
69 changes: 44 additions & 25 deletions teamsyncd/teamsync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void TeamSync::removeLag(const string &lagName)

const struct team_change_handler TeamSync::TeamPortSync::gPortChangeHandler = {
.func = TeamSync::TeamPortSync::teamdHandler,
.type_mask = TEAM_PORT_CHANGE
.type_mask = TEAM_PORT_CHANGE | TEAM_OPTION_CHANGE
};

TeamSync::TeamPortSync::TeamPortSync(const string &lagName, int ifindex,
Expand Down Expand Up @@ -119,7 +119,8 @@ TeamSync::TeamPortSync::TeamPortSync(const string &lagName, int ifindex,
"Unable to register port change event");
}

onPortChange(true);
/* Sync LAG at first */
onChange();
}

TeamSync::TeamPortSync::~TeamPortSync()
Expand All @@ -131,42 +132,60 @@ TeamSync::TeamPortSync::~TeamPortSync()
}
}

int TeamSync::TeamPortSync::onPortChange(bool isInit)
int TeamSync::TeamPortSync::onChange()
{
struct team_port *port;
map<string, bool> tmp_lag_members;

/* Check each port */
team_for_each_port(port, m_team)
{
if (isInit || team_is_port_changed(port))
uint32_t ifindex;
char ifname[MAX_IFNAME + 1] = {0};
bool enabled;

ifindex = team_get_port_ifindex(port);
team_ifindex2ifname(m_team, ifindex, ifname, MAX_IFNAME);

/* Skip the member that is removed from the LAG */
if (team_is_port_removed(port))
continue;

team_get_port_enabled(m_team, ifindex, &enabled);
tmp_lag_members[string(ifname)] = enabled;
}

/* Compare old and new LAG members and set/del accordingly */
for (auto it : tmp_lag_members)
{
if (m_lagMembers.find(it.first) == m_lagMembers.end() || it.second != m_lagMembers[it.first])
{
string key = m_lagName;
key += ":";
uint32_t ifindex = team_get_port_ifindex(port);
char ifname[MAX_IFNAME + 1] = {0};
key += team_ifindex2ifname(m_team, ifindex, ifname, MAX_IFNAME);

if (team_is_port_removed(port))
{
m_lagTable->del(key);
} else
{
std::vector<FieldValueTuple> fvVector;
FieldValueTuple l("linkup", team_is_port_link_up(port) ? "up" : "down");
FieldValueTuple s("speed", to_string(team_get_port_speed(port)) + "Mbit");
FieldValueTuple d("duplex", team_get_port_duplex(port) ? "full" : "half");
fvVector.push_back(l);
fvVector.push_back(s);
fvVector.push_back(d);
m_lagTable->set(key, fvVector);
}
string key = m_lagName + ":" + it.first;
vector<FieldValueTuple> v;
FieldValueTuple l("status", it.second ? "enabled" : "disabled");
v.push_back(l);
m_lagTable->set(key, v);
}
}

for (auto it : m_lagMembers)
{
if (tmp_lag_members.find(it.first) == tmp_lag_members.end())
{
string key = m_lagName + ":" + it.first;
m_lagTable->del(key);
}
}

/* Replace the old LAG members with the new ones */
m_lagMembers = tmp_lag_members;
return 0;
}

int TeamSync::TeamPortSync::teamdHandler(struct team_handle *team, void *arg,
team_change_type_mask_t type_mask)
{
return ((TeamSync::TeamPortSync *)arg)->onPortChange(false);
return ((TeamSync::TeamPortSync *)arg)->onChange();
}

void TeamSync::TeamPortSync::addFd(fd_set *fd)
Expand Down
3 changes: 2 additions & 1 deletion teamsyncd/teamsync.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class TeamSync : public NetMsg
virtual void readMe();

protected:
int onPortChange(bool isInit);
int onChange();
static int teamdHandler(struct team_handle *th, void *arg,
team_change_type_mask_t type_mask);
static const struct team_change_handler gPortChangeHandler;
Expand All @@ -47,6 +47,7 @@ class TeamSync : public NetMsg
struct team_handle *m_team;
std::string m_lagName;
int m_ifindex;
std::map<std::string, bool> m_lagMembers; /* map[ifname] = status (enabled|disabled) */
};

protected:
Expand Down

0 comments on commit 5d31f9d

Please sign in to comment.