All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiawen Wu <jiawenwu@trustnetic.com>
To: dev@dpdk.org
Cc: Jiawen Wu <jiawenwu@trustnetic.com>
Subject: [dpdk-dev] [PATCH v2 02/37] net/txgbe: support ntuple filter add and delete
Date: Wed, 11 Nov 2020 14:49:01 +0800	[thread overview]
Message-ID: <20201111064936.768604-3-jiawenwu@trustnetic.com> (raw)
In-Reply-To: <20201111064936.768604-1-jiawenwu@trustnetic.com>

Support add and delete operations on ntuple filter.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
---
 drivers/net/txgbe/txgbe_ethdev.c | 310 +++++++++++++++++++++++++++++++
 drivers/net/txgbe/txgbe_ethdev.h |   6 +
 2 files changed, 316 insertions(+)

diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c
index 626c333e6..3a31d4bba 100644
--- a/drivers/net/txgbe/txgbe_ethdev.c
+++ b/drivers/net/txgbe/txgbe_ethdev.c
@@ -109,6 +109,8 @@ static void txgbe_dev_interrupt_handler(void *param);
 static void txgbe_dev_interrupt_delayed_handler(void *param);
 static void txgbe_configure_msix(struct rte_eth_dev *dev);
 
+static int txgbe_filter_restore(struct rte_eth_dev *dev);
+
 #define TXGBE_SET_HWSTRIP(h, q) do {\
 		uint32_t idx = (q) / (sizeof((h)->bitmap[0]) * NBBY); \
 		uint32_t bit = (q) % (sizeof((h)->bitmap[0]) * NBBY); \
@@ -1611,6 +1613,7 @@ txgbe_dev_start(struct rte_eth_dev *dev)
 
 	/* resume enabled intr since hw reset */
 	txgbe_enable_intr(dev);
