If the application is being run on a host connected to a
 switch, not changing the ethernet destination may cause
 loops. Added an option to change the destination ethernet
 address. The destination addresses follow the format
 02:00:00:00:00:XX where the final octet is the output
 port number.

Signed-off-by: Matias Elo <matias....@nokia.com>
---
 test/performance/odp_l2fwd.c | 46 ++++++++++++++++++++++++++++++--------------
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/test/performance/odp_l2fwd.c b/test/performance/odp_l2fwd.c
index 812d47f..6755673 100644
--- a/test/performance/odp_l2fwd.c
+++ b/test/performance/odp_l2fwd.c
@@ -75,6 +75,7 @@ typedef struct {
        int time;               /**< Time in seconds to run. */
        int accuracy;           /**< Number of seconds to get and print 
statistics */
        char *if_str;           /**< Storage for interface names */
+       int dst_change;         /**< Change destination eth addresses > */
 } appl_args_t;
 
 static int exit_threads;       /**< Break workers loop if set to 1 */
@@ -107,6 +108,8 @@ typedef struct {
        odp_pktio_t pktios[ODP_CONFIG_PKTIO_ENTRIES];
        /** Table of port ethernet addresses */
        odph_ethaddr_t port_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
+       /** Table of dst ethernet addresses */
+       odph_ethaddr_t dst_eth_addr[ODP_CONFIG_PKTIO_ENTRIES];
        /** Table of port default output queues */
        odp_queue_t outq_def[ODP_CONFIG_PKTIO_ENTRIES];
 } args_t;
@@ -119,8 +122,8 @@ static odp_barrier_t barrier;
 /* helper funcs */
 static inline int lookup_dest_port(odp_packet_t pkt);
 static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned len);
-static void fill_src_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
-                              int dst_port);
+static void fill_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
+                          int dst_port);
 static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
 static void print_info(char *progname, appl_args_t *appl_args);
 static void usage(char *progname);
@@ -160,7 +163,7 @@ static void *pktio_queue_thread(void *arg)
 
                dst_port = lookup_dest_port(pkt);
 
-               fill_src_eth_addrs(&pkt, 1, dst_port);
+               fill_eth_addrs(&pkt, 1, dst_port);
 
                /* Enqueue the packet for output */
                outq_def = gbl_args->outq_def[dst_port];
@@ -239,7 +242,7 @@ static void *pktio_ifburst_thread(void *arg)
                /* Drop packets with errors */
                pkts_ok = drop_err_pkts(pkt_tbl, pkts);
                if (pkts_ok > 0) {
-                       fill_src_eth_addrs(pkt_tbl, pkts_ok, dst_idx);
+                       fill_eth_addrs(pkt_tbl, pkts_ok, dst_idx);
 
                        int sent = odp_pktio_send(pktio_dst, pkt_tbl, pkts_ok);
 
@@ -388,6 +391,7 @@ int main(int argc, char *argv[])
        odp_shm_t shm;
        odp_cpumask_t cpumask;
        char cpumaskstr[ODP_CPUMASK_STR_SIZE];
+       odph_ethaddr_t new_addr;
        odp_pktio_t pktio;
        odp_pool_param_t params;
        int ret;
@@ -478,6 +482,15 @@ int main(int argc, char *argv[])
                if (gbl_args->appl.mode == APPL_MODE_PKT_QUEUE)
                        gbl_args->outq_def[i] = odp_pktio_outq_getdef(pktio);
 
+               /* Save destination eth address */
+               if (gbl_args->appl.dst_change) {
+                       /* 02:00:00:00:00:XX */
+                       memset(&new_addr, 0, sizeof(odph_ethaddr_t));
+                       new_addr.addr[0] = 0x02;
+                       new_addr.addr[5] = i;
+                       gbl_args->dst_eth_addr[i] = new_addr;
+               }
+
                ret = odp_pktio_start(pktio);
                if (ret) {
                        LOG_ERR("Error: unable to start %s\n",
@@ -563,14 +576,13 @@ static int drop_err_pkts(odp_packet_t pkt_tbl[], unsigned 
len)
 }
 
 /**
- * Fill packets' eth src addresses according to the destination port
+ * Fill packets' eth addresses according to the destination port
  *
  * @param pkt_tbl  Array of packets
  * @param num      Number of packets in the array
  * @param dst_port Destination port
  */
-static void fill_src_eth_addrs(odp_packet_t pkt_tbl[], unsigned num,
-                              int dst_port)
+static void fill_eth_addrs(odp_packet_t pkt_tbl[], unsigned num, int dst_port)
 {
        odp_packet_t pkt;
        odph_ethhdr_t *eth;
@@ -581,6 +593,9 @@ static void fill_src_eth_addrs(odp_packet_t pkt_tbl[], 
unsigned num,
                if (odp_packet_has_eth(pkt)) {
                        eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, NULL);
                        eth->src = gbl_args->port_eth_addr[dst_port];
+
+                       if (gbl_args->appl.dst_change)
+                               eth->dst = gbl_args->dst_eth_addr[dst_port];
                }
        }
 }
@@ -603,9 +618,10 @@ static void parse_args(int argc, char *argv[], appl_args_t 
*appl_args)
                {"count", required_argument, NULL, 'c'},
                {"time", required_argument, NULL, 't'},
                {"accuracy", required_argument, NULL, 'a'},
-               {"interface", required_argument, NULL, 'i'},    /* return 'i' */
-               {"mode", required_argument, NULL, 'm'},         /* return 'm' */
-               {"help", no_argument, NULL, 'h'},               /* return 'h' */
+               {"interface", required_argument, NULL, 'i'},
+               {"mode", required_argument, NULL, 'm'},
+               {"dst_change", required_argument, NULL, 'd'},
+               {"help", no_argument, NULL, 'h'},
                {NULL, 0, NULL, 0}
        };
 
@@ -614,7 +630,7 @@ static void parse_args(int argc, char *argv[], appl_args_t 
*appl_args)
        appl_args->mode = -1; /* Invalid, must be changed by parsing */
 
        while (1) {
-               opt = getopt_long(argc, argv, "+c:+t:+a:i:m:h",
+               opt = getopt_long(argc, argv, "+c:+t:+a:i:m:d:h",
                                  longopts, &long_index);
 
                if (opt == -1)
@@ -670,7 +686,6 @@ static void parse_args(int argc, char *argv[], appl_args_t 
*appl_args)
                                appl_args->if_names[i] = token;
                        }
                        break;
-
                case 'm':
                        i = atoi(optarg);
                        if (i == 0)
@@ -678,12 +693,13 @@ static void parse_args(int argc, char *argv[], 
appl_args_t *appl_args)
                        else
                                appl_args->mode = APPL_MODE_PKT_QUEUE;
                        break;
-
+               case 'd':
+                       appl_args->dst_change = atoi(optarg);
+                       break;
                case 'h':
                        usage(argv[0]);
                        exit(EXIT_SUCCESS);
                        break;
-
                default:
                        break;
                }
@@ -757,6 +773,8 @@ static void usage(char *progname)
               "  -t, --time  <number> Time in seconds to run.\n"
               "  -a, --accuracy <number> Time in seconds get print 
statistics\n"
               "                          (default is 1 second).\n"
+              "  -d, --dst_change  0: Don't change packets' dst eth addresses 
(default)\n"
+              "                    1: Change packets' dst eth addresses\n"
               "  -h, --help           Display help and exit.\n\n"
               " environment variables: ODP_PKTIO_DISABLE_NETMAP\n"
               "                        ODP_PKTIO_DISABLE_SOCKET_MMAP\n"
-- 
1.9.1

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to