[dpdk-dev] [PATCH v2 6/7] examples/ip_pipeline: modifies routing pipeline CLI

Piotr Azarewicz piotrx.t.azarewicz at intel.com
Fri May 20 16:35:39 CEST 2016


Several routing commands are merged into two commands:
route and arp - these two commands are handled by cli library.
Rest of the commands are handled internaly by the pipeline code.

Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz at intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu at intel.com>
---
 examples/ip_pipeline/config/l2fwd.cfg            |    5 +-
 examples/ip_pipeline/config/l3fwd.cfg            |    9 +-
 examples/ip_pipeline/config/l3fwd.sh             |   32 +-
 examples/ip_pipeline/config/l3fwd_arp.cfg        |   70 +
 examples/ip_pipeline/config/l3fwd_arp.sh         |   43 +
 examples/ip_pipeline/pipeline/pipeline_routing.c | 1636 ++++++----------------
 6 files changed, 551 insertions(+), 1244 deletions(-)
 create mode 100644 examples/ip_pipeline/config/l3fwd_arp.cfg
 create mode 100644 examples/ip_pipeline/config/l3fwd_arp.sh

diff --git a/examples/ip_pipeline/config/l2fwd.cfg b/examples/ip_pipeline/config/l2fwd.cfg
index c743a14..a1df9e6 100644
--- a/examples/ip_pipeline/config/l2fwd.cfg
+++ b/examples/ip_pipeline/config/l2fwd.cfg
@@ -1,6 +1,6 @@
 ;   BSD LICENSE
 ;
-;   Copyright(c) 2015 Intel Corporation. All rights reserved.
+;   Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
 ;   All rights reserved.
 ;
 ;   Redistribution and use in source and binary forms, with or without
@@ -44,6 +44,9 @@
 ;            |________________|
 ;
 
+[EAL]
+log_level = 0
+
 [PIPELINE0]
 type = MASTER
 core = 0
diff --git a/examples/ip_pipeline/config/l3fwd.cfg b/examples/ip_pipeline/config/l3fwd.cfg
index 5449dc3..02c8f36 100644
--- a/examples/ip_pipeline/config/l3fwd.cfg
+++ b/examples/ip_pipeline/config/l3fwd.cfg
@@ -1,6 +1,6 @@
 ;   BSD LICENSE
 ;
-;   Copyright(c) 2015 Intel Corporation. All rights reserved.
+;   Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
 ;   All rights reserved.
 ;
 ;   Redistribution and use in source and binary forms, with or without
@@ -50,6 +50,9 @@
 ; 2	Ethernet header		256 		14
 ; 3	IPv4 header		270 		20
 
+[EAL]
+log_level = 0
+
 [PIPELINE0]
 type = MASTER
 core = 0
@@ -59,5 +62,7 @@ type = ROUTING
 core = 1
 pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
 pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK0
-encap = ethernet; encap = ethernet / ethernet_qinq / ethernet_mpls
+encap = ethernet
+;encap = ethernet_qinq
+;encap = ethernet_mpls
 ip_hdr_offset = 270
diff --git a/examples/ip_pipeline/config/l3fwd.sh b/examples/ip_pipeline/config/l3fwd.sh
index 2774010..47406aa 100644
--- a/examples/ip_pipeline/config/l3fwd.sh
+++ b/examples/ip_pipeline/config/l3fwd.sh
@@ -1,9 +1,33 @@
+#
+# run ./config/l3fwd.sh
+#
+
 ################################################################################
 # Routing: encap = ethernet, arp = off
 ################################################################################
 p 1 route add default 4 #SINK0
-p 1 route add 0.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0
-p 1 route add 0.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1
-p 1 route add 0.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2
-p 1 route add 0.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3
+p 1 route add 100.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0
+p 1 route add 100.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1
+p 1 route add 100.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2
+p 1 route add 100.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3
 p 1 route ls
