vale-ctl.c revision 260368
1100203Sgad/* 2100203Sgad * Copyright (C) 2013-2014 Michio Honda. All rights reserved. 3220586Sgad * 4100203Sgad * Redistribution and use in source and binary forms, with or without 5100203Sgad * modification, are permitted provided that the following conditions 6100203Sgad * are met: 7100203Sgad * 1. Redistributions of source code must retain the above copyright 8100203Sgad * notice, this list of conditions and the following disclaimer. 9100203Sgad * 2. Redistributions in binary form must reproduce the above copyright 10100203Sgad * notice, this list of conditions and the following disclaimer in the 11100203Sgad * documentation and/or other materials provided with the distribution. 12100203Sgad * 13100203Sgad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14100203Sgad * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15100203Sgad * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16100203Sgad * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17100203Sgad * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18100203Sgad * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19100203Sgad * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20100203Sgad * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21100203Sgad * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22100203Sgad * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23100203Sgad * SUCH DAMAGE. 24100203Sgad */ 25100203Sgad 26100203Sgad/* $FreeBSD: head/tools/tools/netmap/vale-ctl.c 260368 2014-01-06 12:53:15Z luigi $ */ 27100203Sgad 28100203Sgad#include <errno.h> 29100203Sgad#include <stdio.h> 30100203Sgad#include <inttypes.h> /* PRI* macros */ 31100203Sgad#include <string.h> /* strcmp */ 32100203Sgad#include <fcntl.h> /* open */ 33100203Sgad#include <unistd.h> /* close */ 34100203Sgad#include <sys/ioctl.h> /* ioctl */ 35117541Sgad#include <sys/param.h> 36117541Sgad#include <net/if.h> /* ifreq */ 37100203Sgad#include <net/netmap.h> 38100203Sgad#include <net/netmap_user.h> 39100203Sgad#include <libgen.h> /* basename */ 40100203Sgad 41100203Sgad/* debug support */ 42100203Sgad#define ND(format, ...) do {} while(0) 43100203Sgad#define D(format, ...) \ 44100203Sgad fprintf(stderr, "%s [%d] " format "\n", \ 45100203Sgad __FUNCTION__, __LINE__, ##__VA_ARGS__) 46100203Sgad 47100203Sgadstatic int 48100203Sgadbdg_ctl(const char *name, int nr_cmd, int nr_arg) 49100203Sgad{ 50100203Sgad struct nmreq nmr; 51100203Sgad int error = 0; 52100203Sgad int fd = open("/dev/netmap", O_RDWR); 53100203Sgad 54100203Sgad if (fd == -1) { 55100203Sgad D("Unable to open /dev/netmap"); 56100203Sgad return -1; 57100203Sgad } 58100203Sgad 59100203Sgad bzero(&nmr, sizeof(nmr)); 60100203Sgad nmr.nr_version = NETMAP_API; 61100203Sgad if (name != NULL) /* might be NULL */ 62100203Sgad strncpy(nmr.nr_name, name, sizeof(nmr.nr_name)); 63100203Sgad nmr.nr_cmd = nr_cmd; 64100203Sgad 65100203Sgad switch (nr_cmd) { 66100203Sgad case NETMAP_BDG_ATTACH: 67100203Sgad case NETMAP_BDG_DETACH: 68100203Sgad if (nr_arg && nr_arg != NETMAP_BDG_HOST) 69100203Sgad nr_arg = 0; 70100203Sgad nmr.nr_arg1 = nr_arg; 71100203Sgad error = ioctl(fd, NIOCREGIF, &nmr); 72100203Sgad if (error == -1) 73100203Sgad D("Unable to %s %s to the bridge", nr_cmd == 74100203Sgad NETMAP_BDG_DETACH?"detach":"attach", name); 75100203Sgad else 76100203Sgad D("Success to %s %s to the bridge\n", nr_cmd == 77100203Sgad NETMAP_BDG_DETACH?"detach":"attach", name); 78100203Sgad break; 79100203Sgad 80100203Sgad case NETMAP_BDG_LIST: 81100203Sgad if (strlen(nmr.nr_name)) { /* name to bridge/port info */ 82100203Sgad error = ioctl(fd, NIOCGINFO, &nmr); 83100203Sgad if (error) 84100203Sgad D("Unable to obtain info for %s", name); 85100203Sgad else 86100203Sgad D("%s at bridge:%d port:%d", name, nmr.nr_arg1, 87100203Sgad nmr.nr_arg2); 88100203Sgad break; 89100203Sgad } 90100203Sgad 91100203Sgad /* scan all the bridges and ports */ 92100203Sgad nmr.nr_arg1 = nmr.nr_arg2 = 0; 93100203Sgad for (; !ioctl(fd, NIOCGINFO, &nmr); nmr.nr_arg2++) { 94100203Sgad D("bridge:%d port:%d %s", nmr.nr_arg1, nmr.nr_arg2, 95100203Sgad nmr.nr_name); 96100203Sgad nmr.nr_name[0] = '\0'; 97100203Sgad } 98100203Sgad 99100203Sgad break; 100100203Sgad 101100203Sgad default: /* GINFO */ 102100203Sgad nmr.nr_cmd = nmr.nr_arg1 = nmr.nr_arg2 = 0; 103100203Sgad error = ioctl(fd, NIOCGINFO, &nmr); 104100203Sgad if (error) 105100203Sgad D("Unable to get if info for %s", name); 106100203Sgad else 107100203Sgad D("%s: %d queues.", name, nmr.nr_rx_rings); 108100203Sgad break; 109100203Sgad } 110100203Sgad close(fd); 111100203Sgad return error; 112100203Sgad} 113100203Sgad 114100203Sgadint 115100203Sgadmain(int argc, char *argv[]) 116100203Sgad{ 117100203Sgad int ch, nr_cmd = 0, nr_arg = 0; 118100203Sgad const char *command = basename(argv[0]); 119100203Sgad char *name = NULL; 120100203Sgad 121100203Sgad if (argc > 3) { 122100203Sgadusage: 123100203Sgad fprintf(stderr, 124100203Sgad "Usage:\n" 125100203Sgad "%s arguments\n" 126100203Sgad "\t-g interface interface name to get info\n" 127100203Sgad "\t-d interface interface name to be detached\n" 128100203Sgad "\t-a interface interface name to be attached\n" 129100203Sgad "\t-h interface interface name to be attached with the host stack\n" 130100203Sgad "\t-l list all or specified bridge's interfaces (default)\n" 131100203Sgad "", command); 132100203Sgad return 0; 133100203Sgad } 134100203Sgad 135100203Sgad while ((ch = getopt(argc, argv, "d:a:h:g:l")) != -1) { 136100203Sgad name = optarg; /* default */ 137100203Sgad switch (ch) { 138100203Sgad default: 139100203Sgad fprintf(stderr, "bad option %c %s", ch, optarg); 140100203Sgad goto usage; 141100203Sgad case 'd': 142100203Sgad nr_cmd = NETMAP_BDG_DETACH; 143100203Sgad break; 144100203Sgad case 'a': 145100203Sgad nr_cmd = NETMAP_BDG_ATTACH; 146100203Sgad break; 147100203Sgad case 'h': 148100203Sgad nr_cmd = NETMAP_BDG_ATTACH; 149100203Sgad nr_arg = NETMAP_BDG_HOST; 150100203Sgad break; 151100203Sgad case 'g': 152100203Sgad nr_cmd = 0; 153100203Sgad break; 154100203Sgad case 'l': 155100203Sgad nr_cmd = NETMAP_BDG_LIST; 156100203Sgad if (optind < argc && argv[optind][0] == '-') 157100203Sgad name = NULL; 158100203Sgad break; 159100203Sgad } 160100203Sgad if (optind != argc) { 161100203Sgad // fprintf(stderr, "optind %d argc %d\n", optind, argc); 162100203Sgad goto usage; 163100203Sgad } 164100203Sgad } 165100203Sgad if (argc == 1) 166100203Sgad nr_cmd = NETMAP_BDG_LIST; 167100203Sgad bdg_ctl(name, nr_cmd, nr_arg); 168100203Sgad return 0; 169100203Sgad} 170100203Sgad