DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH] ip_pipeline: routing pipeline improvements
@ 2016-05-06 23:57 Jasvinder Singh
  2016-06-01 14:00 ` [dpdk-dev] [PATCH v2 0/6] " Jasvinder Singh
  0 siblings, 1 reply; 9+ messages in thread
From: Jasvinder Singh @ 2016-05-06 23:57 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

This patch implements the tracking mechanism for the routing pipeline in
order to identify the physical nic port where a specific output port of
the rotuing pipeline is eventually connected. Depending upon the
application, tracking could involve traversing the other intermediate
pipelines.

Typically, tracking is successful through those intermediate pipelines
where each input port is connected to a single out port for example
pass-through (RX, TX and TM), flow-actions etc. In such pipelines, all
the packets from the current port can only go out of the idetified output
port. In contrast, the pipelines such as flow-classification, firewall
don't allow the tracking mechanism due to one to many mapping between input
and output ports.

As a result of tracking mechainsm, routing pipeline uses the real MAC
addresses of the network interfaces instead of hardcoded default value.
Furthermore, it allows adding/removing the implicit routes every time when
the corresponding physical nic port is brought up/down.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
 examples/ip_pipeline/app.h                         | 137 +++++++++++++++++++++
 examples/ip_pipeline/pipeline/pipeline_common_fe.c |  88 +++++++++++++
 examples/ip_pipeline/pipeline/pipeline_common_fe.h |   5 +
 examples/ip_pipeline/pipeline/pipeline_routing.c   |  62 +++++++++-
 examples/ip_pipeline/pipeline/pipeline_routing.h   |   7 ++
 .../ip_pipeline/pipeline/pipeline_routing_be.c     |  37 ++++--
 .../ip_pipeline/pipeline/pipeline_routing_be.h     |  15 +++
 7 files changed, 341 insertions(+), 10 deletions(-)

diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index 55a9841..803e42e 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -665,6 +665,40 @@ app_swq_get_readers(struct app_params *app, struct app_pktq_swq_params *swq)
 	return n_readers;
 }
 
+static inline struct app_pipeline_params *
+app_swq_get_reader(struct app_params *app, struct app_pktq_swq_params *swq,
+	uint32_t *pktq_in_id)
+{
+	struct app_pipeline_params *reader;
+	uint32_t pos = swq - app->swq_params;
+	uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+		RTE_DIM(app->pipeline_params));
+	uint32_t n_readers = 0, id, i;
+
+	for (i = 0; i < n_pipelines; i++) {
+		struct app_pipeline_params *p = &app->pipeline_params[i];
+		uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
+		uint32_t j;
+
+		for (j = 0; j < n_pktq_in; j++) {
+			struct app_pktq_in_params *pktq = &p->pktq_in[j];
+
+			if ((pktq->type == APP_PKTQ_IN_SWQ) &&
+				(pktq->id == pos)) {
+				n_readers++;
+				reader = p;
+				id = j;
+			}
+		}
+	}
+
+	if (n_readers != 1)
+		return NULL;
+
+	*pktq_in_id = id;
+	return reader;
+}
+
 static inline uint32_t
 app_tm_get_readers(struct app_params *app, struct app_pktq_tm_params *tm)
 {
@@ -690,6 +724,40 @@ app_tm_get_readers(struct app_params *app, struct app_pktq_tm_params *tm)
 	return n_readers;
 }
 
+static inline struct app_pipeline_params *
+app_tm_get_reader(struct app_params *app, struct app_pktq_tm_params *tm,
+	uint32_t *pktq_in_id)
+{
+	struct app_pipeline_params *reader;
+	uint32_t pos = tm - app->tm_params;
+	uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+		RTE_DIM(app->pipeline_params));
+	uint32_t n_readers = 0, id, i;
+
+	for (i = 0; i < n_pipelines; i++) {
+		struct app_pipeline_params *p = &app->pipeline_params[i];
+		uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
+		uint32_t j;
+
+		for (j = 0; j < n_pktq_in; j++) {
+			struct app_pktq_in_params *pktq = &p->pktq_in[j];
+
+			if ((pktq->type == APP_PKTQ_IN_TM) &&
+				(pktq->id == pos)) {
+				n_readers++;
+				reader = p;
+				id = j;
+			}
+		}
+	}
+
+	if (n_readers != 1)
+		return NULL;
+
+	*pktq_in_id = id;
+	return reader;
+}
+
 static inline uint32_t
 app_source_get_readers(struct app_params *app,
 struct app_pktq_source_params *source)
@@ -789,6 +857,41 @@ app_swq_get_writers(struct app_params *app, struct app_pktq_swq_params *swq)
 	return n_writers;
 }
 
+static inline struct app_pipeline_params *
+app_swq_get_writer(struct app_params *app, struct app_pktq_swq_params *swq,
+	uint32_t *pktq_out_id)
+{
+	struct app_pipeline_params *writer;
+	uint32_t pos = swq - app->swq_params;
+	uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+		RTE_DIM(app->pipeline_params));
+	uint32_t n_writers = 0, id, i;
+
+	for (i = 0; i < n_pipelines; i++) {
+		struct app_pipeline_params *p = &app->pipeline_params[i];
+		uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
+			RTE_DIM(p->pktq_out));
+		uint32_t j;
+
+		for (j = 0; j < n_pktq_out; j++) {
+			struct app_pktq_out_params *pktq = &p->pktq_out[j];
+
+			if ((pktq->type == APP_PKTQ_OUT_SWQ) &&
+				(pktq->id == pos)) {
+				n_writers++;
+				writer = p;
+				id = j;
+			}
+		}
+	}
+
+	if (n_writers != 1)
+		return NULL;
+
+	*pktq_out_id = id;
+	return writer;
+}
+
 static inline uint32_t
 app_tm_get_writers(struct app_params *app, struct app_pktq_tm_params *tm)
 {
@@ -815,6 +918,40 @@ app_tm_get_writers(struct app_params *app, struct app_pktq_tm_params *tm)
 	return n_writers;
 }
 
+static inline struct app_pipeline_params *
+app_tm_get_writer(struct app_params *app, struct app_pktq_tm_params *tm,
+	uint32_t *pktq_out_id)
+{
+	struct app_pipeline_params *writer;
+	uint32_t pos = tm - app->tm_params;
+	uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+		RTE_DIM(app->pipeline_params));
+	uint32_t n_writers = 0, id, i;
+
+	for (i = 0; i < n_pipelines; i++) {
+		struct app_pipeline_params *p = &app->pipeline_params[i];
+		uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
+			RTE_DIM(p->pktq_out));
+		uint32_t j;
+
+		for (j = 0; j < n_pktq_out; j++) {
+			struct app_pktq_out_params *pktq = &p->pktq_out[j];
+
+			if ((pktq->type == APP_PKTQ_OUT_TM) &&
+				(pktq->id == pos))
+				n_writers++;
+				writer = p;
+				id = j;
+		}
+	}
+
+	if (n_writers != 1)
+		return NULL;
+
+	*pktq_out_id = id;
+	return writer;
+}
+
 static inline uint32_t
 app_sink_get_writers(struct app_params *app, struct app_pktq_sink_params *sink)
 {
diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.c b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
index a691d42..e29d9a1 100644
--- a/examples/ip_pipeline/pipeline/pipeline_common_fe.c
+++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
@@ -49,6 +49,94 @@
 
 #include "pipeline_common_fe.h"
 
+struct app_link_params *
+app_pipeline_track_pktq_out_to_link(struct app_params *app,
+	uint32_t pipeline_id,
+	uint32_t pktq_out_id)
+{
+	struct app_pipeline_params *p;
+
+	/* Check input arguments */
+	if (app == NULL)
+		return NULL;
+
+	APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
+	if (p == NULL)
+		return NULL;
+
+	for ( ; ; ) {
+		struct app_pktq_out_params *pktq_out =
+			&p->pktq_out[pktq_out_id];
+
+		switch (pktq_out->type) {
+		case APP_PKTQ_OUT_HWQ:
+		{
+			struct app_pktq_hwq_out_params *hwq_out;
+
+			hwq_out = &app->hwq_out_params[pktq_out->id];
+
+			return app_get_link_for_txq(app, hwq_out);
+		}
+
+		case APP_PKTQ_OUT_SWQ:
+		{
+			struct app_pipeline_data *pdata;
+			struct app_pktq_swq_params *swq;
+			uint32_t pktq_in_id;
+			int status;
+
+			swq = &app->swq_params[pktq_out->id];
+			p = app_swq_get_reader(app, swq, &pktq_in_id);
+			if (p == NULL)
+				return NULL;
+
+			pipeline_id = p - app->pipeline_params;
+			pdata = &app->pipeline_data[pipeline_id];
+			if (pdata->ptype->be_ops->f_track == NULL)
+				return NULL;
+
+			status = pdata->ptype->be_ops->f_track(pdata->be,
+				pktq_in_id,
+				&pktq_out_id);
+			if (status)
+				return NULL;
+
+			break;
+		}
+
+		case APP_PKTQ_OUT_TM:
+		{
+			struct app_pipeline_data *pdata;
+			struct app_pktq_tm_params *tm;
+			uint32_t pktq_in_id;
+			int status;
+
+			tm = &app->tm_params[pktq_out->id];
+			p = app_tm_get_reader(app, tm, &pktq_in_id);
+			if (p == NULL)
+				return NULL;
+
+			pipeline_id = p - app->pipeline_params;
+			pdata = &app->pipeline_data[pipeline_id];
+			if (pdata->ptype->be_ops->f_track == NULL)
+				return NULL;
+
+			status = pdata->ptype->be_ops->f_track(pdata->be,
+				pktq_in_id,
+				&pktq_out_id);
+			if (status)
+				return NULL;
+
+			break;
+		}
+
+		case APP_PKTQ_OUT_SINK:
+		default:
+			return NULL;
+		}
+	}
+}
+
 int
 app_pipeline_ping(struct app_params *app,
 	uint32_t pipeline_id)
diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.h b/examples/ip_pipeline/pipeline/pipeline_common_fe.h
index cfad963..7fa6ea9 100644
--- a/examples/ip_pipeline/pipeline/pipeline_common_fe.h
+++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.h
@@ -182,6 +182,11 @@ app_msg_send_recv(struct app_params *app,
 	return msg_recv;
 }
 
+struct app_link_params *
+app_pipeline_track_pktq_out_to_link(struct app_params *app,
+	uint32_t pipeline_id,
+	uint32_t pktq_out_id);
+
 int
 app_pipeline_ping(struct app_params *app,
 	uint32_t pipeline_id);
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.c b/examples/ip_pipeline/pipeline/pipeline_routing.c
index eab89f2..d890cc8 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing.c
+++ b/examples/ip_pipeline/pipeline/pipeline_routing.c
@@ -81,10 +81,11 @@ struct pipeline_routing {
 
 static void *
 pipeline_routing_init(struct pipeline_params *params,
-	__rte_unused void *arg)
+	void *arg)
 {
+	struct app_params *app = (struct app_params *) arg;
 	struct pipeline_routing *p;
-	uint32_t size;
+	uint32_t pipeline_id, size;
 
 	/* Check input arguments */
 	if ((params == NULL) ||
@@ -108,6 +109,9 @@ pipeline_routing_init(struct pipeline_params *params,
 	TAILQ_INIT(&p->arp_entries);
 	p->n_arp_entries = 0;
 
+	APP_PARAM_GET_ID(params, "PIPELINE", pipeline_id);
+	app_pipeline_routing_set_macaddr(app, pipeline_id);
+
 	return p;
 }
 
@@ -853,6 +857,60 @@ app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
 	return 0;
 }
 
+int
+app_pipeline_routing_set_macaddr(struct app_params *app,
+	uint32_t pipeline_id)
+{
+	struct pipeline_routing *p;
+
+	struct pipeline_routing_set_macaddr_msg_req *req;
+	struct pipeline_routing_set_macaddr_msg_rsp *rsp;
+	uint32_t port_id;
+
+	/* Check input arguments */
+	if (app == NULL)
+		return -1;
+
+	p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
+	if (p == NULL)
+		return -EINVAL;
+
+	/* Allocate and write request */
+	req = app_msg_alloc(app);
+	if (req == NULL)
+		return -ENOMEM;
+
+	req->type = PIPELINE_MSG_REQ_CUSTOM;
+	req->subtype = PIPELINE_ROUTING_MSG_REQ_SET_MACADDR;
+
+	memset(req->macaddr, 0, sizeof(req->macaddr));
+	for (port_id = 0; port_id < p->n_ports_out; port_id++) {
+		struct app_link_params *link;
+
+		link = app_pipeline_track_pktq_out_to_link(app,
+			pipeline_id,
+			port_id);
+		if (link)
+			req->macaddr[port_id] = link->mac_addr;
+	}
+
+	/* Send request and wait for response */
+	rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
+	if (rsp == NULL)
+		return -ETIMEDOUT;
+
+	/* Read response and write entry */
+	if (rsp->status) {
+		app_msg_free(app, rsp);
+		return rsp->status;
+	}
+
+	/* Free response */
+	app_msg_free(app, rsp);
+
+	return 0;
+}
+
 static int
 parse_labels(char *string, uint32_t *labels, uint32_t *n_labels)
 {
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.h b/examples/ip_pipeline/pipeline/pipeline_routing.h
index fa41642..0197449 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing.h
+++ b/examples/ip_pipeline/pipeline/pipeline_routing.h
@@ -86,6 +86,13 @@ app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
 	uint32_t pipeline_id);
 
 /*
+ * SETTINGS
+ */
+int
+app_pipeline_routing_set_macaddr(struct app_params *app,
+	uint32_t pipeline_id);
+
+/*
  * Pipeline type
  */
 extern struct pipeline_type pipeline_routing;
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.c b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
index bc5bf7a..d22a465 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
@@ -65,8 +65,6 @@
 	((((uint64_t) (pipe)) & 0xFFFFFFFF) << 32))
 
 
-#define MAC_SRC_DEFAULT 0x112233445566ULL
-
 #ifndef PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s
 #define PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s 256
 #endif
@@ -74,6 +72,7 @@
 struct pipeline_routing {
 	struct pipeline p;
 	struct pipeline_routing_params params;
+	uint64_t macaddr[PIPELINE_MAX_PORT_OUT];
 	pipeline_msg_req_handler custom_handlers[PIPELINE_ROUTING_MSG_REQS];
 } __rte_cache_aligned;
 
@@ -132,6 +131,10 @@ static void *
 pipeline_routing_msg_req_arp_del_default_handler(struct pipeline *p,
 	void *msg);
 
+static void *
+pipeline_routing_msg_req_set_macaddr_handler(struct pipeline *p,
+	void *msg);
+
 static pipeline_msg_req_handler custom_handlers[] = {
 	[PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD] =
 		pipeline_routing_msg_req_route_add_handler,
@@ -149,6 +152,8 @@ static pipeline_msg_req_handler custom_handlers[] = {
 		pipeline_routing_msg_req_arp_add_default_handler,
 	[PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT] =
 		pipeline_routing_msg_req_arp_del_default_handler,
+	[PIPELINE_ROUTING_MSG_REQ_SET_MACADDR] =
+		pipeline_routing_msg_req_set_macaddr_handler,
 };
 
 /*
@@ -1534,7 +1539,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether - ARP off */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) &&
 		(p_rt->params.n_arp_entries == 0)) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t macaddr_dst;
 		uint64_t ethertype = ETHER_TYPE_IPv4;
 
@@ -1556,7 +1561,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether - ARP on */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) &&
 		p_rt->params.n_arp_entries) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t ethertype = ETHER_TYPE_IPv4;
 
 		entry_arp1.slab[0] = rte_bswap64((macaddr_src << 16) |
@@ -1571,7 +1576,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether QinQ - ARP off */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
 		(p_rt->params.n_arp_entries == 0)) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t macaddr_dst;
 		uint64_t ethertype_ipv4 = ETHER_TYPE_IPv4;
 		uint64_t ethertype_vlan = 0x8100;
@@ -1603,7 +1608,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether QinQ - ARP on */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
 		p_rt->params.n_arp_entries) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t ethertype_ipv4 = ETHER_TYPE_IPv4;
 		uint64_t ethertype_vlan = 0x8100;
 		uint64_t ethertype_qinq = 0x9100;
@@ -1628,7 +1633,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether MPLS - ARP off */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
 		(p_rt->params.n_arp_entries == 0)) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t macaddr_dst;
 		uint64_t ethertype_mpls = 0x8847;
 
@@ -1714,7 +1719,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether MPLS - ARP on */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
 		p_rt->params.n_arp_entries) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t ethertype_mpls = 0x8847;
 
 		uint64_t label0 = req->data.l2.mpls.labels[0];
@@ -1961,6 +1966,22 @@ pipeline_routing_msg_req_arp_del_default_handler(struct pipeline *p, void *msg)
 	return rsp;
 }
 
+void *
+pipeline_routing_msg_req_set_macaddr_handler(struct pipeline *p, void *msg)
+{
+	struct pipeline_routing *p_rt = (struct pipeline_routing *) p;
+	struct pipeline_routing_set_macaddr_msg_req *req = msg;
+	struct pipeline_routing_set_macaddr_msg_rsp *rsp = msg;
+	uint32_t port_id;
+
+	for (port_id = 0; port_id < p->n_ports_out; port_id++)
+		p_rt->macaddr[port_id] = req->macaddr[port_id];
+
+	rsp->status = 0;
+
+	return rsp;
+}
+
 struct pipeline_be_ops pipeline_routing_be_ops = {
 	.f_init = pipeline_routing_init,
 	.f_free = pipeline_routing_free,
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.h b/examples/ip_pipeline/pipeline/pipeline_routing_be.h
index ec767b2..822995b 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing_be.h
+++ b/examples/ip_pipeline/pipeline/pipeline_routing_be.h
@@ -160,6 +160,7 @@ enum pipeline_routing_msg_req_type {
 	PIPELINE_ROUTING_MSG_REQ_ARP_DEL,
 	PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT,
 	PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT,
+	PIPELINE_ROUTING_MSG_REQ_SET_MACADDR,
 	PIPELINE_ROUTING_MSG_REQS
 };
 
@@ -291,6 +292,20 @@ struct pipeline_routing_arp_delete_default_msg_rsp {
 	int status;
 };
 
+/*
+ * MSG SET MACADDR
+ */
+struct pipeline_routing_set_macaddr_msg_req {
+	enum pipeline_msg_req_type type;
+	enum pipeline_routing_msg_req_type subtype;
+
+	uint64_t macaddr[PIPELINE_MAX_PORT_OUT];
+};
+
+struct pipeline_routing_set_macaddr_msg_rsp {
+	int status;
+};
+
 extern struct pipeline_be_ops pipeline_routing_be_ops;
 
 #endif
-- 
2.5.5

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [dpdk-dev] [PATCH v2 0/6] ip_pipeline: routing pipeline improvements
  2016-05-06 23:57 [dpdk-dev] [PATCH] ip_pipeline: routing pipeline improvements Jasvinder Singh
@ 2016-06-01 14:00 ` Jasvinder Singh
  2016-06-01 14:00   ` [dpdk-dev] [PATCH v2 1/6] ip_pipeline: increase macros values Jasvinder Singh
                     ` (6 more replies)
  0 siblings, 7 replies; 9+ messages in thread
