All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Daley <johndale@cisco.com>
To: ferruh.yigit@intel.com
Cc: dev@dpdk.org, John Daley <johndale@cisco.com>
Subject: [PATCH v3 4/6] net/enic: flow API for Legacy NICs
Date: Tue, 16 May 2017 20:03:46 -0700	[thread overview]
Message-ID: <20170517030348.2663-5-johndale@cisco.com> (raw)
In-Reply-To: <20170517030348.2663-1-johndale@cisco.com>

5-tuple exact Flow support for 1200 series adapters. This allows:
Attributes: ingress
Items: ipv4, ipv6, udp, tcp (must exactly match src/dst IP
       addresses and ports and all must be specified).
Actions: queue and void
Selectors: 'is'

Signed-off-by: John Daley <johndale@cisco.com>
Reviewed-by: Nelson Escobar <neescoba@cisco.com>
---
 drivers/net/enic/enic_flow.c | 206 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 201 insertions(+), 5 deletions(-)

diff --git a/drivers/net/enic/enic_flow.c b/drivers/net/enic/enic_flow.c
index edbde98e6..6fbdcfb6c 100644
--- a/drivers/net/enic/enic_flow.c
+++ b/drivers/net/enic/enic_flow.c
@@ -92,6 +92,9 @@ struct enic_action_cap {
 };
 
 /* Forward declarations */
+static enic_copy_item_fn enic_copy_item_ipv4_v1;
+static enic_copy_item_fn enic_copy_item_udp_v1;
+static enic_copy_item_fn enic_copy_item_tcp_v1;
 static enic_copy_item_fn enic_copy_item_eth_v2;
 static enic_copy_item_fn enic_copy_item_vlan_v2;
 static enic_copy_item_fn enic_copy_item_ipv4_v2;
@@ -105,6 +108,36 @@ static copy_action_fn enic_copy_action_v1;
 static copy_action_fn enic_copy_action_v2;
 
 /**
+ * Legacy NICs or NICs with outdated firmware. Only 5-tuple perfect match
+ * is supported.
+ */
+static const struct enic_items enic_items_v1[] = {
+	[RTE_FLOW_ITEM_TYPE_IPV4] = {
+		.copy_item = enic_copy_item_ipv4_v1,
+		.valid_start_item = 1,
+		.prev_items = (const enum rte_flow_item_type[]) {
+			       RTE_FLOW_ITEM_TYPE_END,
+		},
+	},
+	[RTE_FLOW_ITEM_TYPE_UDP] = {
+		.copy_item = enic_copy_item_udp_v1,
+		.valid_start_item = 0,
+		.prev_items = (const enum rte_flow_item_type[]) {
+			       RTE_FLOW_ITEM_TYPE_IPV4,
+			       RTE_FLOW_ITEM_TYPE_END,
+		},
+	},
+	[RTE_FLOW_ITEM_TYPE_TCP] = {
+		.copy_item = enic_copy_item_tcp_v1,
+		.valid_start_item = 0,
+		.prev_items = (const enum rte_flow_item_type[]) {
+			       RTE_FLOW_ITEM_TYPE_IPV4,
+			       RTE_FLOW_ITEM_TYPE_END,
+		},
+	},
+};
+
+/**
  * NICs have Advanced Filters capability but they are disabled. This means
  * that layer 3 must be specified.
  */
