Imported Upstream version 16.07-rc1
[deb_dpdk.git] / examples / ip_pipeline / pipeline / pipeline_routing.c
index eab89f2..3aadbf9 100644 (file)
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
 #include <cmdline_parse.h>
 #include <cmdline_parse_num.h>
 #include <cmdline_parse_string.h>
-#include <cmdline_parse_ipaddr.h>
-#include <cmdline_parse_etheraddr.h>
 
 #include "app.h"
 #include "pipeline_common_fe.h"
 #include "pipeline_routing.h"
+#include "parser.h"
 
 struct app_pipeline_routing_route {
        struct pipeline_routing_route_key key;
@@ -59,8 +58,14 @@ struct app_pipeline_routing_arp_entry {
 
 struct pipeline_routing {
        /* Parameters */
+       struct app_params *app;
+       uint32_t pipeline_id;
        uint32_t n_ports_in;
        uint32_t n_ports_out;
+       struct pipeline_routing_params rp;
+
+       /* Links */
+       uint32_t link_id[PIPELINE_MAX_PORT_OUT];
 
        /* Routes */
        TAILQ_HEAD(, app_pipeline_routing_route) routes;
@@ -79,12 +84,151 @@ struct pipeline_routing {
        void *default_arp_entry_ptr;
 };
 
+static int
+app_pipeline_routing_find_link(struct pipeline_routing *p,
+       uint32_t link_id,
+       uint32_t *port_id)
+{
+       uint32_t i;
+
+       for (i = 0; i < p->n_ports_out; i++)
+               if (p->link_id[i] == link_id) {
+                       *port_id = i;
+                       return 0;
+               }
+
+       return -1;
+}
+
+static void
+app_pipeline_routing_link_op(__rte_unused struct app_params *app,
+       uint32_t link_id,
+       uint32_t up,
+       void *arg)
+{
+       struct pipeline_routing_route_key key0, key1;
+       struct pipeline_routing *p = arg;
+       struct app_link_params *lp;
+       uint32_t port_id, netmask;
+       int status;
+
+       if (app == NULL)
+               return;
+
+       APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, lp);
+       if (lp == NULL)
+               return;
+
+       status = app_pipeline_routing_find_link(p,
+               link_id,
+               &port_id);
+       if (status)
+               return;
+
+       netmask = (~0U) << (32 - lp->depth);
+
+       /* Local network (directly attached network) */
+       key0.type = PIPELINE_ROUTING_ROUTE_IPV4;
+       key0.key.ipv4.ip = lp->ip & netmask;
+       key0.key.ipv4.depth = lp->depth;
+
+       /* Local termination */
+       key1.type = PIPELINE_ROUTING_ROUTE_IPV4;
+       key1.key.ipv4.ip = lp->ip;
+       key1.key.ipv4.depth = 32;
+
+       if (up) {
+               struct pipeline_routing_route_data data0, data1;
+
+               /* Local network (directly attached network) */
+               memset(&data0, 0, sizeof(data0));
+               data0.flags = PIPELINE_ROUTING_ROUTE_LOCAL |
+                       PIPELINE_ROUTING_ROUTE_ARP;
+               if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ)
+                       data0.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
+               if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) {
+                       data0.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
+                       data0.l2.mpls.n_labels = 1;
+               }
+               data0.port_id = port_id;
+
+               if (p->rp.n_arp_entries)
+                       app_pipeline_routing_add_route(app,
+                               p->pipeline_id,
+                               &key0,
+                               &data0);
+
+               /* Local termination */
+               memset(&data1, 0, sizeof(data1));
+               data1.flags = PIPELINE_ROUTING_ROUTE_LOCAL |
+                       PIPELINE_ROUTING_ROUTE_ARP;
+               if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ)
+                       data1.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
+               if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) {
+                       data1.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
+                       data1.l2.mpls.n_labels = 1;
+               }
+               data1.port_id = p->rp.port_local_dest;
+
+               app_pipeline_routing_add_route(app,
+                       p->pipeline_id,
+                       &key1,
+                       &data1);
+       } else {
+               /* Local network (directly attached network) */
+               if (p->rp.n_arp_entries)
+                       app_pipeline_routing_delete_route(app,
+                               p->pipeline_id,
+                               &key0);
+
+               /* Local termination */
+               app_pipeline_routing_delete_route(app,
+                       p->pipeline_id,
+                       &key1);
+       }
+}
+
+static int
+app_pipeline_routing_set_link_op(
+       struct app_params *app,
+       struct pipeline_routing *p)
+{
+       uint32_t port_id;
+
+       for (port_id = 0; port_id < p->n_ports_out; port_id++) {
+               struct app_link_params *link;
+               uint32_t link_id;
+               int status;
+
+               link = app_pipeline_track_pktq_out_to_link(app,
+                       p->pipeline_id,
+                       port_id);
+               if (link == NULL)
+                       continue;
+
+               link_id = link - app->link_params;
+               p->link_id[port_id] = link_id;
+
+               status = app_link_set_op(app,
+                       link_id,
+                       p->pipeline_id,
+                       app_pipeline_routing_link_op,
+                       (void *) p);
+               if (status)
+                       return status;
+       }
+
+       return 0;
+}
+
 static void *
-pipeline_routing_init(struct pipeline_params *params,
-       __rte_unused void *arg)
+app_pipeline_routing_init(struct pipeline_params *params,
+       void *arg)
 {
+       struct app_params *app = (struct app_params *) arg;
        struct pipeline_routing *p;
-       uint32_t size;
+       uint32_t pipeline_id, size;
+       int status;
 
        /* Check input arguments */
        if ((params == NULL) ||
@@ -92,6 +236,8 @@ pipeline_routing_init(struct pipeline_params *params,
                (params->n_ports_out == 0))
                return NULL;
 
+       APP_PARAM_GET_ID(params, "PIPELINE", pipeline_id);
+
        /* Memory allocation */
        size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_routing));
        p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
@@ -99,18 +245,39 @@ pipeline_routing_init(struct pipeline_params *params,
                return NULL;
 
        /* Initialization */
+       p->app = app;
+       p->pipeline_id = pipeline_id;
        p->n_ports_in = params->n_ports_in;
        p->n_ports_out = params->n_ports_out;
 
+       status = pipeline_routing_parse_args(&p->rp, params);
+       if (status) {
+               rte_free(p);
+               return NULL;
+       }
        TAILQ_INIT(&p->routes);
        p->n_routes = 0;
 
        TAILQ_INIT(&p->arp_entries);
        p->n_arp_entries = 0;
 
+       app_pipeline_routing_set_link_op(app, p);
+
        return p;
 }
 
+static int
+app_pipeline_routing_post_init(void *pipeline)
+{
+       struct pipeline_routing *p = pipeline;
+
+       /* Check input arguments */
+       if (p == NULL)
+               return -1;
+
+       return app_pipeline_routing_set_macaddr(p->app, p->pipeline_id);
+}
+
 static int
 app_pipeline_routing_free(void *pipeline)
 {
@@ -198,7 +365,9 @@ print_route(const struct app_pipeline_routing_route *route)
                        key->depth,
                        route->data.port_id);
 
-               if (route->data.flags & PIPELINE_ROUTING_ROUTE_ARP)
+               if (route->data.flags & PIPELINE_ROUTING_ROUTE_LOCAL)
+                       printf(", Local");
+               else if (route->data.flags & PIPELINE_ROUTING_ROUTE_ARP)
                        printf(
                                ", Next Hop IP = %" PRIu32 ".%" PRIu32
                                ".%" PRIu32 ".%" PRIu32,
@@ -383,8 +552,6 @@ app_pipeline_routing_add_route(struct app_params *app,
                p->n_routes++;
        }
 
-       print_route(entry);
-
        /* Message buffer free */
        app_msg_free(app, rsp);
        return 0;
@@ -677,8 +844,6 @@ app_pipeline_routing_add_arp_entry(struct app_params *app, uint32_t pipeline_id,
                p->n_arp_entries++;
        }
 
-       print_arp_entry(entry);
-
        /* Message buffer free */
        app_msg_free(app, rsp);
        return 0;
@@ -853,1382 +1018,600 @@ app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
        return 0;
 }
 
