All of lore.kernel.org
 help / color / mirror / Atom feed
From: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
To: dev@dpdk.org
Cc: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Subject: [PATCH v3 6/7] examples/ip_pipeline: modifies routing pipeline CLI
Date: Wed,  8 Jun 2016 12:35:24 +0200	[thread overview]
Message-ID: <1465382125-2747-7-git-send-email-piotrx.t.azarewicz@intel.com> (raw)
In-Reply-To: <1465382125-2747-1-git-send-email-piotrx.t.azarewicz@intel.com>

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@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@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

  parent reply	other threads:[~2016-06-08 10:35 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-06 15:57 [PATCH 0/6] ip_pipeline: CLI rework and improvements Michal Jastrzebski
2016-05-06 15:57 ` [PATCH 1/6] examples/ip_pipeline: add helper functions for parsing string Michal Jastrzebski
2016-05-06 15:57 ` [PATCH 2/6] examples/ip_pipeline: modifies common pipeline CLI Michal Jastrzebski
2016-05-06 15:57 ` [PATCH 3/6] examples/ip_pipeline: modifies routing commands Michal Jastrzebski
2016-05-06 15:57 ` [PATCH 4/6] examples/ip_pipeline: modifies firewall pipeline CLI Michal Jastrzebski
2016-05-06 15:57 ` [PATCH 5/6] examples/ip_pipeline: modifies flow classifications " Michal Jastrzebski
2016-05-06 15:57 ` [PATCH 6/6] examples/ip_pipeline: modifies flow action " Michal Jastrzebski
2016-05-20 14:35 ` [PATCH v2 0/7] examples/ip_pipeline: CLI rework and improvements Piotr Azarewicz
2016-05-20 14:35   ` [PATCH v2 1/7] examples/ip_pipeline: add helper functions for parsing string Piotr Azarewicz
2016-05-20 14:35   ` [PATCH v2 2/7] examples/ip_pipeline: modifies common pipeline CLI Piotr Azarewicz
2016-05-20 14:35   ` [PATCH v2 3/7] examples/ip_pipeline: modifies firewall " Piotr Azarewicz
2016-05-20 14:35   ` [PATCH v2 4/7] examples/ip_pipeline: modifies flow classifications " Piotr Azarewicz
2016-05-20 14:35   ` [PATCH v2 5/7] examples/ip_pipeline: modifies flow action " Piotr Azarewicz
2016-05-20 14:35   ` [PATCH v2 6/7] examples/ip_pipeline: modifies routing " Piotr Azarewicz
2016-05-20 14:35   ` [PATCH v2 7/7] examples/ip_pipeline: update edge router usecase Piotr Azarewicz
2016-06-07 20:34   ` [PATCH v2 0/7] examples/ip_pipeline: CLI rework and improvements Thomas Monjalon
2016-06-08 10:01     ` Azarewicz, PiotrX T
2016-06-08 10:35   ` [PATCH v3 " Piotr Azarewicz
2016-06-08 10:35     ` [PATCH v3 1/7] examples/ip_pipeline: add helper functions for parsing string Piotr Azarewicz
2016-06-08 10:35     ` [PATCH v3 2/7] examples/ip_pipeline: modifies common pipeline CLI Piotr Azarewicz
2016-06-08 10:35     ` [PATCH v3 3/7] examples/ip_pipeline: modifies firewall " Piotr Azarewicz
2016-06-08 10:35     ` [PATCH v3 4/7] examples/ip_pipeline: modifies flow classifications " Piotr Azarewicz
2016-06-08 10:35     ` [PATCH v3 5/7] examples/ip_pipeline: modifies flow action " Piotr Azarewicz
2016-06-08 10:35     ` Piotr Azarewicz [this message]
2016-06-08 10:35     ` [PATCH v3 7/7] examples/ip_pipeline: update edge router usecase Piotr Azarewicz
2016-06-08 14:46     ` [PATCH v3 0/7] examples/ip_pipeline: CLI rework and improvements Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1465382125-2747-7-git-send-email-piotrx.t.azarewicz@intel.com \
    --to=piotrx.t.azarewicz@intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.