Page MenuHomeFreeBSD

D26161.diff
No OneTemporary

D26161.diff

Index: usr.sbin/valectl/valectl.8
===================================================================
--- usr.sbin/valectl/valectl.8
+++ usr.sbin/valectl/valectl.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd March 31, 2020
+.Dd August 23, 2020
.Dt VALECTL 8
.Os
.Sh NAME
@@ -66,25 +66,32 @@
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
+Print parameters of
.Ar valeSSS:PPP .
.It Fl a Ar valeSSS:interface
Attach
.Ar interface
-(which must be an existing network interface) to
+.Pq which must be a network interface on the system
+to
.Ar valeSSS
-and detach it from the host stack.
+and detach it from the network stack on the system.
.It Fl h Ar valeSSS:interface
Attach
.Ar interface
-(which must be an existing network interface) to
+.Pq which must be a network interface on the system
+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.
+while keeping it attached to the network stack on the system.
+.Pp
+More precisely,
+packets originated from the network stack and directed to the interface
+will go through the specified VALE switch.
+The packets can still reach the interface if the switch rules are configured
+to allow it.
+Conversely, packets received on the interface will go through the VALE
+switch and,
+if configured properly,
+will reach the network stack.
.It Fl d Ar valeSSS:interface
Detach
.Ar interface
@@ -93,8 +100,8 @@
.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.
+The interface name must be different from any other network interface
+on the system.
.It Fl r Ar interface
Destroy the persistent VALE port with name
.Ar inteface .
@@ -115,10 +122,13 @@
.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.
+.Fl n ,
+this supplies the number of tx and rx rings and slots.
+The full format with four numbers gives, in order,
+the number of tx slots,
+the number of rx slots,
+the number of tx rings,
+and the number of rx rings.
The form with three numbers uses
.Ar z
for both the number of tx and the number of rx rings.
@@ -131,7 +141,7 @@
.Pp
When used in conjunction with
.Fl p
-only the first three forms are used.
+only the first three forms are valid.
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,
Index: usr.sbin/valectl/valectl.c
===================================================================
--- usr.sbin/valectl/valectl.c
+++ usr.sbin/valectl/valectl.c
@@ -25,194 +25,251 @@
/* $FreeBSD$ */
+#include <sys/param.h>
+#include <sys/ioctl.h> /* ioctl */
+#include <sys/socket.h> /* apple needs sockaddr */
+
+#include <net/if.h> /* ifreq */
#define NETMAP_WITH_LIBS
#include <net/netmap_user.h>
#include <net/netmap.h>
+#include <err.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 <inttypes.h>
#include <libgen.h> /* basename */
+#include <stdio.h>
+#include <string.h> /* strcmp */
#include <stdlib.h> /* atoi, free */
+#include <sysexits.h>
+#include <unistd.h> /* close */
+static void parse_nmr_config(const char *, struct nmreq_register *);
+static int vale_ctl(const char *, uint16_t, uint32_t, int, char *, int);
+static void usage(int);
+
static void
-parse_nmr_config(const char* conf, struct nmreq *nmr)
+parse_nmr_config(const char *conf, struct nmreq_register *nrr)
{
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);
+ if (w == NULL)
+ perror("strdup()");
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;
+ nrr->nr_tx_slots = nrr->nr_rx_slots = v;
break;
case 1:
- nmr->nr_rx_slots = v;
+ nrr->nr_rx_slots = v;
break;
case 2:
- nmr->nr_tx_rings = nmr->nr_rx_rings = v;
+ nrr->nr_tx_rings = nrr->nr_rx_rings = v;
break;
case 3:
- nmr->nr_rx_rings = v;
+ nrr->nr_rx_rings = v;
break;
default:
- D("ignored config: %s", tok);
+ warnx("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)
+vale_ctl(const char *name, uint16_t nr_reqtype, uint32_t nr_mode, int nr_arg,
+ char *nmr_config, int nr_mem_id)
{
- struct nmreq nmr;
+ struct nmreq_header nrh;
+ struct nmreq_register nrr;
+ struct nmreq_port_info_get *nrpig;
int error = 0;
int fd = open("/dev/netmap", O_RDWR);
- if (fd == -1) {
- D("Unable to open /dev/netmap");
- return -1;
- }
+ if (fd == -1)
+ err(EX_IOERR, "Unable to open /dev/netmap");
- bzero(&nmr, sizeof(nmr));
- nmr.nr_version = NETMAP_API;
+ nrh = (struct nmreq_header){
+ .nr_version = NETMAP_API,
+ .nr_reqtype = nr_reqtype,
+ };
+ nrr = (struct nmreq_register){
+ };
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;
+ strncpy(nrh.nr_name, name, sizeof(nrh.nr_name) - 1);
+ parse_nmr_config(nmr_config, &nrr);
- 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);
- }
+ switch (nr_reqtype) {
+ case NETMAP_REQ_VALE_DELIF:
+ error = ioctl(fd, NIOCCTRL, &nrh);
+ if (error == -1)
+ err(EX_OSERR, "Unable to delete %s", 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);
+ case NETMAP_REQ_VALE_NEWIF:
+ nrh.nr_body = (uintptr_t)&(struct nmreq_vale_newif){
+ .nr_tx_slots = nrr.nr_tx_slots,
+ .nr_tx_rings = nrr.nr_tx_rings,
+ .nr_rx_slots = nrr.nr_rx_slots,
+ .nr_rx_rings = nrr.nr_rx_rings,
+ .nr_mem_id = nr_mem_id
+ };
+ error = ioctl(fd, NIOCCTRL, &nrh);
+ if (error == -1)
+ err(EX_OSERR, "Unable to create %s", name);
+ printf("%s: "
+ "tx_slots=%u tx_rings=%u "
+ "rx_slots=%u rx_rings=%u "
+ "mem_id=%u\n",
+ nrh.nr_name,
+ nrr.nr_tx_slots, nrr.nr_tx_rings,
+ nrr.nr_rx_slots, nrr.nr_rx_rings,
+ nr_mem_id);
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);
+ case NETMAP_REQ_VALE_ATTACH:
+ nrr.nr_mode = nr_mode;
+ nrr.nr_mem_id = nr_mem_id;
+ nrh.nr_body = (uintptr_t)&(struct nmreq_vale_attach){
+ .reg = nrr
+ };
+ error = ioctl(fd, NIOCCTRL, &nrh);
+ if (error == -1)
+ err(EX_OSERR, "Unable to attach %s to the bridge",
+ name);
+ case NETMAP_REQ_VALE_DETACH:
+ nrh.nr_body = (uintptr_t)&(struct nmreq_vale_detach){
+ };
+ error = ioctl(fd, NIOCCTRL, &nrh);
+ if (error == -1)
+ err(EX_OSERR, "Unable to detach %s to the bridge",
+ name);
+ break;
+ case NETMAP_REQ_VALE_LIST:
+ nrh.nr_body = (uintptr_t)&(struct nmreq_vale_list){
+ };
+ if (strlen(nrh.nr_name)) {
+ /* nrh.nr_name is for bridge/port info. */
+ error = ioctl(fd, NIOCCTRL, &nrh);
+ if (error)
+ err(EX_OSERR, "Unable to obtain info for %s",
+ name);
+ else {
+ struct nmreq_vale_list *nrvl =
+ (struct nmreq_vale_list *)nrh.nr_body;
+ printf("%s bridge:%d port:%d\n", name,
+ nrvl->nr_bridge_idx, nrvl->nr_port_idx);
+ }
break;
+ } else {
+ /* Scan all of the bridges and ports. */
+ struct nmreq_vale_list *nrvl =
+ (struct nmreq_vale_list *)nrh.nr_body;
+ nrvl->nr_bridge_idx = 0;
+ nrvl->nr_port_idx = 0;
+ while (ioctl(fd, NIOCCTRL, &nrh) == 0) {
+ printf("%s bridge:%d port:%d\n",
+ nrh.nr_name,
+ nrvl->nr_bridge_idx, nrvl->nr_port_idx);
+ nrvl->nr_port_idx++;
+ nrh.nr_name[0] = '\0';
+ }
}
-
- /* 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
+ case NETMAP_REQ_VALE_POLLING_ENABLE:
+ case NETMAP_REQ_VALE_POLLING_DISABLE:
+ /* Reuse the following members in different meanings:
+ *
+ * nr_tx_slots:
+ * zero = NETMAP_POLLING_MODE_MULTI_CPU
+ * non-zero = NETMAP_POLLING_MODE_SINGLE_CPU
+ *
+ * nr_rx_slots:
+ * CPU core index. This also indicates the first queue
+ * in the case of MULTI_CPU.
+ *
+ * nr_tx_rings:
+ * (MULTI_CPU 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;
+ if (nrr.nr_tx_slots == 0) {
+ /* multi_cpu */
+ nrh.nr_body = (uintptr_t)&(struct nmreq_vale_polling){
+ .nr_mode = NETMAP_POLLING_MODE_MULTI_CPU,
+ .nr_first_cpu_id = nrr.nr_rx_slots &
+ NETMAP_RING_MASK,
+ .nr_num_polling_cpus = (nrr.nr_tx_rings == 0) ?
+ 1 : nrr.nr_tx_rings
+ };
+ } else {
+ /* single_cpu */
+ nrh.nr_body = (uintptr_t)&(struct nmreq_vale_polling){
+ .nr_mode = NETMAP_POLLING_MODE_SINGLE_CPU,
+ .nr_first_cpu_id = nrr.nr_rx_slots &
+ NETMAP_RING_MASK,
+ .nr_num_polling_cpus = 1
+ };
+ }
+ error = ioctl(fd, NIOCCTRL, &nrh);
+ if (error == -1)
+ err(EX_OSERR, "%s: Could not %s polling",
+ nrh.nr_name,
+ nr_reqtype == NETMAP_REQ_VALE_POLLING_ENABLE ?
+ "start" : "stop");
+ printf("%s: mode=%s first_cpu_id=%u polling_cpus=%u\n",
+ nrh.nr_name,
+ (nrr.nr_tx_slots == 0) ? "multi_cpu" : "single_cpu",
+ nrr.nr_rx_slots & NETMAP_RING_MASK,
+ (nrr.nr_tx_slots == 0) ? nrr.nr_tx_rings : 1);
+ break;
+ default: /* NETMAP_REQ_PORT_INFO_GET */
+ nrh.nr_reqtype = NETMAP_REQ_PORT_INFO_GET;
+ nrpig = &(struct nmreq_port_info_get){
+ .nr_mem_id = nr_mem_id
+ };
+ nrh.nr_body = (uintptr_t)nrpig;
+ error = ioctl(fd, NIOCCTRL, &nrh);
+ if (error)
+ err(EX_OSERR, "Could not get if info for %s", name);
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);
+ printf("%s: "
+ "tx_slots=%u tx_rings=%u "
+ "rx_slots=%u rx_rings=%u "
+ "mem_id=%u memsize=%jd\n",
+ nrh.nr_name,
+ nrpig->nr_tx_slots, nrpig->nr_tx_rings,
+ nrpig->nr_rx_slots, nrpig->nr_rx_rings,
+ nrpig->nr_mem_id, nrpig->nr_memsize);
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;
+ return (EX_OK);
}
static void
usage(int errcode)
{
fprintf(stderr,
- "Usage:\n"
- "valectl arguments\n"
- "\t-g interface interface name to get info\n"
+ "Usage: valectl [flags]\n"
+ "\t(no flag) list all of the bridged interfaces\n"
+ "\t-g valeSSS:PPP 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-l valeSSS:PPP list the specified interface\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-p valeSSS:PPP 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-P valeSSS:PPP stop polling\n"
"\t-m memid to use when creating a new interface\n");
exit(errcode);
}
@@ -220,61 +277,68 @@
int
main(int argc, char *argv[])
{
- int ch, nr_cmd = 0, nr_arg = 0;
- char *name = NULL, *nmr_config = NULL;
- int nr_arg2 = 0;
+ int ch, nr_arg, nr_mem_id;
+ char *name, *nmr_config;
+ uint16_t nr_reqtype;
+ uint32_t nr_mode;
+ nr_arg = 0;
+ nr_reqtype = NETMAP_REQ_PORT_INFO_GET;
+ nr_mode = 0;
+ nr_mem_id = 0;
+ name = nmr_config = NULL;
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;
+ nr_reqtype = NETMAP_REQ_VALE_DETACH;
break;
case 'a':
- nr_cmd = NETMAP_BDG_ATTACH;
+ nr_reqtype = NETMAP_REQ_VALE_ATTACH;
+ nr_mode = NR_REG_ALL_NIC;
break;
case 'h':
- nr_cmd = NETMAP_BDG_ATTACH;
- nr_arg = NETMAP_BDG_HOST;
+ nr_reqtype = NETMAP_REQ_VALE_ATTACH;
+ nr_mode = NR_REG_NIC_SW;
break;
case 'n':
- nr_cmd = NETMAP_BDG_NEWIF;
+ nr_reqtype = NETMAP_REQ_VALE_NEWIF;
break;
case 'r':
- nr_cmd = NETMAP_BDG_DELIF;
+ nr_reqtype = NETMAP_REQ_VALE_DELIF;
break;
case 'g':
- nr_cmd = 0;
+ nr_reqtype = NETMAP_REQ_PORT_INFO_GET;
break;
case 'l':
- nr_cmd = NETMAP_BDG_LIST;
+ nr_reqtype = NETMAP_REQ_VALE_LIST;
break;
case 'C':
nmr_config = strdup(optarg);
break;
case 'p':
- nr_cmd = NETMAP_BDG_POLLING_ON;
+ nr_reqtype = NETMAP_REQ_VALE_POLLING_ENABLE;
break;
case 'P':
- nr_cmd = NETMAP_BDG_POLLING_OFF;
+ nr_reqtype = NETMAP_REQ_VALE_POLLING_DISABLE;
break;
case 'm':
- nr_arg2 = atoi(optarg);
+ nr_mem_id = atoi(optarg);
break;
+ default:
+ usage(EX_USAGE);
+ break;
}
}
if (optind != argc) {
// fprintf(stderr, "optind %d argc %d\n", optind, argc);
- usage(-1);
+ usage(EX_USAGE);
}
if (argc == 1) {
- nr_cmd = NETMAP_BDG_LIST;
+ nr_reqtype = NETMAP_REQ_VALE_LIST;
name = NULL;
}
- return bdg_ctl(name, nr_cmd, nr_arg, nmr_config, nr_arg2) ? 1 : 0;
+ return vale_ctl(name, nr_reqtype, nr_mode, nr_arg, nmr_config,
+ nr_mem_id) ? 1 : 0;
}

File Metadata

Mime Type
text/plain
Expires
Sun, Feb 9, 10:48 AM (15 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16551589
Default Alt Text
D26161.diff (16 KB)

Event Timeline