Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109693915
D26161.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
D26161.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D26161: valectl(8) patch to use the new netmap API
Attached
Detach File
Event Timeline
Log In to Comment