2 * Copyright (C) 2013 Michio Honda. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
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 <net/if.h> /* ifreq */
37 #include <net/netmap.h>
38 #include <net/netmap_user.h>
39 #include <libgen.h> /* basename */
42 #define ND(format, ...) do {} while(0)
43 #define D(format, ...) \
44 fprintf(stderr, "%s [%d] " format "\n", \
45 __FUNCTION__, __LINE__, ##__VA_ARGS__)
48 bdg_ctl(const char *name, int nr_cmd, int nr_arg)
52 int fd = open("/dev/netmap", O_RDWR);
55 D("Unable to open /dev/netmap");
59 bzero(&nmr, sizeof(nmr));
60 nmr.nr_version = NETMAP_API;
61 if (name != NULL) /* might be NULL */
62 strncpy(nmr.nr_name, name, sizeof(nmr.nr_name));
66 case NETMAP_BDG_ATTACH:
67 case NETMAP_BDG_DETACH:
68 if (nr_arg && nr_arg != NETMAP_BDG_HOST)
71 error = ioctl(fd, NIOCREGIF, &nmr);
73 D("Unable to %s %s to the bridge", nr_cmd ==
74 NETMAP_BDG_DETACH?"detach":"attach", name);
76 D("Success to %s %s to the bridge\n", nr_cmd ==
77 NETMAP_BDG_DETACH?"detach":"attach", name);
81 if (strlen(nmr.nr_name)) { /* name to bridge/port info */
82 error = ioctl(fd, NIOCGINFO, &nmr);
84 D("Unable to obtain info for %s", name);
86 D("%s at bridge:%d port:%d", name, nmr.nr_arg1,
91 /* scan all the bridges and ports */
92 nmr.nr_arg1 = nmr.nr_arg2 = 0;
93 for (; !ioctl(fd, NIOCGINFO, &nmr); nmr.nr_arg2++) {
94 D("bridge:%d port:%d %s", nmr.nr_arg1, nmr.nr_arg2,
96 nmr.nr_name[0] = '\0';
102 nmr.nr_cmd = nmr.nr_arg1 = nmr.nr_arg2 = 0;
103 error = ioctl(fd, NIOCGINFO, &nmr);
105 D("Unable to get if info for %s", name);
107 D("%s: %d queues.", name, nmr.nr_rx_rings);
115 main(int argc, char *argv[])
117 int ch, nr_cmd = 0, nr_arg = 0;
118 const char *command = basename(argv[0]);
121 if (argc != 3 && argc != 1 /* list all */ ) {
126 "\t-g interface interface name to get info\n"
127 "\t-d interface interface name to be detached\n"
128 "\t-a interface interface name to be attached\n"
129 "\t-h interface interface name to be attached with the host stack\n"
130 "\t-l list all or specified bridge's interfaces\n"
135 while ((ch = getopt(argc, argv, "d:a:h:g:l:")) != -1) {
138 fprintf(stderr, "bad option %c %s", ch, optarg);
141 nr_cmd = NETMAP_BDG_DETACH;
144 nr_cmd = NETMAP_BDG_ATTACH;
147 nr_cmd = NETMAP_BDG_ATTACH;
148 nr_arg = NETMAP_BDG_HOST;
154 nr_cmd = NETMAP_BDG_LIST;
160 nr_cmd = NETMAP_BDG_LIST;
161 bdg_ctl(name, nr_cmd, nr_arg);