-static int
-parse_labels(char *string, uint32_t *labels, uint32_t *n_labels)
+int
+app_pipeline_routing_set_macaddr(struct app_params *app,
+       uint32_t pipeline_id)
 {
-       uint32_t n_max_labels = *n_labels, count = 0;
+       struct app_pipeline_params *p;
+       struct pipeline_routing_set_macaddr_msg_req *req;
+       struct pipeline_routing_set_macaddr_msg_rsp *rsp;
+       uint32_t port_id;
 
-       /* Check for void list of labels */
-       if (strcmp(string, "<void>") == 0) {
-               *n_labels = 0;
-               return 0;
-       }
+       /* Check input arguments */
+       if (app == NULL)
+               return -EINVAL;
 
-       /* At least one label should be present */
-       for ( ; (*string != '\0'); ) {
-               char *next;
-               int value;
+       APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
+       if (p == NULL)
+               return -EINVAL;
 
-               if (count >= n_max_labels)
-                       return -1;
+       /* Allocate and write request */
+       req = app_msg_alloc(app);
+       if (req == NULL)
+               return -ENOMEM;
 
-               if (count > 0) {
-                       if (string[0] != ':')
-                               return -1;
+       req->type = PIPELINE_MSG_REQ_CUSTOM;
+       req->subtype = PIPELINE_ROUTING_MSG_REQ_SET_MACADDR;
 
-                       string++;
-               }
+       memset(req->macaddr, 0, sizeof(req->macaddr));
+       for (port_id = 0; port_id < p->n_pktq_out; port_id++) {
+               struct app_link_params *link;
 
-               value = strtol(string, &next, 10);
-               if (next == string)
-                       return -1;
-               string = next;
+               link = app_pipeline_track_pktq_out_to_link(app,
+                       pipeline_id,
+                       port_id);
+               if (link)
+                       req->macaddr[port_id] = link->mac_addr;
+       }
 
-               labels[count++] = (uint32_t) value;
+       /* Send request and wait for response */
+       rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
+       if (rsp == NULL)
+               return -ETIMEDOUT;
+
+       /* Read response and write entry */
+       if (rsp->status) {
+               app_msg_free(app, rsp);
+               return rsp->status;
        }
 
-       *n_labels = count;
+       /* Free response */
+       app_msg_free(app, rsp);
+
        return 0;
 }
 
 /*
- * route add (mpls = no, qinq = no, arp = no)
+ * route
+ *
+ * route add (ARP = ON/OFF, MPLS = ON/OFF, QINQ = ON/OFF):
+ *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr>
+ *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr>
+ *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr> qinq <svlan> <cvlan>
+ *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr> qinq <svlan> <cvlan>
+ *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr> mpls <mpls labels>
+ *    p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr> mpls <mpls labels>
+ *
+ * route add default:
+ *    p <pipelineid> route add default <portid>
+ *
+ * route del:
+ *    p <pipelineid> route del <ipaddr> <depth>
+ *
+ * route del default:
+ *    p <pipelineid> route del default
+ *
+ * route ls:
+ *    p <pipelineid> route ls
  */
 
-struct cmd_route_add1_result {
+struct cmd_route_result {
        cmdline_fixed_string_t p_string;
        uint32_t p;
        cmdline_fixed_string_t route_string;
-       cmdline_fixed_string_t add_string;
-       cmdline_ipaddr_t ip;
-       uint32_t depth;
-       cmdline_fixed_string_t port_string;
-       uint32_t port;
-       cmdline_fixed_string_t ether_string;
-       struct ether_addr macaddr;
+       cmdline_multi_string_t multi_string;
 };
 
 static void
-cmd_route_add1_parsed(
+cmd_route_parsed(
        void *parsed_result,
        __rte_unused struct cmdline *cl,
        void *data)
 {
-       struct cmd_route_add1_result *params = parsed_result;
+       struct cmd_route_result *params = parsed_result;
        struct app_params *app = data;
-       struct pipeline_routing_route_key key;
-       struct pipeline_routing_route_data route_data;
-       int status;
 
-       /* Create route */
-       key.type = PIPELINE_ROUTING_ROUTE_IPV4;
-       key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
-       key.key.ipv4.depth = params->depth;
-
-       route_data.flags = 0;
-       route_data.port_id = params->port;
-       route_data.ethernet.macaddr = params->macaddr;
-
-       status = app_pipeline_routing_add_route(app,
-               params->p,
-               &key,
-               &route_data);
+       char *tokens[16];
+       uint32_t n_tokens = RTE_DIM(tokens);
+       int status;
 
+       status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
        if (status != 0) {
-               printf("Command failed\n");
+               printf(CMD_MSG_TOO_MANY_ARGS, "route");
                return;
        }
-}
 
-static cmdline_parse_token_string_t cmd_route_add1_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, p_string,
-       "p");
+       /* route add */
+       if ((n_tokens >= 2) &&
+               (strcmp(tokens[0], "add") == 0) &&
+               strcmp(tokens[1], "default")) {
+               struct pipeline_routing_route_key key;
+               struct pipeline_routing_route_data route_data;
+               struct in_addr ipv4, nh_ipv4;
+               struct ether_addr mac_addr;
+               uint32_t depth, port_id, svlan, cvlan, i;
+               uint32_t mpls_labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
+               uint32_t n_labels = RTE_DIM(mpls_labels);
+
+               memset(&key, 0, sizeof(key));
+               memset(&route_data, 0, sizeof(route_data));
+
+               if (n_tokens < 7) {
+                       printf(CMD_MSG_NOT_ENOUGH_ARGS, "route add");
+                       return;
+               }
 
-static cmdline_parse_token_num_t cmd_route_add1_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, p, UINT32);
+               if (parse_ipv4_addr(tokens[1], &ipv4)) {
+                       printf(CMD_MSG_INVALID_ARG, "ipaddr");
+                       return;
+               }
 
-static cmdline_parse_token_string_t cmd_route_add1_route_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, route_string,
-       "route");
+               if (parser_read_uint32(&depth, tokens[2])) {
+                       printf(CMD_MSG_INVALID_ARG, "depth");
+                       return;
+               }
 
-static cmdline_parse_token_string_t cmd_route_add1_add_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, add_string,
-       "add");
+               if (strcmp(tokens[3], "port")) {
+                       printf(CMD_MSG_ARG_NOT_FOUND, "port");
+                       return;
+               }
 
-static cmdline_parse_token_ipaddr_t cmd_route_add1_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_route_add1_result, ip);
+               if (parser_read_uint32(&port_id, tokens[4])) {
+                       printf(CMD_MSG_INVALID_ARG, "portid");
+                       return;
+               }
 
-static cmdline_parse_token_num_t cmd_route_add1_depth =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, depth, UINT32);
+               if (strcmp(tokens[5], "ether")) {
+                       printf(CMD_MSG_ARG_NOT_FOUND, "ether");
+                       return;
+               }
 
-static cmdline_parse_token_string_t cmd_route_add1_port_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, port_string,
-       "port");
+               if (parse_mac_addr(tokens[6], &mac_addr)) {
+                       if (parse_ipv4_addr(tokens[6], &nh_ipv4)) {
+                               printf(CMD_MSG_INVALID_ARG, "nhmacaddr or nhipaddr");
+                               return;
+                       }
 
-static cmdline_parse_token_num_t cmd_route_add1_port =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, port, UINT32);
+                       route_data.flags |= PIPELINE_ROUTING_ROUTE_ARP;
+               }
 
-static cmdline_parse_token_string_t cmd_route_add1_ether_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, ether_string,
-       "ether");
+               if (n_tokens > 7) {
+                       if (strcmp(tokens[7], "mpls") == 0) {
+                               if (n_tokens != 9) {
+                                       printf(CMD_MSG_MISMATCH_ARGS, "route add mpls");
+                                       return;
+                               }
+
+                               if (parse_mpls_labels(tokens[8], mpls_labels, &n_labels)) {
+                                       printf(CMD_MSG_INVALID_ARG, "mpls labels");
+                                       return;
+                               }
+
+                               route_data.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
+                       } else if (strcmp(tokens[7], "qinq") == 0) {
+                               if (n_tokens != 10) {
+                                       printf(CMD_MSG_MISMATCH_ARGS, "route add qinq");
+                                       return;
+                               }
+
+                               if (parser_read_uint32(&svlan, tokens[8])) {
+                                       printf(CMD_MSG_INVALID_ARG, "svlan");
+                                       return;
+                               }
+                               if (parser_read_uint32(&cvlan, tokens[9])) {
+                                       printf(CMD_MSG_INVALID_ARG, "cvlan");
+                                       return;
+                               }
+
+                               route_data.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
+                       } else {
+                               printf(CMD_MSG_ARG_NOT_FOUND, "mpls or qinq");
+                               return;
+                       }
+               }
 
