From owner-svn-src-all@freebsd.org Sun Nov 22 09:20:09 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 517A22EA911; Sun, 22 Nov 2020 09:20:09 +0000 (UTC) (envelope-from vmaffione@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Cf4WF1qkQz4mNF; Sun, 22 Nov 2020 09:20:09 +0000 (UTC) (envelope-from vmaffione@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 319A7179EB; Sun, 22 Nov 2020 09:20:09 +0000 (UTC) (envelope-from vmaffione@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0AM9K9PL008141; Sun, 22 Nov 2020 09:20:09 GMT (envelope-from vmaffione@FreeBSD.org) Received: (from vmaffione@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0AM9K9E5008140; Sun, 22 Nov 2020 09:20:09 GMT (envelope-from vmaffione@FreeBSD.org) Message-Id: <202011220920.0AM9K9E5008140@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: vmaffione set sender to vmaffione@FreeBSD.org using -f From: Vincenzo Maffione Date: Sun, 22 Nov 2020 09:20:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r367932 - head/tools/tools/netmap X-SVN-Group: head X-SVN-Commit-Author: vmaffione X-SVN-Commit-Paths: head/tools/tools/netmap X-SVN-Commit-Revision: 367932 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 22 Nov 2020 09:20:09 -0000 Author: vmaffione Date: Sun Nov 22 09:20:08 2020 New Revision: 367932 URL: https://svnweb.freebsd.org/changeset/base/367932 Log: netmap: pkt-gen: switch to libnetmap Use the newer libnetmap (included in base) rather than the older nm_open()/nm_close() defined in netmap_user.h Modified: head/tools/tools/netmap/pkt-gen.c Modified: head/tools/tools/netmap/pkt-gen.c ============================================================================== --- head/tools/tools/netmap/pkt-gen.c Sun Nov 22 09:10:12 2020 (r367931) +++ head/tools/tools/netmap/pkt-gen.c Sun Nov 22 09:20:08 2020 (r367932) @@ -38,36 +38,40 @@ */ #define _GNU_SOURCE /* for CPU_SET() */ -#include -#define NETMAP_WITH_LIBS -#include - -#include // isprint() -#include // sysconf() -#include #include /* ntohs */ -#ifndef _WIN32 -#include /* sysctl */ -#endif +#include +#include // isprint() +#include +#include #include /* getifaddrs */ +#include +#include #include #include #include -#include #include +#include +#ifndef NO_PCAP +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(_WIN32) && !defined(linux) +#include /* sysctl */ +#endif +#include +#include // sysconf() #ifdef linux #define IPV6_VERSION 0x60 #define IPV6_DEFHLIM 64 #endif -#include -#include -#include - -#ifndef NO_PCAP -#include -#endif - #include "ctrs.h" static void usage(int); @@ -236,7 +240,8 @@ struct mac_range { }; /* ifname can be netmap:foo-xxxx */ -#define MAX_IFNAMELEN 64 /* our buffer for ifname */ +#define MAX_IFNAMELEN 512 /* our buffer for ifname */ +//#define MAX_PKTSIZE 1536 #define MAX_PKTSIZE MAX_BODYSIZE /* XXX: + IP_HDR + ETH_HDR */ /* compact timestamp to fit into 60 byte packet. (enough to obtain RTT) */ @@ -288,7 +293,8 @@ struct glob_arg { int affinity; int main_fd; - struct nm_desc *nmd; + struct nmport_d *nmd; + uint32_t orig_mode; int report_interval; /* milliseconds between prints */ void *(*td_body)(void *); int td_type; @@ -322,7 +328,7 @@ struct targ { int completed; int cancel; int fd; - struct nm_desc *nmd; + struct nmport_d *nmd; /* these ought to be volatile, but they are * only sampled and errors should not accumulate */ @@ -515,17 +521,21 @@ extract_mac_range(struct mac_range *r) static int get_if_mtu(const struct glob_arg *g) { - char ifname[IFNAMSIZ]; struct ifreq ifreq; int s, ret; + const char *ifname = g->nmd->hdr.nr_name; + size_t len; - if (!strncmp(g->ifname, "netmap:", 7) && !strchr(g->ifname, '{') - && !strchr(g->ifname, '}')) { - /* Parse the interface name and ask the kernel for the - * MTU value. */ - strncpy(ifname, g->ifname+7, IFNAMSIZ-1); - ifname[strcspn(ifname, "-*^{}/@")] = '\0'; + if (!strncmp(g->ifname, "netmap:", 7) && !strchr(ifname, '{') + && !strchr(ifname, '}')) { + len = strlen(ifname); + + if (len > IFNAMSIZ) { + D("'%s' too long, cannot ask for MTU", ifname); + return -1; + } + s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { D("socket() failed: %s", strerror(errno)); @@ -533,13 +543,15 @@ get_if_mtu(const struct glob_arg *g) } memset(&ifreq, 0, sizeof(ifreq)); - strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); + memcpy(ifreq.ifr_name, ifname, len); ret = ioctl(s, SIOCGIFMTU, &ifreq); if (ret) { D("ioctl(SIOCGIFMTU) failed: %s", strerror(errno)); } + close(s); + return ifreq.ifr_mtu; } @@ -620,7 +632,7 @@ system_ncpus(void) * and #rx-rings. */ static int -parse_nmr_config(const char* conf, struct nmreq *nmr) +parse_nmr_config(const char* conf, struct nmreq_register *nmr) { char *w, *tok; int i, v; @@ -654,9 +666,7 @@ parse_nmr_config(const char* conf, struct nmreq *nmr) nmr->nr_tx_rings, nmr->nr_tx_slots, nmr->nr_rx_rings, nmr->nr_rx_slots); free(w); - return (nmr->nr_tx_rings || nmr->nr_tx_slots || - nmr->nr_rx_rings || nmr->nr_rx_slots) ? - NM_OPEN_RING_CFG : 0; + return 0; } @@ -1108,20 +1118,22 @@ initialize_packet(struct targ *targ) static void get_vnet_hdr_len(struct glob_arg *g) { - struct nmreq req; + struct nmreq_header hdr; + struct nmreq_port_hdr ph; int err; - memset(&req, 0, sizeof(req)); - bcopy(g->nmd->req.nr_name, req.nr_name, sizeof(req.nr_name)); - req.nr_version = NETMAP_API; - req.nr_cmd = NETMAP_VNET_HDR_GET; - err = ioctl(g->main_fd, NIOCREGIF, &req); + hdr = g->nmd->hdr; /* copy name and version */ + hdr.nr_reqtype = NETMAP_REQ_PORT_HDR_GET; + hdr.nr_options = 0; + memset(&ph, 0, sizeof(ph)); + hdr.nr_body = (uintptr_t)&ph; + err = ioctl(g->main_fd, NIOCCTRL, &hdr); if (err) { D("Unable to get virtio-net header length"); return; } - g->virt_header = req.nr_arg1; + g->virt_header = ph.nr_hdr_len; if (g->virt_header) { D("Port requires virtio-net header, length = %d", g->virt_header); @@ -1132,17 +1144,18 @@ static void set_vnet_hdr_len(struct glob_arg *g) { int err, l = g->virt_header; - struct nmreq req; + struct nmreq_header hdr; + struct nmreq_port_hdr ph; if (l == 0) return; - memset(&req, 0, sizeof(req)); - bcopy(g->nmd->req.nr_name, req.nr_name, sizeof(req.nr_name)); - req.nr_version = NETMAP_API; - req.nr_cmd = NETMAP_BDG_VNET_HDR; - req.nr_arg1 = l; - err = ioctl(g->main_fd, NIOCREGIF, &req); + hdr = g->nmd->hdr; /* copy name and version */ + hdr.nr_reqtype = NETMAP_REQ_PORT_HDR_SET; + hdr.nr_options = 0; + memset(&ph, 0, sizeof(ph)); + hdr.nr_body = (uintptr_t)&ph; + err = ioctl(g->main_fd, NIOCCTRL, &hdr); if (err) { D("Unable to set virtio-net header length %d", l); } @@ -2480,7 +2493,7 @@ usage(int errcode) exit(errcode); } -static void +static int start_threads(struct glob_arg *g) { int i; @@ -2500,31 +2513,43 @@ start_threads(struct glob_arg *g) { memcpy(t->seed, &seed, sizeof(t->seed)); if (g->dev_type == DEV_NETMAP) { - struct nm_desc nmd = *g->nmd; /* copy, we overwrite ringid */ - uint64_t nmd_flags = 0; - nmd.self = &nmd; + int m = -1; + /* + * if the user wants both HW and SW rings, we need to + * know when to switch from NR_REG_ONE_NIC to NR_REG_ONE_SW + */ + if (g->orig_mode == NR_REG_NIC_SW) { + m = (g->td_type == TD_TYPE_RECEIVER ? + g->nmd->reg.nr_rx_rings : + g->nmd->reg.nr_tx_rings); + } + if (i > 0) { + int j; /* the first thread uses the fd opened by the main * thread, the other threads re-open /dev/netmap */ - if (g->nthreads > 1) { - nmd.req.nr_flags = - g->nmd->req.nr_flags & ~NR_REG_MASK; - nmd.req.nr_flags |= NR_REG_ONE_NIC; - nmd.req.nr_ringid = i; + t->nmd = nmport_clone(g->nmd); + if (t->nmd == NULL) + return -1; + + j = i; + if (m > 0 && j >= m) { + /* switch to the software rings */ + t->nmd->reg.nr_mode = NR_REG_ONE_SW; + j -= m; } + t->nmd->reg.nr_ringid = j & NETMAP_RING_MASK; /* Only touch one of the rings (rx is already ok) */ if (g->td_type == TD_TYPE_RECEIVER) - nmd_flags |= NETMAP_NO_TX_POLL; + t->nmd->reg.nr_flags |= NETMAP_NO_TX_POLL; /* register interface. Override ifname and ringid etc. */ - t->nmd = nm_open(t->g->ifname, NULL, nmd_flags | - NM_OPEN_IFNAME | NM_OPEN_NO_MMAP, &nmd); - if (t->nmd == NULL) { - D("Unable to open %s: %s", - t->g->ifname, strerror(errno)); - continue; + if (nmport_open_desc(t->nmd) < 0) { + nmport_undo_prepare(t->nmd); + t->nmd = NULL; + return -1; } } else { t->nmd = g->nmd; @@ -2556,6 +2581,7 @@ start_threads(struct glob_arg *g) { t->used = 0; } } + return 0; } static void @@ -2655,7 +2681,7 @@ main_thread(struct glob_arg *g) if (targs[i].used) pthread_join(targs[i].thread, NULL); /* blocking */ if (g->dev_type == DEV_NETMAP) { - nm_close(targs[i].nmd); + nmport_close(targs[i].nmd); targs[i].nmd = NULL; } else { close(targs[i].fd); @@ -3078,21 +3104,14 @@ main(int arc, char **argv) } else if (g.dummy_send) { /* but DEV_NETMAP */ D("using a dummy send routine"); } else { - struct nm_desc base_nmd; - char errmsg[MAXERRMSG]; - u_int flags; + g.nmd = nmport_prepare(g.ifname); + if (g.nmd == NULL) + goto out; - bzero(&base_nmd, sizeof(base_nmd)); + parse_nmr_config(g.nmr_config, &g.nmd->reg); - parse_nmr_config(g.nmr_config, &base_nmd.req); + g.nmd->reg.nr_flags |= NR_ACCEPT_VNET_HDR; - base_nmd.req.nr_flags |= NR_ACCEPT_VNET_HDR; - - if (nm_parse(g.ifname, &base_nmd, errmsg) < 0) { - D("Invalid name '%s': %s", g.ifname, errmsg); - goto out; - } - /* * Open the netmap device using nm_open(). * @@ -3100,20 +3119,25 @@ main(int arc, char **argv) * which in turn may take some time for the PHY to * reconfigure. We do the open here to have time to reset. */ - flags = NM_OPEN_IFNAME | NM_OPEN_ARG1 | NM_OPEN_ARG2 | - NM_OPEN_ARG3 | NM_OPEN_RING_CFG; + g.orig_mode = g.nmd->reg.nr_mode; if (g.nthreads > 1) { - base_nmd.req.nr_flags &= ~NR_REG_MASK; - base_nmd.req.nr_flags |= NR_REG_ONE_NIC; - base_nmd.req.nr_ringid = 0; + switch (g.orig_mode) { + case NR_REG_ALL_NIC: + case NR_REG_NIC_SW: + g.nmd->reg.nr_mode = NR_REG_ONE_NIC; + break; + case NR_REG_SW: + g.nmd->reg.nr_mode = NR_REG_ONE_SW; + break; + default: + break; + } + g.nmd->reg.nr_ringid = 0; } - g.nmd = nm_open(g.ifname, NULL, flags, &base_nmd); - if (g.nmd == NULL) { - D("Unable to open %s: %s", g.ifname, strerror(errno)); + if (nmport_open_desc(g.nmd) < 0) goto out; - } g.main_fd = g.nmd->fd; - D("mapped %luKB at %p", (unsigned long)(g.nmd->req.nr_memsize>>10), + ND("mapped %luKB at %p", (unsigned long)(g.nmd->req.nr_memsize>>10), g.nmd->mem); if (g.virt_header) { @@ -3128,9 +3152,9 @@ main(int arc, char **argv) /* get num of queues in tx or rx */ if (g.td_type == TD_TYPE_SENDER) - devqueues = g.nmd->req.nr_tx_rings; + devqueues = g.nmd->reg.nr_tx_rings + g.nmd->reg.nr_host_tx_rings; else - devqueues = g.nmd->req.nr_rx_rings; + devqueues = g.nmd->reg.nr_rx_rings + g.nmd->reg.nr_host_rx_rings; /* validate provided nthreads. */ if (g.nthreads < 1 || g.nthreads > devqueues) { @@ -3150,17 +3174,17 @@ main(int arc, char **argv) if (verbose) { struct netmap_if *nifp = g.nmd->nifp; - struct nmreq *req = &g.nmd->req; + struct nmreq_register *req = &g.nmd->reg; - D("nifp at offset %d, %d tx %d rx region %d", + D("nifp at offset %"PRIu64", %d tx %d rx region %d", req->nr_offset, req->nr_tx_rings, req->nr_rx_rings, - req->nr_arg2); - for (i = 0; i <= req->nr_tx_rings; i++) { + req->nr_mem_id); + for (i = 0; i < req->nr_tx_rings + req->nr_host_tx_rings; i++) { struct netmap_ring *ring = NETMAP_TXRING(nifp, i); D(" TX%d at 0x%p slots %d", i, (void *)((char *)ring - (char *)nifp), ring->num_slots); } - for (i = 0; i <= req->nr_rx_rings; i++) { + for (i = 0; i < req->nr_rx_rings + req->nr_host_rx_rings; i++) { struct netmap_ring *ring = NETMAP_RXRING(nifp, i); D(" RX%d at 0x%p slots %d", i, (void *)((char *)ring - (char *)nifp), ring->num_slots); @@ -3230,7 +3254,8 @@ out: if (pthread_sigmask(SIG_BLOCK, &ss, NULL) < 0) { D("failed to block SIGINT: %s", strerror(errno)); } - start_threads(&g); + if (start_threads(&g) < 0) + return 1; /* Install the handler and re-enable SIGINT for the main thread */ memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigint_h;