Author: vmaffione
Date: Sun Nov 22 10:02:56 2020
New Revision: 367935
URL: https://svnweb.freebsd.org/changeset/base/367935

Log:
  netmap: valectl: switch to libnetmap
  
  Use the newer libnetmap (included in base) rather than the older
  nm_open()/nm_close() defined in netmap_user.h
  
  MFC after:      3 days

Modified:
  head/usr.sbin/valectl/Makefile
  head/usr.sbin/valectl/valectl.c

Modified: head/usr.sbin/valectl/Makefile
==============================================================================
--- head/usr.sbin/valectl/Makefile      Sun Nov 22 09:38:01 2020        
(r367934)
+++ head/usr.sbin/valectl/Makefile      Sun Nov 22 10:02:56 2020        
(r367935)
@@ -5,4 +5,6 @@ MAN=    valectl.8
 
 WARNS?=        3
 
+LIBADD=        netmap
+
 .include <bsd.prog.mk>

Modified: head/usr.sbin/valectl/valectl.c
==============================================================================
--- head/usr.sbin/valectl/valectl.c     Sun Nov 22 09:38:01 2020        
(r367934)
+++ head/usr.sbin/valectl/valectl.c     Sun Nov 22 10:02:56 2020        
(r367935)
@@ -25,9 +25,8 @@
 
 /* $FreeBSD$ */
 
-#define NETMAP_WITH_LIBS
-#include <net/netmap_user.h>
-#include <net/netmap.h>
+#define LIBNETMAP_NOTHREADSAFE
+#include <libnetmap.h>
 
 #include <errno.h>
 #include <stdio.h>
@@ -42,14 +41,58 @@
 #include <libgen.h>    /* basename */
 #include <stdlib.h>    /* atoi, free */
 
+int verbose;
+
+struct args {
+       const char *name;
+       const char *config;
+       const char *mem_id;
+
+       uint16_t nr_reqtype;
+       uint32_t nr_mode;
+};
+
 static void