From: Jasvinder Singh @ 2016-06-01 14:00 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

This commit adds following features to the routing pipeline;

1. Implements the tracking mechanism for the routing pipeline for identifying
the physical nic port where a specific output ports of the routing pipeline are
eventually connected. Depending upon the application, tracking could involve
traversing the other intermediate pipelines.

The pipelines such as pass-through allows tracking to be performaned through
them becasue of straightforward connections between their input and output
ports, while pipelines like flow-classifications, firewall fails the tracking
because of dependency upon the table rule set. As a result of tracking
mechainsm, routing pipeline uses the real MAC addresses of the network
interfaces instead of hardcoded default value.

2. Adds support for automatic route automatic update when physical NIC ports
change their state (up/down) or configuration. Every time a physical port
goes up/down, a call-back function that the specific pipeline type
(e.g. routing) registered with NIC ports at init time; will simply add/delete
a route associated with that output port.

v2
- rebased on top of "ip_pipeline: add rss support" patch
  http://dpdk.org/dev/patchwork/patch/13110/
- split the single patch into multiple patches of the patchset. 
- add post init function for tracking and linking physical nic with 
  routing pipeline output port
- create default tracking function "app_pipeline_track_default()" in
  pipeline_common_fe.c for all the pipelines except pass-through
- fix port in/out connections in passthrough pipeline tracking function
  and move that function to pipeline/pipeline_passthrough.c
- fix mac address endianess issue in routing pipeline table
- add/remove implicit routes (for host and local network) when corresponding
  link is brought up/down
- update the release notes

Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>

Jasvinder Singh (6):
  ip_pipeline: increase macros values
  ip_pipeline: linking routing pipeline output ports with NIC ports
  ip_pipeline: assign nic ports mac address to the routing pipeline
    outports
  ip_pipeline: automatic routes update with the change in nic ports
    state
  ip_pipeline: sample config file on adding various network layer
    components
  ip_pipeline: update release notes

 doc/guides/rel_notes/release_16_07.rst             |  10 +
 examples/ip_pipeline/app.h                         | 184 ++++++++++++++--
 examples/ip_pipeline/config/network_layers.cfg     | 223 +++++++++++++++++++
 examples/ip_pipeline/config/network_layers.sh      |  79 +++++++
 examples/ip_pipeline/init.c                        |  32 ++-
 examples/ip_pipeline/pipeline.h                    |  11 +-
 examples/ip_pipeline/pipeline/pipeline_common_fe.c | 161 ++++++++++++++
 examples/ip_pipeline/pipeline/pipeline_common_fe.h |  17 ++
 examples/ip_pipeline/pipeline/pipeline_firewall.c  |   2 +
 .../ip_pipeline/pipeline/pipeline_firewall_be.c    |  22 --
 .../ip_pipeline/pipeline/pipeline_flow_actions.c   |   2 +
 .../pipeline/pipeline_flow_actions_be.c            |  22 --
 .../pipeline/pipeline_flow_classification.c        |   2 +
 .../pipeline/pipeline_flow_classification_be.c     |  22 --
 examples/ip_pipeline/pipeline/pipeline_master.c    |   2 +
 examples/ip_pipeline/pipeline/pipeline_master_be.c |  13 +-
 .../ip_pipeline/pipeline/pipeline_passthrough.c    |  27 +++
 .../ip_pipeline/pipeline/pipeline_passthrough_be.c |  39 ++--
 examples/ip_pipeline/pipeline/pipeline_routing.c   | 239 ++++++++++++++++++++-
 examples/ip_pipeline/pipeline/pipeline_routing.h   |   7 +
 .../ip_pipeline/pipeline/pipeline_routing_be.c     | 102 +++++----
 .../ip_pipeline/pipeline/pipeline_routing_be.h     |  16 ++
 examples/ip_pipeline/pipeline_be.h                 |  18 +-
 23 files changed, 1091 insertions(+), 161 deletions(-)
 create mode 100644 examples/ip_pipeline/config/network_layers.cfg
 create mode 100644 examples/ip_pipeline/config/network_layers.sh