-static cmdline_parse_token_etheraddr_t cmd_route_add1_macaddr =
-       TOKEN_ETHERADDR_INITIALIZER(struct cmd_route_add1_result, macaddr);
+               switch (route_data.flags) {
+               case 0:
+                       route_data.port_id = port_id;
+                       route_data.ethernet.macaddr = mac_addr;
+                       break;
 
-static cmdline_parse_inst_t cmd_route_add1 = {
-       .f = cmd_route_add1_parsed,
-       .data = NULL,
-       .help_str = "Route add (mpls = no, qinq = no, arp = no)",
-       .tokens = {
-               (void *)&cmd_route_add1_p_string,
-               (void *)&cmd_route_add1_p,
-               (void *)&cmd_route_add1_route_string,
-               (void *)&cmd_route_add1_add_string,
-               (void *)&cmd_route_add1_ip,
-               (void *)&cmd_route_add1_depth,
-               (void *)&cmd_route_add1_port_string,
-               (void *)&cmd_route_add1_port,
-               (void *)&cmd_route_add1_ether_string,
-               (void *)&cmd_route_add1_macaddr,
-               NULL,
-       },
-};
+               case PIPELINE_ROUTING_ROUTE_ARP:
+                       route_data.port_id = port_id;
+                       route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
+                       break;
 
-/*
- * route add (mpls = no, qinq = no, arp = yes)
- */
+               case PIPELINE_ROUTING_ROUTE_MPLS:
+                       route_data.port_id = port_id;
+                       route_data.ethernet.macaddr = mac_addr;
+                       for (i = 0; i < n_labels; i++)
+                               route_data.l2.mpls.labels[i] = mpls_labels[i];
+                       route_data.l2.mpls.n_labels = n_labels;
+                       break;
 
-struct cmd_route_add2_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t route_string;
-       cmdline_fixed_string_t add_string;
-       cmdline_ipaddr_t ip;
-       uint32_t depth;
-       cmdline_fixed_string_t port_string;
-       uint32_t port;
-       cmdline_fixed_string_t ether_string;
-       cmdline_ipaddr_t nh_ip;
-};
+               case PIPELINE_ROUTING_ROUTE_MPLS | PIPELINE_ROUTING_ROUTE_ARP:
+                       route_data.port_id = port_id;
+                       route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
+                       for (i = 0; i < n_labels; i++)
+                               route_data.l2.mpls.labels[i] = mpls_labels[i];
+                       route_data.l2.mpls.n_labels = n_labels;
+                       break;
 
-static void
-cmd_route_add2_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_route_add2_result *params = parsed_result;
-       struct app_params *app = data;
-       struct pipeline_routing_route_key key;
-       struct pipeline_routing_route_data route_data;
-       int status;
+               case PIPELINE_ROUTING_ROUTE_QINQ:
+                       route_data.port_id = port_id;
+                       route_data.ethernet.macaddr = mac_addr;
+                       route_data.l2.qinq.svlan = svlan;
+                       route_data.l2.qinq.cvlan = cvlan;
+                       break;
 
-       /* Create route */
-       key.type = PIPELINE_ROUTING_ROUTE_IPV4;
-       key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
-       key.key.ipv4.depth = params->depth;
+               case PIPELINE_ROUTING_ROUTE_QINQ | PIPELINE_ROUTING_ROUTE_ARP:
+               default:
+                       route_data.port_id = port_id;
+                       route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
+                       route_data.l2.qinq.svlan = svlan;
+                       route_data.l2.qinq.cvlan = cvlan;
+                       break;
+               }
 
-       route_data.flags = PIPELINE_ROUTING_ROUTE_ARP;
-       route_data.port_id = params->port;
-       route_data.ethernet.ip =
-               rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
+               key.type = PIPELINE_ROUTING_ROUTE_IPV4;
+               key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
+               key.key.ipv4.depth = depth;
 
-       status = app_pipeline_routing_add_route(app,
-               params->p,
-               &key,
-               &route_data);
+               status = app_pipeline_routing_add_route(app,
+                       params->p,
+                       &key,
+                       &route_data);
+               if (status != 0)
+                       printf(CMD_MSG_FAIL, "route add");
 
-       if (status != 0) {
-               printf("Command failed\n");
                return;
-       }
-}
-
-static cmdline_parse_token_string_t cmd_route_add2_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, p_string,
-       "p");
-
-static cmdline_parse_token_num_t cmd_route_add2_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add2_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add2_route_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, route_string,
-       "route");
+       } /* route add */
 
-static cmdline_parse_token_string_t cmd_route_add2_add_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, add_string,
-       "add");
+       /* route add default */
+       if ((n_tokens >= 2) &&
+               (strcmp(tokens[0], "add") == 0) &&
+               (strcmp(tokens[1], "default") == 0)) {
+               uint32_t port_id;
 
-static cmdline_parse_token_ipaddr_t cmd_route_add2_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_route_add2_result, ip);
-
-static cmdline_parse_token_num_t cmd_route_add2_depth =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add2_result, depth, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add2_port_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, port_string,
-       "port");
+               if (n_tokens != 3) {
+                       printf(CMD_MSG_MISMATCH_ARGS, "route add default");
+                       return;
+               }
 
-static cmdline_parse_token_num_t cmd_route_add2_port =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add2_result, port, UINT32);
+               if (parser_read_uint32(&port_id, tokens[2])) {
+                       printf(CMD_MSG_INVALID_ARG, "portid");
+                       return;
+               }
 
-static cmdline_parse_token_string_t cmd_route_add2_ether_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, ether_string,
-       "ether");
+               status = app_pipeline_routing_add_default_route(app,
+                       params->p,
+                       port_id);
+               if (status != 0)
+                       printf(CMD_MSG_FAIL, "route add default");
 
-static cmdline_parse_token_ipaddr_t cmd_route_add2_nh_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_route_add2_result, nh_ip);
+               return;
+       } /* route add default */
 
-static cmdline_parse_inst_t cmd_route_add2 = {
-       .f = cmd_route_add2_parsed,
-       .data = NULL,
-       .help_str = "Route add (mpls = no, qinq = no, arp = yes)",
-       .tokens = {
-               (void *)&cmd_route_add2_p_string,
-               (void *)&cmd_route_add2_p,
-               (void *)&cmd_route_add2_route_string,
-               (void *)&cmd_route_add2_add_string,
-               (void *)&cmd_route_add2_ip,
-               (void *)&cmd_route_add2_depth,
-               (void *)&cmd_route_add2_port_string,
-               (void *)&cmd_route_add2_port,
-               (void *)&cmd_route_add2_ether_string,
-               (void *)&cmd_route_add2_nh_ip,
-               NULL,
-       },
-};
+       /* route del*/
+       if ((n_tokens >= 2) &&
+               (strcmp(tokens[0], "del") == 0) &&
+               strcmp(tokens[1], "default")) {
+               struct pipeline_routing_route_key key;
+               struct in_addr ipv4;
+               uint32_t depth;
 
-/*
- * route add (mpls = no, qinq = yes, arp = no)
- */
+               memset(&key, 0, sizeof(key));
 
-struct cmd_route_add3_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t route_string;
-       cmdline_fixed_string_t add_string;
-       cmdline_ipaddr_t ip;
-       uint32_t depth;
-       cmdline_fixed_string_t port_string;
-       uint32_t port;
-       cmdline_fixed_string_t ether_string;
-       struct ether_addr macaddr;
-       cmdline_fixed_string_t qinq_string;
-       uint32_t svlan;
-       uint32_t cvlan;
-};
+               if (n_tokens != 3) {
+                       printf(CMD_MSG_MISMATCH_ARGS, "route del");
+                       return;
+               }
 
-static void
-cmd_route_add3_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_route_add3_result *params = parsed_result;
-       struct app_params *app = data;
-       struct pipeline_routing_route_key key;
-       struct pipeline_routing_route_data route_data;
-       int status;
+               if (parse_ipv4_addr(tokens[1], &ipv4)) {
+                       printf(CMD_MSG_INVALID_ARG, "ipaddr");
+                       return;
+               }
 
