1c7c78055SVincenzo Maffione /*
2c7c78055SVincenzo Maffione * Copyright (C) 2013-2014 Michio Honda. All rights reserved.
3c7c78055SVincenzo Maffione *
4c7c78055SVincenzo Maffione * Redistribution and use in source and binary forms, with or without
5c7c78055SVincenzo Maffione * modification, are permitted provided that the following conditions
6c7c78055SVincenzo Maffione * are met:
7c7c78055SVincenzo Maffione * 1. Redistributions of source code must retain the above copyright
8c7c78055SVincenzo Maffione * notice, this list of conditions and the following disclaimer.
9c7c78055SVincenzo Maffione * 2. Redistributions in binary form must reproduce the above copyright
10c7c78055SVincenzo Maffione * notice, this list of conditions and the following disclaimer in the
11c7c78055SVincenzo Maffione * documentation and/or other materials provided with the distribution.
12c7c78055SVincenzo Maffione *
13c7c78055SVincenzo Maffione * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14c7c78055SVincenzo Maffione * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15c7c78055SVincenzo Maffione * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16c7c78055SVincenzo Maffione * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17c7c78055SVincenzo Maffione * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18c7c78055SVincenzo Maffione * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19c7c78055SVincenzo Maffione * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20c7c78055SVincenzo Maffione * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21c7c78055SVincenzo Maffione * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22c7c78055SVincenzo Maffione * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23c7c78055SVincenzo Maffione * SUCH DAMAGE.
24c7c78055SVincenzo Maffione */
25c7c78055SVincenzo Maffione
26c7c78055SVincenzo Maffione
279fd3f663SVincenzo Maffione #define LIBNETMAP_NOTHREADSAFE
289fd3f663SVincenzo Maffione #include <libnetmap.h>
29c7c78055SVincenzo Maffione
30c7c78055SVincenzo Maffione #include <errno.h>
31c7c78055SVincenzo Maffione #include <stdio.h>
32c7c78055SVincenzo Maffione #include <inttypes.h> /* PRI* macros */
33c7c78055SVincenzo Maffione #include <string.h> /* strcmp */
34c7c78055SVincenzo Maffione #include <fcntl.h> /* open */
35c7c78055SVincenzo Maffione #include <unistd.h> /* close */
36c7c78055SVincenzo Maffione #include <sys/ioctl.h> /* ioctl */
37c7c78055SVincenzo Maffione #include <sys/param.h>
38c7c78055SVincenzo Maffione #include <sys/socket.h> /* apple needs sockaddr */
39c7c78055SVincenzo Maffione #include <net/if.h> /* ifreq */
40c7c78055SVincenzo Maffione #include <libgen.h> /* basename */
41c7c78055SVincenzo Maffione #include <stdlib.h> /* atoi, free */
42c7c78055SVincenzo Maffione
439fd3f663SVincenzo Maffione int verbose;
449fd3f663SVincenzo Maffione
459fd3f663SVincenzo Maffione struct args {
469fd3f663SVincenzo Maffione const char *name;
479fd3f663SVincenzo Maffione const char *config;
489fd3f663SVincenzo Maffione const char *mem_id;
499fd3f663SVincenzo Maffione
509fd3f663SVincenzo Maffione uint16_t nr_reqtype;
519fd3f663SVincenzo Maffione uint32_t nr_mode;
529fd3f663SVincenzo Maffione };
539fd3f663SVincenzo Maffione
54c7c78055SVincenzo Maffione static void
dump_port_info(struct nmreq_port_info_get * v)559fd3f663SVincenzo Maffione dump_port_info(struct nmreq_port_info_get *v)
569fd3f663SVincenzo Maffione {
579fd3f663SVincenzo Maffione printf("memsize: %"PRIu64"\n", v->nr_memsize);
589fd3f663SVincenzo Maffione printf("tx_slots: %"PRIu32"\n", v->nr_tx_slots);
599fd3f663SVincenzo Maffione printf("rx_slots: %"PRIu32"\n", v->nr_rx_slots);
609fd3f663SVincenzo Maffione printf("tx_rings: %"PRIu16"\n", v->nr_tx_rings);
619fd3f663SVincenzo Maffione printf("rx_rings %"PRIu16"\n", v->nr_rx_rings);
629fd3f663SVincenzo Maffione printf("mem_id: %"PRIu16"\n", v->nr_mem_id);
639fd3f663SVincenzo Maffione }
649fd3f663SVincenzo Maffione
659fd3f663SVincenzo Maffione static void
dump_newif(struct nmreq_vale_newif * v)669fd3f663SVincenzo Maffione dump_newif(struct nmreq_vale_newif *v)
679fd3f663SVincenzo Maffione {
689fd3f663SVincenzo Maffione printf("tx_slots: %"PRIu32"\n", v->nr_tx_slots);
699fd3f663SVincenzo Maffione printf("rx_slots: %"PRIu32"\n", v->nr_rx_slots);
709fd3f663SVincenzo Maffione printf("tx_rings: %"PRIu16"\n", v->nr_tx_rings);
719fd3f663SVincenzo Maffione printf("rx_ring: %"PRIu16"\n", v->nr_rx_rings);
729fd3f663SVincenzo Maffione printf("mem_id: %"PRIu16"\n", v->nr_mem_id);
739fd3f663SVincenzo Maffione }
749fd3f663SVincenzo Maffione
759fd3f663SVincenzo Maffione static void
dump_vale_list(struct nmreq_vale_list * v)769fd3f663SVincenzo Maffione dump_vale_list(struct nmreq_vale_list *v)
779fd3f663SVincenzo Maffione {
789fd3f663SVincenzo Maffione printf("bridge_idx: %"PRIu16"\n", v->nr_bridge_idx);
799fd3f663SVincenzo Maffione printf("port_idx: %"PRIu16"\n", v->nr_port_idx);
809fd3f663SVincenzo Maffione }
819fd3f663SVincenzo Maffione
829fd3f663SVincenzo Maffione
839fd3f663SVincenzo Maffione static void
parse_ring_config(const char * conf,uint32_t * nr_tx_slots,uint32_t * nr_rx_slots,uint16_t * nr_tx_rings,uint16_t * nr_rx_rings)849fd3f663SVincenzo Maffione parse_ring_config(const char* conf,
859fd3f663SVincenzo Maffione uint32_t *nr_tx_slots,
869fd3f663SVincenzo Maffione uint32_t *nr_rx_slots,
879fd3f663SVincenzo Maffione uint16_t *nr_tx_rings,
889fd3f663SVincenzo Maffione uint16_t *nr_rx_rings)
89c7c78055SVincenzo Maffione {
90c7c78055SVincenzo Maffione char *w, *tok;
91c7c78055SVincenzo Maffione int i, v;
92c7c78055SVincenzo Maffione
939fd3f663SVincenzo Maffione *nr_tx_rings = *nr_rx_rings = 0;
949fd3f663SVincenzo Maffione *nr_tx_slots = *nr_rx_slots = 0;
95c7c78055SVincenzo Maffione if (conf == NULL || ! *conf)
96c7c78055SVincenzo Maffione return;
97c7c78055SVincenzo Maffione w = strdup(conf);
98c7c78055SVincenzo Maffione for (i = 0, tok = strtok(w, ","); tok; i++, tok = strtok(NULL, ",")) {
99c7c78055SVincenzo Maffione v = atoi(tok);
100c7c78055SVincenzo Maffione switch (i) {
101c7c78055SVincenzo Maffione case 0:
1029fd3f663SVincenzo Maffione *nr_tx_slots = *nr_rx_slots = v;
103c7c78055SVincenzo Maffione break;
104c7c78055SVincenzo Maffione case 1:
1059fd3f663SVincenzo Maffione *nr_rx_slots = v;
106c7c78055SVincenzo Maffione break;
107c7c78055SVincenzo Maffione case 2:
1089fd3f663SVincenzo Maffione *nr_tx_rings = *nr_rx_rings = v;
109c7c78055SVincenzo Maffione break;
110c7c78055SVincenzo Maffione case 3:
1119fd3f663SVincenzo Maffione *nr_rx_rings = v;
112c7c78055SVincenzo Maffione break;
113c7c78055SVincenzo Maffione default:
1149fd3f663SVincenzo Maffione fprintf(stderr, "ignored config: %s", tok);
115c7c78055SVincenzo Maffione break;
116c7c78055SVincenzo Maffione }
117c7c78055SVincenzo Maffione }
1189fd3f663SVincenzo Maffione ND("txr %d txd %d rxr %d rxd %d",
1199fd3f663SVincenzo Maffione *nr_tx_rings, *nr_tx_slots,
1209fd3f663SVincenzo Maffione *nr_rx_rings, *nr_rx_slots);
121c7c78055SVincenzo Maffione free(w);
122c7c78055SVincenzo Maffione }
123c7c78055SVincenzo Maffione
124c7c78055SVincenzo Maffione static int
parse_poll_config(const char * conf,struct nmreq_vale_polling * v)1259fd3f663SVincenzo Maffione parse_poll_config(const char *conf, struct nmreq_vale_polling *v)
126c7c78055SVincenzo Maffione {
1279fd3f663SVincenzo Maffione char *w, *tok;
1289fd3f663SVincenzo Maffione int i, p;
129c7c78055SVincenzo Maffione
1309fd3f663SVincenzo Maffione if (conf == NULL || ! *conf) {
1319fd3f663SVincenzo Maffione fprintf(stderr, "invalid null/empty config\n");
132c7c78055SVincenzo Maffione return -1;
133c7c78055SVincenzo Maffione }
1349fd3f663SVincenzo Maffione w = strdup(conf);
1359fd3f663SVincenzo Maffione for (i = 0, tok = strtok(w, ","); tok; i++, tok = strtok(NULL, ",")) {
1369fd3f663SVincenzo Maffione p = atoi(tok);
1379fd3f663SVincenzo Maffione switch (i) {
1389fd3f663SVincenzo Maffione case 0:
1399fd3f663SVincenzo Maffione v->nr_mode = p ? NETMAP_POLLING_MODE_MULTI_CPU :
1409fd3f663SVincenzo Maffione NETMAP_POLLING_MODE_SINGLE_CPU;
1419fd3f663SVincenzo Maffione break;
1429fd3f663SVincenzo Maffione case 1:
1439fd3f663SVincenzo Maffione v->nr_first_cpu_id = p;
1449fd3f663SVincenzo Maffione break;
1459fd3f663SVincenzo Maffione case 2:
1469fd3f663SVincenzo Maffione if (v->nr_mode != NETMAP_POLLING_MODE_MULTI_CPU) {
1479fd3f663SVincenzo Maffione fprintf(stderr, "too many numbers in '%s'\n", conf);
1489fd3f663SVincenzo Maffione return -1;
149c7c78055SVincenzo Maffione }
1509fd3f663SVincenzo Maffione v->nr_num_polling_cpus = p;
151c7c78055SVincenzo Maffione break;
1529fd3f663SVincenzo Maffione case 3:
1539fd3f663SVincenzo Maffione fprintf(stderr, "too many numbers in '%s'\n", conf);
1549fd3f663SVincenzo Maffione return -1;
155c7c78055SVincenzo Maffione }
1569fd3f663SVincenzo Maffione }
1579fd3f663SVincenzo Maffione free(w);
1589fd3f663SVincenzo Maffione return 0;
159c7c78055SVincenzo Maffione }
160c7c78055SVincenzo Maffione
1619fd3f663SVincenzo Maffione static int32_t
parse_mem_id(const char * mem_id)1629fd3f663SVincenzo Maffione parse_mem_id(const char *mem_id)
1639fd3f663SVincenzo Maffione {
1649fd3f663SVincenzo Maffione int32_t id;
1659fd3f663SVincenzo Maffione
1669fd3f663SVincenzo Maffione if (mem_id == NULL)
1679fd3f663SVincenzo Maffione return 0;
1689fd3f663SVincenzo Maffione if (isdigit(*mem_id))
1699fd3f663SVincenzo Maffione return atoi(mem_id);
1709fd3f663SVincenzo Maffione id = nmreq_get_mem_id(&mem_id, nmctx_get());
1719fd3f663SVincenzo Maffione if (id == 0) {
1729fd3f663SVincenzo Maffione fprintf(stderr, "invalid format in '-m %s' (missing 'netmap:'?)\n", mem_id);
1739fd3f663SVincenzo Maffione return -1;
1749fd3f663SVincenzo Maffione }
1759fd3f663SVincenzo Maffione return id;
176c7c78055SVincenzo Maffione }
177c7c78055SVincenzo Maffione
1789fd3f663SVincenzo Maffione static int
list_all(int fd,struct nmreq_header * hdr)1799fd3f663SVincenzo Maffione list_all(int fd, struct nmreq_header *hdr)
1809fd3f663SVincenzo Maffione {
1819fd3f663SVincenzo Maffione int error;
1829fd3f663SVincenzo Maffione struct nmreq_vale_list *vale_list =
183*69768432SAdrian Chadd (struct nmreq_vale_list *)(uintptr_t)hdr->nr_body;
1849fd3f663SVincenzo Maffione
1859fd3f663SVincenzo Maffione for (;;) {
1869fd3f663SVincenzo Maffione hdr->nr_name[0] = '\0';
1879fd3f663SVincenzo Maffione error = ioctl(fd, NIOCCTRL, hdr);
1889fd3f663SVincenzo Maffione if (error < 0) {
1899fd3f663SVincenzo Maffione if (errno == ENOENT)
190c7c78055SVincenzo Maffione break;
191c7c78055SVincenzo Maffione
1929fd3f663SVincenzo Maffione fprintf(stderr, "failed to list all: %s\n", strerror(errno));
1939fd3f663SVincenzo Maffione return 1;
1949fd3f663SVincenzo Maffione }
1959fd3f663SVincenzo Maffione printf("%s bridge_idx %"PRIu16" port_idx %"PRIu32"\n", hdr->nr_name,
1969fd3f663SVincenzo Maffione vale_list->nr_bridge_idx, vale_list->nr_port_idx);
1979fd3f663SVincenzo Maffione vale_list->nr_port_idx++;
1989fd3f663SVincenzo Maffione }
1999fd3f663SVincenzo Maffione return 1;
2009fd3f663SVincenzo Maffione }
201c7c78055SVincenzo Maffione
2029fd3f663SVincenzo Maffione static int
bdg_ctl(struct args * a)2039fd3f663SVincenzo Maffione bdg_ctl(struct args *a)
2049fd3f663SVincenzo Maffione {
2059fd3f663SVincenzo Maffione struct nmreq_header hdr;
2069fd3f663SVincenzo Maffione struct nmreq_vale_attach vale_attach;
2079fd3f663SVincenzo Maffione struct nmreq_vale_detach vale_detach;
2089fd3f663SVincenzo Maffione struct nmreq_vale_newif vale_newif;
2099fd3f663SVincenzo Maffione struct nmreq_vale_list vale_list;
2109fd3f663SVincenzo Maffione struct nmreq_vale_polling vale_polling;
2119fd3f663SVincenzo Maffione struct nmreq_port_info_get port_info_get;
2129fd3f663SVincenzo Maffione int error = 0;
2139fd3f663SVincenzo Maffione int fd;
2149fd3f663SVincenzo Maffione int32_t mem_id;
2159fd3f663SVincenzo Maffione const char *action = NULL;
2169fd3f663SVincenzo Maffione
2179fd3f663SVincenzo Maffione fd = open("/dev/netmap", O_RDWR);
2189fd3f663SVincenzo Maffione if (fd == -1) {
2199fd3f663SVincenzo Maffione perror("/dev/netmap");
2209fd3f663SVincenzo Maffione return 1;
2219fd3f663SVincenzo Maffione }
2229fd3f663SVincenzo Maffione
2239fd3f663SVincenzo Maffione bzero(&hdr, sizeof(hdr));
2249fd3f663SVincenzo Maffione hdr.nr_version = NETMAP_API;
2259fd3f663SVincenzo Maffione if (a->name != NULL) { /* might be NULL */
2269fd3f663SVincenzo Maffione strncpy(hdr.nr_name, a->name, NETMAP_REQ_IFNAMSIZ - 1);
2279fd3f663SVincenzo Maffione hdr.nr_name[NETMAP_REQ_IFNAMSIZ - 1] = '\0';
2289fd3f663SVincenzo Maffione }
2299fd3f663SVincenzo Maffione hdr.nr_reqtype = a->nr_reqtype;
2309fd3f663SVincenzo Maffione
2319fd3f663SVincenzo Maffione switch (a->nr_reqtype) {
2329fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_DELIF:
2339fd3f663SVincenzo Maffione /* no body */
2349fd3f663SVincenzo Maffione action = "remove";
235c7c78055SVincenzo Maffione break;
236c7c78055SVincenzo Maffione
2379fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_NEWIF:
2389fd3f663SVincenzo Maffione memset(&vale_newif, 0, sizeof(vale_newif));
2399fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_newif;
2409fd3f663SVincenzo Maffione parse_ring_config(a->config,
2419fd3f663SVincenzo Maffione &vale_newif.nr_tx_slots,
2429fd3f663SVincenzo Maffione &vale_newif.nr_rx_slots,
2439fd3f663SVincenzo Maffione &vale_newif.nr_tx_rings,
2449fd3f663SVincenzo Maffione &vale_newif.nr_rx_rings);
2459fd3f663SVincenzo Maffione mem_id = parse_mem_id(a->mem_id);
2469fd3f663SVincenzo Maffione if (mem_id < 0)
2479fd3f663SVincenzo Maffione return 1;
2489fd3f663SVincenzo Maffione vale_newif.nr_mem_id = mem_id;
2499fd3f663SVincenzo Maffione action = "create";
2509fd3f663SVincenzo Maffione break;
2519fd3f663SVincenzo Maffione
2529fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_ATTACH:
2539fd3f663SVincenzo Maffione memset(&vale_attach, 0, sizeof(vale_attach));
2549fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_attach;
2559fd3f663SVincenzo Maffione vale_attach.reg.nr_mode = a->nr_mode;
2569fd3f663SVincenzo Maffione parse_ring_config(a->config,
2579fd3f663SVincenzo Maffione &vale_attach.reg.nr_tx_slots,
2589fd3f663SVincenzo Maffione &vale_attach.reg.nr_rx_slots,
2599fd3f663SVincenzo Maffione &vale_attach.reg.nr_tx_rings,
2609fd3f663SVincenzo Maffione &vale_attach.reg.nr_rx_rings);
2619fd3f663SVincenzo Maffione mem_id = parse_mem_id(a->mem_id);
2629fd3f663SVincenzo Maffione if (mem_id < 0)
2639fd3f663SVincenzo Maffione return 1;
2649fd3f663SVincenzo Maffione vale_attach.reg.nr_mem_id = mem_id;
2659fd3f663SVincenzo Maffione action = "attach";
2669fd3f663SVincenzo Maffione break;
2679fd3f663SVincenzo Maffione
2689fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_DETACH:
2699fd3f663SVincenzo Maffione memset(&vale_detach, 0, sizeof(vale_detach));
2709fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_detach;
2719fd3f663SVincenzo Maffione action = "detach";
2729fd3f663SVincenzo Maffione break;
2739fd3f663SVincenzo Maffione
2749fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_LIST:
2759fd3f663SVincenzo Maffione memset(&vale_list, 0, sizeof(vale_list));
2769fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_list;
2779fd3f663SVincenzo Maffione if (a->name == NULL) {
2789fd3f663SVincenzo Maffione return list_all(fd, &hdr);
2799fd3f663SVincenzo Maffione }
2809fd3f663SVincenzo Maffione action = "list";
2819fd3f663SVincenzo Maffione break;
2829fd3f663SVincenzo Maffione
2839fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_POLLING_ENABLE:
2849fd3f663SVincenzo Maffione action = "enable polling on";
2859fd3f663SVincenzo Maffione /* fall through */
2869fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_POLLING_DISABLE:
2879fd3f663SVincenzo Maffione memset(&vale_polling, 0, sizeof(vale_polling));
2889fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_polling;
2899fd3f663SVincenzo Maffione parse_poll_config(a->config, &vale_polling);
2909fd3f663SVincenzo Maffione if (action == NULL)
2919fd3f663SVincenzo Maffione action ="disable polling on";
2929fd3f663SVincenzo Maffione break;
2939fd3f663SVincenzo Maffione
2949fd3f663SVincenzo Maffione case NETMAP_REQ_PORT_INFO_GET:
2959fd3f663SVincenzo Maffione memset(&port_info_get, 0, sizeof(port_info_get));
2969fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&port_info_get;
2979fd3f663SVincenzo Maffione action = "obtain info for";
2989fd3f663SVincenzo Maffione break;
2999fd3f663SVincenzo Maffione }
3009fd3f663SVincenzo Maffione error = ioctl(fd, NIOCCTRL, &hdr);
3019fd3f663SVincenzo Maffione if (error < 0) {
3029fd3f663SVincenzo Maffione fprintf(stderr, "failed to %s %s: %s\n",
3039fd3f663SVincenzo Maffione action, a->name, strerror(errno));
3049fd3f663SVincenzo Maffione return 1;
3059fd3f663SVincenzo Maffione }
3069fd3f663SVincenzo Maffione switch (hdr.nr_reqtype) {
3079fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_NEWIF:
3089fd3f663SVincenzo Maffione if (verbose) {
3099fd3f663SVincenzo Maffione dump_newif(&vale_newif);
3109fd3f663SVincenzo Maffione }
3119fd3f663SVincenzo Maffione break;
3129fd3f663SVincenzo Maffione
3139fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_ATTACH:
3149fd3f663SVincenzo Maffione if (verbose) {
3159fd3f663SVincenzo Maffione printf("port_index: %"PRIu32"\n", vale_attach.port_index);
3169fd3f663SVincenzo Maffione }
3179fd3f663SVincenzo Maffione break;
3189fd3f663SVincenzo Maffione
3199fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_DETACH:
3209fd3f663SVincenzo Maffione if (verbose) {
3219fd3f663SVincenzo Maffione printf("port_index: %"PRIu32"\n", vale_detach.port_index);
3229fd3f663SVincenzo Maffione }
3239fd3f663SVincenzo Maffione break;
3249fd3f663SVincenzo Maffione
3259fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_LIST:
3269fd3f663SVincenzo Maffione dump_vale_list(&vale_list);
3279fd3f663SVincenzo Maffione break;
3289fd3f663SVincenzo Maffione
3299fd3f663SVincenzo Maffione case NETMAP_REQ_PORT_INFO_GET:
3309fd3f663SVincenzo Maffione dump_port_info(&port_info_get);
331c7c78055SVincenzo Maffione break;
332c7c78055SVincenzo Maffione }
333c7c78055SVincenzo Maffione close(fd);
334c7c78055SVincenzo Maffione return error;
335c7c78055SVincenzo Maffione }
336c7c78055SVincenzo Maffione
337c7c78055SVincenzo Maffione static void
usage(int errcode)338c7c78055SVincenzo Maffione usage(int errcode)
339c7c78055SVincenzo Maffione {
340c7c78055SVincenzo Maffione fprintf(stderr,
341c7c78055SVincenzo Maffione "Usage:\n"
3429fd3f663SVincenzo Maffione "vale-ctl [arguments]\n"
343c7c78055SVincenzo Maffione "\t-g interface interface name to get info\n"
344c7c78055SVincenzo Maffione "\t-d interface interface name to be detached\n"
345c7c78055SVincenzo Maffione "\t-a interface interface name to be attached\n"
346c7c78055SVincenzo Maffione "\t-h interface interface name to be attached with the host stack\n"
347c7c78055SVincenzo Maffione "\t-n interface interface name to be created\n"
348c7c78055SVincenzo Maffione "\t-r interface interface name to be deleted\n"
3499fd3f663SVincenzo Maffione "\t-l vale-port show bridge and port indices\n"
350c7c78055SVincenzo Maffione "\t-C string ring/slot setting of an interface creating by -n\n"
351c7c78055SVincenzo Maffione "\t-p interface start polling. Additional -C x,y,z configures\n"
352c7c78055SVincenzo Maffione "\t\t x: 0 (REG_ALL_NIC) or 1 (REG_ONE_NIC),\n"
353c7c78055SVincenzo Maffione "\t\t y: CPU core id for ALL_NIC and core/ring for ONE_NIC\n"
354c7c78055SVincenzo Maffione "\t\t z: (ONE_NIC only) num of total cores/rings\n"
355c7c78055SVincenzo Maffione "\t-P interface stop polling\n"
3569fd3f663SVincenzo Maffione "\t-m memid to use when creating a new interface\n"
3579fd3f663SVincenzo Maffione "\t-v increase verbosity\n"
3589fd3f663SVincenzo Maffione "with no arguments: list all existing vale ports\n");
359c7c78055SVincenzo Maffione exit(errcode);
360c7c78055SVincenzo Maffione }
361c7c78055SVincenzo Maffione
362c7c78055SVincenzo Maffione int
main(int argc,char * argv[])363c7c78055SVincenzo Maffione main(int argc, char *argv[])
364c7c78055SVincenzo Maffione {
3659fd3f663SVincenzo Maffione int ch;
3669fd3f663SVincenzo Maffione struct args a = {
3679fd3f663SVincenzo Maffione .name = NULL,
3689fd3f663SVincenzo Maffione .config = NULL,
3699fd3f663SVincenzo Maffione .mem_id = NULL,
3709fd3f663SVincenzo Maffione .nr_reqtype = 0,
3719fd3f663SVincenzo Maffione .nr_mode = NR_REG_ALL_NIC,
3729fd3f663SVincenzo Maffione };
373c7c78055SVincenzo Maffione
3749fd3f663SVincenzo Maffione while ((ch = getopt(argc, argv, "d:a:h:g:l:n:r:C:p:P:m:v")) != -1) {
375c7c78055SVincenzo Maffione switch (ch) {
376c7c78055SVincenzo Maffione default:
377c7c78055SVincenzo Maffione fprintf(stderr, "bad option %c %s", ch, optarg);
3789fd3f663SVincenzo Maffione usage(1);
379c7c78055SVincenzo Maffione break;
380c7c78055SVincenzo Maffione case 'd':
3819fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_DETACH;
3829fd3f663SVincenzo Maffione a.name = optarg;
383c7c78055SVincenzo Maffione break;
384c7c78055SVincenzo Maffione case 'a':
3859fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_ATTACH;
3869fd3f663SVincenzo Maffione a.nr_mode = NR_REG_ALL_NIC;
3879fd3f663SVincenzo Maffione a.name = optarg;
388c7c78055SVincenzo Maffione break;
389c7c78055SVincenzo Maffione case 'h':
3909fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_ATTACH;
3919fd3f663SVincenzo Maffione a.nr_mode = NR_REG_NIC_SW;
3929fd3f663SVincenzo Maffione a.name = optarg;
393c7c78055SVincenzo Maffione break;
394c7c78055SVincenzo Maffione case 'n':
3959fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_NEWIF;
3969fd3f663SVincenzo Maffione a.name = optarg;
397c7c78055SVincenzo Maffione break;
398c7c78055SVincenzo Maffione case 'r':
3999fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_DELIF;
4009fd3f663SVincenzo Maffione a.name = optarg;
401c7c78055SVincenzo Maffione break;
402c7c78055SVincenzo Maffione case 'g':
4039fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_PORT_INFO_GET;
4049fd3f663SVincenzo Maffione a.name = optarg;
405c7c78055SVincenzo Maffione break;
406c7c78055SVincenzo Maffione case 'l':
4079fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_LIST;
4089fd3f663SVincenzo Maffione a.name = optarg;
4099fd3f663SVincenzo Maffione if (strncmp(a.name, NM_BDG_NAME, strlen(NM_BDG_NAME))) {
4109fd3f663SVincenzo Maffione fprintf(stderr, "invalid vale port name: '%s'\n", a.name);
4119fd3f663SVincenzo Maffione usage(1);
4129fd3f663SVincenzo Maffione }
413c7c78055SVincenzo Maffione break;
414c7c78055SVincenzo Maffione case 'C':
4159fd3f663SVincenzo Maffione a.config = optarg;
416c7c78055SVincenzo Maffione break;
417c7c78055SVincenzo Maffione case 'p':
4189fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_POLLING_ENABLE;
4199fd3f663SVincenzo Maffione a.name = optarg;
420c7c78055SVincenzo Maffione break;
421c7c78055SVincenzo Maffione case 'P':
4229fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_POLLING_DISABLE;
4239fd3f663SVincenzo Maffione a.name = optarg;
424c7c78055SVincenzo Maffione break;
425c7c78055SVincenzo Maffione case 'm':
4269fd3f663SVincenzo Maffione a.mem_id = optarg;
4279fd3f663SVincenzo Maffione break;
4289fd3f663SVincenzo Maffione case 'v':
4299fd3f663SVincenzo Maffione verbose++;
430c7c78055SVincenzo Maffione break;
431c7c78055SVincenzo Maffione }
432c7c78055SVincenzo Maffione }
433c7c78055SVincenzo Maffione if (optind != argc) {
4349fd3f663SVincenzo Maffione usage(1);
435c7c78055SVincenzo Maffione }
436c7c78055SVincenzo Maffione if (argc == 1) {
4379fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_LIST;
4389fd3f663SVincenzo Maffione a.name = NULL;
439c7c78055SVincenzo Maffione }
4409fd3f663SVincenzo Maffione if (!a.nr_reqtype) {
4419fd3f663SVincenzo Maffione usage(1);
4429fd3f663SVincenzo Maffione }
4439fd3f663SVincenzo Maffione return bdg_ctl(&a);
444c7c78055SVincenzo Maffione }
445