DPDK patches and discussions
 help / color / mirror / Atom feed
From: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
To: shahafs@mellanox.com
Cc: dev@dpdk.org
Subject: [dpdk-dev] [PATCH 2/5] net/mlx5: introduce encapsulation rules container
Date: Sat, 29 Dec 2018 19:55:37 +0000	[thread overview]
Message-ID: <1546113340-30356-3-git-send-email-viacheslavo@mellanox.com> (raw)
In-Reply-To: <1546113340-30356-1-git-send-email-viacheslavo@mellanox.com>

Currently the VXLAN encapsulation neigh/local rules
are stored in the list contained in the VTEP device
structure. Encapsulation VTEP device is attached to
outer interface and stored rules are related to this
underlying interface. We are going to use unattached
VXLAN devices for encapsulation (kernel does not use
attached interface to find egress one), so we should
introduce the structure to keep interface related
neigh/local rules instead of VTEP structure. This
patch introduces internal tcf_irule structure, and
its create/delete methods.

Signed-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>
---
 drivers/net/mlx5/mlx5_flow_tcf.c | 108 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 107 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c
index b4734a0..a6dca08 100644
--- a/drivers/net/mlx5/mlx5_flow_tcf.c
+++ b/drivers/net/mlx5/mlx5_flow_tcf.c
@@ -431,6 +431,15 @@ struct tcf_local_rule {
 	};
 };
 