-       /* Create route */
-       key.type = PIPELINE_ROUTING_ROUTE_IPV4;
-       key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
-       key.key.ipv4.depth = params->depth;
+               if (parser_read_uint32(&depth, tokens[2])) {
+                       printf(CMD_MSG_INVALID_ARG, "depth");
+                       return;
+               }
 
-       route_data.flags = PIPELINE_ROUTING_ROUTE_QINQ;
-       route_data.port_id = params->port;
-       route_data.ethernet.macaddr = params->macaddr;
-       route_data.l2.qinq.svlan = params->svlan;
-       route_data.l2.qinq.cvlan = params->cvlan;
+               key.type = PIPELINE_ROUTING_ROUTE_IPV4;
+               key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
+               key.key.ipv4.depth = depth;
 
-       status = app_pipeline_routing_add_route(app,
-               params->p,
-               &key,
-               &route_data);
+               status = app_pipeline_routing_delete_route(app, params->p, &key);
+               if (status != 0)
+                       printf(CMD_MSG_FAIL, "route del");
 
-       if (status != 0) {
-               printf("Command failed\n");
                return;
-       }
-}
-
-static cmdline_parse_token_string_t cmd_route_add3_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, p_string,
-       "p");
-
-static cmdline_parse_token_num_t cmd_route_add3_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add3_route_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, route_string,
-       "route");
+       } /* route del */
+
+       /* route del default */
+       if ((n_tokens >= 2) &&
+               (strcmp(tokens[0], "del") == 0) &&
+               (strcmp(tokens[1], "default") == 0)) {
+               if (n_tokens != 2) {
+                       printf(CMD_MSG_MISMATCH_ARGS, "route del default");
+                       return;
+               }
 
-static cmdline_parse_token_string_t cmd_route_add3_add_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, add_string,
-       "add");
+               status = app_pipeline_routing_delete_default_route(app,
+                       params->p);
+               if (status != 0)
+                       printf(CMD_MSG_FAIL, "route del default");
 
-static cmdline_parse_token_ipaddr_t cmd_route_add3_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_route_add3_result, ip);
+               return;
+       } /* route del default */
 
-static cmdline_parse_token_num_t cmd_route_add3_depth =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, depth, UINT32);
+       /* route ls */
+       if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
+               if (n_tokens != 1) {
+                       printf(CMD_MSG_MISMATCH_ARGS, "route ls");
+                       return;
+               }
 
-static cmdline_parse_token_string_t cmd_route_add3_port_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, port_string,
-       "port");
+               status = app_pipeline_routing_route_ls(app, params->p);
+               if (status != 0)
+                       printf(CMD_MSG_FAIL, "route ls");
 
-static cmdline_parse_token_num_t cmd_route_add3_port =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, port, UINT32);
+               return;
+       } /* route ls */
 
-static cmdline_parse_token_string_t cmd_route_add3_ether_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, ether_string,
-       "ether");
+       printf(CMD_MSG_MISMATCH_ARGS, "route");
+}
 
-static cmdline_parse_token_etheraddr_t cmd_route_add3_macaddr =
-       TOKEN_ETHERADDR_INITIALIZER(struct cmd_route_add3_result, macaddr);
+static cmdline_parse_token_string_t cmd_route_p_string =
+       TOKEN_STRING_INITIALIZER(struct cmd_route_result, p_string, "p");
 
-static cmdline_parse_token_string_t cmd_route_add3_qinq_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, qinq_string,
-       "qinq");
+static cmdline_parse_token_num_t cmd_route_p =
+       TOKEN_NUM_INITIALIZER(struct cmd_route_result, p, UINT32);
 
-static cmdline_parse_token_num_t cmd_route_add3_svlan =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, svlan, UINT32);
+static cmdline_parse_token_string_t cmd_route_route_string =
+       TOKEN_STRING_INITIALIZER(struct cmd_route_result, route_string, "route");
 
-static cmdline_parse_token_num_t cmd_route_add3_cvlan =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, cvlan, UINT32);
+static cmdline_parse_token_string_t cmd_route_multi_string =
+       TOKEN_STRING_INITIALIZER(struct cmd_route_result, multi_string,
+       TOKEN_STRING_MULTI);
 
-static cmdline_parse_inst_t cmd_route_add3 = {
-       .f = cmd_route_add3_parsed,
+static cmdline_parse_inst_t cmd_route = {
+       .f = cmd_route_parsed,
        .data = NULL,
-       .help_str = "Route add (qinq = yes, arp = no)",
+       .help_str = "route add / add default / del / del default / ls",
        .tokens = {
-               (void *)&cmd_route_add3_p_string,
-               (void *)&cmd_route_add3_p,
-               (void *)&cmd_route_add3_route_string,
-               (void *)&cmd_route_add3_add_string,
-               (void *)&cmd_route_add3_ip,
-               (void *)&cmd_route_add3_depth,
-               (void *)&cmd_route_add3_port_string,
-               (void *)&cmd_route_add3_port,
-               (void *)&cmd_route_add3_ether_string,
-               (void *)&cmd_route_add3_macaddr,
-               (void *)&cmd_route_add3_qinq_string,
-               (void *)&cmd_route_add3_svlan,
-               (void *)&cmd_route_add3_cvlan,
+               (void *)&cmd_route_p_string,
+               (void *)&cmd_route_p,
+               (void *)&cmd_route_route_string,
+               (void *)&cmd_route_multi_string,
                NULL,
        },
 };
 
 /*
- * route add (mpls = no, qinq = yes, arp = yes)
+ * arp
+ *
+ * arp add:
+ *    p <pipelineid> arp add <portid> <ipaddr> <macaddr>
+ *
+ * arp add default:
+ *    p <pipelineid> arp add default <portid>
+ *
+ * arp del:
+ *    p <pipelineid> arp del <portid> <ipaddr>
+ *
+ * arp del default:
+ *    p <pipelineid> arp del default
+ *
+ * arp ls:
+ *    p <pipelineid> arp ls
  */
 
-struct cmd_route_add4_result {
+struct cmd_arp_result {
        cmdline_fixed_string_t p_string;
        uint32_t p;
-       cmdline_fixed_string_t route_string;
-       cmdline_fixed_string_t add_string;
-       cmdline_ipaddr_t ip;
-       uint32_t depth;
-       cmdline_fixed_string_t port_string;
-       uint32_t port;
-       cmdline_fixed_string_t ether_string;
-       cmdline_ipaddr_t nh_ip;
-       cmdline_fixed_string_t qinq_string;
-       uint32_t svlan;
-       uint32_t cvlan;
+       cmdline_fixed_string_t arp_string;
+       cmdline_multi_string_t multi_string;
 };
 
 static void
-cmd_route_add4_parsed(
+cmd_arp_parsed(
        void *parsed_result,
        __rte_unused struct cmdline *cl,
        void *data)
 {
-       struct cmd_route_add4_result *params = parsed_result;
+       struct cmd_arp_result *params = parsed_result;
        struct app_params *app = data;
-       struct pipeline_routing_route_key key;
-       struct pipeline_routing_route_data route_data;
-       int status;
 
-       /* Create route */
-       key.type = PIPELINE_ROUTING_ROUTE_IPV4;
-       key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
-       key.key.ipv4.depth = params->depth;
-
-       route_data.flags = PIPELINE_ROUTING_ROUTE_QINQ |
-               PIPELINE_ROUTING_ROUTE_ARP;
-       route_data.port_id = params->port;
-       route_data.ethernet.ip =
-               rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
-       route_data.l2.qinq.svlan = params->svlan;
-       route_data.l2.qinq.cvlan = params->cvlan;
-
-       status = app_pipeline_routing_add_route(app,
-               params->p,
-               &key,
-               &route_data);
+       char *tokens[16];
+       uint32_t n_tokens = RTE_DIM(tokens);
+       int status;
 
+       status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
        if (status != 0) {
-               printf("Command failed\n");
+               printf(CMD_MSG_TOO_MANY_ARGS, "arp");
                return;
        }
-}
-
-static cmdline_parse_token_string_t cmd_route_add4_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, p_string,
-       "p");
-
-static cmdline_parse_token_num_t cmd_route_add4_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add4_route_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, route_string,
-       "route");
-
-static cmdline_parse_token_string_t cmd_route_add4_add_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, add_string,
-       "add");
 
