From: Xuelin Shi <[email protected]>

get config from cmdline arguments instead of hard-coded string.

Signed-off-by: Xuelin Shi <[email protected]>
---
 example/l3fwd/odp_l3fwd.c    | 216 +++++++++++++++++++++++++++++++++++++------
 example/l3fwd/odp_l3fwd_db.c |   9 --
 2 files changed, 190 insertions(+), 35 deletions(-)

diff --git a/example/l3fwd/odp_l3fwd.c b/example/l3fwd/odp_l3fwd.c
index 29da045..5598a5a 100644
--- a/example/l3fwd/odp_l3fwd.c
+++ b/example/l3fwd/odp_l3fwd.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 
+#include <example_debug.h>
 #include <odp_api.h>
 #include <odp/helper/linux.h>
 #include <odp/helper/eth.h>
@@ -14,19 +15,27 @@
 #include <odp/helper/udp.h>
 #include <odp/helper/tcp.h>
 
+#include <getopt.h>
+
 #include "odp_l3fwd_db.h"
 
 #define POOL_NUM_PKT 8192
 #define POOL_SEG_LEN 1856
 #define MAX_PKT_BURST 32
 
-static const char * const route_str[] = {
-       "1.1.1.0/24:fm1-mac1:00.e0.0c.00.85.00",
-       "2.1.1.0/24:fm1-mac2:00.e0.0c.00.85.01",
-};
-
 #define MAX_NB_WORKER  8
 #define MAX_NB_PKTIO   4
