diff --git a/config.ini b/config.ini index 0a5a6bead..e935267a5 100644 --- a/config.ini +++ b/config.ini @@ -36,6 +36,9 @@ idle_sleep=0 # 1-3,4,7 ports 1,2,3,4,7 are enabled port_list=0 +# Number of vdev. +nb_vdev=0 + # Port config section # Correspond to dpdk.port_list's index: port0, port1... [port0] @@ -51,6 +54,22 @@ gateway=192.168.1.1 # Packet capture path, this will hurt performance #pcap=./a.pcap +# Vdev config section +# orrespond to dpdk.nb_vdev's index: vdev0, vdev1... +# iface : Shouldn't set always. +# path : The vuser device path in container. Required. +# queues : The max queues of vuser. Optional, default 1, greater or equal to the number of processes. +# queue_size : Queue size.Optional, default 256. +# mac : The mac address of vuser. Optional, default random, if vhost use phy NIC, it should be set to the phy NIC's mac. +# cq : Optional, if queues = 1, default 0; if queues > 1 default 1. +#[vdev0] +##iface=/usr/local/var/run/openvswitch/vhost-user0 +#path=/var/run/openvswitch/vhost-user0 +#queues=1 +#queue_size=256 +#mac=00:00:00:00:00:01 +#cq=0 + # Kni config: if enabled and method=reject, # all packets that do not belong to the following tcp_port and udp_port # will transmit to kernel; if method=accept, all packets that belong to diff --git a/lib/ff_config.c b/lib/ff_config.c index d9a2f6f68..b3183e659 100644 --- a/lib/ff_config.c +++ b/lib/ff_config.c @@ -402,6 +402,61 @@ port_cfg_handler(struct ff_config *cfg, const char *section, return 1; } +static int +vdev_cfg_handler(struct ff_config *cfg, const char *section, + const char *name, const char *value) { + + if (cfg->dpdk.nb_vdev == 0) { + fprintf(stderr, "vdev_cfg_handler: must config dpdk.nb_vdev first\n"); + return 0; + } + + if (cfg->dpdk.vdev_cfgs == NULL) { + struct ff_vdev_cfg *vc = calloc(RTE_MAX_ETHPORTS, sizeof(struct ff_vdev_cfg)); + if (vc == NULL) { + fprintf(stderr, "vdev_cfg_handler malloc failed\n"); + return 0; + } + cfg->dpdk.vdev_cfgs = vc; + } + + int vdevid; + int ret = sscanf(section, "vdev%d", &vdevid); + if (ret != 1) { + fprintf(stderr, "vdev_cfg_handler section[%s] error\n", section); + return 0; + } + + /* just return true if vdevid >= nb_vdev because it has no effect */ + if (vdevid > cfg->dpdk.nb_vdev) { + fprintf(stderr, "vdev_cfg_handler section[%s] bigger than max vdev id\n", section); + return 1; + } + + struct ff_vdev_cfg *cur = &cfg->dpdk.vdev_cfgs[vdevid]; + if (cur->name == NULL) { + cur->name = strdup(section); + cur->vdev_id = vdevid; + } + + if (strcmp(name, "iface") == 0) { + cur->iface = strdup(value); + } else if (strcmp(name, "path") == 0) { + cur->path = strdup(value); + } else if (strcmp(name, "queues") == 0) { + cur->nb_queues = atoi(value); + } else if (strcmp(name, "queue_size") == 0) { + cur->queue_size = atoi(value); + } else if (strcmp(name, "mac") == 0) { + cur->mac = strdup(value); + } else if (strcmp(name, "cq") == 0) { + cur->nb_cq = atoi(value); + } + + return 1; +} + + static int ini_parse_handler(void* user, const char* section, const char* name, const char* value) @@ -424,6 +479,8 @@ ini_parse_handler(void* user, const char* section, const char* name, pconfig->dpdk.base_virtaddr= strdup(value); } else if (MATCH("dpdk", "port_list")) { return parse_port_list(pconfig, value); + } else if (MATCH("dpdk", "nb_vdev")) { + pconfig->dpdk.nb_vdev = atoi(value); } else if (MATCH("dpdk", "promiscuous")) { pconfig->dpdk.promiscuous = atoi(value); } else if (MATCH("dpdk", "numa_on")) { @@ -456,6 +513,8 @@ ini_parse_handler(void* user, const char* section, const char* name, return freebsd_conf_handler(pconfig, "sysctl", name, value); } else if (strncmp(section, "port", 4) == 0) { return port_cfg_handler(pconfig, section, name, value); + } else if (strncmp(section, "vdev", 4) == 0) { + return vdev_cfg_handler(pconfig, section, name, value); } return 1; @@ -492,8 +551,40 @@ dpdk_args_setup(struct ff_config *cfg) dpdk_argv[n++] = strdup(temp); } + if (cfg->dpdk.nb_vdev) { + for (i=0; idpdk.nb_vdev; i++) { + sprintf(temp, "--vdev=virtio_user%d,path=%s", + cfg->dpdk.vdev_cfgs[i].vdev_id, + cfg->dpdk.vdev_cfgs[i].path); + if (cfg->dpdk.vdev_cfgs[i].nb_queues) { + sprintf(temp, "%s,queues=%u", + temp, cfg->dpdk.vdev_cfgs[i].nb_queues); + } + if (cfg->dpdk.vdev_cfgs[i].nb_cq) { + sprintf(temp, "%s,cq=%u", + temp, cfg->dpdk.vdev_cfgs[i].nb_cq); + } + if (cfg->dpdk.vdev_cfgs[i].queue_size) { + sprintf(temp, "%s,queue_size=%u", + temp, cfg->dpdk.vdev_cfgs[i].queue_size); + } + if (cfg->dpdk.vdev_cfgs[i].mac) { + sprintf(temp, "%s,mac=%s", + temp, cfg->dpdk.vdev_cfgs[i].mac); + } + dpdk_argv[n++] = strdup(temp); + } + sprintf(temp, "--no-pci"); + dpdk_argv[n++] = strdup(temp); + sprintf(temp, "--file-prefix=container"); + dpdk_argv[n++] = strdup(temp); + } + dpdk_argc = n; + for (i=0; i struct ff_port_cfg*) struct ff_port_cfg *port_cfgs; + struct ff_vdev_cfg *vdev_cfgs; } dpdk; struct {