-static cmdline_parse_token_ipaddr_t cmd_route_add4_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_route_add4_result, ip);
+       /* arp add */
+       if ((n_tokens >= 2) &&
+               (strcmp(tokens[0], "add") == 0) &&
+               strcmp(tokens[1], "default")) {
+               struct pipeline_routing_arp_key key;
+               struct in_addr ipv4;
+               struct ether_addr mac_addr;
+               uint32_t port_id;
 
-static cmdline_parse_token_num_t cmd_route_add4_depth =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, depth, UINT32);
+               memset(&key, 0, sizeof(key));
 
-static cmdline_parse_token_string_t cmd_route_add4_port_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, port_string,
-       "port");
-
-static cmdline_parse_token_num_t cmd_route_add4_port =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, port, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add4_ether_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, ether_string,
-       "ether");
-
-static cmdline_parse_token_ipaddr_t cmd_route_add4_nh_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_route_add4_result, nh_ip);
-
-static cmdline_parse_token_string_t cmd_route_add4_qinq_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, qinq_string,
-       "qinq");
-
-static cmdline_parse_token_num_t cmd_route_add4_svlan =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, svlan, UINT32);
-
-static cmdline_parse_token_num_t cmd_route_add4_cvlan =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, cvlan, UINT32);
-
-static cmdline_parse_inst_t cmd_route_add4 = {
-       .f = cmd_route_add4_parsed,
-       .data = NULL,
-       .help_str = "Route add (qinq = yes, arp = yes)",
-       .tokens = {
-               (void *)&cmd_route_add4_p_string,
-               (void *)&cmd_route_add4_p,
-               (void *)&cmd_route_add4_route_string,
-               (void *)&cmd_route_add4_add_string,
-               (void *)&cmd_route_add4_ip,
-               (void *)&cmd_route_add4_depth,
-               (void *)&cmd_route_add4_port_string,
-               (void *)&cmd_route_add4_port,
-               (void *)&cmd_route_add4_ether_string,
-               (void *)&cmd_route_add4_nh_ip,
-               (void *)&cmd_route_add4_qinq_string,
-               (void *)&cmd_route_add4_svlan,
-               (void *)&cmd_route_add4_cvlan,
-               NULL,
-       },
-};
-
-/*
- * route add (mpls = yes, qinq = no, arp = no)
- */
-
-struct cmd_route_add5_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t route_string;
-       cmdline_fixed_string_t add_string;
-       cmdline_ipaddr_t ip;
-       uint32_t depth;
-       cmdline_fixed_string_t port_string;
-       uint32_t port;
-       cmdline_fixed_string_t ether_string;
-       struct ether_addr macaddr;
-       cmdline_fixed_string_t mpls_string;
-       cmdline_fixed_string_t mpls_labels;
-};
+               if (n_tokens != 4) {
+                       printf(CMD_MSG_MISMATCH_ARGS, "arp add");
+                       return;
+               }
 
-static void
-cmd_route_add5_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_route_add5_result *params = parsed_result;
-       struct app_params *app = data;
-       struct pipeline_routing_route_key key;
-       struct pipeline_routing_route_data route_data;
-       uint32_t mpls_labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
-       uint32_t n_labels = RTE_DIM(mpls_labels);
-       uint32_t i;
-       int status;
+               if (parser_read_uint32(&port_id, tokens[1])) {
+                       printf(CMD_MSG_INVALID_ARG, "portid");
+                       return;
+               }
 
-       /* Parse MPLS labels */
-       status = parse_labels(params->mpls_labels, mpls_labels, &n_labels);
-       if (status) {
-               printf("MPLS labels parse error\n");
-               return;
-       }
+               if (parse_ipv4_addr(tokens[2], &ipv4)) {
+                       printf(CMD_MSG_INVALID_ARG, "ipaddr");
+                       return;
+               }
 
-       /* Create route */
-       key.type = PIPELINE_ROUTING_ROUTE_IPV4;
-       key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
-       key.key.ipv4.depth = params->depth;
+               if (parse_mac_addr(tokens[3], &mac_addr)) {
+                       printf(CMD_MSG_INVALID_ARG, "macaddr");
+                       return;
+               }
 
-       route_data.flags = PIPELINE_ROUTING_ROUTE_MPLS;
-       route_data.port_id = params->port;
-       route_data.ethernet.macaddr = params->macaddr;
-       for (i = 0; i < n_labels; i++)
-               route_data.l2.mpls.labels[i] = mpls_labels[i];
-       route_data.l2.mpls.n_labels = n_labels;
+               key.type = PIPELINE_ROUTING_ARP_IPV4;
+               key.key.ipv4.port_id = port_id;
+               key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
 
-       status = app_pipeline_routing_add_route(app,
-               params->p,
-               &key,
-               &route_data);
+               status = app_pipeline_routing_add_arp_entry(app,
+                       params->p,
+                       &key,
+                       &mac_addr);
+               if (status != 0)
+                       printf(CMD_MSG_FAIL, "arp add");
 
-       if (status != 0) {
-               printf("Command failed\n");
                return;
-       }
-}
+       } /* arp add */
 
-static cmdline_parse_token_string_t cmd_route_add5_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, p_string,
-       "p");
+       /* arp add default */
+       if ((n_tokens >= 2) &&
+               (strcmp(tokens[0], "add") == 0) &&
+               (strcmp(tokens[1], "default") == 0)) {
+               uint32_t port_id;
 
-static cmdline_parse_token_num_t cmd_route_add5_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add5_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add5_route_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, route_string,
-       "route");
+               if (n_tokens != 3) {
+                       printf(CMD_MSG_MISMATCH_ARGS, "arp add default");
+                       return;
+               }
 
-static cmdline_parse_token_string_t cmd_route_add5_add_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, add_string,
-       "add");
+               if (parser_read_uint32(&port_id, tokens[2])) {
+                       printf(CMD_MSG_INVALID_ARG, "portid");
+                       return;
+               }
 
-static cmdline_parse_token_ipaddr_t cmd_route_add5_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_route_add5_result, ip);
+               status = app_pipeline_routing_add_default_arp_entry(app,
+                       params->p,
+                       port_id);
+               if (status != 0)
+                       printf(CMD_MSG_FAIL, "arp add default");
 
-static cmdline_parse_token_num_t cmd_route_add5_depth =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add5_result, depth, UINT32);
+               return;
+       } /* arp add default */
 
-static cmdline_parse_token_string_t cmd_route_add5_port_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, port_string,
-       "port");
+       /* arp del*/
+       if ((n_tokens >= 2) &&
+               (strcmp(tokens[0], "del") == 0) &&
+               strcmp(tokens[1], "default")) {
+               struct pipeline_routing_arp_key key;
+               struct in_addr ipv4;
+               uint32_t port_id;
 
-static cmdline_parse_token_num_t cmd_route_add5_port =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add5_result, port, UINT32);
+               memset(&key, 0, sizeof(key));
 
-static cmdline_parse_token_string_t cmd_route_add5_ether_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, ether_string,
-       "ether");
+               if (n_tokens != 3) {
+                       printf(CMD_MSG_MISMATCH_ARGS, "arp del");
+                       return;
+               }
 
-static cmdline_parse_token_etheraddr_t cmd_route_add5_macaddr =
-       TOKEN_ETHERADDR_INITIALIZER(struct cmd_route_add5_result, macaddr);
+               if (parser_read_uint32(&port_id, tokens[1])) {
+                       printf(CMD_MSG_INVALID_ARG, "portid");
+                       return;
+               }
 
-static cmdline_parse_token_string_t cmd_route_add5_mpls_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, mpls_string,
-       "mpls");
+               if (parse_ipv4_addr(tokens[2], &ipv4)) {
+                       printf(CMD_MSG_INVALID_ARG, "ipaddr");
+                       return;
+               }
 
-static cmdline_parse_token_string_t cmd_route_add5_mpls_labels =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, mpls_labels,
-       NULL);
+               key.type = PIPELINE_ROUTING_ARP_IPV4;
+               key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
+               key.key.ipv4.port_id = port_id;
 