+	txgbe_filter_restore(dev);
 
 	/*
 	 * Update link status right before return, because it may
@@ -3509,6 +3512,293 @@ txgbe_set_queue_rate_limit(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static inline enum txgbe_5tuple_protocol
+convert_protocol_type(uint8_t protocol_value)
+{
+	if (protocol_value == IPPROTO_TCP)
+		return TXGBE_5TF_PROT_TCP;
+	else if (protocol_value == IPPROTO_UDP)
+		return TXGBE_5TF_PROT_UDP;
+	else if (protocol_value == IPPROTO_SCTP)
+		return TXGBE_5TF_PROT_SCTP;
+	else
+		return TXGBE_5TF_PROT_NONE;
+}
+
+/* inject a 5-tuple filter to HW */
+static inline void
+txgbe_inject_5tuple_filter(struct rte_eth_dev *dev,
+			   struct txgbe_5tuple_filter *filter)
+{
+	struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+	int i;
+	uint32_t ftqf, sdpqf;
+	uint32_t l34timir = 0;
+	uint32_t mask = TXGBE_5TFCTL0_MASK;
+
+	i = filter->index;
+	sdpqf = TXGBE_5TFPORT_DST(be_to_le16(filter->filter_info.dst_port));
+	sdpqf |= TXGBE_5TFPORT_SRC(be_to_le16(filter->filter_info.src_port));
+
+	ftqf = TXGBE_5TFCTL0_PROTO(filter->filter_info.proto);
+	ftqf |= TXGBE_5TFCTL0_PRI(filter->filter_info.priority);
+	if (filter->filter_info.src_ip_mask == 0) /* 0 means compare. */
+		mask &= ~TXGBE_5TFCTL0_MSADDR;
+	if (filter->filter_info.dst_ip_mask == 0)
+		mask &= ~TXGBE_5TFCTL0_MDADDR;
+	if (filter->filter_info.src_port_mask == 0)
+		mask &= ~TXGBE_5TFCTL0_MSPORT;
+	if (filter->filter_info.dst_port_mask == 0)
+		mask &= ~TXGBE_5TFCTL0_MDPORT;
+	if (filter->filter_info.proto_mask == 0)
+		mask &= ~TXGBE_5TFCTL0_MPROTO;
+	ftqf |= mask;
+	ftqf |= TXGBE_5TFCTL0_MPOOL;
+	ftqf |= TXGBE_5TFCTL0_ENA;
+
+	wr32(hw, TXGBE_5TFDADDR(i), be_to_le32(filter->filter_info.dst_ip));
+	wr32(hw, TXGBE_5TFSADDR(i), be_to_le32(filter->filter_info.src_ip));
+	wr32(hw, TXGBE_5TFPORT(i), sdpqf);
+	wr32(hw, TXGBE_5TFCTL0(i), ftqf);
+
+	l34timir |= TXGBE_5TFCTL1_QP(filter->queue);
+	wr32(hw, TXGBE_5TFCTL1(i), l34timir);
+}
+
+/*
+ * add a 5tuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ * filter: ponter to the filter that will be added.
+ * rx_queue: the queue id the filter assigned to.
+ *
+ * @return
+ *    - On success, zero.
+ *    - On failure, a negative value.
+ */
+static int
+txgbe_add_5tuple_filter(struct rte_eth_dev *dev,
+			struct txgbe_5tuple_filter *filter)
+{
+	struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
+	int i, idx, shift;
+
+	/*
+	 * look for an unused 5tuple filter index,
+	 * and insert the filter to list.
+	 */
+	for (i = 0; i < TXGBE_MAX_FTQF_FILTERS; i++) {
+		idx = i / (sizeof(uint32_t) * NBBY);
+		shift = i % (sizeof(uint32_t) * NBBY);
+		if (!(filter_info->fivetuple_mask[idx] & (1 << shift))) {
+			filter_info->fivetuple_mask[idx] |= 1 << shift;
+			filter->index = i;
+			TAILQ_INSERT_TAIL(&filter_info->fivetuple_list,
+					  filter,
+					  entries);
+			break;
+		}
+	}
+	if (i >= TXGBE_MAX_FTQF_FILTERS) {
+		PMD_DRV_LOG(ERR, "5tuple filters are full.");
+		return -ENOSYS;
+	}
+
+	txgbe_inject_5tuple_filter(dev, filter);
+
+	return 0;
+}
+
+/*
+ * remove a 5tuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * filter: the pointer of the filter will be removed.
+ */
+static void
+txgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
+			struct txgbe_5tuple_filter *filter)
+{
+	struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
+	struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
+	uint16_t index = filter->index;
+
+	filter_info->fivetuple_mask[index / (sizeof(uint32_t) * NBBY)] &=
+				~(1 << (index % (sizeof(uint32_t) * NBBY)));
+	TAILQ_REMOVE(&filter_info->fivetuple_list, filter, entries);
+	rte_free(filter);
+
+	wr32(hw, TXGBE_5TFDADDR(index), 0);
+	wr32(hw, TXGBE_5TFSADDR(index), 0);
+	wr32(hw, TXGBE_5TFPORT(index), 0);
+	wr32(hw, TXGBE_5TFCTL0(index), 0);
+	wr32(hw, TXGBE_5TFCTL1(index), 0);
+}
+
+static inline struct txgbe_5tuple_filter *
+txgbe_5tuple_filter_lookup(struct txgbe_5tuple_filter_list *filter_list,
+			struct txgbe_5tuple_filter_info *key)
+{
+	struct txgbe_5tuple_filter *it;
+
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct txgbe_5tuple_filter_info)) == 0) {
+			return it;
+		}
+	}
+	return NULL;
+}
+
+/* translate elements in struct rte_eth_ntuple_filter
+ * to struct txgbe_5tuple_filter_info
+ */
+static inline int
+ntuple_filter_to_5tuple(struct rte_eth_ntuple_filter *filter,
+			struct txgbe_5tuple_filter_info *filter_info)
+{
+	if (filter->queue >= TXGBE_MAX_RX_QUEUE_NUM ||
+		filter->priority > TXGBE_5TUPLE_MAX_PRI ||
+		filter->priority < TXGBE_5TUPLE_MIN_PRI)
+		return -EINVAL;
+
+	switch (filter->dst_ip_mask) {
+	case UINT32_MAX:
+		filter_info->dst_ip_mask = 0;
+		filter_info->dst_ip = filter->dst_ip;
+		break;
+	case 0:
+		filter_info->dst_ip_mask = 1;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid dst_ip mask.");
+		return -EINVAL;
+	}
+
+	switch (filter->src_ip_mask) {
+	case UINT32_MAX:
+		filter_info->src_ip_mask = 0;
+		filter_info->src_ip = filter->src_ip;
+		break;
+	case 0:
+		filter_info->src_ip_mask = 1;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid src_ip mask.");
+		return -EINVAL;
+	}
+
+	switch (filter->dst_port_mask) {
+	case UINT16_MAX:
+		filter_info->dst_port_mask = 0;
+		filter_info->dst_port = filter->dst_port;
+		break;
+	case 0:
+		filter_info->dst_port_mask = 1;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid dst_port mask.");
+		return -EINVAL;
+	}
+
+	switch (filter->src_port_mask) {
+	case UINT16_MAX:
+		filter_info->src_port_mask = 0;
+		filter_info->src_port = filter->src_port;
+		break;
+	case 0:
+		filter_info->src_port_mask = 1;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid src_port mask.");
+		return -EINVAL;
+	}
+
+	switch (filter->proto_mask) {
+	case UINT8_MAX:
+		filter_info->proto_mask = 0;
+		filter_info->proto =
+			convert_protocol_type(filter->proto);
+		break;
+	case 0:
+		filter_info->proto_mask = 1;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid protocol mask.");
+		return -EINVAL;
+	}
+
+	filter_info->priority = (uint8_t)filter->priority;
+	return 0;
+}
+
+/*
+ * add or delete a ntuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * ntuple_filter: Pointer to struct rte_eth_ntuple_filter
+ * add: if true, add filter, if false, remove filter
+ *
+ * @return
+ *    - On success, zero.
+ *    - On failure, a negative value.
+ */
+int
+txgbe_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter,
+			bool add)
+{
+	struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
+	struct txgbe_5tuple_filter_info filter_5tuple;
+	struct txgbe_5tuple_filter *filter;
+	int ret;
+
+	if (ntuple_filter->flags != RTE_5TUPLE_FLAGS) {
+		PMD_DRV_LOG(ERR, "only 5tuple is supported.");
+		return -EINVAL;
+	}
+
+	memset(&filter_5tuple, 0, sizeof(struct txgbe_5tuple_filter_info));
+	ret = ntuple_filter_to_5tuple(ntuple_filter, &filter_5tuple);
+	if (ret < 0)
+		return ret;
+
+	filter = txgbe_5tuple_filter_lookup(&filter_info->fivetuple_list,
+					 &filter_5tuple);
+	if (filter != NULL && add) {
+		PMD_DRV_LOG(ERR, "filter exists.");
+		return -EEXIST;
+	}
+	if (filter == NULL && !add) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
+	}
+
+	if (add) {
+		filter = rte_zmalloc("txgbe_5tuple_filter",
+				sizeof(struct txgbe_5tuple_filter), 0);
+		if (filter == NULL)
+			return -ENOMEM;
+		rte_memcpy(&filter->filter_info,
+				 &filter_5tuple,
+				 sizeof(struct txgbe_5tuple_filter_info));
+		filter->queue = ntuple_filter->queue;
+		ret = txgbe_add_5tuple_filter(dev, filter);
+		if (ret < 0) {
+			rte_free(filter);
+			return ret;
+		}
+	} else {
+		txgbe_remove_5tuple_filter(dev, filter);
+	}
+
+	return 0;
+}
+
 static u8 *
 txgbe_dev_addr_list_itr(__rte_unused struct txgbe_hw *hw,
 			u8 **mc_addr_ptr, u32 *vmdq)
