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 /* $FreeBSD$ */ 27c7c78055SVincenzo Maffione 289fd3f663SVincenzo Maffione #define LIBNETMAP_NOTHREADSAFE 299fd3f663SVincenzo Maffione #include <libnetmap.h> 30c7c78055SVincenzo Maffione 31c7c78055SVincenzo Maffione #include <errno.h> 32c7c78055SVincenzo Maffione #include <stdio.h> 33c7c78055SVincenzo Maffione #include <inttypes.h> /* PRI* macros */ 34c7c78055SVincenzo Maffione #include <string.h> /* strcmp */ 35c7c78055SVincenzo Maffione #include <fcntl.h> /* open */ 36c7c78055SVincenzo Maffione #include <unistd.h> /* close */ 37c7c78055SVincenzo Maffione #include <sys/ioctl.h> /* ioctl */ 38c7c78055SVincenzo Maffione #include <sys/param.h> 39c7c78055SVincenzo Maffione #include <sys/socket.h> /* apple needs sockaddr */ 40c7c78055SVincenzo Maffione #include <net/if.h> /* ifreq */ 41c7c78055SVincenzo Maffione #include <libgen.h> /* basename */ 42c7c78055SVincenzo Maffione #include <stdlib.h> /* atoi, free */ 43c7c78055SVincenzo Maffione 449fd3f663SVincenzo Maffione int verbose; 459fd3f663SVincenzo Maffione 469fd3f663SVincenzo Maffione struct args { 479fd3f663SVincenzo Maffione const char *name; 489fd3f663SVincenzo Maffione const char *config; 499fd3f663SVincenzo Maffione const char *mem_id; 509fd3f663SVincenzo Maffione 519fd3f663SVincenzo Maffione uint16_t nr_reqtype; 529fd3f663SVincenzo Maffione uint32_t nr_mode; 539fd3f663SVincenzo Maffione }; 549fd3f663SVincenzo Maffione 55c7c78055SVincenzo Maffione static void 569fd3f663SVincenzo Maffione dump_port_info(struct nmreq_port_info_get *v) 579fd3f663SVincenzo Maffione { 589fd3f663SVincenzo Maffione printf("memsize: %"PRIu64"\n", v->nr_memsize); 599fd3f663SVincenzo Maffione printf("tx_slots: %"PRIu32"\n", v->nr_tx_slots); 609fd3f663SVincenzo Maffione printf("rx_slots: %"PRIu32"\n", v->nr_rx_slots); 619fd3f663SVincenzo Maffione printf("tx_rings: %"PRIu16"\n", v->nr_tx_rings); 629fd3f663SVincenzo Maffione printf("rx_rings %"PRIu16"\n", v->nr_rx_rings); 639fd3f663SVincenzo Maffione printf("mem_id: %"PRIu16"\n", v->nr_mem_id); 649fd3f663SVincenzo Maffione } 659fd3f663SVincenzo Maffione 669fd3f663SVincenzo Maffione static void 679fd3f663SVincenzo Maffione dump_newif(struct nmreq_vale_newif *v) 689fd3f663SVincenzo Maffione { 699fd3f663SVincenzo Maffione printf("tx_slots: %"PRIu32"\n", v->nr_tx_slots); 709fd3f663SVincenzo Maffione printf("rx_slots: %"PRIu32"\n", v->nr_rx_slots); 719fd3f663SVincenzo Maffione printf("tx_rings: %"PRIu16"\n", v->nr_tx_rings); 729fd3f663SVincenzo Maffione printf("rx_ring: %"PRIu16"\n", v->nr_rx_rings); 739fd3f663SVincenzo Maffione printf("mem_id: %"PRIu16"\n", v->nr_mem_id); 749fd3f663SVincenzo Maffione } 759fd3f663SVincenzo Maffione 769fd3f663SVincenzo Maffione static void 779fd3f663SVincenzo Maffione dump_vale_list(struct nmreq_vale_list *v) 789fd3f663SVincenzo Maffione { 799fd3f663SVincenzo Maffione printf("bridge_idx: %"PRIu16"\n", v->nr_bridge_idx); 809fd3f663SVincenzo Maffione printf("port_idx: %"PRIu16"\n", v->nr_port_idx); 819fd3f663SVincenzo Maffione } 829fd3f663SVincenzo Maffione 839fd3f663SVincenzo Maffione 849fd3f663SVincenzo Maffione static void 859fd3f663SVincenzo Maffione parse_ring_config(const char* conf, 869fd3f663SVincenzo Maffione uint32_t *nr_tx_slots, 879fd3f663SVincenzo Maffione uint32_t *nr_rx_slots, 889fd3f663SVincenzo Maffione uint16_t *nr_tx_rings, 899fd3f663SVincenzo Maffione uint16_t *nr_rx_rings) 90c7c78055SVincenzo Maffione { 91c7c78055SVincenzo Maffione char *w, *tok; 92c7c78055SVincenzo Maffione int i, v; 93c7c78055SVincenzo Maffione 949fd3f663SVincenzo Maffione *nr_tx_rings = *nr_rx_rings = 0; 959fd3f663SVincenzo Maffione *nr_tx_slots = *nr_rx_slots = 0; 96c7c78055SVincenzo Maffione if (conf == NULL || ! *conf) 97c7c78055SVincenzo Maffione return; 98c7c78055SVincenzo Maffione w = strdup(conf); 99c7c78055SVincenzo Maffione for (i = 0, tok = strtok(w, ","); tok; i++, tok = strtok(NULL, ",")) { 100c7c78055SVincenzo Maffione v = atoi(tok); 101c7c78055SVincenzo Maffione switch (i) { 102c7c78055SVincenzo Maffione case 0: 1039fd3f663SVincenzo Maffione *nr_tx_slots = *nr_rx_slots = v; 104c7c78055SVincenzo Maffione break; 105c7c78055SVincenzo Maffione case 1: 1069fd3f663SVincenzo Maffione *nr_rx_slots = v; 107c7c78055SVincenzo Maffione break; 108c7c78055SVincenzo Maffione case 2: 1099fd3f663SVincenzo Maffione *nr_tx_rings = *nr_rx_rings = v; 110c7c78055SVincenzo Maffione break; 111c7c78055SVincenzo Maffione case 3: 1129fd3f663SVincenzo Maffione *nr_rx_rings = v; 113c7c78055SVincenzo Maffione break; 114c7c78055SVincenzo Maffione default: 1159fd3f663SVincenzo Maffione fprintf(stderr, "ignored config: %s", tok); 116c7c78055SVincenzo Maffione break; 117c7c78055SVincenzo Maffione } 118c7c78055SVincenzo Maffione } 1199fd3f663SVincenzo Maffione ND("txr %d txd %d rxr %d rxd %d", 1209fd3f663SVincenzo Maffione *nr_tx_rings, *nr_tx_slots, 1219fd3f663SVincenzo Maffione *nr_rx_rings, *nr_rx_slots); 122c7c78055SVincenzo Maffione free(w); 123c7c78055SVincenzo Maffione } 124c7c78055SVincenzo Maffione 125c7c78055SVincenzo Maffione static int 1269fd3f663SVincenzo Maffione parse_poll_config(const char *conf, struct nmreq_vale_polling *v) 127c7c78055SVincenzo Maffione { 1289fd3f663SVincenzo Maffione char *w, *tok; 1299fd3f663SVincenzo Maffione int i, p; 130c7c78055SVincenzo Maffione 1319fd3f663SVincenzo Maffione if (conf == NULL || ! *conf) { 1329fd3f663SVincenzo Maffione fprintf(stderr, "invalid null/empty config\n"); 133c7c78055SVincenzo Maffione return -1; 134c7c78055SVincenzo Maffione } 1359fd3f663SVincenzo Maffione w = strdup(conf); 1369fd3f663SVincenzo Maffione for (i = 0, tok = strtok(w, ","); tok; i++, tok = strtok(NULL, ",")) { 1379fd3f663SVincenzo Maffione p = atoi(tok); 1389fd3f663SVincenzo Maffione switch (i) { 1399fd3f663SVincenzo Maffione case 0: 1409fd3f663SVincenzo Maffione v->nr_mode = p ? NETMAP_POLLING_MODE_MULTI_CPU : 1419fd3f663SVincenzo Maffione NETMAP_POLLING_MODE_SINGLE_CPU; 1429fd3f663SVincenzo Maffione break; 1439fd3f663SVincenzo Maffione case 1: 1449fd3f663SVincenzo Maffione v->nr_first_cpu_id = p; 1459fd3f663SVincenzo Maffione break; 1469fd3f663SVincenzo Maffione case 2: 1479fd3f663SVincenzo Maffione if (v->nr_mode != NETMAP_POLLING_MODE_MULTI_CPU) { 1489fd3f663SVincenzo Maffione fprintf(stderr, "too many numbers in '%s'\n", conf); 1499fd3f663SVincenzo Maffione return -1; 150c7c78055SVincenzo Maffione } 1519fd3f663SVincenzo Maffione v->nr_num_polling_cpus = p; 152c7c78055SVincenzo Maffione break; 1539fd3f663SVincenzo Maffione case 3: 1549fd3f663SVincenzo Maffione fprintf(stderr, "too many numbers in '%s'\n", conf); 1559fd3f663SVincenzo Maffione return -1; 156c7c78055SVincenzo Maffione } 1579fd3f663SVincenzo Maffione } 1589fd3f663SVincenzo Maffione free(w); 1599fd3f663SVincenzo Maffione return 0; 160c7c78055SVincenzo Maffione } 161c7c78055SVincenzo Maffione 1629fd3f663SVincenzo Maffione static int32_t 1639fd3f663SVincenzo Maffione parse_mem_id(const char *mem_id) 1649fd3f663SVincenzo Maffione { 1659fd3f663SVincenzo Maffione int32_t id; 1669fd3f663SVincenzo Maffione 1679fd3f663SVincenzo Maffione if (mem_id == NULL) 1689fd3f663SVincenzo Maffione return 0; 1699fd3f663SVincenzo Maffione if (isdigit(*mem_id)) 1709fd3f663SVincenzo Maffione return atoi(mem_id); 1719fd3f663SVincenzo Maffione id = nmreq_get_mem_id(&mem_id, nmctx_get()); 1729fd3f663SVincenzo Maffione if (id == 0) { 1739fd3f663SVincenzo Maffione fprintf(stderr, "invalid format in '-m %s' (missing 'netmap:'?)\n", mem_id); 1749fd3f663SVincenzo Maffione return -1; 1759fd3f663SVincenzo Maffione } 1769fd3f663SVincenzo Maffione return id; 177c7c78055SVincenzo Maffione } 178c7c78055SVincenzo Maffione 1799fd3f663SVincenzo Maffione static int 1809fd3f663SVincenzo Maffione list_all(int fd, struct nmreq_header *hdr) 1819fd3f663SVincenzo Maffione { 1829fd3f663SVincenzo Maffione int error; 1839fd3f663SVincenzo Maffione struct nmreq_vale_list *vale_list = 184*69768432SAdrian Chadd (struct nmreq_vale_list *)(uintptr_t)hdr->nr_body; 1859fd3f663SVincenzo Maffione 1869fd3f663SVincenzo Maffione for (;;) { 1879fd3f663SVincenzo Maffione hdr->nr_name[0] = '\0'; 1889fd3f663SVincenzo Maffione error = ioctl(fd, NIOCCTRL, hdr); 1899fd3f663SVincenzo Maffione if (error < 0) { 1909fd3f663SVincenzo Maffione if (errno == ENOENT) 191c7c78055SVincenzo Maffione break; 192c7c78055SVincenzo Maffione 1939fd3f663SVincenzo Maffione fprintf(stderr, "failed to list all: %s\n", strerror(errno)); 1949fd3f663SVincenzo Maffione return 1; 1959fd3f663SVincenzo Maffione } 1969fd3f663SVincenzo Maffione printf("%s bridge_idx %"PRIu16" port_idx %"PRIu32"\n", hdr->nr_name, 1979fd3f663SVincenzo Maffione vale_list->nr_bridge_idx, vale_list->nr_port_idx); 1989fd3f663SVincenzo Maffione vale_list->nr_port_idx++; 1999fd3f663SVincenzo Maffione } 2009fd3f663SVincenzo Maffione return 1; 2019fd3f663SVincenzo Maffione } 202c7c78055SVincenzo Maffione 2039fd3f663SVincenzo Maffione static int 2049fd3f663SVincenzo Maffione bdg_ctl(struct args *a) 2059fd3f663SVincenzo Maffione { 2069fd3f663SVincenzo Maffione struct nmreq_header hdr; 2079fd3f663SVincenzo Maffione struct nmreq_vale_attach vale_attach; 2089fd3f663SVincenzo Maffione struct nmreq_vale_detach vale_detach; 2099fd3f663SVincenzo Maffione struct nmreq_vale_newif vale_newif; 2109fd3f663SVincenzo Maffione struct nmreq_vale_list vale_list; 2119fd3f663SVincenzo Maffione struct nmreq_vale_polling vale_polling; 2129fd3f663SVincenzo Maffione struct nmreq_port_info_get port_info_get; 2139fd3f663SVincenzo Maffione int error = 0; 2149fd3f663SVincenzo Maffione int fd; 2159fd3f663SVincenzo Maffione int32_t mem_id; 2169fd3f663SVincenzo Maffione const char *action = NULL; 2179fd3f663SVincenzo Maffione 2189fd3f663SVincenzo Maffione fd = open("/dev/netmap", O_RDWR); 2199fd3f663SVincenzo Maffione if (fd == -1) { 2209fd3f663SVincenzo Maffione perror("/dev/netmap"); 2219fd3f663SVincenzo Maffione return 1; 2229fd3f663SVincenzo Maffione } 2239fd3f663SVincenzo Maffione 2249fd3f663SVincenzo Maffione bzero(&hdr, sizeof(hdr)); 2259fd3f663SVincenzo Maffione hdr.nr_version = NETMAP_API; 2269fd3f663SVincenzo Maffione if (a->name != NULL) { /* might be NULL */ 2279fd3f663SVincenzo Maffione strncpy(hdr.nr_name, a->name, NETMAP_REQ_IFNAMSIZ - 1); 2289fd3f663SVincenzo Maffione hdr.nr_name[NETMAP_REQ_IFNAMSIZ - 1] = '\0'; 2299fd3f663SVincenzo Maffione } 2309fd3f663SVincenzo Maffione hdr.nr_reqtype = a->nr_reqtype; 2319fd3f663SVincenzo Maffione 2329fd3f663SVincenzo Maffione switch (a->nr_reqtype) { 2339fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_DELIF: 2349fd3f663SVincenzo Maffione /* no body */ 2359fd3f663SVincenzo Maffione action = "remove"; 236c7c78055SVincenzo Maffione break; 237c7c78055SVincenzo Maffione 2389fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_NEWIF: 2399fd3f663SVincenzo Maffione memset(&vale_newif, 0, sizeof(vale_newif)); 2409fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_newif; 2419fd3f663SVincenzo Maffione parse_ring_config(a->config, 2429fd3f663SVincenzo Maffione &vale_newif.nr_tx_slots, 2439fd3f663SVincenzo Maffione &vale_newif.nr_rx_slots, 2449fd3f663SVincenzo Maffione &vale_newif.nr_tx_rings, 2459fd3f663SVincenzo Maffione &vale_newif.nr_rx_rings); 2469fd3f663SVincenzo Maffione mem_id = parse_mem_id(a->mem_id); 2479fd3f663SVincenzo Maffione if (mem_id < 0) 2489fd3f663SVincenzo Maffione return 1; 2499fd3f663SVincenzo Maffione vale_newif.nr_mem_id = mem_id; 2509fd3f663SVincenzo Maffione action = "create"; 2519fd3f663SVincenzo Maffione break; 2529fd3f663SVincenzo Maffione 2539fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_ATTACH: 2549fd3f663SVincenzo Maffione memset(&vale_attach, 0, sizeof(vale_attach)); 2559fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_attach; 2569fd3f663SVincenzo Maffione vale_attach.reg.nr_mode = a->nr_mode; 2579fd3f663SVincenzo Maffione parse_ring_config(a->config, 2589fd3f663SVincenzo Maffione &vale_attach.reg.nr_tx_slots, 2599fd3f663SVincenzo Maffione &vale_attach.reg.nr_rx_slots, 2609fd3f663SVincenzo Maffione &vale_attach.reg.nr_tx_rings, 2619fd3f663SVincenzo Maffione &vale_attach.reg.nr_rx_rings); 2629fd3f663SVincenzo Maffione mem_id = parse_mem_id(a->mem_id); 2639fd3f663SVincenzo Maffione if (mem_id < 0) 2649fd3f663SVincenzo Maffione return 1; 2659fd3f663SVincenzo Maffione vale_attach.reg.nr_mem_id = mem_id; 2669fd3f663SVincenzo Maffione action = "attach"; 2679fd3f663SVincenzo Maffione break; 2689fd3f663SVincenzo Maffione 2699fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_DETACH: 2709fd3f663SVincenzo Maffione memset(&vale_detach, 0, sizeof(vale_detach)); 2719fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_detach; 2729fd3f663SVincenzo Maffione action = "detach"; 2739fd3f663SVincenzo Maffione break; 2749fd3f663SVincenzo Maffione 2759fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_LIST: 2769fd3f663SVincenzo Maffione memset(&vale_list, 0, sizeof(vale_list)); 2779fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_list; 2789fd3f663SVincenzo Maffione if (a->name == NULL) { 2799fd3f663SVincenzo Maffione return list_all(fd, &hdr); 2809fd3f663SVincenzo Maffione } 2819fd3f663SVincenzo Maffione action = "list"; 2829fd3f663SVincenzo Maffione break; 2839fd3f663SVincenzo Maffione 2849fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_POLLING_ENABLE: 2859fd3f663SVincenzo Maffione action = "enable polling on"; 2869fd3f663SVincenzo Maffione /* fall through */ 2879fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_POLLING_DISABLE: 2889fd3f663SVincenzo Maffione memset(&vale_polling, 0, sizeof(vale_polling)); 2899fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_polling; 2909fd3f663SVincenzo Maffione parse_poll_config(a->config, &vale_polling); 2919fd3f663SVincenzo Maffione if (action == NULL) 2929fd3f663SVincenzo Maffione action ="disable polling on"; 2939fd3f663SVincenzo Maffione break; 2949fd3f663SVincenzo Maffione 2959fd3f663SVincenzo Maffione case NETMAP_REQ_PORT_INFO_GET: 2969fd3f663SVincenzo Maffione memset(&port_info_get, 0, sizeof(port_info_get)); 2979fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&port_info_get; 2989fd3f663SVincenzo Maffione action = "obtain info for"; 2999fd3f663SVincenzo Maffione break; 3009fd3f663SVincenzo Maffione } 3019fd3f663SVincenzo Maffione error = ioctl(fd, NIOCCTRL, &hdr); 3029fd3f663SVincenzo Maffione if (error < 0) { 3039fd3f663SVincenzo Maffione fprintf(stderr, "failed to %s %s: %s\n", 3049fd3f663SVincenzo Maffione action, a->name, strerror(errno)); 3059fd3f663SVincenzo Maffione return 1; 3069fd3f663SVincenzo Maffione } 3079fd3f663SVincenzo Maffione switch (hdr.nr_reqtype) { 3089fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_NEWIF: 3099fd3f663SVincenzo Maffione if (verbose) { 3109fd3f663SVincenzo Maffione dump_newif(&vale_newif); 3119fd3f663SVincenzo Maffione } 3129fd3f663SVincenzo Maffione break; 3139fd3f663SVincenzo Maffione 3149fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_ATTACH: 3159fd3f663SVincenzo Maffione if (verbose) { 3169fd3f663SVincenzo Maffione printf("port_index: %"PRIu32"\n", vale_attach.port_index); 3179fd3f663SVincenzo Maffione } 3189fd3f663SVincenzo Maffione break; 3199fd3f663SVincenzo Maffione 3209fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_DETACH: 3219fd3f663SVincenzo Maffione if (verbose) { 3229fd3f663SVincenzo Maffione printf("port_index: %"PRIu32"\n", vale_detach.port_index); 3239fd3f663SVincenzo Maffione } 3249fd3f663SVincenzo Maffione break; 3259fd3f663SVincenzo Maffione 3269fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_LIST: 3279fd3f663SVincenzo Maffione dump_vale_list(&vale_list); 3289fd3f663SVincenzo Maffione break; 3299fd3f663SVincenzo Maffione 3309fd3f663SVincenzo Maffione case NETMAP_REQ_PORT_INFO_GET: 3319fd3f663SVincenzo Maffione dump_port_info(&port_info_get); 332c7c78055SVincenzo Maffione break; 333c7c78055SVincenzo Maffione } 334c7c78055SVincenzo Maffione close(fd); 335c7c78055SVincenzo Maffione return error; 336c7c78055SVincenzo Maffione } 337c7c78055SVincenzo Maffione 338c7c78055SVincenzo Maffione static void 339c7c78055SVincenzo Maffione usage(int errcode) 340c7c78055SVincenzo Maffione { 341c7c78055SVincenzo Maffione fprintf(stderr, 342c7c78055SVincenzo Maffione "Usage:\n" 3439fd3f663SVincenzo Maffione "vale-ctl [arguments]\n" 344c7c78055SVincenzo Maffione "\t-g interface interface name to get info\n" 345c7c78055SVincenzo Maffione "\t-d interface interface name to be detached\n" 346c7c78055SVincenzo Maffione "\t-a interface interface name to be attached\n" 347c7c78055SVincenzo Maffione "\t-h interface interface name to be attached with the host stack\n" 348c7c78055SVincenzo Maffione "\t-n interface interface name to be created\n" 349c7c78055SVincenzo Maffione "\t-r interface interface name to be deleted\n" 3509fd3f663SVincenzo Maffione "\t-l vale-port show bridge and port indices\n" 351c7c78055SVincenzo Maffione "\t-C string ring/slot setting of an interface creating by -n\n" 352c7c78055SVincenzo Maffione "\t-p interface start polling. Additional -C x,y,z configures\n" 353c7c78055SVincenzo Maffione "\t\t x: 0 (REG_ALL_NIC) or 1 (REG_ONE_NIC),\n" 354c7c78055SVincenzo Maffione "\t\t y: CPU core id for ALL_NIC and core/ring for ONE_NIC\n" 355c7c78055SVincenzo Maffione "\t\t z: (ONE_NIC only) num of total cores/rings\n" 356c7c78055SVincenzo Maffione "\t-P interface stop polling\n" 3579fd3f663SVincenzo Maffione "\t-m memid to use when creating a new interface\n" 3589fd3f663SVincenzo Maffione "\t-v increase verbosity\n" 3599fd3f663SVincenzo Maffione "with no arguments: list all existing vale ports\n"); 360c7c78055SVincenzo Maffione exit(errcode); 361c7c78055SVincenzo Maffione } 362c7c78055SVincenzo Maffione 363c7c78055SVincenzo Maffione int 364c7c78055SVincenzo Maffione main(int argc, char *argv[]) 365c7c78055SVincenzo Maffione { 3669fd3f663SVincenzo Maffione int ch; 3679fd3f663SVincenzo Maffione struct args a = { 3689fd3f663SVincenzo Maffione .name = NULL, 3699fd3f663SVincenzo Maffione .config = NULL, 3709fd3f663SVincenzo Maffione .mem_id = NULL, 3719fd3f663SVincenzo Maffione .nr_reqtype = 0, 3729fd3f663SVincenzo Maffione .nr_mode = NR_REG_ALL_NIC, 3739fd3f663SVincenzo Maffione }; 374c7c78055SVincenzo Maffione 3759fd3f663SVincenzo Maffione while ((ch = getopt(argc, argv, "d:a:h:g:l:n:r:C:p:P:m:v")) != -1) { 376c7c78055SVincenzo Maffione switch (ch) { 377c7c78055SVincenzo Maffione default: 378c7c78055SVincenzo Maffione fprintf(stderr, "bad option %c %s", ch, optarg); 3799fd3f663SVincenzo Maffione usage(1); 380c7c78055SVincenzo Maffione break; 381c7c78055SVincenzo Maffione case 'd': 3829fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_DETACH; 3839fd3f663SVincenzo Maffione a.name = optarg; 384c7c78055SVincenzo Maffione break; 385c7c78055SVincenzo Maffione case 'a': 3869fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_ATTACH; 3879fd3f663SVincenzo Maffione a.nr_mode = NR_REG_ALL_NIC; 3889fd3f663SVincenzo Maffione a.name = optarg; 389c7c78055SVincenzo Maffione break; 390c7c78055SVincenzo Maffione case 'h': 3919fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_ATTACH; 3929fd3f663SVincenzo Maffione a.nr_mode = NR_REG_NIC_SW; 3939fd3f663SVincenzo Maffione a.name = optarg; 394c7c78055SVincenzo Maffione break; 395c7c78055SVincenzo Maffione case 'n': 3969fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_NEWIF; 3979fd3f663SVincenzo Maffione a.name = optarg; 398c7c78055SVincenzo Maffione break; 399c7c78055SVincenzo Maffione case 'r': 4009fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_DELIF; 4019fd3f663SVincenzo Maffione a.name = optarg; 402c7c78055SVincenzo Maffione break; 403c7c78055SVincenzo Maffione case 'g': 4049fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_PORT_INFO_GET; 4059fd3f663SVincenzo Maffione a.name = optarg; 406c7c78055SVincenzo Maffione break; 407c7c78055SVincenzo Maffione case 'l': 4089fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_LIST; 4099fd3f663SVincenzo Maffione a.name = optarg; 4109fd3f663SVincenzo Maffione if (strncmp(a.name, NM_BDG_NAME, strlen(NM_BDG_NAME))) { 4119fd3f663SVincenzo Maffione fprintf(stderr, "invalid vale port name: '%s'\n", a.name); 4129fd3f663SVincenzo Maffione usage(1); 4139fd3f663SVincenzo Maffione } 414c7c78055SVincenzo Maffione break; 415c7c78055SVincenzo Maffione case 'C': 4169fd3f663SVincenzo Maffione a.config = optarg; 417c7c78055SVincenzo Maffione break; 418c7c78055SVincenzo Maffione case 'p': 4199fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_POLLING_ENABLE; 4209fd3f663SVincenzo Maffione a.name = optarg; 421c7c78055SVincenzo Maffione break; 422c7c78055SVincenzo Maffione case 'P': 4239fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_POLLING_DISABLE; 4249fd3f663SVincenzo Maffione a.name = optarg; 425c7c78055SVincenzo Maffione break; 426c7c78055SVincenzo Maffione case 'm': 4279fd3f663SVincenzo Maffione a.mem_id = optarg; 4289fd3f663SVincenzo Maffione break; 4299fd3f663SVincenzo Maffione case 'v': 4309fd3f663SVincenzo Maffione verbose++; 431c7c78055SVincenzo Maffione break; 432c7c78055SVincenzo Maffione } 433c7c78055SVincenzo Maffione } 434c7c78055SVincenzo Maffione if (optind != argc) { 4359fd3f663SVincenzo Maffione usage(1); 436c7c78055SVincenzo Maffione } 437c7c78055SVincenzo Maffione if (argc == 1) { 4389fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_LIST; 4399fd3f663SVincenzo Maffione a.name = NULL; 440c7c78055SVincenzo Maffione } 4419fd3f663SVincenzo Maffione if (!a.nr_reqtype) { 4429fd3f663SVincenzo Maffione usage(1); 4439fd3f663SVincenzo Maffione } 4449fd3f663SVincenzo Maffione return bdg_ctl(&a); 445c7c78055SVincenzo Maffione } 446