vale-ctl.c revision 262151
1139749Simp/* 2113584Ssimokawa * Copyright (C) 2013-2014 Michio Honda. All rights reserved. 3103285Sikob * 4103285Sikob * Redistribution and use in source and binary forms, with or without 5103285Sikob * modification, are permitted provided that the following conditions 6103285Sikob * are met: 7103285Sikob * 1. Redistributions of source code must retain the above copyright 8103285Sikob * notice, this list of conditions and the following disclaimer. 9103285Sikob * 2. Redistributions in binary form must reproduce the above copyright 10103285Sikob * notice, this list of conditions and the following disclaimer in the 11103285Sikob * documentation and/or other materials provided with the distribution. 12103285Sikob * 13103285Sikob * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14103285Sikob * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15103285Sikob * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16103285Sikob * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17103285Sikob * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18103285Sikob * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19103285Sikob * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20103285Sikob * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21103285Sikob * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22103285Sikob * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23103285Sikob * SUCH DAMAGE. 24103285Sikob */ 25103285Sikob 26103285Sikob/* $FreeBSD: stable/10/tools/tools/netmap/vale-ctl.c 262151 2014-02-18 05:01:04Z luigi $ */ 27103285Sikob 28103285Sikob#include <errno.h> 29103285Sikob#include <stdio.h> 30103285Sikob#include <inttypes.h> /* PRI* macros */ 31103285Sikob#include <string.h> /* strcmp */ 32103285Sikob#include <fcntl.h> /* open */ 33103285Sikob#include <unistd.h> /* close */ 34103285Sikob#include <sys/ioctl.h> /* ioctl */ 35227843Smarius#include <sys/param.h> 36227843Smarius#include <sys/socket.h> /* apple needs sockaddr */ 37227843Smarius#include <net/if.h> /* ifreq */ 38103285Sikob#include <net/netmap.h> 39103285Sikob#include <net/netmap_user.h> 40103285Sikob#include <libgen.h> /* basename */ 41103285Sikob 42193066Sjamie/* debug support */ 43103285Sikob#define ND(format, ...) do {} while(0) 44129879Sphk#define D(format, ...) \ 45103285Sikob fprintf(stderr, "%s [%d] " format "\n", \ 46103285Sikob __FUNCTION__, __LINE__, ##__VA_ARGS__) 47103285Sikob 48169806Ssimokawastatic int 49103285Sikobbdg_ctl(const char *name, int nr_cmd, int nr_arg) 50170374Ssimokawa{ 51103285Sikob struct nmreq nmr; 52113584Ssimokawa int error = 0; 53103285Sikob int fd = open("/dev/netmap", O_RDWR); 54103285Sikob 55103285Sikob if (fd == -1) { 56110072Ssimokawa D("Unable to open /dev/netmap"); 57103285Sikob return -1; 58103285Sikob } 59103285Sikob 60116376Ssimokawa bzero(&nmr, sizeof(nmr)); 61116376Ssimokawa nmr.nr_version = NETMAP_API; 62116376Ssimokawa if (name != NULL) /* might be NULL */ 63116376Ssimokawa strncpy(nmr.nr_name, name, sizeof(nmr.nr_name)); 64116376Ssimokawa nmr.nr_cmd = nr_cmd; 65116376Ssimokawa 66116376Ssimokawa switch (nr_cmd) { 67272214Skan case NETMAP_BDG_ATTACH: 68103285Sikob case NETMAP_BDG_DETACH: 69108281Ssimokawa if (nr_arg && nr_arg != NETMAP_BDG_HOST) 70109736Ssimokawa nr_arg = 0; 71109736Ssimokawa nmr.nr_arg1 = nr_arg; 72109736Ssimokawa error = ioctl(fd, NIOCREGIF, &nmr); 73120850Ssimokawa if (error == -1) { 74120850Ssimokawa ND("Unable to %s %s to the bridge", nr_cmd == 75103285Sikob NETMAP_BDG_DETACH?"detach":"attach", name); 76110195Ssimokawa perror(name); 77110269Ssimokawa } else 78110195Ssimokawa ND("Success to %s %s to the bridge", nr_cmd == 79103285Sikob NETMAP_BDG_DETACH?"detach":"attach", name); 80103285Sikob break; 81103285Sikob 82103285Sikob case NETMAP_BDG_LIST: 83272214Skan if (strlen(nmr.nr_name)) { /* name to bridge/port info */ 84272214Skan error = ioctl(fd, NIOCGINFO, &nmr); 85272214Skan if (error) { 86272214Skan ND("Unable to obtain info for %s", name); 87272214Skan perror(name); 88170374Ssimokawa } else 89212413Savg D("%s at bridge:%d port:%d", name, nmr.nr_arg1, 90272214Skan nmr.nr_arg2); 91272214Skan break; 92272214Skan } 93272214Skan 94272214Skan /* scan all the bridges and ports */ 95272214Skan nmr.nr_arg1 = nmr.nr_arg2 = 0; 96169806Ssimokawa for (; !ioctl(fd, NIOCGINFO, &nmr); nmr.nr_arg2++) { 97106543Ssimokawa D("bridge:%d port:%d %s", nmr.nr_arg1, nmr.nr_arg2, 98124169Ssimokawa nmr.nr_name); 99106543Ssimokawa nmr.nr_name[0] = '\0'; 100124169Ssimokawa } 101170374Ssimokawa 102103285Sikob break; 103103285Sikob 104103285Sikob default: /* GINFO */ 105125238Ssimokawa nmr.nr_cmd = nmr.nr_arg1 = nmr.nr_arg2 = 0; 106125238Ssimokawa error = ioctl(fd, NIOCGINFO, &nmr); 107103285Sikob if (error) { 108103285Sikob ND("Unable to get if info for %s", name); 109108642Ssimokawa perror(name); 110116978Ssimokawa } else 111103285Sikob D("%s: %d queues.", name, nmr.nr_rx_rings); 112103285Sikob break; 113103285Sikob } 114103285Sikob close(fd); 115103285Sikob return error; 116227843Smarius} 117103285Sikob 118272214Skanint 119124251Ssimokawamain(int argc, char *argv[]) 120124251Ssimokawa{ 121124251Ssimokawa int ch, nr_cmd = 0, nr_arg = 0; 122124251Ssimokawa const char *command = basename(argv[0]); 123103285Sikob char *name = NULL; 124124251Ssimokawa 125124251Ssimokawa if (argc > 3) { 126124251Ssimokawausage: 127124251Ssimokawa fprintf(stderr, 128124251Ssimokawa "Usage:\n" 129124251Ssimokawa "%s arguments\n" 130124251Ssimokawa "\t-g interface interface name to get info\n" 131114909Ssimokawa "\t-d interface interface name to be detached\n" 132114909Ssimokawa "\t-a interface interface name to be attached\n" 133114909Ssimokawa "\t-h interface interface name to be attached with the host stack\n" 134114909Ssimokawa "\t-l list all or specified bridge's interfaces (default)\n" 135106813Ssimokawa "", command); 136103285Sikob return 0; 137103285Sikob } 138103285Sikob 139103285Sikob while ((ch = getopt(argc, argv, "d:a:h:g:l")) != -1) { 140103285Sikob name = optarg; /* default */ 141103285Sikob switch (ch) { 142103285Sikob default: 143110072Ssimokawa fprintf(stderr, "bad option %c %s", ch, optarg); 144103285Sikob goto usage; 145106810Ssimokawa case 'd': 146110072Ssimokawa nr_cmd = NETMAP_BDG_DETACH; 147103285Sikob break; 148103285Sikob case 'a': 149110072Ssimokawa nr_cmd = NETMAP_BDG_ATTACH; 150277509Swill break; 151110193Ssimokawa case 'h': 152120660Ssimokawa nr_cmd = NETMAP_BDG_ATTACH; 153103285Sikob nr_arg = NETMAP_BDG_HOST; 154277509Swill break; 155110072Ssimokawa case 'g': 156106810Ssimokawa nr_cmd = 0; 157103285Sikob break; 158106813Ssimokawa case 'l': 159103285Sikob nr_cmd = NETMAP_BDG_LIST; 160110072Ssimokawa if (optind < argc && argv[optind][0] == '-') 161110072Ssimokawa name = NULL; 162110072Ssimokawa break; 163110582Ssimokawa } 164110072Ssimokawa if (optind != argc) { 165110072Ssimokawa // fprintf(stderr, "optind %d argc %d\n", optind, argc); 166110072Ssimokawa goto usage; 167170374Ssimokawa } 168110193Ssimokawa } 169110582Ssimokawa if (argc == 1) 170110072Ssimokawa nr_cmd = NETMAP_BDG_LIST; 171170374Ssimokawa return bdg_ctl(name, nr_cmd, nr_arg) ? 1 : 0; 172110072Ssimokawa} 173272214Skan