-parse_nmr_config(const char* conf, struct nmreq *nmr)
+dump_port_info(struct nmreq_port_info_get *v)
 {
+       printf("memsize:    %"PRIu64"\n", v->nr_memsize);
+       printf("tx_slots:   %"PRIu32"\n", v->nr_tx_slots);
+       printf("rx_slots:   %"PRIu32"\n", v->nr_rx_slots);
+       printf("tx_rings:   %"PRIu16"\n", v->nr_tx_rings);
+       printf("rx_rings    %"PRIu16"\n", v->nr_rx_rings);
+       printf("mem_id:     %"PRIu16"\n", v->nr_mem_id);
+}
+
+static void
+dump_newif(struct nmreq_vale_newif *v)
+{
+       printf("tx_slots:   %"PRIu32"\n", v->nr_tx_slots);
+       printf("rx_slots:   %"PRIu32"\n", v->nr_rx_slots);
+       printf("tx_rings:   %"PRIu16"\n", v->nr_tx_rings);
+       printf("rx_ring:    %"PRIu16"\n", v->nr_rx_rings);
+       printf("mem_id:     %"PRIu16"\n", v->nr_mem_id);
+}
+
+static void
+dump_vale_list(struct nmreq_vale_list *v)
+{
+       printf("bridge_idx: %"PRIu16"\n", v->nr_bridge_idx);
+       printf("port_idx:   %"PRIu16"\n", v->nr_port_idx);
+}
+
+
+static void
+parse_ring_config(const char* conf,
+               uint32_t *nr_tx_slots,
+               uint32_t *nr_rx_slots,
+               uint16_t *nr_tx_rings,
+               uint16_t *nr_rx_rings)
+{
        char *w, *tok;
        int i, v;
 
-       nmr->nr_tx_rings = nmr->nr_rx_rings = 0;
-       nmr->nr_tx_slots = nmr->nr_rx_slots = 0;
+       *nr_tx_rings = *nr_rx_rings = 0;
+       *nr_tx_slots = *nr_rx_slots = 0;
        if (conf == NULL || ! *conf)
                return;
        w = strdup(conf);
@@ -57,137 +100,235 @@ parse_nmr_config(const char* conf, struct nmreq *nmr)
                v = atoi(tok);
                switch (i) {
                case 0:
-                       nmr->nr_tx_slots = nmr->nr_rx_slots = v;
+                       *nr_tx_slots = *nr_rx_slots = v;
                        break;
                case 1:
-                       nmr->nr_rx_slots = v;
+                       *nr_rx_slots = v;
                        break;
                case 2:
-                       nmr->nr_tx_rings = nmr->nr_rx_rings = v;
+                       *nr_tx_rings = *nr_rx_rings = v;
                        break;
                case 3:
-                       nmr->nr_rx_rings = v;
+                       *nr_rx_rings = v;
                        break;
                default:
-                       D("ignored config: %s", tok);
+                       fprintf(stderr, "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);
+       ND("txr %d txd %d rxr %d rxd %d",
+                       *nr_tx_rings, *nr_tx_slots,
+                       *nr_rx_rings, *nr_rx_slots);
        free(w);
 }
 
 static int
-bdg_ctl(const char *name, int nr_cmd, int nr_arg, char *nmr_config, int 
nr_arg2)
+parse_poll_config(const char *conf, struct nmreq_vale_polling *v)
 {
-       struct nmreq nmr;
-       int error = 0;
-       int fd = open("/dev/netmap", O_RDWR);
+       char *w, *tok;
+       int i, p;
 
-       if (fd == -1) {
-               D("Unable to open /dev/netmap");
+       if (conf == NULL || ! *conf) {
+               fprintf(stderr, "invalid null/empty config\n");
                return -1;
        }
+       w = strdup(conf);
+       for (i = 0, tok = strtok(w, ","); tok; i++, tok = strtok(NULL, ",")) {
+               p = atoi(tok);
+               switch (i) {
+               case 0:
+                       v->nr_mode = p ? NETMAP_POLLING_MODE_MULTI_CPU :
+                               NETMAP_POLLING_MODE_SINGLE_CPU;
+                       break;
+               case 1:
+                       v->nr_first_cpu_id = p;
+                       break;
+               case 2:
+                       if (v->nr_mode != NETMAP_POLLING_MODE_MULTI_CPU) {
+                               fprintf(stderr, "too many numbers in '%s'\n", 
conf);
+                               return -1;
+                       }
+                       v->nr_num_polling_cpus = p;
+                       break;
+               case 3:
+                       fprintf(stderr, "too many numbers in '%s'\n", conf);
+                       return -1;
+               }
+       }
+       free(w);
+       return 0;
+}
 
-       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;
+static int32_t
+parse_mem_id(const char *mem_id)
+{
+       int32_t id;
 
-       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);
+       if (mem_id == NULL)
+               return 0;
+       if (isdigit(*mem_id))
+               return atoi(mem_id);
+       id = nmreq_get_mem_id(&mem_id, nmctx_get());
+       if (id == 0) {
+               fprintf(stderr, "invalid format in '-m %s' (missing 
'netmap:'?)\n", mem_id);
+               return -1;
+       }
+       return id;
+}
+
+static int
+list_all(int fd, struct nmreq_header *hdr)
+{
+       int error;
+       struct nmreq_vale_list *vale_list =
+               (struct nmreq_vale_list *)hdr->nr_body;
+
+       for (;;) {
+               hdr->nr_name[0] = '\0';
+               error = ioctl(fd, NIOCCTRL, hdr);
+               if (error < 0) {
+                       if (errno == ENOENT)
+                               break;
+
+                       fprintf(stderr, "failed to list all: %s\n", 
strerror(errno));
+                       return 1;
                }
+               printf("%s bridge_idx %"PRIu16" port_idx %"PRIu32"\n", 
hdr->nr_name,
+                               vale_list->nr_bridge_idx, 
vale_list->nr_port_idx);
+               vale_list->nr_port_idx++;
+       }
+       return 1;
+}
+
+static int
+bdg_ctl(struct args *a)
+{
+       struct nmreq_header hdr;
+       struct nmreq_vale_attach   vale_attach;
+       struct nmreq_vale_detach   vale_detach;
+       struct nmreq_vale_newif    vale_newif;
+       struct nmreq_vale_list     vale_list;
+       struct nmreq_vale_polling  vale_polling;
+       struct nmreq_port_info_get port_info_get;
+       int error = 0;
+       int fd;
+       int32_t mem_id;
+       const char *action = NULL;
+
+       fd = open("/dev/netmap", O_RDWR);
+       if (fd == -1) {
+               perror("/dev/netmap");
+               return 1;
+       }
+
+       bzero(&hdr, sizeof(hdr));
+       hdr.nr_version = NETMAP_API;
+       if (a->name != NULL) { /* might be NULL */
+               strncpy(hdr.nr_name, a->name, NETMAP_REQ_IFNAMSIZ - 1);
+               hdr.nr_name[NETMAP_REQ_IFNAMSIZ - 1] = '\0';
+       }
+       hdr.nr_reqtype = a->nr_reqtype;
+
+       switch (a->nr_reqtype) {
+       case NETMAP_REQ_VALE_DELIF:
+               /* no body */
+               action = "remove";
                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;
+
+       case NETMAP_REQ_VALE_NEWIF:
+               memset(&vale_newif, 0, sizeof(vale_newif));
+               hdr.nr_body = (uintptr_t)&vale_newif;
+               parse_ring_config(a->config,
+                               &vale_newif.nr_tx_slots,
+                               &vale_newif.nr_rx_slots,
+                               &vale_newif.nr_tx_rings,
+                               &vale_newif.nr_rx_rings);
+               mem_id = parse_mem_id(a->mem_id);
+               if (mem_id < 0)
+                       return 1;
+               vale_newif.nr_mem_id = mem_id;
+               action = "create";
+               break;
+
+       case NETMAP_REQ_VALE_ATTACH:
+               memset(&vale_attach, 0, sizeof(vale_attach));
+               hdr.nr_body = (uintptr_t)&vale_attach;
+               vale_attach.reg.nr_mode = a->nr_mode;
+               parse_ring_config(a->config,
+                               &vale_attach.reg.nr_tx_slots,
+                               &vale_attach.reg.nr_rx_slots,
+                               &vale_attach.reg.nr_tx_rings,
+                               &vale_attach.reg.nr_rx_rings);
+               mem_id = parse_mem_id(a->mem_id);
+               if (mem_id < 0)
+                       return 1;
+               vale_attach.reg.nr_mem_id = mem_id;
+               action = "attach";
+               break;
+
+       case NETMAP_REQ_VALE_DETACH:
+               memset(&vale_detach, 0, sizeof(vale_detach));
+               hdr.nr_body = (uintptr_t)&vale_detach;
+               action = "detach";
+               break;
+
+       case NETMAP_REQ_VALE_LIST:
+               memset(&vale_list, 0, sizeof(vale_list));
+               hdr.nr_body = (uintptr_t)&vale_list;
+               if (a->name == NULL) {
+                       return list_all(fd, &hdr);
                }
-               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);
+               action = "list";
                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;
+       case NETMAP_REQ_VALE_POLLING_ENABLE:
+               action = "enable polling on";
+               /* fall through */
+       case NETMAP_REQ_VALE_POLLING_DISABLE:
+               memset(&vale_polling, 0, sizeof(vale_polling));
+               hdr.nr_body = (uintptr_t)&vale_polling;
+               parse_poll_config(a->config, &vale_polling);
+               if (action == NULL)
+                       action ="disable polling on";
+               break;
+
+       case NETMAP_REQ_PORT_INFO_GET:
+               memset(&port_info_get, 0, sizeof(port_info_get));
+               hdr.nr_body = (uintptr_t)&port_info_get;
+               action = "obtain info for";
+               break;
+       }
+       error = ioctl(fd, NIOCCTRL, &hdr);
+       if (error < 0) {
+               fprintf(stderr, "failed to %s %s: %s\n",
+                               action, a->name, strerror(errno));
+               return 1;
+       }
+       switch (hdr.nr_reqtype) {
+       case NETMAP_REQ_VALE_NEWIF:
+               if (verbose) {
+                       dump_newif(&vale_newif);
                }
+               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';
+       case NETMAP_REQ_VALE_ATTACH:
+               if (verbose) {
+                       printf("port_index: %"PRIu32"\n", 
vale_attach.port_index);
                }
+               break;
 
+       case NETMAP_REQ_VALE_DETACH:
+               if (verbose) {
+                       printf("port_index: %"PRIu32"\n", 
vale_detach.port_index);
+               }
                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);
+       case NETMAP_REQ_VALE_LIST:
+               dump_vale_list(&vale_list);
                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);
+       case NETMAP_REQ_PORT_INFO_GET:
+               dump_port_info(&port_info_get);
                break;
        }
        close(fd);
