Author: vmaffione
Date: Sun Nov 22 13:39:21 2020
New Revision: 367936
URL: https://svnweb.freebsd.org/changeset/base/367936

Log:
  netmap: bridge: improve readability
  
  Multiple cosmetic changes, plus a fix to a verbose print
  (indicating wrong net->host/host->net direction).
  
  MFC after:    3 days

Modified:
  head/tools/tools/netmap/bridge.c

Modified: head/tools/tools/netmap/bridge.c
==============================================================================
--- head/tools/tools/netmap/bridge.c    Sun Nov 22 10:02:56 2020        
(r367935)
+++ head/tools/tools/netmap/bridge.c    Sun Nov 22 13:39:21 2020        
(r367936)
@@ -3,19 +3,19 @@
  *
  * BSD license
  *
- * A netmap client to bridge two network interfaces
- * (or one interface and the host stack).
+ * A netmap application to bridge two network interfaces,
+ * or one interface and the host stack.
  *
  * $FreeBSD$
  */
 
+#include <libnetmap.h>
+#include <signal.h>
 #include <stdio.h>
 #include <sys/poll.h>
 #include <sys/ioctl.h>
-#include <signal.h>
 #include <stdlib.h>
 #include <unistd.h>
-#include <libnetmap.h>
 
 static int verbose = 0;
 
@@ -32,30 +32,39 @@ sigint_h(int sig)
 
 
 /*
- * how many packets on this set of queues ?
+ * How many slots do we (user application) have on this
+ * set of queues ?
  */
 static int
-pkt_queued(struct nmport_d *d, int tx)
+rx_slots_avail(struct nmport_d *d)
 {
        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));
-               }
+       for (i = d->first_rx_ring; i <= d->last_rx_ring; i++) {
+               tot += nm_ring_space(NETMAP_RXRING(d->nifp, i));
        }
+
        return tot;
 }
 
+static int
+tx_slots_avail(struct nmport_d *d)
+{
+       u_int i, tot = 0;
+
+       for (i = d->first_tx_ring; i <= d->last_tx_ring; i++) {
+               tot += nm_ring_space(NETMAP_TXRING(d->nifp, i));
+       }
+
+       return tot;
+}
+
 /*
- * move up to 'limit' pkts from rxring to txring swapping buffers.
+ * Move up to 'limit' pkts from rxring to txring, swapping buffers
+ * if zerocopy is possible. Otherwise fall back on packet copying.
  */
 static int
