aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/bonding/bond_3ad.c60
-rw-r--r--drivers/net/bonding/bond_procfs.c43
-rw-r--r--include/net/bond_3ad.h29
3 files changed, 125 insertions, 7 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index cfc4a9c1000a..f61b2870cddf 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -38,6 +38,7 @@
38#define AD_STANDBY 0x2 38#define AD_STANDBY 0x2
39#define AD_MAX_TX_IN_SECOND 3 39#define AD_MAX_TX_IN_SECOND 3
40#define AD_COLLECTOR_MAX_DELAY 0 40#define AD_COLLECTOR_MAX_DELAY 0
41#define AD_MONITOR_CHURNED 0x1000
41 42
42/* Timer definitions (43.4.4 in the 802.3ad standard) */ 43/* Timer definitions (43.4.4 in the 802.3ad standard) */
43#define AD_FAST_PERIODIC_TIME 1 44#define AD_FAST_PERIODIC_TIME 1
@@ -1013,16 +1014,19 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
1013 /* check if state machine should change state */ 1014 /* check if state machine should change state */
1014 1015
1015 /* first, check if port was reinitialized */ 1016 /* first, check if port was reinitialized */
1016 if (port->sm_vars & AD_PORT_BEGIN) 1017 if (port->sm_vars & AD_PORT_BEGIN) {
1017 port->sm_rx_state = AD_RX_INITIALIZE; 1018 port->sm_rx_state = AD_RX_INITIALIZE;
1019 port->sm_vars |= AD_MONITOR_CHURNED;
1018 /* check if port is not enabled */ 1020 /* check if port is not enabled */
1019 else if (!(port->sm_vars & AD_PORT_BEGIN) 1021 } else if (!(port->sm_vars & AD_PORT_BEGIN)
1020 && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED)) 1022 && !port->is_enabled && !(port->sm_vars & AD_PORT_MOVED))
1021 port->sm_rx_state = AD_RX_PORT_DISABLED; 1023 port->sm_rx_state = AD_RX_PORT_DISABLED;
1022 /* check if new lacpdu arrived */ 1024 /* check if new lacpdu arrived */
1023 else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) || 1025 else if (lacpdu && ((port->sm_rx_state == AD_RX_EXPIRED) ||
1024 (port->sm_rx_state == AD_RX_DEFAULTED) || 1026 (port->sm_rx_state == AD_RX_DEFAULTED) ||
1025 (port->sm_rx_state == AD_RX_CURRENT))) { 1027 (port->sm_rx_state == AD_RX_CURRENT))) {
1028 if (port->sm_rx_state != AD_RX_CURRENT)
1029 port->sm_vars |= AD_MONITOR_CHURNED;
1026 port->sm_rx_timer_counter = 0; 1030 port->sm_rx_timer_counter = 0;
1027 port->sm_rx_state = AD_RX_CURRENT; 1031 port->sm_rx_state = AD_RX_CURRENT;
1028 } else { 1032 } else {
@@ -1100,9 +1104,11 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
1100 */ 1104 */
1101 port->partner_oper.port_state &= ~AD_STATE_SYNCHRONIZATION; 1105 port->partner_oper.port_state &= ~AD_STATE_SYNCHRONIZATION;
1102 port->sm_vars &= ~AD_PORT_MATCHED; 1106 port->sm_vars &= ~AD_PORT_MATCHED;
1107 port->partner_oper.port_state |= AD_STATE_LACP_TIMEOUT;
1103 port->partner_oper.port_state |= AD_STATE_LACP_ACTIVITY; 1108 port->partner_oper.port_state |= AD_STATE_LACP_ACTIVITY;
1104 port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT)); 1109 port->sm_rx_timer_counter = __ad_timer_to_ticks(AD_CURRENT_WHILE_TIMER, (u16)(AD_SHORT_TIMEOUT));
1105 port->actor_oper_port_state |= AD_STATE_EXPIRED; 1110 port->actor_oper_port_state |= AD_STATE_EXPIRED;
1111 port->sm_vars |= AD_MONITOR_CHURNED;
1106 break; 1112 break;
1107 case AD_RX_DEFAULTED: 1113 case AD_RX_DEFAULTED:
1108 __update_default_selected(port); 1114 __update_default_selected(port);
@@ -1132,6 +1138,45 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port)
1132} 1138}
1133 1139
1134/** 1140/**
1141 * ad_churn_machine - handle port churn's state machine
1142 * @port: the port we're looking at
1143 *
1144 */
1145static void ad_churn_machine(struct port *port)
1146{
1147 if (port->sm_vars & AD_MONITOR_CHURNED) {
1148 port->sm_vars &= ~AD_MONITOR_CHURNED;
1149 port->sm_churn_actor_state = AD_CHURN_MONITOR;
1150 port->sm_churn_partner_state = AD_CHURN_MONITOR;
1151 port->sm_churn_actor_timer_counter =
1152 __ad_timer_to_ticks(AD_ACTOR_CHURN_TIMER, 0);
1153 port->sm_churn_partner_timer_counter =
1154 __ad_timer_to_ticks(AD_PARTNER_CHURN_TIMER, 0);
1155 return;
1156 }
1157 if (port->sm_churn_actor_timer_counter &&
1158 !(--port->sm_churn_actor_timer_counter) &&
1159 port->sm_churn_actor_state == AD_CHURN_MONITOR) {
1160 if (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION) {
1161 port->sm_churn_actor_state = AD_NO_CHURN;
1162 } else {
1163 port->churn_actor_count++;
1164 port->sm_churn_actor_state = AD_CHURN;
1165 }
1166 }
1167 if (port->sm_churn_partner_timer_counter &&
1168 !(--port->sm_churn_partner_timer_counter) &&
1169 port->sm_churn_partner_state == AD_CHURN_MONITOR) {
1170 if (port->partner_oper.port_state & AD_STATE_SYNCHRONIZATION) {
1171 port->sm_churn_partner_state = AD_NO_CHURN;
1172 } else {
1173 port->churn_partner_count++;
1174 port->sm_churn_partner_state = AD_CHURN;
1175 }
1176 }
1177}
1178
1179/**
1135 * ad_tx_machine - handle a port's tx state machine 1180 * ad_tx_machine - handle a port's tx state machine
1136 * @port: the port we're looking at 1181 * @port: the port we're looking at
1137 */ 1182 */
@@ -1745,6 +1790,13 @@ static void ad_initialize_port(struct port *port, int lacp_fast)
1745 port->next_port_in_aggregator = NULL; 1790 port->next_port_in_aggregator = NULL;
1746 port->transaction_id = 0; 1791 port->transaction_id = 0;
1747 1792
1793 port->sm_churn_actor_timer_counter = 0;
1794 port->sm_churn_actor_state = 0;
1795 port->churn_actor_count = 0;
1796 port->sm_churn_partner_timer_counter = 0;
1797 port->sm_churn_partner_state = 0;
1798 port->churn_partner_count = 0;
1799
1748 memcpy(&port->lacpdu, &lacpdu, sizeof(lacpdu)); 1800 memcpy(&port->lacpdu, &lacpdu, sizeof(lacpdu));
1749 } 1801 }
1750} 1802}
@@ -2164,6 +2216,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
2164 ad_port_selection_logic(port, &update_slave_arr); 2216 ad_port_selection_logic(port, &update_slave_arr);
2165 ad_mux_machine(port, &update_slave_arr); 2217 ad_mux_machine(port, &update_slave_arr);
2166 ad_tx_machine(port); 2218 ad_tx_machine(port);
2219 ad_churn_machine(port);
2167 2220
2168 /* turn off the BEGIN bit, since we already handled it */ 2221 /* turn off the BEGIN bit, since we already handled it */
2169 if (port->sm_vars & AD_PORT_BEGIN) 2222 if (port->sm_vars & AD_PORT_BEGIN)
@@ -2485,6 +2538,9 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
2485 if (skb->protocol != PKT_TYPE_LACPDU) 2538 if (skb->protocol != PKT_TYPE_LACPDU)
2486 return RX_HANDLER_ANOTHER; 2539 return RX_HANDLER_ANOTHER;
2487 2540
2541 if (!MAC_ADDRESS_EQUAL(eth_hdr(skb)->h_dest, lacpdu_mcast_addr))
2542 return RX_HANDLER_ANOTHER;
2543
2488 lacpdu = skb_header_pointer(skb, 0, sizeof(_lacpdu), &_lacpdu); 2544 lacpdu = skb_header_pointer(skb, 0, sizeof(_lacpdu), &_lacpdu);
2489 if (!lacpdu) 2545 if (!lacpdu)
2490 return RX_HANDLER_ANOTHER; 2546 return RX_HANDLER_ANOTHER;
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index 976f5ad2a0f2..62694cfc05b6 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -176,18 +176,51 @@ static void bond_info_show_slave(struct seq_file *seq,
176 slave->link_failure_count); 176 slave->link_failure_count);
177 177
178 seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr); 178 seq_printf(seq, "Permanent HW addr: %pM\n", slave->perm_hwaddr);
179 seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id);
179 180
180 if (BOND_MODE(bond) == BOND_MODE_8023AD) { 181 if (BOND_MODE(bond) == BOND_MODE_8023AD) {
181 const struct aggregator *agg 182 const struct port *port = &SLAVE_AD_INFO(slave)->port;
182 = SLAVE_AD_INFO(slave)->port.aggregator; 183 const struct aggregator *agg = port->aggregator;
183 184
184 if (agg) 185 if (agg) {
185 seq_printf(seq, "Aggregator ID: %d\n", 186 seq_printf(seq, "Aggregator ID: %d\n",
186 agg->aggregator_identifier); 187 agg->aggregator_identifier);
187 else 188 seq_printf(seq, "Actor Churn State: %s\n",
189 bond_3ad_churn_desc(port->sm_churn_actor_state));
190 seq_printf(seq, "Partner Churn State: %s\n",
191 bond_3ad_churn_desc(port->sm_churn_partner_state));
192 seq_printf(seq, "Actor Churned Count: %d\n",
193 port->churn_actor_count);
194 seq_printf(seq, "Partner Churned Count: %d\n",
195 port->churn_partner_count);
196
197 seq_puts(seq, "details actor lacp pdu:\n");
198 seq_printf(seq, " system priority: %d\n",
199 port->actor_system_priority);
200 seq_printf(seq, " port key: %d\n",
201 port->actor_oper_port_key);
202 seq_printf(seq, " port priority: %d\n",
203 port->actor_port_priority);
204 seq_printf(seq, " port number: %d\n",
205 port->actor_port_number);
206 seq_printf(seq, " port state: %d\n",
207 port->actor_oper_port_state);
208
209 seq_puts(seq, "details partner lacp pdu:\n");
210 seq_printf(seq, " system priority: %d\n",
211 port->partner_oper.system_priority);
212 seq_printf(seq, " oper key: %d\n",
213 port->partner_oper.key);
214 seq_printf(seq, " port priority: %d\n",
215 port->partner_oper.port_priority);
216 seq_printf(seq, " port number: %d\n",
217 port->partner_oper.port_number);
218 seq_printf(seq, " port state: %d\n",
219 port->partner_oper.port_state);
220 } else {
188 seq_puts(seq, "Aggregator ID: N/A\n"); 221 seq_puts(seq, "Aggregator ID: N/A\n");
222 }
189 } 223 }
190 seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id);
191} 224}
192 225
193static int bond_info_seq_show(struct seq_file *seq, void *v) 226static int bond_info_seq_show(struct seq_file *seq, void *v)
diff --git a/include/net/bond_3ad.h b/include/net/bond_3ad.h
index f04cdbb7848e..c2a40a172fcd 100644
--- a/include/net/bond_3ad.h
+++ b/include/net/bond_3ad.h
@@ -82,6 +82,13 @@ typedef enum {
82 AD_TRANSMIT /* tx Machine */ 82 AD_TRANSMIT /* tx Machine */
83} tx_states_t; 83} tx_states_t;
84 84
85/* churn machine states(43.4.17 in the 802.3ad standard) */
86typedef enum {
87 AD_CHURN_MONITOR, /* monitoring for churn */
88 AD_CHURN, /* churn detected (error) */
89 AD_NO_CHURN /* no churn (no error) */
90} churn_state_t;
91
85/* rx indication types */ 92/* rx indication types */
86typedef enum { 93typedef enum {
87 AD_TYPE_LACPDU = 1, /* type lacpdu */ 94 AD_TYPE_LACPDU = 1, /* type lacpdu */
@@ -229,6 +236,12 @@ typedef struct port {
229 u16 sm_mux_timer_counter; /* state machine mux timer counter */ 236 u16 sm_mux_timer_counter; /* state machine mux timer counter */
230 tx_states_t sm_tx_state; /* state machine tx state */ 237 tx_states_t sm_tx_state; /* state machine tx state */
231 u16 sm_tx_timer_counter; /* state machine tx timer counter(allways on - enter to transmit state 3 time per second) */ 238 u16 sm_tx_timer_counter; /* state machine tx timer counter(allways on - enter to transmit state 3 time per second) */
239 u16 sm_churn_actor_timer_counter;
240 u16 sm_churn_partner_timer_counter;
241 u32 churn_actor_count;
242 u32 churn_partner_count;
243 churn_state_t sm_churn_actor_state;
244 churn_state_t sm_churn_partner_state;
232 struct slave *slave; /* pointer to the bond slave that this port belongs to */ 245 struct slave *slave; /* pointer to the bond slave that this port belongs to */
233 struct aggregator *aggregator; /* pointer to an aggregator that this port related to */ 246 struct aggregator *aggregator; /* pointer to an aggregator that this port related to */
234 struct port *next_port_in_aggregator; /* Next port on the linked list of the parent aggregator */ 247 struct port *next_port_in_aggregator; /* Next port on the linked list of the parent aggregator */
@@ -262,6 +275,22 @@ struct ad_slave_info {
262 u16 id; 275 u16 id;
263}; 276};
264 277
278static inline const char *bond_3ad_churn_desc(churn_state_t state)
279{
280 static const char *const churn_description[] = {
281 "monitoring",
282 "churned",
283 "none",
284 "unknown"
285 };
286 int max_size = sizeof(churn_description) / sizeof(churn_description[0]);
287
288 if (state >= max_size)
289 state = max_size - 1;
290
291 return churn_description[state];
292}
293
265/* ========== AD Exported functions to the main bonding code ========== */ 294/* ========== AD Exported functions to the main bonding code ========== */
266void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution); 295void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution);
267void bond_3ad_bind_slave(struct slave *slave); 296void bond_3ad_bind_slave(struct slave *slave);