Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Oct 2018 15:34:43 +0000 (UTC)
From:      Vincenzo Maffione <vmaffione@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r339659 - in head: share/man/man4 tools/tools/netmap
Message-ID:  <201810231534.w9NFYhhj093530@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: vmaffione
Date: Tue Oct 23 15:34:43 2018
New Revision: 339659
URL: https://svnweb.freebsd.org/changeset/base/339659

Log:
  netmap: add man page for the bridge program
  
  Added bridge(8).
  Also, minor fixes to the netmap "bridge" application:
   - indentation fixes and code cleanup
   - better usage description
   - better processing of netmap flags
  
  Reviewed by:	0mp
  Approved by:	gnn (mentor)
  MFC after:	3 days
  Differential Revision:	https://reviews.freebsd.org/D17664

Added:
  head/tools/tools/netmap/bridge.8   (contents, props changed)
Modified:
  head/share/man/man4/netmap.4
  head/tools/tools/netmap/bridge.c
  head/tools/tools/netmap/pkt-gen.8

Modified: head/share/man/man4/netmap.4
==============================================================================
--- head/share/man/man4/netmap.4	Tue Oct 23 14:44:32 2018	(r339658)
+++ head/share/man/man4/netmap.4	Tue Oct 23 15:34:43 2018	(r339659)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 2, 2017
+.Dd October 23, 2018
 .Dt NETMAP 4
 .Os
 .Sh NAME
@@ -1073,6 +1073,9 @@ Other
 clients attached to the same switch can now communicate
 with the network card or the host.
 .Sh SEE ALSO
+.Xr pkt-gen 8 ,
+.Xr bridge 8
+.Pp
 .Pa http://info.iet.unipi.it/~luigi/netmap/
 .Pp
 Luigi Rizzo, Revisiting network I/O APIs: the netmap framework,

