From f082cff528a3d94ccc17c9459848b0a9123a92cf Mon Sep 17 00:00:00 2001 From: pavel-shirshov Date: Tue, 16 Apr 2019 19:11:24 -0700 Subject: [PATCH] teamd: lacp: update port state according to partner's sync bit (#2793) Backport of https://github.com/jpirko/libteam/commit/54f137c10579bf97800c61ebb13e732aa1d843e6 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 Signed-off-by: Jiri Pirko --- ...-port-state-according-to-partners-sy.patch | 71 +++++++++++++++++++ src/libteam/series | 1 + 2 files changed, 72 insertions(+) create mode 100644 src/libteam/0010-teamd-lacp-update-port-state-according-to-partners-sy.patch diff --git a/src/libteam/0010-teamd-lacp-update-port-state-according-to-partners-sy.patch b/src/libteam/0010-teamd-lacp-update-port-state-according-to-partners-sy.patch new file mode 100644 index 000000000000..33e6140bab6d --- /dev/null +++ b/src/libteam/0010-teamd-lacp-update-port-state-according-to-partners-sy.patch @@ -0,0 +1,71 @@ +commit 15b56de0f309c942f0f3a588f40944d078db97f9 +Author: Pavel Shirshov +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 + Signed-off-by: Jiri Pirko + +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) diff --git a/src/libteam/series b/src/libteam/series index a6c4893d021a..415d6f79af92 100644 --- a/src/libteam/series +++ b/src/libteam/series @@ -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 \ No newline at end of file