+/** Outer interface VXLAN encapsulation rules container. */
+struct tcf_irule {
+	LIST_ENTRY(tcf_irule) next;
+	LIST_HEAD(, tcf_neigh_rule) neigh;
+	LIST_HEAD(, tcf_local_rule) local;
+	uint32_t refcnt;
+	unsigned int ifouter; /**< Own interface index. */
+};
+
 /** VXLAN virtual netdev. */
 struct tcf_vtep {
 	LIST_ENTRY(tcf_vtep) next;
@@ -458,6 +467,7 @@ struct flow_tcf_vxlan_decap {
 
 struct flow_tcf_vxlan_encap {
 	struct flow_tcf_tunnel_hdr hdr;
+	struct tcf_irule *iface;
 	uint32_t mask;
 	uint8_t ip_tos;
 	uint8_t ip_ttl_hop;
@@ -4971,11 +4981,90 @@ struct tcf_nlcb_context {
 	return 0;
 }
 
+/* VXLAN encap rule database for outer interfaces. */
+static  LIST_HEAD(, tcf_irule) iface_list_vxlan = LIST_HEAD_INITIALIZER();
+
 /* VTEP device list is shared between PMD port instances. */
 static LIST_HEAD(, tcf_vtep) vtep_list_vxlan = LIST_HEAD_INITIALIZER();
 static pthread_mutex_t vtep_list_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 /**
+ * Acquire the VXLAN encap rules container for specified interface.
+ * First looks for the container in the existing ones list, creates
+ * and initializes the new container if existing not found.
+ *
+ * @param[in] tcf
+ *   Context object initialized by mlx5_flow_tcf_context_create().
+ * @param[in] ifouter
+ *   Network interface index to create VXLAN encap rules on.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ * @return
+ *   Rule container pointer on success,
+ *   NULL otherwise and rte_errno is set.
+ */
+static struct tcf_irule*
+flow_tcf_encap_irule_acquire(struct mlx5_flow_tcf_context *tcf,
+			     unsigned int ifouter,
+			     struct rte_flow_error *error)
+{
+	struct tcf_irule *iface;
+
+	/* Look whether the container for encap rules is created. */
+	assert(ifouter);
+	LIST_FOREACH(iface, &iface_list_vxlan, next) {
+		if (iface->ifouter == ifouter)
+			break;
+	}
+	if (iface) {
+		/* Container already exists, just increment the reference. */
+		iface->refcnt++;
+		return iface;
+	}
+	/* Not found, we should create the new container. */
+	iface = rte_zmalloc(__func__, sizeof(*iface),
+			    alignof(struct tcf_irule));
+	if (!iface) {
+		rte_flow_error_set(error, ENOMEM,
+				   RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+				   "unable to allocate memory for container");
+		return NULL;
+	}
+	*iface = (struct tcf_irule){
+			.local = LIST_HEAD_INITIALIZER(),
+			.neigh = LIST_HEAD_INITIALIZER(),
+			.ifouter = ifouter,
+			.refcnt = 1,
+	};
+	/* Interface cleanup for new container created. */
+	flow_tcf_encap_iface_cleanup(tcf, ifouter);
+	flow_tcf_encap_local_cleanup(tcf, ifouter);
+	flow_tcf_encap_neigh_cleanup(tcf, ifouter);
+	LIST_INSERT_HEAD(&iface_list_vxlan, iface, next);
+	return iface;
+}
+
+/**
+ * Releases VXLAN encap rules container by pointer. Decrements the
+ * reference cointer and deletes the container if counter is zero.
+ *
+ * @param[in] irule
+ *   VXLAN rule container pointer to release.
+ */
+static void
+flow_tcf_encap_irule_release(struct tcf_irule *iface)
+{
+	assert(iface->refcnt);
+	if (--iface->refcnt == 0) {
+		/* Reference counter is zero, delete the container. */
+		assert(LIST_EMPTY(&iface->local));
+		assert(LIST_EMPTY(&iface->neigh));
+		LIST_REMOVE(iface, next);
+		rte_free(iface);
+	}
+}
+
+/**
  * Deletes VTEP network device.
  *
  * @param[in] tcf
@@ -5247,6 +5336,7 @@ struct tcf_nlcb_context {
 {
 	static uint16_t encap_port = MLX5_VXLAN_PORT_MIN - 1;
 	struct tcf_vtep *vtep;
+	struct tcf_irule *iface;
 	int ret;
 
 	assert(ifouter);
@@ -5296,6 +5386,13 @@ struct tcf_nlcb_context {
 	}
 	assert(vtep->ifouter == ifouter);
 	assert(vtep->ifindex);
+	iface = flow_tcf_encap_irule_acquire(tcf, ifouter, error);
+	if (!iface) {
+		if (--vtep->refcnt == 0)
+			flow_tcf_vtep_delete(tcf, vtep);
+		return NULL;
+	}
+	dev_flow->tcf.vxlan_encap->iface = iface;
 	/* Create local ipaddr with peer to specify the outer IPs. */
 	ret = flow_tcf_encap_local(tcf, vtep, dev_flow, true, error);
 	if (!ret) {
@@ -5306,6 +5403,8 @@ struct tcf_nlcb_context {
 					     dev_flow, false, error);
 	}
 	if (ret) {
+		dev_flow->tcf.vxlan_encap->iface = NULL;
+		flow_tcf_encap_irule_release(iface);
 		if (--vtep->refcnt == 0)
 			flow_tcf_vtep_delete(tcf, vtep);
 		return NULL;
@@ -5378,11 +5477,18 @@ struct tcf_nlcb_context {
 	switch (dev_flow->tcf.tunnel->type) {
 	case FLOW_TCF_TUNACT_VXLAN_DECAP:
 		break;
-	case FLOW_TCF_TUNACT_VXLAN_ENCAP:
+	case FLOW_TCF_TUNACT_VXLAN_ENCAP: {
+		struct tcf_irule *iface;
+
 		/* Remove the encap ancillary rules first. */
+		iface = dev_flow->tcf.vxlan_encap->iface;
+		assert(iface);
 		flow_tcf_encap_neigh(tcf, vtep, dev_flow, false, NULL);
 		flow_tcf_encap_local(tcf, vtep, dev_flow, false, NULL);
+		flow_tcf_encap_irule_release(iface);
+		dev_flow->tcf.vxlan_encap->iface = NULL;
 		break;
+	}
 	default:
 		assert(false);
 		DRV_LOG(WARNING, "Unsupported tunnel type");
-- 
1.8.3.1

  parent reply	other threads:[~2018-12-29 19:55 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-29 19:55 [dpdk-dev] [PATCH 0/5] net/mlx5: simplify VXLAN devices management for E-Switch Viacheslav Ovsiienko
2018-12-29 19:55 ` [dpdk-dev] [PATCH 1/5] net/mlx5: optimize neigh and local encap rules search Viacheslav Ovsiienko
2018-12-29 19:55 ` Viacheslav Ovsiienko [this message]
2018-12-29 19:55 ` [dpdk-dev] [PATCH 3/5] net/mlx5: switch encap rules to use container Viacheslav Ovsiienko
2018-12-29 19:55 ` [dpdk-dev] [PATCH 4/5] net/mlx5: switch to detached VXLAN network devices Viacheslav Ovsiienko
2018-12-29 19:55 ` [dpdk-dev] [PATCH 5/5] net/mlx5: add RH7.2 VXLAN device metadata workaround Viacheslav Ovsiienko
2019-01-13 12:19 ` [dpdk-dev] [PATCH 0/5] net/mlx5: simplify VXLAN devices management for E-Switch Shahaf Shuler

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=1546113340-30356-3-git-send-email-viacheslavo@mellanox.com \
    --to=viacheslavo@mellanox.com \
    --cc=dev@dpdk.org \
    --cc=shahafs@mellanox.com \
    /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).