-- 
2.5.5

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [dpdk-dev] [PATCH v2 1/6] ip_pipeline: increase macros values
  2016-06-01 14:00 ` [dpdk-dev] [PATCH v2 0/6] " Jasvinder Singh
@ 2016-06-01 14:00   ` Jasvinder Singh
  2016-06-01 14:00   ` [dpdk-dev] [PATCH v2 2/6] ip_pipeline: linking routing pipeline output ports with NIC ports Jasvinder Singh
                     ` (5 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jasvinder Singh @ 2016-06-01 14:00 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

To allow more queues, pipeline types, threads, source/sink ports,etc., in
the ip pipeline application, larger values of macros are set.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/app.h         | 12 ++++++------
 examples/ip_pipeline/pipeline_be.h |  8 ++++----
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index 976fbd0..dfdfb51 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -52,11 +52,11 @@
 #define APP_LINK_PCI_BDF_SIZE                    16
 
 #ifndef APP_LINK_MAX_HWQ_IN
-#define APP_LINK_MAX_HWQ_IN                      64
+#define APP_LINK_MAX_HWQ_IN                      128
 #endif
 
 #ifndef APP_LINK_MAX_HWQ_OUT
-#define APP_LINK_MAX_HWQ_OUT                     64
+#define APP_LINK_MAX_HWQ_OUT                     128
 #endif
 
 struct app_mempool_params {
@@ -261,7 +261,7 @@ struct app_thread_pipeline_data {
 };
 
 #ifndef APP_MAX_THREAD_PIPELINES
-#define APP_MAX_THREAD_PIPELINES                 16
+#define APP_MAX_THREAD_PIPELINES                 64
 #endif
 
 #ifndef APP_THREAD_TIMER_PERIOD
@@ -407,15 +407,15 @@ struct app_eal_params {
 #define APP_MAX_PKTQ_TM                          APP_MAX_LINKS
 
 #ifndef APP_MAX_PKTQ_SOURCE
-#define APP_MAX_PKTQ_SOURCE                      16
+#define APP_MAX_PKTQ_SOURCE                      64
 #endif
 
 #ifndef APP_MAX_PKTQ_SINK
-#define APP_MAX_PKTQ_SINK                        16
+#define APP_MAX_PKTQ_SINK                        64
 #endif
 
 #ifndef APP_MAX_MSGQ
-#define APP_MAX_MSGQ                             64
+#define APP_MAX_MSGQ                             256
 #endif
 
 #ifndef APP_MAX_PIPELINES
diff --git a/examples/ip_pipeline/pipeline_be.h b/examples/ip_pipeline/pipeline_be.h
index f4ff262..8f858ed 100644
--- a/examples/ip_pipeline/pipeline_be.h
+++ b/examples/ip_pipeline/pipeline_be.h
@@ -200,15 +200,15 @@ pipeline_port_out_params_get_ops(struct pipeline_port_out_params  *p)
 }
 
 #ifndef PIPELINE_NAME_SIZE
-#define PIPELINE_NAME_SIZE                       32
+#define PIPELINE_NAME_SIZE                       64
 #endif
 
 #ifndef PIPELINE_MAX_PORT_IN
-#define PIPELINE_MAX_PORT_IN                     16
+#define PIPELINE_MAX_PORT_IN                     64
 #endif
 
 #ifndef PIPELINE_MAX_PORT_OUT
-#define PIPELINE_MAX_PORT_OUT                    16
+#define PIPELINE_MAX_PORT_OUT                    64
 #endif
 
 #ifndef PIPELINE_MAX_TABLES
@@ -224,7 +224,7 @@ pipeline_port_out_params_get_ops(struct pipeline_port_out_params  *p)
 #endif
 
 #ifndef PIPELINE_MAX_ARGS
-#define PIPELINE_MAX_ARGS                        32
+#define PIPELINE_MAX_ARGS                        64
 #endif
 
 struct pipeline_params {
-- 
2.5.5

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [dpdk-dev] [PATCH v2 2/6] ip_pipeline: linking routing pipeline output ports with NIC ports
  2016-06-01 14:00 ` [dpdk-dev] [PATCH v2 0/6] " Jasvinder Singh
  2016-06-01 14:00   ` [dpdk-dev] [PATCH v2 1/6] ip_pipeline: increase macros values Jasvinder Singh
@ 2016-06-01 14:00   ` Jasvinder Singh
  2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 3/6] ip_pipeline: assign nic ports mac address to the routing pipeline outports Jasvinder Singh
                     ` (4 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jasvinder Singh @ 2016-06-01 14:00 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

This commit implements tracking mechanism for linking routing pipeline
output ports to physical NIC ports.

Once all the pipelines of the application are initialised, mechanism is
invoked during post initialisation phase for relating routing pipeline
output with NIC ports by navigating through the intermediate pipelines,
if present.

The tracking functions of the pipelines which help in navigating through
the intermediate pipelines are moved from pipeline_<pipeline_name>_be.c
to pipeline_<pipeline_name>.c. All pipelines except passthrough pipelines
use default tracking function (pipeline/pipeline_common_fe.c).

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/app.h                         | 151 ++++++++++++++++++++-
 examples/ip_pipeline/init.c                        |  32 ++++-
 examples/ip_pipeline/pipeline.h                    |  11 +-
 examples/ip_pipeline/pipeline/pipeline_common_fe.c | 109 +++++++++++++++
 examples/ip_pipeline/pipeline/pipeline_common_fe.h |  10 ++
 examples/ip_pipeline/pipeline/pipeline_firewall.c  |   2 +
 .../ip_pipeline/pipeline/pipeline_firewall_be.c    |  22 ---
 .../ip_pipeline/pipeline/pipeline_flow_actions.c   |   2 +
 .../pipeline/pipeline_flow_actions_be.c            |  22 ---
 .../pipeline/pipeline_flow_classification.c        |   2 +
 .../pipeline/pipeline_flow_classification_be.c     |  22 ---
 examples/ip_pipeline/pipeline/pipeline_master.c    |   2 +
 examples/ip_pipeline/pipeline/pipeline_master_be.c |  13 +-
 .../ip_pipeline/pipeline/pipeline_passthrough.c    |  27 ++++
 .../ip_pipeline/pipeline/pipeline_passthrough_be.c |  39 +++---
 examples/ip_pipeline/pipeline/pipeline_routing.c   |   6 +-
 .../ip_pipeline/pipeline/pipeline_routing_be.c     |  22 ---
 examples/ip_pipeline/pipeline_be.h                 |  10 +-
 18 files changed, 380 insertions(+), 124 deletions(-)

diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index dfdfb51..93e96d0 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -205,9 +205,7 @@ struct app_pktq_out_params {
 	uint32_t id; /* Position in the appropriate app array */
 };
 
-#ifndef APP_PIPELINE_TYPE_SIZE
-#define APP_PIPELINE_TYPE_SIZE                   64
-#endif
+#define APP_PIPELINE_TYPE_SIZE                   PIPELINE_TYPE_SIZE
 
 #define APP_MAX_PIPELINE_PKTQ_IN                 PIPELINE_MAX_PORT_IN
 #define APP_MAX_PIPELINE_PKTQ_OUT                PIPELINE_MAX_PORT_OUT
@@ -651,6 +649,41 @@ app_swq_get_readers(struct app_params *app, struct app_pktq_swq_params *swq)
 	return n_readers;
 }
 
+static inline struct app_pipeline_params *
+app_swq_get_reader(struct app_params *app,
+	struct app_pktq_swq_params *swq,
+	uint32_t *pktq_in_id)
+{
+	struct app_pipeline_params *reader;
+	uint32_t pos = swq - app->swq_params;
+	uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+		RTE_DIM(app->pipeline_params));
+	uint32_t n_readers = 0, id, i;
+
+	for (i = 0; i < n_pipelines; i++) {
+		struct app_pipeline_params *p = &app->pipeline_params[i];
+		uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
+		uint32_t j;
+
+		for (j = 0; j < n_pktq_in; j++) {
+			struct app_pktq_in_params *pktq = &p->pktq_in[j];
+
+			if ((pktq->type == APP_PKTQ_IN_SWQ) &&
+				(pktq->id == pos)) {
+				n_readers++;
+				reader = p;
+				id = j;
+			}
+		}
+	}
+
+	if (n_readers != 1)
+		return NULL;
+
+	*pktq_in_id = id;
+	return reader;
+}
+
 static inline uint32_t
 app_tm_get_readers(struct app_params *app, struct app_pktq_tm_params *tm)
 {
@@ -676,6 +709,41 @@ app_tm_get_readers(struct app_params *app, struct app_pktq_tm_params *tm)
 	return n_readers;
 }
 
+static inline struct app_pipeline_params *
+app_tm_get_reader(struct app_params *app,
+	struct app_pktq_tm_params *tm,
+	uint32_t *pktq_in_id)
+{
+	struct app_pipeline_params *reader;
+	uint32_t pos = tm - app->tm_params;
+	uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+		RTE_DIM(app->pipeline_params));
+	uint32_t n_readers = 0, id, i;
+
+	for (i = 0; i < n_pipelines; i++) {
+		struct app_pipeline_params *p = &app->pipeline_params[i];
+		uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
+		uint32_t j;
+
+		for (j = 0; j < n_pktq_in; j++) {
+			struct app_pktq_in_params *pktq = &p->pktq_in[j];
+
+			if ((pktq->type == APP_PKTQ_IN_TM) &&
+				(pktq->id == pos)) {
+				n_readers++;
+				reader = p;
+				id = j;
+			}
+		}
+	}
+
+	if (n_readers != 1)
+		return NULL;
+
+	*pktq_in_id = id;
+	return reader;
+}
+
 static inline uint32_t
 app_source_get_readers(struct app_params *app,
 struct app_pktq_source_params *source)
@@ -775,6 +843,42 @@ app_swq_get_writers(struct app_params *app, struct app_pktq_swq_params *swq)
 	return n_writers;
 }
 
+static inline struct app_pipeline_params *
+app_swq_get_writer(struct app_params *app,
+	struct app_pktq_swq_params *swq,
+	uint32_t *pktq_out_id)
+{
+	struct app_pipeline_params *writer;
+	uint32_t pos = swq - app->swq_params;
+	uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+		RTE_DIM(app->pipeline_params));
+	uint32_t n_writers = 0, id, i;
+
+	for (i = 0; i < n_pipelines; i++) {
+		struct app_pipeline_params *p = &app->pipeline_params[i];
+		uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
+			RTE_DIM(p->pktq_out));
+		uint32_t j;
+
+		for (j = 0; j < n_pktq_out; j++) {
+			struct app_pktq_out_params *pktq = &p->pktq_out[j];
+
+			if ((pktq->type == APP_PKTQ_OUT_SWQ) &&
+				(pktq->id == pos)) {
+				n_writers++;
+				writer = p;
+				id = j;
+			}
+		}
+	}
+
+	if (n_writers != 1)
+		return NULL;
+
+	*pktq_out_id = id;
+	return writer;
+}
+
 static inline uint32_t
 app_tm_get_writers(struct app_params *app, struct app_pktq_tm_params *tm)
 {
@@ -801,6 +905,41 @@ app_tm_get_writers(struct app_params *app, struct app_pktq_tm_params *tm)
 	return n_writers;
 }
 
+static inline struct app_pipeline_params *
+app_tm_get_writer(struct app_params *app,
+	struct app_pktq_tm_params *tm,
+	uint32_t *pktq_out_id)
+{
+	struct app_pipeline_params *writer;
+	uint32_t pos = tm - app->tm_params;
+	uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
+		RTE_DIM(app->pipeline_params));
+	uint32_t n_writers = 0, id, i;
+
+	for (i = 0; i < n_pipelines; i++) {
+		struct app_pipeline_params *p = &app->pipeline_params[i];
+		uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
+			RTE_DIM(p->pktq_out));
+		uint32_t j;
+
+		for (j = 0; j < n_pktq_out; j++) {
+			struct app_pktq_out_params *pktq = &p->pktq_out[j];
+
+			if ((pktq->type == APP_PKTQ_OUT_TM) &&
+				(pktq->id == pos))
+				n_writers++;
+				writer = p;
+				id = j;
+		}
+	}
+
+	if (n_writers != 1)
+		return NULL;
+
+	*pktq_out_id = id;
+	return writer;
+}
+
 static inline uint32_t
 app_sink_get_writers(struct app_params *app, struct app_pktq_sink_params *sink)
 {
@@ -899,6 +1038,10 @@ app_get_link_for_tm(struct app_params *app, struct app_pktq_tm_params *p_tm)
 	return &app->link_params[link_param_idx];
 }
 
+void app_pipeline_params_get(struct app_params *app,
+	struct app_pipeline_params *p_in,
+	struct pipeline_params *p_out);
+
 int app_config_init(struct app_params *app);
 
 int app_config_args(struct app_params *app,
@@ -918,6 +1061,8 @@ int app_config_check(struct app_params *app);
 
 int app_init(struct app_params *app);
 
+int app_post_init(struct app_params *app);
+
 int app_thread(void *arg);
 
 int app_pipeline_type_register(struct app_params *app,
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index b2eafe3..7120bab 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -1196,7 +1196,7 @@ app_init_msgq(struct app_params *app)
 	}
 }
 
