DPDK patches and discussions
 help / color / mirror / Atom feed
From: Jasvinder Singh <jasvinder.singh@intel.com>
To: dev@dpdk.org
Cc: cristian.dumitrescu@intel.com
Subject: [dpdk-dev] [PATCH v2 4/6] ip_pipeline: automatic routes update with the change in nic ports state
Date: Wed,  1 Jun 2016 15:01:01 +0100	[thread overview]
Message-ID: <1464789663-173318-5-git-send-email-jasvinder.singh@intel.com> (raw)
In-Reply-To: <1464789663-173318-1-git-send-email-jasvinder.singh@intel.com>

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

  parent reply	other threads:[~2016-06-01 13:54 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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   ` Jasvinder Singh [this message]
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

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=1464789663-173318-5-git-send-email-jasvinder.singh@intel.com \
    --to=jasvinder.singh@intel.com \
    --cc=cristian.dumitrescu@intel.com \
    --cc=dev@dpdk.org \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is 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).