+
+################################################################################
+# Routing: encap = ethernet_qinq, arp = off
+################################################################################
+#p 1 route add default 4 #SINK0
+#p 1 route add 100.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0 qinq 1000 2000
+#p 1 route add 100.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1 qinq 1001 2001
+#p 1 route add 100.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2 qinq 1002 2002
+#p 1 route add 100.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3 qinq 1003 2003
+#p 1 route ls
+
+################################################################################
+# Routing: encap = ethernet_mpls, arp = off
+################################################################################
+#p 1 route add default 4 #SINK0
+#p 1 route add 100.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0 mpls 1000:2000
+#p 1 route add 100.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1 mpls 1001:2001
+#p 1 route add 100.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2 mpls 1002:2002
+#p 1 route add 100.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3 mpls 1003:2003
+#p 1 route ls
diff --git a/examples/ip_pipeline/config/l3fwd_arp.cfg b/examples/ip_pipeline/config/l3fwd_arp.cfg
new file mode 100644
index 0000000..2c63c8f
--- /dev/null
+++ b/examples/ip_pipeline/config/l3fwd_arp.cfg
@@ -0,0 +1,70 @@
+;   BSD LICENSE
+;
+;   Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
+;   All rights reserved.
+;
+;   Redistribution and use in source and binary forms, with or without
+;   modification, are permitted provided that the following conditions
+;   are met:
+;
+;     * Redistributions of source code must retain the above copyright
+;       notice, this list of conditions and the following disclaimer.
+;     * Redistributions in binary form must reproduce the above copyright
+;       notice, this list of conditions and the following disclaimer in
+;       the documentation and/or other materials provided with the
+;       distribution.
+;     * Neither the name of Intel Corporation nor the names of its
+;       contributors may be used to endorse or promote products derived
+;       from this software without specific prior written permission.
+;
+;   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+;   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+;   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+;   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+;   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+;   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+;   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+;   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+;   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+;   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+;   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;             _______________
+; RXQ0.0 --->|               |---> TXQ0.0
+;            |               |
+; RXQ1.0 --->|               |---> TXQ1.0
+;            |    Routing    |
+; RXQ2.0 --->|               |---> TXQ2.0
+;            |               |
+; RXQ3.0 --->|               |---> TXQ3.0
+;            |_______________|
+;                    |
+;                    +-----------> SINK0 (route miss)
+;
+; Input packet: Ethernet/IPv4
+;
+; Packet buffer layout:
+; #	Field Name		Offset (Bytes)	Size (Bytes)
+; 0	Mbuf			0 		128
+; 1	Headroom		128 		128
+; 2	Ethernet header		256 		14
+; 3	IPv4 header		270 		20
+
+[EAL]
+log_level = 0
+
+[PIPELINE0]
+type = MASTER
+core = 0
+
+[PIPELINE1]
+type = ROUTING
+core = 1
+pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
+pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK0
+encap = ethernet
+;encap = ethernet_qinq
+;encap = ethernet_mpls
+n_arp_entries = 1024
+ip_hdr_offset = 270
+arp_key_offset = 128
diff --git a/examples/ip_pipeline/config/l3fwd_arp.sh b/examples/ip_pipeline/config/l3fwd_arp.sh
new file mode 100644
index 0000000..20bea58
--- /dev/null
+++ b/examples/ip_pipeline/config/l3fwd_arp.sh
@@ -0,0 +1,43 @@
+#
+# run ./config/l3fwd_arp.sh
+#
+
+################################################################################
+# ARP
+################################################################################
+p 1 arp add default 4 #SINK0
+p 1 arp add 0 10.0.0.1 a0:b0:c0:d0:e0:f0
+p 1 arp add 1 11.0.0.1 a1:b1:c1:d1:e1:f1
+p 1 arp add 2 12.0.0.1 a2:b2:c2:d2:e2:f2
+p 1 arp add 3 13.0.0.1 a3:b3:c3:d3:e3:f3
+p 1 arp ls
+
+################################################################################
+# Routing: encap = ethernet, arp = on
+################################################################################
+p 1 route add default 4 #SINK0
+p 1 route add 100.0.0.0 10 port 0 ether 10.0.0.1
+p 1 route add 100.64.0.0 10 port 1 ether 11.0.0.1
+p 1 route add 100.128.0.0 10 port 2 ether 12.0.0.1
+p 1 route add 100.192.0.0 10 port 3 ether 13.0.0.1
+p 1 route ls
+
+################################################################################
+# Routing: encap = ethernet_qinq, arp = on
+################################################################################
+#p 1 route add default 4 #SINK0
+#p 1 route add 100.0.0.0 10 port 0 ether 10.0.0.1 qinq 1000 2000
+#p 1 route add 100.64.0.0 10 port 1 ether 11.0.0.1 qinq 1001 2001
+#p 1 route add 100.128.0.0 10 port 2 ether 12.0.0.1 qinq 1002 2002
+#p 1 route add 100.192.0.0 10 port 3 ether 13.0.0.1 qinq 1003 2003
+#p 1 route ls
+
+################################################################################
+# Routing: encap = ethernet_mpls, arp = on
+################################################################################
+#p 1 route add default 4 #SINK0
+#p 1 route add 100.0.0.0 10 port 0 ether 10.0.0.1 mpls 1000:2000
+#p 1 route add 100.64.0.0 10 port 1 ether 11.0.0.1 mpls 1001:2001
+#p 1 route add 100.128.0.0 10 port 2 ether 12.0.0.1 mpls 1002:2002
+#p 1 route add 100.192.0.0 10 port 3 ether 13.0.0.1 mpls 1003:2003
+#p 1 route ls
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.c b/examples/ip_pipeline/pipeline/pipeline_routing.c
index eab89f2..c68e470 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing.c
+++ b/examples/ip_pipeline/pipeline/pipeline_routing.c
@@ -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
@@ -34,12 +34,11 @@
 #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;
