aboutsummaryrefslogtreecommitdiff
path: root/tools/tools/netmap/bridge.c
diff options
context:
space:
mode:
authorVincenzo Maffione <vmaffione@FreeBSD.org>2018-10-23 15:34:43 +0000
committerVincenzo Maffione <vmaffione@FreeBSD.org>2018-10-23 15:34:43 +0000
commit1a7d3c055b83822ac09c8d71a16faca54a7e9f7d (patch)
tree8a4838b008196da43c314ff46b8a1cd58824fae4 /tools/tools/netmap/bridge.c
parent8b7db4655703ecd16c8fa263bb741a6573be9a5d (diff)
downloadsrc-1a7d3c055b83822ac09c8d71a16faca54a7e9f7d.tar.gz
src-1a7d3c055b83822ac09c8d71a16faca54a7e9f7d.zip
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
Notes
Notes: svn path=/head/; revision=339659
Diffstat (limited to 'tools/tools/netmap/bridge.c')
-rw-r--r--tools/tools/netmap/bridge.c99
1 files changed, 60 insertions, 39 deletions
diff --git a/tools/tools/netmap/bridge.c b/tools/tools/netmap/bridge.c
index e99a507a829a..8c9bd574d84e 100644
--- a/tools/tools/netmap/bridge.c
+++ b/tools/tools/netmap/bridge.c
@@ -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 netmap_ring *txring,
/* 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 netmap_ring *txring,
/* 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 limit)
{
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);