1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2015 Intel Corporation
3 */
4
5 #include <stddef.h>
6 #include <string.h>
7 #include <stdbool.h>
8
9 #include <rte_alarm.h>
10 #include <rte_malloc.h>
11 #include <rte_errno.h>
12 #include <rte_cycles.h>
13 #include <rte_compat.h>
14
15 #include "eth_bond_private.h"
16
17 static void bond_mode_8023ad_ext_periodic_cb(void *arg);
18 #ifdef RTE_LIBRTE_BOND_DEBUG_8023AD
19
20 #define MODE4_DEBUG(fmt, ...) \
21 rte_log(RTE_LOG_DEBUG, bond_logtype, \
22 "%6u [Port %u: %s] " fmt, \
23 bond_dbg_get_time_diff_ms(), slave_id, \
24 __func__, ##__VA_ARGS__)
25
26 static uint64_t start_time;
27
28 static unsigned
bond_dbg_get_time_diff_ms(void)29 bond_dbg_get_time_diff_ms(void)
30 {
31 uint64_t now;
32
33 now = rte_rdtsc();
34 if (start_time == 0)
35 start_time = now;
36
37 return ((now - start_time) * 1000) / rte_get_tsc_hz();
38 }
39
40 static void
bond_print_lacp(struct lacpdu * l)41 bond_print_lacp(struct lacpdu *l)
42 {
43 char a_address[18];
44 char p_address[18];
45 char a_state[256] = { 0 };
46 char p_state[256] = { 0 };
47
48 static const char * const state_labels[] = {
49 "ACT", "TIMEOUT", "AGG", "SYNC", "COL", "DIST", "DEF", "EXP"
50 };
51
52 int a_len = 0;
53 int p_len = 0;
54 uint8_t i;
55 uint8_t *addr;
56
57 addr = l->actor.port_params.system.addr_bytes;
58 snprintf(a_address, sizeof(a_address), RTE_ETHER_ADDR_PRT_FMT,
59 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
60
61 addr = l->partner.port_params.system.addr_bytes;
62 snprintf(p_address, sizeof(p_address), RTE_ETHER_ADDR_PRT_FMT,
63 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
64
65 for (i = 0; i < 8; i++) {
66 if ((l->actor.state >> i) & 1) {
67 a_len += snprintf(&a_state[a_len], RTE_DIM(a_state) - a_len, "%s ",
68 state_labels[i]);
69 }
70
71 if ((l->partner.state >> i) & 1) {
72 p_len += snprintf(&p_state[p_len], RTE_DIM(p_state) - p_len, "%s ",
73 state_labels[i]);
74 }
75 }
76
77 if (a_len && a_state[a_len-1] == ' ')
78 a_state[a_len-1] = '\0';
79
80 if (p_len && p_state[p_len-1] == ' ')
81 p_state[p_len-1] = '\0';
82
83 RTE_BOND_LOG(DEBUG,
84 "LACP: {\n"
85 " subtype= %02X\n"
86 " ver_num=%02X\n"
87 " actor={ tlv=%02X, len=%02X\n"
88 " pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"
89 " state={ %s }\n"
90 " }\n"
91 " partner={ tlv=%02X, len=%02X\n"
92 " pri=%04X, system=%s, key=%04X, p_pri=%04X p_num=%04X\n"
93 " state={ %s }\n"
94 " }\n"
95 " collector={info=%02X, length=%02X, max_delay=%04X\n, "
96 "type_term=%02X, terminator_length = %02X }",
97 l->subtype,
98 l->version_number,
99 l->actor.tlv_type_info,
100 l->actor.info_length,
101 l->actor.port_params.system_priority,
102 a_address,
103 l->actor.port_params.key,
104 l->actor.port_params.port_priority,
105 l->actor.port_params.port_number,
106 a_state,
107 l->partner.tlv_type_info,
108 l->partner.info_length,
109 l->partner.port_params.system_priority,
110 p_address,
111 l->partner.port_params.key,
112 l->partner.port_params.port_priority,
113 l->partner.port_params.port_number,
114 p_state,
115 l->tlv_type_collector_info,
116 l->collector_info_length,
117 l->collector_max_delay,
118 l->tlv_type_terminator,
119 l->terminator_length);
120
121 }
122
123 #define BOND_PRINT_LACP(lacpdu) bond_print_lacp(lacpdu)
124 #else
125 #define BOND_PRINT_LACP(lacpdu) do { } while (0)
126 #define MODE4_DEBUG(fmt, ...) do { } while (0)
127 #endif
128
129 static const struct rte_ether_addr lacp_mac_addr = {
130 .addr_bytes = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x02 }
131 };
132
133 struct port bond_mode_8023ad_ports[RTE_MAX_ETHPORTS];
134
135 static void
timer_cancel(uint64_t * timer)136 timer_cancel(uint64_t *timer)
137 {
138 *timer = 0;
139 }
140
141 static void
timer_set(uint64_t * timer,uint64_t timeout)142 timer_set(uint64_t *timer, uint64_t timeout)
143 {
144 *timer = rte_rdtsc() + timeout;
145 }
146
147 /* Forces given timer to be in expired state. */
148 static void
timer_force_expired(uint64_t * timer)149 timer_force_expired(uint64_t *timer)
150 {
151 *timer = rte_rdtsc();
152 }
153
154 static bool
timer_is_stopped(uint64_t * timer)155 timer_is_stopped(uint64_t *timer)
156 {
157 return *timer == 0;
158 }
159
160 static bool
timer_is_expired(uint64_t * timer)161 timer_is_expired(uint64_t *timer)
162 {
163 return *timer < rte_rdtsc();
164 }
165
166 /* Timer is in running state if it is not stopped nor expired */
167 static bool
timer_is_running(uint64_t * timer)168 timer_is_running(uint64_t *timer)
169 {
170 return !timer_is_stopped(timer) && !timer_is_expired(timer);
171 }
172
173 static void
set_warning_flags(struct port * port,uint16_t flags)174 set_warning_flags(struct port *port, uint16_t flags)
175 {
176 int retval;
177 uint16_t old;
178 uint16_t new_flag = 0;
179
180 do {
181 old = port->warnings_to_show;
182 new_flag = old | flags;
183 retval = rte_atomic16_cmpset(&port->warnings_to_show, old, new_flag);
184 } while (unlikely(retval == 0));
185 }
186
187 static void
show_warnings(uint16_t slave_id)188 show_warnings(uint16_t slave_id)
189 {
190 struct port *port = &bond_mode_8023ad_ports[slave_id];
191 uint8_t warnings;
192
193 do {
194 warnings = port->warnings_to_show;
195 } while (rte_atomic16_cmpset(&port->warnings_to_show, warnings, 0) == 0);
196
197 if (!warnings)
198 return;
199
200 if (!timer_is_expired(&port->warning_timer))
201 return;
202
203
204 timer_set(&port->warning_timer, BOND_8023AD_WARNINGS_PERIOD_MS *
205 rte_get_tsc_hz() / 1000);
206
207 if (warnings & WRN_RX_QUEUE_FULL) {
208 RTE_BOND_LOG(DEBUG,
209 "Slave %u: failed to enqueue LACP packet into RX ring.\n"
210 "Receive and transmit functions must be invoked on bonded"
211 "interface at least 10 times per second or LACP will notwork correctly",
212 slave_id);
213 }
214
215 if (warnings & WRN_TX_QUEUE_FULL) {
216 RTE_BOND_LOG(DEBUG,
217 "Slave %u: failed to enqueue LACP packet into TX ring.\n"
218 "Receive and transmit functions must be invoked on bonded"
219 "interface at least 10 times per second or LACP will not work correctly",
220 slave_id);
221 }
222
223 if (warnings & WRN_RX_MARKER_TO_FAST)
224 RTE_BOND_LOG(INFO, "Slave %u: marker to early - ignoring.",
225 slave_id);
226
227 if (warnings & WRN_UNKNOWN_SLOW_TYPE) {
228 RTE_BOND_LOG(INFO,
229 "Slave %u: ignoring unknown slow protocol frame type",
230 slave_id);
231 }
232
233 if (warnings & WRN_UNKNOWN_MARKER_TYPE)
234 RTE_BOND_LOG(INFO, "Slave %u: ignoring unknown marker type",
235 slave_id);
236
237 if (warnings & WRN_NOT_LACP_CAPABLE)
238 MODE4_DEBUG("Port %u is not LACP capable!\n", slave_id);
239 }
240
241 static void
record_default(struct port * port)242 record_default(struct port *port)
243 {
244 /* Record default parameters for partner. Partner admin parameters
245 * are not implemented so set them to arbitrary default (last known) and
246 * mark actor that partner is in defaulted state. */
247 port->partner_state = STATE_LACP_ACTIVE;
248 ACTOR_STATE_SET(port, DEFAULTED);
249 }
250
251 /** Function handles rx state machine.
252 *
253 * This function implements Receive State Machine from point 5.4.12 in
254 * 802.1AX documentation. It should be called periodically.
255 *
256 * @param lacpdu LACPDU received.
257 * @param port Port on which LACPDU was received.
258 */
259 static void
rx_machine(struct bond_dev_private * internals,uint16_t slave_id,struct lacpdu * lacp)260 rx_machine(struct bond_dev_private *internals, uint16_t slave_id,
261 struct lacpdu *lacp)
262 {
263 struct port *agg, *port = &bond_mode_8023ad_ports[slave_id];
264 uint64_t timeout;
265
266 if (SM_FLAG(port, BEGIN)) {
267 /* Initialize stuff */
268 MODE4_DEBUG("-> INITIALIZE\n");
269 SM_FLAG_CLR(port, MOVED);
270 port->selected = UNSELECTED;
271
272 record_default(port);
273
274 ACTOR_STATE_CLR(port, EXPIRED);
275 timer_cancel(&port->current_while_timer);
276
277 /* DISABLED: On initialization partner is out of sync */
278 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
279
280 /* LACP DISABLED stuff if LACP not enabled on this port */
281 if (!SM_FLAG(port, LACP_ENABLED))
282 PARTNER_STATE_CLR(port, AGGREGATION);
283 else
284 PARTNER_STATE_SET(port, AGGREGATION);
285 }
286
287 if (!SM_FLAG(port, LACP_ENABLED)) {
288 /* Update parameters only if state changed */
289 if (!timer_is_stopped(&port->current_while_timer)) {
290 port->selected = UNSELECTED;
291 record_default(port);
292 PARTNER_STATE_CLR(port, AGGREGATION);
293 ACTOR_STATE_CLR(port, EXPIRED);
294 timer_cancel(&port->current_while_timer);
295 }
296 return;
297 }
298
299 if (lacp) {
300 MODE4_DEBUG("LACP -> CURRENT\n");
301 BOND_PRINT_LACP(lacp);
302 /* Update selected flag. If partner parameters are defaulted assume they
303 * are match. If not defaulted compare LACP actor with ports partner
304 * params. */
305 if (!ACTOR_STATE(port, DEFAULTED) &&
306 (ACTOR_STATE(port, AGGREGATION) != PARTNER_STATE(port, AGGREGATION)
307 || memcmp(&port->partner, &lacp->actor.port_params,
308 sizeof(port->partner)) != 0)) {
309 MODE4_DEBUG("selected <- UNSELECTED\n");
310 port->selected = UNSELECTED;
311 }
312
313 /* Record this PDU actor params as partner params */
314 memcpy(&port->partner, &lacp->actor.port_params,
315 sizeof(struct port_params));
316 port->partner_state = lacp->actor.state;
317
318 /* Partner parameters are not defaulted any more */
319 ACTOR_STATE_CLR(port, DEFAULTED);
320
321 /* If LACP partner params match this port actor params */
322 agg = &bond_mode_8023ad_ports[port->aggregator_port_id];
323 bool match = port->actor.system_priority ==
324 lacp->partner.port_params.system_priority &&
325 rte_is_same_ether_addr(&agg->actor.system,
326 &lacp->partner.port_params.system) &&
327 port->actor.port_priority ==
328 lacp->partner.port_params.port_priority &&
329 port->actor.port_number ==
330 lacp->partner.port_params.port_number;
331
332 /* Update NTT if partners information are outdated (xored and masked
333 * bits are set)*/
334 uint8_t state_mask = STATE_LACP_ACTIVE | STATE_LACP_SHORT_TIMEOUT |
335 STATE_SYNCHRONIZATION | STATE_AGGREGATION;
336
337 if (((port->actor_state ^ lacp->partner.state) & state_mask) ||
338 match == false) {
339 SM_FLAG_SET(port, NTT);
340 }
341
342 /* If LACP partner params match this port actor params */
343 if (match == true && ACTOR_STATE(port, AGGREGATION) ==
344 PARTNER_STATE(port, AGGREGATION))
345 PARTNER_STATE_SET(port, SYNCHRONIZATION);
346 else if (!PARTNER_STATE(port, AGGREGATION) && ACTOR_STATE(port,
347 AGGREGATION))
348 PARTNER_STATE_SET(port, SYNCHRONIZATION);
349 else
350 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
351
352 if (ACTOR_STATE(port, LACP_SHORT_TIMEOUT))
353 timeout = internals->mode4.short_timeout;
354 else
355 timeout = internals->mode4.long_timeout;
356
357 timer_set(&port->current_while_timer, timeout);
358 ACTOR_STATE_CLR(port, EXPIRED);
359 SM_FLAG_CLR(port, EXPIRED);
360 return; /* No state change */
361 }
362
363 /* If CURRENT state timer is not running (stopped or expired)
364 * transit to EXPIRED state from DISABLED or CURRENT */
365 if (!timer_is_running(&port->current_while_timer)) {
366 if (SM_FLAG(port, EXPIRED)) {
367 port->selected = UNSELECTED;
368 memcpy(&port->partner, &port->partner_admin,
369 sizeof(struct port_params));
370 record_default(port);
371 ACTOR_STATE_CLR(port, EXPIRED);
372 timer_cancel(&port->current_while_timer);
373 } else {
374 SM_FLAG_SET(port, EXPIRED);
375 ACTOR_STATE_SET(port, EXPIRED);
376 PARTNER_STATE_CLR(port, SYNCHRONIZATION);
377 PARTNER_STATE_SET(port, LACP_SHORT_TIMEOUT);
378 timer_set(&port->current_while_timer,
379 internals->mode4.short_timeout);
380 }
381 }
382 }
383
384 /**
385 * Function handles periodic tx state machine.
386 *
387 * Function implements Periodic Transmission state machine from point 5.4.13
388 * in 802.1AX documentation. It should be called periodically.
389 *
390 * @param port Port to handle state machine.
391 */
392 static void
periodic_machine(struct bond_dev_private * internals,uint16_t slave_id)393 periodic_machine(struct bond_dev_private *internals, uint16_t slave_id)
394 {
395 struct port *port = &bond_mode_8023ad_ports[slave_id];
396 /* Calculate if either site is LACP enabled */
397 uint64_t timeout;
398 uint8_t active = ACTOR_STATE(port, LACP_ACTIVE) ||
399 PARTNER_STATE(port, LACP_ACTIVE);
400
401 uint8_t is_partner_fast, was_partner_fast;
402 /* No periodic is on BEGIN, LACP DISABLE or when both sides are passive */
403 if (SM_FLAG(port, BEGIN) || !SM_FLAG(port, LACP_ENABLED) || !active) {
404 timer_cancel(&port->periodic_timer);
405 timer_force_expired(&port->tx_machine_timer);
406 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
407
408 MODE4_DEBUG("-> NO_PERIODIC ( %s%s%s)\n",
409 SM_FLAG(port, BEGIN) ? "begin " : "",
410 SM_FLAG(port, LACP_ENABLED) ? "" : "LACP disabled ",
411 active ? "LACP active " : "LACP passive ");
412 return;
413 }
414
415 is_partner_fast = PARTNER_STATE(port, LACP_SHORT_TIMEOUT);
416 was_partner_fast = SM_FLAG(port, PARTNER_SHORT_TIMEOUT);
417
418 /* If periodic timer is not started, transit from NO PERIODIC to FAST/SLOW.
419 * Other case: check if timer expire or partners settings changed. */
420 if (!timer_is_stopped(&port->periodic_timer)) {
421 if (timer_is_expired(&port->periodic_timer)) {
422 SM_FLAG_SET(port, NTT);
423 } else if (is_partner_fast != was_partner_fast) {
424 /* Partners timeout was slow and now it is fast -> send LACP.
425 * In other case (was fast and now it is slow) just switch
426 * timeout to slow without forcing send of LACP (because standard
427 * say so)*/
428 if (is_partner_fast)
429 SM_FLAG_SET(port, NTT);
430 } else
431 return; /* Nothing changed */
432 }
433
434 /* Handle state transition to FAST/SLOW LACP timeout */
435 if (is_partner_fast) {
436 timeout = internals->mode4.fast_periodic_timeout;
437 SM_FLAG_SET(port, PARTNER_SHORT_TIMEOUT);
438 } else {
439 timeout = internals->mode4.slow_periodic_timeout;
440 SM_FLAG_CLR(port, PARTNER_SHORT_TIMEOUT);
441 }
442
443 timer_set(&port->periodic_timer, timeout);
444 }
445
446 /**
447 * Function handles mux state machine.
448 *
449 * Function implements Mux Machine from point 5.4.15 in 802.1AX documentation.
450 * It should be called periodically.
451 *
452 * @param port Port to handle state machine.
453 */
454 static void
mux_machine(struct bond_dev_private * internals,uint16_t slave_id)455 mux_machine(struct bond_dev_private *internals, uint16_t slave_id)
456 {
457 struct port *port = &bond_mode_8023ad_ports[slave_id];
458
459 /* Save current state for later use */
460 const uint8_t state_mask = STATE_SYNCHRONIZATION | STATE_DISTRIBUTING |
461 STATE_COLLECTING;
462
463 /* Enter DETACHED state on BEGIN condition or from any other state if
464 * port was unselected */
465 if (SM_FLAG(port, BEGIN) ||
466 port->selected == UNSELECTED || (port->selected == STANDBY &&
467 (port->actor_state & state_mask) != 0)) {
468 /* detach mux from aggregator */
469 port->actor_state &= ~state_mask;
470 /* Set ntt to true if BEGIN condition or transition from any other state
471 * which is indicated that wait_while_timer was started */
472 if (SM_FLAG(port, BEGIN) ||
473 !timer_is_stopped(&port->wait_while_timer)) {
474 SM_FLAG_SET(port, NTT);
475 MODE4_DEBUG("-> DETACHED\n");
476 }
477 timer_cancel(&port->wait_while_timer);
478 }
479
480 if (timer_is_stopped(&port->wait_while_timer)) {
481 if (port->selected == SELECTED || port->selected == STANDBY) {
482 timer_set(&port->wait_while_timer,
483 internals->mode4.aggregate_wait_timeout);
484
485 MODE4_DEBUG("DETACHED -> WAITING\n");
486 }
487 /* Waiting state entered */
488 return;
489 }
490
491 /* Transit next state if port is ready */
492 if (!timer_is_expired(&port->wait_while_timer))
493 return;
494
495 if ((ACTOR_STATE(port, DISTRIBUTING) || ACTOR_STATE(port, COLLECTING)) &&
496 !PARTNER_STATE(port, SYNCHRONIZATION)) {
497 /* If in COLLECTING or DISTRIBUTING state and partner becomes out of
498 * sync transit to ATTACHED state. */
499 ACTOR_STATE_CLR(port, DISTRIBUTING);
500 ACTOR_STATE_CLR(port, COLLECTING);
501 /* Clear actor sync to activate transit ATTACHED in condition bellow */
502 ACTOR_STATE_CLR(port, SYNCHRONIZATION);
503 MODE4_DEBUG("Out of sync -> ATTACHED\n");
504 }
505
506 if (!ACTOR_STATE(port, SYNCHRONIZATION)) {
507 /* attach mux to aggregator */
508 RTE_ASSERT((port->actor_state & (STATE_COLLECTING |
509 STATE_DISTRIBUTING)) == 0);
510
511 ACTOR_STATE_SET(port, SYNCHRONIZATION);
512 SM_FLAG_SET(port, NTT);
513 MODE4_DEBUG("ATTACHED Entered\n");
514 } else if (!ACTOR_STATE(port, COLLECTING)) {
515 /* Start collecting if in sync */
516 if (PARTNER_STATE(port, SYNCHRONIZATION)) {
517 MODE4_DEBUG("ATTACHED -> COLLECTING\n");
518 ACTOR_STATE_SET(port, COLLECTING);
519 SM_FLAG_SET(port, NTT);
520 }
521 } else if (ACTOR_STATE(port, COLLECTING)) {
522 /* Check if partner is in COLLECTING state. If so this port can
523 * distribute frames to it */
524 if (!ACTOR_STATE(port, DISTRIBUTING)) {
525 if (PARTNER_STATE(port, COLLECTING)) {
526 /* Enable DISTRIBUTING if partner is collecting */
527 ACTOR_STATE_SET(port, DISTRIBUTING);
528 SM_FLAG_SET(port, NTT);
529 MODE4_DEBUG("COLLECTING -> DISTRIBUTING\n");
530 RTE_BOND_LOG(INFO,
531 "Bond %u: slave id %u distributing started.",
532 internals->port_id, slave_id);
533 }
534 } else {
535 if (!PARTNER_STATE(port, COLLECTING)) {
536 /* Disable DISTRIBUTING (enter COLLECTING state) if partner
537 * is not collecting */
538 ACTOR_STATE_CLR(port, DISTRIBUTING);
539 SM_FLAG_SET(port, NTT);
540 MODE4_DEBUG("DISTRIBUTING -> COLLECTING\n");
541 RTE_BOND_LOG(INFO,
542 "Bond %u: slave id %u distributing stopped.",
543 internals->port_id, slave_id);
544 }
545 }
546 }
547 }
548
549 /**
550 * Function handles transmit state machine.
551 *
552 * Function implements Transmit Machine from point 5.4.16 in 802.1AX
553 * documentation.
554 *
555 * @param port
556 */
557 static void
tx_machine(struct bond_dev_private * internals,uint16_t slave_id)558 tx_machine(struct bond_dev_private *internals, uint16_t slave_id)
559 {
560 struct port *agg, *port = &bond_mode_8023ad_ports[slave_id];
561
562 struct rte_mbuf *lacp_pkt = NULL;
563 struct lacpdu_header *hdr;
564 struct lacpdu *lacpdu;
565
566 /* If periodic timer is not running periodic machine is in NO PERIODIC and
567 * according to 802.3ax standard tx machine should not transmit any frames
568 * and set ntt to false. */
569 if (timer_is_stopped(&port->periodic_timer))
570 SM_FLAG_CLR(port, NTT);
571
572 if (!SM_FLAG(port, NTT))
573 return;
574
575 if (!timer_is_expired(&port->tx_machine_timer))
576 return;
577
578 lacp_pkt = rte_pktmbuf_alloc(port->mbuf_pool);
579 if (lacp_pkt == NULL) {
580 RTE_BOND_LOG(ERR, "Failed to allocate LACP packet from pool");
581 return;
582 }
583
584 lacp_pkt->data_len = sizeof(*hdr);
585 lacp_pkt->pkt_len = sizeof(*hdr);
586
587 hdr = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
588
589 /* Source and destination MAC */
590 rte_ether_addr_copy(&lacp_mac_addr, &hdr->eth_hdr.dst_addr);
591 rte_eth_macaddr_get(slave_id, &hdr->eth_hdr.src_addr);
592 hdr->eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_SLOW);
593
594 lacpdu = &hdr->lacpdu;
595 memset(lacpdu, 0, sizeof(*lacpdu));
596
597 /* Initialize LACP part */
598 lacpdu->subtype = SLOW_SUBTYPE_LACP;
599 lacpdu->version_number = 1;
600
601 /* ACTOR */
602 lacpdu->actor.tlv_type_info = TLV_TYPE_ACTOR_INFORMATION;
603 lacpdu->actor.info_length = sizeof(struct lacpdu_actor_partner_params);
604 memcpy(&hdr->lacpdu.actor.port_params, &port->actor,
605 sizeof(port->actor));
606 agg = &bond_mode_8023ad_ports[port->aggregator_port_id];
607 rte_ether_addr_copy(&agg->actor.system,
608 &hdr->lacpdu.actor.port_params.system);
609 lacpdu->actor.state = port->actor_state;
610
611 /* PARTNER */
612 lacpdu->partner.tlv_type_info = TLV_TYPE_PARTNER_INFORMATION;
613 lacpdu->partner.info_length = sizeof(struct lacpdu_actor_partner_params);
614 memcpy(&lacpdu->partner.port_params, &port->partner,
615 sizeof(struct port_params));
616 lacpdu->partner.state = port->partner_state;
617
618 /* Other fields */
619 lacpdu->tlv_type_collector_info = TLV_TYPE_COLLECTOR_INFORMATION;
620 lacpdu->collector_info_length = 0x10;
621 lacpdu->collector_max_delay = 0;
622
623 lacpdu->tlv_type_terminator = TLV_TYPE_TERMINATOR_INFORMATION;
624 lacpdu->terminator_length = 0;
625
626 MODE4_DEBUG("Sending LACP frame\n");
627 BOND_PRINT_LACP(lacpdu);
628
629 if (internals->mode4.dedicated_queues.enabled == 0) {
630 int retval = rte_ring_enqueue(port->tx_ring, lacp_pkt);
631 if (retval != 0) {
632 /* If TX ring full, drop packet and free message.
633 Retransmission will happen in next function call. */
634 rte_pktmbuf_free(lacp_pkt);
635 set_warning_flags(port, WRN_TX_QUEUE_FULL);
636 return;
637 }
638 } else {
639 uint16_t pkts_sent = rte_eth_tx_burst(slave_id,
640 internals->mode4.dedicated_queues.tx_qid,
641 &lacp_pkt, 1);
642 if (pkts_sent != 1) {
643 rte_pktmbuf_free(lacp_pkt);
644 set_warning_flags(port, WRN_TX_QUEUE_FULL);
645 return;
646 }
647 }
648
649
650 timer_set(&port->tx_machine_timer, internals->mode4.tx_period_timeout);
651 SM_FLAG_CLR(port, NTT);
652 }
653
654 static uint16_t
max_index(uint64_t * a,int n)655 max_index(uint64_t *a, int n)
656 {
657 if (n <= 0)
658 return -1;
659
660 int i, max_i = 0;
661 uint64_t max = a[0];
662
663 for (i = 1; i < n; ++i) {
664 if (a[i] > max) {
665 max = a[i];
666 max_i = i;
667 }
668 }
669
670 return max_i;
671 }
672
673 /**
674 * Function assigns port to aggregator.
675 *
676 * @param bond_dev_private Pointer to bond_dev_private structure.
677 * @param port_pos Port to assign.
678 */
679 static void
selection_logic(struct bond_dev_private * internals,uint16_t slave_id)680 selection_logic(struct bond_dev_private *internals, uint16_t slave_id)
681 {
682 struct port *agg, *port;
683 uint16_t slaves_count, new_agg_id, i, j = 0;
684 uint16_t *slaves;
685 uint64_t agg_bandwidth[RTE_MAX_ETHPORTS] = {0};
686 uint64_t agg_count[RTE_MAX_ETHPORTS] = {0};
687 uint16_t default_slave = 0;
688 struct rte_eth_link link_info;
689 uint16_t agg_new_idx = 0;
690 int ret;
691
692 slaves = internals->active_slaves;
693 slaves_count = internals->active_slave_count;
694 port = &bond_mode_8023ad_ports[slave_id];
695
696 /* Search for aggregator suitable for this port */
697 for (i = 0; i < slaves_count; ++i) {
698 agg = &bond_mode_8023ad_ports[slaves[i]];
699 /* Skip ports that are not aggregators */
700 if (agg->aggregator_port_id != slaves[i])
701 continue;
702
703 ret = rte_eth_link_get_nowait(slaves[i], &link_info);
704 if (ret < 0) {
705 RTE_BOND_LOG(ERR,
706 "Slave (port %u) link get failed: %s\n",
707 slaves[i], rte_strerror(-ret));
708 continue;
709 }
710 agg_count[i] += 1;
711 agg_bandwidth[i] += link_info.link_speed;
712
713 /* Actors system ID is not checked since all slave device have the same
714 * ID (MAC address). */
715 if ((agg->actor.key == port->actor.key &&
716 agg->partner.system_priority == port->partner.system_priority &&
717 rte_is_same_ether_addr(&agg->partner.system,
718 &port->partner.system) == 1
719 && (agg->partner.key == port->partner.key)) &&
720 rte_is_zero_ether_addr(&port->partner.system) != 1 &&
721 (agg->actor.key &
722 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) != 0) {
723
724 if (j == 0)
725 default_slave = i;
726 j++;
727 }
728 }
729
730 switch (internals->mode4.agg_selection) {
731 case AGG_COUNT:
732 agg_new_idx = max_index(agg_count, slaves_count);
733 new_agg_id = slaves[agg_new_idx];
734 break;
735 case AGG_BANDWIDTH:
736 agg_new_idx = max_index(agg_bandwidth, slaves_count);
737 new_agg_id = slaves[agg_new_idx];
738 break;
739 case AGG_STABLE:
740 if (default_slave == slaves_count)
741 new_agg_id = slaves[slave_id];
742 else
743 new_agg_id = slaves[default_slave];
744 break;
745 default:
746 if (default_slave == slaves_count)
747 new_agg_id = slaves[slave_id];
748 else
749 new_agg_id = slaves[default_slave];
750 break;
751 }
752
753 if (new_agg_id != port->aggregator_port_id) {
754 port->aggregator_port_id = new_agg_id;
755
756 MODE4_DEBUG("-> SELECTED: ID=%3u\n"
757 "\t%s aggregator ID=%3u\n",
758 port->aggregator_port_id,
759 port->aggregator_port_id == slave_id ?
760 "aggregator not found, using default" : "aggregator found",
761 port->aggregator_port_id);
762 }
763
764 port->selected = SELECTED;
765 }
766
767 /* Function maps DPDK speed to bonding speed stored in key field */
768 static uint16_t
link_speed_key(uint16_t speed)769 link_speed_key(uint16_t speed) {
770 uint16_t key_speed;
771
772 switch (speed) {
773 case RTE_ETH_SPEED_NUM_NONE:
774 key_speed = 0x00;
775 break;
776 case RTE_ETH_SPEED_NUM_10M:
777 key_speed = BOND_LINK_SPEED_KEY_10M;
778 break;
779 case RTE_ETH_SPEED_NUM_100M:
780 key_speed = BOND_LINK_SPEED_KEY_100M;
781 break;
782 case RTE_ETH_SPEED_NUM_1G:
783 key_speed = BOND_LINK_SPEED_KEY_1000M;
784 break;
785 case RTE_ETH_SPEED_NUM_10G:
786 key_speed = BOND_LINK_SPEED_KEY_10G;
787 break;
788 case RTE_ETH_SPEED_NUM_20G:
789 key_speed = BOND_LINK_SPEED_KEY_20G;
790 break;
791 case RTE_ETH_SPEED_NUM_40G:
792 key_speed = BOND_LINK_SPEED_KEY_40G;
793 break;
794 default:
795 /* Unknown speed*/
796 key_speed = 0xFFFF;
797 }
798
799 return key_speed;
800 }
801
802 static void
rx_machine_update(struct bond_dev_private * internals,uint16_t slave_id,struct rte_mbuf * lacp_pkt)803 rx_machine_update(struct bond_dev_private *internals, uint16_t slave_id,
804 struct rte_mbuf *lacp_pkt) {
805 struct lacpdu_header *lacp;
806 struct lacpdu_actor_partner_params *partner;
807 struct port *port, *agg;
808
809 if (lacp_pkt != NULL) {
810 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
811 RTE_ASSERT(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
812
813 partner = &lacp->lacpdu.partner;
814 port = &bond_mode_8023ad_ports[slave_id];
815 agg = &bond_mode_8023ad_ports[port->aggregator_port_id];
816
817 if (rte_is_zero_ether_addr(&partner->port_params.system) ||
818 rte_is_same_ether_addr(&partner->port_params.system,
819 &agg->actor.system)) {
820 /* This LACP frame is sending to the bonding port
821 * so pass it to rx_machine.
822 */
823 rx_machine(internals, slave_id, &lacp->lacpdu);
824 } else {
825 char preferred_system_name[RTE_ETHER_ADDR_FMT_SIZE];
826 char self_system_name[RTE_ETHER_ADDR_FMT_SIZE];
827
828 rte_ether_format_addr(preferred_system_name,
829 RTE_ETHER_ADDR_FMT_SIZE, &partner->port_params.system);
830 rte_ether_format_addr(self_system_name,
831 RTE_ETHER_ADDR_FMT_SIZE, &agg->actor.system);
832 MODE4_DEBUG("preferred partner system %s "
833 "is not equal with self system: %s\n",
834 preferred_system_name, self_system_name);
835 }
836 rte_pktmbuf_free(lacp_pkt);
837 } else
838 rx_machine(internals, slave_id, NULL);
839 }
840
841 static void
bond_mode_8023ad_dedicated_rxq_process(struct bond_dev_private * internals,uint16_t slave_id)842 bond_mode_8023ad_dedicated_rxq_process(struct bond_dev_private *internals,
843 uint16_t slave_id)
844 {
845 #define DEDICATED_QUEUE_BURST_SIZE 32
846 struct rte_mbuf *lacp_pkt[DEDICATED_QUEUE_BURST_SIZE];
847 uint16_t rx_count = rte_eth_rx_burst(slave_id,
848 internals->mode4.dedicated_queues.rx_qid,
849 lacp_pkt, DEDICATED_QUEUE_BURST_SIZE);
850
851 if (rx_count) {
852 uint16_t i;
853
854 for (i = 0; i < rx_count; i++)
855 bond_mode_8023ad_handle_slow_pkt(internals, slave_id,
856 lacp_pkt[i]);
857 } else {
858 rx_machine_update(internals, slave_id, NULL);
859 }
860 }
861
862 static void
bond_mode_8023ad_periodic_cb(void * arg)863 bond_mode_8023ad_periodic_cb(void *arg)
864 {
865 struct rte_eth_dev *bond_dev = arg;
866 struct bond_dev_private *internals = bond_dev->data->dev_private;
867 struct port *port;
868 struct rte_eth_link link_info;
869 struct rte_ether_addr slave_addr;
870 struct rte_mbuf *lacp_pkt = NULL;
871 uint16_t slave_id;
872 uint16_t i;
873
874
875 /* Update link status on each port */
876 for (i = 0; i < internals->active_slave_count; i++) {
877 uint16_t key;
878 int ret;
879
880 slave_id = internals->active_slaves[i];
881 ret = rte_eth_link_get_nowait(slave_id, &link_info);
882 if (ret < 0) {
883 RTE_BOND_LOG(ERR,
884 "Slave (port %u) link get failed: %s\n",
885 slave_id, rte_strerror(-ret));
886 }
887
888 if (ret >= 0 && link_info.link_status != 0) {
889 key = link_speed_key(link_info.link_speed) << 1;
890 if (link_info.link_duplex == RTE_ETH_LINK_FULL_DUPLEX)
891 key |= BOND_LINK_FULL_DUPLEX_KEY;
892 } else {
893 key = 0;
894 }
895
896 rte_eth_macaddr_get(slave_id, &slave_addr);
897 port = &bond_mode_8023ad_ports[slave_id];
898
899 key = rte_cpu_to_be_16(key);
900 if (key != port->actor.key) {
901 if (!(key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)))
902 set_warning_flags(port, WRN_NOT_LACP_CAPABLE);
903
904 port->actor.key = key;
905 SM_FLAG_SET(port, NTT);
906 }
907
908 if (!rte_is_same_ether_addr(&port->actor.system, &slave_addr)) {
909 rte_ether_addr_copy(&slave_addr, &port->actor.system);
910 if (port->aggregator_port_id == slave_id)
911 SM_FLAG_SET(port, NTT);
912 }
913 }
914
915 for (i = 0; i < internals->active_slave_count; i++) {
916 slave_id = internals->active_slaves[i];
917 port = &bond_mode_8023ad_ports[slave_id];
918
919 if ((port->actor.key &
920 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) == 0) {
921
922 SM_FLAG_SET(port, BEGIN);
923
924 /* LACP is disabled on half duplex or link is down */
925 if (SM_FLAG(port, LACP_ENABLED)) {
926 /* If port was enabled set it to BEGIN state */
927 SM_FLAG_CLR(port, LACP_ENABLED);
928 ACTOR_STATE_CLR(port, DISTRIBUTING);
929 ACTOR_STATE_CLR(port, COLLECTING);
930 }
931
932 /* Skip this port processing */
933 continue;
934 }
935
936 SM_FLAG_SET(port, LACP_ENABLED);
937
938 if (internals->mode4.dedicated_queues.enabled == 0) {
939 /* Find LACP packet to this port. Do not check subtype,
940 * it is done in function that queued packet
941 */
942 int retval = rte_ring_dequeue(port->rx_ring,
943 (void **)&lacp_pkt);
944
945 if (retval != 0)
946 lacp_pkt = NULL;
947
948 rx_machine_update(internals, slave_id, lacp_pkt);
949 } else {
950 bond_mode_8023ad_dedicated_rxq_process(internals,
951 slave_id);
952 }
953
954 periodic_machine(internals, slave_id);
955 mux_machine(internals, slave_id);
956 tx_machine(internals, slave_id);
957 selection_logic(internals, slave_id);
958
959 SM_FLAG_CLR(port, BEGIN);
960 show_warnings(slave_id);
961 }
962
963 rte_eal_alarm_set(internals->mode4.update_timeout_us,
964 bond_mode_8023ad_periodic_cb, arg);
965 }
966
967 static int
bond_mode_8023ad_register_lacp_mac(uint16_t slave_id)968 bond_mode_8023ad_register_lacp_mac(uint16_t slave_id)
969 {
970 int ret;
971
972 ret = rte_eth_allmulticast_enable(slave_id);
973 if (ret != 0) {
974 RTE_BOND_LOG(ERR,
975 "failed to enable allmulti mode for port %u: %s",
976 slave_id, rte_strerror(-ret));
977 }
978 if (rte_eth_allmulticast_get(slave_id)) {
979 RTE_BOND_LOG(DEBUG, "forced allmulti for port %u",
980 slave_id);
981 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
982 BOND_8023AD_FORCED_ALLMULTI;
983 return 0;
984 }
985
986 ret = rte_eth_promiscuous_enable(slave_id);
987 if (ret != 0) {
988 RTE_BOND_LOG(ERR,
989 "failed to enable promiscuous mode for port %u: %s",
990 slave_id, rte_strerror(-ret));
991 }
992 if (rte_eth_promiscuous_get(slave_id)) {
993 RTE_BOND_LOG(DEBUG, "forced promiscuous for port %u",
994 slave_id);
995 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
996 BOND_8023AD_FORCED_PROMISC;
997 return 0;
998 }
999
1000 return -1;
1001 }
1002
1003 static void
bond_mode_8023ad_unregister_lacp_mac(uint16_t slave_id)1004 bond_mode_8023ad_unregister_lacp_mac(uint16_t slave_id)
1005 {
1006 int ret;
1007
1008 switch (bond_mode_8023ad_ports[slave_id].forced_rx_flags) {
1009 case BOND_8023AD_FORCED_ALLMULTI:
1010 RTE_BOND_LOG(DEBUG, "unset allmulti for port %u", slave_id);
1011 ret = rte_eth_allmulticast_disable(slave_id);
1012 if (ret != 0)
1013 RTE_BOND_LOG(ERR,
1014 "failed to disable allmulti mode for port %u: %s",
1015 slave_id, rte_strerror(-ret));
1016 break;
1017
1018 case BOND_8023AD_FORCED_PROMISC:
1019 RTE_BOND_LOG(DEBUG, "unset promisc for port %u", slave_id);
1020 ret = rte_eth_promiscuous_disable(slave_id);
1021 if (ret != 0)
1022 RTE_BOND_LOG(ERR,
1023 "failed to disable promiscuous mode for port %u: %s",
1024 slave_id, rte_strerror(-ret));
1025 break;
1026
1027 default:
1028 break;
1029 }
1030 }
1031
1032 void
bond_mode_8023ad_activate_slave(struct rte_eth_dev * bond_dev,uint16_t slave_id)1033 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
1034 uint16_t slave_id)
1035 {
1036 struct bond_dev_private *internals = bond_dev->data->dev_private;
1037
1038 struct port *port = &bond_mode_8023ad_ports[slave_id];
1039 struct port_params initial = {
1040 .system = { { 0 } },
1041 .system_priority = rte_cpu_to_be_16(0xFFFF),
1042 .key = rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY),
1043 .port_priority = rte_cpu_to_be_16(0x00FF),
1044 .port_number = 0,
1045 };
1046
1047 char mem_name[RTE_ETH_NAME_MAX_LEN];
1048 int socket_id;
1049 unsigned element_size;
1050 uint32_t total_tx_desc;
1051 struct bond_tx_queue *bd_tx_q;
1052 uint16_t q_id;
1053
1054 /* Given slave mus not be in active list */
1055 RTE_ASSERT(find_slave_by_id(internals->active_slaves,
1056 internals->active_slave_count, slave_id) == internals->active_slave_count);
1057 RTE_SET_USED(internals); /* used only for assert when enabled */
1058
1059 memcpy(&port->actor, &initial, sizeof(struct port_params));
1060 /* Standard requires that port ID must be grater than 0.
1061 * Add 1 do get corresponding port_number */
1062 port->actor.port_number = rte_cpu_to_be_16(slave_id + 1);
1063
1064 memcpy(&port->partner, &initial, sizeof(struct port_params));
1065 memcpy(&port->partner_admin, &initial, sizeof(struct port_params));
1066
1067 /* default states */
1068 port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
1069 port->partner_state = STATE_LACP_ACTIVE | STATE_AGGREGATION;
1070 port->sm_flags = SM_FLAGS_BEGIN;
1071
1072 /* use this port as aggregator */
1073 port->aggregator_port_id = slave_id;
1074
1075 if (bond_mode_8023ad_register_lacp_mac(slave_id) < 0) {
1076 RTE_BOND_LOG(WARNING, "slave %u is most likely broken and won't receive LACP packets",
1077 slave_id);
1078 }
1079
1080 timer_cancel(&port->warning_timer);
1081
1082 if (port->mbuf_pool != NULL)
1083 return;
1084
1085 RTE_ASSERT(port->rx_ring == NULL);
1086 RTE_ASSERT(port->tx_ring == NULL);
1087
1088 socket_id = rte_eth_dev_socket_id(slave_id);
1089 if (socket_id == -1)
1090 socket_id = rte_socket_id();
1091
1092 element_size = sizeof(struct slow_protocol_frame) +
1093 RTE_PKTMBUF_HEADROOM;
1094
1095 /* The size of the mempool should be at least:
1096 * the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
1097 total_tx_desc = BOND_MODE_8023AX_SLAVE_TX_PKTS;
1098 for (q_id = 0; q_id < bond_dev->data->nb_tx_queues; q_id++) {
1099 bd_tx_q = (struct bond_tx_queue*)bond_dev->data->tx_queues[q_id];
1100 total_tx_desc += bd_tx_q->nb_tx_desc;
1101 }
1102
1103 snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
1104 port->mbuf_pool = rte_pktmbuf_pool_create(mem_name, total_tx_desc,
1105 RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
1106 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
1107 0, element_size, socket_id);
1108
1109 /* Any memory allocation failure in initialization is critical because
1110 * resources can't be free, so reinitialization is impossible. */
1111 if (port->mbuf_pool == NULL) {
1112 rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
1113 slave_id, mem_name, rte_strerror(rte_errno));
1114 }
1115
1116 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
1117 port->rx_ring = rte_ring_create(mem_name,
1118 rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
1119
1120 if (port->rx_ring == NULL) {
1121 rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
1122 mem_name, rte_strerror(rte_errno));
1123 }
1124
1125 /* TX ring is at least one pkt longer to make room for marker packet. */
1126 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_tx", slave_id);
1127 port->tx_ring = rte_ring_create(mem_name,
1128 rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
1129
1130 if (port->tx_ring == NULL) {
1131 rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
1132 mem_name, rte_strerror(rte_errno));
1133 }
1134 }
1135
1136 int
bond_mode_8023ad_deactivate_slave(struct rte_eth_dev * bond_dev __rte_unused,uint16_t slave_id)1137 bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev __rte_unused,
1138 uint16_t slave_id)
1139 {
1140 void *pkt = NULL;
1141 struct port *port = NULL;
1142 uint8_t old_partner_state;
1143
1144 port = &bond_mode_8023ad_ports[slave_id];
1145
1146 ACTOR_STATE_CLR(port, AGGREGATION);
1147 port->selected = UNSELECTED;
1148
1149 old_partner_state = port->partner_state;
1150 record_default(port);
1151
1152 bond_mode_8023ad_unregister_lacp_mac(slave_id);
1153
1154 /* If partner timeout state changes then disable timer */
1155 if (!((old_partner_state ^ port->partner_state) &
1156 STATE_LACP_SHORT_TIMEOUT))
1157 timer_cancel(&port->current_while_timer);
1158
1159 PARTNER_STATE_CLR(port, AGGREGATION);
1160 ACTOR_STATE_CLR(port, EXPIRED);
1161
1162 /* flush rx/tx rings */
1163 while (rte_ring_dequeue(port->rx_ring, &pkt) == 0)
1164 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1165
1166 while (rte_ring_dequeue(port->tx_ring, &pkt) == 0)
1167 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1168 return 0;
1169 }
1170
1171 void
bond_mode_8023ad_mac_address_update(struct rte_eth_dev * bond_dev)1172 bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev)
1173 {
1174 struct bond_dev_private *internals = bond_dev->data->dev_private;
1175 struct rte_ether_addr slave_addr;
1176 struct port *slave, *agg_slave;
1177 uint16_t slave_id, i, j;
1178
1179 bond_mode_8023ad_stop(bond_dev);
1180
1181 for (i = 0; i < internals->active_slave_count; i++) {
1182 slave_id = internals->active_slaves[i];
1183 slave = &bond_mode_8023ad_ports[slave_id];
1184 rte_eth_macaddr_get(slave_id, &slave_addr);
1185
1186 if (rte_is_same_ether_addr(&slave_addr, &slave->actor.system))
1187 continue;
1188
1189 rte_ether_addr_copy(&slave_addr, &slave->actor.system);
1190 /* Do nothing if this port is not an aggregator. In other case
1191 * Set NTT flag on every port that use this aggregator. */
1192 if (slave->aggregator_port_id != slave_id)
1193 continue;
1194
1195 for (j = 0; j < internals->active_slave_count; j++) {
1196 agg_slave = &bond_mode_8023ad_ports[internals->active_slaves[j]];
1197 if (agg_slave->aggregator_port_id == slave_id)
1198 SM_FLAG_SET(agg_slave, NTT);
1199 }
1200 }
1201
1202 if (bond_dev->data->dev_started)
1203 bond_mode_8023ad_start(bond_dev);
1204 }
1205
1206 static void
bond_mode_8023ad_conf_get(struct rte_eth_dev * dev,struct rte_eth_bond_8023ad_conf * conf)1207 bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
1208 struct rte_eth_bond_8023ad_conf *conf)
1209 {
1210 struct bond_dev_private *internals = dev->data->dev_private;
1211 struct mode8023ad_private *mode4 = &internals->mode4;
1212 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1213
1214 conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
1215 conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
1216 conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
1217 conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
1218 conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / ms_ticks;
1219 conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
1220 conf->update_timeout_ms = mode4->update_timeout_us / 1000;
1221 conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
1222 conf->slowrx_cb = mode4->slowrx_cb;
1223 conf->agg_selection = mode4->agg_selection;
1224 }
1225
1226 static void
bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf * conf)1227 bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf)
1228 {
1229 conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
1230 conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
1231 conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
1232 conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
1233 conf->aggregate_wait_timeout_ms = BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
1234 conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
1235 conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
1236 conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
1237 conf->slowrx_cb = NULL;
1238 conf->agg_selection = AGG_STABLE;
1239 }
1240
1241 static void
bond_mode_8023ad_conf_assign(struct mode8023ad_private * mode4,struct rte_eth_bond_8023ad_conf * conf)1242 bond_mode_8023ad_conf_assign(struct mode8023ad_private *mode4,
1243 struct rte_eth_bond_8023ad_conf *conf)
1244 {
1245 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1246
1247 mode4->fast_periodic_timeout = conf->fast_periodic_ms * ms_ticks;
1248 mode4->slow_periodic_timeout = conf->slow_periodic_ms * ms_ticks;
1249 mode4->short_timeout = conf->short_timeout_ms * ms_ticks;
1250 mode4->long_timeout = conf->long_timeout_ms * ms_ticks;
1251 mode4->aggregate_wait_timeout = conf->aggregate_wait_timeout_ms * ms_ticks;
1252 mode4->tx_period_timeout = conf->tx_period_ms * ms_ticks;
1253 mode4->rx_marker_timeout = conf->rx_marker_period_ms * ms_ticks;
1254 mode4->update_timeout_us = conf->update_timeout_ms * 1000;
1255
1256 mode4->dedicated_queues.enabled = 0;
1257 mode4->dedicated_queues.rx_qid = UINT16_MAX;
1258 mode4->dedicated_queues.tx_qid = UINT16_MAX;
1259 }
1260
1261 void
bond_mode_8023ad_setup(struct rte_eth_dev * dev,struct rte_eth_bond_8023ad_conf * conf)1262 bond_mode_8023ad_setup(struct rte_eth_dev *dev,
1263 struct rte_eth_bond_8023ad_conf *conf)
1264 {
1265 struct rte_eth_bond_8023ad_conf def_conf;
1266 struct bond_dev_private *internals = dev->data->dev_private;
1267 struct mode8023ad_private *mode4 = &internals->mode4;
1268
1269 if (conf == NULL) {
1270 conf = &def_conf;
1271 bond_mode_8023ad_conf_get_default(conf);
1272 }
1273
1274 bond_mode_8023ad_stop(dev);
1275 bond_mode_8023ad_conf_assign(mode4, conf);
1276 mode4->slowrx_cb = conf->slowrx_cb;
1277 mode4->agg_selection = AGG_STABLE;
1278
1279 if (dev->data->dev_started)
1280 bond_mode_8023ad_start(dev);
1281 }
1282
1283 int
bond_mode_8023ad_enable(struct rte_eth_dev * bond_dev)1284 bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
1285 {
1286 struct bond_dev_private *internals = bond_dev->data->dev_private;
1287 uint16_t i;
1288
1289 for (i = 0; i < internals->active_slave_count; i++)
1290 bond_mode_8023ad_activate_slave(bond_dev,
1291 internals->active_slaves[i]);
1292
1293 return 0;
1294 }
1295
1296 int
bond_mode_8023ad_start(struct rte_eth_dev * bond_dev)1297 bond_mode_8023ad_start(struct rte_eth_dev *bond_dev)
1298 {
1299 struct bond_dev_private *internals = bond_dev->data->dev_private;
1300 struct mode8023ad_private *mode4 = &internals->mode4;
1301 static const uint64_t us = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS * 1000;
1302
1303 rte_eth_macaddr_get(internals->port_id, &mode4->mac_addr);
1304 if (mode4->slowrx_cb)
1305 return rte_eal_alarm_set(us, &bond_mode_8023ad_ext_periodic_cb,
1306 bond_dev);
1307
1308 return rte_eal_alarm_set(us, &bond_mode_8023ad_periodic_cb, bond_dev);
1309 }
1310
1311 void
bond_mode_8023ad_stop(struct rte_eth_dev * bond_dev)1312 bond_mode_8023ad_stop(struct rte_eth_dev *bond_dev)
1313 {
1314 struct bond_dev_private *internals = bond_dev->data->dev_private;
1315 struct mode8023ad_private *mode4 = &internals->mode4;
1316
1317 if (mode4->slowrx_cb) {
1318 rte_eal_alarm_cancel(&bond_mode_8023ad_ext_periodic_cb,
1319 bond_dev);
1320 return;
1321 }
1322 rte_eal_alarm_cancel(&bond_mode_8023ad_periodic_cb, bond_dev);
1323 }
1324
1325 void
bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private * internals,uint16_t slave_id,struct rte_mbuf * pkt)1326 bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals,
1327 uint16_t slave_id, struct rte_mbuf *pkt)
1328 {
1329 struct mode8023ad_private *mode4 = &internals->mode4;
1330 struct port *port = &bond_mode_8023ad_ports[slave_id];
1331 struct marker_header *m_hdr;
1332 uint64_t marker_timer, old_marker_timer;
1333 int retval;
1334 uint8_t wrn, subtype;
1335 /* If packet is a marker, we send response now by reusing given packet
1336 * and update only source MAC, destination MAC is multicast so don't
1337 * update it. Other frames will be handled later by state machines */
1338 subtype = rte_pktmbuf_mtod(pkt,
1339 struct slow_protocol_frame *)->slow_protocol.subtype;
1340
1341 if (subtype == SLOW_SUBTYPE_MARKER) {
1342 m_hdr = rte_pktmbuf_mtod(pkt, struct marker_header *);
1343
1344 if (likely(m_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_INFO)) {
1345 wrn = WRN_UNKNOWN_MARKER_TYPE;
1346 goto free_out;
1347 }
1348
1349 /* Setup marker timer. Do it in loop in case concurrent access. */
1350 do {
1351 old_marker_timer = port->rx_marker_timer;
1352 if (!timer_is_expired(&old_marker_timer)) {
1353 wrn = WRN_RX_MARKER_TO_FAST;
1354 goto free_out;
1355 }
1356
1357 timer_set(&marker_timer, mode4->rx_marker_timeout);
1358 retval = rte_atomic64_cmpset(&port->rx_marker_timer,
1359 old_marker_timer, marker_timer);
1360 } while (unlikely(retval == 0));
1361
1362 m_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_RESP;
1363 rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.src_addr);
1364
1365 if (internals->mode4.dedicated_queues.enabled == 0) {
1366 if (rte_ring_enqueue(port->tx_ring, pkt) != 0) {
1367 /* reset timer */
1368 port->rx_marker_timer = 0;
1369 wrn = WRN_TX_QUEUE_FULL;
1370 goto free_out;
1371 }
1372 } else {
1373 /* Send packet directly to the slow queue */
1374 uint16_t tx_count = rte_eth_tx_burst(slave_id,
1375 internals->mode4.dedicated_queues.tx_qid,
1376 &pkt, 1);
1377 if (tx_count != 1) {
1378 /* reset timer */
1379 port->rx_marker_timer = 0;
1380 wrn = WRN_TX_QUEUE_FULL;
1381 goto free_out;
1382 }
1383 }
1384 } else if (likely(subtype == SLOW_SUBTYPE_LACP)) {
1385 if (internals->mode4.dedicated_queues.enabled == 0) {
1386 if (rte_ring_enqueue(port->rx_ring, pkt) != 0) {
1387 /* If RX fing full free lacpdu message and drop packet */
1388 wrn = WRN_RX_QUEUE_FULL;
1389 goto free_out;
1390 }
1391 } else
1392 rx_machine_update(internals, slave_id, pkt);
1393 } else {
1394 wrn = WRN_UNKNOWN_SLOW_TYPE;
1395 goto free_out;
1396 }
1397
1398 return;
1399
1400 free_out:
1401 set_warning_flags(port, wrn);
1402 rte_pktmbuf_free(pkt);
1403 }
1404
1405 int
rte_eth_bond_8023ad_conf_get(uint16_t port_id,struct rte_eth_bond_8023ad_conf * conf)1406 rte_eth_bond_8023ad_conf_get(uint16_t port_id,
1407 struct rte_eth_bond_8023ad_conf *conf)
1408 {
1409 struct rte_eth_dev *bond_dev;
1410
1411 if (valid_bonded_port_id(port_id) != 0)
1412 return -EINVAL;
1413
1414 if (conf == NULL)
1415 return -EINVAL;
1416
1417 bond_dev = &rte_eth_devices[port_id];
1418 bond_mode_8023ad_conf_get(bond_dev, conf);
1419 return 0;
1420 }
1421
1422 int
rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id,enum rte_bond_8023ad_agg_selection agg_selection)1423 rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id,
1424 enum rte_bond_8023ad_agg_selection agg_selection)
1425 {
1426 struct rte_eth_dev *bond_dev;
1427 struct bond_dev_private *internals;
1428 struct mode8023ad_private *mode4;
1429
1430 if (valid_bonded_port_id(port_id) != 0)
1431 return -EINVAL;
1432
1433 bond_dev = &rte_eth_devices[port_id];
1434 internals = bond_dev->data->dev_private;
1435
1436 if (internals->mode != 4)
1437 return -EINVAL;
1438
1439 mode4 = &internals->mode4;
1440 if (agg_selection == AGG_COUNT || agg_selection == AGG_BANDWIDTH
1441 || agg_selection == AGG_STABLE)
1442 mode4->agg_selection = agg_selection;
1443 return 0;
1444 }
1445
rte_eth_bond_8023ad_agg_selection_get(uint16_t port_id)1446 int rte_eth_bond_8023ad_agg_selection_get(uint16_t port_id)
1447 {
1448 struct rte_eth_dev *bond_dev;
1449 struct bond_dev_private *internals;
1450 struct mode8023ad_private *mode4;
1451
1452 if (valid_bonded_port_id(port_id) != 0)
1453 return -EINVAL;
1454
1455 bond_dev = &rte_eth_devices[port_id];
1456 internals = bond_dev->data->dev_private;
1457
1458 if (internals->mode != 4)
1459 return -EINVAL;
1460 mode4 = &internals->mode4;
1461
1462 return mode4->agg_selection;
1463 }
1464
1465
1466
1467 static int
bond_8023ad_setup_validate(uint16_t port_id,struct rte_eth_bond_8023ad_conf * conf)1468 bond_8023ad_setup_validate(uint16_t port_id,
1469 struct rte_eth_bond_8023ad_conf *conf)
1470 {
1471 if (valid_bonded_port_id(port_id) != 0)
1472 return -EINVAL;
1473
1474 if (conf != NULL) {
1475 /* Basic sanity check */
1476 if (conf->slow_periodic_ms == 0 ||
1477 conf->fast_periodic_ms >= conf->slow_periodic_ms ||
1478 conf->long_timeout_ms == 0 ||
1479 conf->short_timeout_ms >= conf->long_timeout_ms ||
1480 conf->aggregate_wait_timeout_ms == 0 ||
1481 conf->tx_period_ms == 0 ||
1482 conf->rx_marker_period_ms == 0 ||
1483 conf->update_timeout_ms == 0) {
1484 RTE_BOND_LOG(ERR, "given mode 4 configuration is invalid");
1485 return -EINVAL;
1486 }
1487 }
1488
1489 return 0;
1490 }
1491
1492
1493 int
rte_eth_bond_8023ad_setup(uint16_t port_id,struct rte_eth_bond_8023ad_conf * conf)1494 rte_eth_bond_8023ad_setup(uint16_t port_id,
1495 struct rte_eth_bond_8023ad_conf *conf)
1496 {
1497 struct rte_eth_dev *bond_dev;
1498 int err;
1499
1500 err = bond_8023ad_setup_validate(port_id, conf);
1501 if (err != 0)
1502 return err;
1503
1504 bond_dev = &rte_eth_devices[port_id];
1505 bond_mode_8023ad_setup(bond_dev, conf);
1506
1507 return 0;
1508 }
1509
1510
1511
1512
1513
1514 int
rte_eth_bond_8023ad_slave_info(uint16_t port_id,uint16_t slave_id,struct rte_eth_bond_8023ad_slave_info * info)1515 rte_eth_bond_8023ad_slave_info(uint16_t port_id, uint16_t slave_id,
1516 struct rte_eth_bond_8023ad_slave_info *info)
1517 {
1518 struct rte_eth_dev *bond_dev;
1519 struct bond_dev_private *internals;
1520 struct port *port;
1521
1522 if (info == NULL || valid_bonded_port_id(port_id) != 0 ||
1523 rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1524 return -EINVAL;
1525
1526 bond_dev = &rte_eth_devices[port_id];
1527
1528 internals = bond_dev->data->dev_private;
1529 if (find_slave_by_id(internals->active_slaves,
1530 internals->active_slave_count, slave_id) ==
1531 internals->active_slave_count)
1532 return -EINVAL;
1533
1534 port = &bond_mode_8023ad_ports[slave_id];
1535 info->selected = port->selected;
1536
1537 info->actor_state = port->actor_state;
1538 rte_memcpy(&info->actor, &port->actor, sizeof(port->actor));
1539
1540 info->partner_state = port->partner_state;
1541 rte_memcpy(&info->partner, &port->partner, sizeof(port->partner));
1542
1543 info->agg_port_id = port->aggregator_port_id;
1544 return 0;
1545 }
1546
1547 static int
bond_8023ad_ext_validate(uint16_t port_id,uint16_t slave_id)1548 bond_8023ad_ext_validate(uint16_t port_id, uint16_t slave_id)
1549 {
1550 struct rte_eth_dev *bond_dev;
1551 struct bond_dev_private *internals;
1552 struct mode8023ad_private *mode4;
1553
1554 if (rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1555 return -EINVAL;
1556
1557 bond_dev = &rte_eth_devices[port_id];
1558
1559 if (!bond_dev->data->dev_started)
1560 return -EINVAL;
1561
1562 internals = bond_dev->data->dev_private;
1563 if (find_slave_by_id(internals->active_slaves,
1564 internals->active_slave_count, slave_id) ==
1565 internals->active_slave_count)
1566 return -EINVAL;
1567
1568 mode4 = &internals->mode4;
1569 if (mode4->slowrx_cb == NULL)
1570 return -EINVAL;
1571
1572 return 0;
1573 }
1574
1575 int
rte_eth_bond_8023ad_ext_collect(uint16_t port_id,uint16_t slave_id,int enabled)1576 rte_eth_bond_8023ad_ext_collect(uint16_t port_id, uint16_t slave_id,
1577 int enabled)
1578 {
1579 struct port *port;
1580 int res;
1581
1582 res = bond_8023ad_ext_validate(port_id, slave_id);
1583 if (res != 0)
1584 return res;
1585
1586 port = &bond_mode_8023ad_ports[slave_id];
1587
1588 if (enabled)
1589 ACTOR_STATE_SET(port, COLLECTING);
1590 else
1591 ACTOR_STATE_CLR(port, COLLECTING);
1592
1593 return 0;
1594 }
1595
1596 int
rte_eth_bond_8023ad_ext_distrib(uint16_t port_id,uint16_t slave_id,int enabled)1597 rte_eth_bond_8023ad_ext_distrib(uint16_t port_id, uint16_t slave_id,
1598 int enabled)
1599 {
1600 struct port *port;
1601 int res;
1602
1603 res = bond_8023ad_ext_validate(port_id, slave_id);
1604 if (res != 0)
1605 return res;
1606
1607 port = &bond_mode_8023ad_ports[slave_id];
1608
1609 if (enabled)
1610 ACTOR_STATE_SET(port, DISTRIBUTING);
1611 else
1612 ACTOR_STATE_CLR(port, DISTRIBUTING);
1613
1614 return 0;
1615 }
1616
1617 int
rte_eth_bond_8023ad_ext_distrib_get(uint16_t port_id,uint16_t slave_id)1618 rte_eth_bond_8023ad_ext_distrib_get(uint16_t port_id, uint16_t slave_id)
1619 {
1620 struct port *port;
1621 int err;
1622
1623 err = bond_8023ad_ext_validate(port_id, slave_id);
1624 if (err != 0)
1625 return err;
1626
1627 port = &bond_mode_8023ad_ports[slave_id];
1628 return ACTOR_STATE(port, DISTRIBUTING);
1629 }
1630
1631 int
rte_eth_bond_8023ad_ext_collect_get(uint16_t port_id,uint16_t slave_id)1632 rte_eth_bond_8023ad_ext_collect_get(uint16_t port_id, uint16_t slave_id)
1633 {
1634 struct port *port;
1635 int err;
1636
1637 err = bond_8023ad_ext_validate(port_id, slave_id);
1638 if (err != 0)
1639 return err;
1640
1641 port = &bond_mode_8023ad_ports[slave_id];
1642 return ACTOR_STATE(port, COLLECTING);
1643 }
1644
1645 int
rte_eth_bond_8023ad_ext_slowtx(uint16_t port_id,uint16_t slave_id,struct rte_mbuf * lacp_pkt)1646 rte_eth_bond_8023ad_ext_slowtx(uint16_t port_id, uint16_t slave_id,
1647 struct rte_mbuf *lacp_pkt)
1648 {
1649 struct port *port;
1650 int res;
1651
1652 res = bond_8023ad_ext_validate(port_id, slave_id);
1653 if (res != 0)
1654 return res;
1655
1656 port = &bond_mode_8023ad_ports[slave_id];
1657
1658 if (rte_pktmbuf_pkt_len(lacp_pkt) < sizeof(struct lacpdu_header))
1659 return -EINVAL;
1660
1661 struct lacpdu_header *lacp;
1662
1663 /* only enqueue LACPDUs */
1664 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
1665 if (lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
1666 return -EINVAL;
1667
1668 MODE4_DEBUG("sending LACP frame\n");
1669
1670 return rte_ring_enqueue(port->tx_ring, lacp_pkt);
1671 }
1672
1673 static void
bond_mode_8023ad_ext_periodic_cb(void * arg)1674 bond_mode_8023ad_ext_periodic_cb(void *arg)
1675 {
1676 struct rte_eth_dev *bond_dev = arg;
1677 struct bond_dev_private *internals = bond_dev->data->dev_private;
1678 struct mode8023ad_private *mode4 = &internals->mode4;
1679 struct port *port;
1680 void *pkt = NULL;
1681 uint16_t i, slave_id;
1682
1683 for (i = 0; i < internals->active_slave_count; i++) {
1684 slave_id = internals->active_slaves[i];
1685 port = &bond_mode_8023ad_ports[slave_id];
1686
1687 if (rte_ring_dequeue(port->rx_ring, &pkt) == 0) {
1688 struct rte_mbuf *lacp_pkt = pkt;
1689 struct lacpdu_header *lacp;
1690
1691 lacp = rte_pktmbuf_mtod(lacp_pkt,
1692 struct lacpdu_header *);
1693 RTE_VERIFY(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
1694
1695 /* This is LACP frame so pass it to rx callback.
1696 * Callback is responsible for freeing mbuf.
1697 */
1698 mode4->slowrx_cb(slave_id, lacp_pkt);
1699 }
1700 }
1701
1702 rte_eal_alarm_set(internals->mode4.update_timeout_us,
1703 bond_mode_8023ad_ext_periodic_cb, arg);
1704 }
1705
1706 int
rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)1707 rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
1708 {
1709 int retval = 0;
1710 struct rte_eth_dev *dev;
1711 struct bond_dev_private *internals;
1712
1713 if (valid_bonded_port_id(port) != 0)
1714 return -EINVAL;
1715
1716 dev = &rte_eth_devices[port];
1717 internals = dev->data->dev_private;
1718
1719 if (bond_8023ad_slow_pkt_hw_filter_supported(port) != 0)
1720 return -1;
1721
1722 /* Device must be stopped to set up slow queue */
1723 if (dev->data->dev_started)
1724 return -1;
1725
1726 internals->mode4.dedicated_queues.enabled = 1;
1727
1728 bond_ethdev_mode_set(dev, internals->mode);
1729 return retval;
1730 }
1731
1732 int
rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)1733 rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)
1734 {
1735 int retval = 0;
1736 struct rte_eth_dev *dev;
1737 struct bond_dev_private *internals;
1738
1739 if (valid_bonded_port_id(port) != 0)
1740 return -EINVAL;
1741
1742 dev = &rte_eth_devices[port];
1743 internals = dev->data->dev_private;
1744
1745 /* Device must be stopped to set up slow queue */
1746 if (dev->data->dev_started)
1747 return -1;
1748
1749 internals->mode4.dedicated_queues.enabled = 0;
1750
1751 bond_ethdev_mode_set(dev, internals->mode);
1752
1753 return retval;
1754 }
1755