+#define MAX_NB_ROUTE    32
+
+/** Get rid of path in filename - only for unix-type paths using '/' */
+#define NO_PATH(file_name) (strrchr((file_name), '/') ? \
+                           strrchr((file_name), '/') + 1 : (file_name))
+
+typedef struct {
+       char *if_names[MAX_NB_PKTIO];
+       uint32_t if_count;
+       char *route_str[MAX_NB_ROUTE];
+} app_args_t;
 
 struct l3fwd_pktio_s {
        odp_pktio_t pktio;
@@ -39,6 +48,7 @@ struct thread_arg_s {
 };
 
 struct {
+       app_args_t              cmd_args;
        struct l3fwd_pktio_s    l3fwd_pktios[MAX_NB_PKTIO];
        odph_linux_pthread_t    l3fwd_workers[MAX_NB_WORKER];
        struct thread_arg_s     worker_args[MAX_NB_WORKER];
@@ -46,6 +56,10 @@ struct {
        uint32_t                nb_worker; /* effective workers */
 } global;
 
+static void print_usage(char *progname);
+static void print_info(char *progname, app_args_t *args);
+static void parse_cmdline_args(int argc, char *argv[], app_args_t *args);
+
 static odp_pktio_t create_pktio(const char *name, odp_pool_t pool,
                                odp_pktin_queue_t *pktin,
                                odp_pktout_queue_t *pktout)
@@ -97,16 +111,17 @@ static void *run_worker(void *arg)
        odp_packet_t pkt_tbl_drop[MAX_PKT_BURST];
        uint32_t pkts, i;
        struct l3fwd_pktio_s *port;
+       char *if_name;
 
        i = ((struct thread_arg_s *)arg)->if_idx;
        port = &global.l3fwd_pktios[i];
-
+       if_name = global.cmd_args.if_names[i];
        if (odp_pktio_start(port->pktio)) {
-               printf("unable to start interface: %d\n", i);
+               printf("unable to start pktio: %s\n", if_name);
                exit(1);
        }
 
-       printf("start interface: %d\n", i);
+       printf("start pktio: %s\n", if_name);
        for (;;) {
                int need_to_drop = 0;
 
@@ -180,13 +195,7 @@ int main(int argc, char **argv)
        odph_linux_thr_params_t thr_params;
        uint32_t cpu, i;
        uint8_t mac[ODPH_ETHADDR_LEN];
-
-       if (argc != 3) {
-               printf("Usage: odp_l3fwd eth0 eth1\n");
-               printf("Where eth0 and eth1 are the used interfaces"
-                      " (must have 2 of them)\n");
-               exit(1);
-       }
+       app_args_t *args;
 
        if (odp_init_global(&instance, NULL, NULL)) {
                printf("Error: ODP global init failed.\n");
@@ -201,17 +210,21 @@ int main(int argc, char **argv)
        /* Clear global argument */
        memset(&global, 0, sizeof(global));
 
+       /* Parse cmdline arguments */
+       args = &global.cmd_args;
+       parse_cmdline_args(argc, argv, args);
+
        /* Init l3fwd tale */
        init_fwd_db();
 
        /* Add route into table */
-       for (i = 0; i < sizeof(route_str) / sizeof(char *); i++) {
-               char buf[128];
-
-               snprintf(buf, 128, "%s", route_str[i]);
-               create_fwd_db_entry(buf);
+       for (i = 0; i < MAX_NB_ROUTE; i++) {
+               if (args->route_str[i])
+                       create_fwd_db_entry(args->route_str[i]);
        }
 
+       print_info(NO_PATH(argv[0]), args);
+
        /* Create packet pool */
        odp_pool_param_init(&params);
        params.pkt.seg_len = POOL_SEG_LEN;
@@ -226,20 +239,25 @@ int main(int argc, char **argv)
                exit(1);
        }
 
-       /* TODO: parse cmdline to get pktio number, name */
-       global.nb_pktio = 2;
+       global.nb_pktio = args->if_count;
        for (i = 0; i < global.nb_pktio; i++) {
                struct l3fwd_pktio_s *port;
-               char *ifname = argv[i + 1];
+               char buf[16];
 
                port = &global.l3fwd_pktios[i];
-               port->pktio = create_pktio(ifname, pool, &port->ifin,
+               port->pktio = create_pktio(args->if_names[i], pool, &port->ifin,
                                           &port->ifout);
                odp_pktio_mac_addr(port->pktio, mac, ODPH_ETHADDR_LEN);
-               resolve_fwd_db(ifname, port->pktio, mac);
+               resolve_fwd_db(args->if_names[i], port->pktio, mac);
+
+               /* print mac string, could be used to config pktgen */
+               sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+                       mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+               printf("create pktio %s, mac %s\n", args->if_names[i], buf);
        }
 
-       global.nb_worker = 2;
+       /* one thread for each port */
+       global.nb_worker = args->if_count;
        memset(&thr_params, 0, sizeof(thr_params));
        thr_params.start    = run_worker;
        thr_params.thr_type = ODP_THREAD_WORKER;
@@ -264,3 +282,149 @@ int main(int argc, char **argv)
 
        return 0;
 }
+
+static void print_usage(char *progname)
+{
+       printf("\n"
+              "ODP L3 forwarding application.\n"
+              "\n"
+              "Usage: %s OPTIONS\n"
+              "  E.g. %s -i eth0,eth1\n"
+              " In the above example,\n"
+              " eth0 will send pkts to eth1 and vice versa\n"
+              "\n"
+              "Mandatory OPTIONS:\n"
+              "  -i, --interface eth interfaces (comma-separated, no spaces)\n"
+              "  -r, --route SubNet:Intf[:NextHopMAC]\n"
+              "        NextHopMAC can be optional, in this case, zeroed mac\n"
+              "\n"
+              "Optional OPTIONS\n"
+              "  -h, --help           Display help and exit.\n\n"
+              "\n", NO_PATH(progname), NO_PATH(progname)
+           );
+}
+
+static void parse_cmdline_args(int argc, char *argv[], app_args_t *args)
+{
+       int opt;
+       int long_index;
+       char *token, *local;
+       size_t len, route_index = 0;
+       int i, mem_failure = 0;
+
+       static struct option longopts[] = {
+               {"interface", required_argument, NULL, 'i'},    /* return 'i' */
+               {"route", required_argument, NULL, 'r'},        /* return 'r' */
+               {"help", no_argument, NULL, 'h'},               /* return 'h' */
+               {NULL, 0, NULL, 0}
+       };
+
+       while (1) {
+               opt = getopt_long(argc, argv, "+i:r:h",
+                                 longopts, &long_index);
+
+               if (opt == -1)
+                       break;  /* No more options */
+
+               switch (opt) {
+               /* parse packet-io interface names */
+               case 'i':
+                       len = strlen(optarg);
+                       if (len == 0) {
+                               print_usage(argv[0]);
+                               exit(EXIT_FAILURE);
+                       }
+                       len += 1;       /* add room for '\0' */
+
+                       local = malloc(len);
+                       if (!local) {
+                               print_usage(argv[0]);
+                               exit(EXIT_FAILURE);
+                       }
+
+                       /* count the number of tokens separated by ',' */
+                       strcpy(local, optarg);
+                       for (token = strtok(local, ","), i = 0;
+                            token != NULL;
+                            token = strtok(NULL, ","), i++)
+                               ;
+
+                       if (i == 0) {
+                               print_usage(argv[0]);
+                               exit(EXIT_FAILURE);
+                       }
+
+                       args->if_count = i;
+
+                       /* store the if names (reset names string) */
+                       strcpy(local, optarg);
+                       for (token = strtok(local, ","), i = 0;
+                            token != NULL; token = strtok(NULL, ","), i++) {
+                               args->if_names[i] = token;
+                       }
+                       break;
+
+               /*Configure Route in forwarding database*/
+               case 'r':
+                       if (route_index >= MAX_NB_ROUTE) {
+                               printf("No more routes can be added\n");
+                               break;
+                       }
+                       local = calloc(1, strlen(optarg) + 1);
+                       if (!local) {
+                               mem_failure = 1;
+                               break;
+                       }
+                       memcpy(local, optarg, strlen(optarg));
+                       local[strlen(optarg)] = '\0';
+                       args->route_str[route_index++] = local;
+                       break;
+
+               case 'h':
+                       print_usage(argv[0]);
+                       exit(EXIT_SUCCESS);
+                       break;
+
+               default:
+                       break;
+               }
+       }
+
+       if (args->if_count == 0 || mem_failure == 1) {
+               print_usage(argv[0]);
+               exit(EXIT_FAILURE);
+       }
+
+       optind = 1;             /* reset 'extern optind' from the getopt lib */
+}
+
+static void print_info(char *progname, app_args_t *args)
+{
+       uint32_t i;
+
+       printf("\n"
+              "ODP system info\n"
+              "---------------\n"
+              "ODP API version: %s\n"
+              "ODP impl name:   %s\n"
+              "CPU model:       %s\n"
+              "CPU freq (hz):   %" PRIu64 "\n"
+              "Cache line size: %i\n"
+              "CPU count:       %i\n"
+              "\n",
+              odp_version_api_str(), odp_version_impl_name(),
+              odp_cpu_model_str(), odp_cpu_hz_max(),
+              odp_sys_cache_line_size(), odp_cpu_count());
+
+       printf("Running ODP appl: \"%s\"\n"
+              "-----------------\n"
+              "IF-count:        %i\n"
+              "Using IFs:      ",
+              progname, args->if_count);
+
+       for (i = 0; i < args->if_count; ++i)
+               printf(" %s", args->if_names[i]);
+
+       printf("\n\n");
+       fflush(NULL);
+}
diff --git a/example/l3fwd/odp_l3fwd_db.c b/example/l3fwd/odp_l3fwd_db.c
index 7fde4ae..c1e1b5b 100644
--- a/example/l3fwd/odp_l3fwd_db.c
+++ b/example/l3fwd/odp_l3fwd_db.c
@@ -342,15 +342,6 @@ int create_fwd_db_entry(char *input)
                pos++;
        }
 
-       /* Verify we parsed exactly the number of tokens we expected */
-       if (3 != pos) {
-               printf("ERROR: \"%s\" contains %d tokens, expected 3\n",
-                      input,
-                      pos);
-               free(local);
-               return -1;
-       }
-
        /* Reset pktio to invalid */
        entry->pktio = ODP_PKTIO_INVALID;
 
-- 
2.1.0.27.g96db324

_______________________________________________
lng-odp mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to