-static cmdline_parse_inst_t cmd_route_add5 = {
-       .f = cmd_route_add5_parsed,
-       .data = NULL,
-       .help_str = "Route add (mpls = yes, arp = no)",
-       .tokens = {
-               (void *)&cmd_route_add5_p_string,
-               (void *)&cmd_route_add5_p,
-               (void *)&cmd_route_add5_route_string,
-               (void *)&cmd_route_add5_add_string,
-               (void *)&cmd_route_add5_ip,
-               (void *)&cmd_route_add5_depth,
-               (void *)&cmd_route_add5_port_string,
-               (void *)&cmd_route_add5_port,
-               (void *)&cmd_route_add5_ether_string,
-               (void *)&cmd_route_add5_macaddr,
-               (void *)&cmd_route_add5_mpls_string,
-               (void *)&cmd_route_add5_mpls_labels,
-               NULL,
-       },
-};
+               status = app_pipeline_routing_delete_arp_entry(app,
+                       params->p,
+                       &key);
+               if (status != 0)
+                       printf(CMD_MSG_FAIL, "arp del");
 
-/*
- * route add (mpls = yes, qinq = no, arp = yes)
- */
+               return;
+       } /* arp del */
+
+       /* arp del default */
+       if ((n_tokens >= 2) &&
+               (strcmp(tokens[0], "del") == 0) &&
+               (strcmp(tokens[1], "default") == 0)) {
+                       if (n_tokens != 2) {
+                               printf(CMD_MSG_MISMATCH_ARGS, "arp del default");
+                               return;
+                       }
+
+                       status = app_pipeline_routing_delete_default_arp_entry(app,
+                               params->p);
+                       if (status != 0)
+                               printf(CMD_MSG_FAIL, "arp del default");
+
+                       return;
+       } /* arp del default */
+
+       /* arp ls */
+       if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
+               if (n_tokens != 1) {
+                       printf(CMD_MSG_MISMATCH_ARGS, "arp ls");
+                       return;
+               }
 
-struct cmd_route_add6_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t route_string;
-       cmdline_fixed_string_t add_string;
-       cmdline_ipaddr_t ip;
-       uint32_t depth;
-       cmdline_fixed_string_t port_string;
-       uint32_t port;
-       cmdline_fixed_string_t ether_string;
-       cmdline_ipaddr_t nh_ip;
-       cmdline_fixed_string_t mpls_string;
-       cmdline_fixed_string_t mpls_labels;
-};
+               status = app_pipeline_routing_arp_ls(app, params->p);
+               if (status != 0)
+                       printf(CMD_MSG_FAIL, "arp ls");
 
