@@ -38,6 +38,7 @@
#include <rte_pci.h>
#include <rte_vhost.h>
#include <rte_version.h>
+#include <rte_eth_bond.h>
#include "dirs.h"
#include "dp-packet.h"
@@ -141,6 +142,7 @@ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
* yet mapped to another queue. */
#define DPDK_ETH_PORT_ID_INVALID RTE_MAX_ETHPORTS
+#define DPDK_BOND_SLAVE_MAX RTE_MAX_ETHPORTS
/* DPDK library uses uint16_t for port_id. */
typedef uint16_t dpdk_port_t;
@@ -333,6 +335,22 @@ enum dpdk_hw_ol_features {
NETDEV_RX_CHECKSUM_OFFLOAD = 1 << 0,
};
+enum dpdk_bond_mode {
+ MODE_ROUND_ROBIN = BONDING_MODE_ROUND_ROBIN,
+ MODE_ACTIVE_BACKUP = BONDING_MODE_ACTIVE_BACKUP,
+ MODE_BALANCE = BONDING_MODE_BALANCE,
+ MODE_BROADCAST = BONDING_MODE_BROADCAST,
+ MODE_8023AD = BONDING_MODE_8023AD,
+ MODE_TLB = BONDING_MODE_TLB,
+ MODE_ALB = BONDING_MODE_ALB
+};
+
+struct netdev_dpdk_bond {
+ char *name;
+ uint8_t mode;
+ dpdk_port_t slaves[DPDK_BOND_SLAVE_MAX];
+};
+
/*
* In order to avoid confusion in variables names, following naming convention
* should be used, if possible:
@@ -399,6 +417,8 @@ struct netdev_dpdk {
OVSRCU_TYPE(struct ingress_policer *) ingress_policer;
uint32_t policer_rate;
uint32_t policer_burst;
+ /* The interface may be a dpdk-bond. */
+ struct netdev_dpdk_bond *bond;
);
PADDED_MEMBERS(CACHE_LINE_SIZE,
@@ -879,6 +899,9 @@ netdev_dpdk_alloc_txq(unsigned int n_txqs)
return txqs;
}
+static void netdev_dpdk_bond_init(struct netdev_dpdk *dev);
+static void netdev_dpdk_bond_uninit(struct netdev_dpdk *dev);
+
static int
common_construct(struct netdev *netdev, dpdk_port_t port_no,
enum dpdk_dev_type type, int socket_id)
@@ -935,6 +958,8 @@ common_construct(struct netdev *netdev, dpdk_port_t port_no,
dev->rte_xstats_ids = NULL;
dev->rte_xstats_ids_size = 0;
+ netdev_dpdk_bond_init(dev);
+
return 0;
}
@@ -1087,6 +1112,7 @@ common_destruct(struct netdev_dpdk *dev)
ovs_list_remove(&dev->list_node);
free(ovsrcu_get_protected(struct ingress_policer *,
&dev->ingress_policer));
+ netdev_dpdk_bond_uninit(dev);
ovs_mutex_destroy(&dev->mutex);
}
@@ -1369,6 +1395,21 @@ netdev_dpdk_get_port_by_mac(const char *mac_str)
return DPDK_ETH_PORT_ID_INVALID;
}
+static void
+netdev_dpdk_bond_init(struct netdev_dpdk *dev)
+{
+ dev->bond = xmalloc(sizeof *dev->bond);
+ dev->bond->name = NULL;
+ dev->bond->mode = MODE_ACTIVE_BACKUP;
+}
+
+static void
+netdev_dpdk_bond_uninit(struct netdev_dpdk *dev)
+{
+ free(dev->bond->name);
+ free(dev->bond);
+}
+
/*
* Normally, a PCI id is enough for identifying a specific DPDK port.
* However, for some NICs having multiple ports sharing the same PCI