-static void app_pipeline_params_get(struct app_params *app,
+void app_pipeline_params_get(struct app_params *app,
 	struct app_pipeline_params *p_in,
 	struct pipeline_params *p_out)
 {
@@ -1204,6 +1204,8 @@ static void app_pipeline_params_get(struct app_params *app,
 
 	snprintf(p_out->name, PIPELINE_NAME_SIZE, "%s", p_in->name);
 
+	snprintf(p_out->type, PIPELINE_TYPE_SIZE, "%s", p_in->type);
+
 	p_out->socket_id = (int) p_in->socket_id;
 
 	p_out->log_level = app->log_level;
@@ -1499,6 +1501,27 @@ app_init_pipelines(struct app_params *app)
 }
 
 static void
+app_post_init_pipelines(struct app_params *app)
+{
+	uint32_t p_id;
+
+	for (p_id = 0; p_id < app->n_pipelines; p_id++) {
+		struct app_pipeline_params *params =
+			&app->pipeline_params[p_id];
+		struct app_pipeline_data *data = &app->pipeline_data[p_id];
+		int status;
+
+		if (data->ptype->fe_ops->f_post_init == NULL)
+			continue;
+
+		status = data->ptype->fe_ops->f_post_init(data->fe);
+		if (status)
+			rte_panic("Pipeline instance \"%s\" front-end "
+				"post-init error\n", params->name);
+	}
+}
+
+static void
 app_init_threads(struct app_params *app)
 {
 	uint64_t time = rte_get_tsc_cycles();
@@ -1601,6 +1624,13 @@ int app_init(struct app_params *app)
 	return 0;
 }
 
+int app_post_init(struct app_params *app)
+{
+	app_post_init_pipelines(app);
+
+	return 0;
+}
+
 static int
 app_pipeline_type_cmd_push(struct app_params *app,
 	struct pipeline_type *ptype)
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index dab9c36..14a551d 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -42,13 +42,22 @@
  * Pipeline type front-end operations
  */
 
-typedef void* (*pipeline_fe_op_init)(struct pipeline_params *params, void *arg);
+typedef void* (*pipeline_fe_op_init)(struct pipeline_params *params,
+	void *arg);
+
+typedef int (*pipeline_fe_op_post_init)(void *pipeline);
 
 typedef int (*pipeline_fe_op_free)(void *pipeline);
 
+typedef int (*pipeline_fe_op_track)(struct pipeline_params *params,
+	uint32_t port_in,
+	uint32_t *port_out);
+
 struct pipeline_fe_ops {
 	pipeline_fe_op_init f_init;
+	pipeline_fe_op_post_init f_post_init;
 	pipeline_fe_op_free f_free;
+	pipeline_fe_op_track f_track;
 	cmdline_parse_ctx_t *cmds;
 };
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.c b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
index dc37a5f..fa0a482 100644
--- a/examples/ip_pipeline/pipeline/pipeline_common_fe.c
+++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
@@ -47,6 +47,115 @@
 #include "pipeline_common_fe.h"
 #include "parser.h"
 
+struct app_link_params *
+app_pipeline_track_pktq_out_to_link(struct app_params *app,
+	uint32_t pipeline_id,
+	uint32_t pktq_out_id)
+{
+	struct app_pipeline_params *p;
+
+	/* Check input arguments */
+	if (app == NULL)
+		return NULL;
+
+	APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
+	if (p == NULL)
+		return NULL;
+
+	for ( ; ; ) {
+		struct app_pktq_out_params *pktq_out =
+			&p->pktq_out[pktq_out_id];
+
+		switch (pktq_out->type) {
+		case APP_PKTQ_OUT_HWQ:
+		{
+			struct app_pktq_hwq_out_params *hwq_out;
+
+			hwq_out = &app->hwq_out_params[pktq_out->id];
+
+			return app_get_link_for_txq(app, hwq_out);
+		}
+
+		case APP_PKTQ_OUT_SWQ:
+		{
+			struct pipeline_params pp;
+			struct pipeline_type *ptype;
+			struct app_pktq_swq_params *swq;
+			uint32_t pktq_in_id;
+			int status;
+
+			swq = &app->swq_params[pktq_out->id];
+			p = app_swq_get_reader(app, swq, &pktq_in_id);
+			if (p == NULL)
+				return NULL;
+
+			ptype = app_pipeline_type_find(app, p->type);
+			if ((ptype == NULL) || (ptype->fe_ops->f_track == NULL))
+				return NULL;
+
+			app_pipeline_params_get(app, p, &pp);
+			status = ptype->fe_ops->f_track(&pp,
+				pktq_in_id,
+				&pktq_out_id);
+			if (status)
+				return NULL;
+
+			break;
+		}
+
+		case APP_PKTQ_OUT_TM:
+		{
+			struct pipeline_params pp;
+			struct pipeline_type *ptype;
+			struct app_pktq_tm_params *tm;
+			uint32_t pktq_in_id;
+			int status;
+
+			tm = &app->tm_params[pktq_out->id];
+			p = app_tm_get_reader(app, tm, &pktq_in_id);
+			if (p == NULL)
+				return NULL;
+
+			ptype = app_pipeline_type_find(app, p->type);
+			if ((ptype == NULL) || (ptype->fe_ops->f_track == NULL))
+				return NULL;
+
+			app_pipeline_params_get(app, p, &pp);
+			status = ptype->fe_ops->f_track(&pp,
+				pktq_in_id,
+				&pktq_out_id);
+			if (status)
+				return NULL;
+
+			break;
+		}
+
+		case APP_PKTQ_OUT_SINK:
+		default:
+			return NULL;
+		}
+	}
+}
+
+int
+app_pipeline_track_default(struct pipeline_params *p,
+	uint32_t port_in,
+	uint32_t *port_out)
+{
+	/* Check input arguments */
+	if ((p == NULL) ||
+		(port_in >= p->n_ports_in) ||
+		(port_out == NULL))
+		return -1;
+
+	if (p->n_ports_out == 1) {
+		*port_out = 0;
+		return 0;
+	}
+
+	return -1;
+}
+
 int
 app_pipeline_ping(struct app_params *app,
 	uint32_t pipeline_id)
diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.h b/examples/ip_pipeline/pipeline/pipeline_common_fe.h
index f93ff74..8abee4a 100644
--- a/examples/ip_pipeline/pipeline/pipeline_common_fe.h
+++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.h
@@ -182,6 +182,16 @@ app_msg_send_recv(struct app_params *app,
 	return msg_recv;
 }
 
+struct app_link_params *
+app_pipeline_track_pktq_out_to_link(struct app_params *app,
+	uint32_t pipeline_id,
+	uint32_t pktq_out_id);
+
+int
+app_pipeline_track_default(struct pipeline_params *params,
+	uint32_t port_in,
+	uint32_t *port_out);
+
 int
 app_pipeline_ping(struct app_params *app,
 	uint32_t pipeline_id);
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall.c b/examples/ip_pipeline/pipeline/pipeline_firewall.c
index 30b22a1..a82e552 100644
--- a/examples/ip_pipeline/pipeline/pipeline_firewall.c
+++ b/examples/ip_pipeline/pipeline/pipeline_firewall.c
@@ -1437,7 +1437,9 @@ static cmdline_parse_ctx_t pipeline_cmds[] = {
 
 static struct pipeline_fe_ops pipeline_firewall_fe_ops = {
 	.f_init = app_pipeline_firewall_init,
+	.f_post_init = NULL,
 	.f_free = app_pipeline_firewall_free,
+	.f_track = app_pipeline_track_default,
 	.cmds = pipeline_cmds,
 };
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall_be.c b/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
index 4edca66..b61f303 100644
--- a/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
@@ -565,27 +565,6 @@ pipeline_firewall_free(void *pipeline)
 }
 
 static int
-pipeline_firewall_track(void *pipeline,
-	__rte_unused 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;
-
-	if (p->n_ports_in == 1) {
-		*port_out = 0;
-		return 0;
-	}
-
-	return -1;
-}
-
-static int
 pipeline_firewall_timer(void *pipeline)
 {
 	struct pipeline *p = (struct pipeline *) pipeline;
@@ -903,5 +882,4 @@ struct pipeline_be_ops pipeline_firewall_be_ops = {
 	.f_free = pipeline_firewall_free,
 	.f_run = NULL,
 	.f_timer = pipeline_firewall_timer,
-	.f_track = pipeline_firewall_track,
 };
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_actions.c b/examples/ip_pipeline/pipeline/pipeline_flow_actions.c
index 7560051..bf12fd7 100644
--- a/examples/ip_pipeline/pipeline/pipeline_flow_actions.c
+++ b/examples/ip_pipeline/pipeline/pipeline_flow_actions.c
@@ -1300,7 +1300,9 @@ static cmdline_parse_ctx_t pipeline_cmds[] = {
 
 static struct pipeline_fe_ops pipeline_flow_actions_fe_ops = {
 	.f_init = app_pipeline_fa_init,
+	.f_post_init = NULL,
 	.f_free = app_pipeline_fa_free,
+	.f_track = app_pipeline_track_default,
 	.cmds = pipeline_cmds,
 };
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
index 3ad3ee6..11fcbb7 100644
--- a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
@@ -760,27 +760,6 @@ pipeline_fa_free(void *pipeline)
 }
 
 static int
-pipeline_fa_track(void *pipeline,
-	__rte_unused 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;
-
-	if (p->n_ports_in == 1) {
-		*port_out = 0;
-		return 0;
-	}
-
-	return -1;
-}
-
-static int
 pipeline_fa_timer(void *pipeline)
 {
 	struct pipeline *p = (struct pipeline *) pipeline;
@@ -1007,5 +986,4 @@ struct pipeline_be_ops pipeline_flow_actions_be_ops = {
 	.f_free = pipeline_fa_free,
 	.f_run = NULL,
 	.f_timer = pipeline_fa_timer,
-	.f_track = pipeline_fa_track,
 };
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification.c
index e49c881..9ef50cc 100644
--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c
+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification.c
@@ -1892,7 +1892,9 @@ static cmdline_parse_ctx_t pipeline_cmds[] = {
 
 static struct pipeline_fe_ops pipeline_flow_classification_fe_ops = {
 	.f_init = app_pipeline_fc_init,
+	.f_post_init = NULL,
 	.f_free = app_pipeline_fc_free,
+	.f_track = app_pipeline_track_default,
 	.cmds = pipeline_cmds,
 };
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
index 70d976d..8a762bc 100644
--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
@@ -643,27 +643,6 @@ pipeline_fc_free(void *pipeline)
 }
 
 static int
-pipeline_fc_track(void *pipeline,
-	__rte_unused 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;
-
-	if (p->n_ports_in == 1) {
-		*port_out = 0;
-		return 0;
-	}
-
-	return -1;
-}
-
-static int
 pipeline_fc_timer(void *pipeline)
 {
 	struct pipeline *p = (struct pipeline *) pipeline;
@@ -807,5 +786,4 @@ struct pipeline_be_ops pipeline_flow_classification_be_ops = {
 	.f_free = pipeline_fc_free,
 	.f_run = NULL,
 	.f_timer = pipeline_fc_timer,
-	.f_track = pipeline_fc_track,
 };
diff --git a/examples/ip_pipeline/pipeline/pipeline_master.c b/examples/ip_pipeline/pipeline/pipeline_master.c
index 1ccdad1..aab58a2 100644
--- a/examples/ip_pipeline/pipeline/pipeline_master.c
+++ b/examples/ip_pipeline/pipeline/pipeline_master.c
@@ -36,7 +36,9 @@
 
 static struct pipeline_fe_ops pipeline_master_fe_ops = {
 	.f_init = NULL,
+	.f_post_init = NULL,
 	.f_free = NULL,
+	.f_track = NULL,
 	.cmds = NULL,
 };
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_master_be.c b/examples/ip_pipeline/pipeline/pipeline_master_be.c
index ac0cbbc..79869a4 100644
--- a/examples/ip_pipeline/pipeline/pipeline_master_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_master_be.c
@@ -48,6 +48,7 @@
 struct pipeline_master {
 	struct app_params *app;
 	struct cmdline *cl;
+	int post_init_done;
 	int script_file_done;
 } __rte_cache_aligned;
 
@@ -77,6 +78,7 @@ pipeline_init(__rte_unused struct pipeline_params *params, void *arg)
 		return NULL;
 	}
 
+	p->post_init_done = 0;
 	p->script_file_done = 0;
 	if (app->script_file == NULL)
 		p->script_file_done = 1;
@@ -102,8 +104,17 @@ static int
 pipeline_run(void *pipeline)
 {
 	struct pipeline_master *p = (struct pipeline_master *) pipeline;
+	struct app_params *app = p->app;
 	int status;
 
+	/* Application post-init phase */
+	if (p->post_init_done == 0) {
+		app_post_init(app);
+
+		p->post_init_done = 1;
+	}
+
+	/* Run startup script file */
 	if (p->script_file_done == 0) {
 		struct app_params *app = p->app;
 		int fd = open(app->script_file, O_RDONLY);
@@ -124,6 +135,7 @@ pipeline_run(void *pipeline)
 		p->script_file_done = 1;
 	}
 
+	/* Command Line Interface (CLI) */
 	status = cmdline_poll(p->cl);
 	if (status < 0)
 		rte_panic("CLI poll error (%" PRId32 ")\n", status);
@@ -146,5 +158,4 @@ struct pipeline_be_ops pipeline_master_be_ops = {
 		.f_free = pipeline_free,
 		.f_run = pipeline_run,
 		.f_timer = pipeline_timer,
-		.f_track = NULL,
 };
diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough.c b/examples/ip_pipeline/pipeline/pipeline_passthrough.c
index fc2cae5..63ce147 100644
--- a/examples/ip_pipeline/pipeline/pipeline_passthrough.c
+++ b/examples/ip_pipeline/pipeline/pipeline_passthrough.c
@@ -34,9 +34,36 @@
 #include "pipeline_passthrough.h"
 #include "pipeline_passthrough_be.h"
 
+static int
+app_pipeline_passthrough_track(struct pipeline_params *p,
+	uint32_t port_in,
+	uint32_t *port_out)
+{
+	struct pipeline_passthrough_params pp;
+	int status;
+
+	/* Check input arguments */
+	if ((p == NULL) ||
+		(port_in >= p->n_ports_in) ||
+		(port_out == NULL))
+		return -1;
+
+	status = pipeline_passthrough_parse_args(&pp, p);
+	if (status)
+		return -1;
+
+	if (pp.lb_hash_enabled)
+		return -1;
+
+	*port_out = port_in / (p->n_ports_in / p->n_ports_out);
+	return 0;
+}
+
 static struct pipeline_fe_ops pipeline_passthrough_fe_ops = {
 	.f_init = NULL,
+	.f_post_init = NULL,
 	.f_free = NULL,
+	.f_track = app_pipeline_passthrough_track,
 	.cmds = NULL,
 };
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
index a0d11ae..6146a28 100644
--- a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
@@ -547,6 +547,18 @@ pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
 			"dma_src_mask", dma_mask_str);
 	}
 
+	if (p->lb_hash_enabled)
+		PIPELINE_ARG_CHECK((params->n_ports_out > 1),
+			"Parse error in section \"%s\": entry \"lb\" not "
+			"allowed for single output port pipeline",
+			params->name);
+	else
+		PIPELINE_ARG_CHECK(((params->n_ports_in >= params->n_ports_out)
+			&& ((params->n_ports_in % params->n_ports_out) == 0)),
+			"Parse error in section \"%s\": n_ports_in needs to be "
+			"a multiple of n_ports_out (lb mode disabled)",
+			params->name);
+
 	return 0;
 }
 
@@ -579,9 +591,7 @@ pipeline_passthrough_init(struct pipeline_params *params,
 	/* 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))
+		(params->n_ports_out == 0))
 		return NULL;
 
 	/* Memory allocation */
@@ -702,10 +712,13 @@ pipeline_passthrough_init(struct pipeline_params *params,
 
 	/* Add entries to tables */
 	for (i = 0; i < p->n_ports_in; i++) {
+		uint32_t port_out_id = (p_pt->params.lb_hash_enabled == 0) ?
+			(i / (p->n_ports_in / p->n_ports_out)) :
+			0;
+
 		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)]},
+			{.port_id = p->port_out_id[port_out_id]},
 		};
 
 		struct rte_pipeline_table_entry *default_entry_ptr;
@@ -780,25 +793,9 @@ pipeline_passthrough_timer(void *pipeline)
 	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_be_ops pipeline_passthrough_be_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_routing.c b/examples/ip_pipeline/pipeline/pipeline_routing.c
index c68e470..4d074c1 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing.c
+++ b/examples/ip_pipeline/pipeline/pipeline_routing.c
@@ -382,8 +382,6 @@ app_pipeline_routing_add_route(struct app_params *app,
 		p->n_routes++;
 	}
 
-	print_route(entry);
-
 	/* Message buffer free */
 	app_msg_free(app, rsp);
 	return 0;
@@ -676,8 +674,6 @@ app_pipeline_routing_add_arp_entry(struct app_params *app, uint32_t pipeline_id,
 		p->n_arp_entries++;
 	}
 
-	print_arp_entry(entry);
-
 	/* Message buffer free */
 	app_msg_free(app, rsp);
 	return 0;
@@ -1390,7 +1386,9 @@ static cmdline_parse_ctx_t pipeline_cmds[] = {
 
 static struct pipeline_fe_ops pipeline_routing_fe_ops = {
 	.f_init = pipeline_routing_init,
+	.f_post_init = NULL,
 	.f_free = app_pipeline_routing_free,
+	.f_track = app_pipeline_track_default,
 	.cmds = pipeline_cmds,
 };
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.c b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
index bc5bf7a..e7542a8 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
@@ -1419,27 +1419,6 @@ pipeline_routing_free(void *pipeline)
 }
 
 static int
-pipeline_routing_track(void *pipeline,
-	__rte_unused 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;
-
-	if (p->n_ports_in == 1) {
-		*port_out = 0;
-		return 0;
-	}
-
-	return -1;
-}
-
-static int
 pipeline_routing_timer(void *pipeline)
 {
 	struct pipeline *p = (struct pipeline *) pipeline;
@@ -1966,5 +1945,4 @@ struct pipeline_be_ops pipeline_routing_be_ops = {
 	.f_free = pipeline_routing_free,
 	.f_run = NULL,
 	.f_timer = pipeline_routing_timer,
-	.f_track = pipeline_routing_track,
 };
diff --git a/examples/ip_pipeline/pipeline_be.h b/examples/ip_pipeline/pipeline_be.h
index 8f858ed..5501ab7 100644
--- a/examples/ip_pipeline/pipeline_be.h
+++ b/examples/ip_pipeline/pipeline_be.h
@@ -203,6 +203,10 @@ pipeline_port_out_params_get_ops(struct pipeline_port_out_params  *p)
 #define PIPELINE_NAME_SIZE                       64
 #endif
 
+#ifndef PIPELINE_TYPE_SIZE
+#define PIPELINE_TYPE_SIZE                       64
+#endif
+
 #ifndef PIPELINE_MAX_PORT_IN
 #define PIPELINE_MAX_PORT_IN                     64
 #endif
@@ -229,6 +233,7 @@ pipeline_port_out_params_get_ops(struct pipeline_port_out_params  *p)
 
 struct pipeline_params {
 	char name[PIPELINE_NAME_SIZE];
+	char type[PIPELINE_TYPE_SIZE];
 
 	struct pipeline_port_in_params port_in[PIPELINE_MAX_PORT_IN];
 	struct pipeline_port_out_params port_out[PIPELINE_MAX_PORT_OUT];
@@ -261,16 +266,11 @@ typedef int (*pipeline_be_op_run)(void *pipeline);
 
 typedef int (*pipeline_be_op_timer)(void *pipeline);
 
-typedef int (*pipeline_be_op_track)(void *pipeline,
-	uint32_t port_in,
-	uint32_t *port_out);
-
 struct pipeline_be_ops {
 	pipeline_be_op_init f_init;
 	pipeline_be_op_free f_free;
 	pipeline_be_op_run f_run;
 	pipeline_be_op_timer f_timer;
-	pipeline_be_op_track f_track;
 };
 
 /* Pipeline specific config parse error messages */
-- 
2.5.5

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [dpdk-dev] [PATCH v2 3/6] ip_pipeline: assign nic ports mac address to the routing pipeline outports
  2016-06-01 14:00 ` [dpdk-dev] [PATCH v2 0/6] " Jasvinder Singh
  2016-06-01 14:00   ` [dpdk-dev] [PATCH v2 1/6] ip_pipeline: increase macros values Jasvinder Singh
  2016-06-01 14:00   ` [dpdk-dev] [PATCH v2 2/6] ip_pipeline: linking routing pipeline output ports with NIC ports Jasvinder Singh
@ 2016-06-01 14:01   ` Jasvinder Singh
  2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 4/6] ip_pipeline: automatic routes update with the change in nic ports state Jasvinder Singh
                     ` (3 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jasvinder Singh @ 2016-06-01 14:01 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

As a result of tracking, output ports of routing pipelines are linked with
physical nic ports(potentially through other pipeline instances). Thus, the
mac addresses of the NIC ports are assigned to routing pipeline out ports which
are connected to them and are further used in routing table entries instead
of hardcoded default values.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/pipeline/pipeline_routing.c   | 89 ++++++++++++++++++++--
 examples/ip_pipeline/pipeline/pipeline_routing.h   |  7 ++
 .../ip_pipeline/pipeline/pipeline_routing_be.c     | 61 ++++++++++-----
 .../ip_pipeline/pipeline/pipeline_routing_be.h     | 15 ++++
 4 files changed, 149 insertions(+), 23 deletions(-)

diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.c b/examples/ip_pipeline/pipeline/pipeline_routing.c
index 4d074c1..80f029d 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing.c
+++ b/examples/ip_pipeline/pipeline/pipeline_routing.c
@@ -58,8 +58,11 @@ struct app_pipeline_routing_arp_entry {
 
 struct pipeline_routing {
 	/* Parameters */
+	struct app_params *app;
+	uint32_t pipeline_id;
 	uint32_t n_ports_in;
 	uint32_t n_ports_out;
+	struct pipeline_routing_params rp;
 
 	/* Routes */
 	TAILQ_HEAD(, app_pipeline_routing_route) routes;
@@ -79,11 +82,13 @@ struct pipeline_routing {
 };
 
 static void *
-pipeline_routing_init(struct pipeline_params *params,
-	__rte_unused void *arg)
+app_pipeline_routing_init(struct pipeline_params *params,
+	void *arg)
 {
+	struct app_params *app = (struct app_params *) arg;
 	struct pipeline_routing *p;
-	uint32_t size;
+	uint32_t pipeline_id, size;
+	int status;
 
 	/* Check input arguments */
 	if ((params == NULL) ||
@@ -91,6 +96,8 @@ pipeline_routing_init(struct pipeline_params *params,
 		(params->n_ports_out == 0))
 		return NULL;
 
+	APP_PARAM_GET_ID(params, "PIPELINE", pipeline_id);
+
 	/* Memory allocation */
 	size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_routing));
 	p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
@@ -98,9 +105,16 @@ pipeline_routing_init(struct pipeline_params *params,
 		return NULL;
 
 	/* Initialization */
+	p->app = app;
+	p->pipeline_id = pipeline_id;
 	p->n_ports_in = params->n_ports_in;
 	p->n_ports_out = params->n_ports_out;
 
+	status = pipeline_routing_parse_args(&p->rp, params);
+	if (status) {
+		rte_free(p);
+		return NULL;
+	}
 	TAILQ_INIT(&p->routes);
 	p->n_routes = 0;
 
@@ -111,6 +125,18 @@ pipeline_routing_init(struct pipeline_params *params,
 }
 
 static int
+app_pipeline_routing_post_init(void *pipeline)
+{
+	struct pipeline_routing *p = pipeline;
+
+	/* Check input arguments */
+	if (p == NULL)
+		return -1;
+
+	return app_pipeline_routing_set_macaddr(p->app, p->pipeline_id);
+}
+
+static int
 app_pipeline_routing_free(void *pipeline)
 {
 	struct pipeline_routing *p = pipeline;
@@ -848,6 +874,59 @@ app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
 	return 0;
 }
 
+int
+app_pipeline_routing_set_macaddr(struct app_params *app,
+	uint32_t pipeline_id)
+{
+	struct app_pipeline_params *p;
+	struct pipeline_routing_set_macaddr_msg_req *req;
+	struct pipeline_routing_set_macaddr_msg_rsp *rsp;
+	uint32_t port_id;
+
+	/* Check input arguments */
+	if (app == NULL)
+		return -EINVAL;
+
+	APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
+	if (p == NULL)
+		return -EINVAL;
+
+	/* Allocate and write request */
+	req = app_msg_alloc(app);
+	if (req == NULL)
+		return -ENOMEM;
+
+	req->type = PIPELINE_MSG_REQ_CUSTOM;
+	req->subtype = PIPELINE_ROUTING_MSG_REQ_SET_MACADDR;
+
+	memset(req->macaddr, 0, sizeof(req->macaddr));
+	for (port_id = 0; port_id < p->n_pktq_out; port_id++) {
+		struct app_link_params *link;
+
+		link = app_pipeline_track_pktq_out_to_link(app,
+			pipeline_id,
+			port_id);
+		if (link)
+			req->macaddr[port_id] = link->mac_addr;
+	}
+
+	/* Send request and wait for response */
+	rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
+	if (rsp == NULL)
+		return -ETIMEDOUT;
+
+	/* Read response and write entry */
+	if (rsp->status) {
+		app_msg_free(app, rsp);
+		return rsp->status;
+	}
+
+	/* Free response */
+	app_msg_free(app, rsp);
+
+	return 0;
+}
+
 /*
  * route
  *
@@ -1385,8 +1464,8 @@ static cmdline_parse_ctx_t pipeline_cmds[] = {
 };
 
 static struct pipeline_fe_ops pipeline_routing_fe_ops = {
-	.f_init = pipeline_routing_init,
-	.f_post_init = NULL,
+	.f_init = app_pipeline_routing_init,
+	.f_post_init = app_pipeline_routing_post_init,
 	.f_free = app_pipeline_routing_free,
 	.f_track = app_pipeline_track_default,
 	.cmds = pipeline_cmds,
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.h b/examples/ip_pipeline/pipeline/pipeline_routing.h
index fa41642..0197449 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing.h
+++ b/examples/ip_pipeline/pipeline/pipeline_routing.h
@@ -86,6 +86,13 @@ app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
 	uint32_t pipeline_id);
 
 /*
+ * SETTINGS
+ */
+int
+app_pipeline_routing_set_macaddr(struct app_params *app,
+	uint32_t pipeline_id);
+
+/*
  * Pipeline type
  */
 extern struct pipeline_type pipeline_routing;
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.c b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
index e7542a8..a448157 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
@@ -65,7 +65,9 @@
 	((((uint64_t) (pipe)) & 0xFFFFFFFF) << 32))
 
 
-#define MAC_SRC_DEFAULT 0x112233445566ULL
+/* Network Byte Order (NBO) */
+#define SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr, ethertype)	\
+	(((uint64_t) macaddr) | (((uint64_t) rte_cpu_to_be_16(ethertype)) << 48))
 
 #ifndef PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s
 #define PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s 256
@@ -75,6 +77,7 @@ struct pipeline_routing {
 	struct pipeline p;
 	struct pipeline_routing_params params;
 	pipeline_msg_req_handler custom_handlers[PIPELINE_ROUTING_MSG_REQS];
+	uint64_t macaddr[PIPELINE_MAX_PORT_OUT];
 } __rte_cache_aligned;
 
 /*
@@ -132,6 +135,10 @@ static void *
 pipeline_routing_msg_req_arp_del_default_handler(struct pipeline *p,
 	void *msg);
 
+static void *
+pipeline_routing_msg_req_set_macaddr_handler(struct pipeline *p,
+	void *msg);
+
 static pipeline_msg_req_handler custom_handlers[] = {
 	[PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD] =
 		pipeline_routing_msg_req_route_add_handler,
@@ -149,6 +156,8 @@ static pipeline_msg_req_handler custom_handlers[] = {
 		pipeline_routing_msg_req_arp_add_default_handler,
 	[PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT] =
 		pipeline_routing_msg_req_arp_del_default_handler,
+	[PIPELINE_ROUTING_MSG_REQ_SET_MACADDR] =
+		pipeline_routing_msg_req_set_macaddr_handler,
 };
 
 /*
@@ -1513,7 +1522,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether - ARP off */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) &&
 		(p_rt->params.n_arp_entries == 0)) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t macaddr_dst;
 		uint64_t ethertype = ETHER_TYPE_IPv4;
 
@@ -1521,7 +1530,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 		macaddr_dst = rte_bswap64(macaddr_dst << 16);
 
 		entry_arp0.slab[0] =
-			rte_bswap64((macaddr_src << 16) | ethertype);
+			SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype);
 		entry_arp0.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
 
 		entry_arp0.slab[1] = rte_bswap64(macaddr_dst);
@@ -1535,11 +1544,11 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether - ARP on */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) &&
 		p_rt->params.n_arp_entries) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t ethertype = ETHER_TYPE_IPv4;
 
-		entry_arp1.slab[0] = rte_bswap64((macaddr_src << 16) |
-			ethertype);
+		entry_arp1.slab[0] =
+			SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype);
 		entry_arp1.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
 
 		entry_arp1.data_offset = entry_arp1.slab_offset[0] - 6
@@ -1550,7 +1559,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether QinQ - ARP off */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
 		(p_rt->params.n_arp_entries == 0)) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t macaddr_dst;
 		uint64_t ethertype_ipv4 = ETHER_TYPE_IPv4;
 		uint64_t ethertype_vlan = 0x8100;
@@ -1567,8 +1576,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 			ethertype_ipv4);
 		entry_arp0.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
 
-		entry_arp0.slab[1] = rte_bswap64((macaddr_src << 16) |
-			ethertype_qinq);
+		entry_arp0.slab[1] =
+			SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_qinq);
 		entry_arp0.slab_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
 
 		entry_arp0.slab[2] = rte_bswap64(macaddr_dst);
@@ -1582,7 +1591,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether QinQ - ARP on */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
 		p_rt->params.n_arp_entries) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t ethertype_ipv4 = ETHER_TYPE_IPv4;
 		uint64_t ethertype_vlan = 0x8100;
 		uint64_t ethertype_qinq = 0x9100;
@@ -1595,8 +1604,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 			ethertype_ipv4);
 		entry_arp1.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
 
-		entry_arp1.slab[1] = rte_bswap64((macaddr_src << 16) |
-			ethertype_qinq);
+		entry_arp1.slab[1] =
+			SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_qinq);
 		entry_arp1.slab_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
 
 		entry_arp1.data_offset = entry_arp1.slab_offset[1] - 6
@@ -1607,7 +1616,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether MPLS - ARP off */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
 		(p_rt->params.n_arp_entries == 0)) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t macaddr_dst;
 		uint64_t ethertype_mpls = 0x8847;
 
@@ -1676,8 +1685,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 			return rsp;
 		}
 
-		entry_arp0.slab[2] = rte_bswap64((macaddr_src << 16) |
-			ethertype_mpls);
+		entry_arp0.slab[2] =
+			SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_mpls);
 		entry_arp0.slab_offset[2] = p_rt->params.ip_hdr_offset -
 			(n_labels * 4 + 8);
 
@@ -1693,7 +1702,7 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 	/* Ether MPLS - ARP on */
 	if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
 		p_rt->params.n_arp_entries) {
-		uint64_t macaddr_src = MAC_SRC_DEFAULT;
+		uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
 		uint64_t ethertype_mpls = 0x8847;
 
 		uint64_t label0 = req->data.l2.mpls.labels[0];
@@ -1758,8 +1767,8 @@ pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
 			return rsp;
 		}
 
-		entry_arp1.slab[2] = rte_bswap64((macaddr_src << 16) |
-			ethertype_mpls);
+		entry_arp1.slab[2] =
+			SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_mpls);
 		entry_arp1.slab_offset[2] = p_rt->params.ip_hdr_offset -
 			(n_labels * 4 + 8);
 
@@ -1940,6 +1949,22 @@ pipeline_routing_msg_req_arp_del_default_handler(struct pipeline *p, void *msg)
 	return rsp;
 }
 
+void *
+pipeline_routing_msg_req_set_macaddr_handler(struct pipeline *p, void *msg)
+{
+	struct pipeline_routing *p_rt = (struct pipeline_routing *) p;
+	struct pipeline_routing_set_macaddr_msg_req *req = msg;
+	struct pipeline_routing_set_macaddr_msg_rsp *rsp = msg;
+	uint32_t port_id;
+
+	for (port_id = 0; port_id < p->n_ports_out; port_id++)
+		p_rt->macaddr[port_id] = req->macaddr[port_id];
+
+	rsp->status = 0;
+
+	return rsp;
+}
+
 struct pipeline_be_ops pipeline_routing_be_ops = {
 	.f_init = pipeline_routing_init,
 	.f_free = pipeline_routing_free,
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.h b/examples/ip_pipeline/pipeline/pipeline_routing_be.h
index ec767b2..822995b 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing_be.h
+++ b/examples/ip_pipeline/pipeline/pipeline_routing_be.h
@@ -160,6 +160,7 @@ enum pipeline_routing_msg_req_type {
 	PIPELINE_ROUTING_MSG_REQ_ARP_DEL,
 	PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT,
 	PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT,
+	PIPELINE_ROUTING_MSG_REQ_SET_MACADDR,
 	PIPELINE_ROUTING_MSG_REQS
 };
 
@@ -291,6 +292,20 @@ struct pipeline_routing_arp_delete_default_msg_rsp {
 	int status;
 };
 
+/*
+ * MSG SET MACADDR
+ */
+struct pipeline_routing_set_macaddr_msg_req {
+	enum pipeline_msg_req_type type;
+	enum pipeline_routing_msg_req_type subtype;
+
+	uint64_t macaddr[PIPELINE_MAX_PORT_OUT];
+};
+
+struct pipeline_routing_set_macaddr_msg_rsp {
+	int status;
+};
+
 extern struct pipeline_be_ops pipeline_routing_be_ops;
 
 #endif
-- 
2.5.5

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [dpdk-dev] [PATCH v2 4/6] ip_pipeline: automatic routes update with the change in nic ports state
  2016-06-01 14:00 ` [dpdk-dev] [PATCH v2 0/6] " Jasvinder Singh
                     ` (2 preceding siblings ...)
  2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 3/6] ip_pipeline: assign nic ports mac address to the routing pipeline outports Jasvinder Singh
@ 2016-06-01 14:01   ` Jasvinder Singh
  2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 5/6] ip_pipeline: sample config file on adding various network layer components Jasvinder Singh
                     ` (2 subsequent siblings)
  6 siblings, 0 replies; 9+ messages in thread
From: Jasvinder Singh @ 2016-06-01 14:01 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

The routing pipeline registers a callback function with the nic ports and
this function is invoked for updating the routing entries (corrsponding to
local host and directly attached network) tables whenever the nic ports
change their states (up/down).

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/app.h                         |  21 ++-
 examples/ip_pipeline/pipeline/pipeline_common_fe.c |  52 ++++++++
 examples/ip_pipeline/pipeline/pipeline_common_fe.h |   7 +
 examples/ip_pipeline/pipeline/pipeline_routing.c   | 146 ++++++++++++++++++++-
 .../ip_pipeline/pipeline/pipeline_routing_be.c     |  19 +++
 .../ip_pipeline/pipeline/pipeline_routing_be.h     |   1 +
 6 files changed, 241 insertions(+), 5 deletions(-)

diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index 93e96d0..848244a 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -241,6 +241,22 @@ struct app_pipeline_params {
 	uint32_t n_args;
 };
 
+struct app_params;
+
+typedef void (*app_link_op)(struct app_params *app,
+	uint32_t link_id,
+	uint32_t up,
+	void *arg);
+
+#ifndef APP_MAX_PIPELINES
+#define APP_MAX_PIPELINES                        64
+#endif
+
+struct app_link_data {
+	app_link_op f_link[APP_MAX_PIPELINES];
+	void *arg[APP_MAX_PIPELINES];
+};
+
 struct app_pipeline_data {
 	void *be;
 	void *fe;
@@ -416,10 +432,6 @@ struct app_eal_params {
 #define APP_MAX_MSGQ                             256
 #endif
 
-#ifndef APP_MAX_PIPELINES
-#define APP_MAX_PIPELINES                        64
-#endif
-
 #ifndef APP_EAL_ARGC
 #define APP_EAL_ARGC                             64
 #endif
@@ -480,6 +492,7 @@ struct app_params {
 	struct cpu_core_map *core_map;
 	uint64_t core_mask;
 	struct rte_mempool *mempool[APP_MAX_MEMPOOLS];
+	struct app_link_data link_data[APP_MAX_LINKS];
 	struct rte_ring *swq[APP_MAX_PKTQ_SWQ];
 	struct rte_sched_port *tm[APP_MAX_PKTQ_TM];
 	struct rte_ring *msgq[APP_MAX_MSGQ];
diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.c b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
index fa0a482..70c57e4 100644
--- a/examples/ip_pipeline/pipeline/pipeline_common_fe.c
+++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
@@ -419,6 +419,40 @@ app_pipeline_port_in_disable(struct app_params *app,
 }
 
 int
+app_link_set_op(struct app_params *app,
+	uint32_t link_id,
+	uint32_t pipeline_id,
+	app_link_op op,
+	void *arg)
+{
+	struct app_pipeline_params *pp;
+	struct app_link_params *lp;
+	struct app_link_data *ld;
+	uint32_t ppos, lpos;
+
+	/* Check input arguments */
+	if ((app == NULL) ||
+		(op == NULL))
+		return -1;
+
+	APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, lp);
+	if (lp == NULL)
+		return -1;
+	lpos = lp - app->link_params;
+	ld = &app->link_data[lpos];
+
+	APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, pp);
+	if (pp == NULL)
+		return -1;
+	ppos = pp - app->pipeline_params;
+
+	ld->f_link[ppos] = op;
+	ld->arg[ppos] = arg;
+
+	return 0;
+}
+
+int
 app_link_config(struct app_params *app,
 	uint32_t link_id,
 	uint32_t ip,
@@ -489,6 +523,8 @@ app_link_up(struct app_params *app,
 	uint32_t link_id)
 {
 	struct app_link_params *p;
+	struct app_link_data *d;
+	int i;
 
 	/* Check input arguments */
 	if (app == NULL)
@@ -501,6 +537,8 @@ app_link_up(struct app_params *app,
 		return -1;
 	}
 
+	d = &app->link_data[p - app->link_params];
+
 	/* Check link state */
 	if (p->state) {
 		APP_LOG(app, HIGH, "%s is already UP", p->name);
@@ -515,6 +553,11 @@ app_link_up(struct app_params *app,
 
 	app_link_up_internal(app, p);
 
+	/* Callbacks */
+	for (i = 0; i < APP_MAX_PIPELINES; i++)
+		if (d->f_link[i])
+			d->f_link[i](app, link_id, 1, d->arg[i]);
+
 	return 0;
 }
 
@@ -523,6 +566,8 @@ app_link_down(struct app_params *app,
 	uint32_t link_id)
 {
 	struct app_link_params *p;
+	struct app_link_data *d;
+	uint32_t i;
 
 	/* Check input arguments */
 	if (app == NULL)
@@ -535,6 +580,8 @@ app_link_down(struct app_params *app,
 		return -1;
 	}
 
+	d = &app->link_data[p - app->link_params];
+
 	/* Check link state */
 	if (p->state == 0) {
 		APP_LOG(app, HIGH, "%s is already DOWN", p->name);
@@ -543,6 +590,11 @@ app_link_down(struct app_params *app,
 
 	app_link_down_internal(app, p);
 
+	/* Callbacks */
+	for (i = 0; i < APP_MAX_PIPELINES; i++)
+		if (d->f_link[i])
+			d->f_link[i](app, link_id, 0, d->arg[i]);
+
 	return 0;
 }
 
diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.h b/examples/ip_pipeline/pipeline/pipeline_common_fe.h
index 8abee4a..ce0bf13 100644
--- a/examples/ip_pipeline/pipeline/pipeline_common_fe.h
+++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.h
@@ -225,6 +225,13 @@ app_pipeline_port_in_disable(struct app_params *app,
 	uint32_t port_id);
 
 int
+app_link_set_op(struct app_params *app,
+	uint32_t link_id,
+	uint32_t pipeline_id,
+	app_link_op op,
+	void *arg);
+
+int
 app_link_config(struct app_params *app,
 	uint32_t link_id,
 	uint32_t ip,
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.c b/examples/ip_pipeline/pipeline/pipeline_routing.c
index 80f029d..3aadbf9 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing.c
+++ b/examples/ip_pipeline/pipeline/pipeline_routing.c
@@ -64,6 +64,9 @@ struct pipeline_routing {
 	uint32_t n_ports_out;
 	struct pipeline_routing_params rp;
 
+	/* Links */
+	uint32_t link_id[PIPELINE_MAX_PORT_OUT];
+
 	/* Routes */
 	TAILQ_HEAD(, app_pipeline_routing_route) routes;
 	uint32_t n_routes;
@@ -81,6 +84,143 @@ struct pipeline_routing {
 	void *default_arp_entry_ptr;
 };
 
+static int
+app_pipeline_routing_find_link(struct pipeline_routing *p,
+	uint32_t link_id,
+	uint32_t *port_id)
+{
+	uint32_t i;
+
+	for (i = 0; i < p->n_ports_out; i++)
+		if (p->link_id[i] == link_id) {
+			*port_id = i;
+			return 0;
+		}
+
+	return -1;
+}
+
+static void
+app_pipeline_routing_link_op(__rte_unused struct app_params *app,
+	uint32_t link_id,
+	uint32_t up,
+	void *arg)
+{
+	struct pipeline_routing_route_key key0, key1;
+	struct pipeline_routing *p = arg;
+	struct app_link_params *lp;
+	uint32_t port_id, netmask;
+	int status;
+
+	if (app == NULL)
+		return;
+
+	APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, lp);
+	if (lp == NULL)
+		return;
+
+	status = app_pipeline_routing_find_link(p,
+		link_id,
+		&port_id);
+	if (status)
+		return;
+
+	netmask = (~0U) << (32 - lp->depth);
+
+	/* Local network (directly attached network) */
+	key0.type = PIPELINE_ROUTING_ROUTE_IPV4;
+	key0.key.ipv4.ip = lp->ip & netmask;
+	key0.key.ipv4.depth = lp->depth;
+
+	/* Local termination */
+	key1.type = PIPELINE_ROUTING_ROUTE_IPV4;
+	key1.key.ipv4.ip = lp->ip;
+	key1.key.ipv4.depth = 32;
+
+	if (up) {
+		struct pipeline_routing_route_data data0, data1;
+
+		/* Local network (directly attached network) */
+		memset(&data0, 0, sizeof(data0));
+		data0.flags = PIPELINE_ROUTING_ROUTE_LOCAL |
+			PIPELINE_ROUTING_ROUTE_ARP;
+		if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ)
+			data0.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
+		if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) {
+			data0.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
+			data0.l2.mpls.n_labels = 1;
+		}
+		data0.port_id = port_id;
+
+		if (p->rp.n_arp_entries)
+			app_pipeline_routing_add_route(app,
+				p->pipeline_id,
+				&key0,
+				&data0);
+
+		/* Local termination */
+		memset(&data1, 0, sizeof(data1));
+		data1.flags = PIPELINE_ROUTING_ROUTE_LOCAL |
+			PIPELINE_ROUTING_ROUTE_ARP;
+		if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ)
+			data1.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
+		if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) {
+			data1.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
+			data1.l2.mpls.n_labels = 1;
+		}
+		data1.port_id = p->rp.port_local_dest;
+
+		app_pipeline_routing_add_route(app,
+			p->pipeline_id,
+			&key1,
+			&data1);
+	} else {
+		/* Local network (directly attached network) */
+		if (p->rp.n_arp_entries)
+			app_pipeline_routing_delete_route(app,
+				p->pipeline_id,
+				&key0);
+
+		/* Local termination */
+		app_pipeline_routing_delete_route(app,
+			p->pipeline_id,
+			&key1);
+	}
+}
+
+static int
+app_pipeline_routing_set_link_op(
+	struct app_params *app,
+	struct pipeline_routing *p)
+{
+	uint32_t port_id;
+
+	for (port_id = 0; port_id < p->n_ports_out; port_id++) {
+		struct app_link_params *link;
+		uint32_t link_id;
+		int status;
+
+		link = app_pipeline_track_pktq_out_to_link(app,
+			p->pipeline_id,
+			port_id);
+		if (link == NULL)
+			continue;
+
+		link_id = link - app->link_params;
+		p->link_id[port_id] = link_id;
+
+		status = app_link_set_op(app,
+			link_id,
+			p->pipeline_id,
+			app_pipeline_routing_link_op,
+			(void *) p);
+		if (status)
+			return status;
+	}
+
+	return 0;
+}
+
 static void *
 app_pipeline_routing_init(struct pipeline_params *params,
 	void *arg)
@@ -121,6 +261,8 @@ app_pipeline_routing_init(struct pipeline_params *params,
 	TAILQ_INIT(&p->arp_entries);
 	p->n_arp_entries = 0;
 
+	app_pipeline_routing_set_link_op(app, p);
+
 	return p;
 }
 
@@ -223,7 +365,9 @@ print_route(const struct app_pipeline_routing_route *route)
 			key->depth,
 			route->data.port_id);
 
-		if (route->data.flags & PIPELINE_ROUTING_ROUTE_ARP)
+		if (route->data.flags & PIPELINE_ROUTING_ROUTE_LOCAL)
+			printf(", Local");
+		else if (route->data.flags & PIPELINE_ROUTING_ROUTE_ARP)
 			printf(
 				", Next Hop IP = %" PRIu32 ".%" PRIu32
 				".%" PRIu32 ".%" PRIu32,
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.c b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
index a448157..21ac788 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
@@ -930,6 +930,7 @@ pipeline_routing_parse_args(struct pipeline_routing_params *p,
 	struct pipeline_params *params)
 {
 	uint32_t n_routes_present = 0;
+	uint32_t port_local_dest_present = 0;
 	uint32_t encap_present = 0;
 	uint32_t qinq_sched_present = 0;
 	uint32_t mpls_color_mark_present = 0;
@@ -942,6 +943,7 @@ pipeline_routing_parse_args(struct pipeline_routing_params *p,
 
 	/* default values */
 	p->n_routes = PIPELINE_ROUTING_N_ROUTES_DEFAULT;
+	p->port_local_dest = params->n_ports_out - 1;
 	p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET;
 	p->qinq_sched = 0;
 	p->mpls_color_mark = 0;
@@ -971,6 +973,23 @@ pipeline_routing_parse_args(struct pipeline_routing_params *p,
 
 			continue;
 		}
+		/* port_local_dest */
+		if (strcmp(arg_name, "port_local_dest") == 0) {
+			int status;
+
+			PIPELINE_PARSE_ERR_DUPLICATE(
+				port_local_dest_present == 0, params->name,
+				arg_name);
+			port_local_dest_present = 1;
+
+			status = parser_read_uint32(&p->port_local_dest,
+				arg_value);
+			PIPELINE_PARSE_ERR_INV_VAL(((status == 0) &&
+				(p->port_local_dest < params->n_ports_out)),
+				params->name, arg_name, arg_value);
+
+			continue;
+		}
 
 		/* encap */
 		if (strcmp(arg_name, "encap") == 0) {
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.h b/examples/ip_pipeline/pipeline/pipeline_routing_be.h
index 822995b..1276342 100644
--- a/examples/ip_pipeline/pipeline/pipeline_routing_be.h
+++ b/examples/ip_pipeline/pipeline/pipeline_routing_be.h
@@ -54,6 +54,7 @@ enum pipeline_routing_encap {
 struct pipeline_routing_params {
 	/* routing */
 	uint32_t n_routes;
+	uint32_t port_local_dest;
 
 	/* routing packet encapsulation */
 	enum pipeline_routing_encap encap;
-- 
2.5.5

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [dpdk-dev] [PATCH v2 5/6] ip_pipeline: sample config file on adding various network layer components
  2016-06-01 14:00 ` [dpdk-dev] [PATCH v2 0/6] " Jasvinder Singh
                     ` (3 preceding siblings ...)
  2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 4/6] ip_pipeline: automatic routes update with the change in nic ports state Jasvinder Singh
@ 2016-06-01 14:01   ` Jasvinder Singh
  2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 6/6] ip_pipeline: update release notes Jasvinder Singh
  2016-06-08 19:43   ` [dpdk-dev] [PATCH v2 0/6] ip_pipeline: routing pipeline improvements Thomas Monjalon
  6 siblings, 0 replies; 9+ messages in thread
From: Jasvinder Singh @ 2016-06-01 14:01 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

The sample configuration file demonstrates that network layer components such
as TCP, UDP, ICMP etc, can be easily integrated into ip pipeline infrastructure.
Similarily, various other functionalities such as IP Reassembly for input
traffic with local destination and IP Fragmentation to enforce the MTU for
the routed output traffic, can be added using SWQs enabled with
reassembly and fragmentation features.

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 examples/ip_pipeline/config/network_layers.cfg | 223 +++++++++++++++++++++++++
 examples/ip_pipeline/config/network_layers.sh  |  79 +++++++++
 2 files changed, 302 insertions(+)
 create mode 100644 examples/ip_pipeline/config/network_layers.cfg
 create mode 100644 examples/ip_pipeline/config/network_layers.sh

diff --git a/examples/ip_pipeline/config/network_layers.cfg b/examples/ip_pipeline/config/network_layers.cfg
new file mode 100644
index 0000000..8054d9f
--- /dev/null
+++ b/examples/ip_pipeline/config/network_layers.cfg
@@ -0,0 +1,223 @@
+;   BSD LICENSE
+;
+;   Copyright(c) 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.
+
+; The diagram below shows how additional protocol components can be plugged into
+; the IP layer implemented by the ip_pipeline application. Pick your favorite
+; open source components for dynamic ARP, ICMP, UDP or TCP termination, etc and
+; connect them through SWQs to the IP infrastructure.
+;
+; The input packets with local destination are sent to the UDP/TCP applications
+; while the input packets with remote destination are routed back to the
+; network. Additional features can easily be added to this setup:
+;  * IP Reassembly: add SWQs with IP reassembly enabled (typically required for
+;    the input traffic with local destination);
+;  * IP Fragmentation: add SWQs with IP fragmentation enabled (typically
+;    required to enforce the MTU for the routed output traffic);
+;  * Traffic Metering: add Flow Action pipeline instances (e.g. for metering the
+;    TCP connections or ICMP input traffic);
+;  * Traffic Management: add TMs for the required output LINKs;
+;  * Protocol encapsulations (QinQ, MPLS) for the output packets: part of the
+;    routing pipeline configuration.
+;
+;                     _________                       _________
+;                    |         |                     |         |
+;                    |   UDP   |                     |   TCP   |
+;                    |   App   |                     |   App   |
+;                    |_________|                     |_________|
+;                       ^   |                           ^   |
+;                     __|___V__                       __|___V__
+;                    |         |  SWQ0 (UDP TX)      |         |  SWQ1 (TCP TX)
+;                    |   UDP   |-------+             |   TCP   |------------+
+;                    |         |       |             |         |            |
+;                    |_________|       |             |_________|            |
+;                         ^            |                  ^                 |
+;                         | SWQ2       |                  | SWQ3            |
+;                         | (UDP RX)   |                  | (TCP RX)        |
+;                     ____|____        |              ____|____             |
+;                    |         |       |             |         |            |
+; RXQ<0..3>.1 ------>|Firewall +--->|  |     +------>|  Flow   +--->|       |
+; (UDP local dest)   |  (P2)   | SINK0 |     |       |  (P3)   |  SINK1     |
+;                    |_________| (Deny)|     |       |_________|  (RST)     |
+; RXQ<0..3>.2 -------------------------|-----+                              |
+; (TCP local dest)                     |                                    |
+;                                      |     +------------------------------+
+;                                      |     |
+;                                     _V_____V_
+;                                    |         |
+;                                    | Routing |                   TXQ<0..3>.0
+; RXQ<0..3>.0 ---------------------->|  & ARP  +----------------------------->
+; (IP remote dest)                   |  (P1)   |
+;                                    |_________|
+;                                      |  ^  |
+;                   SWQ4 +-------------+  |  |  SWQ5 (ARP miss)
+;           (Route miss) |                |  +------------+
+;                        |  +-------------+               |
+;                     ___V__|__   SWQ6                ____V____
+;                    |         |  (ICMP TX)          |         |   TXQ<0..3>.1
+; RXQ<0..3>.3 ------>|  ICMP   |             +------>| Dyn ARP +------------->
+; (IP local dest)    |         |             |       |         |
+;                    |_________|             |       |_________|
+; RXQ<0..3>.4 -------------------------------+
+; (ARP)
+;
+; This configuration file implements the diagram presented below, where the
+; dynamic ARP, ICMP, UDP and TCP components have been stubbed out and replaced
+; with loop-back and packet drop devices.
+;
+;                     _________                       _________
+;                    |         |  SWQ0 (UDP TX)      |         |  SWQ1 (TCP TX)
+;                    |Loobpack |-------+             |Loopback |------------+
+;                    |  (P4)   |       |             |  (P5)   |            |
+;                    |_________|       |             |_________|            |
+;                         ^            |                  ^                 |
+;                         | SWQ2       |                  | SWQ3            |
+;                         | (UDP RX)   |                  | (TCP RX)        |
+;                     ____|____        |              ____|____             |
+;                    |         |       |             |         |            |
+; RXQ<0..3>.1 ------>|Firewall +--->|  |     +------>|  Flow   +--->|       |
+; (UDP local dest)   |  (P2)   | SINK0 |     |       |  (P3)   |  SINK1     |
+;                    |_________| (Deny)|     |       |_________|  (RST)     |
+; RXQ<0..3>.2 -------------------------|-----+                              |
+; (TCP local dest)                     |                                    |
+;                                      |     +------------------------------+
+;                                      |     |
+;                                     _V_____V_
+;                                    |         |
+;                                    | Routing |                   TXQ<0..3>.0
+; RXQ<0..3>.0 ---------------------->|  & ARP  +----------------------------->
+; (IP remote dest)                   |  (P1)   |
+;                                    |_________|
+;                                      |     |
+;                           SINK2 |<---+     +--->| SINK3
+;                           (Route miss)            (ARP miss)
+;
+;                     _________                            _________
+;                    |         |                          |         |
+; RXQ<0..3>.3 ------>|  Drop   +--->| SINK<4..7>  +------>|  Drop   +--->| SINK<8..11>
+; (IP local dest)    |  (P6)   | (IP local dest)  |       |  (P7)   |     (ARP)
+;                    |_________|                  |       |_________|
+; RXQ<0..3>.4 ------------------------------------+
+; (ARP)
+;
+;
+; Input packet: Ethernet/IPv4 or Ethernet/ARP
+; Output packet: Ethernet/IPv4 or Ethernet/ARP
+;
+; Packet buffer layout (for input IPv4 packets):
+; #	Field Name			Offset (Bytes)	Size (Bytes)
+; 0	Mbuf				0				128
+; 1	Headroom			128				128
+; 2	Ethernet header		256				14
+; 3	IPv4 header			270				20
+; 4	ICMP/UDP/TCP header	290				8/8/20
+
+[EAL]
+log_level = 0
+
+[LINK0]
+udp_local_q = 1
+tcp_local_q = 2
+ip_local_q = 3
+arp_q = 4
+
+[LINK1]
+udp_local_q = 1
+tcp_local_q = 2
+ip_local_q = 3
+arp_q = 4
+
+[LINK2]
+udp_local_q = 1
+tcp_local_q = 2
+ip_local_q = 3
+arp_q = 4
+
+[LINK3]
+udp_local_q = 1
+tcp_local_q = 2
+ip_local_q = 3
+arp_q = 4
+
+[PIPELINE0]
+type = MASTER
+core = 0
+
+[PIPELINE1]
+type = ROUTING
+core = 1
+pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0 SWQ0 SWQ1
+pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK2 SINK3
+port_local_dest = 4 ; SINK2 (Drop)
+n_arp_entries = 1000
+ip_hdr_offset = 270
+arp_key_offset = 128
+
+[PIPELINE2]
+type = FIREWALL
+core = 1
+pktq_in = RXQ0.1 RXQ1.1 RXQ2.1 RXQ3.1
+pktq_out = SWQ2 SINK0
+n_rules = 4096
+
+[PIPELINE3]
+type = FLOW_CLASSIFICATION
+core = 1
+pktq_in = RXQ0.2 RXQ1.2 RXQ2.2 RXQ3.2
+pktq_out = SWQ3 SINK1
+n_flows = 65536
+key_size = 16                               ; IPv4 5-tuple key size
+key_offset = 278                            ; IPv4 5-tuple key offset
+key_mask = 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF ; IPv4 5-tuple key mask
+flowid_offset = 128 ; Flow ID effectively acts as TCP socket ID
+
+[PIPELINE4]
+type = PASS-THROUGH ; Loop-back (UDP place-holder)
+core = 1
+pktq_in = SWQ2
+pktq_out = SWQ0
+
+[PIPELINE5]
+type = PASS-THROUGH ; Loop-back (TCP place-holder)
+core = 1
+pktq_in = SWQ3
+pktq_out = SWQ1
+
+[PIPELINE6]
+type = PASS-THROUGH ; Drop (ICMP place-holder)
+core = 1
+pktq_in = RXQ0.3 RXQ1.3 RXQ2.3 RXQ3.3
+pktq_out = SINK4 SINK5 SINK6 SINK7
+
+[PIPELINE7]
+type = PASS-THROUGH ; Drop (Dynamic ARP place-holder)
+core = 1
+pktq_in = RXQ0.4 RXQ1.4 RXQ2.4 RXQ3.4
+pktq_out = SINK8 SINK9 SINK10 SINK11
diff --git a/examples/ip_pipeline/config/network_layers.sh b/examples/ip_pipeline/config/network_layers.sh
new file mode 100644
index 0000000..3b86beb
--- /dev/null
+++ b/examples/ip_pipeline/config/network_layers.sh
@@ -0,0 +1,79 @@
+#
+# run ./config/network_layers.sh
+#
+
+################################################################################
+# Link configuration
+################################################################################
+# Routes added implicitly when links are brought UP:
+# IP Prefix = 10.0.0.1/16 => (Port 0, Local)
+# IP Prefix = 10.0.0.1/32 => (Port 4, Local)
+# IP Prefix = 10.1.0.1/16 => (Port 1, Local)
+# IP Prefix = 10.1.0.1/32 => (Port 4, Local)
+# IP Prefix = 10.2.0.1/16 => (Port 2, Local)
+# IP Prefix = 10.2.0.1/32 => (Port 4, Local)
+# IP Prefix = 10.3.0.1/16 => (Port 3, Local)
+# IP Prefix = 10.3.0.1/32 => (Port 4, Local)
+link 0 down
+link 1 down
+link 2 down
+link 3 down
+link 0 config 10.0.0.1 16
+link 1 config 10.1.0.1 16
+link 2 config 10.2.0.1 16
+link 3 config 10.3.0.1 16
+link 0 up
+link 1 up
+link 2 up
+link 3 up
+#link ls
+
+################################################################################
+# Static ARP
+################################################################################
+p 1 arp add default 5 #SINK3
+p 1 arp add 0 10.0.0.2 a0:b0:c0:d0:e0:f0
+p 1 arp add 1 10.1.0.2 a1:b1:c1:d1:e1:f1
+p 1 arp add 2 10.2.0.2 a2:b2:c2:d2:e2:f2
+p 1 arp add 3 10.3.0.2 a3:b3:c3:d3:e3:f3
+#p 1 arp ls
+
+################################################################################
+# Routes
+################################################################################
+p 1 route add default 4 #SINK2
+p 1 route add 100.0.0.0 16 port 0 ether 10.0.0.2
+p 1 route add 100.1.0.0 16 port 1 ether 10.1.0.2
+p 1 route add 100.2.0.0 16 port 2 ether 10.2.0.2
+p 1 route add 100.3.0.0 16 port 3 ether 10.3.0.2
+#p 1 route ls
+
+################################################################################
+# Local destination UDP traffic
+################################################################################
+# Prio = Lowest: [SA = ANY, DA = ANY, SP = ANY, DP = ANY, PROTO = ANY] => Drop
+# Prio = 1 (High): [SA = ANY, DA = 10.0.0.1, SP = ANY, DP = 1000, PROTO = UDP] => Allow
+# Prio = 1 (High): [SA = ANY, DA = 10.1.0.1, SP = ANY, DP = 1001, PROTO = UDP] => Allow
+# Prio = 1 (High): [SA = ANY, DA = 10.2.0.1, SP = ANY, DP = 1002, PROTO = UDP] => Allow
+# Prio = 1 (High): [SA = ANY, DA = 10.3.0.1, SP = ANY, DP = 1003, PROTO = UDP] => Allow
+p 1 firewall add default 1 #SINK0
+p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.0.0.1 32 0 65535 1000 1000 17 0xF port 0
+p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.1.0.1 32 0 65535 1001 1001 17 0xF port 0
+p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.2.0.1 32 0 65535 1002 1002 17 0xF port 0
+p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.3.0.1 32 0 65535 1003 1003 17 0xF port 0
+#p 2 firewall ls
+
+################################################################################
+# Local destination TCP traffic
+################################################################################
+# Unknown connection => Drop
+# TCP [SA = 100.0.0.10, DA = 10.0.0.1, SP = 1000, DP = 80] => socket ID = 0
+# TCP [SA = 100.1.0.10, DA = 10.1.0.1, SP = 1001, DP = 80] => socket ID = 1
+# TCP [SA = 100.2.0.10, DA = 10.2.0.1, SP = 1002, DP = 80] => socket ID = 2
+# TCP [SA = 100.3.0.10, DA = 10.3.0.1, SP = 1003, DP = 80] => socket ID = 3
+p 3 flow add default 1 #SINK1
+p 3 flow add ipv4 100.0.0.10 10.0.0.1 1000 80 6 port 1 id 0
+p 3 flow add ipv4 100.1.0.10 10.1.0.1 1001 80 6 port 1 id 1
+p 3 flow add ipv4 100.2.0.10 10.2.0.1 1002 80 6 port 1 id 2
+p 3 flow add ipv4 100.3.0.10 10.3.0.1 1003 80 6 port 1 id 3
+#p 3 flow ls
-- 
2.5.5

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [dpdk-dev] [PATCH v2 6/6] ip_pipeline: update release notes
  2016-06-01 14:00 ` [dpdk-dev] [PATCH v2 0/6] " Jasvinder Singh
                     ` (4 preceding siblings ...)
  2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 5/6] ip_pipeline: sample config file on adding various network layer components Jasvinder Singh
@ 2016-06-01 14:01   ` Jasvinder Singh
  2016-06-08 19:43   ` [dpdk-dev] [PATCH v2 0/6] ip_pipeline: routing pipeline improvements Thomas Monjalon
  6 siblings, 0 replies; 9+ messages in thread
From: Jasvinder Singh @ 2016-06-01 14:01 UTC (permalink / raw)
  To: dev; +Cc: cristian.dumitrescu

Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 doc/guides/rel_notes/release_16_07.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/doc/guides/rel_notes/release_16_07.rst b/doc/guides/rel_notes/release_16_07.rst
index 30e78d4..d8215bc 100644
--- a/doc/guides/rel_notes/release_16_07.rst
+++ b/doc/guides/rel_notes/release_16_07.rst
@@ -47,6 +47,16 @@ New Features
   * Dropped specific Xen Dom0 code.
   * Dropped specific anonymous mempool code in testpmd.
 
+* **IP Pipeline Application.**
+
+  The following features have been added to ip_pipeline application;
+
+  * Configure the MAC address in the routing pipeline and automatic routes
+    updates with change in link state.
+  * Enable RSS per network interface through the ip pipeline application
+    configuration file.
+  * Streamline the CLI code of the IP pipeline application.
+
 
 Resolved Issues
 ---------------
-- 
2.5.5

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [dpdk-dev] [PATCH v2 0/6] ip_pipeline: routing pipeline improvements
  2016-06-01 14:00 ` [dpdk-dev] [PATCH v2 0/6] " Jasvinder Singh
                     ` (5 preceding siblings ...)
  2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 6/6] ip_pipeline: update release notes Jasvinder Singh
@ 2016-06-08 19:43   ` Thomas Monjalon
  6 siblings, 0 replies; 9+ messages in thread
