This patch removes restrictions in bonded device library which prevent a bonded device to be added to another bonded device.
There's two limitations to create master bonding: - Total depth of nesting is limited to two levels, - 802.3ad mode is not supported if one or more slaves is a bond device, Signed-off-by: Tomasz Kulasek <tomaszx.kula...@intel.com> --- drivers/net/bonding/rte_eth_bond_api.c | 63 ++++++++++++++++++++++++------ drivers/net/bonding/rte_eth_bond_pmd.c | 6 +++ drivers/net/bonding/rte_eth_bond_private.h | 5 ++- 3 files changed, 60 insertions(+), 14 deletions(-) diff --git a/drivers/net/bonding/rte_eth_bond_api.c b/drivers/net/bonding/rte_eth_bond_api.c index 36ec65d..05f565d 100644 --- a/drivers/net/bonding/rte_eth_bond_api.c +++ b/drivers/net/bonding/rte_eth_bond_api.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2016 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2017 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,13 +63,45 @@ } int -valid_slave_port_id(uint8_t port_id) +check_for_master_bonded_ethdev(const struct rte_eth_dev *eth_dev) { + int i; + struct bond_dev_private *internals; + + if (check_for_bonded_ethdev(eth_dev) != 0) + return 0; + + internals = eth_dev->data->dev_private; + + /* Check if any of slave devices is a bonded device */ + for (i = 0; i < internals->slave_count; i++) + if (valid_bonded_port_id(internals->slaves[i].port_id) == 0) + return 1; + + return 0; +} + +int +valid_slave_port_id(uint8_t port_id, uint8_t mode) { RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -1); /* Verify that port_id refers to a non bonded port */ - if (check_for_bonded_ethdev(&rte_eth_devices[port_id]) == 0) - return -1; + if (check_for_bonded_ethdev(&rte_eth_devices[port_id]) == 0) { + if (mode == BONDING_MODE_8023AD) { + RTE_BOND_LOG(ERR, "One or more slaves is a bond device," + " there 802.3ad mode can not be" + " supported on this bond device."); + return -1; + } + + if (check_for_master_bonded_ethdev(&rte_eth_devices[port_id])) { + RTE_BOND_LOG(ERR, "Too many levels of bonding"); + return -1; + } + + /* Slave is in master bonding */ + return 1; + } return 0; } @@ -250,14 +282,19 @@ struct bond_dev_private *internals; struct rte_eth_link link_props; struct rte_eth_dev_info dev_info; - - if (valid_slave_port_id(slave_port_id) != 0) - return -1; + int status; bonded_eth_dev = &rte_eth_devices[bonded_port_id]; internals = bonded_eth_dev->data->dev_private; + status = valid_slave_port_id(slave_port_id, internals->mode); + + /* Slave is invalid */ + if (status < 0) + return -1; + slave_eth_dev = &rte_eth_devices[slave_port_id]; + if (slave_eth_dev->data->dev_flags & RTE_ETH_DEV_BONDED_SLAVE) { RTE_BOND_LOG(ERR, "Slave device is already a slave of a bonded device"); return -1; @@ -402,12 +439,12 @@ struct rte_eth_dev *slave_eth_dev; int i, slave_idx; - if (valid_slave_port_id(slave_port_id) != 0) - return -1; - bonded_eth_dev = &rte_eth_devices[bonded_port_id]; internals = bonded_eth_dev->data->dev_private; + if (valid_slave_port_id(slave_port_id, internals->mode) < 0) + return -1; + /* first remove from active slave list */ slave_idx = find_slave_by_id(internals->active_slaves, internals->active_slave_count, slave_port_id); @@ -528,11 +565,11 @@ if (valid_bonded_port_id(bonded_port_id) != 0) return -1; - if (valid_slave_port_id(slave_port_id) != 0) - return -1; - internals = rte_eth_devices[bonded_port_id].data->dev_private; + if (valid_slave_port_id(slave_port_id, internals->mode) < 0) + return -1; + internals->user_defined_primary_port = 1; internals->primary_port = slave_port_id; diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c b/drivers/net/bonding/rte_eth_bond_pmd.c index 82959ab..d477f37 100644 --- a/drivers/net/bonding/rte_eth_bond_pmd.c +++ b/drivers/net/bonding/rte_eth_bond_pmd.c @@ -1292,6 +1292,12 @@ struct bwg_slave { eth_dev->rx_pkt_burst = bond_ethdev_rx_burst; break; case BONDING_MODE_8023AD: + if (check_for_master_bonded_ethdev(eth_dev) == 1) { + RTE_BOND_LOG(ERR, "One or more slaves is a bond device," + " there 802.3ad mode can not be" + " supported on this bond device."); + return -1; + } if (bond_mode_8023ad_enable(eth_dev) != 0) return -1; diff --git a/drivers/net/bonding/rte_eth_bond_private.h b/drivers/net/bonding/rte_eth_bond_private.h index c8db090..1a10564 100644 --- a/drivers/net/bonding/rte_eth_bond_private.h +++ b/drivers/net/bonding/rte_eth_bond_private.h @@ -184,6 +184,9 @@ struct bond_dev_private { int check_for_bonded_ethdev(const struct rte_eth_dev *eth_dev); +int +check_for_master_bonded_ethdev(const struct rte_eth_dev *eth_dev); + /* Search given slave array to find possition of given id. * Return slave pos or slaves_count if not found. */ static inline uint8_t @@ -205,7 +208,7 @@ struct bond_dev_private { valid_bonded_port_id(uint8_t port_id); int -valid_slave_port_id(uint8_t port_id); +valid_slave_port_id(uint8_t port_id, uint8_t mode); void deactivate_slave(struct rte_eth_dev *eth_dev, uint8_t port_id); -- 1.9.1