@@ -853,1376 +852,539 @@ 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)
-{
-	uint32_t n_max_labels = *n_labels, count = 0;
-
-	/* Check for void list of labels */
-	if (strcmp(string, "<void>") == 0) {
-		*n_labels = 0;
-		return 0;
-	}
-
-	/* At least one label should be present */
-	for ( ; (*string != '\0'); ) {
-		char *next;
-		int value;
-
-		if (count >= n_max_labels)
-			return -1;
-
-		if (count > 0) {
-			if (string[0] != ':')
-				return -1;
-
-			string++;
-		}
-
-		value = strtol(string, &next, 10);
-		if (next == string)
-			return -1;
-		string = next;
-
-		labels[count++] = (uint32_t) value;
-	}
-
-	*n_labels = count;
-	return 0;
-}
-
 /*
- * route add (mpls = no, qinq = no, arp = no)
- */
-
-struct cmd_route_add1_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;
-};
-
-static void
-cmd_route_add1_parsed(
-	void *parsed_result,
-	__rte_unused struct cmdline *cl,
-	void *data)
-{
-	struct cmd_route_add1_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);
-
-	if (status != 0) {
-		printf("Command failed\n");
-		return;
-	}
-}
-
-static cmdline_parse_token_string_t cmd_route_add1_p_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, p_string,
-	"p");
-
-static cmdline_parse_token_num_t cmd_route_add1_p =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add1_route_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, route_string,
-	"route");
-
-static cmdline_parse_token_string_t cmd_route_add1_add_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, add_string,
-	"add");
-
-static cmdline_parse_token_ipaddr_t cmd_route_add1_ip =
-	TOKEN_IPV4_INITIALIZER(struct cmd_route_add1_result, ip);
-
-static cmdline_parse_token_num_t cmd_route_add1_depth =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, depth, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add1_port_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, port_string,
-	"port");
-
-static cmdline_parse_token_num_t cmd_route_add1_port =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add1_result, port, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add1_ether_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add1_result, ether_string,
-	"ether");
-
-static cmdline_parse_token_etheraddr_t cmd_route_add1_macaddr =
-	TOKEN_ETHERADDR_INITIALIZER(struct cmd_route_add1_result, macaddr);
-
-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,
-	},
-};
-
-/*
- * route add (mpls = no, qinq = no, arp = yes)
+ * 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_add2_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;
-	cmdline_ipaddr_t nh_ip;
+	cmdline_multi_string_t multi_string;
 };
 
 static void
-cmd_route_add2_parsed(
+cmd_route_parsed(
 	void *parsed_result,
 	__rte_unused struct cmdline *cl,
 	void *data)
 {
-	struct cmd_route_add2_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 = 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);
-
-	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_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");
-
-static cmdline_parse_token_string_t cmd_route_add2_add_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, add_string,
-	"add");
-
-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");
-
-static cmdline_parse_token_num_t cmd_route_add2_port =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add2_result, port, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add2_ether_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add2_result, ether_string,
-	"ether");
-
-static cmdline_parse_token_ipaddr_t cmd_route_add2_nh_ip =
-	TOKEN_IPV4_INITIALIZER(struct cmd_route_add2_result, nh_ip);
-
-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 add (mpls = no, qinq = yes, arp = no)
- */
 
-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;
-};
-
-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;
+	char *tokens[16];
+	uint32_t n_tokens = RTE_DIM(tokens);
 	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;