-static void
-cmd_route_add6_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_route_add6_result *params = parsed_result;
-       struct app_params *app = data;
-       struct pipeline_routing_route_key key;
-       struct pipeline_routing_route_data route_data;
-       uint32_t mpls_labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
-       uint32_t n_labels = RTE_DIM(mpls_labels);
-       uint32_t i;
-       int status;
-
-       /* Parse MPLS labels */
-       status = parse_labels(params->mpls_labels, mpls_labels, &n_labels);
-       if (status) {
-               printf("MPLS labels parse error\n");
-               return;
-       }
-
-       /* Create route */
-       key.type = PIPELINE_ROUTING_ROUTE_IPV4;
-       key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
-       key.key.ipv4.depth = params->depth;
-
-       route_data.flags = PIPELINE_ROUTING_ROUTE_MPLS |
-               PIPELINE_ROUTING_ROUTE_ARP;
-       route_data.port_id = params->port;
-       route_data.ethernet.ip =
-               rte_bswap32((uint32_t) params->nh_ip.addr.ipv4.s_addr);
-       for (i = 0; i < n_labels; i++)
-               route_data.l2.mpls.labels[i] = mpls_labels[i];
-       route_data.l2.mpls.n_labels = n_labels;
-
-       status = app_pipeline_routing_add_route(app,
-               params->p,
-               &key,
-               &route_data);
-
-       if (status != 0) {
-               printf("Command failed\n");
-               return;
-       }
-}
-
-static cmdline_parse_token_string_t cmd_route_add6_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, p_string,
-       "p");
-
-static cmdline_parse_token_num_t cmd_route_add6_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add6_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add6_route_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, route_string,
-       "route");
-
-static cmdline_parse_token_string_t cmd_route_add6_add_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, add_string,
-       "add");
-
-static cmdline_parse_token_ipaddr_t cmd_route_add6_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_route_add6_result, ip);
-
-static cmdline_parse_token_num_t cmd_route_add6_depth =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add6_result, depth, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add6_port_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, port_string,
-       "port");
-
-static cmdline_parse_token_num_t cmd_route_add6_port =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add6_result, port, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add6_ether_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, ether_string,
-       "ether");
-
-static cmdline_parse_token_ipaddr_t cmd_route_add6_nh_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_route_add6_result, nh_ip);
-
-static cmdline_parse_token_string_t cmd_route_add6_mpls_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, mpls_string,
-       "mpls");
-
-static cmdline_parse_token_string_t cmd_route_add6_mpls_labels =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add6_result, mpls_labels,
-       NULL);
-
-static cmdline_parse_inst_t cmd_route_add6 = {
-       .f = cmd_route_add6_parsed,
-       .data = NULL,
-       .help_str = "Route add (mpls = yes, arp = yes)",
-       .tokens = {
-               (void *)&cmd_route_add6_p_string,
-               (void *)&cmd_route_add6_p,
-               (void *)&cmd_route_add6_route_string,
-               (void *)&cmd_route_add6_add_string,
-               (void *)&cmd_route_add6_ip,
-               (void *)&cmd_route_add6_depth,
-               (void *)&cmd_route_add6_port_string,
-               (void *)&cmd_route_add6_port,
-               (void *)&cmd_route_add6_ether_string,
-               (void *)&cmd_route_add6_nh_ip,
-               (void *)&cmd_route_add6_mpls_string,
-               (void *)&cmd_route_add6_mpls_labels,
-               NULL,
-       },
-};
-
-/*
- * route del
- */
-
-struct cmd_route_del_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t route_string;
-       cmdline_fixed_string_t del_string;
-       cmdline_ipaddr_t ip;
-       uint32_t depth;
-};
-
-static void
-cmd_route_del_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_route_del_result *params = parsed_result;
-       struct app_params *app = data;
-       struct pipeline_routing_route_key key;
-
-       int status;
-
-       /* Create route */
-       key.type = PIPELINE_ROUTING_ROUTE_IPV4;
-       key.key.ipv4.ip = rte_bswap32((uint32_t) params->ip.addr.ipv4.s_addr);
-       key.key.ipv4.depth = params->depth;
-
-       status = app_pipeline_routing_delete_route(app, params->p, &key);
-
-       if (status != 0) {
-               printf("Command failed\n");
-               return;
-       }
-}
-
-static cmdline_parse_token_string_t cmd_route_del_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, p_string,
-       "p");
-
-static cmdline_parse_token_num_t cmd_route_del_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_del_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_del_route_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, route_string,
-       "route");
-
-static cmdline_parse_token_string_t cmd_route_del_del_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_del_result, del_string,
-       "del");
-
-static cmdline_parse_token_ipaddr_t cmd_route_del_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_route_del_result, ip);
-
-static cmdline_parse_token_num_t cmd_route_del_depth =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_del_result, depth, UINT32);
-
-static cmdline_parse_inst_t cmd_route_del = {
-       .f = cmd_route_del_parsed,
-       .data = NULL,
-       .help_str = "Route delete",
-       .tokens = {
-               (void *)&cmd_route_del_p_string,
-               (void *)&cmd_route_del_p,
-               (void *)&cmd_route_del_route_string,
-               (void *)&cmd_route_del_del_string,
-               (void *)&cmd_route_del_ip,
-               (void *)&cmd_route_del_depth,
-               NULL,
-       },
-};
-
-/*
- * route add default
- */
-
-struct cmd_route_add_default_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t route_string;
-       cmdline_fixed_string_t add_string;
-       cmdline_fixed_string_t default_string;
-       uint32_t port;
-};
-
-static void
-cmd_route_add_default_parsed(
-       void *parsed_result,
-       __attribute__((unused)) struct cmdline *cl,
-       void *data)
-{
-       struct cmd_route_add_default_result *params = parsed_result;
-       struct app_params *app = data;
-       int status;
-
-       status = app_pipeline_routing_add_default_route(app, params->p,
-                       params->port);
-
-       if (status != 0) {
-               printf("Command failed\n");
-               return;
-       }
-}
-
-static cmdline_parse_token_string_t cmd_route_add_default_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add_default_result, p_string,
-       "p");
-
-static cmdline_parse_token_num_t cmd_route_add_default_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add_default_result, p, UINT32);
-
-cmdline_parse_token_string_t cmd_route_add_default_route_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add_default_result,
-               route_string, "route");
-
-cmdline_parse_token_string_t cmd_route_add_default_add_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add_default_result,
-               add_string, "add");
-
-cmdline_parse_token_string_t cmd_route_add_default_default_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_add_default_result,
-       default_string, "default");
-
-cmdline_parse_token_num_t cmd_route_add_default_port =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_add_default_result,
-               port, UINT32);
-
-cmdline_parse_inst_t cmd_route_add_default = {
-       .f = cmd_route_add_default_parsed,
-       .data = NULL,
-       .help_str = "Route default set",
-       .tokens = {
-               (void *)&cmd_route_add_default_p_string,
-               (void *)&cmd_route_add_default_p,
-               (void *)&cmd_route_add_default_route_string,
-               (void *)&cmd_route_add_default_add_string,
-               (void *)&cmd_route_add_default_default_string,
-               (void *)&cmd_route_add_default_port,
-               NULL,
-       },
-};
-
-/*
- * route del default
- */
-
-struct cmd_route_del_default_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t route_string;
-       cmdline_fixed_string_t del_string;
-       cmdline_fixed_string_t default_string;
-};
-
-static void
-cmd_route_del_default_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-        void *data)
-{
-       struct cmd_route_del_default_result *params = parsed_result;
-       struct app_params *app = data;
-       int status;
-
-       status = app_pipeline_routing_delete_default_route(app, params->p);
-
-       if (status != 0) {
-               printf("Command failed\n");
-               return;
-       }
-}
-
-static cmdline_parse_token_string_t cmd_route_del_default_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_del_default_result, p_string,
-       "p");
-
-static cmdline_parse_token_num_t cmd_route_del_default_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_del_default_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_del_default_route_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_del_default_result,
-               route_string, "route");
-
-static cmdline_parse_token_string_t cmd_route_del_default_del_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_del_default_result,
-               del_string, "del");
-
-static cmdline_parse_token_string_t cmd_route_del_default_default_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_del_default_result,
-       default_string, "default");
-
-
-static cmdline_parse_inst_t cmd_route_del_default = {
-       .f = cmd_route_del_default_parsed,
-       .data = NULL,
-       .help_str = "Route default clear",
-       .tokens = {
-               (void *)&cmd_route_del_default_p_string,
-               (void *)&cmd_route_del_default_p,
-               (void *)&cmd_route_del_default_route_string,
-               (void *)&cmd_route_del_default_del_string,
-               (void *)&cmd_route_del_default_default_string,
-               NULL,
-       },
-};
-
-/*
- * route ls
- */
-
-struct cmd_route_ls_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t route_string;
-       cmdline_fixed_string_t ls_string;
-};
-
-static void
-cmd_route_ls_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_route_ls_result *params = parsed_result;
-       struct app_params *app = data;
-       int status;
-
-       status = app_pipeline_routing_route_ls(app, params->p);
-
-       if (status != 0) {
-               printf("Command failed\n");
-               return;
-       }
-}
-
-static cmdline_parse_token_string_t cmd_route_ls_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_ls_result, p_string, "p");
-
-static cmdline_parse_token_num_t cmd_route_ls_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_route_ls_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_ls_route_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_ls_result,
-       route_string, "route");
-
-static cmdline_parse_token_string_t cmd_route_ls_ls_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_route_ls_result, ls_string,
-       "ls");
-
-static cmdline_parse_inst_t cmd_route_ls = {
-       .f = cmd_route_ls_parsed,
-       .data = NULL,
-       .help_str = "Route list",
-       .tokens = {
-               (void *)&cmd_route_ls_p_string,
-               (void *)&cmd_route_ls_p,
-               (void *)&cmd_route_ls_route_string,
-               (void *)&cmd_route_ls_ls_string,
-               NULL,
-       },
-};
-
-/*
- * arp add
- */
-
-struct cmd_arp_add_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t arp_string;
-       cmdline_fixed_string_t add_string;
-       uint32_t port_id;
-       cmdline_ipaddr_t ip;
-       struct ether_addr macaddr;
-
-};
-
-static void
-cmd_arp_add_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_arp_add_result *params = parsed_result;
-       struct app_params *app = data;
-
-       struct pipeline_routing_arp_key key;
-       int status;
-
-       key.type = PIPELINE_ROUTING_ARP_IPV4;
-       key.key.ipv4.port_id = params->port_id;
-       key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
-
-       status = app_pipeline_routing_add_arp_entry(app,
-               params->p,
-               &key,
-               &params->macaddr);
-
-       if (status != 0) {
-               printf("Command failed\n");
-               return;
-       }
-}
-
-static cmdline_parse_token_string_t cmd_arp_add_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, p_string,
-       "p");
-
-static cmdline_parse_token_num_t cmd_arp_add_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_arp_add_arp_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, arp_string, "arp");
-
-static cmdline_parse_token_string_t cmd_arp_add_add_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_add_result, add_string, "add");
-
-static cmdline_parse_token_num_t cmd_arp_add_port_id =
-       TOKEN_NUM_INITIALIZER(struct cmd_arp_add_result, port_id, UINT32);
-
-static cmdline_parse_token_ipaddr_t cmd_arp_add_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_arp_add_result, ip);
-
-static cmdline_parse_token_etheraddr_t cmd_arp_add_macaddr =
-       TOKEN_ETHERADDR_INITIALIZER(struct cmd_arp_add_result, macaddr);
-
-static cmdline_parse_inst_t cmd_arp_add = {
-       .f = cmd_arp_add_parsed,
-       .data = NULL,
-       .help_str = "ARP add",
-       .tokens = {
-               (void *)&cmd_arp_add_p_string,
-               (void *)&cmd_arp_add_p,
-               (void *)&cmd_arp_add_arp_string,
-               (void *)&cmd_arp_add_add_string,
-               (void *)&cmd_arp_add_port_id,
-               (void *)&cmd_arp_add_ip,
-               (void *)&cmd_arp_add_macaddr,
-               NULL,
-       },
-};
-
-/*
- * arp del
- */
-
-struct cmd_arp_del_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t arp_string;
-       cmdline_fixed_string_t del_string;
-       uint32_t port_id;
-       cmdline_ipaddr_t ip;
-};
-
-static void
-cmd_arp_del_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_arp_del_result *params = parsed_result;
-       struct app_params *app = data;
-
-       struct pipeline_routing_arp_key key;
-       int status;
-
-       key.type = PIPELINE_ROUTING_ARP_IPV4;
-       key.key.ipv4.ip = rte_cpu_to_be_32(params->ip.addr.ipv4.s_addr);
-       key.key.ipv4.port_id = params->port_id;
-
-       status = app_pipeline_routing_delete_arp_entry(app, params->p, &key);
-
-       if (status != 0) {
-               printf("Command failed\n");
-               return;
-       }
-}
-
-static cmdline_parse_token_string_t cmd_arp_del_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, p_string,
-       "p");
-
-static cmdline_parse_token_num_t cmd_arp_del_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_arp_del_arp_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, arp_string, "arp");
-
-static cmdline_parse_token_string_t cmd_arp_del_del_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_del_result, del_string, "del");
-
-static cmdline_parse_token_num_t cmd_arp_del_port_id =
-       TOKEN_NUM_INITIALIZER(struct cmd_arp_del_result, port_id, UINT32);
-
-static cmdline_parse_token_ipaddr_t cmd_arp_del_ip =
-       TOKEN_IPV4_INITIALIZER(struct cmd_arp_del_result, ip);
-
-static cmdline_parse_inst_t cmd_arp_del = {
-       .f = cmd_arp_del_parsed,
-       .data = NULL,
-       .help_str = "ARP delete",
-       .tokens = {
-               (void *)&cmd_arp_del_p_string,
-               (void *)&cmd_arp_del_p,
-               (void *)&cmd_arp_del_arp_string,
-               (void *)&cmd_arp_del_del_string,
-               (void *)&cmd_arp_del_port_id,
-               (void *)&cmd_arp_del_ip,
-               NULL,
-       },
-};
-
-/*
- * arp add default
- */
-
-struct cmd_arp_add_default_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t arp_string;
-       cmdline_fixed_string_t add_string;
-       cmdline_fixed_string_t default_string;
-       uint32_t port_id;
-};
-
-static void
-cmd_arp_add_default_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_arp_add_default_result *params = parsed_result;
-       struct app_params *app = data;
-
-       int status;
-
-       status = app_pipeline_routing_add_default_arp_entry(app,
-               params->p,
-               params->port_id);
-
-       if (status != 0) {
-               printf("Command failed\n");
-               return;
-       }
-}
-
-static cmdline_parse_token_string_t cmd_arp_add_default_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_add_default_result, p_string,
-       "p");
-
-static cmdline_parse_token_num_t cmd_arp_add_default_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_arp_add_default_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_arp_add_default_arp_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_add_default_result, arp_string,
-       "arp");
-
-static cmdline_parse_token_string_t cmd_arp_add_default_add_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_add_default_result, add_string,
-       "add");
-
-static cmdline_parse_token_string_t cmd_arp_add_default_default_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_add_default_result,
-               default_string, "default");
-
-static cmdline_parse_token_num_t cmd_arp_add_default_port_id =
-       TOKEN_NUM_INITIALIZER(struct cmd_arp_add_default_result, port_id,
-       UINT32);
-
-static cmdline_parse_inst_t cmd_arp_add_default = {
-       .f = cmd_arp_add_default_parsed,
-       .data = NULL,
-       .help_str = "ARP add default",
-       .tokens = {
-               (void *)&cmd_arp_add_default_p_string,
-               (void *)&cmd_arp_add_default_p,
-               (void *)&cmd_arp_add_default_arp_string,
-               (void *)&cmd_arp_add_default_add_string,
-               (void *)&cmd_arp_add_default_default_string,
-               (void *)&cmd_arp_add_default_port_id,
-               NULL,
-       },
-};
-
-/*
- * arp del default
- */
-
-struct cmd_arp_del_default_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t arp_string;
-       cmdline_fixed_string_t del_string;
-       cmdline_fixed_string_t default_string;
-};
-
-static void
-cmd_arp_del_default_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_arp_del_default_result *params = parsed_result;
-       struct app_params *app = data;
-
-       int status;
-
-       status = app_pipeline_routing_delete_default_arp_entry(app, params->p);
-
-       if (status != 0) {
-               printf("Command failed\n");
-               return;
-       }
-}
-
-static cmdline_parse_token_string_t cmd_arp_del_default_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_del_default_result, p_string,
-       "p");
-
-static cmdline_parse_token_num_t cmd_arp_del_default_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_arp_del_default_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_arp_del_default_arp_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_del_default_result, arp_string,
-       "arp");
-
-static cmdline_parse_token_string_t cmd_arp_del_default_del_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_del_default_result, del_string,
-       "del");
-
-static cmdline_parse_token_string_t cmd_arp_del_default_default_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_del_default_result,
-               default_string, "default");
-
-static cmdline_parse_inst_t cmd_arp_del_default = {
-       .f = cmd_arp_del_default_parsed,
-       .data = NULL,
-       .help_str = "ARP delete default",
-       .tokens = {
-               (void *)&cmd_arp_del_default_p_string,
-               (void *)&cmd_arp_del_default_p,
-               (void *)&cmd_arp_del_default_arp_string,
-               (void *)&cmd_arp_del_default_del_string,
-               (void *)&cmd_arp_del_default_default_string,
-               NULL,
-       },
-};
-
-/*
- * arp ls
- */
-
-struct cmd_arp_ls_result {
-       cmdline_fixed_string_t p_string;
-       uint32_t p;
-       cmdline_fixed_string_t arp_string;
-       cmdline_fixed_string_t ls_string;
-};
-
-static void
-cmd_arp_ls_parsed(
-       void *parsed_result,
-       __rte_unused struct cmdline *cl,
-       void *data)
-{
-       struct cmd_arp_ls_result *params = parsed_result;
-       struct app_params *app = data;
-       struct pipeline_routing *p;
-
-       p = app_pipeline_data_fe(app, params->p, &pipeline_routing);
-       if (p == NULL)
                return;
+       } /* arp ls */
 