@@ -4030,6 +4320,26 @@ txgbe_dev_get_dcb_info(struct rte_eth_dev *dev,
 	return 0;
 }
 
+/* restore n-tuple filter */
+static inline void
+txgbe_ntuple_filter_restore(struct rte_eth_dev *dev)
+{
+	struct txgbe_filter_info *filter_info = TXGBE_DEV_FILTER(dev);
+	struct txgbe_5tuple_filter *node;
+
+	TAILQ_FOREACH(node, &filter_info->fivetuple_list, entries) {
+		txgbe_inject_5tuple_filter(dev, node);
+	}
+}
+
+static int
+txgbe_filter_restore(struct rte_eth_dev *dev)
+{
+	txgbe_ntuple_filter_restore(dev);
+
+	return 0;
+}
+
 static const struct eth_dev_ops txgbe_eth_dev_ops = {
 	.dev_configure              = txgbe_dev_configure,
 	.dev_infos_get              = txgbe_dev_info_get,
diff --git a/drivers/net/txgbe/txgbe_ethdev.h b/drivers/net/txgbe/txgbe_ethdev.h
index 4ba42a737..b4804ee1c 100644
--- a/drivers/net/txgbe/txgbe_ethdev.h
+++ b/drivers/net/txgbe/txgbe_ethdev.h
@@ -39,6 +39,9 @@
 
 #define TXGBE_MAX_QUEUE_NUM_PER_VF  8
 
+#define TXGBE_5TUPLE_MAX_PRI            7
+#define TXGBE_5TUPLE_MIN_PRI            1
+
 #define TXGBE_RSS_OFFLOAD_ALL ( \
 	ETH_RSS_IPV4 | \
 	ETH_RSS_NONFRAG_IPV4_TCP | \
@@ -311,6 +314,9 @@ int txgbe_dev_rss_hash_conf_get(struct rte_eth_dev *dev,
 
 bool txgbe_rss_update_sp(enum txgbe_mac_type mac_type);
 
+int txgbe_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter,
+			bool add);
 void txgbe_set_ivar_map(struct txgbe_hw *hw, int8_t direction,
 			       uint8_t queue, uint8_t msix_vector);
 
-- 
2.18.4




  parent reply	other threads:[~2020-11-11  6:48 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-11  6:48 [dpdk-dev] [PATCH v2 00/37] net: add txgbe PMD part 2 Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 01/37] net/txgbe: add ntuple filter init and uninit Jiawen Wu
2020-11-11  6:49 ` Jiawen Wu [this message]
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 03/37] net/txgbe: add ntuple parse rule Jiawen Wu
2020-11-11 16:06   ` Ferruh Yigit
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 04/37] net/txgbe: support ntuple filter remove operaion Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 05/37] net/txgbe: support ethertype filter add and delete Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 06/37] net/txgbe: add ethertype parse rule Jiawen Wu
2020-11-11 16:02   ` Ferruh Yigit
2020-11-11 16:04     ` Ferruh Yigit
2020-11-12  1:57       ` Wang, Haiyue
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 07/37] net/txgbe: support syn filter add and delete Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 08/37] net/txgbe: add syn filter parse rule Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 09/37] net/txgbe: add L2 tunnel filter init and uninit Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 10/37] net/txgbe: config L2 tunnel filter with e-tag Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 11/37] net/txgbe: support L2 tunnel filter add and delete Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 12/37] net/txgbe: add L2 tunnel filter parse rule Jiawen Wu
2020-11-11 16:10   ` Ferruh Yigit
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 13/37] net/txgbe: add FDIR filter init and uninit Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 14/37] net/txgbe: configure FDIR filter Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 15/37] net/txgbe: support FDIR add and delete operations Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 16/37] net/txgbe: add FDIR parse normal rule Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 17/37] net/txgbe: add FDIR parse tunnel rule Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 18/37] net/txgbe: add FDIR restore operation Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 19/37] net/txgbe: add RSS filter parse rule Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 20/37] net/txgbe: add RSS filter restore operation Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 21/37] net/txgbe: add filter list init and uninit Jiawen Wu
2020-11-11 16:10   ` Ferruh Yigit
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 22/37] net/txgbe: add generic flow API Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 23/37] net/txgbe: add flow API create function Jiawen Wu
2020-11-11 16:11   ` Ferruh Yigit
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 24/37] net/txgbe: add flow API destroy function Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 25/37] net/txgbe: add flow API flush function Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 26/37] net/txgbe: support UDP tunnel port add and delete Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 27/37] net/txgbe: add TM configuration init and uninit Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 28/37] net/txgbe: add TM capabilities get operation Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 29/37] net/txgbe: support TM shaper profile add and delete Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 30/37] net/txgbe: support TM node " Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 31/37] net/txgbe: add TM hierarchy commit Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 32/37] net/txgbe: add macsec setting Jiawen Wu
2020-11-11 16:13   ` Ferruh Yigit
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 33/37] net/txgbe: add IPsec context creation Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 34/37] net/txgbe: add security session create operation Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 35/37] net/txgbe: support security session destroy Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 36/37] net/txgbe: add security offload in Rx and Tx process Jiawen Wu
2020-11-11  6:49 ` [dpdk-dev] [PATCH v2 37/37] net/txgbe: add security type in flow action Jiawen Wu
2020-11-11 16:00 ` [dpdk-dev] [PATCH v2 00/37] net: add txgbe PMD part 2 Ferruh Yigit
2020-11-11 16:09   ` 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=20201111064936.768604-3-jiawenwu@trustnetic.com \
    --to=jiawenwu@trustnetic.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 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.