-	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;
-
-	status = app_pipeline_routing_add_route(app,
-		params->p,
-		&key,
-		&route_data);
-
+	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_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");
-
-static cmdline_parse_token_string_t cmd_route_add3_add_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, add_string,
-	"add");
-
-static cmdline_parse_token_ipaddr_t cmd_route_add3_ip =
-	TOKEN_IPV4_INITIALIZER(struct cmd_route_add3_result, ip);
-
-static cmdline_parse_token_num_t cmd_route_add3_depth =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, depth, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add3_port_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, port_string,
-	"port");
 
-static cmdline_parse_token_num_t cmd_route_add3_port =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, port, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add3_ether_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, ether_string,
-	"ether");
-
-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_add3_qinq_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add3_result, qinq_string,
-	"qinq");
-
-static cmdline_parse_token_num_t cmd_route_add3_svlan =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, svlan, UINT32);
-
-static cmdline_parse_token_num_t cmd_route_add3_cvlan =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add3_result, cvlan, UINT32);
-
-static cmdline_parse_inst_t cmd_route_add3 = {
-	.f = cmd_route_add3_parsed,
-	.data = NULL,
-	.help_str = "Route add (qinq = yes, arp = no)",
-	.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,
-		NULL,
-	},
-};
-
-/*
- * route add (mpls = no, qinq = yes, arp = yes)
- */
-
-struct cmd_route_add4_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;
-};
-
-static void
-cmd_route_add4_parsed(
-	void *parsed_result,
-	__rte_unused struct cmdline *cl,
-	void *data)
-{
-	struct cmd_route_add4_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);
-
-	if (status != 0) {
-		printf("Command failed\n");
-		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);
+	/* 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_add4_depth =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, depth, UINT32);
+		if (parse_ipv4_addr(tokens[1], &ipv4)) {
+			printf(CMD_MSG_INVALID_ARG, "ipaddr");
+			return;
+		}
 
-static cmdline_parse_token_string_t cmd_route_add4_port_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, port_string,
-	"port");
+		if (parser_read_uint32(&depth, tokens[2])) {
+			printf(CMD_MSG_INVALID_ARG, "depth");
+			return;
+		}
 
-static cmdline_parse_token_num_t cmd_route_add4_port =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, port, UINT32);
+		if (strcmp(tokens[3], "port")) {
+			printf(CMD_MSG_ARG_NOT_FOUND, "port");
+			return;
+		}
 
-static cmdline_parse_token_string_t cmd_route_add4_ether_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, ether_string,
-	"ether");
+		if (parser_read_uint32(&port_id, tokens[4])) {
+			printf(CMD_MSG_INVALID_ARG, "portid");
+			return;
+		}
 
-static cmdline_parse_token_ipaddr_t cmd_route_add4_nh_ip =
-	TOKEN_IPV4_INITIALIZER(struct cmd_route_add4_result, nh_ip);
+		if (strcmp(tokens[5], "ether")) {
+			printf(CMD_MSG_ARG_NOT_FOUND, "ether");
+			return;
+		}
 
-static cmdline_parse_token_string_t cmd_route_add4_qinq_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add4_result, qinq_string,
-	"qinq");
+		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_add4_svlan =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, svlan, UINT32);
+			route_data.flags |= PIPELINE_ROUTING_ROUTE_ARP;
+		}
 
-static cmdline_parse_token_num_t cmd_route_add4_cvlan =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add4_result, cvlan, UINT32);
+		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_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,
-	},
-};
+		switch (route_data.flags) {
+		case 0:
+			route_data.port_id = port_id;
+			route_data.ethernet.macaddr = mac_addr;
+			break;
 
-/*
- * route add (mpls = yes, qinq = no, arp = no)
- */
+		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;
 
-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;
-};
+		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;
 
-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;
+		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;
 
-	/* Parse MPLS labels */
-	status = parse_labels(params->mpls_labels, mpls_labels, &n_labels);
-	if (status) {
-		printf("MPLS labels parse error\n");
-		return;
-	}
+		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_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_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_add5_p_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, p_string,
-	"p");
-
-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");
-
-static cmdline_parse_token_string_t cmd_route_add5_add_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, add_string,
-	"add");
-
-static cmdline_parse_token_ipaddr_t cmd_route_add5_ip =
-	TOKEN_IPV4_INITIALIZER(struct cmd_route_add5_result, ip);
-
-static cmdline_parse_token_num_t cmd_route_add5_depth =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add5_result, depth, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add5_port_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, port_string,
-	"port");
-
-static cmdline_parse_token_num_t cmd_route_add5_port =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add5_result, port, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_add5_ether_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, ether_string,
-	"ether");
-
-static cmdline_parse_token_etheraddr_t cmd_route_add5_macaddr =
-	TOKEN_ETHERADDR_INITIALIZER(struct cmd_route_add5_result, macaddr);
-
-static cmdline_parse_token_string_t cmd_route_add5_mpls_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, mpls_string,
-	"mpls");
-
-static cmdline_parse_token_string_t cmd_route_add5_mpls_labels =
-	TOKEN_STRING_INITIALIZER(struct cmd_route_add5_result, mpls_labels,
-	NULL);
-
-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,
-	},
-};
-
-/*
- * route add (mpls = yes, qinq = no, arp = yes)
- */
+	} /* route add */
 
