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