vale-ctl.c revision 262151
1/* 2 * Copyright (C) 2013-2014 Michio Honda. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26/* $FreeBSD: stable/10/tools/tools/netmap/vale-ctl.c 262151 2014-02-18 05:01:04Z luigi $ */ 27 28#include <errno.h> 29#include <stdio.h> 30#include <inttypes.h> /* PRI* macros */ 31#include <string.h> /* strcmp */ 32#include <fcntl.h> /* open */ 33#include <unistd.h> /* close */ 34#include <sys/ioctl.h> /* ioctl */ 35#include <sys/param.h> 36#include <sys/socket.h> /* apple needs sockaddr */ 37#include <net/if.h> /* ifreq */ 38#include <net/netmap.h> 39#include <net/netmap_user.h> 40#include <libgen.h> /* basename */ 41 42/* debug support */ 43#define ND(format, ...) do {} while(0) 44#define D(format, ...) \ 45 fprintf(stderr, "%s [%d] " format "\n", \ 46 __FUNCTION__, __LINE__, ##__VA_ARGS__) 47 48static int 49bdg_ctl(const char *name, int nr_cmd, int nr_arg) 50{ 51 struct nmreq nmr; 52 int error = 0; 53 int fd = open("/dev/netmap", O_RDWR); 54 55 if (fd == -1) { 56 D("Unable to open /dev/netmap"); 57 return -1; 58 } 59 60 bzero(&nmr, sizeof(nmr)); 61 nmr.nr_version = NETMAP_API; 62 if (name != NULL) /* might be NULL */ 63 strncpy(nmr.nr_name, name, sizeof(nmr.nr_name)); 64 nmr.nr_cmd = nr_cmd; 65 66 switch (nr_cmd) { 67 case NETMAP_BDG_ATTACH: 68 case NETMAP_BDG_DETACH: 69 if (nr_arg && nr_arg != NETMAP_BDG_HOST) 70 nr_arg = 0; 71 nmr.nr_arg1 = nr_arg; 72 error = ioctl(fd, NIOCREGIF, &nmr); 73 if (error == -1) { 74 ND("Unable to %s %s to the bridge", nr_cmd == 75 NETMAP_BDG_DETACH?"detach":"attach", name); 76 perror(name); 77 } else 78 ND("Success to %s %s to the bridge", nr_cmd == 79 NETMAP_BDG_DETACH?"detach":"attach", name); 80 break; 81 82 case NETMAP_BDG_LIST: 83 if (strlen(nmr.nr_name)) { /* name to bridge/port info */ 84 error = ioctl(fd, NIOCGINFO, &nmr); 85 if (error) { 86 ND("Unable to obtain info for %s", name); 87 perror(name); 88 } else 89 D("%s at bridge:%d port:%d", name, nmr.nr_arg1, 90 nmr.nr_arg2); 91 break; 92 } 93 94 /* scan all the bridges and ports */ 95 nmr.nr_arg1 = nmr.nr_arg2 = 0; 96 for (; !ioctl(fd, NIOCGINFO, &nmr); nmr.nr_arg2++) { 97 D("bridge:%d port:%d %s", nmr.nr_arg1, nmr.nr_arg2, 98 nmr.nr_name); 99 nmr.nr_name[0] = '\0'; 100 } 101 102 break; 103 104 default: /* GINFO */ 105 nmr.nr_cmd = nmr.nr_arg1 = nmr.nr_arg2 = 0; 106 error = ioctl(fd, NIOCGINFO, &nmr); 107 if (error) { 108 ND("Unable to get if info for %s", name); 109 perror(name); 110 } else 111 D("%s: %d queues.", name, nmr.nr_rx_rings); 112 break; 113 } 114 close(fd); 115 return error; 116} 117 118int 119main(int argc, char *argv[]) 120{ 121 int ch, nr_cmd = 0, nr_arg = 0; 122 const char *command = basename(argv[0]); 123 char *name = NULL; 124 125 if (argc > 3) { 126usage: 127 fprintf(stderr, 128 "Usage:\n" 129 "%s arguments\n" 130 "\t-g interface interface name to get info\n" 131 "\t-d interface interface name to be detached\n" 132 "\t-a interface interface name to be attached\n" 133 "\t-h interface interface name to be attached with the host stack\n" 134 "\t-l list all or specified bridge's interfaces (default)\n" 135 "", command); 136 return 0; 137 } 138 139 while ((ch = getopt(argc, argv, "d:a:h:g:l")) != -1) { 140 name = optarg; /* default */ 141 switch (ch) { 142 default: 143 fprintf(stderr, "bad option %c %s", ch, optarg); 144 goto usage; 145 case 'd': 146 nr_cmd = NETMAP_BDG_DETACH; 147 break; 148 case 'a': 149 nr_cmd = NETMAP_BDG_ATTACH; 150 break; 151 case 'h': 152 nr_cmd = NETMAP_BDG_ATTACH; 153 nr_arg = NETMAP_BDG_HOST; 154 break; 155 case 'g': 156 nr_cmd = 0; 157 break; 158 case 'l': 159 nr_cmd = NETMAP_BDG_LIST; 160 if (optind < argc && argv[optind][0] == '-') 161 name = NULL; 162 break; 163 } 164 if (optind != argc) { 165 // fprintf(stderr, "optind %d argc %d\n", optind, argc); 166 goto usage; 167 } 168 } 169 if (argc == 1) 170 nr_cmd = NETMAP_BDG_LIST; 171 return bdg_ctl(name, nr_cmd, nr_arg) ? 1 : 0; 172} 173