-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;
-};
+	/* route add default */
+	if ((n_tokens >= 2) &&
+		(strcmp(tokens[0], "add") == 0) &&
+		(strcmp(tokens[1], "default") == 0)) {
+		uint32_t port_id;
 
-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;
+		if (n_tokens != 3) {
+			printf(CMD_MSG_MISMATCH_ARGS, "route add default");
+			return;
+		}
 
-	/* Parse MPLS labels */
-	status = parse_labels(params->mpls_labels, mpls_labels, &n_labels);
-	if (status) {
-		printf("MPLS labels parse error\n");
-		return;
-	}
+		if (parser_read_uint32(&port_id, tokens[2])) {
+			printf(CMD_MSG_INVALID_ARG, "portid");
+			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);
+		status = app_pipeline_routing_add_default_route(app,
+			params->p,
+			port_id);
+		if (status != 0)
+			printf(CMD_MSG_FAIL, "route add default");
 
-	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");
+	} /* route add default */
 
-static cmdline_parse_token_ipaddr_t cmd_route_add6_ip =
-	TOKEN_IPV4_INITIALIZER(struct cmd_route_add6_result, ip);
+	/* 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;
 
-static cmdline_parse_token_num_t cmd_route_add6_depth =
-	TOKEN_NUM_INITIALIZER(struct cmd_route_add6_result, depth, UINT32);
+		memset(&key, 0, sizeof(key));
 
-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;
-};
+		if (n_tokens != 3) {
+			printf(CMD_MSG_MISMATCH_ARGS, "route del");
+			return;
+		}
 
-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;
+		if (parse_ipv4_addr(tokens[1], &ipv4)) {
+			printf(CMD_MSG_INVALID_ARG, "ipaddr");
+			return;
+		}
 
-	int status;
+		if (parser_read_uint32(&depth, tokens[2])) {
+			printf(CMD_MSG_INVALID_ARG, "depth");
+			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;
+		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_delete_route(app, params->p, &key);
+		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_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;
+	} /* 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;
+		}
 
-	status = app_pipeline_routing_add_default_route(app, params->p,
-			params->port);
+		status = app_pipeline_routing_delete_default_route(app,
+			params->p);
+		if (status != 0)
+			printf(CMD_MSG_FAIL, "route del default");
 
-	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);
+	} /* route del default */
 
-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;
+	/* route ls */
+	if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
+		if (n_tokens != 1) {
+			printf(CMD_MSG_MISMATCH_ARGS, "route ls");
+			return;
+		}
 
-	status = app_pipeline_routing_delete_default_route(app, params->p);
+		status = app_pipeline_routing_route_ls(app, params->p);
+		if (status != 0)
+			printf(CMD_MSG_FAIL, "route ls");
 