-process_rings(struct netmap_ring *rxring, struct netmap_ring *txring,
+rings_move(struct netmap_ring *rxring, struct netmap_ring *txring,
              u_int limit, const char *msg)
 {
        u_int j, k, m = 0;
@@ -63,7 +72,7 @@ process_rings(struct netmap_ring *rxring, struct netma
        /* print a warning if any of the ring flags is set (e.g. NM_REINIT) */
        if (rxring->flags || txring->flags)
                D("%s rxflags %x txflags %x",
-                       msg, rxring->flags, txring->flags);
+                   msg, rxring->flags, txring->flags);
        j = rxring->head; /* RX */
        k = txring->head; /* TX */
        m = nm_ring_space(rxring);
@@ -79,16 +88,18 @@ process_rings(struct netmap_ring *rxring, struct netma
 
                /* swap packets */
                if (ts->buf_idx < 2 || rs->buf_idx < 2) {
-                       RD(5, "wrong index rx[%d] = %d  -> tx[%d] = %d",
-                               j, rs->buf_idx, k, ts->buf_idx);
+                       RD(2, "wrong index rxr[%d] = %d  -> txr[%d] = %d",
+                           j, rs->buf_idx, k, ts->buf_idx);
                        sleep(2);
                }
                /* copy the packet length. */
                if (rs->len > rxring->nr_buf_size) {
-                       RD(5, "wrong len %d rx[%d] -> tx[%d]", rs->len, j, k);
+                       RD(2,  "%s: invalid len %u, rxr[%d] -> txr[%d]",
+                           msg, 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);
+                       D("%s: fwd len %u, rx[%d] -> tx[%d]",
+                           msg, rs->len, j, k);
                }
                ts->len = rs->len;
                if (zerocopy) {
@@ -111,24 +122,23 @@ process_rings(struct netmap_ring *rxring, struct netma
        rxring->head = rxring->cur = j;
        txring->head = txring->cur = k;
        if (verbose && m > 0)
-               D("%s sent %d packets to %p", msg, m, txring);
+               D("%s fwd %d packets: rxring %u --> txring %u",
+                   msg, m, rxring->ringid, txring->ringid);
 
        return (m);
 }
 
-/* move packts from src to destination */
+/* Move packets from source port to destination port. */
 static int
-move(struct nmport_d *src, struct nmport_d *dst, u_int limit)
+ports_move(struct nmport_d *src, struct nmport_d *dst, u_int limit,
+       const char *msg)
 {
        struct netmap_ring *txring, *rxring;
        u_int m = 0, si = src->first_rx_ring, di = dst->first_tx_ring;
-       const char *msg = (src->reg.nr_flags == NR_REG_SW) ?
-               "host->net" : "net->host";
 
        while (si <= src->last_rx_ring && di <= dst->last_tx_ring) {
                rxring = NETMAP_RXRING(src->nifp, si);
                txring = NETMAP_TXRING(dst->nifp, di);
-               ND("txring %p rxring %p", txring, rxring);
                if (nm_ring_empty(rxring)) {
                        si++;
                        continue;
@@ -137,7 +147,7 @@ move(struct nmport_d *src, struct nmport_d *dst, u_int
                        di++;
                        continue;
                }
-               m += process_rings(rxring, txring, limit, msg);
+               m += rings_move(rxring, txring, limit, msg);
        }
 
        return (m);
@@ -149,7 +159,7 @@ usage(void)
 {
        fprintf(stderr,
                "netmap bridge program: forward packets between two "
-                       "network interfaces\n"
+                       "netmap ports\n"
                "    usage(1): bridge [-v] [-i ifa] [-i ifb] [-b burst] "
                        "[-w wait_time] [-L]\n"
                "    usage(2): bridge [-v] [-w wait_time] [-L] "
@@ -161,6 +171,11 @@ usage(void)
                "    is not specified, otherwise loopback traffic on ifa.\n"
                "\n"
                "    example: bridge -w 10 -i netmap:eth3 -i netmap:eth1\n"
+               "\n"
+               "    If ifa and ifb are two interfaces, they must be in\n"
+               "    promiscuous mode. Otherwise, if bridging with the \n"
+               "    host stack, the interface must have the offloads \n"
+               "    disabled.\n"
                );
        exit(1);
 }
@@ -175,13 +190,15 @@ usage(void)
 int
 main(int argc, char **argv)
 {
+       char msg_a2b[128], msg_b2a[128];
        struct pollfd pollfd[2];
-       int ch;
        u_int burst = 1024, wait_link = 4;
        struct nmport_d *pa = NULL, *pb = NULL;
        char *ifa = NULL, *ifb = NULL;
        char ifabuf[64] = { 0 };
+       int pa_sw_rings, pb_sw_rings;
        int loopback = 0;
+       int ch;
 
        fprintf(stderr, "%s built %s %s\n\n", argv[0], __DATE__, __TIME__);
 
@@ -281,14 +298,27 @@ main(int argc, char **argv)
                pa->hdr.nr_name, pa->first_rx_ring, pa->reg.nr_rx_rings,
                pb->hdr.nr_name, pb->first_rx_ring, pb->reg.nr_rx_rings);
 
+       pa_sw_rings = (pa->reg.nr_mode == NR_REG_SW ||
+           pa->reg.nr_mode == NR_REG_ONE_SW);
+       pb_sw_rings = (pb->reg.nr_mode == NR_REG_SW ||
+           pb->reg.nr_mode == NR_REG_ONE_SW);
+
+       snprintf(msg_a2b, sizeof(msg_a2b), "%s:%s --> %s:%s",
+                       pa->hdr.nr_name, pa_sw_rings ? "host" : "nic",
+                       pb->hdr.nr_name, pb_sw_rings ? "host" : "nic");
+
+       snprintf(msg_b2a, sizeof(msg_b2a), "%s:%s --> %s:%s",
+                       pb->hdr.nr_name, pb_sw_rings ? "host" : "nic",
+                       pa->hdr.nr_name, pa_sw_rings ? "host" : "nic");
+
        /* main loop */
        signal(SIGINT, sigint_h);
        while (!do_abort) {
                int n0, n1, ret;
                pollfd[0].events = pollfd[1].events = 0;
                pollfd[0].revents = pollfd[1].revents = 0;
-               n0 = pkt_queued(pa, 0);
-               n1 = pkt_queued(pb, 0);
+               n0 = rx_slots_avail(pa);
+               n1 = rx_slots_avail(pb);
 #if defined(_WIN32) || defined(BUSYWAIT)
                if (n0) {
                        ioctl(pollfd[1].fd, NIOCTXSYNC, NULL);
@@ -322,35 +352,37 @@ main(int argc, char **argv)
                                ret <= 0 ? "timeout" : "ok",
                                pollfd[0].events,
                                pollfd[0].revents,
-                               pkt_queued(pa, 0),
+                               rx_slots_avail(pa),
                                NETMAP_RXRING(pa->nifp, pa->cur_rx_ring)->head,
-                               pkt_queued(pa, 1),
+                               tx_slots_avail(pa),
                                pollfd[1].events,
                                pollfd[1].revents,
-                               pkt_queued(pb, 0),
+                               rx_slots_avail(pb),
                                NETMAP_RXRING(pb->nifp, pb->cur_rx_ring)->head,
-                               pkt_queued(pb, 1)
+                               tx_slots_avail(pb)
                        );
                if (ret < 0)
                        continue;
                if (pollfd[0].revents & POLLERR) {
                        struct netmap_ring *rx = NETMAP_RXRING(pa->nifp, 
pa->cur_rx_ring);
                        D("error on fd0, rx [%d,%d,%d)",
-                               rx->head, rx->cur, rx->tail);
+                           rx->head, rx->cur, rx->tail);
                }
                if (pollfd[1].revents & POLLERR) {
                        struct netmap_ring *rx = NETMAP_RXRING(pb->nifp, 
pb->cur_rx_ring);
                        D("error on fd1, rx [%d,%d,%d)",
-                               rx->head, rx->cur, rx->tail);
+                           rx->head, rx->cur, rx->tail);
                }
                if (pollfd[0].revents & POLLOUT)
-                       move(pb, pa, burst);
+                       ports_move(pb, pa, burst, msg_b2a);
 
                if (pollfd[1].revents & POLLOUT)
-                       move(pa, pb, burst);
+                       ports_move(pa, pb, burst, msg_a2b);
 
-               /* We don't need ioctl(NIOCTXSYNC) on the two file descriptors 
here,
-                * kernel will txsync on next poll(). */
+               /*
+                * We don't need ioctl(NIOCTXSYNC) on the two file descriptors.
+                * here. The kernel will txsync on next poll().
+                */
        }
        nmport_close(pb);
        nmport_close(pa);
_______________________________________________
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