[dpdk-dev,08/11] ip_pipeline: added new implementation of passthrough pipeline

Message ID 1432914198-11812-9-git-send-email-maciejx.t.gajdzica@intel.com (mailing list archive)
State Superseded, archived
Headers

Commit Message

Maciej Gajdzica May 29, 2015, 3:43 p.m. UTC
  Passthrough pipeline implementation is split to two files.
pipeline_passthrough.c file handles front-end functions (cli commands
parsing) pipeline_passthrough_ops.c contains implementation of functions
done by pipeline (back-end).

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 examples/ip_pipeline/Makefile                      |    7 +-
 examples/ip_pipeline/init.c                        |    2 +
 .../ip_pipeline/pipeline/pipeline_passthrough.c    |  192 +-------------
 .../ip_pipeline/pipeline/pipeline_passthrough.h    |   41 +++
 .../pipeline/pipeline_passthrough_ops.c            |  275 ++++++++++++++++++++
 .../pipeline/pipeline_passthrough_ops.h            |   41 +++
 6 files changed, 374 insertions(+), 184 deletions(-)
 create mode 100644 examples/ip_pipeline/pipeline/pipeline_passthrough.h
 create mode 100644 examples/ip_pipeline/pipeline/pipeline_passthrough_ops.c
 create mode 100644 examples/ip_pipeline/pipeline/pipeline_passthrough_ops.h
  

Patch

diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile
index db677ec..fc845ce 100644
--- a/examples/ip_pipeline/Makefile
+++ b/examples/ip_pipeline/Makefile
@@ -59,13 +59,10 @@  SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_common_ops.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_common.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_master_ops.c
 SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_master.c
-#SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_rx.c
-#SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_tx.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_passthrough_ops.c
+SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_passthrough.c
 #SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_flow_classification.c
 #SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_routing.c
-#SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_passthrough.c
-#SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_ipv4_frag.c
-#SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_ipv4_ras.c
 
 #ifeq ($(CONFIG_RTE_LIBRTE_ACL),y)
 #SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) += pipeline_firewall.c
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index b066476..22b2c77 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -44,6 +44,7 @@ 
 #include "app.h"
 #include "pipeline.h"
 #include "pipeline_master.h"
+#include "pipeline_passthrough.h"
 
 #define APP_NAME_SIZE	32
 
@@ -1144,6 +1145,7 @@  int app_init(struct app_params *app)
 	app_init_msgq(app);
 
 	app_pipeline_type_register(app, &pipeline_master);
+	app_pipeline_type_register(app, &pipeline_passthrough);
 
 	app_init_pipelines(app);
 	app_init_threads(app);
diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough.c b/examples/ip_pipeline/pipeline/pipeline_passthrough.c
index 948b2c1..e39de32 100644
--- a/examples/ip_pipeline/pipeline/pipeline_passthrough.c
+++ b/examples/ip_pipeline/pipeline/pipeline_passthrough.c
@@ -1,7 +1,7 @@ 
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -31,183 +31,17 @@ 
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
+#include "pipeline_passthrough_ops.h"
+#include "pipeline_passthrough.h"
 
-#include <rte_malloc.h>
-#include <rte_log.h>
+static struct pipeline_fe_ops pipeline_passthrough_fe_ops = {
+	.f_init = NULL,
+	.f_free = NULL,
+	.cmds = NULL,
+};
 