-	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
- */
+	} /* 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;
-	}
+	printf(CMD_MSG_MISMATCH_ARGS, "route");
 }
 
-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_string_t cmd_route_p_string =
+	TOKEN_STRING_INITIALIZER(struct cmd_route_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_num_t cmd_route_p =
+	TOKEN_NUM_INITIALIZER(struct cmd_route_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_route_string =
+	TOKEN_STRING_INITIALIZER(struct cmd_route_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_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_ls = {
-	.f = cmd_route_ls_parsed,
+static cmdline_parse_inst_t cmd_route = {
+	.f = cmd_route_parsed,
 	.data = NULL,
-	.help_str = "Route list",
+	.help_str = "route add / add default / del / del default / ls",
 	.tokens = {
-		(void *)&cmd_route_ls_p_string,
-		(void *)&cmd_route_ls_p,
-		(void *)&cmd_route_ls_route_string,
-		(void *)&cmd_route_ls_ls_string,
+		(void *)&cmd_route_p_string,
+		(void *)&cmd_route_p,
+		(void *)&cmd_route_route_string,
+		(void *)&cmd_route_multi_string,
 		NULL,
 	},
 };
 
 /*
- * arp add
+ * 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_arp_add_result {
+struct cmd_arp_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;
-
+	cmdline_multi_string_t multi_string;
 };
 
 static void
-cmd_arp_add_parsed(
+cmd_arp_parsed(
 	void *parsed_result,
 	__rte_unused struct cmdline *cl,
 	void *data)
 {
-	struct cmd_arp_add_result *params = parsed_result;
+	struct cmd_arp_result *params = parsed_result;
 	struct app_params *app = data;
 
-	struct pipeline_routing_arp_key key;
+	char *tokens[16];
+	uint32_t n_tokens = RTE_DIM(tokens);
 	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);
-
+	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_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");
+	/* 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_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,
-	},
-};
+		memset(&key, 0, sizeof(key));
 
-/*
- * arp del
- */
+		if (n_tokens != 4) {
+			printf(CMD_MSG_MISMATCH_ARGS, "arp add");
+			return;
+		}
 
-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;
-};
+		if (parser_read_uint32(&port_id, tokens[1])) {
+			printf(CMD_MSG_INVALID_ARG, "portid");
+			return;
+		}
 
-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;
+		if (parse_ipv4_addr(tokens[2], &ipv4)) {
+			printf(CMD_MSG_INVALID_ARG, "ipaddr");
+			return;
+		}
 
-	struct pipeline_routing_arp_key key;
-	int status;
+		if (parse_mac_addr(tokens[3], &mac_addr)) {
+			printf(CMD_MSG_INVALID_ARG, "macaddr");
+			return;
+		}
 
-	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;
+		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_delete_arp_entry(app, params->p, &key);
+		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;
-	}
-}
-
-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");
+	} /* arp add */
 
-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 */
+	if ((n_tokens >= 2) &&
+		(strcmp(tokens[0], "add") == 0) &&
+		(strcmp(tokens[1], "default") == 0)) {
+		uint32_t port_id;
 
-/*
- * 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;
+		if (n_tokens != 3) {
+			printf(CMD_MSG_MISMATCH_ARGS, "arp add default");
+			return;
+		}
 
-	int status;
+		if (parser_read_uint32(&port_id, tokens[2])) {
+			printf(CMD_MSG_INVALID_ARG, "portid");
+			return;
+		}
 
-	status = app_pipeline_routing_add_default_arp_entry(app,
-		params->p,
-		params->port_id);
+		status = app_pipeline_routing_add_default_arp_entry(app,
+			params->p,
+			port_id);
+		if (status != 0)
+			printf(CMD_MSG_FAIL, "arp add default");
 
-	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");
+	} /* arp add default */
 
-static cmdline_parse_token_string_t cmd_arp_add_default_add_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_arp_add_default_result, add_string,
-	"add");
+	/* 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_string_t cmd_arp_add_default_default_string =
-	TOKEN_STRING_INITIALIZER(struct cmd_arp_add_default_result,
-		default_string, "default");
+		memset(&key, 0, sizeof(key));
 
-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
- */
+		if (n_tokens != 3) {
+			printf(CMD_MSG_MISMATCH_ARGS, "arp del");
+			return;
+		}
 
-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;
-};
+		if (parser_read_uint32(&port_id, tokens[1])) {
+			printf(CMD_MSG_INVALID_ARG, "portid");
+			return;
+		}
 
-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;
+		if (parse_ipv4_addr(tokens[2], &ipv4)) {
+			printf(CMD_MSG_INVALID_ARG, "ipaddr");
+			return;
+		}
 
-	int status;
+		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;
 
-	status = app_pipeline_routing_delete_default_arp_entry(app, params->p);
+		status = app_pipeline_routing_delete_arp_entry(app,
+			params->p,
+			&key);
+		if (status != 0)
+			printf(CMD_MSG_FAIL, "arp del");
 
-	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
- */
+	} /* 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_arp_ls_result {
-	cmdline_fixed_string_t p_string;
-	uint32_t p;
-	cmdline_fixed_string_t arp_string;
-	cmdline_fixed_string_t ls_string;
-};
+		status = app_pipeline_routing_arp_ls(app, params->p);
+		if (status != 0)
+			printf(CMD_MSG_FAIL, "arp ls");
 
-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,
 };
 
-- 
1.7.9.5



More information about the dev mailing list