1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2017 Intel Corporation
8 #include <rte_malloc.h>
9 #include <rte_ethdev.h>
11 #include <rte_bus_vdev.h>
12 #include <rte_kvargs.h>
14 #include "rte_eth_bond.h"
15 #include "rte_eth_bond_private.h"
16 #include "rte_eth_bond_8023ad_private.h"
19 check_for_bonded_ethdev(const struct rte_eth_dev *eth_dev)
21 /* Check valid pointer */
22 if (eth_dev->device->driver->name == NULL)
25 /* return 0 if driver name matches */
26 return eth_dev->device->driver->name != pmd_bond_drv.driver.name;
30 valid_bonded_port_id(uint16_t port_id)
32 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
33 return check_for_bonded_ethdev(&rte_eth_devices[port_id]);
37 valid_slave_port_id(uint16_t port_id, uint8_t mode)
39 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1);
41 /* Verify that port_id refers to a non bonded port */
42 if (check_for_bonded_ethdev(&rte_eth_devices[port_id]) == 0 &&
43 mode == BONDING_MODE_8023AD) {
44 RTE_BOND_LOG(ERR, "Cannot add slave to bonded device in 802.3ad"
45 " mode as slave is also a bonded device, only "
46 "physical devices can be support in this mode.");
54 activate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id)
56 struct bond_dev_private *internals = eth_dev->data->dev_private;
57 uint8_t active_count = internals->active_slave_count;
59 if (internals->mode == BONDING_MODE_8023AD)
60 bond_mode_8023ad_activate_slave(eth_dev, port_id);
62 if (internals->mode == BONDING_MODE_TLB
63 || internals->mode == BONDING_MODE_ALB) {
65 internals->tlb_slaves_order[active_count] = port_id;
68 RTE_ASSERT(internals->active_slave_count <
69 (RTE_DIM(internals->active_slaves) - 1));
71 internals->active_slaves[internals->active_slave_count] = port_id;
72 internals->active_slave_count++;
74 if (internals->mode == BONDING_MODE_TLB)
75 bond_tlb_activate_slave(internals);
76 if (internals->mode == BONDING_MODE_ALB)
77 bond_mode_alb_client_list_upd(eth_dev);
81 deactivate_slave(struct rte_eth_dev *eth_dev, uint16_t port_id)
84 struct bond_dev_private *internals = eth_dev->data->dev_private;
85 uint16_t active_count = internals->active_slave_count;
87 if (internals->mode == BONDING_MODE_8023AD) {
88 bond_mode_8023ad_stop(eth_dev);
89 bond_mode_8023ad_deactivate_slave(eth_dev, port_id);
90 } else if (internals->mode == BONDING_MODE_TLB
91 || internals->mode == BONDING_MODE_ALB)
92 bond_tlb_disable(internals);
94 slave_pos = find_slave_by_id(internals->active_slaves, active_count,
97 /* If slave was not at the end of the list
98 * shift active slaves up active array list */
99 if (slave_pos < active_count) {
101 memmove(internals->active_slaves + slave_pos,
102 internals->active_slaves + slave_pos + 1,
103 (active_count - slave_pos) *
104 sizeof(internals->active_slaves[0]));
107 RTE_ASSERT(active_count < RTE_DIM(internals->active_slaves));
108 internals->active_slave_count = active_count;
110 if (eth_dev->data->dev_started) {
111 if (internals->mode == BONDING_MODE_8023AD) {
112 bond_mode_8023ad_start(eth_dev);
113 } else if (internals->mode == BONDING_MODE_TLB) {
114 bond_tlb_enable(internals);
115 } else if (internals->mode == BONDING_MODE_ALB) {
116 bond_tlb_enable(internals);
117 bond_mode_alb_client_list_upd(eth_dev);
123 rte_eth_bond_create(const char *name, uint8_t mode, uint8_t socket_id)
125 struct bond_dev_private *internals;
131 RTE_BOND_LOG(ERR, "Invalid name specified");
135 ret = snprintf(devargs, sizeof(devargs),
136 "driver=net_bonding,mode=%d,socket_id=%d", mode, socket_id);
137 if (ret < 0 || ret >= (int)sizeof(devargs))
140 ret = rte_vdev_init(name, devargs);
144 ret = rte_eth_dev_get_port_by_name(name, &port_id);
148 * To make bond_ethdev_configure() happy we need to free the
149 * internals->kvlist here.
151 * Also see comment in bond_ethdev_configure().
153 internals = rte_eth_devices[port_id].data->dev_private;
154 rte_kvargs_free(internals->kvlist);
155 internals->kvlist = NULL;
161 rte_eth_bond_free(const char *name)
163 return rte_vdev_uninit(name);
167 slave_vlan_filter_set(uint16_t bonded_port_id, uint16_t slave_port_id)
169 struct rte_eth_dev *bonded_eth_dev;
170 struct bond_dev_private *internals;
177 bonded_eth_dev = &rte_eth_devices[bonded_port_id];
178 if (bonded_eth_dev->data->dev_conf.rxmode.hw_vlan_filter == 0)
181 internals = bonded_eth_dev->data->dev_private;
182 found = rte_bitmap_scan(internals->vlan_filter_bmp, &pos, &slab);
192 for (i = 0, mask = 1;
193 i < RTE_BITMAP_SLAB_BIT_SIZE;
195 if (unlikely(slab & mask))
196 res = rte_eth_dev_vlan_filter(slave_port_id,
199 found = rte_bitmap_scan(internals->vlan_filter_bmp,
201 } while (found && first != pos && res == 0);
207 __eth_bond_slave_add_lock_free(uint16_t bonded_port_id, uint16_t slave_port_id)
209 struct rte_eth_dev *bonded_eth_dev, *slave_eth_dev;
210 struct bond_dev_private *internals;
211 struct rte_eth_link link_props;
212 struct rte_eth_dev_info dev_info;
214 bonded_eth_dev = &rte_eth_devices[bonded_port_id];
215 internals = bonded_eth_dev->data->dev_private;
217 if (valid_slave_port_id(slave_port_id, internals->mode) != 0)
220 slave_eth_dev = &rte_eth_devices[slave_port_id];
221 if (slave_eth_dev->data->dev_flags & RTE_ETH_DEV_BONDED_SLAVE) {
222 RTE_BOND_LOG(ERR, "Slave device is already a slave of a bonded device");
226 /* Add slave details to bonded device */
227 slave_eth_dev->data->dev_flags |= RTE_ETH_DEV_BONDED_SLAVE;
229 rte_eth_dev_info_get(slave_port_id, &dev_info);
230 if (dev_info.max_rx_pktlen < internals->max_rx_pktlen) {
231 RTE_BOND_LOG(ERR, "Slave (port %u) max_rx_pktlen too small",
236 slave_add(internals, slave_eth_dev);
238 /* We need to store slaves reta_size to be able to synchronize RETA for all
239 * slave devices even if its sizes are different.
241 internals->slaves[internals->slave_count].reta_size = dev_info.reta_size;
243 if (internals->slave_count < 1) {
244 /* if MAC is not user defined then use MAC of first slave add to
246 if (!internals->user_defined_mac)
247 mac_address_set(bonded_eth_dev, slave_eth_dev->data->mac_addrs);
249 /* Inherit eth dev link properties from first slave */
250 link_properties_set(bonded_eth_dev,
251 &(slave_eth_dev->data->dev_link));
253 /* Make primary slave */
254 internals->primary_port = slave_port_id;
255 internals->current_primary_port = slave_port_id;
257 /* Inherit queues settings from first slave */
258 internals->nb_rx_queues = slave_eth_dev->data->nb_rx_queues;
259 internals->nb_tx_queues = slave_eth_dev->data->nb_tx_queues;
261 internals->reta_size = dev_info.reta_size;
263 /* Take the first dev's offload capabilities */
264 internals->rx_offload_capa = dev_info.rx_offload_capa;
265 internals->tx_offload_capa = dev_info.tx_offload_capa;
266 internals->flow_type_rss_offloads = dev_info.flow_type_rss_offloads;
268 /* Inherit first slave's max rx packet size */
269 internals->candidate_max_rx_pktlen = dev_info.max_rx_pktlen;
272 internals->rx_offload_capa &= dev_info.rx_offload_capa;
273 internals->tx_offload_capa &= dev_info.tx_offload_capa;
274 internals->flow_type_rss_offloads &= dev_info.flow_type_rss_offloads;
276 if (link_properties_valid(bonded_eth_dev,
277 &slave_eth_dev->data->dev_link) != 0) {
278 RTE_BOND_LOG(ERR, "Invalid link properties for slave %d"
279 " in bonding mode %d", slave_port_id,
284 /* RETA size is GCD of all slaves RETA sizes, so, if all sizes will be
285 * the power of 2, the lower one is GCD
287 if (internals->reta_size > dev_info.reta_size)
288 internals->reta_size = dev_info.reta_size;
290 if (!internals->max_rx_pktlen &&
291 dev_info.max_rx_pktlen < internals->candidate_max_rx_pktlen)
292 internals->candidate_max_rx_pktlen = dev_info.max_rx_pktlen;
295 bonded_eth_dev->data->dev_conf.rx_adv_conf.rss_conf.rss_hf &=
296 internals->flow_type_rss_offloads;
298 internals->slave_count++;
300 /* Update all slave devices MACs*/
301 mac_address_slaves_update(bonded_eth_dev);
303 if (bonded_eth_dev->data->dev_started) {
304 if (slave_configure(bonded_eth_dev, slave_eth_dev) != 0) {
305 slave_eth_dev->data->dev_flags &= (~RTE_ETH_DEV_BONDED_SLAVE);
306 RTE_BOND_LOG(ERR, "rte_bond_slaves_configure: port=%d",
312 /* Register link status change callback with bonded device pointer as
314 rte_eth_dev_callback_register(slave_port_id, RTE_ETH_EVENT_INTR_LSC,
315 bond_ethdev_lsc_event_callback, &bonded_eth_dev->data->port_id);
317 /* If bonded device is started then we can add the slave to our active
319 if (bonded_eth_dev->data->dev_started) {
320 rte_eth_link_get_nowait(slave_port_id, &link_props);
322 if (link_props.link_status == ETH_LINK_UP) {
323 if (internals->active_slave_count == 0 &&
324 !internals->user_defined_primary_port)
325 bond_ethdev_primary_set(internals,
328 if (find_slave_by_id(internals->active_slaves,
329 internals->active_slave_count,
330 slave_port_id) == internals->active_slave_count)
331 activate_slave(bonded_eth_dev, slave_port_id);
335 slave_vlan_filter_set(bonded_port_id, slave_port_id);
342 rte_eth_bond_slave_add(uint16_t bonded_port_id, uint16_t slave_port_id)
344 struct rte_eth_dev *bonded_eth_dev;
345 struct bond_dev_private *internals;
349 /* Verify that port id's are valid bonded and slave ports */
350 if (valid_bonded_port_id(bonded_port_id) != 0)
353 bonded_eth_dev = &rte_eth_devices[bonded_port_id];
354 internals = bonded_eth_dev->data->dev_private;
356 rte_spinlock_lock(&internals->lock);
358 retval = __eth_bond_slave_add_lock_free(bonded_port_id, slave_port_id);
360 rte_spinlock_unlock(&internals->lock);
366 __eth_bond_slave_remove_lock_free(uint16_t bonded_port_id,
367 uint16_t slave_port_id)
369 struct rte_eth_dev *bonded_eth_dev;
370 struct bond_dev_private *internals;
371 struct rte_eth_dev *slave_eth_dev;
374 bonded_eth_dev = &rte_eth_devices[bonded_port_id];
375 internals = bonded_eth_dev->data->dev_private;
377 if (valid_slave_port_id(slave_port_id, internals->mode) < 0)
380 /* first remove from active slave list */
381 slave_idx = find_slave_by_id(internals->active_slaves,
382 internals->active_slave_count, slave_port_id);
384 if (slave_idx < internals->active_slave_count)
385 deactivate_slave(bonded_eth_dev, slave_port_id);
388 /* now find in slave list */
389 for (i = 0; i < internals->slave_count; i++)
390 if (internals->slaves[i].port_id == slave_port_id) {
396 RTE_BOND_LOG(ERR, "Couldn't find slave in port list, slave count %d",
397 internals->slave_count);
401 /* Un-register link status change callback with bonded device pointer as
403 rte_eth_dev_callback_unregister(slave_port_id, RTE_ETH_EVENT_INTR_LSC,
404 bond_ethdev_lsc_event_callback,
405 &rte_eth_devices[bonded_port_id].data->port_id);
407 /* Restore original MAC address of slave device */
408 mac_address_set(&rte_eth_devices[slave_port_id],
409 &(internals->slaves[slave_idx].persisted_mac_addr));
411 slave_eth_dev = &rte_eth_devices[slave_port_id];
412 slave_remove(internals, slave_eth_dev);
413 slave_eth_dev->data->dev_flags &= (~RTE_ETH_DEV_BONDED_SLAVE);
415 /* first slave in the active list will be the primary by default,
416 * otherwise use first device in list */
417 if (internals->current_primary_port == slave_port_id) {
418 if (internals->active_slave_count > 0)
419 internals->current_primary_port = internals->active_slaves[0];
420 else if (internals->slave_count > 0)
421 internals->current_primary_port = internals->slaves[0].port_id;
423 internals->primary_port = 0;
426 if (internals->active_slave_count < 1) {
427 /* if no slaves are any longer attached to bonded device and MAC is not
428 * user defined then clear MAC of bonded device as it will be reset
429 * when a new slave is added */
430 if (internals->slave_count < 1 && !internals->user_defined_mac)
431 memset(rte_eth_devices[bonded_port_id].data->mac_addrs, 0,
432 sizeof(*(rte_eth_devices[bonded_port_id].data->mac_addrs)));
434 if (internals->slave_count == 0) {
435 internals->rx_offload_capa = 0;
436 internals->tx_offload_capa = 0;
437 internals->flow_type_rss_offloads = ETH_RSS_PROTO_MASK;
438 internals->reta_size = 0;
439 internals->candidate_max_rx_pktlen = 0;
440 internals->max_rx_pktlen = 0;
446 rte_eth_bond_slave_remove(uint16_t bonded_port_id, uint16_t slave_port_id)
448 struct rte_eth_dev *bonded_eth_dev;
449 struct bond_dev_private *internals;
452 if (valid_bonded_port_id(bonded_port_id) != 0)
455 bonded_eth_dev = &rte_eth_devices[bonded_port_id];
456 internals = bonded_eth_dev->data->dev_private;
458 rte_spinlock_lock(&internals->lock);
460 retval = __eth_bond_slave_remove_lock_free(bonded_port_id, slave_port_id);
462 rte_spinlock_unlock(&internals->lock);
468 rte_eth_bond_mode_set(uint16_t bonded_port_id, uint8_t mode)
470 if (valid_bonded_port_id(bonded_port_id) != 0)
473 return bond_ethdev_mode_set(&rte_eth_devices[bonded_port_id], mode);
477 rte_eth_bond_mode_get(uint16_t bonded_port_id)
479 struct bond_dev_private *internals;
481 if (valid_bonded_port_id(bonded_port_id) != 0)
484 internals = rte_eth_devices[bonded_port_id].data->dev_private;
486 return internals->mode;
490 rte_eth_bond_primary_set(uint16_t bonded_port_id, uint16_t slave_port_id)
492 struct bond_dev_private *internals;
494 if (valid_bonded_port_id(bonded_port_id) != 0)
497 internals = rte_eth_devices[bonded_port_id].data->dev_private;
499 if (valid_slave_port_id(slave_port_id, internals->mode) != 0)
502 internals->user_defined_primary_port = 1;
503 internals->primary_port = slave_port_id;
505 bond_ethdev_primary_set(internals, slave_port_id);
511 rte_eth_bond_primary_get(uint16_t bonded_port_id)
513 struct bond_dev_private *internals;
515 if (valid_bonded_port_id(bonded_port_id) != 0)
518 internals = rte_eth_devices[bonded_port_id].data->dev_private;
520 if (internals->slave_count < 1)
523 return internals->current_primary_port;
527 rte_eth_bond_slaves_get(uint16_t bonded_port_id, uint16_t slaves[],
530 struct bond_dev_private *internals;
533 if (valid_bonded_port_id(bonded_port_id) != 0)
539 internals = rte_eth_devices[bonded_port_id].data->dev_private;
541 if (internals->slave_count > len)
544 for (i = 0; i < internals->slave_count; i++)
545 slaves[i] = internals->slaves[i].port_id;
547 return internals->slave_count;
551 rte_eth_bond_active_slaves_get(uint16_t bonded_port_id, uint16_t slaves[],
554 struct bond_dev_private *internals;
556 if (valid_bonded_port_id(bonded_port_id) != 0)
562 internals = rte_eth_devices[bonded_port_id].data->dev_private;
564 if (internals->active_slave_count > len)
567 memcpy(slaves, internals->active_slaves,
568 internals->active_slave_count * sizeof(internals->active_slaves[0]));
570 return internals->active_slave_count;
574 rte_eth_bond_mac_address_set(uint16_t bonded_port_id,
575 struct ether_addr *mac_addr)
577 struct rte_eth_dev *bonded_eth_dev;
578 struct bond_dev_private *internals;
580 if (valid_bonded_port_id(bonded_port_id) != 0)
583 bonded_eth_dev = &rte_eth_devices[bonded_port_id];
584 internals = bonded_eth_dev->data->dev_private;
586 /* Set MAC Address of Bonded Device */
587 if (mac_address_set(bonded_eth_dev, mac_addr))
590 internals->user_defined_mac = 1;
592 /* Update all slave devices MACs*/
593 if (internals->slave_count > 0)
594 return mac_address_slaves_update(bonded_eth_dev);
600 rte_eth_bond_mac_address_reset(uint16_t bonded_port_id)
602 struct rte_eth_dev *bonded_eth_dev;
603 struct bond_dev_private *internals;
605 if (valid_bonded_port_id(bonded_port_id) != 0)
608 bonded_eth_dev = &rte_eth_devices[bonded_port_id];
609 internals = bonded_eth_dev->data->dev_private;
611 internals->user_defined_mac = 0;
613 if (internals->slave_count > 0) {
614 /* Set MAC Address of Bonded Device */
615 if (mac_address_set(bonded_eth_dev,
616 &internals->slaves[internals->primary_port].persisted_mac_addr)
618 RTE_BOND_LOG(ERR, "Failed to set MAC address on bonded device");
621 /* Update all slave devices MAC addresses */
622 return mac_address_slaves_update(bonded_eth_dev);
624 /* No need to update anything as no slaves present */
629 rte_eth_bond_xmit_policy_set(uint16_t bonded_port_id, uint8_t policy)
631 struct bond_dev_private *internals;
633 if (valid_bonded_port_id(bonded_port_id) != 0)
636 internals = rte_eth_devices[bonded_port_id].data->dev_private;
639 case BALANCE_XMIT_POLICY_LAYER2:
640 internals->balance_xmit_policy = policy;
641 internals->xmit_hash = xmit_l2_hash;
643 case BALANCE_XMIT_POLICY_LAYER23:
644 internals->balance_xmit_policy = policy;
645 internals->xmit_hash = xmit_l23_hash;
647 case BALANCE_XMIT_POLICY_LAYER34:
648 internals->balance_xmit_policy = policy;
649 internals->xmit_hash = xmit_l34_hash;
659 rte_eth_bond_xmit_policy_get(uint16_t bonded_port_id)
661 struct bond_dev_private *internals;
663 if (valid_bonded_port_id(bonded_port_id) != 0)
666 internals = rte_eth_devices[bonded_port_id].data->dev_private;
668 return internals->balance_xmit_policy;
672 rte_eth_bond_link_monitoring_set(uint16_t bonded_port_id, uint32_t internal_ms)
674 struct bond_dev_private *internals;
676 if (valid_bonded_port_id(bonded_port_id) != 0)
679 internals = rte_eth_devices[bonded_port_id].data->dev_private;
680 internals->link_status_polling_interval_ms = internal_ms;
686 rte_eth_bond_link_monitoring_get(uint16_t bonded_port_id)
688 struct bond_dev_private *internals;
690 if (valid_bonded_port_id(bonded_port_id) != 0)
693 internals = rte_eth_devices[bonded_port_id].data->dev_private;
695 return internals->link_status_polling_interval_ms;
699 rte_eth_bond_link_down_prop_delay_set(uint16_t bonded_port_id,
703 struct bond_dev_private *internals;
705 if (valid_bonded_port_id(bonded_port_id) != 0)
708 internals = rte_eth_devices[bonded_port_id].data->dev_private;
709 internals->link_down_delay_ms = delay_ms;
715 rte_eth_bond_link_down_prop_delay_get(uint16_t bonded_port_id)
717 struct bond_dev_private *internals;
719 if (valid_bonded_port_id(bonded_port_id) != 0)
722 internals = rte_eth_devices[bonded_port_id].data->dev_private;
724 return internals->link_down_delay_ms;
728 rte_eth_bond_link_up_prop_delay_set(uint16_t bonded_port_id, uint32_t delay_ms)
731 struct bond_dev_private *internals;
733 if (valid_bonded_port_id(bonded_port_id) != 0)
736 internals = rte_eth_devices[bonded_port_id].data->dev_private;
737 internals->link_up_delay_ms = delay_ms;
743 rte_eth_bond_link_up_prop_delay_get(uint16_t bonded_port_id)
745 struct bond_dev_private *internals;
747 if (valid_bonded_port_id(bonded_port_id) != 0)
750 internals = rte_eth_devices[bonded_port_id].data->dev_private;
752 return internals->link_up_delay_ms;