aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorVincenzo Maffione <vmaffione@FreeBSD.org>2019-10-31 21:01:34 +0000
committerVincenzo Maffione <vmaffione@FreeBSD.org>2019-10-31 21:01:34 +0000
commitc7c780553187d5a8ccb6d17e03c43e0c6daf8ecc (patch)
tree8a20db04f73da22e1832607a5267f5ae30699c33 /usr.sbin
parent2e5f9189bb92b6f77ed7ac4608a058e69e2b5bee (diff)
downloadsrc-c7c780553187d5a8ccb6d17e03c43e0c6daf8ecc.tar.gz
src-c7c780553187d5a8ccb6d17e03c43e0c6daf8ecc.zip
add valectl to the system commands
The valectl(4) program is used to manage vale(4) switches. Add it to the system commands so that it can be used right away. This program was previously called vale-ctl, and stored in tools/tools/netmap Reviewed by: hrs, bcr, lwhsu, kevans MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D22146
Notes
Notes: svn path=/head/; revision=354229
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/Makefile1
-rw-r--r--usr.sbin/valectl/Makefile8
-rw-r--r--usr.sbin/valectl/valectl.8163
-rw-r--r--usr.sbin/valectl/valectl.c280
4 files changed, 452 insertions, 0 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 001bc11571e1..458f25b69077 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -96,6 +96,7 @@ SUBDIR= adduser \
trpt \
tzsetup \
ugidfw \
+ valectl \
vigr \
vipw \
wake \
diff --git a/usr.sbin/valectl/Makefile b/usr.sbin/valectl/Makefile
new file mode 100644
index 000000000000..026646948c0e
--- /dev/null
+++ b/usr.sbin/valectl/Makefile
@@ -0,0 +1,8 @@
+# $FreeBSD$
+
+PROG= valectl
+MAN= valectl.8
+
+WARNS?= 3
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/valectl/valectl.8 b/usr.sbin/valectl/valectl.8
new file mode 100644
index 000000000000..4b5a80897825
--- /dev/null
+++ b/usr.sbin/valectl/valectl.8
@@ -0,0 +1,163 @@
+.\" Copyright (c) 2016 Michio Honda.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 26, 2019
+.Dt VALECTL 8
+.Os
+.Sh NAME
+.Nm valectl
+.Nd manage VALE switches provided by netmap
+.Sh SYNOPSIS
+.Bk -words
+.Bl -tag -width "valectl"
+.It Nm
+.Op Fl g Ar valeSSS:PPP
+.Op Fl a Ar valeSSS:interface
+.Op Fl h Ar valeSSS:interface
+.Op Fl d Ar valeSSS:interface
+.Op Fl n Ar interface
+.Op Fl r Ar interface
+.Op Fl l Ar valeSSS:PPP
+.Op Fl l
+.Op Fl p Ar valeSSS:PPP
+.Op Fl P Ar valeSSS:PPP
+.Op Fl C Ar spec
+.Op Fl m Ar memid
+.El
+.Ek
+.Sh DESCRIPTION
+.Nm
+manages and inspects
+.Xr vale 4
+switches, for instance attaching and detaching interfaces, creating
+and deleting persistent VALE ports, or listing the existing switches
+and their ports.
+In the following,
+.Ar valeSSS
+is the name of a VALE switch, while
+.Ar valeSSS:PPP
+is the name of a VALE port of
+.Ar valeSSS .
+.Pp
+When issued without options it lists all the existing switch ports together
+with their internal bridge number and port number.
+.Bl -tag -width Ds
+.It Fl g Ar valeSSS:PPP
+Print the number of receive rings of
+.Ar valeSSS:PPP .
+.It Fl a Ar valeSSS:interface
+Attach
+.Ar interface
+(which must be an existing network interface) to
+.Ar valeSSS
+and detach it from the host stack.
+.It Fl h Ar valeSSS:interface
+Attach
+.Ar interface
+(which must be an existing network interface) to
+.Ar valeSSS
+while keeping it attached to the host stack.
+More precisely, packets coming from
+the host stack and directed to the interface will go through the switch, where
+they can still reach the interface if the switch rules allow it.
+Conversely, packets coming from the interface will go through the switch and,
+if appropriate, will reach the host stack.
+.It Fl d Ar valeSSS:interface
+Detach
+.Ar interface
+from
+.Ar valeSSS .
+.It Fl n Ar interface
+Create a new persistent VALE port with name
+.Ar interface .
+The name must be different from any other network interface
+already present in the system.
+.It Fl d Ar interface
+Destroy the persistent VALE port with name
+.Ar inteface .
+.It Fl l Ar valeSSS:PPP
+Show the internal bridge number and port number of the given switch port.
+.It Fl p Ar valeSSS:PPP
+Enable polling mode for
+.Ar valeSSS:PPP .
+In polling mode, a dedicated kernel thread is spawned to handle packets
+received from
+.Ar valeSSS:PPP
+and push them into the switch.
+The kernel thread busy waits on the switch port rather than relying on
+interrupts or notifications.
+Polling mode can only be used on physical NICs attached to a VALE switch.
+.It Fl P Ar valeSSS:PPP
+Disable polling mode for
+.Ar valeSSS:PPP .
+.It Fl C Ar x | Ar x,y | Ar x,y,z | Ar x,y,z,w
+When used in conjunction with
+.Fl n
+it supplies the number of tx and rx rings and slots.
+The full format with four numbers gives, in order, number of tx slots, number
+of rx slots, number of tx rings and number of rx rings.
+The form with three numbers uses
+.Ar z
+for both the number of tx and the number of rx rings.
+The forms with less than two numbers use the default values for the number
+of rings.
+The form with two numbers supplies the numbers of tx and rx slots.
+The form with only one number uses
+.Ar x
+for both the number of tx and the number of rx slots.
+.Pp
+When used in conjunction with
+.Fl p
+only the first three forms are used.
+The first number may be either 0 or 1.
+If 0, then all interface rings will be polled by a single thread, running
+on the core id given by the second number (the third number, if present,
+must be 1).
+If the first number is 1, then the ring identified by the second number will
+be polled by the core with the same id.
+If a third number is given, then this is repeated for as many consecutive
+rings and cores.
+.It Fl m Ar memid
+Used in conjunction with
+.Fl n
+supplies the netmap memory region identifier to use together with the newly
+created persistent VALE port.
+These ports use a private memory region by default.
+Using this option you can let them share memory with other ports.
+Pass 1 as
+.Ar memid
+to use the global memory region already shared by all
+harware netmap ports.
+.El
+.Sh SEE ALSO
+.Xr netmap 4 ,
+.Xr vale 4
+.Sh AUTHORS
+.An -nosplit
+.Nm
+was written by
+.An Michio Honda
+at NetApp.
diff --git a/usr.sbin/valectl/valectl.c b/usr.sbin/valectl/valectl.c
new file mode 100644
index 000000000000..1e19dfef9e4d
--- /dev/null
+++ b/usr.sbin/valectl/valectl.c
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2013-2014 Michio Honda. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $FreeBSD$ */
+
+#define NETMAP_WITH_LIBS
+#include <net/netmap_user.h>
+#include <net/netmap.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <inttypes.h> /* PRI* macros */
+#include <string.h> /* strcmp */
+#include <fcntl.h> /* open */
+#include <unistd.h> /* close */
+#include <sys/ioctl.h> /* ioctl */
+#include <sys/param.h>
+#include <sys/socket.h> /* apple needs sockaddr */
+#include <net/if.h> /* ifreq */
+#include <libgen.h> /* basename */
+#include <stdlib.h> /* atoi, free */
+
+static void
+parse_nmr_config(const char* conf, struct nmreq *nmr)
+{
+ char *w, *tok;
+ int i, v;
+
+ nmr->nr_tx_rings = nmr->nr_rx_rings = 0;
+ nmr->nr_tx_slots = nmr->nr_rx_slots = 0;
+ if (conf == NULL || ! *conf)
+ return;
+ w = strdup(conf);
+ for (i = 0, tok = strtok(w, ","); tok; i++, tok = strtok(NULL, ",")) {
+ v = atoi(tok);
+ switch (i) {
+ case 0:
+ nmr->nr_tx_slots = nmr->nr_rx_slots = v;
+ break;
+ case 1:
+ nmr->nr_rx_slots = v;
+ break;
+ case 2:
+ nmr->nr_tx_rings = nmr->nr_rx_rings = v;
+ break;
+ case 3:
+ nmr->nr_rx_rings = v;
+ break;
+ default:
+ D("ignored config: %s", tok);
+ break;
+ }
+ }
+ D("txr %d txd %d rxr %d rxd %d",
+ nmr->nr_tx_rings, nmr->nr_tx_slots,
+ nmr->nr_rx_rings, nmr->nr_rx_slots);
+ free(w);
+}
+
+static int
+bdg_ctl(const char *name, int nr_cmd, int nr_arg, char *nmr_config, int nr_arg2)
+{
+ struct nmreq nmr;
+ int error = 0;
+ int fd = open("/dev/netmap", O_RDWR);
+
+ if (fd == -1) {
+ D("Unable to open /dev/netmap");
+ return -1;
+ }
+
+ bzero(&nmr, sizeof(nmr));
+ nmr.nr_version = NETMAP_API;
+ if (name != NULL) /* might be NULL */
+ strncpy(nmr.nr_name, name, sizeof(nmr.nr_name)-1);
+ nmr.nr_cmd = nr_cmd;
+ parse_nmr_config(nmr_config, &nmr);
+ nmr.nr_arg2 = nr_arg2;
+
+ switch (nr_cmd) {
+ case NETMAP_BDG_DELIF:
+ case NETMAP_BDG_NEWIF:
+ error = ioctl(fd, NIOCREGIF, &nmr);
+ if (error == -1) {
+ ND("Unable to %s %s", nr_cmd == NETMAP_BDG_DELIF ? "delete":"create", name);
+ perror(name);
+ } else {
+ ND("Success to %s %s", nr_cmd == NETMAP_BDG_DELIF ? "delete":"create", name);
+ }
+ break;
+ case NETMAP_BDG_ATTACH:
+ case NETMAP_BDG_DETACH:
+ nmr.nr_flags = NR_REG_ALL_NIC;
+ if (nr_arg && nr_arg != NETMAP_BDG_HOST) {
+ nmr.nr_flags = NR_REG_NIC_SW;
+ nr_arg = 0;
+ }
+ nmr.nr_arg1 = nr_arg;
+ error = ioctl(fd, NIOCREGIF, &nmr);
+ if (error == -1) {
+ ND("Unable to %s %s to the bridge", nr_cmd ==
+ NETMAP_BDG_DETACH?"detach":"attach", name);
+ perror(name);
+ } else
+ ND("Success to %s %s to the bridge", nr_cmd ==
+ NETMAP_BDG_DETACH?"detach":"attach", name);
+ break;
+
+ case NETMAP_BDG_LIST:
+ if (strlen(nmr.nr_name)) { /* name to bridge/port info */
+ error = ioctl(fd, NIOCGINFO, &nmr);
+ if (error) {
+ ND("Unable to obtain info for %s", name);
+ perror(name);
+ } else
+ D("%s at bridge:%d port:%d", name, nmr.nr_arg1,
+ nmr.nr_arg2);
+ break;
+ }
+
+ /* scan all the bridges and ports */
+ nmr.nr_arg1 = nmr.nr_arg2 = 0;
+ for (; !ioctl(fd, NIOCGINFO, &nmr); nmr.nr_arg2++) {
+ D("bridge:%d port:%d %s", nmr.nr_arg1, nmr.nr_arg2,
+ nmr.nr_name);
+ nmr.nr_name[0] = '\0';
+ }
+
+ break;
+
+ case NETMAP_BDG_POLLING_ON:
+ case NETMAP_BDG_POLLING_OFF:
+ /* We reuse nmreq fields as follows:
+ * nr_tx_slots: 0 and non-zero indicate REG_ALL_NIC
+ * REG_ONE_NIC, respectively.
+ * nr_rx_slots: CPU core index. This also indicates the
+ * first queue in the case of REG_ONE_NIC
+ * nr_tx_rings: (REG_ONE_NIC only) indicates the
+ * number of CPU cores or the last queue
+ */
+ nmr.nr_flags |= nmr.nr_tx_slots ?
+ NR_REG_ONE_NIC : NR_REG_ALL_NIC;
+ nmr.nr_ringid = nmr.nr_rx_slots;
+ /* number of cores/rings */
+ if (nmr.nr_flags == NR_REG_ALL_NIC)
+ nmr.nr_arg1 = 1;
+ else
+ nmr.nr_arg1 = nmr.nr_tx_rings;
+
+ error = ioctl(fd, NIOCREGIF, &nmr);
+ if (!error)
+ D("polling on %s %s", nmr.nr_name,
+ nr_cmd == NETMAP_BDG_POLLING_ON ?
+ "started" : "stopped");
+ else
+ D("polling on %s %s (err %d)", nmr.nr_name,
+ nr_cmd == NETMAP_BDG_POLLING_ON ?
+ "couldn't start" : "couldn't stop", error);
+ break;
+
+ default: /* GINFO */
+ nmr.nr_cmd = nmr.nr_arg1 = nmr.nr_arg2 = 0;
+ error = ioctl(fd, NIOCGINFO, &nmr);
+ if (error) {
+ ND("Unable to get if info for %s", name);
+ perror(name);
+ } else
+ D("%s: %d queues.", name, nmr.nr_rx_rings);
+ break;
+ }
+ close(fd);
+ return error;
+}
+
+static void
+usage(int errcode)
+{
+ fprintf(stderr,
+ "Usage:\n"
+ "valectl arguments\n"
+ "\t-g interface interface name to get info\n"
+ "\t-d interface interface name to be detached\n"
+ "\t-a interface interface name to be attached\n"
+ "\t-h interface interface name to be attached with the host stack\n"
+ "\t-n interface interface name to be created\n"
+ "\t-r interface interface name to be deleted\n"
+ "\t-l list all or specified bridge's interfaces (default)\n"
+ "\t-C string ring/slot setting of an interface creating by -n\n"
+ "\t-p interface start polling. Additional -C x,y,z configures\n"
+ "\t\t x: 0 (REG_ALL_NIC) or 1 (REG_ONE_NIC),\n"
+ "\t\t y: CPU core id for ALL_NIC and core/ring for ONE_NIC\n"
+ "\t\t z: (ONE_NIC only) num of total cores/rings\n"
+ "\t-P interface stop polling\n"
+ "\t-m memid to use when creating a new interface\n");
+ exit(errcode);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ch, nr_cmd = 0, nr_arg = 0;
+ char *name = NULL, *nmr_config = NULL;
+ int nr_arg2 = 0;
+
+ while ((ch = getopt(argc, argv, "d:a:h:g:l:n:r:C:p:P:m:")) != -1) {
+ if (ch != 'C' && ch != 'm')
+ name = optarg; /* default */
+ switch (ch) {
+ default:
+ fprintf(stderr, "bad option %c %s", ch, optarg);
+ usage(-1);
+ break;
+ case 'd':
+ nr_cmd = NETMAP_BDG_DETACH;
+ break;
+ case 'a':
+ nr_cmd = NETMAP_BDG_ATTACH;
+ break;
+ case 'h':
+ nr_cmd = NETMAP_BDG_ATTACH;
+ nr_arg = NETMAP_BDG_HOST;
+ break;
+ case 'n':
+ nr_cmd = NETMAP_BDG_NEWIF;
+ break;
+ case 'r':
+ nr_cmd = NETMAP_BDG_DELIF;
+ break;
+ case 'g':
+ nr_cmd = 0;
+ break;
+ case 'l':
+ nr_cmd = NETMAP_BDG_LIST;
+ break;
+ case 'C':
+ nmr_config = strdup(optarg);
+ break;
+ case 'p':
+ nr_cmd = NETMAP_BDG_POLLING_ON;
+ break;
+ case 'P':
+ nr_cmd = NETMAP_BDG_POLLING_OFF;
+ break;
+ case 'm':
+ nr_arg2 = atoi(optarg);
+ break;
+ }
+ }
+ if (optind != argc) {
+ // fprintf(stderr, "optind %d argc %d\n", optind, argc);
+ usage(-1);
+ }
+ if (argc == 1) {
+ nr_cmd = NETMAP_BDG_LIST;
+ name = NULL;
+ }
+ return bdg_ctl(name, nr_cmd, nr_arg, nmr_config, nr_arg2) ? 1 : 0;
+}