@@ -106,6 +106,9 @@ static void ad_agg_selection_logic(struct aggregator *aggregator,
106106static void ad_clear_agg (struct aggregator * aggregator );
107107static void ad_initialize_agg (struct aggregator * aggregator );
108108static void ad_initialize_port (struct port * port , int lacp_fast );
109+ static void ad_enable_collecting (struct port * port );
110+ static void ad_disable_distributing (struct port * port ,
111+ bool * update_slave_arr );
109112static void ad_enable_collecting_distributing (struct port * port ,
110113 bool * update_slave_arr );
111114static void ad_disable_collecting_distributing (struct port * port ,
@@ -171,9 +174,38 @@ static inline int __agg_has_partner(struct aggregator *agg)
171174 return !is_zero_ether_addr (agg -> partner_system .mac_addr_value );
172175}
173176
177+ /**
178+ * __disable_distributing_port - disable the port's slave for distributing.
179+ * Port will still be able to collect.
180+ * @port: the port we're looking at
181+ *
182+ * This will disable only distributing on the port's slave.
183+ */
184+ static void __disable_distributing_port (struct port * port )
185+ {
186+ bond_set_slave_tx_disabled_flags (port -> slave , BOND_SLAVE_NOTIFY_LATER );
187+ }
188+
189+ /**
190+ * __enable_collecting_port - enable the port's slave for collecting,
191+ * if it's up
192+ * @port: the port we're looking at
193+ *
194+ * This will enable only collecting on the port's slave.
195+ */
196+ static void __enable_collecting_port (struct port * port )
197+ {
198+ struct slave * slave = port -> slave ;
199+
200+ if (slave -> link == BOND_LINK_UP && bond_slave_is_up (slave ))
201+ bond_set_slave_rx_enabled_flags (slave , BOND_SLAVE_NOTIFY_LATER );
202+ }
203+
174204/**
175205 * __disable_port - disable the port's slave
176206 * @port: the port we're looking at
207+ *
208+ * This will disable both collecting and distributing on the port's slave.
177209 */
178210static inline void __disable_port (struct port * port )
179211{
@@ -183,6 +215,8 @@ static inline void __disable_port(struct port *port)
183215/**
184216 * __enable_port - enable the port's slave, if it's up
185217 * @port: the port we're looking at
218+ *
219+ * This will enable both collecting and distributing on the port's slave.
186220 */
187221static inline void __enable_port (struct port * port )
188222{
@@ -193,10 +227,27 @@ static inline void __enable_port(struct port *port)
193227}
194228
195229/**
196- * __port_is_enabled - check if the port's slave is in active state
230+ * __port_move_to_attached_state - check if port should transition back to attached
231+ * state.
232+ * @port: the port we're looking at
233+ */
234+ static bool __port_move_to_attached_state (struct port * port )
235+ {
236+ if (!(port -> sm_vars & AD_PORT_SELECTED ) ||
237+ (port -> sm_vars & AD_PORT_STANDBY ) ||
238+ !(port -> partner_oper .port_state & LACP_STATE_SYNCHRONIZATION ) ||
239+ !(port -> actor_oper_port_state & LACP_STATE_SYNCHRONIZATION ))
240+ port -> sm_mux_state = AD_MUX_ATTACHED ;
241+
242+ return port -> sm_mux_state == AD_MUX_ATTACHED ;
243+ }
244+
245+ /**
246+ * __port_is_collecting_distributing - check if the port's slave is in the
247+ * combined collecting/distributing state
197248 * @port: the port we're looking at
198249 */
199- static inline int __port_is_enabled (struct port * port )
250+ static int __port_is_collecting_distributing (struct port * port )
200251{
201252 return bond_is_active_slave (port -> slave );
202253}
@@ -942,6 +993,7 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker)
942993 */
943994static void ad_mux_machine (struct port * port , bool * update_slave_arr )
944995{
996+ struct bonding * bond = __get_bond_by_port (port );
945997 mux_states_t last_state ;
946998
947999 /* keep current State Machine state to compare later if it was
@@ -999,9 +1051,13 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)
9991051 if ((port -> sm_vars & AD_PORT_SELECTED ) &&
10001052 (port -> partner_oper .port_state & LACP_STATE_SYNCHRONIZATION ) &&
10011053 !__check_agg_selection_timer (port )) {
1002- if (port -> aggregator -> is_active )
1003- port -> sm_mux_state =
1004- AD_MUX_COLLECTING_DISTRIBUTING ;
1054+ if (port -> aggregator -> is_active ) {
1055+ int state = AD_MUX_COLLECTING_DISTRIBUTING ;
1056+
1057+ if (!bond -> params .coupled_control )
1058+ state = AD_MUX_COLLECTING ;
1059+ port -> sm_mux_state = state ;
1060+ }
10051061 } else if (!(port -> sm_vars & AD_PORT_SELECTED ) ||
10061062 (port -> sm_vars & AD_PORT_STANDBY )) {
10071063 /* if UNSELECTED or STANDBY */
@@ -1019,19 +1075,53 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)
10191075 }
10201076 break ;
10211077 case AD_MUX_COLLECTING_DISTRIBUTING :
1078+ if (!__port_move_to_attached_state (port )) {
1079+ /* if port state hasn't changed make
1080+ * sure that a collecting distributing
1081+ * port in an active aggregator is enabled
1082+ */
1083+ if (port -> aggregator -> is_active &&
1084+ !__port_is_collecting_distributing (port )) {
1085+ __enable_port (port );
1086+ * update_slave_arr = true;
1087+ }
1088+ }
1089+ break ;
1090+ case AD_MUX_COLLECTING :
1091+ if (!__port_move_to_attached_state (port )) {
1092+ if ((port -> sm_vars & AD_PORT_SELECTED ) &&
1093+ (port -> partner_oper .port_state & LACP_STATE_SYNCHRONIZATION ) &&
1094+ (port -> partner_oper .port_state & LACP_STATE_COLLECTING )) {
1095+ port -> sm_mux_state = AD_MUX_DISTRIBUTING ;
1096+ } else {
1097+ /* If port state hasn't changed, make sure that a collecting
1098+ * port is enabled for an active aggregator.
1099+ */
1100+ struct slave * slave = port -> slave ;
1101+
1102+ if (port -> aggregator -> is_active &&
1103+ bond_is_slave_rx_disabled (slave )) {
1104+ ad_enable_collecting (port );
1105+ * update_slave_arr = true;
1106+ }
1107+ }
1108+ }
1109+ break ;
1110+ case AD_MUX_DISTRIBUTING :
10221111 if (!(port -> sm_vars & AD_PORT_SELECTED ) ||
10231112 (port -> sm_vars & AD_PORT_STANDBY ) ||
1113+ !(port -> partner_oper .port_state & LACP_STATE_COLLECTING ) ||
10241114 !(port -> partner_oper .port_state & LACP_STATE_SYNCHRONIZATION ) ||
10251115 !(port -> actor_oper_port_state & LACP_STATE_SYNCHRONIZATION )) {
1026- port -> sm_mux_state = AD_MUX_ATTACHED ;
1116+ port -> sm_mux_state = AD_MUX_COLLECTING ;
10271117 } else {
10281118 /* if port state hasn't changed make
10291119 * sure that a collecting distributing
10301120 * port in an active aggregator is enabled
10311121 */
10321122 if (port -> aggregator &&
10331123 port -> aggregator -> is_active &&
1034- !__port_is_enabled (port )) {
1124+ !__port_is_collecting_distributing (port )) {
10351125 __enable_port (port );
10361126 * update_slave_arr = true;
10371127 }
@@ -1082,6 +1172,20 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)
10821172 update_slave_arr );
10831173 port -> ntt = true;
10841174 break ;
1175+ case AD_MUX_COLLECTING :
1176+ port -> actor_oper_port_state |= LACP_STATE_COLLECTING ;
1177+ port -> actor_oper_port_state &= ~LACP_STATE_DISTRIBUTING ;
1178+ port -> actor_oper_port_state |= LACP_STATE_SYNCHRONIZATION ;
1179+ ad_enable_collecting (port );
1180+ ad_disable_distributing (port , update_slave_arr );
1181+ port -> ntt = true;
1182+ break ;
1183+ case AD_MUX_DISTRIBUTING :
1184+ port -> actor_oper_port_state |= LACP_STATE_DISTRIBUTING ;
1185+ port -> actor_oper_port_state |= LACP_STATE_SYNCHRONIZATION ;
1186+ ad_enable_collecting_distributing (port ,
1187+ update_slave_arr );
1188+ break ;
10851189 default :
10861190 break ;
10871191 }
@@ -1906,6 +2010,45 @@ static void ad_initialize_port(struct port *port, int lacp_fast)
19062010 }
19072011}
19082012
2013+ /**
2014+ * ad_enable_collecting - enable a port's receive
2015+ * @port: the port we're looking at
2016+ *
2017+ * Enable @port if it's in an active aggregator
2018+ */
2019+ static void ad_enable_collecting (struct port * port )
2020+ {
2021+ if (port -> aggregator -> is_active ) {
2022+ struct slave * slave = port -> slave ;
2023+
2024+ slave_dbg (slave -> bond -> dev , slave -> dev ,
2025+ "Enabling collecting on port %d (LAG %d)\n" ,
2026+ port -> actor_port_number ,
2027+ port -> aggregator -> aggregator_identifier );
2028+ __enable_collecting_port (port );
2029+ }
2030+ }
2031+
2032+ /**
2033+ * ad_disable_distributing - disable a port's transmit
2034+ * @port: the port we're looking at
2035+ * @update_slave_arr: Does slave array need update?
2036+ */
2037+ static void ad_disable_distributing (struct port * port , bool * update_slave_arr )
2038+ {
2039+ if (port -> aggregator &&
2040+ !MAC_ADDRESS_EQUAL (& port -> aggregator -> partner_system ,
2041+ & (null_mac_addr ))) {
2042+ slave_dbg (port -> slave -> bond -> dev , port -> slave -> dev ,
2043+ "Disabling distributing on port %d (LAG %d)\n" ,
2044+ port -> actor_port_number ,
2045+ port -> aggregator -> aggregator_identifier );
2046+ __disable_distributing_port (port );
2047+ /* Slave array needs an update */
2048+ * update_slave_arr = true;
2049+ }
2050+ }
2051+
19092052/**
19102053 * ad_enable_collecting_distributing - enable a port's transmit/receive
19112054 * @port: the port we're looking at
0 commit comments