From: Thomas Monjalon @ 2016-06-08 19:43 UTC (permalink / raw)
  To: Jasvinder Singh; +Cc: dev, cristian.dumitrescu

2016-06-01 15:00, Jasvinder Singh:
> This commit adds following features to the routing pipeline;
> 
> 1. Implements the tracking mechanism for the routing pipeline for identifying
> the physical nic port where a specific output ports of the routing pipeline are
> eventually connected. Depending upon the application, tracking could involve
> traversing the other intermediate pipelines.
> 
> The pipelines such as pass-through allows tracking to be performaned through
> them becasue of straightforward connections between their input and output
> ports, while pipelines like flow-classifications, firewall fails the tracking
> because of dependency upon the table rule set. As a result of tracking
> mechainsm, routing pipeline uses the real MAC addresses of the network
> interfaces instead of hardcoded default value.
> 
> 2. Adds support for automatic route automatic update when physical NIC ports
> change their state (up/down) or configuration. Every time a physical port
> goes up/down, a call-back function that the specific pipeline type
> (e.g. routing) registered with NIC ports at init time; will simply add/delete
> a route associated with that output port.
> 
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> 
> Jasvinder Singh (6):
>   ip_pipeline: increase macros values
>   ip_pipeline: linking routing pipeline output ports with NIC ports
>   ip_pipeline: assign nic ports mac address to the routing pipeline
>     outports
>   ip_pipeline: automatic routes update with the change in nic ports
>     state
>   ip_pipeline: sample config file on adding various network layer
>     components
>   ip_pipeline: update release notes

Applied, thanks

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2016-06-08 19:43 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-06 23:57 [dpdk-dev] [PATCH] ip_pipeline: routing pipeline improvements Jasvinder Singh
2016-06-01 14:00 ` [dpdk-dev] [PATCH v2 0/6] " Jasvinder Singh
2016-06-01 14:00   ` [dpdk-dev] [PATCH v2 1/6] ip_pipeline: increase macros values Jasvinder Singh
2016-06-01 14:00   ` [dpdk-dev] [PATCH v2 2/6] ip_pipeline: linking routing pipeline output ports with NIC ports Jasvinder Singh
2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 3/6] ip_pipeline: assign nic ports mac address to the routing pipeline outports Jasvinder Singh
2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 4/6] ip_pipeline: automatic routes update with the change in nic ports state Jasvinder Singh
2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 5/6] ip_pipeline: sample config file on adding various network layer components Jasvinder Singh
2016-06-01 14:01   ` [dpdk-dev] [PATCH v2 6/6] ip_pipeline: update release notes Jasvinder Singh
2016-06-08 19:43   ` [dpdk-dev] [PATCH v2 0/6] ip_pipeline: routing pipeline improvements Thomas Monjalon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).