-#include <rte_port_ring.h>
-#include <rte_table_stub.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-void
-app_main_loop_pipeline_passthrough(void) {
-	struct rte_pipeline_params pipeline_params = {
-		.name = "pipeline",
-		.socket_id = rte_socket_id(),
-	};
-
-	struct rte_pipeline *p;
-	uint32_t port_in_id[APP_MAX_PORTS];
-	uint32_t port_out_id[APP_MAX_PORTS];
-	uint32_t table_id[APP_MAX_PORTS];
-	uint32_t i;
-
-	uint32_t core_id = rte_lcore_id();
-	struct app_core_params *core_params = app_get_core_params(core_id);
-
-	if ((core_params == NULL) || (core_params->core_type != APP_CORE_PT))
-		rte_panic("Core %u misconfiguration\n", core_id);
-
-	RTE_LOG(INFO, USER1, "Core %u is doing pass-through\n", core_id);
-
-	/* Pipeline configuration */
-	p = rte_pipeline_create(&pipeline_params);
-	if (p == NULL)
-		rte_panic("%s: Unable to configure the pipeline\n", __func__);
-
-	/* Input port configuration */
-	for (i = 0; i < app.n_ports; i++) {
-		struct rte_port_ring_reader_params port_ring_params = {
-			.ring = app.rings[core_params->swq_in[i]],
-		};
-
-		struct rte_pipeline_port_in_params port_params = {
-			.ops = &rte_port_ring_reader_ops,
-			.arg_create = (void *) &port_ring_params,
-			.f_action = NULL,
-			.arg_ah = NULL,
-			.burst_size = app.bsz_swq_rd,
-		};
-
-		if (rte_pipeline_port_in_create(p, &port_params,
-			&port_in_id[i])) {
-			rte_panic("%s: Unable to configure input port for "
-				"ring %d\n", __func__, i);
-		}
-	}
-
-	/* Output port configuration */
-	for (i = 0; i < app.n_ports; i++) {
-		struct rte_port_ring_writer_params port_ring_params = {
-			.ring = app.rings[core_params->swq_out[i]],
-			.tx_burst_sz = app.bsz_swq_wr,
-		};
-
-		struct rte_pipeline_port_out_params port_params = {
-			.ops = &rte_port_ring_writer_ops,
-			.arg_create = (void *) &port_ring_params,
-			.f_action = NULL,
-			.f_action_bulk = NULL,
-			.arg_ah = NULL,
-		};
-
-		if (rte_pipeline_port_out_create(p, &port_params,
-			&port_out_id[i])) {
-			rte_panic("%s: Unable to configure output port for "
-				"ring %d\n", __func__, i);
-		}
-	}
-
-	/* Table configuration */
-	for (i = 0; i < app.n_ports; i++) {
-		struct rte_pipeline_table_params table_params = {
-			.ops = &rte_table_stub_ops,
-			.arg_create = NULL,
-			.f_action_hit = NULL,
-			.f_action_miss = NULL,
-			.arg_ah = NULL,
-			.action_data_size = 0,
-		};
-
-		if (rte_pipeline_table_create(p, &table_params, &table_id[i]))
-			rte_panic("%s: Unable to configure table %u\n",
-				__func__, i);
-	}
-
-	/* Interconnecting ports and tables */
-	for (i = 0; i < app.n_ports; i++) {
-		if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
-			table_id[i])) {
-			rte_panic("%s: Unable to connect input port %u to "
-				"table %u\n", __func__, port_in_id[i],
-				table_id[i]);
-		}
-	}
-
-	/* Add entries to tables */
-	for (i = 0; i < app.n_ports; i++) {
-		struct rte_pipeline_table_entry default_entry = {
-			.action = RTE_PIPELINE_ACTION_PORT,
-			{.port_id = port_out_id[i]},
-		};
-
-		struct rte_pipeline_table_entry *default_entry_ptr;
-
-		if (rte_pipeline_table_default_entry_add(p, table_id[i],
-			&default_entry, &default_entry_ptr))
-			rte_panic("%s: Unable to add default entry to "
-				"table %u\n", __func__, table_id[i]);
-	}
-
-	/* Enable input ports */
-	for (i = 0; i < app.n_ports; i++)
-		if (rte_pipeline_port_in_enable(p, port_in_id[i]))
-			rte_panic("Unable to enable input port %u\n",
-				port_in_id[i]);
-
-	/* Check pipeline consistency */
-	if (rte_pipeline_check(p) < 0)
-		rte_panic("%s: Pipeline consistency check failed\n", __func__);
-
-	/* Run-time */
-	for (i = 0; ; i++) {
-		rte_pipeline_run(p);
-
-		if ((i & APP_FLUSH) == 0)
-			rte_pipeline_flush(p);
-	}
-}
-
-void
-app_main_loop_passthrough(void) {
-	struct app_mbuf_array *m;
-	uint32_t i;
-
-	uint32_t core_id = rte_lcore_id();
-	struct app_core_params *core_params = app_get_core_params(core_id);
-
-	if ((core_params == NULL) || (core_params->core_type != APP_CORE_PT))
-		rte_panic("Core %u misconfiguration\n", core_id);
-
-	RTE_LOG(INFO, USER1, "Core %u is doing pass-through (no pipeline)\n",
-		core_id);
-
-	m = rte_malloc_socket(NULL, sizeof(struct app_mbuf_array),
-		RTE_CACHE_LINE_SIZE, rte_socket_id());
-	if (m == NULL)
-		rte_panic("%s: cannot allocate buffer space\n", __func__);
-
-	for (i = 0; ; i = ((i + 1) & (app.n_ports - 1))) {
-		int ret;
-
-		ret = rte_ring_sc_dequeue_bulk(
-			app.rings[core_params->swq_in[i]],
-			(void **) m->array,
-			app.bsz_swq_rd);
-
-		if (ret == -ENOENT)
-			continue;
-
-		do {
-			ret = rte_ring_sp_enqueue_bulk(
-				app.rings[core_params->swq_out[i]],
-				(void **) m->array,
-				app.bsz_swq_wr);
-		} while (ret < 0);
-	}
-}
+struct pipeline_type pipeline_passthrough = {
+	.name = "PASS-THROUGH",
+	.ops = &pipeline_passthrough_ops,
+	.fe_ops = &pipeline_passthrough_fe_ops,
+};
diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough.h b/examples/ip_pipeline/pipeline/pipeline_passthrough.h
new file mode 100644
index 0000000..420a876
--- /dev/null
+++ b/examples/ip_pipeline/pipeline/pipeline_passthrough.h
@@ -0,0 +1,41 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 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.
+ */
+
+#ifndef __INCLUDE_PIPELINE_PASSTHROUGH_H__
+#define __INCLUDE_PIPELINE_PASSTHROUGH_H__
+
+#include "pipeline.h"
+
+extern struct pipeline_type pipeline_passthrough;
+
+#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough_ops.c b/examples/ip_pipeline/pipeline/pipeline_passthrough_ops.c
new file mode 100644
index 0000000..8f91779
--- /dev/null
+++ b/examples/ip_pipeline/pipeline/pipeline_passthrough_ops.c
@@ -0,0 +1,275 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 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.
+ */
+
+#include <string.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_table_stub.h>
+
+#include "pipeline_common_ops.h"
+#include "pipeline_passthrough_ops.h"
+
+struct pipeline_passthrough {
+	struct pipeline p;
+} __rte_cache_aligned;
+
+static pipeline_msg_req_handler handlers[] = {
+	[PIPELINE_MSG_REQ_PING] = pipeline_msg_req_ping_handler,
+	[PIPELINE_MSG_REQ_STATS_PORT_IN] = pipeline_msg_req_stats_port_in_handler,
+	[PIPELINE_MSG_REQ_STATS_PORT_OUT] = pipeline_msg_req_stats_port_out_handler,
+	[PIPELINE_MSG_REQ_STATS_TABLE] = pipeline_msg_req_stats_table_handler,
+	[PIPELINE_MSG_REQ_PORT_IN_ENABLE] = pipeline_msg_req_port_in_enable_handler,
+	[PIPELINE_MSG_REQ_PORT_IN_DISABLE] = pipeline_msg_req_port_in_disable_handler,
+	[PIPELINE_MSG_REQ_CUSTOM] = pipeline_msg_req_invalid_handler,
+};
+
+static void*
+pipeline_passthrough_init(struct pipeline_params *params,
+	__rte_unused void *arg)
+{
+	struct pipeline *p;
+	uint32_t size, i;
+
+	/* Check input arguments */
+	if ((params == NULL) ||
+		(params->n_ports_in == 0) ||
+		(params->n_ports_out == 0) ||
+		(params->n_ports_in < params->n_ports_out) ||
+		(params->n_ports_in % params->n_ports_out))
+		return NULL;
+	
+	/* Memory allocation */
+	size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_passthrough));
+	p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (p == NULL)
+		return NULL;
+
+	/* Pipeline */
+	{
+		struct rte_pipeline_params pipeline_params = {
+			.name = "PASS-THROUGH",
+			.socket_id = params->socket_id,
+			.offset_port_id = 0,
+		};
+
+		p->p = rte_pipeline_create(&pipeline_params);
+		if (p->p == NULL) {
+			rte_free(p);
+			return NULL;
+		}
+	}
+
+	/* Input ports */
+	p->n_ports_in = params->n_ports_in;
+	for (i = 0; i < p->n_ports_in; i++) {
+		struct rte_pipeline_port_in_params port_params = {
+			.ops = pipeline_port_in_params_get_ops(&params->port_in[i]),
+			.arg_create = pipeline_port_in_params_convert(&params->port_in[i]),
+			.f_action = NULL,
+			.arg_ah = NULL,
+			.burst_size = params->port_in[i].burst_size,
+		};
+
+		int status = rte_pipeline_port_in_create(p->p,
+			&port_params,
+			&p->port_in_id[i]);
+
+		if (status) {
+			rte_pipeline_free(p->p);
+			rte_free(p);
+			return NULL;
+		}
+	}
+
+	/* Output ports */
+	p->n_ports_out = params->n_ports_out;
+	for (i = 0; i < p->n_ports_out; i++) {
+		struct rte_pipeline_port_out_params port_params = {
+			.ops = pipeline_port_out_params_get_ops(&params->port_out[i]),
+			.arg_create = pipeline_port_out_params_convert(&params->port_out[i]),
+			.f_action = NULL,
+			.f_action_bulk = NULL,
+			.arg_ah = NULL,
+		};
+
+		int status = rte_pipeline_port_out_create(p->p,
+			&port_params,
+			&p->port_out_id[i]);
+		
+		if (status) {
+			rte_pipeline_free(p->p);
+			rte_free(p);
+			return NULL;
+		}
+	}
+
+	/* Tables */
+	p->n_tables = p->n_ports_in;
+	for (i = 0; i < p->n_ports_in; i++) {
+		struct rte_pipeline_table_params table_params = {
+			.ops = &rte_table_stub_ops,
+			.arg_create = NULL,
+			.f_action_hit = NULL,
+			.f_action_miss = NULL,
+			.arg_ah = NULL,
+			.action_data_size = 0,
+		};
+
+		int status = rte_pipeline_table_create(p->p,
+			&table_params,
+			&p->table_id[i]);
+		
+		
+		if (status) {
+			rte_pipeline_free(p->p);
+			rte_free(p);
+			return NULL;
+		}
+	}
+
+	/* Connecting input ports to tables */
+	for (i = 0; i < p->n_ports_in; i++) {
+		int status = rte_pipeline_port_in_connect_to_table(p->p,
+			p->port_in_id[i],
+			p->table_id[i]);
+
+		if (status) {
+			rte_pipeline_free(p->p);
+			rte_free(p);
+			return NULL;
+		}
+	}
+
+	/* Add entries to tables */
+	for (i = 0; i < p->n_ports_in; i++) {
+		struct rte_pipeline_table_entry default_entry = {
+			.action = RTE_PIPELINE_ACTION_PORT,
+			{.port_id = p->port_out_id[i / (p->n_ports_in / p->n_ports_out)]},
+		};
+
+		
+		struct rte_pipeline_table_entry *default_entry_ptr;
+
+		int status = rte_pipeline_table_default_entry_add(p->p,
+			p->table_id[i],
+			&default_entry,
+			&default_entry_ptr);
+		
+		if (status) {
+			rte_pipeline_free(p->p);
+			rte_free(p);
+			return NULL;
+		}
+	}
+
+	/* Enable input ports */
+	for (i = 0; i < p->n_ports_in; i++) {
+		int status = rte_pipeline_port_in_enable(p->p,
+			p->port_in_id[i]);
+		
+		if (status) {
+			rte_pipeline_free(p->p);
+			rte_free(p);
+			return NULL;
+		}
+	}
+
+	/* Check pipeline consistency */
+	if (rte_pipeline_check(p->p) < 0) {
+		rte_pipeline_free(p->p);
+		rte_free(p);
+		return NULL;
+	}
+	
+	/* Message queues */
+	p->n_msgq = params->n_msgq;
+	for (i = 0; i < p->n_msgq; i++)
+		p->msgq_in[i] = params->msgq_in[i];
+	for (i = 0; i < p->n_msgq; i++)
+		p->msgq_out[i] = params->msgq_out[i];
+	
+	/* Message handlers */
+	memcpy(p->handlers, handlers, sizeof(p->handlers));
+
+	return p;
+}
+
+static int
+pipeline_passthrough_free(void *pipeline)
+{
+	struct pipeline *p = (struct pipeline *) pipeline;
+
+	/* Check input arguments */
+	if (p == NULL)
+		return -1;
+	
+	/* Free resources */
+	rte_pipeline_free(p->p);
+	rte_free(p);
+	return 0;
+}
+
+static int
+pipeline_passthrough_timer(void *pipeline)
+{
+	struct pipeline *p = (struct pipeline *) pipeline;
+
+	pipeline_msg_req_handle(p);
+	rte_pipeline_flush(p->p);
+
+	return 0;
+}
+
+static int
+pipeline_passthrough_track(void *pipeline, uint32_t port_in, uint32_t *port_out)
+{
+	struct pipeline *p = (struct pipeline *) pipeline;
+
+	/* Check input arguments */
+	if ((p == NULL) ||
+		(port_in >= p->n_ports_in) ||
+		(port_out == NULL))
+		return -1;
+	
+	*port_out = port_in / p->n_ports_in;
+	return 0;
+}
+
+struct pipeline_ops pipeline_passthrough_ops = {
+		.f_init = pipeline_passthrough_init,
+		.f_free = pipeline_passthrough_free,
+		.f_run = NULL,
+		.f_timer = pipeline_passthrough_timer,
+		.f_track = pipeline_passthrough_track,
+};
diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough_ops.h b/examples/ip_pipeline/pipeline/pipeline_passthrough_ops.h
new file mode 100644
index 0000000..8aebb07
--- /dev/null
+++ b/examples/ip_pipeline/pipeline/pipeline_passthrough_ops.h
@@ -0,0 +1,41 @@ 
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2010-2015 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.
+ */
+
+#ifndef __INCLUDE_PIPELINE_PASSTHROUGH_OPS_H__
+#define __INCLUDE_PIPELINE_PASSTHROUGH_OPS_H__
+
+#include "pipeline_ops.h"
+
+extern struct pipeline_ops pipeline_passthrough_ops;
+
+#endif