]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - tools/tools/netmap/vale-ctl.c
Copy stable/9 to releng/9.3 as part of the 9.3-RELEASE cycle.
[FreeBSD/releng/9.3.git] / tools / tools / netmap / vale-ctl.c
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$ */
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
48 static int
49 bdg_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
118 int
119 main(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) {
126 usage:
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 }