Added: head/tools/tools/netmap/bridge.8
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/tools/tools/netmap/bridge.8	Tue Oct 23 15:34:43 2018	(r339659)
@@ -0,0 +1,82 @@
+.\" Copyright (c) 2016 Luigi Rizzo, Universita` di Pisa
+.\"
+.\" 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 23, 2018
+.Dt BRIDGE 8
+.Os
+.Sh NAME
+.Nm bridge
+.Nd netmap client to bridge two netmap ports
+.Sh SYNOPSIS
+.Bk -words
+.Bl -tag -width "bridge"
+.It Nm
+.Op Fl i Ar port
+.Op Fl b Ar batch size
+.Op Fl w Ar wait-link
+.Op Fl v
+.Op Fl c
+.El
+.Ek
+.Sh DESCRIPTION
+.Nm
+is a simple netmap application that bridges packets between two netmap ports.
+If the two netmap ports use the same netmap memory region
+.Nm
+forwards packets without copying the packets payload (zero-copy mode), unless
+explicitly prevented by the
+.Fl c
+flag.
+.Bl -tag -width Ds
+.It Fl i Ar port
+Name of the netmap port.
+It can be supplied up to two times to identify the ports that must be bridged.
+Any netmap port type (physical interface, VALE switch, pipe, monitor port...)
+can be used.
+If the option is supplied only once, then it must be for a physical interface and, in that case,
+.Nm
+will bridge the port and the host stack.
+.It Fl b Ar batch-size
+Maximum number of packets to send in one operation.
+.It Fl w Ar wait-link
+indicates the number of seconds to wait before transmitting.
+It defaults to 2, and may be useful when talking to physical
+ports to let link negotiation complete before starting transmission.
+.It Fl v
+Enable verbose mode
+.It Fl c
+Disable zero-copy mode.
+.El
+.Sh SEE ALSO
+.Xr netmap 4 ,
+.Xr pkt-gen 8
+.Sh AUTHORS
+.An -nosplit
+.Nm
+has been written by
+.An Luigi Rizzo
+and
+.An Matteo Landi
+at the Universita` di Pisa, Italy.

Modified: head/tools/tools/netmap/bridge.c
==============================================================================
--- head/tools/tools/netmap/bridge.c	Tue Oct 23 14:44:32 2018	(r339658)
+++ head/tools/tools/netmap/bridge.c	Tue Oct 23 15:34:43 2018	(r339659)
@@ -34,18 +34,18 @@ sigint_h(int sig)
 int
 pkt_queued(struct nm_desc *d, int tx)
 {
-        u_int i, tot = 0;
+	u_int i, tot = 0;
 
-        if (tx) {
-                for (i = d->first_tx_ring; i <= d->last_tx_ring; i++) {
-                        tot += nm_ring_space(NETMAP_TXRING(d->nifp, i));
-                }
-        } else {
-                for (i = d->first_rx_ring; i <= d->last_rx_ring; i++) {
-                        tot += nm_ring_space(NETMAP_RXRING(d->nifp, i));
-                }
-        }
-        return tot;
+	if (tx) {
+		for (i = d->first_tx_ring; i <= d->last_tx_ring; i++) {
+			tot += nm_ring_space(NETMAP_TXRING(d->nifp, i));
+		}
+	} else {
+		for (i = d->first_rx_ring; i <= d->last_rx_ring; i++) {
+			tot += nm_ring_space(NETMAP_RXRING(d->nifp, i));
+		}
+	}
+	return tot;
 }
 
 /*
@@ -76,13 +76,13 @@ process_rings(struct netmap_ring *rxring, struct netma
 
 		/* swap packets */
 		if (ts->buf_idx < 2 || rs->buf_idx < 2) {
-			D("wrong index rx[%d] = %d  -> tx[%d] = %d",
+			RD(5, "wrong index rx[%d] = %d  -> tx[%d] = %d",
 				j, rs->buf_idx, k, ts->buf_idx);
 			sleep(2);
 		}
 		/* copy the packet length. */
-		if (rs->len > 2048) {
-			D("wrong len %d rx[%d] -> tx[%d]", rs->len, j, k);
+		if (rs->len > rxring->nr_buf_size) {
+			RD(5, "wrong len %d rx[%d] -> tx[%d]", rs->len, j, k);
 			rs->len = 0;
 		} else if (verbose > 1) {
 			D("%s send len %d rx[%d] -> tx[%d]", msg, rs->len, j, k);
@@ -95,6 +95,8 @@ process_rings(struct netmap_ring *rxring, struct netma
 			/* report the buffer change. */
 			ts->flags |= NS_BUF_CHANGED;
 			rs->flags |= NS_BUF_CHANGED;
+			/* copy the NS_MOREFRAG */
+			rs->flags = (rs->flags & ~NS_MOREFRAG) | (ts->flags & NS_MOREFRAG);
 		} else {
 			char *rxbuf = NETMAP_BUF(rxring, rs->buf_idx);
 			char *txbuf = NETMAP_BUF(txring, ts->buf_idx);
@@ -117,7 +119,7 @@ move(struct nm_desc *src, struct nm_desc *dst, u_int l
 {
 	struct netmap_ring *txring, *rxring;
 	u_int m = 0, si = src->first_rx_ring, di = dst->first_tx_ring;
-	const char *msg = (src->req.nr_ringid & NETMAP_SW_RING) ?
+	const char *msg = (src->req.nr_flags == NR_REG_SW) ?
 		"host->net" : "net->host";
 
 	while (si <= src->last_rx_ring && di <= dst->last_tx_ring) {
@@ -143,7 +145,20 @@ static void
 usage(void)
 {
 	fprintf(stderr,
-	    "usage: bridge [-v] [-i ifa] [-i ifb] [-b burst] [-w wait_time] [ifa [ifb [burst]]]\n");
+		"netmap bridge program: forward packets between two "
+			"network interfaces\n"
+		"    usage(1): bridge [-v] [-i ifa] [-i ifb] [-b burst] "
+			"[-w wait_time] [-L]\n"
+		"    usage(2): bridge [-v] [-w wait_time] [-L] "
+			"[ifa [ifb [burst]]]\n"
+		"\n"
+		"    ifa and ifb are specified using the nm_open() syntax.\n"
+		"    When ifb is missing (or is equal to ifa), bridge will\n"
+		"    forward between between ifa and the host stack if -L\n"
+		"    is not specified, otherwise loopback traffic on ifa.\n"
+		"\n"
+		"    example: bridge -w 10 -i netmap:eth3 -i netmap:eth1\n"
+		);
 	exit(1);
 }
 
@@ -163,14 +178,16 @@ main(int argc, char **argv)
 	struct nm_desc *pa = NULL, *pb = NULL;
 	char *ifa = NULL, *ifb = NULL;
 	char ifabuf[64] = { 0 };
+	int loopback = 0;
 
-	fprintf(stderr, "%s built %s %s\n",
-		argv[0], __DATE__, __TIME__);
+	fprintf(stderr, "%s built %s %s\n\n", argv[0], __DATE__, __TIME__);
 
-	while ( (ch = getopt(argc, argv, "b:ci:vw:")) != -1) {
+	while ((ch = getopt(argc, argv, "hb:ci:vw:L")) != -1) {
 		switch (ch) {
 		default:
 			D("bad option %c %s", ch, optarg);
+			/* fallthrough */
+		case 'h':
 			usage();
 			break;
 		case 'b':	/* burst */
@@ -194,6 +211,9 @@ main(int argc, char **argv)
 		case 'w':
 			wait_link = atoi(optarg);
 			break;
+		case 'L':
+			loopback = 1;
+			break;
 		}
 
 	}
@@ -222,9 +242,13 @@ main(int argc, char **argv)
 		wait_link = 4;
 	}
 	if (!strcmp(ifa, ifb)) {
-		D("same interface, endpoint 0 goes to host");
-		snprintf(ifabuf, sizeof(ifabuf) - 1, "%s^", ifa);
-		ifa = ifabuf;
+		if (!loopback) {
+			D("same interface, endpoint 0 goes to host");
+			snprintf(ifabuf, sizeof(ifabuf) - 1, "%s^", ifa);
+			ifa = ifabuf;
+		} else {
+			D("same interface, loopbacking traffic");
+		}
 	} else {
 		/* two different interfaces. Take all rings on if1 */
 	}
@@ -243,7 +267,7 @@ main(int argc, char **argv)
 	zerocopy = zerocopy && (pa->mem == pb->mem);
 	D("------- zerocopy %ssupported", zerocopy ? "" : "NOT ");
 
-	/* setup poll(2) variables. */
+	/* setup poll(2) array */
 	memset(pollfd, 0, sizeof(pollfd));
 	pollfd[0].fd = pa->fd;
 	pollfd[1].fd = pb->fd;
@@ -263,18 +287,16 @@ main(int argc, char **argv)
 		n0 = pkt_queued(pa, 0);
 		n1 = pkt_queued(pb, 0);
 #if defined(_WIN32) || defined(BUSYWAIT)
-		if (n0){
+		if (n0) {
 			ioctl(pollfd[1].fd, NIOCTXSYNC, NULL);
 			pollfd[1].revents = POLLOUT;
-		}
-		else {
+		} else {
 			ioctl(pollfd[0].fd, NIOCRXSYNC, NULL);
 		}
-		if (n1){
+		if (n1) {
 			ioctl(pollfd[0].fd, NIOCTXSYNC, NULL);
 			pollfd[0].revents = POLLOUT;
-		}
-		else {
+		} else {
 			ioctl(pollfd[1].fd, NIOCRXSYNC, NULL);
 		}
 		ret = 1;
@@ -287,8 +309,10 @@ main(int argc, char **argv)
 			pollfd[0].events |= POLLOUT;
 		else
 			pollfd[1].events |= POLLIN;
+
+		/* poll() also cause kernel to txsync/rxsync the NICs */
 		ret = poll(pollfd, 2, 2500);
-#endif //defined(_WIN32) || defined(BUSYWAIT)
+#endif /* defined(_WIN32) || defined(BUSYWAIT) */
 		if (ret <= 0 || verbose)
 		    D("poll %s [0] ev %x %x rx %d@%d tx %d,"
 			     " [1] ev %x %x rx %d@%d tx %d",
@@ -316,18 +340,15 @@ main(int argc, char **argv)
 			D("error on fd1, rx [%d,%d,%d)",
 				rx->head, rx->cur, rx->tail);
 		}
-		if (pollfd[0].revents & POLLOUT) {
+		if (pollfd[0].revents & POLLOUT)
 			move(pb, pa, burst);
-			// XXX we don't need the ioctl */
-			// ioctl(me[0].fd, NIOCTXSYNC, NULL);
-		}
-		if (pollfd[1].revents & POLLOUT) {
+
+		if (pollfd[1].revents & POLLOUT)
 			move(pa, pb, burst);
-			// XXX we don't need the ioctl */
-			// ioctl(me[1].fd, NIOCTXSYNC, NULL);
-		}
+
+		/* We don't need ioctl(NIOCTXSYNC) on the two file descriptors here,
+		 * kernel will txsync on next poll(). */
 	}
-	D("exiting");
 	nm_close(pb);
 	nm_close(pa);
 

Modified: head/tools/tools/netmap/pkt-gen.8
==============================================================================
--- head/tools/tools/netmap/pkt-gen.8	Tue Oct 23 14:44:32 2018	(r339658)
+++ head/tools/tools/netmap/pkt-gen.8	Tue Oct 23 15:34:43 2018	(r339659)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 1, 2016
+.Dd October 23, 2018
 .Dt PKT-GEN 8
 .Os
 .Sh NAME
@@ -170,10 +170,9 @@ packets to be received by the target host.
 .Dl
 .Nm
 -i netmap:ncxl0 -f tx -s 172.16.0.1:53 -d 172.16.1.3:53 -D 00:07:43:29:2a:e0 
-.Sh FILES
-.Xr netmap 4
 .Sh SEE ALSO
-.Xr netmap 4
+.Xr netmap 4 ,
+.Xr bridge 8
 .Sh AUTHORS
 This manual page was written by
 .An George V. Neville-Neil Aq gnn@FreeBSD.org .



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201810231534.w9NFYhhj093530>