Skip to content

teamd: lacp: update port state according to partner's sync bit #2793

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 17, 2019
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
commit 15b56de0f309c942f0f3a588f40944d078db97f9
Author: Pavel Shirshov <[email protected]>
Date: Tue Apr 16 12:18:12 2019 -0700

teamd: lacp: update port state according to partner's sync bit

Backport of
https://github.com/jpirko/libteam/commit/54f137c10579bf97800c61ebb13e732aa1d843e6#diff-f17610bfcc2bafe661a9f3ba496ebf12

According to 6.4.15 of IEEE 802.1AX-2014, Figure 6-22, the state that the
port is selected moves MUX state from DETACHED to ATTACHED.

But ATTACHED state does not mean that the port can send and receive user
frames. COLLECTING_DISTRIBUTION state is the state that the port can send
and receive user frames. To move MUX state from ATTACHED to
COLLECTING_DISTRIBUTION, the partner state should be sync as well as the
port selected.

In function lacp_port_actor_update(), only INFO_STATE_SYNCHRONIZATION
should be set to the actor.state when the port is selected.
INFO_STATE_COLLECTING and INFO_STATE_DISTRIBUTING should be set to false
with ATTACHED mode and set to true when INFO_STATE_SYNCHRONIZATION of
partner.state is set.

In function lacp_port_should_be_{enabled, disabled}(), we also need to
check the INFO_STATE_SYNCHRONIZATION bit of partner.state.

Signed-off-by: Hangbin Liu <[email protected]>
Signed-off-by: Jiri Pirko <[email protected]>

diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c
index dae9086..5fa026a 100644
--- a/teamd/teamd_runner_lacp.c
+++ b/teamd/teamd_runner_lacp.c
@@ -361,7 +361,8 @@ static int lacp_port_should_be_enabled(struct lacp_port *lacp_port)
struct lacp *lacp = lacp_port->lacp;

if (lacp_port_selected(lacp_port) &&
- lacp_port->agg_lead == lacp->selected_agg_lead)
+ lacp_port->agg_lead == lacp->selected_agg_lead &&
+ lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION)
return true;
return false;
}
@@ -371,7 +372,8 @@ static int lacp_port_should_be_disabled(struct lacp_port *lacp_port)
struct lacp *lacp = lacp_port->lacp;

if (!lacp_port_selected(lacp_port) ||
- lacp_port->agg_lead != lacp->selected_agg_lead)
+ lacp_port->agg_lead != lacp->selected_agg_lead ||
+ !(lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION))
return true;
return false;
}
@@ -966,9 +968,14 @@ static void lacp_port_actor_update(struct lacp_port *lacp_port)
state |= INFO_STATE_LACP_ACTIVITY;
if (lacp_port->lacp->cfg.fast_rate)
state |= INFO_STATE_LACP_TIMEOUT;
- if (lacp_port_selected(lacp_port))
+ if (lacp_port_selected(lacp_port) &&
+ lacp_port_agg_selected(lacp_port)) {
state |= INFO_STATE_SYNCHRONIZATION;
- state |= INFO_STATE_COLLECTING | INFO_STATE_DISTRIBUTING;
+ state &= ~(INFO_STATE_COLLECTING | INFO_STATE_DISTRIBUTING);
+ if (lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION)
+ state |= INFO_STATE_COLLECTING |
+ INFO_STATE_DISTRIBUTING;
+ }
if (lacp_port->state == PORT_STATE_EXPIRED)
state |= INFO_STATE_EXPIRED;
if (lacp_port->state == PORT_STATE_DEFAULTED)
1 change: 1 addition & 0 deletions src/libteam/series
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
0007-Skip-setting-the-same-hwaddr-to-lag-port-to-avoid-di.patch
0008-teamd-register-change-handler-for-TEAM_IFINFO_CHANGE.patch
0009-teamd-prevent-private-change-handler-reentrance.patch
0010-teamd-lacp-update-port-state-according-to-partners-sy.patch