diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c
index 471dfbad38..37fc6f9551 100644
--- a/examples/pipeline/cli.c
+++ b/examples/pipeline/cli.c
@@ -292,16 +292,14 @@ cmd_ethdev(char **tokens,
 	uint32_t n_tokens,
 	char *out,
 	size_t out_size,
-	void *obj)
+	void *obj __rte_unused)
 {
-	struct link_params p;
-	struct link_params_rss rss;
-	struct link *link;
+	struct ethdev_params p = {0};
+	struct ethdev_params_rss rss = {0};
 	char *name;
+	int status;
 
-	memset(&p, 0, sizeof(p));
-
-	if ((n_tokens < 11) || (n_tokens > 12 + LINK_RXQ_RSS_MAX)) {
+	if (n_tokens < 11 || n_tokens > 12 + ETHDEV_RXQ_RSS_MAX) {
 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
 		return;
 	}
@@ -377,111 +375,98 @@ cmd_ethdev(char **tokens,
 		}
 	}
 
-	link = link_create(obj, name, &p);
-	if (link == NULL) {
+	status = ethdev_config(name, &p);
+	if (status) {
 		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
 		return;
 	}
 }
 
-/* Print the link stats and info */
 static void
-print_link_info(struct link *link, char *out, size_t out_size)
+ethdev_show(uint16_t port_id, char **out, size_t *out_size)
 {
-	struct rte_eth_stats stats;
-	struct rte_ether_addr mac_addr;
-	struct rte_eth_link eth_link;
-	uint16_t mtu;
-	int ret;
-
-	memset(&stats, 0, sizeof(stats));
-	rte_eth_stats_get(link->port_id, &stats);
-
-	ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
-	if (ret != 0) {
-		snprintf(out, out_size, "\n%s: MAC address get failed: %s",
-			 link->name, rte_strerror(-ret));
-		return;
-	}
-
-	ret = rte_eth_link_get(link->port_id, &eth_link);
-	if (ret < 0) {
-		snprintf(out, out_size, "\n%s: link get failed: %s",
-			 link->name, rte_strerror(-ret));
-		return;
-	}
-
-	rte_eth_dev_get_mtu(link->port_id, &mtu);
-
-	snprintf(out, out_size,
-		"\n"
-		"%s: flags=<%s> mtu %u\n"
-		"\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
-		"\tport# %u  speed %s\n"
-		"\tRX packets %" PRIu64"  bytes %" PRIu64"\n"
-		"\tRX errors %" PRIu64"  missed %" PRIu64"  no-mbuf %" PRIu64"\n"
-		"\tTX packets %" PRIu64"  bytes %" PRIu64"\n"
-		"\tTX errors %" PRIu64"\n",
-		link->name,
-		eth_link.link_status == 0 ? "DOWN" : "UP",
-		mtu,
-		RTE_ETHER_ADDR_BYTES(&mac_addr),
-		link->n_rxq,
-		link->n_txq,
-		link->port_id,
-		rte_eth_link_speed_to_str(eth_link.link_speed),
-		stats.ipackets,
-		stats.ibytes,
-		stats.ierrors,
-		stats.imissed,
-		stats.rx_nombuf,
-		stats.opackets,
-		stats.obytes,
-		stats.oerrors);
+	char name[RTE_ETH_NAME_MAX_LEN] = {0};
+	struct rte_eth_dev_info info = {0};
+	struct rte_eth_stats stats = {0};
+	struct rte_ether_addr addr = {0};
+	struct rte_eth_link link = {0};
+	uint32_t length;
+	uint16_t mtu = 0;
+
+	if (!rte_eth_dev_is_valid_port(port_id))
+		return;
+
+	rte_eth_dev_get_name_by_port(port_id, name);
+	rte_eth_dev_info_get(port_id, &info);
+	rte_eth_stats_get(port_id, &stats);
+	rte_eth_macaddr_get(port_id, &addr);
+	rte_eth_link_get(port_id, &link);
+	rte_eth_dev_get_mtu(port_id, &mtu);
+
+	snprintf(*out, *out_size,
+		 "%s: flags=<%s> mtu %u\n"
+		 "\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
+		 "\tport# %u  speed %s\n"
+		 "\tRX packets %" PRIu64"  bytes %" PRIu64"\n"
+		 "\tRX errors %" PRIu64"  missed %" PRIu64"  no-mbuf %" PRIu64"\n"
+		 "\tTX packets %" PRIu64"  bytes %" PRIu64"\n"
+		 "\tTX errors %" PRIu64"\n\n",
+		 name,
+		 link.link_status ? "UP" : "DOWN",
+		 mtu,
+		 RTE_ETHER_ADDR_BYTES(&addr),
+		 info.nb_rx_queues,
+		 info.nb_tx_queues,
+		 port_id,
+		 rte_eth_link_speed_to_str(link.link_speed),
+		 stats.ipackets,
+		 stats.ibytes,
+		 stats.ierrors,
+		 stats.imissed,
+		 stats.rx_nombuf,
+		 stats.opackets,
+		 stats.obytes,
+		 stats.oerrors);
+
+	length = strlen(*out);
+	*out_size -= length;
+	*out += length;
 }
 
-/*
- * ethdev show [<ethdev_name>]
- */
+
+static char cmd_ethdev_show_help[] =
+"ethdev show [ <ethdev_name> ]\n";
+
 static void
 cmd_ethdev_show(char **tokens,
 	      uint32_t n_tokens,
 	      char *out,
 	      size_t out_size,
-	      void *obj)
+	      void *obj __rte_unused)
 {
-	struct link *link;
-	char *link_name;
+	uint16_t port_id;
 
 	if (n_tokens != 2 && n_tokens != 3) {
 		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
 		return;
 	}
 
-	if (n_tokens == 2) {
-		link = link_next(obj, NULL);
-
-		while (link != NULL) {
-			out_size = out_size - strlen(out);
-			out = &out[strlen(out)];
-
-			print_link_info(link, out, out_size);
-			link = link_next(obj, link);
-		}
-	} else {
-		out_size = out_size - strlen(out);
-		out = &out[strlen(out)];
+	/* Single device. */
+	if (n_tokens == 3) {
+		int status;
 
-		link_name = tokens[2];
-		link = link_find(obj, link_name);
+		status = rte_eth_dev_get_port_by_name(tokens[2], &port_id);
+		if (status)
+			snprintf(out, out_size, "Error: Invalid Ethernet device name.\n");
 
-		if (link == NULL) {
-			snprintf(out, out_size, MSG_ARG_INVALID,
-					"Link does not exist");
-			return;
-		}
-		print_link_info(link, out, out_size);
+		ethdev_show(port_id, &out, &out_size);
+		return;
 	}
+
+	/*  All devices. */
+	for (port_id = 0; port_id < RTE_MAX_ETHPORTS; port_id++)
+		if (rte_eth_dev_is_valid_port(port_id))
+			ethdev_show(port_id, &out, &out_size);
 }
 
 static const char cmd_ring_help[] =
@@ -3003,6 +2988,7 @@ cmd_help(char **tokens,
 			"List of commands:\n"
 			"\tmempool\n"
 			"\tethdev\n"
+			"\tethdev show\n"
 			"\tring\n"
 			"\tpipeline codegen\n"
 			"\tpipeline libbuild\n"
@@ -3038,9 +3024,16 @@ cmd_help(char **tokens,
 		return;
 	}
 
-	if (strcmp(tokens[0], "ethdev") == 0) {
-		snprintf(out, out_size, "\n%s\n", cmd_ethdev_help);
-		return;
+	if (!strcmp(tokens[0], "ethdev")) {
+		if (n_tokens == 1) {
+			snprintf(out, out_size, "\n%s\n", cmd_ethdev_help);
+			return;
+		}
+
+		if (n_tokens == 2 && !strcmp(tokens[1], "show")) {
+			snprintf(out, out_size, "\n%s\n", cmd_ethdev_show_help);
+			return;
+		}
 	}
 
 	if (strcmp(tokens[0], "ring") == 0) {
diff --git a/examples/pipeline/main.c b/examples/pipeline/main.c
index 6fb839f4cb..da5dd2b3f6 100644
--- a/examples/pipeline/main.c
+++ b/examples/pipeline/main.c
@@ -135,7 +135,6 @@ int
 main(int argc, char **argv)
 {
 	struct conn *conn;
-	struct obj *obj;
 	int status;
 
 	/* Parse application arguments */
@@ -150,13 +149,6 @@ main(int argc, char **argv)
 		return status;
 	};
 
-	/* Obj */
-	obj = obj_init();
-	if (!obj) {
-		printf("Error: Obj initialization failed (%d)\n", status);
-		return status;
-	}
-
 	/* Thread */
 	status = thread_init();
 	if (status) {
@@ -174,10 +166,10 @@ main(int argc, char **argv)
 		cli_script_process(app.script_name,
 			app.conn.msg_in_len_max,
 			app.conn.msg_out_len_max,
-			obj);
+			NULL);
 
 	/* Connectivity */
-	app.conn.msg_handle_arg = obj;
+	app.conn.msg_handle_arg = NULL;
 	conn = conn_init(&app.conn);
 	if (!conn) {
 		printf("Error: Connectivity initialization failed (%d)\n",
diff --git a/examples/pipeline/obj.c b/examples/pipeline/obj.c
index f1a50133f4..a5c09e7219 100644
--- a/examples/pipeline/obj.c
+++ b/examples/pipeline/obj.c
@@ -4,35 +4,14 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <netinet/in.h>
-#ifdef RTE_EXEC_ENV_LINUX
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#endif
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <unistd.h>
 
 #include <rte_mbuf.h>
 #include <rte_ethdev.h>
-#include <rte_swx_ctl.h>
 
 #include "obj.h"
 
 /*
- * link
- */
-TAILQ_HEAD(link_list, link);
-
-/*
- * obj
- */
-struct obj {
-	struct link_list link_list;
-};
-
-/*
- * link
+ * ethdev
  */
 static struct rte_eth_conf port_conf_default = {
 	.link_speeds = 0,
@@ -59,7 +38,7 @@ static struct rte_eth_conf port_conf_default = {
 static int
 rss_setup(uint16_t port_id,
 	uint16_t reta_size,
-	struct link_params_rss *rss)
+	struct ethdev_params_rss *rss)
 {
 	struct rte_eth_rss_reta_entry64 reta_conf[RETA_CONF_SIZE];
 	uint32_t i;
@@ -88,69 +67,64 @@ rss_setup(uint16_t port_id,
 	return status;
 }
 
-struct link *
-link_create(struct obj *obj, const char *name, struct link_params *params)
+int
+ethdev_config(const char *name, struct ethdev_params *params)
 {
 	struct rte_eth_dev_info port_info;
 	struct rte_eth_conf port_conf;
-	struct link *link;
-	struct link_params_rss *rss;
+	struct ethdev_params_rss *rss;
 	struct rte_mempool *mempool;
-	uint32_t cpu_id, i;
-	int status;
+	uint32_t i;
+	int numa_node, status;
 	uint16_t port_id = 0;
 
 	/* Check input params */
-	if ((name == NULL) ||
-		link_find(obj, name) ||
-		(params == NULL) ||
-		(params->rx.n_queues == 0) ||
-		(params->rx.queue_size == 0) ||
-		(params->tx.n_queues == 0) ||
-		(params->tx.queue_size == 0))
-		return NULL;
+	if (!name ||
+	    !name[0] ||
+	    !params ||
+	    !params->rx.n_queues ||
+	    !params->rx.queue_size ||
+	    !params->tx.n_queues ||
+	    !params->tx.queue_size)
+		return -EINVAL;
 
 	status = rte_eth_dev_get_port_by_name(name, &port_id);
 	if (status)
-		return NULL;
+		return -EINVAL;
 
-	if (rte_eth_dev_info_get(port_id, &port_info) != 0)
-		return NULL;
+	status = rte_eth_dev_info_get(port_id, &port_info);
+	if (status)
+		return -EINVAL;
 
 	mempool = rte_mempool_lookup(params->rx.mempool_name);
 	if (!mempool)
-		return NULL;
+		return -EINVAL;
 
 	rss = params->rx.rss;
 	if (rss) {
-		if ((port_info.reta_size == 0) ||
-			(port_info.reta_size > RTE_ETH_RSS_RETA_SIZE_512))
-			return NULL;
+		if (!port_info.reta_size || port_info.reta_size > RTE_ETH_RSS_RETA_SIZE_512)
+			return -EINVAL;
 
-		if ((rss->n_queues == 0) ||
-			(rss->n_queues >= LINK_RXQ_RSS_MAX))
-			return NULL;
+		if (!rss->n_queues || rss->n_queues >= ETHDEV_RXQ_RSS_MAX)
+			return -EINVAL;
 
 		for (i = 0; i < rss->n_queues; i++)
 			if (rss->queue_id[i] >= port_info.max_rx_queues)
-				return NULL;
+				return -EINVAL;
 	}
 
-	/**
-	 * Resource create
-	 */
 	/* Port */
 	memcpy(&port_conf, &port_conf_default, sizeof(port_conf));
 	if (rss) {
+		uint64_t rss_hf = RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP | RTE_ETH_RSS_UDP;
+
 		port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
-		port_conf.rx_adv_conf.rss_conf.rss_hf =
-			(RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP | RTE_ETH_RSS_UDP) &
-			port_info.flow_type_rss_offloads;
+		port_conf.rx_adv_conf.rss_conf.rss_hf = rss_hf & port_info.flow_type_rss_offloads;
 	}
 
-	cpu_id = (uint32_t) rte_eth_dev_socket_id(port_id);
-	if (cpu_id == (uint32_t) SOCKET_ID_ANY)
-		cpu_id = 0;
+	numa_node = rte_eth_dev_socket_id(port_id);
+	if (numa_node == SOCKET_ID_ANY)
+		numa_node = 0;
 
 	status = rte_eth_dev_configure(
 		port_id,
@@ -159,12 +133,12 @@ link_create(struct obj *obj, const char *name, struct link_params *params)
 		&port_conf);
 
 	if (status < 0)
-		return NULL;
+		return -EINVAL;
 
 	if (params->promiscuous) {
 		status = rte_eth_promiscuous_enable(port_id);
-		if (status != 0)
-			return NULL;
+		if (status)
+			return -EINVAL;
 	}
 
 	/* Port RX */
@@ -173,12 +147,12 @@ link_create(struct obj *obj, const char *name, struct link_params *params)
 			port_id,
 			i,
 			params->rx.queue_size,
-			cpu_id,
+			numa_node,
 			NULL,
 			mempool);
 
 		if (status < 0)
-			return NULL;
+			return -EINVAL;
 	}
 
 	/* Port TX */
@@ -187,24 +161,24 @@ link_create(struct obj *obj, const char *name, struct link_params *params)
 			port_id,
 			i,
 			params->tx.queue_size,
-			cpu_id,
+			numa_node,
 			NULL);
 
 		if (status < 0)
-			return NULL;
+			return -EINVAL;
 	}
 
 	/* Port start */
 	status = rte_eth_dev_start(port_id);
 	if (status < 0)
-		return NULL;
+		return -EINVAL;
 
 	if (rss) {
 		status = rss_setup(port_id, port_info.reta_size, rss);
 
 		if (status) {
 			rte_eth_dev_stop(port_id);
-			return NULL;
+			return -EINVAL;
 		}
 	}
 
@@ -212,84 +186,8 @@ link_create(struct obj *obj, const char *name, struct link_params *params)
 	status = rte_eth_dev_set_link_up(port_id);
 	if ((status < 0) && (status != -ENOTSUP)) {
 		rte_eth_dev_stop(port_id);
-		return NULL;
-	}
-
-	/* Node allocation */
-	link = calloc(1, sizeof(struct link));
-	if (link == NULL) {
-		rte_eth_dev_stop(port_id);
-		return NULL;
+		return -EINVAL;
 	}
 
-	/* Node fill in */
-	strlcpy(link->name, name, sizeof(link->name));
-	link->port_id = port_id;
-	link->n_rxq = params->rx.n_queues;
-	link->n_txq = params->tx.n_queues;
-
-	/* Node add to list */
-	TAILQ_INSERT_TAIL(&obj->link_list, link, node);
-
-	return link;
-}
-
-int
-link_is_up(struct obj *obj, const char *name)
-{
-	struct rte_eth_link link_params;
-	struct link *link;
-
-	/* Check input params */
-	if (!obj || !name)
-		return 0;
-
-	link = link_find(obj, name);
-	if (link == NULL)
-		return 0;
-
-	/* Resource */
-	if (rte_eth_link_get(link->port_id, &link_params) < 0)
-		return 0;
-
-	return (link_params.link_status == RTE_ETH_LINK_DOWN) ? 0 : 1;
-}
-
-struct link *
-link_find(struct obj *obj, const char *name)
-{
-	struct link *link;
-
-	if (!obj || !name)
-		return NULL;
-
-	TAILQ_FOREACH(link, &obj->link_list, node)
-		if (strcmp(link->name, name) == 0)
-			return link;
-
-	return NULL;
-}
-
-struct link *
-link_next(struct obj *obj, struct link *link)
-{
-	return (link == NULL) ?
-		TAILQ_FIRST(&obj->link_list) : TAILQ_NEXT(link, node);
-}
-
-/*
- * obj
- */
-struct obj *
-obj_init(void)
-{
-	struct obj *obj;
-
-	obj = calloc(1, sizeof(struct obj));
-	if (!obj)
-		return NULL;
-
-	TAILQ_INIT(&obj->link_list);
-
-	return obj;
+	return 0;
 }
diff --git a/examples/pipeline/obj.h b/examples/pipeline/obj.h
index dbbc6d39a0..fb091f4ba7 100644
--- a/examples/pipeline/obj.h
+++ b/examples/pipeline/obj.h
@@ -6,41 +6,25 @@
 #define _INCLUDE_OBJ_H_
 
 #include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_swx_pipeline.h>
-#include <rte_swx_ctl.h>
-
-#ifndef NAME_SIZE
-#define NAME_SIZE 64
-#endif
-
-/*
- * obj
- */
-struct obj;
-
-struct obj *
-obj_init(void);
 
 /*
- * link
+ * ethdev
  */
-#ifndef LINK_RXQ_RSS_MAX
-#define LINK_RXQ_RSS_MAX                                   16
+#ifndef ETHDEV_RXQ_RSS_MAX
+#define ETHDEV_RXQ_RSS_MAX 16
 #endif
 
-struct link_params_rss {
-	uint32_t queue_id[LINK_RXQ_RSS_MAX];
+struct ethdev_params_rss {
+	uint32_t queue_id[ETHDEV_RXQ_RSS_MAX];
 	uint32_t n_queues;
 };
 
-struct link_params {
+struct ethdev_params {
 	struct {
 		uint32_t n_queues;
 		uint32_t queue_size;
 		const char *mempool_name;
-		struct link_params_rss *rss;
+		struct ethdev_params_rss *rss;
 	} rx;
 
 	struct {
@@ -51,26 +35,7 @@ struct link_params {
 	int promiscuous;
 };
 
-struct link {
-	TAILQ_ENTRY(link) node;
-	char name[NAME_SIZE];
-	uint16_t port_id;
-	uint32_t n_rxq;
-	uint32_t n_txq;
-};
-
-struct link *
-link_create(struct obj *obj,
-	    const char *name,
-	    struct link_params *params);
-
 int
-link_is_up(struct obj *obj, const char *name);
-
-struct link *
-link_find(struct obj *obj, const char *name);
-
-struct link *
-link_next(struct obj *obj, struct link *link);
+ethdev_config(const char *name, struct ethdev_params *params);
 
 #endif /* _INCLUDE_OBJ_H_ */