-       app_pipeline_routing_arp_ls(app, params->p);
+       printf(CMD_MSG_FAIL, "arp");
 }
 
-static cmdline_parse_token_string_t cmd_arp_ls_p_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, p_string,
-       "p");
+static cmdline_parse_token_string_t cmd_arp_p_string =
+       TOKEN_STRING_INITIALIZER(struct cmd_arp_result, p_string, "p");
 
-static cmdline_parse_token_num_t cmd_arp_ls_p =
-       TOKEN_NUM_INITIALIZER(struct cmd_arp_ls_result, p, UINT32);
+static cmdline_parse_token_num_t cmd_arp_p =
+       TOKEN_NUM_INITIALIZER(struct cmd_arp_result, p, UINT32);
 
-static cmdline_parse_token_string_t cmd_arp_ls_arp_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, arp_string,
-       "arp");
+static cmdline_parse_token_string_t cmd_arp_arp_string =
+       TOKEN_STRING_INITIALIZER(struct cmd_arp_result, arp_string, "arp");
 
-static cmdline_parse_token_string_t cmd_arp_ls_ls_string =
-       TOKEN_STRING_INITIALIZER(struct cmd_arp_ls_result, ls_string,
-       "ls");
+static cmdline_parse_token_string_t cmd_arp_multi_string =
+       TOKEN_STRING_INITIALIZER(struct cmd_arp_result, multi_string,
+       TOKEN_STRING_MULTI);
 
-static cmdline_parse_inst_t cmd_arp_ls = {
-       .f = cmd_arp_ls_parsed,
+static cmdline_parse_inst_t cmd_arp = {
+       .f = cmd_arp_parsed,
        .data = NULL,
-       .help_str = "ARP list",
+       .help_str = "arp add / add default / del / del default / ls",
        .tokens = {
-               (void *)&cmd_arp_ls_p_string,
-               (void *)&cmd_arp_ls_p,
-               (void *)&cmd_arp_ls_arp_string,
-               (void *)&cmd_arp_ls_ls_string,
+               (void *)&cmd_arp_p_string,
+               (void *)&cmd_arp_p,
+               (void *)&cmd_arp_arp_string,
+               (void *)&cmd_arp_multi_string,
                NULL,
        },
 };
 
 static cmdline_parse_ctx_t pipeline_cmds[] = {
-       (cmdline_parse_inst_t *)&cmd_route_add1,
-       (cmdline_parse_inst_t *)&cmd_route_add2,
-       (cmdline_parse_inst_t *)&cmd_route_add3,
-       (cmdline_parse_inst_t *)&cmd_route_add4,
-       (cmdline_parse_inst_t *)&cmd_route_add5,
-       (cmdline_parse_inst_t *)&cmd_route_add6,
-       (cmdline_parse_inst_t *)&cmd_route_del,
-       (cmdline_parse_inst_t *)&cmd_route_add_default,
-       (cmdline_parse_inst_t *)&cmd_route_del_default,
-       (cmdline_parse_inst_t *)&cmd_route_ls,
-       (cmdline_parse_inst_t *)&cmd_arp_add,
-       (cmdline_parse_inst_t *)&cmd_arp_del,
-       (cmdline_parse_inst_t *)&cmd_arp_add_default,
-       (cmdline_parse_inst_t *)&cmd_arp_del_default,
-       (cmdline_parse_inst_t *)&cmd_arp_ls,
+       (cmdline_parse_inst_t *)&cmd_route,
+       (cmdline_parse_inst_t *)&cmd_arp,
        NULL,
 };
 
 static struct pipeline_fe_ops pipeline_routing_fe_ops = {
-       .f_init = pipeline_routing_init,
+       .f_init = app_pipeline_routing_init,
+       .f_post_init = app_pipeline_routing_post_init,
        .f_free = app_pipeline_routing_free,
+       .f_track = app_pipeline_track_default,
        .cmds = pipeline_cmds,
 };