@@ -105,6 +105,9 @@ static void ad_agg_selection_logic(struct aggregator *aggregator,
105105static void ad_clear_agg (struct aggregator * aggregator );
106106static void ad_initialize_agg (struct aggregator * aggregator );
107107static void ad_initialize_port (struct port * port , int lacp_fast );
108+ static void ad_enable_collecting (struct port * port );
109+ static void ad_disable_distributing (struct port * port ,
110+ bool * update_slave_arr );
108111static void ad_enable_collecting_distributing (struct port * port ,
109112 bool * update_slave_arr );
110113static void ad_disable_collecting_distributing (struct port * port ,
@@ -170,9 +173,38 @@ static inline int __agg_has_partner(struct aggregator *agg)
170173 return !is_zero_ether_addr (agg -> partner_system .mac_addr_value );
171174}
172175
176+ /**
177+ * __disable_distributing_port - disable the port's slave for distributing.
178+ * Port will still be able to collect.
179+ * @port: the port we're looking at
180+ *
181+ * This will disable only distributing on the port's slave.
182+ */
183+ static void __disable_distributing_port (struct port * port )
184+ {
185+ bond_set_slave_tx_disabled_flags (port -> slave , BOND_SLAVE_NOTIFY_LATER );
186+ }
187+
188+ /**
189+ * __enable_collecting_port - enable the port's slave for collecting,
190+ * if it's up
191+ * @port: the port we're looking at
192+ *
193+ * This will enable only collecting on the port's slave.
194+ */
195+ static void __enable_collecting_port (struct port * port )
196+ {
197+ struct slave * slave = port -> slave ;
198+
199+ if (slave -> link == BOND_LINK_UP && bond_slave_is_up (slave ))
200+ bond_set_slave_rx_enabled_flags (slave , BOND_SLAVE_NOTIFY_LATER );
201+ }
202+
173203/**
174204 * __disable_port - disable the port's slave
175205 * @port: the port we're looking at
206+ *
207+ * This will disable both collecting and distributing on the port's slave.
176208 */
177209static inline void __disable_port (struct port * port )
178210{
@@ -182,6 +214,8 @@ static inline void __disable_port(struct port *port)
182214/**
183215 * __enable_port - enable the port's slave, if it's up
184216 * @port: the port we're looking at
217+ *
218+ * This will enable both collecting and distributing on the port's slave.
185219 */
186220static inline void __enable_port (struct port * port )
187221{
@@ -192,10 +226,27 @@ static inline void __enable_port(struct port *port)
192226}
193227
194228/**
195- * __port_is_enabled - check if the port's slave is in active state
229+ * __port_move_to_attached_state - check if port should transition back to attached
230+ * state.
231+ * @port: the port we're looking at
232+ */
233+ static bool __port_move_to_attached_state (struct port * port )
234+ {
235+ if (!(port -> sm_vars & AD_PORT_SELECTED ) ||
236+ (port -> sm_vars & AD_PORT_STANDBY ) ||
237+ !(port -> partner_oper .port_state & LACP_STATE_SYNCHRONIZATION ) ||
238+ !(port -> actor_oper_port_state & LACP_STATE_SYNCHRONIZATION ))
239+ port -> sm_mux_state = AD_MUX_ATTACHED ;
240+
241+ return port -> sm_mux_state == AD_MUX_ATTACHED ;
242+ }
243+
244+ /**
245+ * __port_is_collecting_distributing - check if the port's slave is in the
246+ * combined collecting/distributing state
196247 * @port: the port we're looking at
197248 */
198- static inline int __port_is_enabled (struct port * port )
249+ static int __port_is_collecting_distributing (struct port * port )
199250{
200251 return bond_is_active_slave (port -> slave );
201252}
@@ -933,6 +984,7 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker)
933984 */
934985static void ad_mux_machine (struct port * port , bool * update_slave_arr )
935986{
987+ struct bonding * bond = __get_bond_by_port (port );
936988 mux_states_t last_state ;
937989
938990 /* keep current State Machine state to compare later if it was
@@ -990,9 +1042,13 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)
9901042 if ((port -> sm_vars & AD_PORT_SELECTED ) &&
9911043 (port -> partner_oper .port_state & LACP_STATE_SYNCHRONIZATION ) &&
9921044 !__check_agg_selection_timer (port )) {
993- if (port -> aggregator -> is_active )
994- port -> sm_mux_state =
995- AD_MUX_COLLECTING_DISTRIBUTING ;
1045+ if (port -> aggregator -> is_active ) {
1046+ int state = AD_MUX_COLLECTING_DISTRIBUTING ;
1047+
1048+ if (!bond -> params .coupled_control )
1049+ state = AD_MUX_COLLECTING ;
1050+ port -> sm_mux_state = state ;
1051+ }
9961052 } else if (!(port -> sm_vars & AD_PORT_SELECTED ) ||
9971053 (port -> sm_vars & AD_PORT_STANDBY )) {
9981054 /* if UNSELECTED or STANDBY */
@@ -1010,19 +1066,53 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)
10101066 }
10111067 break ;
10121068 case AD_MUX_COLLECTING_DISTRIBUTING :
1069+ if (!__port_move_to_attached_state (port )) {
1070+ /* if port state hasn't changed make
1071+ * sure that a collecting distributing
1072+ * port in an active aggregator is enabled
1073+ */
1074+ if (port -> aggregator -> is_active &&
1075+ !__port_is_collecting_distributing (port )) {
1076+ __enable_port (port );
1077+ * update_slave_arr = true;
1078+ }
1079+ }
1080+ break ;
1081+ case AD_MUX_COLLECTING :
1082+ if (!__port_move_to_attached_state (port )) {
1083+ if ((port -> sm_vars & AD_PORT_SELECTED ) &&
1084+ (port -> partner_oper .port_state & LACP_STATE_SYNCHRONIZATION ) &&
1085+ (port -> partner_oper .port_state & LACP_STATE_COLLECTING )) {
1086+ port -> sm_mux_state = AD_MUX_DISTRIBUTING ;
1087+ } else {
1088+ /* If port state hasn't changed, make sure that a collecting
1089+ * port is enabled for an active aggregator.
1090+ */
1091+ struct slave * slave = port -> slave ;
1092+
1093+ if (port -> aggregator -> is_active &&
1094+ bond_is_slave_rx_disabled (slave )) {
1095+ ad_enable_collecting (port );
1096+ * update_slave_arr = true;
1097+ }
1098+ }
1099+ }
1100+ break ;
1101+ case AD_MUX_DISTRIBUTING :
10131102 if (!(port -> sm_vars & AD_PORT_SELECTED ) ||
10141103 (port -> sm_vars & AD_PORT_STANDBY ) ||
1104+ !(port -> partner_oper .port_state & LACP_STATE_COLLECTING ) ||
10151105 !(port -> partner_oper .port_state & LACP_STATE_SYNCHRONIZATION ) ||
10161106 !(port -> actor_oper_port_state & LACP_STATE_SYNCHRONIZATION )) {
1017- port -> sm_mux_state = AD_MUX_ATTACHED ;
1107+ port -> sm_mux_state = AD_MUX_COLLECTING ;
10181108 } else {
10191109 /* if port state hasn't changed make
10201110 * sure that a collecting distributing
10211111 * port in an active aggregator is enabled
10221112 */
10231113 if (port -> aggregator &&
10241114 port -> aggregator -> is_active &&
1025- !__port_is_enabled (port )) {
1115+ !__port_is_collecting_distributing (port )) {
10261116 __enable_port (port );
10271117 * update_slave_arr = true;
10281118 }
@@ -1073,6 +1163,20 @@ static void ad_mux_machine(struct port *port, bool *update_slave_arr)
10731163 update_slave_arr );
10741164 port -> ntt = true;
10751165 break ;
1166+ case AD_MUX_COLLECTING :
1167+ port -> actor_oper_port_state |= LACP_STATE_COLLECTING ;
1168+ port -> actor_oper_port_state &= ~LACP_STATE_DISTRIBUTING ;
1169+ port -> actor_oper_port_state |= LACP_STATE_SYNCHRONIZATION ;
1170+ ad_enable_collecting (port );
1171+ ad_disable_distributing (port , update_slave_arr );
1172+ port -> ntt = true;
1173+ break ;
1174+ case AD_MUX_DISTRIBUTING :
1175+ port -> actor_oper_port_state |= LACP_STATE_DISTRIBUTING ;
1176+ port -> actor_oper_port_state |= LACP_STATE_SYNCHRONIZATION ;
1177+ ad_enable_collecting_distributing (port ,
1178+ update_slave_arr );
1179+ break ;
10761180 default :
10771181 break ;
10781182 }
@@ -1897,6 +2001,45 @@ static void ad_initialize_port(struct port *port, int lacp_fast)
18972001 }
18982002}
18992003
2004+ /**
2005+ * ad_enable_collecting - enable a port's receive
2006+ * @port: the port we're looking at
2007+ *
2008+ * Enable @port if it's in an active aggregator
2009+ */
2010+ static void ad_enable_collecting (struct port * port )
2011+ {
2012+ if (port -> aggregator -> is_active ) {
2013+ struct slave * slave = port -> slave ;
2014+
2015+ slave_dbg (slave -> bond -> dev , slave -> dev ,
2016+ "Enabling collecting on port %d (LAG %d)\n" ,
2017+ port -> actor_port_number ,
2018+ port -> aggregator -> aggregator_identifier );
2019+ __enable_collecting_port (port );
2020+ }
2021+ }
2022+
2023+ /**
2024+ * ad_disable_distributing - disable a port's transmit
2025+ * @port: the port we're looking at
2026+ * @update_slave_arr: Does slave array need update?
2027+ */
2028+ static void ad_disable_distributing (struct port * port , bool * update_slave_arr )
2029+ {
2030+ if (port -> aggregator &&
2031+ !MAC_ADDRESS_EQUAL (& port -> aggregator -> partner_system ,
2032+ & (null_mac_addr ))) {
2033+ slave_dbg (port -> slave -> bond -> dev , port -> slave -> dev ,
2034+ "Disabling distributing on port %d (LAG %d)\n" ,
2035+ port -> actor_port_number ,
2036+ port -> aggregator -> aggregator_identifier );
2037+ __disable_distributing_port (port );
2038+ /* Slave array needs an update */
2039+ * update_slave_arr = true;
2040+ }
2041+ }
2042+
19002043/**
19012044 * ad_enable_collecting_distributing - enable a port's transmit/receive
19022045 * @port: the port we're looking at
0 commit comments