diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile
index 35e4302..0f6bb78 100644
--- a/examples/ip_pipeline/Makefile
+++ b/examples/ip_pipeline/Makefile
@@ -12,6 +12,7 @@ SRCS-y += main.c
 SRCS-y += mempool.c
 SRCS-y += parser.c
 SRCS-y += swq.c
+SRCS-y += tap.c
 SRCS-y += tmgr.c
 #SRCS-y += thread.c
 
diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
index b895d60..a3b1ffd 100644
--- a/examples/ip_pipeline/cli.c
+++ b/examples/ip_pipeline/cli.c
@@ -14,6 +14,7 @@
 #include "mempool.h"
 #include "parser.h"
 #include "swq.h"
+#include "tap.h"
 #include "tmgr.h"
 
 #ifndef CMD_MAX_TOKENS
@@ -603,6 +604,32 @@ cmd_tmgr_subport_pipe(char **tokens,
 	}
 }
 
+/**
+ * tap <tap_name>
+ */
+static void
+cmd_tap(char **tokens,
+	uint32_t n_tokens,
+	char *out,
+	size_t out_size)
+{
+	char *name;
+	struct tap *tap;
+
+	if (n_tokens != 2) {
+		snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+		return;
+	}
+
+	name = tokens[1];
+
+	tap = tap_create(name);
+	if (tap == NULL) {
+		snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
+		return;
+	}
+}
+
 void
 cli_process(char *in, char *out, size_t out_size)
 {
@@ -671,6 +698,11 @@ cli_process(char *in, char *out, size_t out_size)
 		return;
 	}
 
+	if (strcmp(tokens[0], "tap") == 0) {
+		cmd_tap(tokens, n_tokens, out, out_size);
+		return;
+	}
+
 	snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
 }
 
diff --git a/examples/ip_pipeline/main.c b/examples/ip_pipeline/main.c
index 490991f..33c3354 100644
--- a/examples/ip_pipeline/main.c
+++ b/examples/ip_pipeline/main.c
@@ -15,6 +15,7 @@
 #include "link.h"
 #include "mempool.h"
 #include "swq.h"
+#include "tap.h"
 #include "tmgr.h"
 
 static const char usage[] =
@@ -191,6 +192,13 @@ main(int argc, char **argv)
 		return status;
 	}
 
+	/* TAP */
+	status = tap_init();
+	if (status) {
+		printf("Error: TAP initialization failed (%d)\n", status);
+		return status;
+	}
+
 	/* Script */
 	if (app.script_name)
 		cli_script_process(app.script_name,
diff --git a/examples/ip_pipeline/meson.build b/examples/ip_pipeline/meson.build
index cb2154c..e875811 100644
--- a/examples/ip_pipeline/meson.build
+++ b/examples/ip_pipeline/meson.build
@@ -15,5 +15,6 @@ sources = files(
 	'mempool.c',
 	'parser.c',
 	'swq.c',
+	'tap.c',
 	'tmgr.c'
 )
diff --git a/examples/ip_pipeline/tap.c b/examples/ip_pipeline/tap.c
new file mode 100644
index 0000000..5b34032
--- /dev/null
+++ b/examples/ip_pipeline/tap.c
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include <netinet/in.h>
+#ifdef RTE_EXEC_ENV_LINUXAPP
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#endif
+#include <sys/ioctl.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tap.h"
+
+#define TAP_DEV                                            "/dev/net/tun"
+
+static struct tap_list tap_list;
+
+int
+tap_init(void)
+{
+	TAILQ_INIT(&tap_list);
+
+	return 0;
+}
+
+struct tap *
+tap_find(const char *name)
+{
+	struct tap *tap;
+
+	if (name == NULL)
+		return NULL;
+
+	TAILQ_FOREACH(tap, &tap_list, node)
+		if (strcmp(tap->name, name) == 0)
+			return tap;
+
+	return NULL;
+}
+
+#ifndef RTE_EXEC_ENV_LINUXAPP
+
+struct tap *
+tap_create(const char *name __rte_unused)
+{
+	return NULL;
+}
+
+#else
+
+struct tap *
+tap_create(const char *name)
+{
+	struct tap *tap;
+	struct ifreq ifr;
+	int fd, status;
+
+	/* Check input params */
+	if ((name == NULL) ||
+		tap_find(name))
+		return NULL;
+
+	/* Resource create */
+	fd = open(TAP_DEV, O_RDWR | O_NONBLOCK);
+	if (fd < 0)
+		return NULL;
+
+	memset(&ifr, 0, sizeof(ifr));
+	ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */
+	snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
+
+	status = ioctl(fd, TUNSETIFF, (void *) &ifr);
+	if (status < 0)
+		return NULL;
+
+	/* Node allocation */
+	tap = calloc(1, sizeof(struct tap));
+	if (tap == NULL)
+		return NULL;
+
+	/* Node fill in */
+	strncpy(tap->name, name, sizeof(tap->name));
+	tap->fd = fd;
+
+	/* Node add to list */
+	TAILQ_INSERT_TAIL(&tap_list, tap, node);
+
+	return tap;
+}
+
+#endif
diff --git a/examples/ip_pipeline/tap.h b/examples/ip_pipeline/tap.h
new file mode 100644
index 0000000..0dce72f
--- /dev/null
+++ b/examples/ip_pipeline/tap.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#ifndef _INCLUDE_TAP_H_
+#define _INCLUDE_TAP_H_
+
+#include <sys/queue.h>
+
+#include "common.h"
+
+struct tap {
+	TAILQ_ENTRY(tap) node;
+	char name[NAME_SIZE];
+	int fd;
+};
+
+TAILQ_HEAD(tap_list, tap);
+
+int
+tap_init(void);
+
+struct tap *
+tap_find(const char *name);
+
+struct tap *
+tap_create(const char *name);
+
+#endif /* _INCLUDE_TAP_H_ */