@@ -199,82 +340,106 @@ usage(int errcode)
 {
        fprintf(stderr,
            "Usage:\n"
-           "valectl arguments\n"
+           "vale-ctl [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-l vale-port     show bridge and port indices\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");
+           "\t-m memid to use when creating a new interface\n"
+           "\t-v increase verbosity\n"
+           "with no arguments: list all existing vale ports\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;
+       int ch;
+       struct args a = {
+               .name = NULL,
+               .config = NULL,
+               .mem_id = NULL,
+               .nr_reqtype = 0,
+               .nr_mode = NR_REG_ALL_NIC,
+       };
 
-       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 */
+       while ((ch = getopt(argc, argv, "d:a:h:g:l:n:r:C:p:P:m:v")) != -1) {
                switch (ch) {
                default:
                        fprintf(stderr, "bad option %c %s", ch, optarg);
-                       usage(-1);
+                       usage(1);
                        break;
                case 'd':
-                       nr_cmd = NETMAP_BDG_DETACH;
+                       a.nr_reqtype = NETMAP_REQ_VALE_DETACH;
+                       a.name = optarg;
                        break;
                case 'a':
-                       nr_cmd = NETMAP_BDG_ATTACH;
+                       a.nr_reqtype = NETMAP_REQ_VALE_ATTACH;
+                       a.nr_mode = NR_REG_ALL_NIC;
+                       a.name = optarg;
                        break;
                case 'h':
-                       nr_cmd = NETMAP_BDG_ATTACH;
-                       nr_arg = NETMAP_BDG_HOST;
+                       a.nr_reqtype = NETMAP_REQ_VALE_ATTACH;
+                       a.nr_mode = NR_REG_NIC_SW;
+                       a.name = optarg;
                        break;
                case 'n':
-                       nr_cmd = NETMAP_BDG_NEWIF;
+                       a.nr_reqtype = NETMAP_REQ_VALE_NEWIF;
+                       a.name = optarg;
                        break;
                case 'r':
-                       nr_cmd = NETMAP_BDG_DELIF;
+                       a.nr_reqtype = NETMAP_REQ_VALE_DELIF;
+                       a.name = optarg;
                        break;
                case 'g':
-                       nr_cmd = 0;
+                       a.nr_reqtype = NETMAP_REQ_PORT_INFO_GET;
+                       a.name = optarg;
                        break;
                case 'l':
-                       nr_cmd = NETMAP_BDG_LIST;
+                       a.nr_reqtype = NETMAP_REQ_VALE_LIST;
+                       a.name = optarg;
+                       if (strncmp(a.name, NM_BDG_NAME, strlen(NM_BDG_NAME))) {
+                               fprintf(stderr, "invalid vale port name: 
'%s'\n", a.name);
+                               usage(1);
+                       }
                        break;
                case 'C':
-                       nmr_config = strdup(optarg);
+                       a.config = optarg;
                        break;
                case 'p':
-                       nr_cmd = NETMAP_BDG_POLLING_ON;
+                       a.nr_reqtype = NETMAP_REQ_VALE_POLLING_ENABLE;
+                       a.name = optarg;
                        break;
                case 'P':
-                       nr_cmd = NETMAP_BDG_POLLING_OFF;
+                       a.nr_reqtype = NETMAP_REQ_VALE_POLLING_DISABLE;
+                       a.name = optarg;
                        break;
                case 'm':
-                       nr_arg2 = atoi(optarg);
+                       a.mem_id = optarg;
                        break;
+               case 'v':
+                       verbose++;
+                       break;
                }
        }
        if (optind != argc) {
-               // fprintf(stderr, "optind %d argc %d\n", optind, argc);
-               usage(-1);
+               usage(1);
        }
        if (argc == 1) {
-               nr_cmd = NETMAP_BDG_LIST;
-               name = NULL;
+               a.nr_reqtype = NETMAP_REQ_VALE_LIST;
+               a.name = NULL;
        }
-       return bdg_ctl(name, nr_cmd, nr_arg, nmr_config, nr_arg2) ? 1 : 0;
+       if (!a.nr_reqtype) {
+               usage(1);
+       }
+       return bdg_ctl(&a);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to