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 28*9fd3f663SVincenzo Maffione #define LIBNETMAP_NOTHREADSAFE 29*9fd3f663SVincenzo 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 44*9fd3f663SVincenzo Maffione int verbose; 45*9fd3f663SVincenzo Maffione 46*9fd3f663SVincenzo Maffione struct args { 47*9fd3f663SVincenzo Maffione const char *name; 48*9fd3f663SVincenzo Maffione const char *config; 49*9fd3f663SVincenzo Maffione const char *mem_id; 50*9fd3f663SVincenzo Maffione 51*9fd3f663SVincenzo Maffione uint16_t nr_reqtype; 52*9fd3f663SVincenzo Maffione uint32_t nr_mode; 53*9fd3f663SVincenzo Maffione }; 54*9fd3f663SVincenzo Maffione 55c7c78055SVincenzo Maffione static void 56*9fd3f663SVincenzo Maffione dump_port_info(struct nmreq_port_info_get *v) 57*9fd3f663SVincenzo Maffione { 58*9fd3f663SVincenzo Maffione printf("memsize: %"PRIu64"\n", v->nr_memsize); 59*9fd3f663SVincenzo Maffione printf("tx_slots: %"PRIu32"\n", v->nr_tx_slots); 60*9fd3f663SVincenzo Maffione printf("rx_slots: %"PRIu32"\n", v->nr_rx_slots); 61*9fd3f663SVincenzo Maffione printf("tx_rings: %"PRIu16"\n", v->nr_tx_rings); 62*9fd3f663SVincenzo Maffione printf("rx_rings %"PRIu16"\n", v->nr_rx_rings); 63*9fd3f663SVincenzo Maffione printf("mem_id: %"PRIu16"\n", v->nr_mem_id); 64*9fd3f663SVincenzo Maffione } 65*9fd3f663SVincenzo Maffione 66*9fd3f663SVincenzo Maffione static void 67*9fd3f663SVincenzo Maffione dump_newif(struct nmreq_vale_newif *v) 68*9fd3f663SVincenzo Maffione { 69*9fd3f663SVincenzo Maffione printf("tx_slots: %"PRIu32"\n", v->nr_tx_slots); 70*9fd3f663SVincenzo Maffione printf("rx_slots: %"PRIu32"\n", v->nr_rx_slots); 71*9fd3f663SVincenzo Maffione printf("tx_rings: %"PRIu16"\n", v->nr_tx_rings); 72*9fd3f663SVincenzo Maffione printf("rx_ring: %"PRIu16"\n", v->nr_rx_rings); 73*9fd3f663SVincenzo Maffione printf("mem_id: %"PRIu16"\n", v->nr_mem_id); 74*9fd3f663SVincenzo Maffione } 75*9fd3f663SVincenzo Maffione 76*9fd3f663SVincenzo Maffione static void 77*9fd3f663SVincenzo Maffione dump_vale_list(struct nmreq_vale_list *v) 78*9fd3f663SVincenzo Maffione { 79*9fd3f663SVincenzo Maffione printf("bridge_idx: %"PRIu16"\n", v->nr_bridge_idx); 80*9fd3f663SVincenzo Maffione printf("port_idx: %"PRIu16"\n", v->nr_port_idx); 81*9fd3f663SVincenzo Maffione } 82*9fd3f663SVincenzo Maffione 83*9fd3f663SVincenzo Maffione 84*9fd3f663SVincenzo Maffione static void 85*9fd3f663SVincenzo Maffione parse_ring_config(const char* conf, 86*9fd3f663SVincenzo Maffione uint32_t *nr_tx_slots, 87*9fd3f663SVincenzo Maffione uint32_t *nr_rx_slots, 88*9fd3f663SVincenzo Maffione uint16_t *nr_tx_rings, 89*9fd3f663SVincenzo Maffione uint16_t *nr_rx_rings) 90c7c78055SVincenzo Maffione { 91c7c78055SVincenzo Maffione char *w, *tok; 92c7c78055SVincenzo Maffione int i, v; 93c7c78055SVincenzo Maffione 94*9fd3f663SVincenzo Maffione *nr_tx_rings = *nr_rx_rings = 0; 95*9fd3f663SVincenzo 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: 103*9fd3f663SVincenzo Maffione *nr_tx_slots = *nr_rx_slots = v; 104c7c78055SVincenzo Maffione break; 105c7c78055SVincenzo Maffione case 1: 106*9fd3f663SVincenzo Maffione *nr_rx_slots = v; 107c7c78055SVincenzo Maffione break; 108c7c78055SVincenzo Maffione case 2: 109*9fd3f663SVincenzo Maffione *nr_tx_rings = *nr_rx_rings = v; 110c7c78055SVincenzo Maffione break; 111c7c78055SVincenzo Maffione case 3: 112*9fd3f663SVincenzo Maffione *nr_rx_rings = v; 113c7c78055SVincenzo Maffione break; 114c7c78055SVincenzo Maffione default: 115*9fd3f663SVincenzo Maffione fprintf(stderr, "ignored config: %s", tok); 116c7c78055SVincenzo Maffione break; 117c7c78055SVincenzo Maffione } 118c7c78055SVincenzo Maffione } 119*9fd3f663SVincenzo Maffione ND("txr %d txd %d rxr %d rxd %d", 120*9fd3f663SVincenzo Maffione *nr_tx_rings, *nr_tx_slots, 121*9fd3f663SVincenzo Maffione *nr_rx_rings, *nr_rx_slots); 122c7c78055SVincenzo Maffione free(w); 123c7c78055SVincenzo Maffione } 124c7c78055SVincenzo Maffione 125c7c78055SVincenzo Maffione static int 126*9fd3f663SVincenzo Maffione parse_poll_config(const char *conf, struct nmreq_vale_polling *v) 127c7c78055SVincenzo Maffione { 128*9fd3f663SVincenzo Maffione char *w, *tok; 129*9fd3f663SVincenzo Maffione int i, p; 130c7c78055SVincenzo Maffione 131*9fd3f663SVincenzo Maffione if (conf == NULL || ! *conf) { 132*9fd3f663SVincenzo Maffione fprintf(stderr, "invalid null/empty config\n"); 133c7c78055SVincenzo Maffione return -1; 134c7c78055SVincenzo Maffione } 135*9fd3f663SVincenzo Maffione w = strdup(conf); 136*9fd3f663SVincenzo Maffione for (i = 0, tok = strtok(w, ","); tok; i++, tok = strtok(NULL, ",")) { 137*9fd3f663SVincenzo Maffione p = atoi(tok); 138*9fd3f663SVincenzo Maffione switch (i) { 139*9fd3f663SVincenzo Maffione case 0: 140*9fd3f663SVincenzo Maffione v->nr_mode = p ? NETMAP_POLLING_MODE_MULTI_CPU : 141*9fd3f663SVincenzo Maffione NETMAP_POLLING_MODE_SINGLE_CPU; 142*9fd3f663SVincenzo Maffione break; 143*9fd3f663SVincenzo Maffione case 1: 144*9fd3f663SVincenzo Maffione v->nr_first_cpu_id = p; 145*9fd3f663SVincenzo Maffione break; 146*9fd3f663SVincenzo Maffione case 2: 147*9fd3f663SVincenzo Maffione if (v->nr_mode != NETMAP_POLLING_MODE_MULTI_CPU) { 148*9fd3f663SVincenzo Maffione fprintf(stderr, "too many numbers in '%s'\n", conf); 149*9fd3f663SVincenzo Maffione return -1; 150c7c78055SVincenzo Maffione } 151*9fd3f663SVincenzo Maffione v->nr_num_polling_cpus = p; 152c7c78055SVincenzo Maffione break; 153*9fd3f663SVincenzo Maffione case 3: 154*9fd3f663SVincenzo Maffione fprintf(stderr, "too many numbers in '%s'\n", conf); 155*9fd3f663SVincenzo Maffione return -1; 156c7c78055SVincenzo Maffione } 157*9fd3f663SVincenzo Maffione } 158*9fd3f663SVincenzo Maffione free(w); 159*9fd3f663SVincenzo Maffione return 0; 160c7c78055SVincenzo Maffione } 161c7c78055SVincenzo Maffione 162*9fd3f663SVincenzo Maffione static int32_t 163*9fd3f663SVincenzo Maffione parse_mem_id(const char *mem_id) 164*9fd3f663SVincenzo Maffione { 165*9fd3f663SVincenzo Maffione int32_t id; 166*9fd3f663SVincenzo Maffione 167*9fd3f663SVincenzo Maffione if (mem_id == NULL) 168*9fd3f663SVincenzo Maffione return 0; 169*9fd3f663SVincenzo Maffione if (isdigit(*mem_id)) 170*9fd3f663SVincenzo Maffione return atoi(mem_id); 171*9fd3f663SVincenzo Maffione id = nmreq_get_mem_id(&mem_id, nmctx_get()); 172*9fd3f663SVincenzo Maffione if (id == 0) { 173*9fd3f663SVincenzo Maffione fprintf(stderr, "invalid format in '-m %s' (missing 'netmap:'?)\n", mem_id); 174*9fd3f663SVincenzo Maffione return -1; 175*9fd3f663SVincenzo Maffione } 176*9fd3f663SVincenzo Maffione return id; 177c7c78055SVincenzo Maffione } 178c7c78055SVincenzo Maffione 179*9fd3f663SVincenzo Maffione static int 180*9fd3f663SVincenzo Maffione list_all(int fd, struct nmreq_header *hdr) 181*9fd3f663SVincenzo Maffione { 182*9fd3f663SVincenzo Maffione int error; 183*9fd3f663SVincenzo Maffione struct nmreq_vale_list *vale_list = 184*9fd3f663SVincenzo Maffione (struct nmreq_vale_list *)hdr->nr_body; 185*9fd3f663SVincenzo Maffione 186*9fd3f663SVincenzo Maffione for (;;) { 187*9fd3f663SVincenzo Maffione hdr->nr_name[0] = '\0'; 188*9fd3f663SVincenzo Maffione error = ioctl(fd, NIOCCTRL, hdr); 189*9fd3f663SVincenzo Maffione if (error < 0) { 190*9fd3f663SVincenzo Maffione if (errno == ENOENT) 191c7c78055SVincenzo Maffione break; 192c7c78055SVincenzo Maffione 193*9fd3f663SVincenzo Maffione fprintf(stderr, "failed to list all: %s\n", strerror(errno)); 194*9fd3f663SVincenzo Maffione return 1; 195*9fd3f663SVincenzo Maffione } 196*9fd3f663SVincenzo Maffione printf("%s bridge_idx %"PRIu16" port_idx %"PRIu32"\n", hdr->nr_name, 197*9fd3f663SVincenzo Maffione vale_list->nr_bridge_idx, vale_list->nr_port_idx); 198*9fd3f663SVincenzo Maffione vale_list->nr_port_idx++; 199*9fd3f663SVincenzo Maffione } 200*9fd3f663SVincenzo Maffione return 1; 201*9fd3f663SVincenzo Maffione } 202c7c78055SVincenzo Maffione 203*9fd3f663SVincenzo Maffione static int 204*9fd3f663SVincenzo Maffione bdg_ctl(struct args *a) 205*9fd3f663SVincenzo Maffione { 206*9fd3f663SVincenzo Maffione struct nmreq_header hdr; 207*9fd3f663SVincenzo Maffione struct nmreq_vale_attach vale_attach; 208*9fd3f663SVincenzo Maffione struct nmreq_vale_detach vale_detach; 209*9fd3f663SVincenzo Maffione struct nmreq_vale_newif vale_newif; 210*9fd3f663SVincenzo Maffione struct nmreq_vale_list vale_list; 211*9fd3f663SVincenzo Maffione struct nmreq_vale_polling vale_polling; 212*9fd3f663SVincenzo Maffione struct nmreq_port_info_get port_info_get; 213*9fd3f663SVincenzo Maffione int error = 0; 214*9fd3f663SVincenzo Maffione int fd; 215*9fd3f663SVincenzo Maffione int32_t mem_id; 216*9fd3f663SVincenzo Maffione const char *action = NULL; 217*9fd3f663SVincenzo Maffione 218*9fd3f663SVincenzo Maffione fd = open("/dev/netmap", O_RDWR); 219*9fd3f663SVincenzo Maffione if (fd == -1) { 220*9fd3f663SVincenzo Maffione perror("/dev/netmap"); 221*9fd3f663SVincenzo Maffione return 1; 222*9fd3f663SVincenzo Maffione } 223*9fd3f663SVincenzo Maffione 224*9fd3f663SVincenzo Maffione bzero(&hdr, sizeof(hdr)); 225*9fd3f663SVincenzo Maffione hdr.nr_version = NETMAP_API; 226*9fd3f663SVincenzo Maffione if (a->name != NULL) { /* might be NULL */ 227*9fd3f663SVincenzo Maffione strncpy(hdr.nr_name, a->name, NETMAP_REQ_IFNAMSIZ - 1); 228*9fd3f663SVincenzo Maffione hdr.nr_name[NETMAP_REQ_IFNAMSIZ - 1] = '\0'; 229*9fd3f663SVincenzo Maffione } 230*9fd3f663SVincenzo Maffione hdr.nr_reqtype = a->nr_reqtype; 231*9fd3f663SVincenzo Maffione 232*9fd3f663SVincenzo Maffione switch (a->nr_reqtype) { 233*9fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_DELIF: 234*9fd3f663SVincenzo Maffione /* no body */ 235*9fd3f663SVincenzo Maffione action = "remove"; 236c7c78055SVincenzo Maffione break; 237c7c78055SVincenzo Maffione 238*9fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_NEWIF: 239*9fd3f663SVincenzo Maffione memset(&vale_newif, 0, sizeof(vale_newif)); 240*9fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_newif; 241*9fd3f663SVincenzo Maffione parse_ring_config(a->config, 242*9fd3f663SVincenzo Maffione &vale_newif.nr_tx_slots, 243*9fd3f663SVincenzo Maffione &vale_newif.nr_rx_slots, 244*9fd3f663SVincenzo Maffione &vale_newif.nr_tx_rings, 245*9fd3f663SVincenzo Maffione &vale_newif.nr_rx_rings); 246*9fd3f663SVincenzo Maffione mem_id = parse_mem_id(a->mem_id); 247*9fd3f663SVincenzo Maffione if (mem_id < 0) 248*9fd3f663SVincenzo Maffione return 1; 249*9fd3f663SVincenzo Maffione vale_newif.nr_mem_id = mem_id; 250*9fd3f663SVincenzo Maffione action = "create"; 251*9fd3f663SVincenzo Maffione break; 252*9fd3f663SVincenzo Maffione 253*9fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_ATTACH: 254*9fd3f663SVincenzo Maffione memset(&vale_attach, 0, sizeof(vale_attach)); 255*9fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_attach; 256*9fd3f663SVincenzo Maffione vale_attach.reg.nr_mode = a->nr_mode; 257*9fd3f663SVincenzo Maffione parse_ring_config(a->config, 258*9fd3f663SVincenzo Maffione &vale_attach.reg.nr_tx_slots, 259*9fd3f663SVincenzo Maffione &vale_attach.reg.nr_rx_slots, 260*9fd3f663SVincenzo Maffione &vale_attach.reg.nr_tx_rings, 261*9fd3f663SVincenzo Maffione &vale_attach.reg.nr_rx_rings); 262*9fd3f663SVincenzo Maffione mem_id = parse_mem_id(a->mem_id); 263*9fd3f663SVincenzo Maffione if (mem_id < 0) 264*9fd3f663SVincenzo Maffione return 1; 265*9fd3f663SVincenzo Maffione vale_attach.reg.nr_mem_id = mem_id; 266*9fd3f663SVincenzo Maffione action = "attach"; 267*9fd3f663SVincenzo Maffione break; 268*9fd3f663SVincenzo Maffione 269*9fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_DETACH: 270*9fd3f663SVincenzo Maffione memset(&vale_detach, 0, sizeof(vale_detach)); 271*9fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_detach; 272*9fd3f663SVincenzo Maffione action = "detach"; 273*9fd3f663SVincenzo Maffione break; 274*9fd3f663SVincenzo Maffione 275*9fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_LIST: 276*9fd3f663SVincenzo Maffione memset(&vale_list, 0, sizeof(vale_list)); 277*9fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_list; 278*9fd3f663SVincenzo Maffione if (a->name == NULL) { 279*9fd3f663SVincenzo Maffione return list_all(fd, &hdr); 280*9fd3f663SVincenzo Maffione } 281*9fd3f663SVincenzo Maffione action = "list"; 282*9fd3f663SVincenzo Maffione break; 283*9fd3f663SVincenzo Maffione 284*9fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_POLLING_ENABLE: 285*9fd3f663SVincenzo Maffione action = "enable polling on"; 286*9fd3f663SVincenzo Maffione /* fall through */ 287*9fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_POLLING_DISABLE: 288*9fd3f663SVincenzo Maffione memset(&vale_polling, 0, sizeof(vale_polling)); 289*9fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&vale_polling; 290*9fd3f663SVincenzo Maffione parse_poll_config(a->config, &vale_polling); 291*9fd3f663SVincenzo Maffione if (action == NULL) 292*9fd3f663SVincenzo Maffione action ="disable polling on"; 293*9fd3f663SVincenzo Maffione break; 294*9fd3f663SVincenzo Maffione 295*9fd3f663SVincenzo Maffione case NETMAP_REQ_PORT_INFO_GET: 296*9fd3f663SVincenzo Maffione memset(&port_info_get, 0, sizeof(port_info_get)); 297*9fd3f663SVincenzo Maffione hdr.nr_body = (uintptr_t)&port_info_get; 298*9fd3f663SVincenzo Maffione action = "obtain info for"; 299*9fd3f663SVincenzo Maffione break; 300*9fd3f663SVincenzo Maffione } 301*9fd3f663SVincenzo Maffione error = ioctl(fd, NIOCCTRL, &hdr); 302*9fd3f663SVincenzo Maffione if (error < 0) { 303*9fd3f663SVincenzo Maffione fprintf(stderr, "failed to %s %s: %s\n", 304*9fd3f663SVincenzo Maffione action, a->name, strerror(errno)); 305*9fd3f663SVincenzo Maffione return 1; 306*9fd3f663SVincenzo Maffione } 307*9fd3f663SVincenzo Maffione switch (hdr.nr_reqtype) { 308*9fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_NEWIF: 309*9fd3f663SVincenzo Maffione if (verbose) { 310*9fd3f663SVincenzo Maffione dump_newif(&vale_newif); 311*9fd3f663SVincenzo Maffione } 312*9fd3f663SVincenzo Maffione break; 313*9fd3f663SVincenzo Maffione 314*9fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_ATTACH: 315*9fd3f663SVincenzo Maffione if (verbose) { 316*9fd3f663SVincenzo Maffione printf("port_index: %"PRIu32"\n", vale_attach.port_index); 317*9fd3f663SVincenzo Maffione } 318*9fd3f663SVincenzo Maffione break; 319*9fd3f663SVincenzo Maffione 320*9fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_DETACH: 321*9fd3f663SVincenzo Maffione if (verbose) { 322*9fd3f663SVincenzo Maffione printf("port_index: %"PRIu32"\n", vale_detach.port_index); 323*9fd3f663SVincenzo Maffione } 324*9fd3f663SVincenzo Maffione break; 325*9fd3f663SVincenzo Maffione 326*9fd3f663SVincenzo Maffione case NETMAP_REQ_VALE_LIST: 327*9fd3f663SVincenzo Maffione dump_vale_list(&vale_list); 328*9fd3f663SVincenzo Maffione break; 329*9fd3f663SVincenzo Maffione 330*9fd3f663SVincenzo Maffione case NETMAP_REQ_PORT_INFO_GET: 331*9fd3f663SVincenzo 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" 343*9fd3f663SVincenzo 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" 350*9fd3f663SVincenzo 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" 357*9fd3f663SVincenzo Maffione "\t-m memid to use when creating a new interface\n" 358*9fd3f663SVincenzo Maffione "\t-v increase verbosity\n" 359*9fd3f663SVincenzo 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 { 366*9fd3f663SVincenzo Maffione int ch; 367*9fd3f663SVincenzo Maffione struct args a = { 368*9fd3f663SVincenzo Maffione .name = NULL, 369*9fd3f663SVincenzo Maffione .config = NULL, 370*9fd3f663SVincenzo Maffione .mem_id = NULL, 371*9fd3f663SVincenzo Maffione .nr_reqtype = 0, 372*9fd3f663SVincenzo Maffione .nr_mode = NR_REG_ALL_NIC, 373*9fd3f663SVincenzo Maffione }; 374c7c78055SVincenzo Maffione 375*9fd3f663SVincenzo 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); 379*9fd3f663SVincenzo Maffione usage(1); 380c7c78055SVincenzo Maffione break; 381c7c78055SVincenzo Maffione case 'd': 382*9fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_DETACH; 383*9fd3f663SVincenzo Maffione a.name = optarg; 384c7c78055SVincenzo Maffione break; 385c7c78055SVincenzo Maffione case 'a': 386*9fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_ATTACH; 387*9fd3f663SVincenzo Maffione a.nr_mode = NR_REG_ALL_NIC; 388*9fd3f663SVincenzo Maffione a.name = optarg; 389c7c78055SVincenzo Maffione break; 390c7c78055SVincenzo Maffione case 'h': 391*9fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_ATTACH; 392*9fd3f663SVincenzo Maffione a.nr_mode = NR_REG_NIC_SW; 393*9fd3f663SVincenzo Maffione a.name = optarg; 394c7c78055SVincenzo Maffione break; 395c7c78055SVincenzo Maffione case 'n': 396*9fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_NEWIF; 397*9fd3f663SVincenzo Maffione a.name = optarg; 398c7c78055SVincenzo Maffione break; 399c7c78055SVincenzo Maffione case 'r': 400*9fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_DELIF; 401*9fd3f663SVincenzo Maffione a.name = optarg; 402c7c78055SVincenzo Maffione break; 403c7c78055SVincenzo Maffione case 'g': 404*9fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_PORT_INFO_GET; 405*9fd3f663SVincenzo Maffione a.name = optarg; 406c7c78055SVincenzo Maffione break; 407c7c78055SVincenzo Maffione case 'l': 408*9fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_LIST; 409*9fd3f663SVincenzo Maffione a.name = optarg; 410*9fd3f663SVincenzo Maffione if (strncmp(a.name, NM_BDG_NAME, strlen(NM_BDG_NAME))) { 411*9fd3f663SVincenzo Maffione fprintf(stderr, "invalid vale port name: '%s'\n", a.name); 412*9fd3f663SVincenzo Maffione usage(1); 413*9fd3f663SVincenzo Maffione } 414c7c78055SVincenzo Maffione break; 415c7c78055SVincenzo Maffione case 'C': 416*9fd3f663SVincenzo Maffione a.config = optarg; 417c7c78055SVincenzo Maffione break; 418c7c78055SVincenzo Maffione case 'p': 419*9fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_POLLING_ENABLE; 420*9fd3f663SVincenzo Maffione a.name = optarg; 421c7c78055SVincenzo Maffione break; 422c7c78055SVincenzo Maffione case 'P': 423*9fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_POLLING_DISABLE; 424*9fd3f663SVincenzo Maffione a.name = optarg; 425c7c78055SVincenzo Maffione break; 426c7c78055SVincenzo Maffione case 'm': 427*9fd3f663SVincenzo Maffione a.mem_id = optarg; 428*9fd3f663SVincenzo Maffione break; 429*9fd3f663SVincenzo Maffione case 'v': 430*9fd3f663SVincenzo Maffione verbose++; 431c7c78055SVincenzo Maffione break; 432c7c78055SVincenzo Maffione } 433c7c78055SVincenzo Maffione } 434c7c78055SVincenzo Maffione if (optind != argc) { 435*9fd3f663SVincenzo Maffione usage(1); 436c7c78055SVincenzo Maffione } 437c7c78055SVincenzo Maffione if (argc == 1) { 438*9fd3f663SVincenzo Maffione a.nr_reqtype = NETMAP_REQ_VALE_LIST; 439*9fd3f663SVincenzo Maffione a.name = NULL; 440c7c78055SVincenzo Maffione } 441*9fd3f663SVincenzo Maffione if (!a.nr_reqtype) { 442*9fd3f663SVincenzo Maffione usage(1); 443*9fd3f663SVincenzo Maffione } 444*9fd3f663SVincenzo Maffione return bdg_ctl(&a); 445c7c78055SVincenzo Maffione } 446