@@ -150,6 +150,8 @@ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
for (int i = 0; i < DPDK_BOND_SLAVE_MAX && \
SLAVES[i] != DPDK_ETH_PORT_ID_INVALID; i++)
+#define DIM(a) (sizeof (a) / sizeof ((a)[0]))
+
/* DPDK library uses uint16_t for port_id. */
typedef uint16_t dpdk_port_t;
#define DPDK_PORT_ID_FMT "%"PRIu16
@@ -348,7 +350,8 @@ enum dpdk_bond_mode {
MODE_BROADCAST = BONDING_MODE_BROADCAST,
MODE_8023AD = BONDING_MODE_8023AD,
MODE_TLB = BONDING_MODE_TLB,
- MODE_ALB = BONDING_MODE_ALB
+ MODE_ALB = BONDING_MODE_ALB,
+ MODE_INVALID,
};
struct netdev_dpdk_bond {
@@ -1536,6 +1539,75 @@ netdev_dpdk_bond_name_key(char *key, dpdk_port_t *rs)
return key;
}
+static uint8_t
+netdev_dpdk_bond_mode_parse(const char *mode)
+{
+ static struct {
+ const char *name;
+ enum dpdk_bond_mode mode;
+ } map[] = {
+ { "round_robin", MODE_ROUND_ROBIN },
+ { "active_backup", MODE_ACTIVE_BACKUP},
+ { "balance", MODE_BALANCE },
+ { "broadcast", MODE_BROADCAST },
+ { "8023ad", MODE_8023AD },
+ { "tlb", MODE_TLB },
+ { "alb", MODE_ALB },
+ };
+
+ for (int i = 0; i < DIM(map); i++) {
+ if(!strcasecmp(mode, map[i].name)) {
+ return map[i].mode;
+ }
+ }
+
+ return MODE_INVALID;
+}
+
+static void
+netdev_dpdk_bond_mode_set(struct netdev_dpdk *dev, const char *mode)
+{
+ uint8_t bond_mode;
+
+ bond_mode = netdev_dpdk_bond_mode_parse(mode);
+ if (bond_mode != MODE_INVALID &&
+ bond_mode == dev->bond->mode) {
+ return;
+ }
+
+ if (bond_mode == MODE_INVALID) {
+ VLOG_WARN_ONCE("The dpdk-bond (%s) mode (%s) is invalid, "
+ "do not change current mode.",
+ dev->up.name,
+ mode);
+ return;
+ }
+
+ if (rte_eth_bond_mode_set(dev->port_id, bond_mode)) {
+ VLOG_WARN_ONCE("Set %s the dpdk-bond mode failed.\n",
+ dev->up.name);
+ return;
+ }
+
+ dev->bond->mode = bond_mode;
+}
+
+static bool
+netdev_dpdk_bond_is_active(struct netdev_dpdk *dev)
+{
+ return dev->bond->name && dev->bond->name[0];
+}
+
+static void
+netdev_dpdk_bond_args_set(struct netdev_dpdk *dev, const struct smap *args)
+{
+ if (!netdev_dpdk_bond_is_active(dev)) {
+ return;
+ }
+
+ netdev_dpdk_bond_mode_set(dev, smap_get(args, "dpdkbond-mode"));
+}
+
/* Try to parse devargs as dpdk-bond device. If success,
* create a bond device and add slave ports to it. And the
* bond devcie id will be set to dev->port_id as a normal
@@ -1732,6 +1804,9 @@ netdev_dpdk_set_config(struct netdev *netdev, const struct smap *args,
}
}
}
+
+ netdev_dpdk_bond_args_set(dev, args);
+
} else {
VLOG_WARN_BUF(errp, "'%s' is missing 'options:dpdk-devargs'. "
"The old 'dpdk<port_id>' names are not supported",