|
| 1 | +commit 15b56de0f309c942f0f3a588f40944d078db97f9 |
| 2 | +Author: Pavel Shirshov < [email protected]> |
| 3 | +Date: Tue Apr 16 12:18:12 2019 -0700 |
| 4 | + |
| 5 | + teamd: lacp: update port state according to partner's sync bit |
| 6 | + |
| 7 | + Backport of |
| 8 | + https://github.com/jpirko/libteam/commit/54f137c10579bf97800c61ebb13e732aa1d843e6#diff-f17610bfcc2bafe661a9f3ba496ebf12 |
| 9 | + |
| 10 | + According to 6.4.15 of IEEE 802.1AX-2014, Figure 6-22, the state that the |
| 11 | + port is selected moves MUX state from DETACHED to ATTACHED. |
| 12 | + |
| 13 | + But ATTACHED state does not mean that the port can send and receive user |
| 14 | + frames. COLLECTING_DISTRIBUTION state is the state that the port can send |
| 15 | + and receive user frames. To move MUX state from ATTACHED to |
| 16 | + COLLECTING_DISTRIBUTION, the partner state should be sync as well as the |
| 17 | + port selected. |
| 18 | + |
| 19 | + In function lacp_port_actor_update(), only INFO_STATE_SYNCHRONIZATION |
| 20 | + should be set to the actor.state when the port is selected. |
| 21 | + INFO_STATE_COLLECTING and INFO_STATE_DISTRIBUTING should be set to false |
| 22 | + with ATTACHED mode and set to true when INFO_STATE_SYNCHRONIZATION of |
| 23 | + partner.state is set. |
| 24 | + |
| 25 | + In function lacp_port_should_be_{enabled, disabled}(), we also need to |
| 26 | + check the INFO_STATE_SYNCHRONIZATION bit of partner.state. |
| 27 | + |
| 28 | + Signed-off-by: Hangbin Liu < [email protected]> |
| 29 | + Signed-off-by: Jiri Pirko < [email protected]> |
| 30 | + |
| 31 | +diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c |
| 32 | +index dae9086..5fa026a 100644 |
| 33 | +--- a/teamd/teamd_runner_lacp.c |
| 34 | ++++ b/teamd/teamd_runner_lacp.c |
| 35 | +@@ -361,7 +361,8 @@ static int lacp_port_should_be_enabled(struct lacp_port *lacp_port) |
| 36 | + struct lacp *lacp = lacp_port->lacp; |
| 37 | + |
| 38 | + if (lacp_port_selected(lacp_port) && |
| 39 | +- lacp_port->agg_lead == lacp->selected_agg_lead) |
| 40 | ++ lacp_port->agg_lead == lacp->selected_agg_lead && |
| 41 | ++ lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION) |
| 42 | + return true; |
| 43 | + return false; |
| 44 | + } |
| 45 | +@@ -371,7 +372,8 @@ static int lacp_port_should_be_disabled(struct lacp_port *lacp_port) |
| 46 | + struct lacp *lacp = lacp_port->lacp; |
| 47 | + |
| 48 | + if (!lacp_port_selected(lacp_port) || |
| 49 | +- lacp_port->agg_lead != lacp->selected_agg_lead) |
| 50 | ++ lacp_port->agg_lead != lacp->selected_agg_lead || |
| 51 | ++ !(lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION)) |
| 52 | + return true; |
| 53 | + return false; |
| 54 | + } |
| 55 | +@@ -966,9 +968,14 @@ static void lacp_port_actor_update(struct lacp_port *lacp_port) |
| 56 | + state |= INFO_STATE_LACP_ACTIVITY; |
| 57 | + if (lacp_port->lacp->cfg.fast_rate) |
| 58 | + state |= INFO_STATE_LACP_TIMEOUT; |
| 59 | +- if (lacp_port_selected(lacp_port)) |
| 60 | ++ if (lacp_port_selected(lacp_port) && |
| 61 | ++ lacp_port_agg_selected(lacp_port)) { |
| 62 | + state |= INFO_STATE_SYNCHRONIZATION; |
| 63 | +- state |= INFO_STATE_COLLECTING | INFO_STATE_DISTRIBUTING; |
| 64 | ++ state &= ~(INFO_STATE_COLLECTING | INFO_STATE_DISTRIBUTING); |
| 65 | ++ if (lacp_port->partner.state & INFO_STATE_SYNCHRONIZATION) |
| 66 | ++ state |= INFO_STATE_COLLECTING | |
| 67 | ++ INFO_STATE_DISTRIBUTING; |
| 68 | ++ } |
| 69 | + if (lacp_port->state == PORT_STATE_EXPIRED) |
| 70 | + state |= INFO_STATE_EXPIRED; |
| 71 | + if (lacp_port->state == PORT_STATE_DEFAULTED) |
0 commit comments