Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146426349
D17664.id49495.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D17664.id49495.diff
View Options
Index: tools/tools/netmap/bridge.8
===================================================================
--- tools/tools/netmap/bridge.8
+++ tools/tools/netmap/bridge.8
@@ -0,0 +1,79 @@
+.\" Copyright (c) 2016 Luigi Rizzo, Universita` di Pisa
+.\" All rights reserved.
+.\"
+.\" 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 1
+.Os
+.Sh NAME
+.Nm bridge
+.Nd A netmap client to bridge two network interfaces (or one interface and the host stack)
+.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
+operates in zero copy (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 AUTHORS
+.An -nosplit
+.Nm
+has been written by
+.An Luigi Rizzo
+and
+.An Matteo Landi
+at the Universita` di Pisa, Italy.
Index: tools/tools/netmap/bridge.c
===================================================================
--- tools/tools/netmap/bridge.c
+++ tools/tools/netmap/bridge.c
@@ -34,18 +34,18 @@
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 @@
/* 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 @@
/* 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 @@
{
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 @@
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 @@
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 @@
case 'w':
wait_link = atoi(optarg);
break;
+ case 'L':
+ loopback = 1;
+ break;
}
}
@@ -222,9 +242,13 @@
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 @@
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 @@
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 @@
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 @@
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);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Mar 3, 2:50 PM (9 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29177364
Default Alt Text
D17664.id49495.diff (8 KB)
Attached To
Mode
D17664: netmap: add man page for the bridge program
Attached
Detach File
Event Timeline
Log In to Comment