vale-ctl.c revision 261909
1251139Sluigi/* 2260368Sluigi * Copyright (C) 2013-2014 Michio Honda. All rights reserved. 3251139Sluigi * 4251139Sluigi * Redistribution and use in source and binary forms, with or without 5251139Sluigi * modification, are permitted provided that the following conditions 6251139Sluigi * are met: 7251139Sluigi * 1. Redistributions of source code must retain the above copyright 8251139Sluigi * notice, this list of conditions and the following disclaimer. 9251139Sluigi * 2. Redistributions in binary form must reproduce the above copyright 10251139Sluigi * notice, this list of conditions and the following disclaimer in the 11251139Sluigi * documentation and/or other materials provided with the distribution. 12251139Sluigi * 13251139Sluigi * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14251139Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15251139Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16251139Sluigi * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17251139Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18251139Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19251139Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20251139Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21251139Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22251139Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23251139Sluigi * SUCH DAMAGE. 24251139Sluigi */ 25251139Sluigi 26251139Sluigi/* $FreeBSD: head/tools/tools/netmap/vale-ctl.c 261909 2014-02-15 04:53:04Z luigi $ */ 27251139Sluigi 28251139Sluigi#include <errno.h> 29251139Sluigi#include <stdio.h> 30251139Sluigi#include <inttypes.h> /* PRI* macros */ 31251139Sluigi#include <string.h> /* strcmp */ 32251139Sluigi#include <fcntl.h> /* open */ 33251139Sluigi#include <unistd.h> /* close */ 34251139Sluigi#include <sys/ioctl.h> /* ioctl */ 35251139Sluigi#include <sys/param.h> 36261909Sluigi#include <sys/socket.h> /* apple needs sockaddr */ 37251139Sluigi#include <net/if.h> /* ifreq */ 38251139Sluigi#include <net/netmap.h> 39251139Sluigi#include <net/netmap_user.h> 40251139Sluigi#include <libgen.h> /* basename */ 41251139Sluigi 42251139Sluigi/* debug support */ 43251139Sluigi#define ND(format, ...) do {} while(0) 44251139Sluigi#define D(format, ...) \ 45251139Sluigi fprintf(stderr, "%s [%d] " format "\n", \ 46251139Sluigi __FUNCTION__, __LINE__, ##__VA_ARGS__) 47251139Sluigi 48251139Sluigistatic int 49251139Sluigibdg_ctl(const char *name, int nr_cmd, int nr_arg) 50251139Sluigi{ 51251139Sluigi struct nmreq nmr; 52251139Sluigi int error = 0; 53251139Sluigi int fd = open("/dev/netmap", O_RDWR); 54251139Sluigi 55251139Sluigi if (fd == -1) { 56251139Sluigi D("Unable to open /dev/netmap"); 57251139Sluigi return -1; 58251139Sluigi } 59251139Sluigi 60251139Sluigi bzero(&nmr, sizeof(nmr)); 61251139Sluigi nmr.nr_version = NETMAP_API; 62251139Sluigi if (name != NULL) /* might be NULL */ 63251139Sluigi strncpy(nmr.nr_name, name, sizeof(nmr.nr_name)); 64251139Sluigi nmr.nr_cmd = nr_cmd; 65251139Sluigi 66251139Sluigi switch (nr_cmd) { 67251139Sluigi case NETMAP_BDG_ATTACH: 68251139Sluigi case NETMAP_BDG_DETACH: 69251139Sluigi if (nr_arg && nr_arg != NETMAP_BDG_HOST) 70251139Sluigi nr_arg = 0; 71251139Sluigi nmr.nr_arg1 = nr_arg; 72251139Sluigi error = ioctl(fd, NIOCREGIF, &nmr); 73260700Sluigi if (error == -1) { 74260700Sluigi ND("Unable to %s %s to the bridge", nr_cmd == 75251139Sluigi NETMAP_BDG_DETACH?"detach":"attach", name); 76260700Sluigi perror(name); 77260700Sluigi } else 78260700Sluigi ND("Success to %s %s to the bridge", nr_cmd == 79251139Sluigi NETMAP_BDG_DETACH?"detach":"attach", name); 80251139Sluigi break; 81251139Sluigi 82251139Sluigi case NETMAP_BDG_LIST: 83251139Sluigi if (strlen(nmr.nr_name)) { /* name to bridge/port info */ 84251139Sluigi error = ioctl(fd, NIOCGINFO, &nmr); 85260700Sluigi if (error) { 86260700Sluigi ND("Unable to obtain info for %s", name); 87260700Sluigi perror(name); 88260700Sluigi } else 89251139Sluigi D("%s at bridge:%d port:%d", name, nmr.nr_arg1, 90251139Sluigi nmr.nr_arg2); 91251139Sluigi break; 92251139Sluigi } 93251139Sluigi 94251139Sluigi /* scan all the bridges and ports */ 95251139Sluigi nmr.nr_arg1 = nmr.nr_arg2 = 0; 96251139Sluigi for (; !ioctl(fd, NIOCGINFO, &nmr); nmr.nr_arg2++) { 97251139Sluigi D("bridge:%d port:%d %s", nmr.nr_arg1, nmr.nr_arg2, 98251139Sluigi nmr.nr_name); 99251139Sluigi nmr.nr_name[0] = '\0'; 100251139Sluigi } 101251139Sluigi 102251139Sluigi break; 103251139Sluigi 104251139Sluigi default: /* GINFO */ 105251139Sluigi nmr.nr_cmd = nmr.nr_arg1 = nmr.nr_arg2 = 0; 106251139Sluigi error = ioctl(fd, NIOCGINFO, &nmr); 107260700Sluigi if (error) { 108260700Sluigi ND("Unable to get if info for %s", name); 109260700Sluigi perror(name); 110260700Sluigi } else 111251139Sluigi D("%s: %d queues.", name, nmr.nr_rx_rings); 112251139Sluigi break; 113251139Sluigi } 114251139Sluigi close(fd); 115251139Sluigi return error; 116251139Sluigi} 117251139Sluigi 118251139Sluigiint 119251139Sluigimain(int argc, char *argv[]) 120251139Sluigi{ 121251139Sluigi int ch, nr_cmd = 0, nr_arg = 0; 122251139Sluigi const char *command = basename(argv[0]); 123251139Sluigi char *name = NULL; 124251139Sluigi 125260368Sluigi if (argc > 3) { 126251139Sluigiusage: 127251139Sluigi fprintf(stderr, 128251139Sluigi "Usage:\n" 129251139Sluigi "%s arguments\n" 130251139Sluigi "\t-g interface interface name to get info\n" 131251139Sluigi "\t-d interface interface name to be detached\n" 132251139Sluigi "\t-a interface interface name to be attached\n" 133251139Sluigi "\t-h interface interface name to be attached with the host stack\n" 134260368Sluigi "\t-l list all or specified bridge's interfaces (default)\n" 135251139Sluigi "", command); 136251139Sluigi return 0; 137251139Sluigi } 138251139Sluigi 139260368Sluigi while ((ch = getopt(argc, argv, "d:a:h:g:l")) != -1) { 140260368Sluigi name = optarg; /* default */ 141251139Sluigi switch (ch) { 142251139Sluigi default: 143251139Sluigi fprintf(stderr, "bad option %c %s", ch, optarg); 144251139Sluigi goto usage; 145251139Sluigi case 'd': 146251139Sluigi nr_cmd = NETMAP_BDG_DETACH; 147251139Sluigi break; 148251139Sluigi case 'a': 149251139Sluigi nr_cmd = NETMAP_BDG_ATTACH; 150251139Sluigi break; 151251139Sluigi case 'h': 152251139Sluigi nr_cmd = NETMAP_BDG_ATTACH; 153251139Sluigi nr_arg = NETMAP_BDG_HOST; 154251139Sluigi break; 155251139Sluigi case 'g': 156251139Sluigi nr_cmd = 0; 157251139Sluigi break; 158251139Sluigi case 'l': 159251139Sluigi nr_cmd = NETMAP_BDG_LIST; 160260368Sluigi if (optind < argc && argv[optind][0] == '-') 161260368Sluigi name = NULL; 162251139Sluigi break; 163251139Sluigi } 164260368Sluigi if (optind != argc) { 165260368Sluigi // fprintf(stderr, "optind %d argc %d\n", optind, argc); 166260368Sluigi goto usage; 167260368Sluigi } 168251139Sluigi } 169251139Sluigi if (argc == 1) 170251139Sluigi nr_cmd = NETMAP_BDG_LIST; 171260700Sluigi return bdg_ctl(name, nr_cmd, nr_arg) ? 1 : 0; 172251139Sluigi} 173