@@ -255,6 +288,9 @@ static const struct enic_items enic_items_v3[] = {
 
 /** Filtering capabilites indexed this NICs supported filter type. */
 static const struct enic_filter_cap enic_filter_cap[] = {
+	[FILTER_IPV4_5TUPLE] = {
+		.item_info = enic_items_v1,
+	},
 	[FILTER_USNIC_IP] = {
 		.item_info = enic_items_v2,
 	},
@@ -288,6 +324,171 @@ static const struct enic_action_cap enic_action_cap[] = {
 		.copy_fn = enic_copy_action_v2,
 	},
 };
+
+static int
+mask_exact_match(const u8 *supported, const u8 *supplied,
+		 unsigned int size)
+{
+	unsigned int i;
+	for (i = 0; i < size; i++) {
+		if (supported[i] != supplied[i])
+			return 0;
+	}
+	return 1;
+}
+
+/**
+ * Copy IPv4 item into version 1 NIC filter.
+ *
+ * @param item[in]
+ *   Item specification.
+ * @param enic_filter[out]
+ *   Partially filled in NIC filter structure.
+ * @param inner_ofst[in]
+ *   Should always be 0 for version 1.
+ */
+static int
+enic_copy_item_ipv4_v1(const struct rte_flow_item *item,
+		       struct filter_v2 *enic_filter, u8 *inner_ofst)
+{
+	const struct rte_flow_item_ipv4 *spec = item->spec;
+	const struct rte_flow_item_ipv4 *mask = item->mask;
+	struct filter_ipv4_5tuple *enic_5tup = &enic_filter->u.ipv4;
+	struct ipv4_hdr supported_mask = {
+		.src_addr = 0xffffffff,
+		.dst_addr = 0xffffffff,
+	};
+
+	FLOW_TRACE();
+
+	if (*inner_ofst)
+		return ENOTSUP;
+
+	if (!mask)
+		mask = &rte_flow_item_ipv4_mask;
+
+	/* This is an exact match filter, both fields must be set */
+	if (!spec || !spec->hdr.src_addr || !spec->hdr.dst_addr) {
+		FLOW_LOG(ERR, "IPv4 exact match src/dst addr");
+		return ENOTSUP;
+	}
+
+	/* check that the suppied mask exactly matches capabilty */
+	if (!mask_exact_match((const u8 *)&supported_mask,
+			      (const u8 *)item->mask, sizeof(*mask))) {
+		FLOW_LOG(ERR, "IPv4 exact match mask");
+		return ENOTSUP;
+	}
+
+	enic_filter->u.ipv4.flags = FILTER_FIELDS_IPV4_5TUPLE;
+	enic_5tup->src_addr = spec->hdr.src_addr;
+	enic_5tup->dst_addr = spec->hdr.dst_addr;
+
+	return 0;
+}
+
+/**
+ * Copy UDP item into version 1 NIC filter.
+ *
+ * @param item[in]
+ *   Item specification.
+ * @param enic_filter[out]
+ *   Partially filled in NIC filter structure.
+ * @param inner_ofst[in]
+ *   Should always be 0 for version 1.
+ */
+static int
+enic_copy_item_udp_v1(const struct rte_flow_item *item,
+		      struct filter_v2 *enic_filter, u8 *inner_ofst)
+{
+	const struct rte_flow_item_udp *spec = item->spec;
+	const struct rte_flow_item_udp *mask = item->mask;
+	struct filter_ipv4_5tuple *enic_5tup = &enic_filter->u.ipv4;
+	struct udp_hdr supported_mask = {
+		.src_port = 0xffff,
+		.dst_port = 0xffff,
+	};
+
+	FLOW_TRACE();
+
+	if (*inner_ofst)
+		return ENOTSUP;
+
+	if (!mask)
+		mask = &rte_flow_item_udp_mask;
+
+	/* This is an exact match filter, both ports must be set */
+	if (!spec || !spec->hdr.src_port || !spec->hdr.dst_port) {
+		FLOW_LOG(ERR, "UDP exact match src/dst addr");
+		return ENOTSUP;
+	}
+
+	/* check that the suppied mask exactly matches capabilty */
+	if (!mask_exact_match((const u8 *)&supported_mask,
+			      (const u8 *)item->mask, sizeof(*mask))) {
+		FLOW_LOG(ERR, "UDP exact match mask");
+		return ENOTSUP;
+	}
+
+	enic_filter->u.ipv4.flags = FILTER_FIELDS_IPV4_5TUPLE;
+	enic_5tup->src_port = spec->hdr.src_port;
+	enic_5tup->dst_port = spec->hdr.dst_port;
+	enic_5tup->protocol = PROTO_UDP;
+
+	return 0;
+}
+
+/**
+ * Copy TCP item into version 1 NIC filter.
+ *
+ * @param item[in]
+ *   Item specification.
+ * @param enic_filter[out]
+ *   Partially filled in NIC filter structure.
+ * @param inner_ofst[in]
+ *   Should always be 0 for version 1.
+ */
+static int
+enic_copy_item_tcp_v1(const struct rte_flow_item *item,
+		      struct filter_v2 *enic_filter, u8 *inner_ofst)
+{
+	const struct rte_flow_item_tcp *spec = item->spec;
+	const struct rte_flow_item_tcp *mask = item->mask;
+	struct filter_ipv4_5tuple *enic_5tup = &enic_filter->u.ipv4;
+	struct tcp_hdr supported_mask = {
+		.src_port = 0xffff,
+		.dst_port = 0xffff,
+	};
+
+	FLOW_TRACE();
+
+	if (*inner_ofst)
+		return ENOTSUP;
+
+	if (!mask)
+		mask = &rte_flow_item_tcp_mask;
+
+	/* This is an exact match filter, both ports must be set */
+	if (!spec || !spec->hdr.src_port || !spec->hdr.dst_port) {
+		FLOW_LOG(ERR, "TCPIPv4 exact match src/dst addr");
+		return ENOTSUP;
+	}
+
+	/* check that the suppied mask exactly matches capabilty */
+	if (!mask_exact_match((const u8 *)&supported_mask,
+			     (const u8 *)item->mask, sizeof(*mask))) {
+		FLOW_LOG(ERR, "TCP exact match mask");
+		return ENOTSUP;
+	}
+
+	enic_filter->u.ipv4.flags = FILTER_FIELDS_IPV4_5TUPLE;
+	enic_5tup->src_port = spec->hdr.src_port;
+	enic_5tup->dst_port = spec->hdr.dst_port;
+	enic_5tup->protocol = PROTO_TCP;
+
+	return 0;
+}
+
 /**
  * Copy ETH item into version 2 NIC filter.
  *
@@ -881,11 +1082,6 @@ enic_match_action(const struct rte_flow_action *action,
 static const struct enic_filter_cap *
 enic_get_filter_cap(struct enic *enic)
 {
-	/* FIXME: only support advanced filters for now */
-	if ((enic->flow_filter_mode != FILTER_DPDK_1) &&
-	   (enic->flow_filter_mode != FILTER_USNIC_IP))
-		return (const struct enic_filter_cap *)NULL;
-
 	if (enic->flow_filter_mode)
 		return &enic_filter_cap[enic->flow_filter_mode];
 
-- 
2.12.0

  parent reply	other threads:[~2017-05-17  3:04 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-30 21:28 [PATCH 1/6] net/enic: bring NIC interface functions up to date John Daley
2017-03-30 21:28 ` [PATCH 2/6] net/enic: flow API skeleton John Daley
2017-03-30 21:28 ` [PATCH 3/6] net/enic: flow API for NICs with advanced filters enabled John Daley
2017-03-30 21:28 ` [PATCH 4/6] net/enic: flow API for NICs with advanced filters disabled John Daley
2017-03-30 21:28 ` [PATCH 5/6] net/enic: flow API support for Legacy NICs John Daley
2017-03-30 21:28 ` [PATCH 6/6] net/enic: flow API debug John Daley
2017-03-31  2:06 ` [PATCH v2 0/7] *** flow API support for enic *** John Daley
2017-03-31  2:06   ` [PATCH v2 1/7] net/enic: bring NIC interface functions up to date John Daley
2017-03-31  2:06   ` [PATCH v2 2/7] net/enic: flow API skeleton John Daley
2017-03-31  2:06   ` [PATCH v2 3/7] net/enic: flow API for NICs with advanced filters enabled John Daley
2017-03-31  2:06   ` [PATCH v2 4/7] net/enic: flow API for NICs with advanced filters disabled John Daley
2017-03-31  2:06   ` [PATCH v2 5/7] net/enic: flow API for Legacy NICs John Daley
2017-03-31  2:06   ` [PATCH v2 6/7] net/enic: flow API debug John Daley
2017-03-31  2:06   ` [PATCH v2 7/7] net/enic: flow API documentation John Daley
2017-04-02 15:18     ` Mcnamara, John
2017-05-12 12:11     ` Ferruh Yigit
2017-05-17  3:03     ` [PATCH v3 0/6] enic flow api support John Daley
2017-05-17  3:03       ` [PATCH v3 1/6] net/enic: flow API skeleton John Daley
2017-05-17 11:12         ` Ferruh Yigit
2017-05-17  3:03       ` [PATCH v3 2/6] net/enic: flow API for NICs with advanced filters enabled John Daley
2017-05-17 11:12         ` Ferruh Yigit
2017-05-17  3:03       ` [PATCH v3 3/6] net/enic: flow API for NICs with advanced filters disabled John Daley
2017-05-17 11:13         ` Ferruh Yigit
2017-05-17  3:03       ` John Daley [this message]
2017-05-17  3:03       ` [PATCH v3 5/6] net/enic: flow API debug John Daley
2017-05-17  3:03       ` [PATCH v3 6/6] net/enic: flow API documentation John Daley
2017-05-17 11:13         ` Ferruh Yigit
2017-05-17 22:38           ` [PATCH v4 0/8] enic flow api support John Daley
2017-05-17 22:38             ` [PATCH v4 1/8] net/enic: bring NIC interface functions up to date John Daley
2017-05-22  9:49               ` Ferruh Yigit
2017-06-08 10:44               ` Jerin Jacob
2017-05-17 22:38             ` [PATCH v4 2/8] net/enic: flow API skeleton John Daley
2017-05-17 22:38             ` [PATCH v4 3/8] net/enic: flow API for NICs with advanced filters enabled John Daley
2017-05-17 22:38             ` [PATCH v4 4/8] net/enic: flow API mark and flag support John Daley
2017-05-17 22:38             ` [PATCH v4 5/8] net/enic: flow API for NICs with advanced filters disabled John Daley
2017-05-17 22:38             ` [PATCH v4 6/8] net/enic: flow API for Legacy NICs John Daley
2017-05-17 22:38             ` [PATCH v4 7/8] net/enic: flow API debug John Daley
2017-05-17 22:38             ` [PATCH v4 8/8] net/enic: flow API documentation John Daley
2017-05-22 10:05             ` [PATCH v4 0/8] enic flow api support Ferruh Yigit
2017-05-17 11:12       ` [PATCH v3 0/6] " Ferruh Yigit
2017-03-31 10:12 ` [PATCH 1/6] net/enic: bring NIC interface functions up to date Ferruh Yigit

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=20170517030348.2663-5-johndale@cisco.com \
    --to=johndale@cisco.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.