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), "%02X:%02X:%02X:%02X:%02X:%02X",
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), "%02X:%02X:%02X:%02X:%02X:%02X",
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 parner 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 parner
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 pasive */
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) ? "begind " : "",
410 SM_FLAG(port, LACP_ENABLED) ? "" : "LACP disabled ",
411 active ? "LACP active " : "LACP pasive ");
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 ATACHED state. */
499 ACTOR_STATE_CLR(port, DISTRIBUTING);
500 ACTOR_STATE_CLR(port, COLLECTING);
501 /* Clear actor sync to activate transit ATACHED 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.d_addr);
591 rte_eth_macaddr_get(slave_id, &hdr->eth_hdr.s_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 aggreagators */
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 ETH_SPEED_NUM_NONE:
774 key_speed = 0x00;
775 break;
776 case ETH_SPEED_NUM_10M:
777 key_speed = BOND_LINK_SPEED_KEY_10M;
778 break;
779 case ETH_SPEED_NUM_100M:
780 key_speed = BOND_LINK_SPEED_KEY_100M;
781 break;
782 case ETH_SPEED_NUM_1G:
783 key_speed = BOND_LINK_SPEED_KEY_1000M;
784 break;
785 case ETH_SPEED_NUM_10G:
786 key_speed = BOND_LINK_SPEED_KEY_10G;
787 break;
788 case ETH_SPEED_NUM_20G:
789 key_speed = BOND_LINK_SPEED_KEY_20G;
790 break;
791 case 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
808 if (lacp_pkt != NULL) {
809 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
810 RTE_ASSERT(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
811
812 partner = &lacp->lacpdu.partner;
813 if (rte_is_zero_ether_addr(&partner->port_params.system) ||
814 rte_is_same_ether_addr(&partner->port_params.system,
815 &internals->mode4.mac_addr)) {
816 /* This LACP frame is sending to the bonding port
817 * so pass it to rx_machine.
818 */
819 rx_machine(internals, slave_id, &lacp->lacpdu);
820 }
821 rte_pktmbuf_free(lacp_pkt);
822 } else
823 rx_machine(internals, slave_id, NULL);
824 }
825
826 static void
bond_mode_8023ad_periodic_cb(void * arg)827 bond_mode_8023ad_periodic_cb(void *arg)
828 {
829 struct rte_eth_dev *bond_dev = arg;
830 struct bond_dev_private *internals = bond_dev->data->dev_private;
831 struct port *port;
832 struct rte_eth_link link_info;
833 struct rte_ether_addr slave_addr;
834 struct rte_mbuf *lacp_pkt = NULL;
835 uint16_t slave_id;
836 uint16_t i;
837
838
839 /* Update link status on each port */
840 for (i = 0; i < internals->active_slave_count; i++) {
841 uint16_t key;
842 int ret;
843
844 slave_id = internals->active_slaves[i];
845 ret = rte_eth_link_get_nowait(slave_id, &link_info);
846 if (ret < 0) {
847 RTE_BOND_LOG(ERR,
848 "Slave (port %u) link get failed: %s\n",
849 slave_id, rte_strerror(-ret));
850 }
851
852 if (ret >= 0 && link_info.link_status != 0) {
853 key = link_speed_key(link_info.link_speed) << 1;
854 if (link_info.link_duplex == ETH_LINK_FULL_DUPLEX)
855 key |= BOND_LINK_FULL_DUPLEX_KEY;
856 } else {
857 key = 0;
858 }
859
860 rte_eth_macaddr_get(slave_id, &slave_addr);
861 port = &bond_mode_8023ad_ports[slave_id];
862
863 key = rte_cpu_to_be_16(key);
864 if (key != port->actor.key) {
865 if (!(key & rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)))
866 set_warning_flags(port, WRN_NOT_LACP_CAPABLE);
867
868 port->actor.key = key;
869 SM_FLAG_SET(port, NTT);
870 }
871
872 if (!rte_is_same_ether_addr(&port->actor.system, &slave_addr)) {
873 rte_ether_addr_copy(&slave_addr, &port->actor.system);
874 if (port->aggregator_port_id == slave_id)
875 SM_FLAG_SET(port, NTT);
876 }
877 }
878
879 for (i = 0; i < internals->active_slave_count; i++) {
880 slave_id = internals->active_slaves[i];
881 port = &bond_mode_8023ad_ports[slave_id];
882
883 if ((port->actor.key &
884 rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY)) == 0) {
885
886 SM_FLAG_SET(port, BEGIN);
887
888 /* LACP is disabled on half duples or link is down */
889 if (SM_FLAG(port, LACP_ENABLED)) {
890 /* If port was enabled set it to BEGIN state */
891 SM_FLAG_CLR(port, LACP_ENABLED);
892 ACTOR_STATE_CLR(port, DISTRIBUTING);
893 ACTOR_STATE_CLR(port, COLLECTING);
894 }
895
896 /* Skip this port processing */
897 continue;
898 }
899
900 SM_FLAG_SET(port, LACP_ENABLED);
901
902 if (internals->mode4.dedicated_queues.enabled == 0) {
903 /* Find LACP packet to this port. Do not check subtype,
904 * it is done in function that queued packet
905 */
906 int retval = rte_ring_dequeue(port->rx_ring,
907 (void **)&lacp_pkt);
908
909 if (retval != 0)
910 lacp_pkt = NULL;
911
912 rx_machine_update(internals, slave_id, lacp_pkt);
913 } else {
914 uint16_t rx_count = rte_eth_rx_burst(slave_id,
915 internals->mode4.dedicated_queues.rx_qid,
916 &lacp_pkt, 1);
917
918 if (rx_count == 1)
919 bond_mode_8023ad_handle_slow_pkt(internals,
920 slave_id, lacp_pkt);
921 else
922 rx_machine_update(internals, slave_id, NULL);
923 }
924
925 periodic_machine(internals, slave_id);
926 mux_machine(internals, slave_id);
927 tx_machine(internals, slave_id);
928 selection_logic(internals, slave_id);
929
930 SM_FLAG_CLR(port, BEGIN);
931 show_warnings(slave_id);
932 }
933
934 rte_eal_alarm_set(internals->mode4.update_timeout_us,
935 bond_mode_8023ad_periodic_cb, arg);
936 }
937
938 static int
bond_mode_8023ad_register_lacp_mac(uint16_t slave_id)939 bond_mode_8023ad_register_lacp_mac(uint16_t slave_id)
940 {
941 int ret;
942
943 ret = rte_eth_allmulticast_enable(slave_id);
944 if (ret != 0) {
945 RTE_BOND_LOG(ERR,
946 "failed to enable allmulti mode for port %u: %s",
947 slave_id, rte_strerror(-ret));
948 }
949 if (rte_eth_allmulticast_get(slave_id)) {
950 RTE_BOND_LOG(DEBUG, "forced allmulti for port %u",
951 slave_id);
952 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
953 BOND_8023AD_FORCED_ALLMULTI;
954 return 0;
955 }
956
957 ret = rte_eth_promiscuous_enable(slave_id);
958 if (ret != 0) {
959 RTE_BOND_LOG(ERR,
960 "failed to enable promiscuous mode for port %u: %s",
961 slave_id, rte_strerror(-ret));
962 }
963 if (rte_eth_promiscuous_get(slave_id)) {
964 RTE_BOND_LOG(DEBUG, "forced promiscuous for port %u",
965 slave_id);
966 bond_mode_8023ad_ports[slave_id].forced_rx_flags =
967 BOND_8023AD_FORCED_PROMISC;
968 return 0;
969 }
970
971 return -1;
972 }
973
974 static void
bond_mode_8023ad_unregister_lacp_mac(uint16_t slave_id)975 bond_mode_8023ad_unregister_lacp_mac(uint16_t slave_id)
976 {
977 int ret;
978
979 switch (bond_mode_8023ad_ports[slave_id].forced_rx_flags) {
980 case BOND_8023AD_FORCED_ALLMULTI:
981 RTE_BOND_LOG(DEBUG, "unset allmulti for port %u", slave_id);
982 ret = rte_eth_allmulticast_disable(slave_id);
983 if (ret != 0)
984 RTE_BOND_LOG(ERR,
985 "failed to disable allmulti mode for port %u: %s",
986 slave_id, rte_strerror(-ret));
987 break;
988
989 case BOND_8023AD_FORCED_PROMISC:
990 RTE_BOND_LOG(DEBUG, "unset promisc for port %u", slave_id);
991 ret = rte_eth_promiscuous_disable(slave_id);
992 if (ret != 0)
993 RTE_BOND_LOG(ERR,
994 "failed to disable promiscuous mode for port %u: %s",
995 slave_id, rte_strerror(-ret));
996 break;
997
998 default:
999 break;
1000 }
1001 }
1002
1003 void
bond_mode_8023ad_activate_slave(struct rte_eth_dev * bond_dev,uint16_t slave_id)1004 bond_mode_8023ad_activate_slave(struct rte_eth_dev *bond_dev,
1005 uint16_t slave_id)
1006 {
1007 struct bond_dev_private *internals = bond_dev->data->dev_private;
1008
1009 struct port *port = &bond_mode_8023ad_ports[slave_id];
1010 struct port_params initial = {
1011 .system = { { 0 } },
1012 .system_priority = rte_cpu_to_be_16(0xFFFF),
1013 .key = rte_cpu_to_be_16(BOND_LINK_FULL_DUPLEX_KEY),
1014 .port_priority = rte_cpu_to_be_16(0x00FF),
1015 .port_number = 0,
1016 };
1017
1018 char mem_name[RTE_ETH_NAME_MAX_LEN];
1019 int socket_id;
1020 unsigned element_size;
1021 uint32_t total_tx_desc;
1022 struct bond_tx_queue *bd_tx_q;
1023 uint16_t q_id;
1024
1025 /* Given slave mus not be in active list */
1026 RTE_ASSERT(find_slave_by_id(internals->active_slaves,
1027 internals->active_slave_count, slave_id) == internals->active_slave_count);
1028 RTE_SET_USED(internals); /* used only for assert when enabled */
1029
1030 memcpy(&port->actor, &initial, sizeof(struct port_params));
1031 /* Standard requires that port ID must be grater than 0.
1032 * Add 1 do get corresponding port_number */
1033 port->actor.port_number = rte_cpu_to_be_16(slave_id + 1);
1034
1035 memcpy(&port->partner, &initial, sizeof(struct port_params));
1036 memcpy(&port->partner_admin, &initial, sizeof(struct port_params));
1037
1038 /* default states */
1039 port->actor_state = STATE_AGGREGATION | STATE_LACP_ACTIVE | STATE_DEFAULTED;
1040 port->partner_state = STATE_LACP_ACTIVE | STATE_AGGREGATION;
1041 port->sm_flags = SM_FLAGS_BEGIN;
1042
1043 /* use this port as agregator */
1044 port->aggregator_port_id = slave_id;
1045
1046 if (bond_mode_8023ad_register_lacp_mac(slave_id) < 0) {
1047 RTE_BOND_LOG(WARNING, "slave %u is most likely broken and won't receive LACP packets",
1048 slave_id);
1049 }
1050
1051 timer_cancel(&port->warning_timer);
1052
1053 if (port->mbuf_pool != NULL)
1054 return;
1055
1056 RTE_ASSERT(port->rx_ring == NULL);
1057 RTE_ASSERT(port->tx_ring == NULL);
1058
1059 socket_id = rte_eth_dev_socket_id(slave_id);
1060 if (socket_id == -1)
1061 socket_id = rte_socket_id();
1062
1063 element_size = sizeof(struct slow_protocol_frame) +
1064 RTE_PKTMBUF_HEADROOM;
1065
1066 /* The size of the mempool should be at least:
1067 * the sum of the TX descriptors + BOND_MODE_8023AX_SLAVE_TX_PKTS */
1068 total_tx_desc = BOND_MODE_8023AX_SLAVE_TX_PKTS;
1069 for (q_id = 0; q_id < bond_dev->data->nb_tx_queues; q_id++) {
1070 bd_tx_q = (struct bond_tx_queue*)bond_dev->data->tx_queues[q_id];
1071 total_tx_desc += bd_tx_q->nb_tx_desc;
1072 }
1073
1074 snprintf(mem_name, RTE_DIM(mem_name), "slave_port%u_pool", slave_id);
1075 port->mbuf_pool = rte_pktmbuf_pool_create(mem_name, total_tx_desc,
1076 RTE_MEMPOOL_CACHE_MAX_SIZE >= 32 ?
1077 32 : RTE_MEMPOOL_CACHE_MAX_SIZE,
1078 0, element_size, socket_id);
1079
1080 /* Any memory allocation failure in initialization is critical because
1081 * resources can't be free, so reinitialization is impossible. */
1082 if (port->mbuf_pool == NULL) {
1083 rte_panic("Slave %u: Failed to create memory pool '%s': %s\n",
1084 slave_id, mem_name, rte_strerror(rte_errno));
1085 }
1086
1087 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_rx", slave_id);
1088 port->rx_ring = rte_ring_create(mem_name,
1089 rte_align32pow2(BOND_MODE_8023AX_SLAVE_RX_PKTS), socket_id, 0);
1090
1091 if (port->rx_ring == NULL) {
1092 rte_panic("Slave %u: Failed to create rx ring '%s': %s\n", slave_id,
1093 mem_name, rte_strerror(rte_errno));
1094 }
1095
1096 /* TX ring is at least one pkt longer to make room for marker packet. */
1097 snprintf(mem_name, RTE_DIM(mem_name), "slave_%u_tx", slave_id);
1098 port->tx_ring = rte_ring_create(mem_name,
1099 rte_align32pow2(BOND_MODE_8023AX_SLAVE_TX_PKTS + 1), socket_id, 0);
1100
1101 if (port->tx_ring == NULL) {
1102 rte_panic("Slave %u: Failed to create tx ring '%s': %s\n", slave_id,
1103 mem_name, rte_strerror(rte_errno));
1104 }
1105 }
1106
1107 int
bond_mode_8023ad_deactivate_slave(struct rte_eth_dev * bond_dev __rte_unused,uint16_t slave_id)1108 bond_mode_8023ad_deactivate_slave(struct rte_eth_dev *bond_dev __rte_unused,
1109 uint16_t slave_id)
1110 {
1111 void *pkt = NULL;
1112 struct port *port = NULL;
1113 uint8_t old_partner_state;
1114
1115 port = &bond_mode_8023ad_ports[slave_id];
1116
1117 ACTOR_STATE_CLR(port, AGGREGATION);
1118 port->selected = UNSELECTED;
1119
1120 old_partner_state = port->partner_state;
1121 record_default(port);
1122
1123 bond_mode_8023ad_unregister_lacp_mac(slave_id);
1124
1125 /* If partner timeout state changes then disable timer */
1126 if (!((old_partner_state ^ port->partner_state) &
1127 STATE_LACP_SHORT_TIMEOUT))
1128 timer_cancel(&port->current_while_timer);
1129
1130 PARTNER_STATE_CLR(port, AGGREGATION);
1131 ACTOR_STATE_CLR(port, EXPIRED);
1132
1133 /* flush rx/tx rings */
1134 while (rte_ring_dequeue(port->rx_ring, &pkt) == 0)
1135 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1136
1137 while (rte_ring_dequeue(port->tx_ring, &pkt) == 0)
1138 rte_pktmbuf_free((struct rte_mbuf *)pkt);
1139 return 0;
1140 }
1141
1142 void
bond_mode_8023ad_mac_address_update(struct rte_eth_dev * bond_dev)1143 bond_mode_8023ad_mac_address_update(struct rte_eth_dev *bond_dev)
1144 {
1145 struct bond_dev_private *internals = bond_dev->data->dev_private;
1146 struct rte_ether_addr slave_addr;
1147 struct port *slave, *agg_slave;
1148 uint16_t slave_id, i, j;
1149
1150 bond_mode_8023ad_stop(bond_dev);
1151
1152 for (i = 0; i < internals->active_slave_count; i++) {
1153 slave_id = internals->active_slaves[i];
1154 slave = &bond_mode_8023ad_ports[slave_id];
1155 rte_eth_macaddr_get(slave_id, &slave_addr);
1156
1157 if (rte_is_same_ether_addr(&slave_addr, &slave->actor.system))
1158 continue;
1159
1160 rte_ether_addr_copy(&slave_addr, &slave->actor.system);
1161 /* Do nothing if this port is not an aggregator. In other case
1162 * Set NTT flag on every port that use this aggregator. */
1163 if (slave->aggregator_port_id != slave_id)
1164 continue;
1165
1166 for (j = 0; j < internals->active_slave_count; j++) {
1167 agg_slave = &bond_mode_8023ad_ports[internals->active_slaves[j]];
1168 if (agg_slave->aggregator_port_id == slave_id)
1169 SM_FLAG_SET(agg_slave, NTT);
1170 }
1171 }
1172
1173 if (bond_dev->data->dev_started)
1174 bond_mode_8023ad_start(bond_dev);
1175 }
1176
1177 static void
bond_mode_8023ad_conf_get(struct rte_eth_dev * dev,struct rte_eth_bond_8023ad_conf * conf)1178 bond_mode_8023ad_conf_get(struct rte_eth_dev *dev,
1179 struct rte_eth_bond_8023ad_conf *conf)
1180 {
1181 struct bond_dev_private *internals = dev->data->dev_private;
1182 struct mode8023ad_private *mode4 = &internals->mode4;
1183 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1184
1185 conf->fast_periodic_ms = mode4->fast_periodic_timeout / ms_ticks;
1186 conf->slow_periodic_ms = mode4->slow_periodic_timeout / ms_ticks;
1187 conf->short_timeout_ms = mode4->short_timeout / ms_ticks;
1188 conf->long_timeout_ms = mode4->long_timeout / ms_ticks;
1189 conf->aggregate_wait_timeout_ms = mode4->aggregate_wait_timeout / ms_ticks;
1190 conf->tx_period_ms = mode4->tx_period_timeout / ms_ticks;
1191 conf->update_timeout_ms = mode4->update_timeout_us / 1000;
1192 conf->rx_marker_period_ms = mode4->rx_marker_timeout / ms_ticks;
1193 conf->slowrx_cb = mode4->slowrx_cb;
1194 conf->agg_selection = mode4->agg_selection;
1195 }
1196
1197 static void
bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf * conf)1198 bond_mode_8023ad_conf_get_default(struct rte_eth_bond_8023ad_conf *conf)
1199 {
1200 conf->fast_periodic_ms = BOND_8023AD_FAST_PERIODIC_MS;
1201 conf->slow_periodic_ms = BOND_8023AD_SLOW_PERIODIC_MS;
1202 conf->short_timeout_ms = BOND_8023AD_SHORT_TIMEOUT_MS;
1203 conf->long_timeout_ms = BOND_8023AD_LONG_TIMEOUT_MS;
1204 conf->aggregate_wait_timeout_ms = BOND_8023AD_AGGREGATE_WAIT_TIMEOUT_MS;
1205 conf->tx_period_ms = BOND_8023AD_TX_MACHINE_PERIOD_MS;
1206 conf->rx_marker_period_ms = BOND_8023AD_RX_MARKER_PERIOD_MS;
1207 conf->update_timeout_ms = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS;
1208 conf->slowrx_cb = NULL;
1209 conf->agg_selection = AGG_STABLE;
1210 }
1211
1212 static void
bond_mode_8023ad_conf_assign(struct mode8023ad_private * mode4,struct rte_eth_bond_8023ad_conf * conf)1213 bond_mode_8023ad_conf_assign(struct mode8023ad_private *mode4,
1214 struct rte_eth_bond_8023ad_conf *conf)
1215 {
1216 uint64_t ms_ticks = rte_get_tsc_hz() / 1000;
1217
1218 mode4->fast_periodic_timeout = conf->fast_periodic_ms * ms_ticks;
1219 mode4->slow_periodic_timeout = conf->slow_periodic_ms * ms_ticks;
1220 mode4->short_timeout = conf->short_timeout_ms * ms_ticks;
1221 mode4->long_timeout = conf->long_timeout_ms * ms_ticks;
1222 mode4->aggregate_wait_timeout = conf->aggregate_wait_timeout_ms * ms_ticks;
1223 mode4->tx_period_timeout = conf->tx_period_ms * ms_ticks;
1224 mode4->rx_marker_timeout = conf->rx_marker_period_ms * ms_ticks;
1225 mode4->update_timeout_us = conf->update_timeout_ms * 1000;
1226
1227 mode4->dedicated_queues.enabled = 0;
1228 mode4->dedicated_queues.rx_qid = UINT16_MAX;
1229 mode4->dedicated_queues.tx_qid = UINT16_MAX;
1230 }
1231
1232 void
bond_mode_8023ad_setup(struct rte_eth_dev * dev,struct rte_eth_bond_8023ad_conf * conf)1233 bond_mode_8023ad_setup(struct rte_eth_dev *dev,
1234 struct rte_eth_bond_8023ad_conf *conf)
1235 {
1236 struct rte_eth_bond_8023ad_conf def_conf;
1237 struct bond_dev_private *internals = dev->data->dev_private;
1238 struct mode8023ad_private *mode4 = &internals->mode4;
1239
1240 if (conf == NULL) {
1241 conf = &def_conf;
1242 bond_mode_8023ad_conf_get_default(conf);
1243 }
1244
1245 bond_mode_8023ad_stop(dev);
1246 bond_mode_8023ad_conf_assign(mode4, conf);
1247 mode4->slowrx_cb = conf->slowrx_cb;
1248 mode4->agg_selection = AGG_STABLE;
1249
1250 if (dev->data->dev_started)
1251 bond_mode_8023ad_start(dev);
1252 }
1253
1254 int
bond_mode_8023ad_enable(struct rte_eth_dev * bond_dev)1255 bond_mode_8023ad_enable(struct rte_eth_dev *bond_dev)
1256 {
1257 struct bond_dev_private *internals = bond_dev->data->dev_private;
1258 uint16_t i;
1259
1260 for (i = 0; i < internals->active_slave_count; i++)
1261 bond_mode_8023ad_activate_slave(bond_dev,
1262 internals->active_slaves[i]);
1263
1264 return 0;
1265 }
1266
1267 int
bond_mode_8023ad_start(struct rte_eth_dev * bond_dev)1268 bond_mode_8023ad_start(struct rte_eth_dev *bond_dev)
1269 {
1270 struct bond_dev_private *internals = bond_dev->data->dev_private;
1271 struct mode8023ad_private *mode4 = &internals->mode4;
1272 static const uint64_t us = BOND_MODE_8023AX_UPDATE_TIMEOUT_MS * 1000;
1273
1274 rte_eth_macaddr_get(internals->port_id, &mode4->mac_addr);
1275 if (mode4->slowrx_cb)
1276 return rte_eal_alarm_set(us, &bond_mode_8023ad_ext_periodic_cb,
1277 bond_dev);
1278
1279 return rte_eal_alarm_set(us, &bond_mode_8023ad_periodic_cb, bond_dev);
1280 }
1281
1282 void
bond_mode_8023ad_stop(struct rte_eth_dev * bond_dev)1283 bond_mode_8023ad_stop(struct rte_eth_dev *bond_dev)
1284 {
1285 struct bond_dev_private *internals = bond_dev->data->dev_private;
1286 struct mode8023ad_private *mode4 = &internals->mode4;
1287
1288 if (mode4->slowrx_cb) {
1289 rte_eal_alarm_cancel(&bond_mode_8023ad_ext_periodic_cb,
1290 bond_dev);
1291 return;
1292 }
1293 rte_eal_alarm_cancel(&bond_mode_8023ad_periodic_cb, bond_dev);
1294 }
1295
1296 void
bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private * internals,uint16_t slave_id,struct rte_mbuf * pkt)1297 bond_mode_8023ad_handle_slow_pkt(struct bond_dev_private *internals,
1298 uint16_t slave_id, struct rte_mbuf *pkt)
1299 {
1300 struct mode8023ad_private *mode4 = &internals->mode4;
1301 struct port *port = &bond_mode_8023ad_ports[slave_id];
1302 struct marker_header *m_hdr;
1303 uint64_t marker_timer, old_marker_timer;
1304 int retval;
1305 uint8_t wrn, subtype;
1306 /* If packet is a marker, we send response now by reusing given packet
1307 * and update only source MAC, destination MAC is multicast so don't
1308 * update it. Other frames will be handled later by state machines */
1309 subtype = rte_pktmbuf_mtod(pkt,
1310 struct slow_protocol_frame *)->slow_protocol.subtype;
1311
1312 if (subtype == SLOW_SUBTYPE_MARKER) {
1313 m_hdr = rte_pktmbuf_mtod(pkt, struct marker_header *);
1314
1315 if (likely(m_hdr->marker.tlv_type_marker != MARKER_TLV_TYPE_INFO)) {
1316 wrn = WRN_UNKNOWN_MARKER_TYPE;
1317 goto free_out;
1318 }
1319
1320 /* Setup marker timer. Do it in loop in case concurrent access. */
1321 do {
1322 old_marker_timer = port->rx_marker_timer;
1323 if (!timer_is_expired(&old_marker_timer)) {
1324 wrn = WRN_RX_MARKER_TO_FAST;
1325 goto free_out;
1326 }
1327
1328 timer_set(&marker_timer, mode4->rx_marker_timeout);
1329 retval = rte_atomic64_cmpset(&port->rx_marker_timer,
1330 old_marker_timer, marker_timer);
1331 } while (unlikely(retval == 0));
1332
1333 m_hdr->marker.tlv_type_marker = MARKER_TLV_TYPE_RESP;
1334 rte_eth_macaddr_get(slave_id, &m_hdr->eth_hdr.s_addr);
1335
1336 if (internals->mode4.dedicated_queues.enabled == 0) {
1337 int retval = rte_ring_enqueue(port->tx_ring, pkt);
1338 if (retval != 0) {
1339 /* reset timer */
1340 port->rx_marker_timer = 0;
1341 wrn = WRN_TX_QUEUE_FULL;
1342 goto free_out;
1343 }
1344 } else {
1345 /* Send packet directly to the slow queue */
1346 uint16_t tx_count = rte_eth_tx_burst(slave_id,
1347 internals->mode4.dedicated_queues.tx_qid,
1348 &pkt, 1);
1349 if (tx_count != 1) {
1350 /* reset timer */
1351 port->rx_marker_timer = 0;
1352 wrn = WRN_TX_QUEUE_FULL;
1353 goto free_out;
1354 }
1355 }
1356 } else if (likely(subtype == SLOW_SUBTYPE_LACP)) {
1357 if (internals->mode4.dedicated_queues.enabled == 0) {
1358 int retval = rte_ring_enqueue(port->rx_ring, pkt);
1359 if (retval != 0) {
1360 /* If RX fing full free lacpdu message and drop packet */
1361 wrn = WRN_RX_QUEUE_FULL;
1362 goto free_out;
1363 }
1364 } else
1365 rx_machine_update(internals, slave_id, pkt);
1366 } else {
1367 wrn = WRN_UNKNOWN_SLOW_TYPE;
1368 goto free_out;
1369 }
1370
1371 return;
1372
1373 free_out:
1374 set_warning_flags(port, wrn);
1375 rte_pktmbuf_free(pkt);
1376 }
1377
1378 int
rte_eth_bond_8023ad_conf_get(uint16_t port_id,struct rte_eth_bond_8023ad_conf * conf)1379 rte_eth_bond_8023ad_conf_get(uint16_t port_id,
1380 struct rte_eth_bond_8023ad_conf *conf)
1381 {
1382 struct rte_eth_dev *bond_dev;
1383
1384 if (valid_bonded_port_id(port_id) != 0)
1385 return -EINVAL;
1386
1387 if (conf == NULL)
1388 return -EINVAL;
1389
1390 bond_dev = &rte_eth_devices[port_id];
1391 bond_mode_8023ad_conf_get(bond_dev, conf);
1392 return 0;
1393 }
1394
1395 int
rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id,enum rte_bond_8023ad_agg_selection agg_selection)1396 rte_eth_bond_8023ad_agg_selection_set(uint16_t port_id,
1397 enum rte_bond_8023ad_agg_selection agg_selection)
1398 {
1399 struct rte_eth_dev *bond_dev;
1400 struct bond_dev_private *internals;
1401 struct mode8023ad_private *mode4;
1402
1403 if (valid_bonded_port_id(port_id) != 0)
1404 return -EINVAL;
1405
1406 bond_dev = &rte_eth_devices[port_id];
1407 internals = bond_dev->data->dev_private;
1408
1409 if (internals->mode != 4)
1410 return -EINVAL;
1411
1412 mode4 = &internals->mode4;
1413 if (agg_selection == AGG_COUNT || agg_selection == AGG_BANDWIDTH
1414 || agg_selection == AGG_STABLE)
1415 mode4->agg_selection = agg_selection;
1416 return 0;
1417 }
1418
rte_eth_bond_8023ad_agg_selection_get(uint16_t port_id)1419 int rte_eth_bond_8023ad_agg_selection_get(uint16_t port_id)
1420 {
1421 struct rte_eth_dev *bond_dev;
1422 struct bond_dev_private *internals;
1423 struct mode8023ad_private *mode4;
1424
1425 if (valid_bonded_port_id(port_id) != 0)
1426 return -EINVAL;
1427
1428 bond_dev = &rte_eth_devices[port_id];
1429 internals = bond_dev->data->dev_private;
1430
1431 if (internals->mode != 4)
1432 return -EINVAL;
1433 mode4 = &internals->mode4;
1434
1435 return mode4->agg_selection;
1436 }
1437
1438
1439
1440 static int
bond_8023ad_setup_validate(uint16_t port_id,struct rte_eth_bond_8023ad_conf * conf)1441 bond_8023ad_setup_validate(uint16_t port_id,
1442 struct rte_eth_bond_8023ad_conf *conf)
1443 {
1444 if (valid_bonded_port_id(port_id) != 0)
1445 return -EINVAL;
1446
1447 if (conf != NULL) {
1448 /* Basic sanity check */
1449 if (conf->slow_periodic_ms == 0 ||
1450 conf->fast_periodic_ms >= conf->slow_periodic_ms ||
1451 conf->long_timeout_ms == 0 ||
1452 conf->short_timeout_ms >= conf->long_timeout_ms ||
1453 conf->aggregate_wait_timeout_ms == 0 ||
1454 conf->tx_period_ms == 0 ||
1455 conf->rx_marker_period_ms == 0 ||
1456 conf->update_timeout_ms == 0) {
1457 RTE_BOND_LOG(ERR, "given mode 4 configuration is invalid");
1458 return -EINVAL;
1459 }
1460 }
1461
1462 return 0;
1463 }
1464
1465
1466 int
rte_eth_bond_8023ad_setup(uint16_t port_id,struct rte_eth_bond_8023ad_conf * conf)1467 rte_eth_bond_8023ad_setup(uint16_t port_id,
1468 struct rte_eth_bond_8023ad_conf *conf)
1469 {
1470 struct rte_eth_dev *bond_dev;
1471 int err;
1472
1473 err = bond_8023ad_setup_validate(port_id, conf);
1474 if (err != 0)
1475 return err;
1476
1477 bond_dev = &rte_eth_devices[port_id];
1478 bond_mode_8023ad_setup(bond_dev, conf);
1479
1480 return 0;
1481 }
1482
1483
1484
1485
1486
1487 int
rte_eth_bond_8023ad_slave_info(uint16_t port_id,uint16_t slave_id,struct rte_eth_bond_8023ad_slave_info * info)1488 rte_eth_bond_8023ad_slave_info(uint16_t port_id, uint16_t slave_id,
1489 struct rte_eth_bond_8023ad_slave_info *info)
1490 {
1491 struct rte_eth_dev *bond_dev;
1492 struct bond_dev_private *internals;
1493 struct port *port;
1494
1495 if (info == NULL || valid_bonded_port_id(port_id) != 0 ||
1496 rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1497 return -EINVAL;
1498
1499 bond_dev = &rte_eth_devices[port_id];
1500
1501 internals = bond_dev->data->dev_private;
1502 if (find_slave_by_id(internals->active_slaves,
1503 internals->active_slave_count, slave_id) ==
1504 internals->active_slave_count)
1505 return -EINVAL;
1506
1507 port = &bond_mode_8023ad_ports[slave_id];
1508 info->selected = port->selected;
1509
1510 info->actor_state = port->actor_state;
1511 rte_memcpy(&info->actor, &port->actor, sizeof(port->actor));
1512
1513 info->partner_state = port->partner_state;
1514 rte_memcpy(&info->partner, &port->partner, sizeof(port->partner));
1515
1516 info->agg_port_id = port->aggregator_port_id;
1517 return 0;
1518 }
1519
1520 static int
bond_8023ad_ext_validate(uint16_t port_id,uint16_t slave_id)1521 bond_8023ad_ext_validate(uint16_t port_id, uint16_t slave_id)
1522 {
1523 struct rte_eth_dev *bond_dev;
1524 struct bond_dev_private *internals;
1525 struct mode8023ad_private *mode4;
1526
1527 if (rte_eth_bond_mode_get(port_id) != BONDING_MODE_8023AD)
1528 return -EINVAL;
1529
1530 bond_dev = &rte_eth_devices[port_id];
1531
1532 if (!bond_dev->data->dev_started)
1533 return -EINVAL;
1534
1535 internals = bond_dev->data->dev_private;
1536 if (find_slave_by_id(internals->active_slaves,
1537 internals->active_slave_count, slave_id) ==
1538 internals->active_slave_count)
1539 return -EINVAL;
1540
1541 mode4 = &internals->mode4;
1542 if (mode4->slowrx_cb == NULL)
1543 return -EINVAL;
1544
1545 return 0;
1546 }
1547
1548 int
rte_eth_bond_8023ad_ext_collect(uint16_t port_id,uint16_t slave_id,int enabled)1549 rte_eth_bond_8023ad_ext_collect(uint16_t port_id, uint16_t slave_id,
1550 int enabled)
1551 {
1552 struct port *port;
1553 int res;
1554
1555 res = bond_8023ad_ext_validate(port_id, slave_id);
1556 if (res != 0)
1557 return res;
1558
1559 port = &bond_mode_8023ad_ports[slave_id];
1560
1561 if (enabled)
1562 ACTOR_STATE_SET(port, COLLECTING);
1563 else
1564 ACTOR_STATE_CLR(port, COLLECTING);
1565
1566 return 0;
1567 }
1568
1569 int
rte_eth_bond_8023ad_ext_distrib(uint16_t port_id,uint16_t slave_id,int enabled)1570 rte_eth_bond_8023ad_ext_distrib(uint16_t port_id, uint16_t slave_id,
1571 int enabled)
1572 {
1573 struct port *port;
1574 int res;
1575
1576 res = bond_8023ad_ext_validate(port_id, slave_id);
1577 if (res != 0)
1578 return res;
1579
1580 port = &bond_mode_8023ad_ports[slave_id];
1581
1582 if (enabled)
1583 ACTOR_STATE_SET(port, DISTRIBUTING);
1584 else
1585 ACTOR_STATE_CLR(port, DISTRIBUTING);
1586
1587 return 0;
1588 }
1589
1590 int
rte_eth_bond_8023ad_ext_distrib_get(uint16_t port_id,uint16_t slave_id)1591 rte_eth_bond_8023ad_ext_distrib_get(uint16_t port_id, uint16_t slave_id)
1592 {
1593 struct port *port;
1594 int err;
1595
1596 err = bond_8023ad_ext_validate(port_id, slave_id);
1597 if (err != 0)
1598 return err;
1599
1600 port = &bond_mode_8023ad_ports[slave_id];
1601 return ACTOR_STATE(port, DISTRIBUTING);
1602 }
1603
1604 int
rte_eth_bond_8023ad_ext_collect_get(uint16_t port_id,uint16_t slave_id)1605 rte_eth_bond_8023ad_ext_collect_get(uint16_t port_id, uint16_t slave_id)
1606 {
1607 struct port *port;
1608 int err;
1609
1610 err = bond_8023ad_ext_validate(port_id, slave_id);
1611 if (err != 0)
1612 return err;
1613
1614 port = &bond_mode_8023ad_ports[slave_id];
1615 return ACTOR_STATE(port, COLLECTING);
1616 }
1617
1618 int
rte_eth_bond_8023ad_ext_slowtx(uint16_t port_id,uint16_t slave_id,struct rte_mbuf * lacp_pkt)1619 rte_eth_bond_8023ad_ext_slowtx(uint16_t port_id, uint16_t slave_id,
1620 struct rte_mbuf *lacp_pkt)
1621 {
1622 struct port *port;
1623 int res;
1624
1625 res = bond_8023ad_ext_validate(port_id, slave_id);
1626 if (res != 0)
1627 return res;
1628
1629 port = &bond_mode_8023ad_ports[slave_id];
1630
1631 if (rte_pktmbuf_pkt_len(lacp_pkt) < sizeof(struct lacpdu_header))
1632 return -EINVAL;
1633
1634 struct lacpdu_header *lacp;
1635
1636 /* only enqueue LACPDUs */
1637 lacp = rte_pktmbuf_mtod(lacp_pkt, struct lacpdu_header *);
1638 if (lacp->lacpdu.subtype != SLOW_SUBTYPE_LACP)
1639 return -EINVAL;
1640
1641 MODE4_DEBUG("sending LACP frame\n");
1642
1643 return rte_ring_enqueue(port->tx_ring, lacp_pkt);
1644 }
1645
1646 static void
bond_mode_8023ad_ext_periodic_cb(void * arg)1647 bond_mode_8023ad_ext_periodic_cb(void *arg)
1648 {
1649 struct rte_eth_dev *bond_dev = arg;
1650 struct bond_dev_private *internals = bond_dev->data->dev_private;
1651 struct mode8023ad_private *mode4 = &internals->mode4;
1652 struct port *port;
1653 void *pkt = NULL;
1654 uint16_t i, slave_id;
1655
1656 for (i = 0; i < internals->active_slave_count; i++) {
1657 slave_id = internals->active_slaves[i];
1658 port = &bond_mode_8023ad_ports[slave_id];
1659
1660 if (rte_ring_dequeue(port->rx_ring, &pkt) == 0) {
1661 struct rte_mbuf *lacp_pkt = pkt;
1662 struct lacpdu_header *lacp;
1663
1664 lacp = rte_pktmbuf_mtod(lacp_pkt,
1665 struct lacpdu_header *);
1666 RTE_VERIFY(lacp->lacpdu.subtype == SLOW_SUBTYPE_LACP);
1667
1668 /* This is LACP frame so pass it to rx callback.
1669 * Callback is responsible for freeing mbuf.
1670 */
1671 mode4->slowrx_cb(slave_id, lacp_pkt);
1672 }
1673 }
1674
1675 rte_eal_alarm_set(internals->mode4.update_timeout_us,
1676 bond_mode_8023ad_ext_periodic_cb, arg);
1677 }
1678
1679 int
rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)1680 rte_eth_bond_8023ad_dedicated_queues_enable(uint16_t port)
1681 {
1682 int retval = 0;
1683 struct rte_eth_dev *dev;
1684 struct bond_dev_private *internals;
1685
1686 if (valid_bonded_port_id(port) != 0)
1687 return -EINVAL;
1688
1689 dev = &rte_eth_devices[port];
1690 internals = dev->data->dev_private;
1691
1692 if (bond_8023ad_slow_pkt_hw_filter_supported(port) != 0)
1693 return -1;
1694
1695 /* Device must be stopped to set up slow queue */
1696 if (dev->data->dev_started)
1697 return -1;
1698
1699 internals->mode4.dedicated_queues.enabled = 1;
1700
1701 bond_ethdev_mode_set(dev, internals->mode);
1702 return retval;
1703 }
1704
1705 int
rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)1706 rte_eth_bond_8023ad_dedicated_queues_disable(uint16_t port)
1707 {
1708 int retval = 0;
1709 struct rte_eth_dev *dev;
1710 struct bond_dev_private *internals;
1711
1712 if (valid_bonded_port_id(port) != 0)
1713 return -EINVAL;
1714
1715 dev = &rte_eth_devices[port];
1716 internals = dev->data->dev_private;
1717
1718 /* Device must be stopped to set up slow queue */
1719 if (dev->data->dev_started)
1720 return -1;
1721
1722 internals->mode4.dedicated_queues.enabled = 0;
1723
1724 bond_ethdev_mode_set(dev, internals->mode);
1725
1726 return retval;
1727 }
1728