DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters
@ 2015-01-15  1:45 Jingjing Wu
  2015-01-15  1:45 ` [dpdk-dev] [PATCH 1/5] ethdev: define ntuple filter type and its structure Jingjing Wu
                   ` (6 more replies)
  0 siblings, 7 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-15  1:45 UTC (permalink / raw)
  To: dev

The patch set uses new filter_ctrl API to replace old 2tuple and 5tuple filter APIs.
It defines ntuple filter to combine 2tuple and 5tuple types. 
It uses new functions and structure to replace old ones in igb/ixgbe driver,
new commands to replace old ones in testpmd, and removes the old APIs.
It removes the filter's index parameters from user interface, only the
filter's key and assigned queue are visible to user.

Jingjing Wu (5):
  ethdev: define ntuple filter type and its structure
  ixgbe: ntuple filter functions replace old ones for 5tuple filter
  e1000: ntuple filter functions replace old ones for 2tuple and 5tuple
    filter
  testpmd: new commands for ntuple filter
  ethdev: remove old APIs and structures of 5tuple and 2tuple filters

 app/test-pmd/cmdline.c              | 406 ++++++++--------
 app/test-pmd/config.c               |  65 ---
 lib/librte_ether/rte_eth_ctrl.h     |  57 +++
 lib/librte_ether/rte_ethdev.c       | 116 -----
 lib/librte_ether/rte_ethdev.h       | 193 --------
 lib/librte_pmd_e1000/e1000_ethdev.h |  79 +++-
 lib/librte_pmd_e1000/igb_ethdev.c   | 892 +++++++++++++++++++++++++-----------
 lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 489 +++++++++++++++-----
 lib/librte_pmd_ixgbe/ixgbe_ethdev.h |  62 ++-
 9 files changed, 1344 insertions(+), 1015 deletions(-)

-- 
1.9.3

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

* [dpdk-dev] [PATCH 1/5] ethdev: define ntuple filter type and its structure
  2015-01-15  1:45 [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters Jingjing Wu
@ 2015-01-15  1:45 ` Jingjing Wu
  2015-01-15  1:45 ` [dpdk-dev] [PATCH 2/5] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-15  1:45 UTC (permalink / raw)
  To: dev

This patch defines ntuple filter type RTE_ETH_FILTER_NTUPLE and its structure rte_eth_ntuple_filter.
It also corrects the typo TCP_UGR_FLAG to TCP_URG_FLAG

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h | 50 +++++++++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h   |  2 ++
 2 files changed, 52 insertions(+)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 5d9c387..58d830d 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -53,6 +53,7 @@ enum rte_filter_type {
 	RTE_ETH_FILTER_NONE = 0,
 	RTE_ETH_FILTER_MACVLAN,
 	RTE_ETH_FILTER_ETHERTYPE,
+	RTE_ETH_FILTER_NTUPLE,
 	RTE_ETH_FILTER_TUNNEL,
 	RTE_ETH_FILTER_FDIR,
 	RTE_ETH_FILTER_MAX
@@ -117,6 +118,55 @@ struct rte_eth_ethertype_filter {
 };
 
 /**
+ * Define all structures for ntuple Filter type.
+ */
+
+#define RTE_NTUPLE_FLAGS_DST_IP    0x0001 /**< If set, dst_ip is part of ntuple */
+#define RTE_NTUPLE_FLAGS_SRC_IP    0x0002 /**< If set, src_ip is part of ntuple */
+#define RTE_NTUPLE_FLAGS_DST_PORT  0x0004 /**< If set, dst_port is part of ntuple */
+#define RTE_NTUPLE_FLAGS_SRC_PORT  0x0008 /**< If set, src_port is part of ntuple */
+#define RTE_NTUPLE_FLAGS_PROTO     0x0010 /**< If set, protocol is part of ntuple */
+#define RTE_NTUPLE_FLAGS_TCP_FLAG  0x0020 /**< If set, tcp flag is involved */
+
+#define RTE_5TUPLE_FLAGS ( \
+		RTE_NTUPLE_FLAGS_DST_IP | \
+		RTE_NTUPLE_FLAGS_SRC_IP | \
+		RTE_NTUPLE_FLAGS_DST_PORT | \
+		RTE_NTUPLE_FLAGS_SRC_PORT | \
+		RTE_NTUPLE_FLAGS_PROTO)
+
+#define RTE_2TUPLE_FLAGS ( \
+		RTE_NTUPLE_FLAGS_DST_PORT | \
+		RTE_NTUPLE_FLAGS_PROTO)
+
+
+/**
+ * A structure used to define the ntuple filter entry
+ * to support RTE_ETH_FILTER_NTUPLE with RTE_ETH_FILTER_ADD,
+ * RTE_ETH_FILTER_DELETE and RTE_ETH_FILTER_GET operations.
+ */
+struct rte_eth_ntuple_filter {
+	uint16_t flags;          /**< Flags from RTE_NTUPLE_FLAGS_* */
+	uint32_t dst_ip;         /**< Destination IP address in big endian. */
+	uint32_t dst_ip_mask;    /**< Mask of destination IP address. */
+	uint32_t src_ip;         /**< Source IP address in big endian. */
+	uint32_t src_ip_mask;    /**< Mask of destination IP address. */
+	uint16_t dst_port;       /**< Destination port in big endian. */
+	uint16_t dst_port_mask;  /**< Mask of destination port. */
+	uint16_t src_port;       /**< Source Port in big endian. */
+	uint16_t src_port_mask;  /**< Mask of source port. */
+	uint8_t proto;           /**< L4 protocol. */
+	uint8_t proto_mask;      /**< Mask of L4 protocol. */
+	/** tcp_flags only meaningful when the proto is TCP.
+	    The packet matched above ntuple fields and contain
+	    any set bit in tcp_flags will hit this filter. */
+	uint8_t tcp_flags;
+	uint16_t priority;       /**< seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint16_t queue;          /**< Queue assigned to when match*/
+};
+
+/**
  * Tunneled type.
  */
 enum rte_eth_tunnel_type {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index ce0528f..551b28f 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -963,6 +963,8 @@ struct rte_eth_dev_callback;
 /** @internal Structure to keep track of registered callbacks */
 TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 
+
+#define TCP_URG_FLAG 0x20
 #define TCP_UGR_FLAG 0x20
 #define TCP_ACK_FLAG 0x10
 #define TCP_PSH_FLAG 0x08
-- 
1.9.3

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

* [dpdk-dev] [PATCH 2/5] ixgbe: ntuple filter functions replace old ones for 5tuple filter
  2015-01-15  1:45 [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters Jingjing Wu
  2015-01-15  1:45 ` [dpdk-dev] [PATCH 1/5] ethdev: define ntuple filter type and its structure Jingjing Wu
@ 2015-01-15  1:45 ` Jingjing Wu
  2015-01-15  1:45 ` [dpdk-dev] [PATCH 3/5] e1000: ntuple filter functions replace old ones for 2tuple and " Jingjing Wu
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-15  1:45 UTC (permalink / raw)
  To: dev

This patch defines new functions dealing with ntuple filters which is
corresponding to 5tuple in HW.
It removes old functions which deal with 5tuple filters.
It also defines ixgbe_dev_filter_ctrl which is binding to filter_ctrl API,
and ntuple filter can be dealt with through this new entrance.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 489 +++++++++++++++++++++++++++---------
 lib/librte_pmd_ixgbe/ixgbe_ethdev.h |  62 ++++-
 2 files changed, 421 insertions(+), 130 deletions(-)

diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
index 3fc3738..02a6be1 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
@@ -237,13 +237,22 @@ static int ixgbe_remove_ethertype_filter(struct rte_eth_dev *dev,
 			uint16_t index);
 static int ixgbe_get_ethertype_filter(struct rte_eth_dev *dev, uint16_t index,
 			struct rte_ethertype_filter *filter, uint16_t *rx_queue);
-static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue);
-static int ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index);
-static int ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue);
-
+static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev,
+			struct ixgbe_5tuple_filter *filter);
+static void ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
+			struct ixgbe_5tuple_filter *filter);
+static int ixgbe_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter,
+			bool add);
+static int ixgbe_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg);
+static int ixgbe_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter);
+static int ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,
+		     enum rte_filter_type filter_type,
+		     enum rte_filter_op filter_op,
+		     void *arg);
 static int ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
 
 /*
@@ -383,9 +392,7 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.add_ethertype_filter    = ixgbe_add_ethertype_filter,
 	.remove_ethertype_filter = ixgbe_remove_ethertype_filter,
 	.get_ethertype_filter    = ixgbe_get_ethertype_filter,
-	.add_5tuple_filter       = ixgbe_add_5tuple_filter,
-	.remove_5tuple_filter    = ixgbe_remove_5tuple_filter,
-	.get_5tuple_filter       = ixgbe_get_5tuple_filter,
+	.filter_ctrl             = ixgbe_dev_filter_ctrl,
 };
 
 /*
@@ -732,6 +739,8 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 		IXGBE_DEV_PRIVATE_TO_HWSTRIP_BITMAP(eth_dev->data->dev_private);
 	struct ixgbe_dcb_config *dcb_config =
 		IXGBE_DEV_PRIVATE_TO_DCB_CFG(eth_dev->data->dev_private);
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
 	uint32_t ctrl_ext;
 	uint16_t csum;
 	int diag, i;
@@ -913,6 +922,11 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 	/* enable support intr */
 	ixgbe_enable_intr(eth_dev);
 
+	/* initialize 5tuple filter list */
+	TAILQ_INIT(&filter_info->fivetuple_list);
+	memset(filter_info->fivetuple_mask, 0,
+		sizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);
+
 	return 0;
 }
 
@@ -1602,6 +1616,9 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ixgbe_vf_info *vfinfo =
 		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct ixgbe_5tuple_filter *p_5tuple, *p_5tuple_next;
 	int vf;
 
 	PMD_INIT_FUNC_TRACE();
@@ -1631,6 +1648,18 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
 	/* Clear recorded link status */
 	memset(&link, 0, sizeof(link));
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
+
+	/* Remove all ntuple filters of the device */
+	for (p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list);
+	     p_5tuple != NULL; p_5tuple = p_5tuple_next) {
+		p_5tuple_next = TAILQ_NEXT(p_5tuple, entries);
+		TAILQ_REMOVE(&filter_info->fivetuple_list,
+			     p_5tuple, entries);
+		rte_free(p_5tuple);
+	}
+	memset(filter_info->fivetuple_mask, 0,
+		sizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);
+
 }
 
 /*
@@ -3933,62 +3962,69 @@ revert_protocol_type(enum ixgbe_5tuple_protocol protocol)
  *    - On failure, a negative value.
  */
 static int
-ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue)
+ixgbe_add_5tuple_filter(struct rte_eth_dev *dev,
+			struct ixgbe_5tuple_filter *filter)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t ftqf, sdpqf = 0;
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	int i, idx, shift;
+	uint32_t ftqf, sdpqf;
 	uint32_t l34timir = 0;
 	uint8_t mask = 0xff;
 
-	if (hw->mac.type != ixgbe_mac_82599EB)
+	/*
+	 * look for an unused 5tuple filter index,
+	 * and insert the filter to list.
+	 */
+	for (i = 0; i < IXGBE_MAX_FTQF_FILTERS; i++) {
+		idx = i / UINT32_BIT;
+		shift = i % UINT32_BIT;
+		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 >= IXGBE_MAX_FTQF_FILTERS) {
+		PMD_DRV_LOG(ERR, "5tuple filters are full.");
 		return -ENOSYS;
-
-	if (index >= IXGBE_MAX_FTQF_FILTERS ||
-		rx_queue >= IXGBE_MAX_RX_QUEUE_NUM ||
-		filter->priority > IXGBE_5TUPLE_MAX_PRI ||
-		filter->priority < IXGBE_5TUPLE_MIN_PRI)
-		return -EINVAL;  /* filter index is out of range. */
-
-	if (filter->tcp_flags) {
-		PMD_INIT_LOG(INFO, "82599EB not tcp flags in 5tuple");
-		return -EINVAL;
 	}
 
-	ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index));
-	if (ftqf & IXGBE_FTQF_QUEUE_ENABLE)
-		return -EINVAL;  /* filter index is in use. */
+	sdpqf = (uint32_t)(filter->filter_info.dst_port <<
+				IXGBE_SDPQF_DSTPORT_SHIFT);
+	sdpqf = sdpqf | (filter->filter_info.src_port & IXGBE_SDPQF_SRCPORT);
 
-	ftqf = 0;
-	sdpqf = (uint32_t)(filter->dst_port << IXGBE_SDPQF_DSTPORT_SHIFT);
-	sdpqf = sdpqf | (filter->src_port & IXGBE_SDPQF_SRCPORT);
-
-	ftqf |= (uint32_t)(convert_protocol_type(filter->protocol) &
+	ftqf = (uint32_t)(filter->filter_info.proto &
 		IXGBE_FTQF_PROTOCOL_MASK);
-	ftqf |= (uint32_t)((filter->priority & IXGBE_FTQF_PRIORITY_MASK) <<
-		IXGBE_FTQF_PRIORITY_SHIFT);
-	if (filter->src_ip_mask == 0) /* 0 means compare. */
+	ftqf |= (uint32_t)((filter->filter_info.priority &
+		IXGBE_FTQF_PRIORITY_MASK) << IXGBE_FTQF_PRIORITY_SHIFT);
+	if (filter->filter_info.src_ip_mask == 0) /* 0 means compare. */
 		mask &= IXGBE_FTQF_SOURCE_ADDR_MASK;
-	if (filter->dst_ip_mask == 0)
+	if (filter->filter_info.dst_ip_mask == 0)
 		mask &= IXGBE_FTQF_DEST_ADDR_MASK;
-	if (filter->src_port_mask == 0)
+	if (filter->filter_info.src_port_mask == 0)
 		mask &= IXGBE_FTQF_SOURCE_PORT_MASK;
-	if (filter->dst_port_mask == 0)
+	if (filter->filter_info.dst_port_mask == 0)
 		mask &= IXGBE_FTQF_DEST_PORT_MASK;
-	if (filter->protocol_mask == 0)
+	if (filter->filter_info.proto_mask == 0)
 		mask &= IXGBE_FTQF_PROTOCOL_COMP_MASK;
 	ftqf |= mask << IXGBE_FTQF_5TUPLE_MASK_SHIFT;
 	ftqf |= IXGBE_FTQF_POOL_MASK_EN;
 	ftqf |= IXGBE_FTQF_QUEUE_ENABLE;
 
-	IXGBE_WRITE_REG(hw, IXGBE_DAQF(index), filter->dst_ip);
-	IXGBE_WRITE_REG(hw, IXGBE_SAQF(index), filter->src_ip);
-	IXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), sdpqf);
-	IXGBE_WRITE_REG(hw, IXGBE_FTQF(index), ftqf);
+	IXGBE_WRITE_REG(hw, IXGBE_DAQF(idx), filter->filter_info.dst_ip);
+	IXGBE_WRITE_REG(hw, IXGBE_SAQF(idx), filter->filter_info.src_ip);
+	IXGBE_WRITE_REG(hw, IXGBE_SDPQF(idx), sdpqf);
+	IXGBE_WRITE_REG(hw, IXGBE_FTQF(idx), ftqf);
 
 	l34timir |= IXGBE_L34T_IMIR_RESERVE;
-	l34timir |= (uint32_t)(rx_queue << IXGBE_L34T_IMIR_QUEUE_SHIFT);
-	IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), l34timir);
+	l34timir |= (uint32_t)(filter->queue <<
+				IXGBE_L34T_IMIR_QUEUE_SHIFT);
+	IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(i), l34timir);
 	return 0;
 }
 
@@ -3997,92 +4033,27 @@ ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
+ * filter: the pointer of the filter will be removed.
  */
-static int
+static void
 ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index)
+			struct ixgbe_5tuple_filter *filter)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	uint16_t index = filter->index;
 
-	if (hw->mac.type != ixgbe_mac_82599EB)
-		return -ENOSYS;
-
-	if (index >= IXGBE_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	filter_info->fivetuple_mask[index / UINT32_BIT] &=
+					~(1 << (index % UINT32_BIT));
+	TAILQ_REMOVE(&filter_info->fivetuple_list, filter, entries);
+	rte_free(filter);
 
 	IXGBE_WRITE_REG(hw, IXGBE_DAQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_SAQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_FTQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), 0);
-	return 0;
-}
-
-/*
- * get a 5tuple filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates
- * filter: ponter to the filter that returns.
- * *rx_queue: pointer of the queue id the filter assigned to.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
- */
-static int
-ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue)
-{
-	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t sdpqf, ftqf, l34timir;
-	uint8_t mask;
-	enum ixgbe_5tuple_protocol proto;
-
-	if (hw->mac.type != ixgbe_mac_82599EB)
-		return -ENOSYS;
-
-	if (index >= IXGBE_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
-
-	ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index));
-	if (ftqf & IXGBE_FTQF_QUEUE_ENABLE) {
-		proto = (enum ixgbe_5tuple_protocol)(ftqf & IXGBE_FTQF_PROTOCOL_MASK);
-		filter->protocol = revert_protocol_type(proto);
-		filter->priority = (ftqf >> IXGBE_FTQF_PRIORITY_SHIFT) &
-					IXGBE_FTQF_PRIORITY_MASK;
-		mask = (uint8_t)((ftqf >> IXGBE_FTQF_5TUPLE_MASK_SHIFT) &
-					IXGBE_FTQF_5TUPLE_MASK_MASK);
-		filter->src_ip_mask =
-			(mask & IXGBE_FTQF_SOURCE_ADDR_MASK) ? 1 : 0;
-		filter->dst_ip_mask =
-			(mask & IXGBE_FTQF_DEST_ADDR_MASK) ? 1 : 0;
-		filter->src_port_mask =
-			(mask & IXGBE_FTQF_SOURCE_PORT_MASK) ? 1 : 0;
-		filter->dst_port_mask =
-			(mask & IXGBE_FTQF_DEST_PORT_MASK) ? 1 : 0;
-		filter->protocol_mask =
-			(mask & IXGBE_FTQF_PROTOCOL_COMP_MASK) ? 1 : 0;
-
-		sdpqf = IXGBE_READ_REG(hw, IXGBE_SDPQF(index));
-		filter->dst_port = (sdpqf & IXGBE_SDPQF_DSTPORT) >>
-					IXGBE_SDPQF_DSTPORT_SHIFT;
-		filter->src_port = sdpqf & IXGBE_SDPQF_SRCPORT;
-		filter->dst_ip = IXGBE_READ_REG(hw, IXGBE_DAQF(index));
-		filter->src_ip = IXGBE_READ_REG(hw, IXGBE_SAQF(index));
-
-		l34timir = IXGBE_READ_REG(hw, IXGBE_L34T_IMIR(index));
-		*rx_queue = (l34timir & IXGBE_L34T_IMIR_QUEUE) >>
-					IXGBE_L34T_IMIR_QUEUE_SHIFT;
-		return 0;
-	}
-	return -ENOENT;
 }
 
 static int
@@ -4119,6 +4090,284 @@ ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+#define MAC_TYPE_FILTER_SUP(type)    do {\
+	if ((type) != ixgbe_mac_82599EB && (type) != ixgbe_mac_X540)\
+		return -ENOTSUP;\
+} while (0)
+
+static inline struct ixgbe_5tuple_filter *
+ixgbe_5tuple_filter_lookup(struct ixgbe_5tuple_filter_list *filter_list,
+			struct ixgbe_5tuple_filter_info *key)
+{
+	struct ixgbe_5tuple_filter *it;
+
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct ixgbe_5tuple_filter_info)) == 0) {
+			return it;
+		}
+	}
+	return NULL;
+}
+
+/* translate elements in struct rte_eth_ntuple_filter to struct ixgbe_5tuple_filter_info*/
+static inline int
+ntuple_filter_to_5tuple(struct rte_eth_ntuple_filter *filter,
+			struct ixgbe_5tuple_filter_info *filter_info)
+{
+	if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM ||
+		filter->priority > IXGBE_5TUPLE_MAX_PRI ||
+		filter->priority < IXGBE_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.
+ */
+static int
+ixgbe_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter,
+			bool add)
+{
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct ixgbe_5tuple_filter_info filter_5tuple;
+	struct ixgbe_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 ixgbe_5tuple_filter_info));
+	ret = ntuple_filter_to_5tuple(ntuple_filter, &filter_5tuple);
+	if (ret < 0)
+		return ret;
+
+	filter = ixgbe_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("ixgbe_5tuple_filter",
+				sizeof(struct ixgbe_5tuple_filter), 0);
+		if (filter == NULL)
+			return -ENOMEM;
+		(void)rte_memcpy(&filter->filter_info,
+				 &filter_5tuple,
+				 sizeof(struct ixgbe_5tuple_filter_info));
+		filter->queue = ntuple_filter->queue;
+		ret = ixgbe_add_5tuple_filter(dev, filter);
+		if (ret < 0) {
+			rte_free(filter);
+			return ret;
+		}
+	} else
+		ixgbe_remove_5tuple_filter(dev, filter);
+
+	return 0;
+}
+
+/*
+ * get a ntuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * ntuple_filter: Pointer to struct rte_eth_ntuple_filter
+ *
+ * @return
+ *    - On success, zero.
+ *    - On failure, a negative value.
+ */
+static int
+ixgbe_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
+{
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct ixgbe_5tuple_filter_info filter_5tuple;
+	struct ixgbe_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 ixgbe_5tuple_filter_info));
+	ret = ntuple_filter_to_5tuple(ntuple_filter, &filter_5tuple);
+	if (ret < 0)
+		return ret;
+
+	filter = ixgbe_5tuple_filter_lookup(&filter_info->fivetuple_list,
+					 &filter_5tuple);
+	if (filter == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
+	}
+	ntuple_filter->queue = filter->queue;
+	return 0;
+}
+
+/*
+ * ixgbe_ntuple_filter_handle - Handle operations for ntuple filter.
+ * @dev: pointer to rte_eth_dev structure
+ * @filter_op:operation will be taken.
+ * @arg: a pointer to specific structure corresponding to the filter_op
+ *
+ * @return
+ *    - On success, zero.
+ *    - On failure, a negative value.
+ */
+static int
+ixgbe_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg)
+{
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
+
+	MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+	if (filter_op == RTE_ETH_FILTER_NOP)
+		return 0;
+
+	if (arg == NULL) {
+		PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
+			    filter_op);
+		return -EINVAL;
+	}
+
+	switch (filter_op) {
+	case RTE_ETH_FILTER_ADD:
+		ret = ixgbe_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			TRUE);
+		break;
+	case RTE_ETH_FILTER_DELETE:
+		ret = ixgbe_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			FALSE);
+		break;
+	case RTE_ETH_FILTER_GET:
+		ret = ixgbe_get_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,
+		     enum rte_filter_type filter_type,
+		     enum rte_filter_op filter_op,
+		     void *arg)
+{
+	int ret = -EINVAL;
+
+	switch (filter_type) {
+	case RTE_ETH_FILTER_NTUPLE:
+		ret = ixgbe_ntuple_filter_handle(dev, filter_op, arg);
+		break;
+	default:
+		PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
+							filter_type);
+		break;
+	}
+
+	return ret;
+}
+
 static struct rte_driver rte_ixgbe_driver = {
 	.type = PMD_PDEV,
 	.init = rte_ixgbe_pmd_init,
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
index ca99170..69f0326 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
@@ -162,6 +162,54 @@ struct ixgbe_vf_info {
 };
 
 /*
+ *  Possible l4type of 5tuple filters.
+ */
+enum ixgbe_5tuple_protocol {
+	IXGBE_FILTER_PROTOCOL_TCP = 0,
+	IXGBE_FILTER_PROTOCOL_UDP,
+	IXGBE_FILTER_PROTOCOL_SCTP,
+	IXGBE_FILTER_PROTOCOL_NONE,
+};
+
+TAILQ_HEAD(ixgbe_5tuple_filter_list, ixgbe_5tuple_filter);
+
+struct ixgbe_5tuple_filter_info {
+	uint32_t dst_ip;
+	uint32_t src_ip;
+	uint16_t dst_port;
+	uint16_t src_port;
+	enum ixgbe_5tuple_protocol proto;        /* l4 protocol. */
+	uint8_t priority;        /* seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint8_t dst_ip_mask:1,   /* if mask is 1b, do not compare dst ip. */
+		src_ip_mask:1,   /* if mask is 1b, do not compare src ip. */
+		dst_port_mask:1, /* if mask is 1b, do not compare dst port. */
+		src_port_mask:1, /* if mask is 1b, do not compare src port. */
+		proto_mask:1;    /* if mask is 1b, do not compare protocol. */
+};
+
+/* 5tuple filter structure */
+struct ixgbe_5tuple_filter {
+	TAILQ_ENTRY(ixgbe_5tuple_filter) entries;
+	uint16_t index;       /* the index of 5tuple filter */
+	struct ixgbe_5tuple_filter_info filter_info;
+	uint16_t queue;       /* rx queue assigned to */
+};
+
+#define UINT32_BIT 32
+#define IXGBE_5TUPLE_ARRAY_SIZE \
+	(RTE_ALIGN(IXGBE_MAX_FTQF_FILTERS, UINT32_BIT) / (UINT32_BIT))
+
+/*
+ * Structure to store filters' info.
+ */
+struct ixgbe_filter_info {
+	/* Bit mask for every used 5tuple filter */
+	uint32_t fivetuple_mask[IXGBE_5TUPLE_ARRAY_SIZE];
+	struct ixgbe_5tuple_filter_list fivetuple_list;
+};
+
+/*
  * Structure to store private data for each driver instance (for each port).
  */
 struct ixgbe_adapter {
@@ -179,16 +227,7 @@ struct ixgbe_adapter {
 #ifdef RTE_NIC_BYPASS
 	struct ixgbe_bypass_info    bps;
 #endif /* RTE_NIC_BYPASS */
-};
-
-/*
- *  Possible l4type of 5tuple filters.
- */
-enum ixgbe_5tuple_protocol {
-	IXGBE_FILTER_PROTOCOL_TCP = 0,
-	IXGBE_FILTER_PROTOCOL_UDP,
-	IXGBE_FILTER_PROTOCOL_SCTP,
-	IXGBE_FILTER_PROTOCOL_NONE,
+	struct ixgbe_filter_info    filter;
 };
 
 #define IXGBE_DEV_PRIVATE_TO_HW(adapter)\
@@ -224,6 +263,9 @@ enum ixgbe_5tuple_protocol {
 #define IXGBE_DEV_PRIVATE_TO_UTA(adapter) \
 	(&((struct ixgbe_adapter *)adapter)->uta_info)
 
+#define IXGBE_DEV_PRIVATE_TO_FILTER_INFO(adapter) \
+	(&((struct ixgbe_adapter *)adapter)->filter)
+
 /*
  * RX/TX function prototypes
  */
-- 
1.9.3

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

* [dpdk-dev] [PATCH 3/5] e1000: ntuple filter functions replace old ones for 2tuple and 5tuple filter
  2015-01-15  1:45 [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters Jingjing Wu
  2015-01-15  1:45 ` [dpdk-dev] [PATCH 1/5] ethdev: define ntuple filter type and its structure Jingjing Wu
  2015-01-15  1:45 ` [dpdk-dev] [PATCH 2/5] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
@ 2015-01-15  1:45 ` Jingjing Wu
  2015-01-15  1:46 ` [dpdk-dev] [PATCH 4/5] testpmd: new commands for ntuple filter Jingjing Wu
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-15  1:45 UTC (permalink / raw)
  To: dev

This patch defines new functions dealing with ntuple filters which is
corresponding to 2tuple filter for 82580 and i350 in HW, and to 5tuple
filter for 82576 in HW.
It removes old functions which deal with 2tuple and 5tuple filters in igb driver.
It also defines eth_igb_filter_ctrl which is binding to filter_ctrl API,
and ntuple filter can be dealt with through this new entrance.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_pmd_e1000/e1000_ethdev.h |  79 +++-
 lib/librte_pmd_e1000/igb_ethdev.c   | 892 +++++++++++++++++++++++++-----------
 2 files changed, 680 insertions(+), 291 deletions(-)

diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h
index 71eb5fb..2433759 100644
--- a/lib/librte_pmd_e1000/e1000_ethdev.h
+++ b/lib/librte_pmd_e1000/e1000_ethdev.h
@@ -67,14 +67,6 @@
 
 #define E1000_IMIR_DSTPORT             0x0000FFFF
 #define E1000_IMIR_PRIORITY            0xE0000000
-#define E1000_IMIR_EXT_SIZE_BP         0x00001000
-#define E1000_IMIR_EXT_CTRL_UGR        0x00002000
-#define E1000_IMIR_EXT_CTRL_ACK        0x00004000
-#define E1000_IMIR_EXT_CTRL_PSH        0x00008000
-#define E1000_IMIR_EXT_CTRL_RST        0x00010000
-#define E1000_IMIR_EXT_CTRL_SYN        0x00020000
-#define E1000_IMIR_EXT_CTRL_FIN        0x00040000
-#define E1000_IMIR_EXT_CTRL_BP         0x00080000
 #define E1000_MAX_TTQF_FILTERS         8
 #define E1000_2TUPLE_MAX_PRI           7
 
@@ -96,11 +88,6 @@
 #define E1000_MAX_FTQF_FILTERS           8
 #define E1000_FTQF_PROTOCOL_MASK         0x000000FF
 #define E1000_FTQF_5TUPLE_MASK_SHIFT     28
-#define E1000_FTQF_PROTOCOL_COMP_MASK    0x10000000
-#define E1000_FTQF_SOURCE_ADDR_MASK      0x20000000
-#define E1000_FTQF_DEST_ADDR_MASK        0x40000000
-#define E1000_FTQF_SOURCE_PORT_MASK      0x80000000
-#define E1000_FTQF_VF_MASK_EN            0x00008000
 #define E1000_FTQF_QUEUE_MASK            0x03ff0000
 #define E1000_FTQF_QUEUE_SHIFT           16
 #define E1000_FTQF_QUEUE_ENABLE          0x00000100
@@ -131,6 +118,68 @@ struct e1000_vf_info {
 	uint16_t tx_rate;
 };
 
+TAILQ_HEAD(e1000_5tuple_filter_list, e1000_5tuple_filter);
+TAILQ_HEAD(e1000_2tuple_filter_list, e1000_2tuple_filter);
+
+struct e1000_5tuple_filter_info {
+	uint32_t dst_ip;
+	uint32_t src_ip;
+	uint16_t dst_port;
+	uint16_t src_port;
+	uint8_t proto;           /* l4 protocol. */
+	/* the packet matched above 5tuple and contain any set bit will hit this filter. */
+	uint8_t tcp_flags;
+	uint8_t priority;        /* seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint8_t dst_ip_mask:1,   /* if mask is 1b, do not compare dst ip. */
+		src_ip_mask:1,   /* if mask is 1b, do not compare src ip. */
+		dst_port_mask:1, /* if mask is 1b, do not compare dst port. */
+		src_port_mask:1, /* if mask is 1b, do not compare src port. */
+		proto_mask:1;    /* if mask is 1b, do not compare protocol. */
+};
+
+struct e1000_2tuple_filter_info {
+	uint16_t dst_port;
+	uint8_t proto;           /* l4 protocol. */
+	/* the packet matched above 2tuple and contain any set bit will hit this filter. */
+	uint8_t tcp_flags;
+	uint8_t priority;        /* seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint8_t dst_ip_mask:1,   /* if mask is 1b, do not compare dst ip. */
+		src_ip_mask:1,   /* if mask is 1b, do not compare src ip. */
+		dst_port_mask:1, /* if mask is 1b, do not compare dst port. */
+		src_port_mask:1, /* if mask is 1b, do not compare src port. */
+		proto_mask:1;    /* if mask is 1b, do not compare protocol. */
+};
+
+/* 5tuple filter structure */
+struct e1000_5tuple_filter {
+	TAILQ_ENTRY(e1000_5tuple_filter) entries;
+	uint16_t index;       /* the index of 5tuple filter */
+	struct e1000_5tuple_filter_info filter_info;
+	uint16_t queue;       /* rx queue assigned to */
+};
+
+/* 2tuple filter structure */
+struct e1000_2tuple_filter {
+	TAILQ_ENTRY(e1000_2tuple_filter) entries;
+	uint16_t index;         /* the index of 2tuple filter */
+	struct e1000_2tuple_filter_info filter_info;
+	uint16_t queue;       /* rx queue assigned to */
+};
+
+/*
+ * Structure to store filters' info.
+ */
+struct e1000_filter_info {
+	/* Bit mask for every used 5tuple filter */
+	uint8_t fivetuple_mask;
+	struct e1000_5tuple_filter_list fivetuple_list;
+	/* Bit mask for every used 2tuple filter */
+	uint8_t twotuple_mask;
+	struct e1000_2tuple_filter_list twotuple_list;
+};
+
 /*
  * Structure to store private data for each driver instance (for each port).
  */
@@ -140,6 +189,7 @@ struct e1000_adapter {
 	struct e1000_interrupt  intr;
 	struct e1000_vfta       shadow_vfta;
 	struct e1000_vf_info    *vfdata;
+	struct e1000_filter_info filter;
 };
 
 #define E1000_DEV_PRIVATE_TO_HW(adapter) \
@@ -157,6 +207,9 @@ struct e1000_adapter {
 #define E1000_DEV_PRIVATE_TO_P_VFDATA(adapter) \
         (&((struct e1000_adapter *)adapter)->vfdata)
 
+#define E1000_DEV_PRIVATE_TO_FILTER_INFO(adapter) \
+	(&((struct e1000_adapter *)adapter)->filter)
+
 /*
  * RX/TX IGB function prototypes
  */
diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c
index 873d65e..551283e 100644
--- a/lib/librte_pmd_e1000/igb_ethdev.c
+++ b/lib/librte_pmd_e1000/igb_ethdev.c
@@ -162,14 +162,10 @@ static int eth_igb_remove_ethertype_filter(struct rte_eth_dev *dev,
 static int eth_igb_get_ethertype_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_ethertype_filter *filter, uint16_t *rx_queue);
-static int eth_igb_add_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue);
-static int eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index);
-static int eth_igb_get_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue);
+static int igb_add_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_remove_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
 static int eth_igb_add_flex_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_flex_filter *filter, uint16_t rx_queue);
@@ -178,14 +174,22 @@ static int eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
 static int eth_igb_get_flex_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_flex_filter *filter, uint16_t *rx_queue);
-static int eth_igb_add_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue);
-static int eth_igb_remove_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index);
-static int eth_igb_get_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue);
+static int igb_add_5tuple_filter_82576(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_remove_5tuple_filter_82576(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter,
+			bool add);
+static int igb_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter);
+static int igb_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg);
+static int eth_igb_filter_ctrl(struct rte_eth_dev *dev,
+		     enum rte_filter_type filter_type,
+		     enum rte_filter_op filter_op,
+		     void *arg);
 
 /*
  * Define VF Stats MACRO for Non "cleared on read" register
@@ -267,15 +271,10 @@ static struct eth_dev_ops eth_igb_ops = {
 	.add_ethertype_filter    = eth_igb_add_ethertype_filter,
 	.remove_ethertype_filter = eth_igb_remove_ethertype_filter,
 	.get_ethertype_filter    = eth_igb_get_ethertype_filter,
-	.add_2tuple_filter       = eth_igb_add_2tuple_filter,
-	.remove_2tuple_filter    = eth_igb_remove_2tuple_filter,
-	.get_2tuple_filter       = eth_igb_get_2tuple_filter,
 	.add_flex_filter         = eth_igb_add_flex_filter,
 	.remove_flex_filter      = eth_igb_remove_flex_filter,
 	.get_flex_filter         = eth_igb_get_flex_filter,
-	.add_5tuple_filter       = eth_igb_add_5tuple_filter,
-	.remove_5tuple_filter    = eth_igb_remove_5tuple_filter,
-	.get_5tuple_filter       = eth_igb_get_5tuple_filter,
+	.filter_ctrl             = eth_igb_filter_ctrl,
 };
 
 /*
@@ -468,6 +467,8 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 		E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
 	struct e1000_vfta * shadow_vfta =
 			E1000_DEV_PRIVATE_TO_VFTA(eth_dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
 	uint32_t ctrl_ext;
 
 	pci_dev = eth_dev->pci_dev;
@@ -599,6 +600,12 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 	/* enable support intr */
 	igb_intr_enable(eth_dev);
 
+	/* initialize ntuple filter list */
+	TAILQ_INIT(&filter_info->twotuple_list);
+	filter_info->twotuple_mask = 0;
+	TAILQ_INIT(&filter_info->fivetuple_list);
+	filter_info->fivetuple_mask = 0;
+
 	return 0;
 
 err_late:
@@ -924,7 +931,11 @@ static void
 eth_igb_stop(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 	struct rte_eth_link link;
+	struct e1000_5tuple_filter *p_5tuple, *p_5tuple_next;
+	struct e1000_2tuple_filter *p_2tuple, *p_2tuple_next;
 
 	igb_intr_disable(hw);
 	igb_pf_reset_hw(hw);
@@ -947,6 +958,24 @@ eth_igb_stop(struct rte_eth_dev *dev)
 	/* clear the recorded link status */
 	memset(&link, 0, sizeof(link));
 	rte_igb_dev_atomic_write_link_status(dev, &link);
+
+	/* Remove all ntuple filters of the device */
+	for (p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list);
+	     p_5tuple != NULL; p_5tuple = p_5tuple_next) {
+		p_5tuple_next = TAILQ_NEXT(p_5tuple, entries);
+		TAILQ_REMOVE(&filter_info->fivetuple_list,
+			     p_5tuple, entries);
+		rte_free(p_5tuple);
+	}
+	filter_info->fivetuple_mask = 0;
+	for (p_2tuple = TAILQ_FIRST(&filter_info->twotuple_list);
+	     p_2tuple != NULL; p_2tuple = p_2tuple_next) {
+		p_2tuple_next = TAILQ_NEXT(p_2tuple, entries);
+		TAILQ_REMOVE(&filter_info->twotuple_list,
+			     p_2tuple, entries);
+		rte_free(p_2tuple);
+	}
+	filter_info->twotuple_mask = 0;
 }
 
 static void
@@ -2388,7 +2417,7 @@ eth_igb_rss_reta_query(struct rte_eth_dev *dev,
 #define MAC_TYPE_FILTER_SUP(type)    do {\
 	if ((type) != e1000_82580 && (type) != e1000_i350 &&\
 		(type) != e1000_82576)\
-		return -ENOSYS;\
+		return -ENOTSUP;\
 } while (0)
 
 /*
@@ -2595,165 +2624,209 @@ eth_igb_get_ethertype_filter(struct rte_eth_dev *dev, uint16_t index,
 		return -ENOSYS; \
 } while (0)
 
-/*
- * add a 2tuple 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
-eth_igb_add_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue)
+/* translate elements in struct rte_eth_ntuple_filter to struct e1000_2tuple_filter_info*/
+static inline int
+ntuple_filter_to_2tuple(struct rte_eth_ntuple_filter *filter,
+			struct e1000_2tuple_filter_info *filter_info)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t ttqf, imir = 0;
-	uint32_t imir_ext = 0;
-
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
-
-	if (index >= E1000_MAX_TTQF_FILTERS ||
-		rx_queue >= IGB_MAX_RX_QUEUE_NUM ||
-		filter->priority > E1000_2TUPLE_MAX_PRI)
+	if (filter->queue >= IGB_MAX_RX_QUEUE_NUM)
+		return -EINVAL;
+	if (filter->priority > E1000_2TUPLE_MAX_PRI)
 		return -EINVAL;  /* filter index is out of range. */
-	if  (filter->tcp_flags > TCP_FLAG_ALL)
+	if (filter->tcp_flags > TCP_FLAG_ALL)
 		return -EINVAL;  /* flags is invalid. */
 
-	ttqf = E1000_READ_REG(hw, E1000_TTQF(index));
-	if (ttqf & E1000_TTQF_QUEUE_ENABLE)
-		return -EINVAL;  /* filter index is in use. */
-
-	imir = (uint32_t)(filter->dst_port & E1000_IMIR_DSTPORT);
-	if (filter->dst_port_mask == 1) /* 1b means not compare. */
-		imir |= E1000_IMIR_PORT_BP;
-	else
-		imir &= ~E1000_IMIR_PORT_BP;
+	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;
+	}
 
-	imir |= filter->priority << E1000_IMIR_PRIORITY_SHIFT;
+	switch (filter->proto_mask) {
+	case UINT8_MAX:
+		filter_info->proto_mask = 0;
+		filter_info->proto = filter->proto;
+		break;
+	case 0:
+		filter_info->proto_mask = 1;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid protocol mask.");
+		return -EINVAL;
+	}
 
-	ttqf = 0;
-	ttqf |= E1000_TTQF_QUEUE_ENABLE;
-	ttqf |= (uint32_t)(rx_queue << E1000_TTQF_QUEUE_SHIFT);
-	ttqf |= (uint32_t)(filter->protocol & E1000_TTQF_PROTOCOL_MASK);
-	if (filter->protocol_mask == 1)
-		ttqf |= E1000_TTQF_MASK_ENABLE;
+	filter_info->priority = (uint8_t)filter->priority;
+	if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG)
+		filter_info->tcp_flags = filter->tcp_flags;
 	else
-		ttqf &= ~E1000_TTQF_MASK_ENABLE;
+		filter_info->tcp_flags = 0;
 
-	imir_ext |= E1000_IMIR_EXT_SIZE_BP;
-	/* tcp flags bits setting. */
-	if (filter->tcp_flags & TCP_FLAG_ALL) {
-		if (filter->tcp_flags & TCP_UGR_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_UGR;
-		if (filter->tcp_flags & TCP_ACK_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_ACK;
-		if (filter->tcp_flags & TCP_PSH_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_PSH;
-		if (filter->tcp_flags & TCP_RST_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_RST;
-		if (filter->tcp_flags & TCP_SYN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_SYN;
-		if (filter->tcp_flags & TCP_FIN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_FIN;
-		imir_ext &= ~E1000_IMIR_EXT_CTRL_BP;
-	} else
-		imir_ext |= E1000_IMIR_EXT_CTRL_BP;
-	E1000_WRITE_REG(hw, E1000_IMIR(index), imir);
-	E1000_WRITE_REG(hw, E1000_TTQF(index), ttqf);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), imir_ext);
 	return 0;
 }
 
+static inline struct e1000_2tuple_filter *
+igb_2tuple_filter_lookup(struct e1000_2tuple_filter_list *filter_list,
+			struct e1000_2tuple_filter_info *key)
+{
+	struct e1000_2tuple_filter *it;
+
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct e1000_2tuple_filter_info)) == 0) {
+			return it;
+		}
+	}
+	return NULL;
+}
+
 /*
- * remove a 2tuple filter
+ * igb_add_2tuple_filter - add a 2tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
+ * ntuple_filter: ponter to the filter that will be added.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index)
+igb_add_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_2tuple_filter *filter;
+	uint32_t ttqf = E1000_TTQF_DISABLE_MASK;
+	uint32_t imir, imir_ext = E1000_IMIREXT_SIZE_BP;
+	int i, ret;
+
+	filter = rte_zmalloc("e1000_2tuple_filter",
+			sizeof(struct e1000_2tuple_filter), 0);
+	if (filter == NULL)
+		return -ENOMEM;
 
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+	ret = ntuple_filter_to_2tuple(ntuple_filter,
+				      &filter->filter_info);
+	if (ret < 0) {
+		rte_free(filter);
+		return ret;
+	}
+	if (igb_2tuple_filter_lookup(&filter_info->twotuple_list,
+					 &filter->filter_info) != NULL) {
+		PMD_DRV_LOG(ERR, "filter exists.");
+		rte_free(filter);
+		return -EEXIST;
+	}
+	filter->queue = ntuple_filter->queue;
+
+	/*
+	 * look for an unused 2tuple filter index,
+	 * and insert the filter to list.
+	 */
+	for (i = 0; i < E1000_MAX_TTQF_FILTERS; i++) {
+		if (!(filter_info->twotuple_mask & (1 << i))) {
+			filter_info->twotuple_mask |= 1 << i;
+			filter->index = i;
+			TAILQ_INSERT_TAIL(&filter_info->twotuple_list,
+					  filter,
+					  entries);
+			break;
+		}
+	}
+	if (i >= E1000_MAX_TTQF_FILTERS) {
+		PMD_DRV_LOG(ERR, "2tuple filters are full.");
+		rte_free(filter);
+		return -ENOSYS;
+	}
 
-	if (index >= E1000_MAX_TTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range */
+	imir = (uint32_t)(filter->filter_info.dst_port & E1000_IMIR_DSTPORT);
+	if (filter->filter_info.dst_port_mask == 1) /* 1b means not compare. */
+		imir |= E1000_IMIR_PORT_BP;
+	else
+		imir &= ~E1000_IMIR_PORT_BP;
+
+	imir |= filter->filter_info.priority << E1000_IMIR_PRIORITY_SHIFT;
+
+	ttqf |= E1000_TTQF_QUEUE_ENABLE;
+	ttqf |= (uint32_t)(filter->queue << E1000_TTQF_QUEUE_SHIFT);
+	ttqf |= (uint32_t)(filter->filter_info.proto & E1000_TTQF_PROTOCOL_MASK);
+	if (filter->filter_info.proto_mask == 0)
+		ttqf &= ~E1000_TTQF_MASK_ENABLE;
 
-	E1000_WRITE_REG(hw, E1000_TTQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIR(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), 0);
+	/* tcp flags bits setting. */
+	if (filter->filter_info.tcp_flags & TCP_FLAG_ALL) {
+		if (filter->filter_info.tcp_flags & TCP_URG_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_URG;
+		if (filter->filter_info.tcp_flags & TCP_ACK_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_ACK;
+		if (filter->filter_info.tcp_flags & TCP_PSH_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_PSH;
+		if (filter->filter_info.tcp_flags & TCP_RST_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_RST;
+		if (filter->filter_info.tcp_flags & TCP_SYN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_SYN;
+		if (filter->filter_info.tcp_flags & TCP_FIN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_FIN;
+	} else
+		imir_ext |= E1000_IMIREXT_CTRL_BP;
+	E1000_WRITE_REG(hw, E1000_IMIR(i), imir);
+	E1000_WRITE_REG(hw, E1000_TTQF(i), ttqf);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(i), imir_ext);
 	return 0;
 }
 
 /*
- * get a 2tuple filter
+ * igb_remove_2tuple_filter - remove a 2tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that returns.
- * *rx_queue: pointer of the queue id the filter assigned to.
+ * ntuple_filter: ponter to the filter that will be removed.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_get_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue)
+igb_remove_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t imir, ttqf, imir_ext;
-
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_2tuple_filter_info filter_2tuple;
+	struct e1000_2tuple_filter *filter;
+	int ret;
 
-	if (index >= E1000_MAX_TTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	memset(&filter_2tuple, 0, sizeof(struct e1000_2tuple_filter_info));
+	ret = ntuple_filter_to_2tuple(ntuple_filter,
+				      &filter_2tuple);
+	if (ret < 0)
+		return ret;
 
-	ttqf = E1000_READ_REG(hw, E1000_TTQF(index));
-	if (ttqf & E1000_TTQF_QUEUE_ENABLE) {
-		imir = E1000_READ_REG(hw, E1000_IMIR(index));
-		filter->protocol = ttqf & E1000_TTQF_PROTOCOL_MASK;
-		filter->protocol_mask = (ttqf & E1000_TTQF_MASK_ENABLE) ? 1 : 0;
-		*rx_queue = (ttqf & E1000_TTQF_RX_QUEUE_MASK) >>
-				E1000_TTQF_QUEUE_SHIFT;
-		filter->dst_port = (uint16_t)(imir & E1000_IMIR_DSTPORT);
-		filter->dst_port_mask = (imir & E1000_IMIR_PORT_BP) ? 1 : 0;
-		filter->priority = (imir & E1000_IMIR_PRIORITY) >>
-			E1000_IMIR_PRIORITY_SHIFT;
-
-		imir_ext = E1000_READ_REG(hw, E1000_IMIREXT(index));
-		if (!(imir_ext & E1000_IMIR_EXT_CTRL_BP)) {
-			if (imir_ext & E1000_IMIR_EXT_CTRL_UGR)
-				filter->tcp_flags |= TCP_UGR_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_ACK)
-				filter->tcp_flags |= TCP_ACK_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_PSH)
-				filter->tcp_flags |= TCP_PSH_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_RST)
-				filter->tcp_flags |= TCP_RST_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_SYN)
-				filter->tcp_flags |= TCP_SYN_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_FIN)
-				filter->tcp_flags |= TCP_FIN_FLAG;
-		} else
-			filter->tcp_flags = 0;
-		return 0;
+	filter = igb_2tuple_filter_lookup(&filter_info->twotuple_list,
+					 &filter_2tuple);
+	if (filter == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
 	}
-	return -ENOENT;
+
+	filter_info->twotuple_mask &= ~(1 << filter->index);
+	TAILQ_REMOVE(&filter_info->twotuple_list, filter, entries);
+	rte_free(filter);
+
+	E1000_WRITE_REG(hw, E1000_TTQF(filter->index), E1000_TTQF_DISABLE_MASK);
+	E1000_WRITE_REG(hw, E1000_IMIR(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(filter->index), 0);
+	return 0;
 }
 
 /*
@@ -2911,192 +2984,265 @@ eth_igb_get_flex_filter(struct rte_eth_dev *dev, uint16_t index,
 	return -ENOENT;
 }
 
-/*
- * 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
-eth_igb_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue)
+/* translate elements in struct rte_eth_ntuple_filter to struct e1000_5tuple_filter_info*/
+static inline int
+ntuple_filter_to_5tuple_82576(struct rte_eth_ntuple_filter *filter,
+			struct e1000_5tuple_filter_info *filter_info)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t ftqf, spqf = 0;
-	uint32_t imir = 0;
-	uint32_t imir_ext = 0;
+	if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576)
+		return -EINVAL;
+	if (filter->priority > E1000_2TUPLE_MAX_PRI)
+		return -EINVAL;  /* filter index is out of range. */
+	if (filter->tcp_flags > TCP_FLAG_ALL)
+		return -EINVAL;  /* flags is invalid. */
 
-	if (hw->mac.type != e1000_82576)
-		return -ENOSYS;
+	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;
+	}
 
-	if (index >= E1000_MAX_FTQF_FILTERS ||
-		rx_queue >= IGB_MAX_RX_QUEUE_NUM_82576)
-		return -EINVAL;  /* filter index is out of range. */
+	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;
+	}
 
-	ftqf = E1000_READ_REG(hw, E1000_FTQF(index));
-	if (ftqf & E1000_FTQF_QUEUE_ENABLE)
-		return -EINVAL;  /* filter index is in use. */
+	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;
+	}
 
-	ftqf = 0;
-	ftqf |= filter->protocol & E1000_FTQF_PROTOCOL_MASK;
-	if (filter->src_ip_mask == 1) /* 1b means not compare. */
-		ftqf |= E1000_FTQF_SOURCE_ADDR_MASK;
-	if (filter->dst_ip_mask == 1)
-		ftqf |= E1000_FTQF_DEST_ADDR_MASK;
-	if (filter->src_port_mask == 1)
-		ftqf |= E1000_FTQF_SOURCE_PORT_MASK;
-	if (filter->protocol_mask == 1)
-		ftqf |= E1000_FTQF_PROTOCOL_COMP_MASK;
-	ftqf |= (rx_queue << E1000_FTQF_QUEUE_SHIFT) & E1000_FTQF_QUEUE_MASK;
-	ftqf |= E1000_FTQF_VF_MASK_EN;
-	ftqf |= E1000_FTQF_QUEUE_ENABLE;
-	E1000_WRITE_REG(hw, E1000_FTQF(index), ftqf);
-	E1000_WRITE_REG(hw, E1000_DAQF(index), filter->dst_ip);
-	E1000_WRITE_REG(hw, E1000_SAQF(index), filter->src_ip);
+	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;
+	}
 
-	spqf |= filter->src_port & E1000_SPQF_SRCPORT;
-	E1000_WRITE_REG(hw, E1000_SPQF(index), spqf);
+	switch (filter->proto_mask) {
+	case UINT8_MAX:
+		filter_info->proto_mask = 0;
+		filter_info->proto = filter->proto;
+		break;
+	case 0:
+		filter_info->proto_mask = 1;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid protocol mask.");
+		return -EINVAL;
+	}
 
-	imir |= (uint32_t)(filter->dst_port & E1000_IMIR_DSTPORT);
-	if (filter->dst_port_mask == 1) /* 1b means not compare. */
-		imir |= E1000_IMIR_PORT_BP;
+	filter_info->priority = (uint8_t)filter->priority;
+	if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG)
+		filter_info->tcp_flags = filter->tcp_flags;
 	else
-		imir &= ~E1000_IMIR_PORT_BP;
-	imir |= filter->priority << E1000_IMIR_PRIORITY_SHIFT;
+		filter_info->tcp_flags = 0;
 
-	imir_ext |= E1000_IMIR_EXT_SIZE_BP;
-	/* tcp flags bits setting. */
-	if (filter->tcp_flags & TCP_FLAG_ALL) {
-		if (filter->tcp_flags & TCP_UGR_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_UGR;
-		if (filter->tcp_flags & TCP_ACK_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_ACK;
-		if (filter->tcp_flags & TCP_PSH_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_PSH;
-		if (filter->tcp_flags & TCP_RST_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_RST;
-		if (filter->tcp_flags & TCP_SYN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_SYN;
-		if (filter->tcp_flags & TCP_FIN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_FIN;
-	} else
-		imir_ext |= E1000_IMIR_EXT_CTRL_BP;
-	E1000_WRITE_REG(hw, E1000_IMIR(index), imir);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), imir_ext);
 	return 0;
 }
 
+static inline struct e1000_5tuple_filter *
+igb_5tuple_filter_lookup_82576(struct e1000_5tuple_filter_list *filter_list,
+			struct e1000_5tuple_filter_info *key)
+{
+	struct e1000_5tuple_filter *it;
+
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct e1000_5tuple_filter_info)) == 0) {
+			return it;
+		}
+	}
+	return NULL;
+}
+
 /*
- * remove a 5tuple filter
+ * igb_add_5tuple_filter_82576 - add a 5tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates
+ * ntuple_filter: ponter to the filter that will be added.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_remove_5tuple_filter(struct rte_eth_dev *dev,
-				uint16_t index)
+igb_add_5tuple_filter_82576(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_5tuple_filter *filter;
+	uint32_t ftqf = E1000_FTQF_VF_BP | E1000_FTQF_MASK;
+	uint32_t spqf, imir, imir_ext = E1000_IMIREXT_SIZE_BP;
+	uint8_t i;
+	int ret;
 
-	if (hw->mac.type != e1000_82576)
+	filter = rte_zmalloc("e1000_5tuple_filter",
+			sizeof(struct e1000_5tuple_filter), 0);
+	if (filter == NULL)
+		return -ENOMEM;
+
+	ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+					    &filter->filter_info);
+	if (ret < 0) {
+		rte_free(filter);
+		return ret;
+	}
+
+	if (igb_5tuple_filter_lookup_82576(&filter_info->fivetuple_list,
+					 &filter->filter_info) != NULL) {
+		PMD_DRV_LOG(ERR, "filter exists.");
+		rte_free(filter);
+		return -EEXIST;
+	}
+	filter->queue = ntuple_filter->queue;
+
+	/*
+	 * look for an unused 5tuple filter index,
+	 * and insert the filter to list.
+	 */
+	for (i = 0; i < E1000_MAX_FTQF_FILTERS; i++) {
+		if (!(filter_info->fivetuple_mask & (1 << i))) {
+			filter_info->fivetuple_mask |= 1 << i;
+			filter->index = i;
+			TAILQ_INSERT_TAIL(&filter_info->fivetuple_list,
+					  filter,
+					  entries);
+			break;
+		}
+	}
+	if (i >= E1000_MAX_FTQF_FILTERS) {
+		PMD_DRV_LOG(ERR, "5tuple filters are full.");
+		rte_free(filter);
 		return -ENOSYS;
+	}
 
-	if (index >= E1000_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	ftqf |= filter->filter_info.proto & E1000_FTQF_PROTOCOL_MASK;
+	if (filter->filter_info.src_ip_mask == 0) /* 0b means compare. */
+		ftqf &= ~E1000_FTQF_MASK_SOURCE_ADDR_BP;
+	if (filter->filter_info.dst_ip_mask == 0)
+		ftqf &= ~E1000_FTQF_MASK_DEST_ADDR_BP;
+	if (filter->filter_info.src_port_mask == 0)
+		ftqf &= ~E1000_FTQF_MASK_SOURCE_PORT_BP;
+	if (filter->filter_info.proto_mask == 0)
+		ftqf &= ~E1000_FTQF_MASK_PROTO_BP;
+	ftqf |= (filter->queue << E1000_FTQF_QUEUE_SHIFT) &
+		E1000_FTQF_QUEUE_MASK;
+	ftqf |= E1000_FTQF_QUEUE_ENABLE;
+	E1000_WRITE_REG(hw, E1000_FTQF(i), ftqf);
+	E1000_WRITE_REG(hw, E1000_DAQF(i), filter->filter_info.dst_ip);
+	E1000_WRITE_REG(hw, E1000_SAQF(i), filter->filter_info.src_ip);
+
+	spqf = filter->filter_info.src_port & E1000_SPQF_SRCPORT;
+	E1000_WRITE_REG(hw, E1000_SPQF(i), spqf);
 
-	E1000_WRITE_REG(hw, E1000_FTQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_DAQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_SAQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_SPQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIR(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), 0);
+	imir = (uint32_t)(filter->filter_info.dst_port & E1000_IMIR_DSTPORT);
+	if (filter->filter_info.dst_port_mask == 1) /* 1b means not compare. */
+		imir |= E1000_IMIR_PORT_BP;
+	else
+		imir &= ~E1000_IMIR_PORT_BP;
+	imir |= filter->filter_info.priority << E1000_IMIR_PRIORITY_SHIFT;
+
+	/* tcp flags bits setting. */
+	if (filter->filter_info.tcp_flags & TCP_FLAG_ALL) {
+		if (filter->filter_info.tcp_flags & TCP_URG_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_URG;
+		if (filter->filter_info.tcp_flags & TCP_ACK_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_ACK;
+		if (filter->filter_info.tcp_flags & TCP_PSH_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_PSH;
+		if (filter->filter_info.tcp_flags & TCP_RST_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_RST;
+		if (filter->filter_info.tcp_flags & TCP_SYN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_SYN;
+		if (filter->filter_info.tcp_flags & TCP_FIN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_FIN;
+	} else
+		imir_ext |= E1000_IMIREXT_CTRL_BP;
+	E1000_WRITE_REG(hw, E1000_IMIR(i), imir);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(i), imir_ext);
 	return 0;
 }
 
 /*
- * get a 5tuple filter
+ * igb_remove_5tuple_filter_82576 - remove a 5tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates
- * filter: ponter to the filter that returns
- * *rx_queue: pointer of the queue id the filter assigned to
+ * ntuple_filter: ponter to the filter that will be removed.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue)
+igb_remove_5tuple_filter_82576(struct rte_eth_dev *dev,
+				struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t spqf, ftqf, imir, imir_ext;
-
-	if (hw->mac.type != e1000_82576)
-		return -ENOSYS;
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_5tuple_filter_info filter_5tuple;
+	struct e1000_5tuple_filter *filter;
+	int ret;
 
-	if (index >= E1000_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	memset(&filter_5tuple, 0, sizeof(struct e1000_5tuple_filter_info));
+	ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+					    &filter_5tuple);
+	if (ret < 0)
+		return ret;
 
-	ftqf = E1000_READ_REG(hw, E1000_FTQF(index));
-	if (ftqf & E1000_FTQF_QUEUE_ENABLE) {
-		filter->src_ip_mask =
-			(ftqf & E1000_FTQF_SOURCE_ADDR_MASK) ? 1 : 0;
-		filter->dst_ip_mask =
-			(ftqf & E1000_FTQF_DEST_ADDR_MASK) ? 1 : 0;
-		filter->src_port_mask =
-			(ftqf & E1000_FTQF_SOURCE_PORT_MASK) ? 1 : 0;
-		filter->protocol_mask =
-			(ftqf & E1000_FTQF_PROTOCOL_COMP_MASK) ? 1 : 0;
-		filter->protocol =
-			(uint8_t)ftqf & E1000_FTQF_PROTOCOL_MASK;
-		*rx_queue = (uint16_t)((ftqf & E1000_FTQF_QUEUE_MASK) >>
-				E1000_FTQF_QUEUE_SHIFT);
-
-		spqf = E1000_READ_REG(hw, E1000_SPQF(index));
-		filter->src_port = spqf & E1000_SPQF_SRCPORT;
-
-		filter->dst_ip = E1000_READ_REG(hw, E1000_DAQF(index));
-		filter->src_ip = E1000_READ_REG(hw, E1000_SAQF(index));
-
-		imir = E1000_READ_REG(hw, E1000_IMIR(index));
-		filter->dst_port_mask = (imir & E1000_IMIR_PORT_BP) ? 1 : 0;
-		filter->dst_port = (uint16_t)(imir & E1000_IMIR_DSTPORT);
-		filter->priority = (imir & E1000_IMIR_PRIORITY) >>
-			E1000_IMIR_PRIORITY_SHIFT;
-
-		imir_ext = E1000_READ_REG(hw, E1000_IMIREXT(index));
-		if (!(imir_ext & E1000_IMIR_EXT_CTRL_BP)) {
-			if (imir_ext & E1000_IMIR_EXT_CTRL_UGR)
-				filter->tcp_flags |= TCP_UGR_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_ACK)
-				filter->tcp_flags |= TCP_ACK_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_PSH)
-				filter->tcp_flags |= TCP_PSH_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_RST)
-				filter->tcp_flags |= TCP_RST_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_SYN)
-				filter->tcp_flags |= TCP_SYN_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_FIN)
-				filter->tcp_flags |= TCP_FIN_FLAG;
-		} else
-			filter->tcp_flags = 0;
-		return 0;
+	filter = igb_5tuple_filter_lookup_82576(&filter_info->fivetuple_list,
+					 &filter_5tuple);
+	if (filter == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
 	}
-	return -ENOENT;
+
+	filter_info->fivetuple_mask &= ~(1 << filter->index);
+	TAILQ_REMOVE(&filter_info->fivetuple_list, filter, entries);
+	rte_free(filter);
+
+	E1000_WRITE_REG(hw, E1000_FTQF(filter->index),
+			E1000_FTQF_VF_BP | E1000_FTQF_MASK);
+	E1000_WRITE_REG(hw, E1000_DAQF(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_SAQF(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_SPQF(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_IMIR(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(filter->index), 0);
+	return 0;
 }
 
 static int
@@ -3149,6 +3295,196 @@ eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+/*
+ * igb_add_del_ntuple_filter - 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.
+ */
+static int
+igb_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter,
+			bool add)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
+
+	switch (ntuple_filter->flags) {
+	case RTE_5TUPLE_FLAGS:
+	case (RTE_5TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82576)
+			return -ENOTSUP;
+		if (add)
+			ret = igb_add_5tuple_filter_82576(dev,
+							  ntuple_filter);
+		else
+			ret = igb_remove_5tuple_filter_82576(dev,
+							     ntuple_filter);
+		break;
+	case RTE_2TUPLE_FLAGS:
+	case (RTE_2TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82580 && hw->mac.type != e1000_i350)
+			return -ENOTSUP;
+		if (add)
+			ret = igb_add_2tuple_filter(dev, ntuple_filter);
+		else
+			ret = igb_remove_2tuple_filter(dev, ntuple_filter);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * igb_get_ntuple_filter - get a ntuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * ntuple_filter: Pointer to struct rte_eth_ntuple_filter
+ *
+ * @return
+ *    - On success, zero.
+ *    - On failure, a negative value.
+ */
+static int
+igb_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_5tuple_filter_info filter_5tuple;
+	struct e1000_2tuple_filter_info filter_2tuple;
+	struct e1000_5tuple_filter *p_5tuple_filter;
+	struct e1000_2tuple_filter *p_2tuple_filter;
+	int ret;
+
+	switch (ntuple_filter->flags) {
+	case RTE_5TUPLE_FLAGS:
+	case (RTE_5TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82576)
+			return -ENOTSUP;
+		memset(&filter_5tuple,
+			0,
+			sizeof(struct e1000_5tuple_filter_info));
+		ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+						    &filter_5tuple);
+		if (ret < 0)
+			return ret;
+		p_5tuple_filter = igb_5tuple_filter_lookup_82576(
+					&filter_info->fivetuple_list,
+					&filter_5tuple);
+		if (p_5tuple_filter == NULL) {
+			PMD_DRV_LOG(ERR, "filter doesn't exist.");
+			return -ENOENT;
+		}
+		ntuple_filter->queue = p_5tuple_filter->queue;
+		break;
+	case RTE_2TUPLE_FLAGS:
+	case (RTE_2TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82580 && hw->mac.type != e1000_i350)
+			return -ENOTSUP;
+		memset(&filter_2tuple,
+			0,
+			sizeof(struct e1000_2tuple_filter_info));
+		ret = ntuple_filter_to_2tuple(ntuple_filter, &filter_2tuple);
+		if (ret < 0)
+			return ret;
+		p_2tuple_filter = igb_2tuple_filter_lookup(
+					&filter_info->twotuple_list,
+					&filter_2tuple);
+		if (p_2tuple_filter == NULL) {
+			PMD_DRV_LOG(ERR, "filter doesn't exist.");
+			return -ENOENT;
+		}
+		ntuple_filter->queue = p_2tuple_filter->queue;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * igb_ntuple_filter_handle - Handle operations for ntuple filter.
+ * @dev: pointer to rte_eth_dev structure
+ * @filter_op:operation will be taken.
+ * @arg: a pointer to specific structure corresponding to the filter_op
+ */
+static int
+igb_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
+
+	MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+	if (filter_op == RTE_ETH_FILTER_NOP)
+		return 0;
+
+	if (arg == NULL) {
+		PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
+			    filter_op);
+		return -EINVAL;
+	}
+
+	switch (filter_op) {
+	case RTE_ETH_FILTER_ADD:
+		ret = igb_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			TRUE);
+		break;
+	case RTE_ETH_FILTER_DELETE:
+		ret = igb_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			FALSE);
+		break;
+	case RTE_ETH_FILTER_GET:
+		ret = igb_get_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
+static int
+eth_igb_filter_ctrl(struct rte_eth_dev *dev,
+		     enum rte_filter_type filter_type,
+		     enum rte_filter_op filter_op,
+		     void *arg)
+{
+	int ret = -EINVAL;
+
+	switch (filter_type) {
+	case RTE_ETH_FILTER_NTUPLE:
+		ret = igb_ntuple_filter_handle(dev, filter_op, arg);
+		break;
+	default:
+		PMD_DRV_LOG(WARNING, "Filter type (%d) not supported",
+							filter_type);
+		break;
+	}
+
+	return ret;
+}
+
 static struct rte_driver pmd_igb_drv = {
 	.type = PMD_PDEV,
 	.init = rte_igb_pmd_init,
-- 
1.9.3

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

* [dpdk-dev] [PATCH 4/5] testpmd: new commands for ntuple filter
  2015-01-15  1:45 [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters Jingjing Wu
                   ` (2 preceding siblings ...)
  2015-01-15  1:45 ` [dpdk-dev] [PATCH 3/5] e1000: ntuple filter functions replace old ones for 2tuple and " Jingjing Wu
@ 2015-01-15  1:46 ` Jingjing Wu
  2015-01-15  1:46 ` [dpdk-dev] [PATCH 5/5] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-15  1:46 UTC (permalink / raw)
  To: dev

Following commands of 5tuple and 2tuple filter are removed:
 - add_2tuple_filter (port_id) protocol (pro_value) (pro_mask)
   dst_port (port_value) (port_mask) flags (flg_value) priority (prio
   queue (queue_id) index (idx)
 - remove_2tuple_filter (port_id) index (idx)
 - get_2tuple_filter (port_id) index (idx)
 - add_5tuple_filter (port_id) dst_ip (dst_address) src_ip (src_addres
   dst_port (dst_port_value) src_port (src_port_value) protocol (prot
   mask (mask_value) flags (flags_value) priority (prio_value)"
   queue (queue_id) index (idx)
 - remove_5tuple_filter (port_id) index (idx)
 - get_5tuple_filter (port_id) index (idx)

New commands are added for 5tuple and 2tuple filter by using filter_ctrl API
and new ntuple filter structure:
 - 2tuple_filter (port_id) (add|del)
   dst_port (dst_port_value) protocol (protocol_value)
   mask (mask_value) tcp_flags (tcp_flags_value)
   priority (prio_value) queue (queue_id)
 - 5tuple_filter (port_id) (add|del)
   dst_ip (dst_address) src_ip (src_address)
   dst_port (dst_port_value) src_port (src_port_value)
   protocol (protocol_value)
   mask (mask_value) tcp_flags (tcp_flags_value)
   priority (prio_value) queue (queue_id)

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c | 406 ++++++++++++++++++++++---------------------------
 app/test-pmd/config.c  |  65 --------
 2 files changed, 186 insertions(+), 285 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 882a5a2..1d74870 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -664,28 +664,19 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"get_ethertype_filter (port_id) index (idx)\n"
 			"    get info of a ethertype filter.\n\n"
 
-			"add_2tuple_filter (port_id) protocol (pro_value) (pro_mask)"
-			" dst_port (port_value) (port_mask) flags (flg_value) priority (prio_value)"
-			" queue (queue_id) index (idx)\n"
-			"    add a 2tuple filter.\n\n"
-
-			"remove_2tuple_filter (port_id) index (idx)\n"
-			"    remove a 2tuple filter.\n\n"
-
-			"get_2tuple_filter (port_id) index (idx)\n"
-			"    get info of a 2tuple filter.\n\n"
-
-			"add_5tuple_filter (port_id) dst_ip (dst_address) src_ip (src_address)"
-			" dst_port (dst_port_value) src_port (src_port_value) protocol (protocol_value)"
-			" mask (mask_value) flags (flags_value) priority (prio_value)"
-			" queue (queue_id) index (idx)\n"
-			"    add a 5tuple filter.\n\n"
-
-			"remove_5tuple_filter (port_id) index (idx)\n"
-			"    remove a 5tuple filter.\n\n"
-
-			"get_5tuple_filter (port_id) index (idx)\n"
-			"    get info of a 5tuple filter.\n\n"
+			"2tuple_filter (port_id) (add|del)"
+			" dst_port (dst_port_value) protocol (protocol_value)"
+			" mask (mask_value) tcp_flags (tcp_flags_value)"
+			" priority (prio_value) queue (queue_id)\n"
+			"    Add/Del a 2tuple filter.\n\n"
+
+			"5tuple_filter (port_id) (add|del)"
+			" dst_ip (dst_address) src_ip (src_address)"
+			" dst_port (dst_port_value) src_port (src_port_value)"
+			" protocol (protocol_value)"
+			" mask (mask_value) tcp_flags (tcp_flags_value)"
+			" priority (prio_value) queue (queue_id)\n"
+			"    Add/Del a 5tuple filter.\n\n"
 
 			"add_syn_filter (port_id) priority (high|low) queue (queue_id)"
 			"    add syn filter.\n\n"
@@ -7491,21 +7482,20 @@ cmdline_parse_inst_t cmd_get_syn_filter = {
 /* *** ADD/REMOVE A 2tuple FILTER *** */
 struct cmd_2tuple_filter_result {
 	cmdline_fixed_string_t filter;
-	uint8_t port_id;
-	cmdline_fixed_string_t protocol;
-	uint8_t protocol_value;
-	uint8_t protocol_mask;
+	uint8_t  port_id;
+	cmdline_fixed_string_t ops;
 	cmdline_fixed_string_t dst_port;
 	uint16_t dst_port_value;
-	uint16_t dst_port_mask;
-	cmdline_fixed_string_t flags;
-	uint8_t flags_value;
+	cmdline_fixed_string_t protocol;
+	uint8_t protocol_value;
+	cmdline_fixed_string_t mask;
+	uint8_t  mask_value;
+	cmdline_fixed_string_t tcp_flags;
+	uint8_t tcp_flags_value;
 	cmdline_fixed_string_t priority;
-	uint8_t priority_value;
+	uint8_t  priority_value;
 	cmdline_fixed_string_t queue;
-	uint16_t queue_id;
-	cmdline_fixed_string_t index;
-	uint16_t index_value;
+	uint16_t  queue_id;
 };
 
 static void
@@ -7513,59 +7503,92 @@ cmd_2tuple_filter_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
 			__attribute__((unused)) void *data)
 {
-	int ret = 0;
-	struct rte_2tuple_filter filter;
+	struct rte_eth_ntuple_filter filter;
 	struct cmd_2tuple_filter_result *res = parsed_result;
+	int ret = 0;
 
-	memset(&filter, 0, sizeof(struct rte_2tuple_filter));
+	ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
+	if (ret < 0) {
+		printf("ntuple filter is not supported on port %u.\n",
+			res->port_id);
+		return;
+	}
 
-	if (!strcmp(res->filter, "add_2tuple_filter")) {
-		/* need convert to big endian. */
-		filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
-		filter.protocol = res->protocol_value;
-		filter.dst_port_mask = (res->dst_port_mask) ? 0 : 1;
-		filter.protocol_mask = (res->protocol_mask) ? 0 : 1;
-		filter.priority = res->priority_value;
-		filter.tcp_flags = res->flags_value;
-		ret = rte_eth_dev_add_2tuple_filter(res->port_id,
-			res->index_value, &filter, res->queue_id);
-	} else if (!strcmp(res->filter, "remove_2tuple_filter"))
-		ret = rte_eth_dev_remove_2tuple_filter(res->port_id,
-			res->index_value);
-	else if (!strcmp(res->filter, "get_2tuple_filter"))
-		get_2tuple_filter(res->port_id, res->index_value);
+	memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
+
+	filter.flags = RTE_2TUPLE_FLAGS;
+	filter.dst_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
+	filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
+	filter.proto = res->protocol_value;
+	filter.priority = res->priority_value;
+	if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
+		printf("nonzero tcp_flags is only meaningful"
+			" when protocol is TCP.\n");
+		return;
+	}
+	if (res->tcp_flags_value > TCP_FLAG_ALL) {
+		printf("invalid TCP flags.\n");
+		return;
+	}
+
+	if (res->tcp_flags_value != 0) {
+		filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
+		filter.tcp_flags = res->tcp_flags_value;
+	}
+
+	/* need convert to big endian. */
+	filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
+	filter.queue = res->queue_id;
 
+	if (!strcmp(res->ops, "add"))
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_ADD,
+				&filter);
+	else
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_DELETE,
+				&filter);
 	if (ret < 0)
-		printf("2tuple filter setting error: (%s)\n", strerror(-ret));
+		printf("2tuple filter programming error: (%s)\n",
+			strerror(-ret));
+
 }
 
+cmdline_parse_token_string_t cmd_2tuple_filter_filter =
+	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+				 filter, "2tuple_filter");
 cmdline_parse_token_num_t cmd_2tuple_filter_port_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
 				port_id, UINT8);
-cmdline_parse_token_string_t cmd_2tuple_filter_protocol =
+cmdline_parse_token_string_t cmd_2tuple_filter_ops =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				 protocol, "protocol");
-cmdline_parse_token_num_t cmd_2tuple_filter_protocol_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				 protocol_value, UINT8);
-cmdline_parse_token_num_t cmd_2tuple_filter_protocol_mask =
-	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				protocol_mask, UINT8);
+				 ops, "add#del");
 cmdline_parse_token_string_t cmd_2tuple_filter_dst_port =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
 				dst_port, "dst_port");
 cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
 				dst_port_value, UINT16);
-cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_mask =
+cmdline_parse_token_string_t cmd_2tuple_filter_protocol =
+	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+				protocol, "protocol");
+cmdline_parse_token_num_t cmd_2tuple_filter_protocol_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				dst_port_mask, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_flags =
+				protocol_value, UINT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_mask =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				flags, "flags");
-cmdline_parse_token_num_t cmd_2tuple_filter_flags_value =
+				mask, "mask");
+cmdline_parse_token_num_t cmd_2tuple_filter_mask_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				flags_value, UINT8);
+				mask_value, INT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_tcp_flags =
+	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+				tcp_flags, "tcp_flags");
+cmdline_parse_token_num_t cmd_2tuple_filter_tcp_flags_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+				tcp_flags_value, UINT8);
 cmdline_parse_token_string_t cmd_2tuple_filter_priority =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
 				priority, "priority");
@@ -7578,67 +7601,27 @@ cmdline_parse_token_string_t cmd_2tuple_filter_queue =
 cmdline_parse_token_num_t cmd_2tuple_filter_queue_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
 				queue_id, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_index =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				index, "index");
-cmdline_parse_token_num_t cmd_2tuple_filter_index_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				index_value, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_add_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				filter, "add_2tuple_filter");
-cmdline_parse_inst_t cmd_add_2tuple_filter = {
+
+cmdline_parse_inst_t cmd_2tuple_filter = {
 	.f = cmd_2tuple_filter_parsed,
 	.data = NULL,
 	.help_str = "add a 2tuple filter",
 	.tokens = {
-		(void *)&cmd_2tuple_filter_add_filter,
+		(void *)&cmd_2tuple_filter_filter,
 		(void *)&cmd_2tuple_filter_port_id,
-		(void *)&cmd_2tuple_filter_protocol,
-		(void *)&cmd_2tuple_filter_protocol_value,
-		(void *)&cmd_2tuple_filter_protocol_mask,
+		(void *)&cmd_2tuple_filter_ops,
 		(void *)&cmd_2tuple_filter_dst_port,
 		(void *)&cmd_2tuple_filter_dst_port_value,
-		(void *)&cmd_2tuple_filter_dst_port_mask,
-		(void *)&cmd_2tuple_filter_flags,
-		(void *)&cmd_2tuple_filter_flags_value,
+		(void *)&cmd_2tuple_filter_protocol,
+		(void *)&cmd_2tuple_filter_protocol_value,
+		(void *)&cmd_2tuple_filter_mask,
+		(void *)&cmd_2tuple_filter_mask_value,
+		(void *)&cmd_2tuple_filter_tcp_flags,
+		(void *)&cmd_2tuple_filter_tcp_flags_value,
 		(void *)&cmd_2tuple_filter_priority,
 		(void *)&cmd_2tuple_filter_priority_value,
 		(void *)&cmd_2tuple_filter_queue,
 		(void *)&cmd_2tuple_filter_queue_id,
-		(void *)&cmd_2tuple_filter_index,
-		(void *)&cmd_2tuple_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_2tuple_filter_remove_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				filter, "remove_2tuple_filter");
-cmdline_parse_inst_t cmd_remove_2tuple_filter = {
-	.f = cmd_2tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "remove a 2tuple filter",
-	.tokens = {
-		(void *)&cmd_2tuple_filter_remove_filter,
-		(void *)&cmd_2tuple_filter_port_id,
-		(void *)&cmd_2tuple_filter_index,
-		(void *)&cmd_2tuple_filter_index_value,
-		NULL,
-	},
-};
-cmdline_parse_token_string_t cmd_2tuple_filter_get_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				filter, "get_2tuple_filter");
-cmdline_parse_inst_t cmd_get_2tuple_filter = {
-	.f = cmd_2tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "get a 2tuple filter",
-	.tokens = {
-		(void *)&cmd_2tuple_filter_get_filter,
-		(void *)&cmd_2tuple_filter_port_id,
-		(void *)&cmd_2tuple_filter_index,
-		(void *)&cmd_2tuple_filter_index_value,
 		NULL,
 	},
 };
@@ -7647,6 +7630,7 @@ cmdline_parse_inst_t cmd_get_2tuple_filter = {
 struct cmd_5tuple_filter_result {
 	cmdline_fixed_string_t filter;
 	uint8_t  port_id;
+	cmdline_fixed_string_t ops;
 	cmdline_fixed_string_t dst_ip;
 	cmdline_ipaddr_t dst_ip_value;
 	cmdline_fixed_string_t src_ip;
@@ -7659,14 +7643,12 @@ struct cmd_5tuple_filter_result {
 	uint8_t protocol_value;
 	cmdline_fixed_string_t mask;
 	uint8_t  mask_value;
-	cmdline_fixed_string_t flags;
-	uint8_t flags_value;
+	cmdline_fixed_string_t tcp_flags;
+	uint8_t tcp_flags_value;
 	cmdline_fixed_string_t priority;
 	uint8_t  priority_value;
 	cmdline_fixed_string_t queue;
 	uint16_t  queue_id;
-	cmdline_fixed_string_t index;
-	uint16_t  index_value;
 };
 
 static void
@@ -7674,62 +7656,92 @@ cmd_5tuple_filter_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
 			__attribute__((unused)) void *data)
 {
-	int ret = 0;
-	struct rte_5tuple_filter filter;
+	struct rte_eth_ntuple_filter filter;
 	struct cmd_5tuple_filter_result *res = parsed_result;
+	int ret = 0;
 
-	memset(&filter, 0, sizeof(struct rte_5tuple_filter));
+	ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
+	if (ret < 0) {
+		printf("ntuple filter is not supported on port %u.\n",
+			res->port_id);
+		return;
+	}
 
-	if (!strcmp(res->filter, "add_5tuple_filter")) {
-		filter.dst_ip_mask = (res->mask_value & 0x10) ? 0 : 1;
-		filter.src_ip_mask = (res->mask_value & 0x08) ? 0 : 1;
-		filter.dst_port_mask = (res->mask_value & 0x04) ? 0 : 1;
-		filter.src_port_mask = (res->mask_value & 0x02) ? 0 : 1;
-		filter.protocol = res->protocol_value;
-		filter.protocol_mask = (res->mask_value & 0x01) ? 0 : 1;
-		filter.priority = res->priority_value;
-		filter.tcp_flags = res->flags_value;
+	memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
 
-		if (res->dst_ip_value.family == AF_INET)
-			/* no need to convert, already big endian. */
-			filter.dst_ip = res->dst_ip_value.addr.ipv4.s_addr;
-		else {
-			if (filter.dst_ip_mask == 0) {
-				printf("can not support ipv6 involved compare.\n");
-				return;
-			}
-			filter.dst_ip = 0;
+	filter.flags = RTE_5TUPLE_FLAGS;
+	filter.dst_ip_mask = (res->mask_value & 0x10) ? UINT32_MAX : 0;
+	filter.src_ip_mask = (res->mask_value & 0x08) ? UINT32_MAX : 0;
+	filter.dst_port_mask = (res->mask_value & 0x04) ? UINT16_MAX : 0;
+	filter.src_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
+	filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
+	filter.proto = res->protocol_value;
+	filter.priority = res->priority_value;
+	if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
+		printf("nonzero tcp_flags is only meaningful"
+			" when protocol is TCP.\n");
+		return;
+	}
+	if (res->tcp_flags_value > TCP_FLAG_ALL) {
+		printf("invalid TCP flags.\n");
+		return;
+	}
+
+	if (res->tcp_flags_value != 0) {
+		filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
+		filter.tcp_flags = res->tcp_flags_value;
+	}
+
+	if (res->dst_ip_value.family == AF_INET)
+		/* no need to convert, already big endian. */
+		filter.dst_ip = res->dst_ip_value.addr.ipv4.s_addr;
+	else {
+		if (filter.dst_ip_mask == 0) {
+			printf("can not support ipv6 involved compare.\n");
+			return;
 		}
+		filter.dst_ip = 0;
+	}
 
-		if (res->src_ip_value.family == AF_INET)
-			/* no need to convert, already big endian. */
-			filter.src_ip = res->src_ip_value.addr.ipv4.s_addr;
-		else {
-			if (filter.src_ip_mask == 0) {
-				printf("can not support ipv6 involved compare.\n");
-				return;
-			}
-			filter.src_ip = 0;
+	if (res->src_ip_value.family == AF_INET)
+		/* no need to convert, already big endian. */
+		filter.src_ip = res->src_ip_value.addr.ipv4.s_addr;
+	else {
+		if (filter.src_ip_mask == 0) {
+			printf("can not support ipv6 involved compare.\n");
+			return;
 		}
-		/* need convert to big endian. */
-		filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
-		filter.src_port = rte_cpu_to_be_16(res->src_port_value);
+		filter.src_ip = 0;
+	}
+	/* need convert to big endian. */
+	filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
+	filter.src_port = rte_cpu_to_be_16(res->src_port_value);
+	filter.queue = res->queue_id;
 
-		ret = rte_eth_dev_add_5tuple_filter(res->port_id,
-			res->index_value, &filter, res->queue_id);
-	} else if (!strcmp(res->filter, "remove_5tuple_filter"))
-		ret = rte_eth_dev_remove_5tuple_filter(res->port_id,
-			res->index_value);
-	else if (!strcmp(res->filter, "get_5tuple_filter"))
-		get_5tuple_filter(res->port_id, res->index_value);
+	if (!strcmp(res->ops, "add"))
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_ADD,
+				&filter);
+	else
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_DELETE,
+				&filter);
 	if (ret < 0)
-		printf("5tuple filter setting error: (%s)\n", strerror(-ret));
+		printf("5tuple filter programming error: (%s)\n",
+			strerror(-ret));
 }
 
-
+cmdline_parse_token_string_t cmd_5tuple_filter_filter =
+	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+				 filter, "5tuple_filter");
 cmdline_parse_token_num_t cmd_5tuple_filter_port_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
 				port_id, UINT8);
+cmdline_parse_token_string_t cmd_5tuple_filter_ops =
+	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+				 ops, "add#del");
 cmdline_parse_token_string_t cmd_5tuple_filter_dst_ip =
 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
 				dst_ip, "dst_ip");
@@ -7766,12 +7778,12 @@ cmdline_parse_token_string_t cmd_5tuple_filter_mask =
 cmdline_parse_token_num_t cmd_5tuple_filter_mask_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
 				mask_value, INT8);
-cmdline_parse_token_string_t cmd_5tuple_filter_flags =
+cmdline_parse_token_string_t cmd_5tuple_filter_tcp_flags =
 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				flags, "flags");
-cmdline_parse_token_num_t cmd_5tuple_filter_flags_value =
+				tcp_flags, "tcp_flags");
+cmdline_parse_token_num_t cmd_5tuple_filter_tcp_flags_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
-				flags_value, UINT8);
+				tcp_flags_value, UINT8);
 cmdline_parse_token_string_t cmd_5tuple_filter_priority =
 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
 				priority, "priority");
@@ -7784,23 +7796,15 @@ cmdline_parse_token_string_t cmd_5tuple_filter_queue =
 cmdline_parse_token_num_t cmd_5tuple_filter_queue_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
 				queue_id, UINT16);
-cmdline_parse_token_string_t cmd_5tuple_filter_index =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				index, "index");
-cmdline_parse_token_num_t cmd_5tuple_filter_index_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
-				index_value, UINT16);
 
-cmdline_parse_token_string_t cmd_5tuple_filter_add_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				 filter, "add_5tuple_filter");
-cmdline_parse_inst_t cmd_add_5tuple_filter = {
+cmdline_parse_inst_t cmd_5tuple_filter = {
 	.f = cmd_5tuple_filter_parsed,
 	.data = NULL,
-	.help_str = "add a 5tuple filter",
+	.help_str = "add/del a 5tuple filter",
 	.tokens = {
-		(void *)&cmd_5tuple_filter_add_filter,
+		(void *)&cmd_5tuple_filter_filter,
 		(void *)&cmd_5tuple_filter_port_id,
+		(void *)&cmd_5tuple_filter_ops,
 		(void *)&cmd_5tuple_filter_dst_ip,
 		(void *)&cmd_5tuple_filter_dst_ip_value,
 		(void *)&cmd_5tuple_filter_src_ip,
@@ -7813,46 +7817,12 @@ cmdline_parse_inst_t cmd_add_5tuple_filter = {
 		(void *)&cmd_5tuple_filter_protocol_value,
 		(void *)&cmd_5tuple_filter_mask,
 		(void *)&cmd_5tuple_filter_mask_value,
-		(void *)&cmd_5tuple_filter_flags,
-		(void *)&cmd_5tuple_filter_flags_value,
+		(void *)&cmd_5tuple_filter_tcp_flags,
+		(void *)&cmd_5tuple_filter_tcp_flags_value,
 		(void *)&cmd_5tuple_filter_priority,
 		(void *)&cmd_5tuple_filter_priority_value,
 		(void *)&cmd_5tuple_filter_queue,
 		(void *)&cmd_5tuple_filter_queue_id,
-		(void *)&cmd_5tuple_filter_index,
-		(void *)&cmd_5tuple_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_5tuple_filter_remove_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				filter, "remove_5tuple_filter");
-cmdline_parse_inst_t cmd_remove_5tuple_filter = {
-	.f = cmd_5tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "remove a 5tuple filter",
-	.tokens = {
-		(void *)&cmd_5tuple_filter_remove_filter,
-		(void *)&cmd_5tuple_filter_port_id,
-		(void *)&cmd_5tuple_filter_index,
-		(void *)&cmd_5tuple_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_5tuple_filter_get_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				filter, "get_5tuple_filter");
-cmdline_parse_inst_t cmd_get_5tuple_filter = {
-	.f = cmd_5tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "get a 5tuple filter",
-	.tokens = {
-		(void *)&cmd_5tuple_filter_get_filter,
-		(void *)&cmd_5tuple_filter_port_id,
-		(void *)&cmd_5tuple_filter_index,
-		(void *)&cmd_5tuple_filter_index_value,
 		NULL,
 	},
 };
@@ -8821,12 +8791,8 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_add_syn_filter,
 	(cmdline_parse_inst_t *)&cmd_remove_syn_filter,
 	(cmdline_parse_inst_t *)&cmd_get_syn_filter,
-	(cmdline_parse_inst_t *)&cmd_add_2tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_remove_2tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_get_2tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_add_5tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_remove_5tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_get_5tuple_filter,
+	(cmdline_parse_inst_t *)&cmd_2tuple_filter,
+	(cmdline_parse_inst_t *)&cmd_5tuple_filter,
 	(cmdline_parse_inst_t *)&cmd_add_flex_filter,
 	(cmdline_parse_inst_t *)&cmd_remove_flex_filter,
 	(cmdline_parse_inst_t *)&cmd_get_flex_filter,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 97b6525..ae1439e 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2213,73 +2213,8 @@ get_syn_filter(uint8_t port_id)
 		filter.hig_pri ? "high" : "low",
 		rx_queue);
 }
-void
-get_2tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_2tuple_filter filter;
-	int ret = 0;
-	uint16_t rx_queue;
-
-	memset(&filter, 0, sizeof(filter));
-	ret = rte_eth_dev_get_2tuple_filter(port_id, index,
-				&filter, &rx_queue);
-	if (ret < 0) {
-		if (ret == (-ENOENT))
-			printf("filter[%d] is not enabled\n", index);
-		else
-			printf("get 2tuple filter fails(%s)\n", strerror(-ret));
-		return;
-	} else {
-		printf("filter[%d]:\n", index);
-		printf("    Destination Port:     0x%04x    mask: %d\n",
-			rte_be_to_cpu_16(filter.dst_port),
-			filter.dst_port_mask ? 0 : 1);
-		printf("    protocol:  0x%02x     mask:%d     tcp_flags: 0x%02x\n",
-			filter.protocol, filter.protocol_mask ? 0 : 1,
-			filter.tcp_flags);
-		printf("    priority: %d    queue: %d\n",
-			filter.priority, rx_queue);
-	}
-}
 
 void
-get_5tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_5tuple_filter filter;
-	int ret = 0;
-	uint16_t rx_queue;
-
-	memset(&filter, 0, sizeof(filter));
-	ret = rte_eth_dev_get_5tuple_filter(port_id, index,
-				&filter, &rx_queue);
-	if (ret < 0) {
-		if (ret == (-ENOENT))
-			printf("filter[%d] is not enabled\n", index);
-		else
-			printf("get 5tuple filter fails(%s)\n", strerror(-ret));
-		return;
-	} else {
-		printf("filter[%d]:\n", index);
-		printf("    Destination IP:  0x%08x    mask: %d\n",
-			(unsigned)rte_be_to_cpu_32(filter.dst_ip),
-			filter.dst_ip_mask ? 0 : 1);
-		printf("    Source IP:       0x%08x    mask: %d\n",
-			(unsigned)rte_be_to_cpu_32(filter.src_ip),
-			filter.src_ip_mask ? 0 : 1);
-		printf("    Destination Port:       0x%04x    mask: %d\n",
-			rte_be_to_cpu_16(filter.dst_port),
-			filter.dst_port_mask ? 0 : 1);
-		printf("    Source Port:       0x%04x    mask: %d\n",
-			rte_be_to_cpu_16(filter.src_port),
-			filter.src_port_mask ? 0 : 1);
-		printf("    protocol:           0x%02x    mask: %d\n",
-			filter.protocol,
-			filter.protocol_mask ? 0 : 1);
-		printf("    priority: %d    flags: 0x%02x    queue: %d\n",
-			filter.priority, filter.tcp_flags, rx_queue);
-	}
-}
-void
 get_flex_filter(uint8_t port_id, uint16_t index)
 
 {
-- 
1.9.3

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

* [dpdk-dev] [PATCH 5/5] ethdev: remove old APIs and structures of 5tuple and 2tuple filters
  2015-01-15  1:45 [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters Jingjing Wu
                   ` (3 preceding siblings ...)
  2015-01-15  1:46 ` [dpdk-dev] [PATCH 4/5] testpmd: new commands for ntuple filter Jingjing Wu
@ 2015-01-15  1:46 ` Jingjing Wu
  2015-01-21 12:18 ` [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters De Lara Guarch, Pablo
  2015-01-22  7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
  6 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-15  1:46 UTC (permalink / raw)
  To: dev

Following structures are removed:
 - rte_2tuple_filter
 - rte_5tuple_filter
Following APIs are removed:
 - rte_eth_dev_add_2tuple_filter
 - rte_eth_dev_remove_2tuple_filter
 - rte_eth_dev_get_2tuple_filter
 - rte_eth_dev_add_5tuple_filter
 - rte_eth_dev_remove_5tuple_filter
 - rte_eth_dev_get_5tuple_filter
It also move macros TCP_*_FLAG to rte_eth_ctrl.h, and removes the macro
TCP_UGR_FLAG which is duplicated with TCP_URG_FLAG.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h |   7 ++
 lib/librte_ether/rte_ethdev.c   | 116 ------------------------
 lib/librte_ether/rte_ethdev.h   | 195 ----------------------------------------
 3 files changed, 7 insertions(+), 311 deletions(-)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 58d830d..ab8e9a9 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -139,6 +139,13 @@ struct rte_eth_ethertype_filter {
 		RTE_NTUPLE_FLAGS_DST_PORT | \
 		RTE_NTUPLE_FLAGS_PROTO)
 
+#define TCP_URG_FLAG 0x20
+#define TCP_ACK_FLAG 0x10
+#define TCP_PSH_FLAG 0x08
+#define TCP_RST_FLAG 0x04
+#define TCP_SYN_FLAG 0x02
+#define TCP_FIN_FLAG 0x01
+#define TCP_FLAG_ALL 0x3F
 
 /**
  * A structure used to define the ntuple filter entry
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 95f2ceb..22d76c8 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3072,122 +3072,6 @@ rte_eth_dev_get_ethertype_filter(uint8_t port_id, uint16_t index,
 }
 
 int
-rte_eth_dev_add_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-	if (filter->protocol != IPPROTO_TCP &&
-		filter->tcp_flags != 0){
-		PMD_DEBUG_TRACE("tcp flags is 0x%x, but the protocol value"
-			" is not TCP\n",
-			filter->tcp_flags);
-		return -EINVAL;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_2tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->add_2tuple_filter)(dev, index, filter, rx_queue);
-}
-
-int
-rte_eth_dev_remove_2tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_2tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->remove_2tuple_filter)(dev, index);
-}
-
-int
-rte_eth_dev_get_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (filter == NULL || rx_queue == NULL)
-		return -EINVAL;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_2tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->get_2tuple_filter)(dev, index, filter, rx_queue);
-}
-
-int
-rte_eth_dev_add_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	if (filter->protocol != IPPROTO_TCP &&
-		filter->tcp_flags != 0){
-		PMD_DEBUG_TRACE("tcp flags is 0x%x, but the protocol value"
-			" is not TCP\n",
-			filter->tcp_flags);
-		return -EINVAL;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_5tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->add_5tuple_filter)(dev, index, filter, rx_queue);
-}
-
-int
-rte_eth_dev_remove_5tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_5tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->remove_5tuple_filter)(dev, index);
-}
-
-int
-rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (filter == NULL || rx_queue == NULL)
-		return -EINVAL;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_5tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->get_5tuple_filter)(dev, index, filter,
-						rx_queue);
-}
-
-int
 rte_eth_dev_add_flex_filter(uint8_t port_id, uint16_t index,
 			struct rte_flex_filter *filter, uint16_t rx_queue)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 551b28f..f6adeaa 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -963,16 +963,6 @@ struct rte_eth_dev_callback;
 /** @internal Structure to keep track of registered callbacks */
 TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 
-
-#define TCP_URG_FLAG 0x20
-#define TCP_UGR_FLAG 0x20
-#define TCP_ACK_FLAG 0x10
-#define TCP_PSH_FLAG 0x08
-#define TCP_RST_FLAG 0x04
-#define TCP_SYN_FLAG 0x02
-#define TCP_FIN_FLAG 0x01
-#define TCP_FLAG_ALL 0x3F
-
 /**
  *  A structure used to define an ethertype filter.
  */
@@ -991,18 +981,6 @@ struct rte_syn_filter {
 };
 
 /**
- *  A structure used to define a 2tuple filter.
- */
-struct rte_2tuple_filter {
-	uint16_t dst_port;        /**< big endian. */
-	uint8_t protocol;
-	uint8_t tcp_flags;
-	uint16_t priority;        /**< used when more than one filter matches. */
-	uint8_t dst_port_mask:1,  /**< if mask is 1b, means not compare. */
-		protocol_mask:1;
-};
-
-/**
  *  A structure used to define a flex filter.
  */
 struct rte_flex_filter {
@@ -1013,25 +991,6 @@ struct rte_flex_filter {
 	uint8_t priority;
 };
 
-/**
- *  A structure used to define a 5tuple filter.
- */
-struct rte_5tuple_filter {
-	uint32_t dst_ip;         /**< destination IP address in big endian. */
-	uint32_t src_ip;         /**< source IP address in big endian. */
-	uint16_t dst_port;       /**< destination port in big endian. */
-	uint16_t src_port;       /**< source Port big endian. */
-	uint8_t protocol;        /**< l4 protocol. */
-	uint8_t tcp_flags;       /**< tcp flags. */
-	uint16_t priority;       /**< seven evels (001b-111b), 111b is highest,
-				      used when more than one filter matches. */
-	uint8_t dst_ip_mask:1,   /**< if mask is 1b, do not compare dst ip. */
-		src_ip_mask:1,   /**< if mask is 1b, do not compare src ip. */
-		dst_port_mask:1, /**< if mask is 1b, do not compare dst port. */
-		src_port_mask:1, /**< if mask is 1b, do not compare src port. */
-		protocol_mask:1; /**< if mask is 1b, do not compare protocol. */
-};
-
 /*
  * Definitions of all functions exported by an Ethernet driver through the
  * the generic structure of type *eth_dev_ops* supplied in the *rte_eth_dev*
@@ -1388,34 +1347,6 @@ typedef int (*eth_get_ethertype_filter_t)(struct rte_eth_dev *dev,
 			uint16_t *rx_queue);
 /**< @internal Get an ethertype filter rule on an Ethernet device */
 
-typedef int (*eth_add_2tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_2tuple_filter *filter,
-			uint16_t rx_queue);
-/**< @internal Setup a new 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_remove_2tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index);
-/**< @internal Remove a 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_get_2tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_2tuple_filter *filter,
-			uint16_t *rx_queue);
-/**< @internal Get a 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_add_5tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_5tuple_filter *filter,
-			uint16_t rx_queue);
-/**< @internal Setup a new 5tuple filter rule on an Ethernet device */
-
-typedef int (*eth_remove_5tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index);
-/**< @internal Remove a 5tuple filter rule on an Ethernet device */
-
-typedef int (*eth_get_5tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_5tuple_filter *filter,
-			uint16_t *rx_queue);
-/**< @internal Get a 5tuple filter rule on an Ethernet device */
-
 typedef int (*eth_add_flex_filter_t)(struct rte_eth_dev *dev,
 			uint16_t index, struct rte_flex_filter *filter,
 			uint16_t rx_queue);
@@ -1537,12 +1468,6 @@ struct eth_dev_ops {
 	eth_add_ethertype_filter_t     add_ethertype_filter;    /**< add ethertype filter. */
 	eth_remove_ethertype_filter_t  remove_ethertype_filter; /**< remove ethertype filter. */
 	eth_get_ethertype_filter_t     get_ethertype_filter;    /**< get ethertype filter. */
-	eth_add_2tuple_filter_t        add_2tuple_filter;    /**< add 2tuple filter. */
-	eth_remove_2tuple_filter_t     remove_2tuple_filter; /**< remove 2tuple filter. */
-	eth_get_2tuple_filter_t        get_2tuple_filter;    /**< get 2tuple filter. */
-	eth_add_5tuple_filter_t        add_5tuple_filter;    /**< add 5tuple filter. */
-	eth_remove_5tuple_filter_t     remove_5tuple_filter; /**< remove 5tuple filter. */
-	eth_get_5tuple_filter_t        get_5tuple_filter;    /**< get 5tuple filter. */
 	eth_add_flex_filter_t          add_flex_filter;      /**< add flex filter. */
 	eth_remove_flex_filter_t       remove_flex_filter;   /**< remove flex filter. */
 	eth_get_flex_filter_t          get_flex_filter;      /**< get flex filter. */
@@ -3538,126 +3463,6 @@ int rte_eth_dev_get_ethertype_filter(uint8_t port_id, uint16_t index,
 			struct rte_ethertype_filter *filter, uint16_t *rx_queue);
 
 /**
- * Add a new 2tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
- * @param filter
- *   The pointer to the structure describing the 2tuple filter rule.
- *   The *rte_2tuple_filter* structure includes the values of the different
- *   fields to match: protocol, dst_port and
- *   tcp_flags if the protocol is tcp type.
- * @param rx_queue
- *   The index of the RX queue where to store RX packets matching the added
- *   2tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_add_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue);
-
-/**
- * remove a 2tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_remove_2tuple_filter(uint8_t port_id, uint16_t index);
-
-/**
- * Get an 2tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
- * @param filter
- *   A pointer to a structure of type *rte_2tuple_filter* to be filled with
- *   the information of the 2tuple filter.
- * @param rx_queue
- *   A pointer to get the queue index.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- *   - (-ENOENT) if no enabled filter in this index.
- */
-int rte_eth_dev_get_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue);
-
-/**
- * Add a new 5tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
- * @param filter
- *   The pointer to the structure describing the 5tuple filter rule.
- *   The *rte_5tuple_filter* structure includes the values of the different
- *   fields to match: dst src IP, dst src port, protocol and relative masks
- * @param rx_queue
- *   The index of the RX queue where to store RX packets matching the added
- *   5tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_add_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue);
-
-/**
- * remove a 5tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_remove_5tuple_filter(uint8_t port_id, uint16_t index);
-
-/**
- * Get an 5tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
- * @param filter
- *   A pointer to a structure of type *rte_5tuple_filter* to be filled with
- *   the information of the 5tuple filter.
- * @param rx_queue
- *   A pointer to get the queue index.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue);
-
-/**
  * Add a new flex filter rule on an Ethernet device.
  *
  * @param port_id
-- 
1.9.3

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

* Re: [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters
  2015-01-15  1:45 [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters Jingjing Wu
                   ` (4 preceding siblings ...)
  2015-01-15  1:46 ` [dpdk-dev] [PATCH 5/5] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
@ 2015-01-21 12:18 ` De Lara Guarch, Pablo
  2015-01-22  0:28   ` Wu, Jingjing
  2015-01-22  7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
  6 siblings, 1 reply; 27+ messages in thread
From: De Lara Guarch, Pablo @ 2015-01-21 12:18 UTC (permalink / raw)
  To: Wu, Jingjing, dev



> -----Original Message-----
> From: Wu, Jingjing
> Sent: Thursday, January 15, 2015 1:46 AM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; De Lara Guarch, Pablo; Cao, Min
> Subject: [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters
> 
> The patch set uses new filter_ctrl API to replace old 2tuple and 5tuple filter
> APIs.
> It defines ntuple filter to combine 2tuple and 5tuple types.
> It uses new functions and structure to replace old ones in igb/ixgbe driver,
> new commands to replace old ones in testpmd, and removes the old APIs.
> It removes the filter's index parameters from user interface, only the
> filter's key and assigned queue are visible to user.
> 
> Jingjing Wu (5):
>   ethdev: define ntuple filter type and its structure
>   ixgbe: ntuple filter functions replace old ones for 5tuple filter
>   e1000: ntuple filter functions replace old ones for 2tuple and 5tuple
>     filter
>   testpmd: new commands for ntuple filter
>   ethdev: remove old APIs and structures of 5tuple and 2tuple filters
> 
>  app/test-pmd/cmdline.c              | 406 ++++++++--------
>  app/test-pmd/config.c               |  65 ---
>  lib/librte_ether/rte_eth_ctrl.h     |  57 +++
>  lib/librte_ether/rte_ethdev.c       | 116 -----
>  lib/librte_ether/rte_ethdev.h       | 193 --------
>  lib/librte_pmd_e1000/e1000_ethdev.h |  79 +++-
>  lib/librte_pmd_e1000/igb_ethdev.c   | 892 +++++++++++++++++++++++++-
> ----------
>  lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 489 +++++++++++++++-----
>  lib/librte_pmd_ixgbe/ixgbe_ethdev.h |  62 ++-
>  9 files changed, 1344 insertions(+), 1015 deletions(-)
> 
> --
> 1.9.3

Could you send a v2 of this patchset? Your previous patchset "Integrate ethertype filter in igb/ixgbe driver to new API"
(which has been applied yesterday) contains already some of the code that this patchset has.

Thanks,
Pablo

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

* Re: [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters
  2015-01-21 12:18 ` [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters De Lara Guarch, Pablo
@ 2015-01-22  0:28   ` Wu, Jingjing
  0 siblings, 0 replies; 27+ messages in thread
From: Wu, Jingjing @ 2015-01-22  0:28 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, dev

Hi, Pablo

Yes, sure.

I will send it soon. Thanks for your attention.


> -----Original Message-----
> From: De Lara Guarch, Pablo
> Sent: Wednesday, January 21, 2015 8:18 PM
> To: Wu, Jingjing; dev@dpdk.org
> Cc: Cao, Min
> Subject: RE: [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters
> 
> 
> 
> > -----Original Message-----
> > From: Wu, Jingjing
> > Sent: Thursday, January 15, 2015 1:46 AM
> > To: dev@dpdk.org
> > Cc: Wu, Jingjing; De Lara Guarch, Pablo; Cao, Min
> > Subject: [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple
> > filters
> >
> > The patch set uses new filter_ctrl API to replace old 2tuple and
> > 5tuple filter APIs.
> > It defines ntuple filter to combine 2tuple and 5tuple types.
> > It uses new functions and structure to replace old ones in igb/ixgbe
> > driver, new commands to replace old ones in testpmd, and removes the
> old APIs.
> > It removes the filter's index parameters from user interface, only the
> > filter's key and assigned queue are visible to user.
> >
> > Jingjing Wu (5):
> >   ethdev: define ntuple filter type and its structure
> >   ixgbe: ntuple filter functions replace old ones for 5tuple filter
> >   e1000: ntuple filter functions replace old ones for 2tuple and 5tuple
> >     filter
> >   testpmd: new commands for ntuple filter
> >   ethdev: remove old APIs and structures of 5tuple and 2tuple filters
> >
> >  app/test-pmd/cmdline.c              | 406 ++++++++--------
> >  app/test-pmd/config.c               |  65 ---
> >  lib/librte_ether/rte_eth_ctrl.h     |  57 +++
> >  lib/librte_ether/rte_ethdev.c       | 116 -----
> >  lib/librte_ether/rte_ethdev.h       | 193 --------
> >  lib/librte_pmd_e1000/e1000_ethdev.h |  79 +++-
> >  lib/librte_pmd_e1000/igb_ethdev.c   | 892
> +++++++++++++++++++++++++-
> > ----------
> >  lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 489 +++++++++++++++-----
> > lib/librte_pmd_ixgbe/ixgbe_ethdev.h |  62 ++-
> >  9 files changed, 1344 insertions(+), 1015 deletions(-)
> >
> > --
> > 1.9.3
> 
> Could you send a v2 of this patchset? Your previous patchset "Integrate
> ethertype filter in igb/ixgbe driver to new API"
> (which has been applied yesterday) contains already some of the code that
> this patchset has.
> 
> Thanks,
> Pablo

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

* [dpdk-dev] [PATCH v2 0/6] new ntuple filter replaces 2tuple and 5tuple filters
  2015-01-15  1:45 [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters Jingjing Wu
                   ` (5 preceding siblings ...)
  2015-01-21 12:18 ` [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters De Lara Guarch, Pablo
@ 2015-01-22  7:38 ` Jingjing Wu
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 1/6] ethdev: define ntuple filter type and its structure Jingjing Wu
                     ` (7 more replies)
  6 siblings, 8 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-22  7:38 UTC (permalink / raw)
  To: dev

v2 changes:
  - remove the code which is already applied in patch "Integrate ethertype
    filter in igb/ixgbe driver to new API".
  - modify commands' description in doc testpmd_funcs.rst.

The patch set uses filter_ctrl API to replace old 2tuple and 5tuple filter APIs.
It defines ntuple filter to combine 2tuple and 5tuple types. 
It uses new functions and structure to replace old ones in igb/ixgbe driver,
new commands to replace old ones in testpmd, and removes the old APIs.
It removes the filter's index parameters from user interface, only the
filter's key and assigned queue are visible to user.

Jingjing Wu (6):
  ethdev: define ntuple filter type and its structure
  ixgbe: ntuple filter functions replace old ones for 5tuple filter
  e1000: ntuple filter functions replace old ones for 2tuple and 5tuple
    filter
  testpmd: new commands for ntuple filter
  ethdev: remove old APIs and structures of 5tuple and 2tuple filters
  doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter

 app/test-pmd/cmdline.c                      | 406 ++++++-------
 app/test-pmd/config.c                       |  65 ---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  99 +---
 lib/librte_ether/rte_eth_ctrl.h             |  57 ++
 lib/librte_ether/rte_ethdev.c               | 116 ----
 lib/librte_ether/rte_ethdev.h               | 192 ------
 lib/librte_pmd_e1000/e1000_ethdev.h         |  69 ++-
 lib/librte_pmd_e1000/igb_ethdev.c           | 869 +++++++++++++++++++---------
 lib/librte_pmd_ixgbe/ixgbe_ethdev.c         | 468 +++++++++++----
 lib/librte_pmd_ixgbe/ixgbe_ethdev.h         |  52 +-
 10 files changed, 1300 insertions(+), 1093 deletions(-)

-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 1/6] ethdev: define ntuple filter type and its structure
  2015-01-22  7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
@ 2015-01-22  7:38   ` Jingjing Wu
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 2/6] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-22  7:38 UTC (permalink / raw)
  To: dev

This patch defines ntuple filter type RTE_ETH_FILTER_NTUPLE and its structure rte_eth_ntuple_filter.
It also corrects the typo TCP_UGR_FLAG to TCP_URG_FLAG

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h | 50 +++++++++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h   |  2 ++
 2 files changed, 52 insertions(+)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 5d9c387..3465c68 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -53,6 +53,7 @@ enum rte_filter_type {
 	RTE_ETH_FILTER_NONE = 0,
 	RTE_ETH_FILTER_MACVLAN,
 	RTE_ETH_FILTER_ETHERTYPE,
+	RTE_ETH_FILTER_NTUPLE,
 	RTE_ETH_FILTER_TUNNEL,
 	RTE_ETH_FILTER_FDIR,
 	RTE_ETH_FILTER_MAX
@@ -117,6 +118,55 @@ struct rte_eth_ethertype_filter {
 };
 
 /**
+ * Define all structures for ntuple Filter type.
+ */
+
+#define RTE_NTUPLE_FLAGS_DST_IP    0x0001 /**< If set, dst_ip is part of ntuple */
+#define RTE_NTUPLE_FLAGS_SRC_IP    0x0002 /**< If set, src_ip is part of ntuple */
+#define RTE_NTUPLE_FLAGS_DST_PORT  0x0004 /**< If set, dst_port is part of ntuple */
+#define RTE_NTUPLE_FLAGS_SRC_PORT  0x0008 /**< If set, src_port is part of ntuple */
+#define RTE_NTUPLE_FLAGS_PROTO     0x0010 /**< If set, protocol is part of ntuple */
+#define RTE_NTUPLE_FLAGS_TCP_FLAG  0x0020 /**< If set, tcp flag is involved */
+
+#define RTE_5TUPLE_FLAGS ( \
+		RTE_NTUPLE_FLAGS_DST_IP | \
+		RTE_NTUPLE_FLAGS_SRC_IP | \
+		RTE_NTUPLE_FLAGS_DST_PORT | \
+		RTE_NTUPLE_FLAGS_SRC_PORT | \
+		RTE_NTUPLE_FLAGS_PROTO)
+
+#define RTE_2TUPLE_FLAGS ( \
+		RTE_NTUPLE_FLAGS_DST_PORT | \
+		RTE_NTUPLE_FLAGS_PROTO)
+
+
+/**
+ * A structure used to define the ntuple filter entry
+ * to support RTE_ETH_FILTER_NTUPLE with RTE_ETH_FILTER_ADD,
+ * RTE_ETH_FILTER_DELETE and RTE_ETH_FILTER_GET operations.
+ */
+struct rte_eth_ntuple_filter {
+	uint16_t flags;          /**< Flags from RTE_NTUPLE_FLAGS_* */
+	uint32_t dst_ip;         /**< Destination IP address in big endian. */
+	uint32_t dst_ip_mask;    /**< Mask of destination IP address. */
+	uint32_t src_ip;         /**< Source IP address in big endian. */
+	uint32_t src_ip_mask;    /**< Mask of destination IP address. */
+	uint16_t dst_port;       /**< Destination port in big endian. */
+	uint16_t dst_port_mask;  /**< Mask of destination port. */
+	uint16_t src_port;       /**< Source Port in big endian. */
+	uint16_t src_port_mask;  /**< Mask of source port. */
+	uint8_t proto;           /**< L4 protocol. */
+	uint8_t proto_mask;      /**< Mask of L4 protocol. */
+	/** tcp_flags only meaningful when the proto is TCP.
+	    The packet matched above ntuple fields and contain
+	    any set bit in tcp_flags will hit this filter. */
+	uint8_t tcp_flags;
+	uint16_t priority;       /**< seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint16_t queue;          /**< Queue assigned to when match*/
+};
+
+/**
  * Tunneled type.
  */
 enum rte_eth_tunnel_type {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 1200c1c..5992e43 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -963,6 +963,8 @@ struct rte_eth_dev_callback;
 /** @internal Structure to keep track of registered callbacks */
 TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 
+
+#define TCP_URG_FLAG 0x20
 #define TCP_UGR_FLAG 0x20
 #define TCP_ACK_FLAG 0x10
 #define TCP_PSH_FLAG 0x08
-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 2/6] ixgbe: ntuple filter functions replace old ones for 5tuple filter
  2015-01-22  7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 1/6] ethdev: define ntuple filter type and its structure Jingjing Wu
@ 2015-01-22  7:38   ` Jingjing Wu
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 3/6] e1000: ntuple filter functions replace old ones for 2tuple and " Jingjing Wu
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-22  7:38 UTC (permalink / raw)
  To: dev

This patch defines new functions dealing with ntuple filters which is
corresponding to 5tuple in HW.
It removes old functions which deal with 5tuple filters.
Ntuple filter ie dealt with through entrance ixgbe_dev_filter_ctrl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 468 ++++++++++++++++++++++++++----------
 lib/librte_pmd_ixgbe/ixgbe_ethdev.h |  52 +++-
 2 files changed, 389 insertions(+), 131 deletions(-)

diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
index b58ec45..9f1ad5b 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
@@ -231,14 +231,18 @@ static int ixgbe_add_syn_filter(struct rte_eth_dev *dev,
 static int ixgbe_remove_syn_filter(struct rte_eth_dev *dev);
 static int ixgbe_get_syn_filter(struct rte_eth_dev *dev,
 			struct rte_syn_filter *filter, uint16_t *rx_queue);
-static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue);
-static int ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index);
-static int ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue);
-
-static int ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
+static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev,
+			struct ixgbe_5tuple_filter *filter);
+static void ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
+			struct ixgbe_5tuple_filter *filter);
+static int ixgbe_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter,
+			bool add);
+static int ixgbe_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg);
+static int ixgbe_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter);
 static int ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
 			struct rte_eth_ethertype_filter *filter,
 			bool add);
@@ -251,6 +255,7 @@ static int ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,
 		     enum rte_filter_type filter_type,
 		     enum rte_filter_op filter_op,
 		     void *arg);
+static int ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
 
 /*
  * Define VF Stats MACRO for Non "cleared on read" register
@@ -386,9 +391,6 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.add_syn_filter	         = ixgbe_add_syn_filter,
 	.remove_syn_filter       = ixgbe_remove_syn_filter,
 	.get_syn_filter          = ixgbe_get_syn_filter,
-	.add_5tuple_filter       = ixgbe_add_5tuple_filter,
-	.remove_5tuple_filter    = ixgbe_remove_5tuple_filter,
-	.get_5tuple_filter       = ixgbe_get_5tuple_filter,
 	.filter_ctrl             = ixgbe_dev_filter_ctrl,
 };
 
@@ -736,6 +738,8 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 		IXGBE_DEV_PRIVATE_TO_HWSTRIP_BITMAP(eth_dev->data->dev_private);
 	struct ixgbe_dcb_config *dcb_config =
 		IXGBE_DEV_PRIVATE_TO_DCB_CFG(eth_dev->data->dev_private);
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
 	uint32_t ctrl_ext;
 	uint16_t csum;
 	int diag, i;
@@ -917,6 +921,11 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 	/* enable support intr */
 	ixgbe_enable_intr(eth_dev);
 
+	/* initialize 5tuple filter list */
+	TAILQ_INIT(&filter_info->fivetuple_list);
+	memset(filter_info->fivetuple_mask, 0,
+		sizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);
+
 	return 0;
 }
 
@@ -1606,6 +1615,9 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ixgbe_vf_info *vfinfo =
 		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct ixgbe_5tuple_filter *p_5tuple, *p_5tuple_next;
 	int vf;
 
 	PMD_INIT_FUNC_TRACE();
@@ -1635,6 +1647,18 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
 	/* Clear recorded link status */
 	memset(&link, 0, sizeof(link));
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
+
+	/* Remove all ntuple filters of the device */
+	for (p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list);
+	     p_5tuple != NULL; p_5tuple = p_5tuple_next) {
+		p_5tuple_next = TAILQ_NEXT(p_5tuple, entries);
+		TAILQ_REMOVE(&filter_info->fivetuple_list,
+			     p_5tuple, entries);
+		rte_free(p_5tuple);
+	}
+	memset(filter_info->fivetuple_mask, 0,
+		sizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);
+
 }
 
 /*
@@ -3818,62 +3842,69 @@ revert_protocol_type(enum ixgbe_5tuple_protocol protocol)
  *    - On failure, a negative value.
  */
 static int
-ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue)
+ixgbe_add_5tuple_filter(struct rte_eth_dev *dev,
+			struct ixgbe_5tuple_filter *filter)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t ftqf, sdpqf = 0;
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	int i, idx, shift;
+	uint32_t ftqf, sdpqf;
 	uint32_t l34timir = 0;
 	uint8_t mask = 0xff;
 
-	if (hw->mac.type != ixgbe_mac_82599EB)
+	/*
+	 * look for an unused 5tuple filter index,
+	 * and insert the filter to list.
+	 */
+	for (i = 0; i < IXGBE_MAX_FTQF_FILTERS; i++) {
+		idx = i / UINT32_BIT;
+		shift = i % UINT32_BIT;
+		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 >= IXGBE_MAX_FTQF_FILTERS) {
+		PMD_DRV_LOG(ERR, "5tuple filters are full.");
 		return -ENOSYS;
-
-	if (index >= IXGBE_MAX_FTQF_FILTERS ||
-		rx_queue >= IXGBE_MAX_RX_QUEUE_NUM ||
-		filter->priority > IXGBE_5TUPLE_MAX_PRI ||
-		filter->priority < IXGBE_5TUPLE_MIN_PRI)
-		return -EINVAL;  /* filter index is out of range. */
-
-	if (filter->tcp_flags) {
-		PMD_INIT_LOG(INFO, "82599EB not tcp flags in 5tuple");
-		return -EINVAL;
 	}
 
-	ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index));
-	if (ftqf & IXGBE_FTQF_QUEUE_ENABLE)
-		return -EINVAL;  /* filter index is in use. */
-
-	ftqf = 0;
-	sdpqf = (uint32_t)(filter->dst_port << IXGBE_SDPQF_DSTPORT_SHIFT);
-	sdpqf = sdpqf | (filter->src_port & IXGBE_SDPQF_SRCPORT);
+	sdpqf = (uint32_t)(filter->filter_info.dst_port <<
+				IXGBE_SDPQF_DSTPORT_SHIFT);
+	sdpqf = sdpqf | (filter->filter_info.src_port & IXGBE_SDPQF_SRCPORT);
 
-	ftqf |= (uint32_t)(convert_protocol_type(filter->protocol) &
+	ftqf = (uint32_t)(filter->filter_info.proto &
 		IXGBE_FTQF_PROTOCOL_MASK);
-	ftqf |= (uint32_t)((filter->priority & IXGBE_FTQF_PRIORITY_MASK) <<
-		IXGBE_FTQF_PRIORITY_SHIFT);
-	if (filter->src_ip_mask == 0) /* 0 means compare. */
+	ftqf |= (uint32_t)((filter->filter_info.priority &
+		IXGBE_FTQF_PRIORITY_MASK) << IXGBE_FTQF_PRIORITY_SHIFT);
+	if (filter->filter_info.src_ip_mask == 0) /* 0 means compare. */
 		mask &= IXGBE_FTQF_SOURCE_ADDR_MASK;
-	if (filter->dst_ip_mask == 0)
+	if (filter->filter_info.dst_ip_mask == 0)
 		mask &= IXGBE_FTQF_DEST_ADDR_MASK;
-	if (filter->src_port_mask == 0)
+	if (filter->filter_info.src_port_mask == 0)
 		mask &= IXGBE_FTQF_SOURCE_PORT_MASK;
-	if (filter->dst_port_mask == 0)
+	if (filter->filter_info.dst_port_mask == 0)
 		mask &= IXGBE_FTQF_DEST_PORT_MASK;
-	if (filter->protocol_mask == 0)
+	if (filter->filter_info.proto_mask == 0)
 		mask &= IXGBE_FTQF_PROTOCOL_COMP_MASK;
 	ftqf |= mask << IXGBE_FTQF_5TUPLE_MASK_SHIFT;
 	ftqf |= IXGBE_FTQF_POOL_MASK_EN;
 	ftqf |= IXGBE_FTQF_QUEUE_ENABLE;
 
-	IXGBE_WRITE_REG(hw, IXGBE_DAQF(index), filter->dst_ip);
-	IXGBE_WRITE_REG(hw, IXGBE_SAQF(index), filter->src_ip);
-	IXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), sdpqf);
-	IXGBE_WRITE_REG(hw, IXGBE_FTQF(index), ftqf);
+	IXGBE_WRITE_REG(hw, IXGBE_DAQF(idx), filter->filter_info.dst_ip);
+	IXGBE_WRITE_REG(hw, IXGBE_SAQF(idx), filter->filter_info.src_ip);
+	IXGBE_WRITE_REG(hw, IXGBE_SDPQF(idx), sdpqf);
+	IXGBE_WRITE_REG(hw, IXGBE_FTQF(idx), ftqf);
 
 	l34timir |= IXGBE_L34T_IMIR_RESERVE;
-	l34timir |= (uint32_t)(rx_queue << IXGBE_L34T_IMIR_QUEUE_SHIFT);
-	IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), l34timir);
+	l34timir |= (uint32_t)(filter->queue <<
+				IXGBE_L34T_IMIR_QUEUE_SHIFT);
+	IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(i), l34timir);
 	return 0;
 }
 
@@ -3882,92 +3913,27 @@ ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
+ * filter: the pointer of the filter will be removed.
  */
-static int
+static void
 ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index)
+			struct ixgbe_5tuple_filter *filter)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	uint16_t index = filter->index;
 
-	if (hw->mac.type != ixgbe_mac_82599EB)
-		return -ENOSYS;
-
-	if (index >= IXGBE_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	filter_info->fivetuple_mask[index / UINT32_BIT] &=
+					~(1 << (index % UINT32_BIT));
+	TAILQ_REMOVE(&filter_info->fivetuple_list, filter, entries);
+	rte_free(filter);
 
 	IXGBE_WRITE_REG(hw, IXGBE_DAQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_SAQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_FTQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), 0);
-	return 0;
-}
-
-/*
- * get a 5tuple filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates
- * filter: ponter to the filter that returns.
- * *rx_queue: pointer of the queue id the filter assigned to.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
- */
-static int
-ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue)
-{
-	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t sdpqf, ftqf, l34timir;
-	uint8_t mask;
-	enum ixgbe_5tuple_protocol proto;
-
-	if (hw->mac.type != ixgbe_mac_82599EB)
-		return -ENOSYS;
-
-	if (index >= IXGBE_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
-
-	ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index));
-	if (ftqf & IXGBE_FTQF_QUEUE_ENABLE) {
-		proto = (enum ixgbe_5tuple_protocol)(ftqf & IXGBE_FTQF_PROTOCOL_MASK);
-		filter->protocol = revert_protocol_type(proto);
-		filter->priority = (ftqf >> IXGBE_FTQF_PRIORITY_SHIFT) &
-					IXGBE_FTQF_PRIORITY_MASK;
-		mask = (uint8_t)((ftqf >> IXGBE_FTQF_5TUPLE_MASK_SHIFT) &
-					IXGBE_FTQF_5TUPLE_MASK_MASK);
-		filter->src_ip_mask =
-			(mask & IXGBE_FTQF_SOURCE_ADDR_MASK) ? 1 : 0;
-		filter->dst_ip_mask =
-			(mask & IXGBE_FTQF_DEST_ADDR_MASK) ? 1 : 0;
-		filter->src_port_mask =
-			(mask & IXGBE_FTQF_SOURCE_PORT_MASK) ? 1 : 0;
-		filter->dst_port_mask =
-			(mask & IXGBE_FTQF_DEST_PORT_MASK) ? 1 : 0;
-		filter->protocol_mask =
-			(mask & IXGBE_FTQF_PROTOCOL_COMP_MASK) ? 1 : 0;
-
-		sdpqf = IXGBE_READ_REG(hw, IXGBE_SDPQF(index));
-		filter->dst_port = (sdpqf & IXGBE_SDPQF_DSTPORT) >>
-					IXGBE_SDPQF_DSTPORT_SHIFT;
-		filter->src_port = sdpqf & IXGBE_SDPQF_SRCPORT;
-		filter->dst_ip = IXGBE_READ_REG(hw, IXGBE_DAQF(index));
-		filter->src_ip = IXGBE_READ_REG(hw, IXGBE_SAQF(index));
-
-		l34timir = IXGBE_READ_REG(hw, IXGBE_L34T_IMIR(index));
-		*rx_queue = (l34timir & IXGBE_L34T_IMIR_QUEUE) >>
-					IXGBE_L34T_IMIR_QUEUE_SHIFT;
-		return 0;
-	}
-	return -ENOENT;
 }
 
 static int
@@ -4004,6 +3970,263 @@ ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+#define MAC_TYPE_FILTER_SUP_EXT(type)    do {\
+	if ((type) != ixgbe_mac_82599EB && (type) != ixgbe_mac_X540)\
+		return -ENOTSUP;\
+} while (0)
+
+static inline struct ixgbe_5tuple_filter *
+ixgbe_5tuple_filter_lookup(struct ixgbe_5tuple_filter_list *filter_list,
+			struct ixgbe_5tuple_filter_info *key)
+{
+	struct ixgbe_5tuple_filter *it;
+
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct ixgbe_5tuple_filter_info)) == 0) {
+			return it;
+		}
+	}
+	return NULL;
+}
+
+/* translate elements in struct rte_eth_ntuple_filter to struct ixgbe_5tuple_filter_info*/
+static inline int
+ntuple_filter_to_5tuple(struct rte_eth_ntuple_filter *filter,
+			struct ixgbe_5tuple_filter_info *filter_info)
+{
+	if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM ||
+		filter->priority > IXGBE_5TUPLE_MAX_PRI ||
+		filter->priority < IXGBE_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.
+ */
+static int
+ixgbe_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter,
+			bool add)
+{
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct ixgbe_5tuple_filter_info filter_5tuple;
+	struct ixgbe_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 ixgbe_5tuple_filter_info));
+	ret = ntuple_filter_to_5tuple(ntuple_filter, &filter_5tuple);
+	if (ret < 0)
+		return ret;
+
+	filter = ixgbe_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("ixgbe_5tuple_filter",
+				sizeof(struct ixgbe_5tuple_filter), 0);
+		if (filter == NULL)
+			return -ENOMEM;
+		(void)rte_memcpy(&filter->filter_info,
+				 &filter_5tuple,
+				 sizeof(struct ixgbe_5tuple_filter_info));
+		filter->queue = ntuple_filter->queue;
+		ret = ixgbe_add_5tuple_filter(dev, filter);
+		if (ret < 0) {
+			rte_free(filter);
+			return ret;
+		}
+	} else
+		ixgbe_remove_5tuple_filter(dev, filter);
+
+	return 0;
+}
+
+/*
+ * get a ntuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * ntuple_filter: Pointer to struct rte_eth_ntuple_filter
+ *
+ * @return
+ *    - On success, zero.
+ *    - On failure, a negative value.
+ */
+static int
+ixgbe_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
+{
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct ixgbe_5tuple_filter_info filter_5tuple;
+	struct ixgbe_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 ixgbe_5tuple_filter_info));
+	ret = ntuple_filter_to_5tuple(ntuple_filter, &filter_5tuple);
+	if (ret < 0)
+		return ret;
+
+	filter = ixgbe_5tuple_filter_lookup(&filter_info->fivetuple_list,
+					 &filter_5tuple);
+	if (filter == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
+	}
+	ntuple_filter->queue = filter->queue;
+	return 0;
+}
+
+/*
+ * ixgbe_ntuple_filter_handle - Handle operations for ntuple filter.
+ * @dev: pointer to rte_eth_dev structure
+ * @filter_op:operation will be taken.
+ * @arg: a pointer to specific structure corresponding to the filter_op
+ *
+ * @return
+ *    - On success, zero.
+ *    - On failure, a negative value.
+ */
+static int
+ixgbe_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg)
+{
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
+
+	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+
+	if (filter_op == RTE_ETH_FILTER_NOP)
+		return 0;
+
+	if (arg == NULL) {
+		PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
+			    filter_op);
+		return -EINVAL;
+	}
+
+	switch (filter_op) {
+	case RTE_ETH_FILTER_ADD:
+		ret = ixgbe_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			TRUE);
+		break;
+	case RTE_ETH_FILTER_DELETE:
+		ret = ixgbe_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			FALSE);
+		break;
+	case RTE_ETH_FILTER_GET:
+		ret = ixgbe_get_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
 #define MAC_TYPE_FILTER_SUP(type)    do {\
 	if ((type) != ixgbe_mac_82599EB && (type) != ixgbe_mac_X540 &&\
 		(type) != ixgbe_mac_X550)\
@@ -4205,6 +4428,9 @@ ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,
 	int ret = -EINVAL;
 
 	switch (filter_type) {
+	case RTE_ETH_FILTER_NTUPLE:
+		ret = ixgbe_ntuple_filter_handle(dev, filter_op, arg);
+		break;
 	case RTE_ETH_FILTER_ETHERTYPE:
 		ret = ixgbe_ethertype_filter_handle(dev, filter_op, arg);
 		break;
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
index 677c257..2b3baef 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
@@ -163,12 +163,54 @@ struct ixgbe_vf_info {
 };
 
 /*
+ *  Possible l4type of 5tuple filters.
+ */
+enum ixgbe_5tuple_protocol {
+	IXGBE_FILTER_PROTOCOL_TCP = 0,
+	IXGBE_FILTER_PROTOCOL_UDP,
+	IXGBE_FILTER_PROTOCOL_SCTP,
+	IXGBE_FILTER_PROTOCOL_NONE,
+};
+
+TAILQ_HEAD(ixgbe_5tuple_filter_list, ixgbe_5tuple_filter);
+
+struct ixgbe_5tuple_filter_info {
+	uint32_t dst_ip;
+	uint32_t src_ip;
+	uint16_t dst_port;
+	uint16_t src_port;
+	enum ixgbe_5tuple_protocol proto;        /* l4 protocol. */
+	uint8_t priority;        /* seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint8_t dst_ip_mask:1,   /* if mask is 1b, do not compare dst ip. */
+		src_ip_mask:1,   /* if mask is 1b, do not compare src ip. */
+		dst_port_mask:1, /* if mask is 1b, do not compare dst port. */
+		src_port_mask:1, /* if mask is 1b, do not compare src port. */
+		proto_mask:1;    /* if mask is 1b, do not compare protocol. */
+};
+
+/* 5tuple filter structure */
+struct ixgbe_5tuple_filter {
+	TAILQ_ENTRY(ixgbe_5tuple_filter) entries;
+	uint16_t index;       /* the index of 5tuple filter */
+	struct ixgbe_5tuple_filter_info filter_info;
+	uint16_t queue;       /* rx queue assigned to */
+};
+
+#define UINT32_BIT 32
+#define IXGBE_5TUPLE_ARRAY_SIZE \
+	(RTE_ALIGN(IXGBE_MAX_FTQF_FILTERS, UINT32_BIT) / (UINT32_BIT))
+
+/*
  * Structure to store filters' info.
  */
 struct ixgbe_filter_info {
 	uint8_t ethertype_mask;  /* Bit mask for every used ethertype filter */
 	/* store used ethertype filters*/
 	uint16_t ethertype_filters[IXGBE_MAX_ETQF_FILTERS];
+	/* Bit mask for every used 5tuple filter */
+	uint32_t fivetuple_mask[IXGBE_5TUPLE_ARRAY_SIZE];
+	struct ixgbe_5tuple_filter_list fivetuple_list;
 };
 
 /*
@@ -192,16 +234,6 @@ struct ixgbe_adapter {
 	struct ixgbe_filter_info    filter;
 };
 
-/*
- *  Possible l4type of 5tuple filters.
- */
-enum ixgbe_5tuple_protocol {
-	IXGBE_FILTER_PROTOCOL_TCP = 0,
-	IXGBE_FILTER_PROTOCOL_UDP,
-	IXGBE_FILTER_PROTOCOL_SCTP,
-	IXGBE_FILTER_PROTOCOL_NONE,
-};
-
 #define IXGBE_DEV_PRIVATE_TO_HW(adapter)\
 	(&((struct ixgbe_adapter *)adapter)->hw)
 
-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 3/6] e1000: ntuple filter functions replace old ones for 2tuple and 5tuple filter
  2015-01-22  7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 1/6] ethdev: define ntuple filter type and its structure Jingjing Wu
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 2/6] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
@ 2015-01-22  7:38   ` Jingjing Wu
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 4/6] testpmd: new commands for ntuple filter Jingjing Wu
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-22  7:38 UTC (permalink / raw)
  To: dev

This patch defines new functions dealing with ntuple filters which is
corresponding to 2tuple filter for 82580 and i350 in HW, and to 5tuple
filter for 82576 in HW.
It removes old functions which deal with 2tuple and 5tuple filters in igb driver.
Ntuple filter is dealt with through entrance eth_igb_filter_ctrl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_pmd_e1000/e1000_ethdev.h |  69 ++-
 lib/librte_pmd_e1000/igb_ethdev.c   | 869 ++++++++++++++++++++++++------------
 2 files changed, 647 insertions(+), 291 deletions(-)

diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h
index d155e77..571a70d 100644
--- a/lib/librte_pmd_e1000/e1000_ethdev.h
+++ b/lib/librte_pmd_e1000/e1000_ethdev.h
@@ -67,14 +67,6 @@
 
 #define E1000_IMIR_DSTPORT             0x0000FFFF
 #define E1000_IMIR_PRIORITY            0xE0000000
-#define E1000_IMIR_EXT_SIZE_BP         0x00001000
-#define E1000_IMIR_EXT_CTRL_UGR        0x00002000
-#define E1000_IMIR_EXT_CTRL_ACK        0x00004000
-#define E1000_IMIR_EXT_CTRL_PSH        0x00008000
-#define E1000_IMIR_EXT_CTRL_RST        0x00010000
-#define E1000_IMIR_EXT_CTRL_SYN        0x00020000
-#define E1000_IMIR_EXT_CTRL_FIN        0x00040000
-#define E1000_IMIR_EXT_CTRL_BP         0x00080000
 #define E1000_MAX_TTQF_FILTERS         8
 #define E1000_2TUPLE_MAX_PRI           7
 
@@ -96,11 +88,6 @@
 #define E1000_MAX_FTQF_FILTERS           8
 #define E1000_FTQF_PROTOCOL_MASK         0x000000FF
 #define E1000_FTQF_5TUPLE_MASK_SHIFT     28
-#define E1000_FTQF_PROTOCOL_COMP_MASK    0x10000000
-#define E1000_FTQF_SOURCE_ADDR_MASK      0x20000000
-#define E1000_FTQF_DEST_ADDR_MASK        0x40000000
-#define E1000_FTQF_SOURCE_PORT_MASK      0x80000000
-#define E1000_FTQF_VF_MASK_EN            0x00008000
 #define E1000_FTQF_QUEUE_MASK            0x03ff0000
 #define E1000_FTQF_QUEUE_SHIFT           16
 #define E1000_FTQF_QUEUE_ENABLE          0x00000100
@@ -131,6 +118,56 @@ struct e1000_vf_info {
 	uint16_t tx_rate;
 };
 
+TAILQ_HEAD(e1000_5tuple_filter_list, e1000_5tuple_filter);
+TAILQ_HEAD(e1000_2tuple_filter_list, e1000_2tuple_filter);
+
+struct e1000_5tuple_filter_info {
+	uint32_t dst_ip;
+	uint32_t src_ip;
+	uint16_t dst_port;
+	uint16_t src_port;
+	uint8_t proto;           /* l4 protocol. */
+	/* the packet matched above 5tuple and contain any set bit will hit this filter. */
+	uint8_t tcp_flags;
+	uint8_t priority;        /* seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint8_t dst_ip_mask:1,   /* if mask is 1b, do not compare dst ip. */
+		src_ip_mask:1,   /* if mask is 1b, do not compare src ip. */
+		dst_port_mask:1, /* if mask is 1b, do not compare dst port. */
+		src_port_mask:1, /* if mask is 1b, do not compare src port. */
+		proto_mask:1;    /* if mask is 1b, do not compare protocol. */
+};
+
+struct e1000_2tuple_filter_info {
+	uint16_t dst_port;
+	uint8_t proto;           /* l4 protocol. */
+	/* the packet matched above 2tuple and contain any set bit will hit this filter. */
+	uint8_t tcp_flags;
+	uint8_t priority;        /* seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint8_t dst_ip_mask:1,   /* if mask is 1b, do not compare dst ip. */
+		src_ip_mask:1,   /* if mask is 1b, do not compare src ip. */
+		dst_port_mask:1, /* if mask is 1b, do not compare dst port. */
+		src_port_mask:1, /* if mask is 1b, do not compare src port. */
+		proto_mask:1;    /* if mask is 1b, do not compare protocol. */
+};
+
+/* 5tuple filter structure */
+struct e1000_5tuple_filter {
+	TAILQ_ENTRY(e1000_5tuple_filter) entries;
+	uint16_t index;       /* the index of 5tuple filter */
+	struct e1000_5tuple_filter_info filter_info;
+	uint16_t queue;       /* rx queue assigned to */
+};
+
+/* 2tuple filter structure */
+struct e1000_2tuple_filter {
+	TAILQ_ENTRY(e1000_2tuple_filter) entries;
+	uint16_t index;         /* the index of 2tuple filter */
+	struct e1000_2tuple_filter_info filter_info;
+	uint16_t queue;       /* rx queue assigned to */
+};
+
 /*
  * Structure to store filters' info.
  */
@@ -138,6 +175,12 @@ struct e1000_filter_info {
 	uint8_t ethertype_mask; /* Bit mask for every used ethertype filter */
 	/* store used ethertype filters*/
 	uint16_t ethertype_filters[E1000_MAX_ETQF_FILTERS];
+	/* Bit mask for every used 5tuple filter */
+	uint8_t fivetuple_mask;
+	struct e1000_5tuple_filter_list fivetuple_list;
+	/* Bit mask for every used 2tuple filter */
+	uint8_t twotuple_mask;
+	struct e1000_2tuple_filter_list twotuple_list;
 };
 
 /*
diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c
index 81b2ca7..ebef67f 100644
--- a/lib/librte_pmd_e1000/igb_ethdev.c
+++ b/lib/librte_pmd_e1000/igb_ethdev.c
@@ -154,14 +154,10 @@ static int eth_igb_add_syn_filter(struct rte_eth_dev *dev,
 static int eth_igb_remove_syn_filter(struct rte_eth_dev *dev);
 static int eth_igb_get_syn_filter(struct rte_eth_dev *dev,
 			struct rte_syn_filter *filter, uint16_t *rx_queue);
-static int eth_igb_add_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue);
-static int eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index);
-static int eth_igb_get_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue);
+static int igb_add_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_remove_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
 static int eth_igb_add_flex_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_flex_filter *filter, uint16_t rx_queue);
@@ -170,14 +166,18 @@ static int eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
 static int eth_igb_get_flex_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_flex_filter *filter, uint16_t *rx_queue);
-static int eth_igb_add_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue);
-static int eth_igb_remove_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index);
-static int eth_igb_get_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue);
+static int igb_add_5tuple_filter_82576(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_remove_5tuple_filter_82576(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter,
+			bool add);
+static int igb_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter);
+static int igb_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg);
 static int igb_add_del_ethertype_filter(struct rte_eth_dev *dev,
 			struct rte_eth_ethertype_filter *filter,
 			bool add);
@@ -268,15 +268,9 @@ static struct eth_dev_ops eth_igb_ops = {
 	.add_syn_filter          = eth_igb_add_syn_filter,
 	.remove_syn_filter       = eth_igb_remove_syn_filter,
 	.get_syn_filter          = eth_igb_get_syn_filter,
-	.add_2tuple_filter       = eth_igb_add_2tuple_filter,
-	.remove_2tuple_filter    = eth_igb_remove_2tuple_filter,
-	.get_2tuple_filter       = eth_igb_get_2tuple_filter,
 	.add_flex_filter         = eth_igb_add_flex_filter,
 	.remove_flex_filter      = eth_igb_remove_flex_filter,
 	.get_flex_filter         = eth_igb_get_flex_filter,
-	.add_5tuple_filter       = eth_igb_add_5tuple_filter,
-	.remove_5tuple_filter    = eth_igb_remove_5tuple_filter,
-	.get_5tuple_filter       = eth_igb_get_5tuple_filter,
 	.filter_ctrl             = eth_igb_filter_ctrl,
 };
 
@@ -470,6 +464,8 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 		E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
 	struct e1000_vfta * shadow_vfta =
 			E1000_DEV_PRIVATE_TO_VFTA(eth_dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
 	uint32_t ctrl_ext;
 
 	pci_dev = eth_dev->pci_dev;
@@ -601,6 +597,12 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 	/* enable support intr */
 	igb_intr_enable(eth_dev);
 
+	/* initialize ntuple filter list */
+	TAILQ_INIT(&filter_info->twotuple_list);
+	filter_info->twotuple_mask = 0;
+	TAILQ_INIT(&filter_info->fivetuple_list);
+	filter_info->fivetuple_mask = 0;
+
 	return 0;
 
 err_late:
@@ -926,7 +928,11 @@ static void
 eth_igb_stop(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 	struct rte_eth_link link;
+	struct e1000_5tuple_filter *p_5tuple, *p_5tuple_next;
+	struct e1000_2tuple_filter *p_2tuple, *p_2tuple_next;
 
 	igb_intr_disable(hw);
 	igb_pf_reset_hw(hw);
@@ -949,6 +955,24 @@ eth_igb_stop(struct rte_eth_dev *dev)
 	/* clear the recorded link status */
 	memset(&link, 0, sizeof(link));
 	rte_igb_dev_atomic_write_link_status(dev, &link);
+
+	/* Remove all ntuple filters of the device */
+	for (p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list);
+	     p_5tuple != NULL; p_5tuple = p_5tuple_next) {
+		p_5tuple_next = TAILQ_NEXT(p_5tuple, entries);
+		TAILQ_REMOVE(&filter_info->fivetuple_list,
+			     p_5tuple, entries);
+		rte_free(p_5tuple);
+	}
+	filter_info->fivetuple_mask = 0;
+	for (p_2tuple = TAILQ_FIRST(&filter_info->twotuple_list);
+	     p_2tuple != NULL; p_2tuple = p_2tuple_next) {
+		p_2tuple_next = TAILQ_NEXT(p_2tuple, entries);
+		TAILQ_REMOVE(&filter_info->twotuple_list,
+			     p_2tuple, entries);
+		rte_free(p_2tuple);
+	}
+	filter_info->twotuple_mask = 0;
 }
 
 static void
@@ -2492,165 +2516,209 @@ eth_igb_get_syn_filter(struct rte_eth_dev *dev,
 		return -ENOSYS; \
 } while (0)
 
-/*
- * add a 2tuple 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
-eth_igb_add_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue)
+/* translate elements in struct rte_eth_ntuple_filter to struct e1000_2tuple_filter_info*/
+static inline int
+ntuple_filter_to_2tuple(struct rte_eth_ntuple_filter *filter,
+			struct e1000_2tuple_filter_info *filter_info)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t ttqf, imir = 0;
-	uint32_t imir_ext = 0;
-
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
-
-	if (index >= E1000_MAX_TTQF_FILTERS ||
-		rx_queue >= IGB_MAX_RX_QUEUE_NUM ||
-		filter->priority > E1000_2TUPLE_MAX_PRI)
+	if (filter->queue >= IGB_MAX_RX_QUEUE_NUM)
+		return -EINVAL;
+	if (filter->priority > E1000_2TUPLE_MAX_PRI)
 		return -EINVAL;  /* filter index is out of range. */
-	if  (filter->tcp_flags > TCP_FLAG_ALL)
+	if (filter->tcp_flags > TCP_FLAG_ALL)
 		return -EINVAL;  /* flags is invalid. */
 
-	ttqf = E1000_READ_REG(hw, E1000_TTQF(index));
-	if (ttqf & E1000_TTQF_QUEUE_ENABLE)
-		return -EINVAL;  /* filter index is in use. */
-
-	imir = (uint32_t)(filter->dst_port & E1000_IMIR_DSTPORT);
-	if (filter->dst_port_mask == 1) /* 1b means not compare. */
-		imir |= E1000_IMIR_PORT_BP;
-	else
-		imir &= ~E1000_IMIR_PORT_BP;
+	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;
+	}
 
-	imir |= filter->priority << E1000_IMIR_PRIORITY_SHIFT;
+	switch (filter->proto_mask) {
+	case UINT8_MAX:
+		filter_info->proto_mask = 0;
+		filter_info->proto = filter->proto;
+		break;
+	case 0:
+		filter_info->proto_mask = 1;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid protocol mask.");
+		return -EINVAL;
+	}
 
-	ttqf = 0;
-	ttqf |= E1000_TTQF_QUEUE_ENABLE;
-	ttqf |= (uint32_t)(rx_queue << E1000_TTQF_QUEUE_SHIFT);
-	ttqf |= (uint32_t)(filter->protocol & E1000_TTQF_PROTOCOL_MASK);
-	if (filter->protocol_mask == 1)
-		ttqf |= E1000_TTQF_MASK_ENABLE;
+	filter_info->priority = (uint8_t)filter->priority;
+	if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG)
+		filter_info->tcp_flags = filter->tcp_flags;
 	else
-		ttqf &= ~E1000_TTQF_MASK_ENABLE;
+		filter_info->tcp_flags = 0;
 
-	imir_ext |= E1000_IMIR_EXT_SIZE_BP;
-	/* tcp flags bits setting. */
-	if (filter->tcp_flags & TCP_FLAG_ALL) {
-		if (filter->tcp_flags & TCP_UGR_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_UGR;
-		if (filter->tcp_flags & TCP_ACK_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_ACK;
-		if (filter->tcp_flags & TCP_PSH_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_PSH;
-		if (filter->tcp_flags & TCP_RST_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_RST;
-		if (filter->tcp_flags & TCP_SYN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_SYN;
-		if (filter->tcp_flags & TCP_FIN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_FIN;
-		imir_ext &= ~E1000_IMIR_EXT_CTRL_BP;
-	} else
-		imir_ext |= E1000_IMIR_EXT_CTRL_BP;
-	E1000_WRITE_REG(hw, E1000_IMIR(index), imir);
-	E1000_WRITE_REG(hw, E1000_TTQF(index), ttqf);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), imir_ext);
 	return 0;
 }
 
+static inline struct e1000_2tuple_filter *
+igb_2tuple_filter_lookup(struct e1000_2tuple_filter_list *filter_list,
+			struct e1000_2tuple_filter_info *key)
+{
+	struct e1000_2tuple_filter *it;
+
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct e1000_2tuple_filter_info)) == 0) {
+			return it;
+		}
+	}
+	return NULL;
+}
+
 /*
- * remove a 2tuple filter
+ * igb_add_2tuple_filter - add a 2tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
+ * ntuple_filter: ponter to the filter that will be added.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index)
+igb_add_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_2tuple_filter *filter;
+	uint32_t ttqf = E1000_TTQF_DISABLE_MASK;
+	uint32_t imir, imir_ext = E1000_IMIREXT_SIZE_BP;
+	int i, ret;
+
+	filter = rte_zmalloc("e1000_2tuple_filter",
+			sizeof(struct e1000_2tuple_filter), 0);
+	if (filter == NULL)
+		return -ENOMEM;
 
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+	ret = ntuple_filter_to_2tuple(ntuple_filter,
+				      &filter->filter_info);
+	if (ret < 0) {
+		rte_free(filter);
+		return ret;
+	}
+	if (igb_2tuple_filter_lookup(&filter_info->twotuple_list,
+					 &filter->filter_info) != NULL) {
+		PMD_DRV_LOG(ERR, "filter exists.");
+		rte_free(filter);
+		return -EEXIST;
+	}
+	filter->queue = ntuple_filter->queue;
 
-	if (index >= E1000_MAX_TTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range */
+	/*
+	 * look for an unused 2tuple filter index,
+	 * and insert the filter to list.
+	 */
+	for (i = 0; i < E1000_MAX_TTQF_FILTERS; i++) {
+		if (!(filter_info->twotuple_mask & (1 << i))) {
+			filter_info->twotuple_mask |= 1 << i;
+			filter->index = i;
+			TAILQ_INSERT_TAIL(&filter_info->twotuple_list,
+					  filter,
+					  entries);
+			break;
+		}
+	}
+	if (i >= E1000_MAX_TTQF_FILTERS) {
+		PMD_DRV_LOG(ERR, "2tuple filters are full.");
+		rte_free(filter);
+		return -ENOSYS;
+	}
+
+	imir = (uint32_t)(filter->filter_info.dst_port & E1000_IMIR_DSTPORT);
+	if (filter->filter_info.dst_port_mask == 1) /* 1b means not compare. */
+		imir |= E1000_IMIR_PORT_BP;
+	else
+		imir &= ~E1000_IMIR_PORT_BP;
 
-	E1000_WRITE_REG(hw, E1000_TTQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIR(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), 0);
+	imir |= filter->filter_info.priority << E1000_IMIR_PRIORITY_SHIFT;
+
+	ttqf |= E1000_TTQF_QUEUE_ENABLE;
+	ttqf |= (uint32_t)(filter->queue << E1000_TTQF_QUEUE_SHIFT);
+	ttqf |= (uint32_t)(filter->filter_info.proto & E1000_TTQF_PROTOCOL_MASK);
+	if (filter->filter_info.proto_mask == 0)
+		ttqf &= ~E1000_TTQF_MASK_ENABLE;
+
+	/* tcp flags bits setting. */
+	if (filter->filter_info.tcp_flags & TCP_FLAG_ALL) {
+		if (filter->filter_info.tcp_flags & TCP_URG_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_URG;
+		if (filter->filter_info.tcp_flags & TCP_ACK_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_ACK;
+		if (filter->filter_info.tcp_flags & TCP_PSH_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_PSH;
+		if (filter->filter_info.tcp_flags & TCP_RST_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_RST;
+		if (filter->filter_info.tcp_flags & TCP_SYN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_SYN;
+		if (filter->filter_info.tcp_flags & TCP_FIN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_FIN;
+	} else
+		imir_ext |= E1000_IMIREXT_CTRL_BP;
+	E1000_WRITE_REG(hw, E1000_IMIR(i), imir);
+	E1000_WRITE_REG(hw, E1000_TTQF(i), ttqf);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(i), imir_ext);
 	return 0;
 }
 
 /*
- * get a 2tuple filter
+ * igb_remove_2tuple_filter - remove a 2tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that returns.
- * *rx_queue: pointer of the queue id the filter assigned to.
+ * ntuple_filter: ponter to the filter that will be removed.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_get_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue)
+igb_remove_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t imir, ttqf, imir_ext;
-
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_2tuple_filter_info filter_2tuple;
+	struct e1000_2tuple_filter *filter;
+	int ret;
 
-	if (index >= E1000_MAX_TTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	memset(&filter_2tuple, 0, sizeof(struct e1000_2tuple_filter_info));
+	ret = ntuple_filter_to_2tuple(ntuple_filter,
+				      &filter_2tuple);
+	if (ret < 0)
+		return ret;
 
-	ttqf = E1000_READ_REG(hw, E1000_TTQF(index));
-	if (ttqf & E1000_TTQF_QUEUE_ENABLE) {
-		imir = E1000_READ_REG(hw, E1000_IMIR(index));
-		filter->protocol = ttqf & E1000_TTQF_PROTOCOL_MASK;
-		filter->protocol_mask = (ttqf & E1000_TTQF_MASK_ENABLE) ? 1 : 0;
-		*rx_queue = (ttqf & E1000_TTQF_RX_QUEUE_MASK) >>
-				E1000_TTQF_QUEUE_SHIFT;
-		filter->dst_port = (uint16_t)(imir & E1000_IMIR_DSTPORT);
-		filter->dst_port_mask = (imir & E1000_IMIR_PORT_BP) ? 1 : 0;
-		filter->priority = (imir & E1000_IMIR_PRIORITY) >>
-			E1000_IMIR_PRIORITY_SHIFT;
-
-		imir_ext = E1000_READ_REG(hw, E1000_IMIREXT(index));
-		if (!(imir_ext & E1000_IMIR_EXT_CTRL_BP)) {
-			if (imir_ext & E1000_IMIR_EXT_CTRL_UGR)
-				filter->tcp_flags |= TCP_UGR_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_ACK)
-				filter->tcp_flags |= TCP_ACK_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_PSH)
-				filter->tcp_flags |= TCP_PSH_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_RST)
-				filter->tcp_flags |= TCP_RST_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_SYN)
-				filter->tcp_flags |= TCP_SYN_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_FIN)
-				filter->tcp_flags |= TCP_FIN_FLAG;
-		} else
-			filter->tcp_flags = 0;
-		return 0;
+	filter = igb_2tuple_filter_lookup(&filter_info->twotuple_list,
+					 &filter_2tuple);
+	if (filter == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
 	}
-	return -ENOENT;
+
+	filter_info->twotuple_mask &= ~(1 << filter->index);
+	TAILQ_REMOVE(&filter_info->twotuple_list, filter, entries);
+	rte_free(filter);
+
+	E1000_WRITE_REG(hw, E1000_TTQF(filter->index), E1000_TTQF_DISABLE_MASK);
+	E1000_WRITE_REG(hw, E1000_IMIR(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(filter->index), 0);
+	return 0;
 }
 
 /*
@@ -2808,192 +2876,265 @@ eth_igb_get_flex_filter(struct rte_eth_dev *dev, uint16_t index,
 	return -ENOENT;
 }
 
-/*
- * 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
-eth_igb_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue)
+/* translate elements in struct rte_eth_ntuple_filter to struct e1000_5tuple_filter_info*/
+static inline int
+ntuple_filter_to_5tuple_82576(struct rte_eth_ntuple_filter *filter,
+			struct e1000_5tuple_filter_info *filter_info)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t ftqf, spqf = 0;
-	uint32_t imir = 0;
-	uint32_t imir_ext = 0;
+	if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576)
+		return -EINVAL;
+	if (filter->priority > E1000_2TUPLE_MAX_PRI)
+		return -EINVAL;  /* filter index is out of range. */
+	if (filter->tcp_flags > TCP_FLAG_ALL)
+		return -EINVAL;  /* flags is invalid. */
 
-	if (hw->mac.type != e1000_82576)
-		return -ENOSYS;
+	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;
+	}
 
-	if (index >= E1000_MAX_FTQF_FILTERS ||
-		rx_queue >= IGB_MAX_RX_QUEUE_NUM_82576)
-		return -EINVAL;  /* filter index is out of range. */
+	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;
+	}
 
-	ftqf = E1000_READ_REG(hw, E1000_FTQF(index));
-	if (ftqf & E1000_FTQF_QUEUE_ENABLE)
-		return -EINVAL;  /* filter index is in use. */
-
-	ftqf = 0;
-	ftqf |= filter->protocol & E1000_FTQF_PROTOCOL_MASK;
-	if (filter->src_ip_mask == 1) /* 1b means not compare. */
-		ftqf |= E1000_FTQF_SOURCE_ADDR_MASK;
-	if (filter->dst_ip_mask == 1)
-		ftqf |= E1000_FTQF_DEST_ADDR_MASK;
-	if (filter->src_port_mask == 1)
-		ftqf |= E1000_FTQF_SOURCE_PORT_MASK;
-	if (filter->protocol_mask == 1)
-		ftqf |= E1000_FTQF_PROTOCOL_COMP_MASK;
-	ftqf |= (rx_queue << E1000_FTQF_QUEUE_SHIFT) & E1000_FTQF_QUEUE_MASK;
-	ftqf |= E1000_FTQF_VF_MASK_EN;
-	ftqf |= E1000_FTQF_QUEUE_ENABLE;
-	E1000_WRITE_REG(hw, E1000_FTQF(index), ftqf);
-	E1000_WRITE_REG(hw, E1000_DAQF(index), filter->dst_ip);
-	E1000_WRITE_REG(hw, E1000_SAQF(index), filter->src_ip);
+	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;
+	}
 
-	spqf |= filter->src_port & E1000_SPQF_SRCPORT;
-	E1000_WRITE_REG(hw, E1000_SPQF(index), spqf);
+	switch (filter->proto_mask) {
+	case UINT8_MAX:
+		filter_info->proto_mask = 0;
+		filter_info->proto = filter->proto;
+		break;
+	case 0:
+		filter_info->proto_mask = 1;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid protocol mask.");
+		return -EINVAL;
+	}
 
-	imir |= (uint32_t)(filter->dst_port & E1000_IMIR_DSTPORT);
-	if (filter->dst_port_mask == 1) /* 1b means not compare. */
-		imir |= E1000_IMIR_PORT_BP;
+	filter_info->priority = (uint8_t)filter->priority;
+	if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG)
+		filter_info->tcp_flags = filter->tcp_flags;
 	else
-		imir &= ~E1000_IMIR_PORT_BP;
-	imir |= filter->priority << E1000_IMIR_PRIORITY_SHIFT;
+		filter_info->tcp_flags = 0;
 
-	imir_ext |= E1000_IMIR_EXT_SIZE_BP;
-	/* tcp flags bits setting. */
-	if (filter->tcp_flags & TCP_FLAG_ALL) {
-		if (filter->tcp_flags & TCP_UGR_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_UGR;
-		if (filter->tcp_flags & TCP_ACK_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_ACK;
-		if (filter->tcp_flags & TCP_PSH_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_PSH;
-		if (filter->tcp_flags & TCP_RST_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_RST;
-		if (filter->tcp_flags & TCP_SYN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_SYN;
-		if (filter->tcp_flags & TCP_FIN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_FIN;
-	} else
-		imir_ext |= E1000_IMIR_EXT_CTRL_BP;
-	E1000_WRITE_REG(hw, E1000_IMIR(index), imir);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), imir_ext);
 	return 0;
 }
 
+static inline struct e1000_5tuple_filter *
+igb_5tuple_filter_lookup_82576(struct e1000_5tuple_filter_list *filter_list,
+			struct e1000_5tuple_filter_info *key)
+{
+	struct e1000_5tuple_filter *it;
+
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct e1000_5tuple_filter_info)) == 0) {
+			return it;
+		}
+	}
+	return NULL;
+}
+
 /*
- * remove a 5tuple filter
+ * igb_add_5tuple_filter_82576 - add a 5tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates
+ * ntuple_filter: ponter to the filter that will be added.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_remove_5tuple_filter(struct rte_eth_dev *dev,
-				uint16_t index)
+igb_add_5tuple_filter_82576(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_5tuple_filter *filter;
+	uint32_t ftqf = E1000_FTQF_VF_BP | E1000_FTQF_MASK;
+	uint32_t spqf, imir, imir_ext = E1000_IMIREXT_SIZE_BP;
+	uint8_t i;
+	int ret;
+
+	filter = rte_zmalloc("e1000_5tuple_filter",
+			sizeof(struct e1000_5tuple_filter), 0);
+	if (filter == NULL)
+		return -ENOMEM;
+
+	ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+					    &filter->filter_info);
+	if (ret < 0) {
+		rte_free(filter);
+		return ret;
+	}
 
-	if (hw->mac.type != e1000_82576)
+	if (igb_5tuple_filter_lookup_82576(&filter_info->fivetuple_list,
+					 &filter->filter_info) != NULL) {
+		PMD_DRV_LOG(ERR, "filter exists.");
+		rte_free(filter);
+		return -EEXIST;
+	}
+	filter->queue = ntuple_filter->queue;
+
+	/*
+	 * look for an unused 5tuple filter index,
+	 * and insert the filter to list.
+	 */
+	for (i = 0; i < E1000_MAX_FTQF_FILTERS; i++) {
+		if (!(filter_info->fivetuple_mask & (1 << i))) {
+			filter_info->fivetuple_mask |= 1 << i;
+			filter->index = i;
+			TAILQ_INSERT_TAIL(&filter_info->fivetuple_list,
+					  filter,
+					  entries);
+			break;
+		}
+	}
+	if (i >= E1000_MAX_FTQF_FILTERS) {
+		PMD_DRV_LOG(ERR, "5tuple filters are full.");
+		rte_free(filter);
 		return -ENOSYS;
+	}
 
-	if (index >= E1000_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	ftqf |= filter->filter_info.proto & E1000_FTQF_PROTOCOL_MASK;
+	if (filter->filter_info.src_ip_mask == 0) /* 0b means compare. */
+		ftqf &= ~E1000_FTQF_MASK_SOURCE_ADDR_BP;
+	if (filter->filter_info.dst_ip_mask == 0)
+		ftqf &= ~E1000_FTQF_MASK_DEST_ADDR_BP;
+	if (filter->filter_info.src_port_mask == 0)
+		ftqf &= ~E1000_FTQF_MASK_SOURCE_PORT_BP;
+	if (filter->filter_info.proto_mask == 0)
+		ftqf &= ~E1000_FTQF_MASK_PROTO_BP;
+	ftqf |= (filter->queue << E1000_FTQF_QUEUE_SHIFT) &
+		E1000_FTQF_QUEUE_MASK;
+	ftqf |= E1000_FTQF_QUEUE_ENABLE;
+	E1000_WRITE_REG(hw, E1000_FTQF(i), ftqf);
+	E1000_WRITE_REG(hw, E1000_DAQF(i), filter->filter_info.dst_ip);
+	E1000_WRITE_REG(hw, E1000_SAQF(i), filter->filter_info.src_ip);
+
+	spqf = filter->filter_info.src_port & E1000_SPQF_SRCPORT;
+	E1000_WRITE_REG(hw, E1000_SPQF(i), spqf);
 
-	E1000_WRITE_REG(hw, E1000_FTQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_DAQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_SAQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_SPQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIR(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), 0);
+	imir = (uint32_t)(filter->filter_info.dst_port & E1000_IMIR_DSTPORT);
+	if (filter->filter_info.dst_port_mask == 1) /* 1b means not compare. */
+		imir |= E1000_IMIR_PORT_BP;
+	else
+		imir &= ~E1000_IMIR_PORT_BP;
+	imir |= filter->filter_info.priority << E1000_IMIR_PRIORITY_SHIFT;
+
+	/* tcp flags bits setting. */
+	if (filter->filter_info.tcp_flags & TCP_FLAG_ALL) {
+		if (filter->filter_info.tcp_flags & TCP_URG_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_URG;
+		if (filter->filter_info.tcp_flags & TCP_ACK_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_ACK;
+		if (filter->filter_info.tcp_flags & TCP_PSH_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_PSH;
+		if (filter->filter_info.tcp_flags & TCP_RST_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_RST;
+		if (filter->filter_info.tcp_flags & TCP_SYN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_SYN;
+		if (filter->filter_info.tcp_flags & TCP_FIN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_FIN;
+	} else
+		imir_ext |= E1000_IMIREXT_CTRL_BP;
+	E1000_WRITE_REG(hw, E1000_IMIR(i), imir);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(i), imir_ext);
 	return 0;
 }
 
 /*
- * get a 5tuple filter
+ * igb_remove_5tuple_filter_82576 - remove a 5tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates
- * filter: ponter to the filter that returns
- * *rx_queue: pointer of the queue id the filter assigned to
+ * ntuple_filter: ponter to the filter that will be removed.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue)
+igb_remove_5tuple_filter_82576(struct rte_eth_dev *dev,
+				struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t spqf, ftqf, imir, imir_ext;
-
-	if (hw->mac.type != e1000_82576)
-		return -ENOSYS;
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_5tuple_filter_info filter_5tuple;
+	struct e1000_5tuple_filter *filter;
+	int ret;
 
-	if (index >= E1000_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	memset(&filter_5tuple, 0, sizeof(struct e1000_5tuple_filter_info));
+	ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+					    &filter_5tuple);
+	if (ret < 0)
+		return ret;
 
-	ftqf = E1000_READ_REG(hw, E1000_FTQF(index));
-	if (ftqf & E1000_FTQF_QUEUE_ENABLE) {
-		filter->src_ip_mask =
-			(ftqf & E1000_FTQF_SOURCE_ADDR_MASK) ? 1 : 0;
-		filter->dst_ip_mask =
-			(ftqf & E1000_FTQF_DEST_ADDR_MASK) ? 1 : 0;
-		filter->src_port_mask =
-			(ftqf & E1000_FTQF_SOURCE_PORT_MASK) ? 1 : 0;
-		filter->protocol_mask =
-			(ftqf & E1000_FTQF_PROTOCOL_COMP_MASK) ? 1 : 0;
-		filter->protocol =
-			(uint8_t)ftqf & E1000_FTQF_PROTOCOL_MASK;
-		*rx_queue = (uint16_t)((ftqf & E1000_FTQF_QUEUE_MASK) >>
-				E1000_FTQF_QUEUE_SHIFT);
-
-		spqf = E1000_READ_REG(hw, E1000_SPQF(index));
-		filter->src_port = spqf & E1000_SPQF_SRCPORT;
-
-		filter->dst_ip = E1000_READ_REG(hw, E1000_DAQF(index));
-		filter->src_ip = E1000_READ_REG(hw, E1000_SAQF(index));
-
-		imir = E1000_READ_REG(hw, E1000_IMIR(index));
-		filter->dst_port_mask = (imir & E1000_IMIR_PORT_BP) ? 1 : 0;
-		filter->dst_port = (uint16_t)(imir & E1000_IMIR_DSTPORT);
-		filter->priority = (imir & E1000_IMIR_PRIORITY) >>
-			E1000_IMIR_PRIORITY_SHIFT;
-
-		imir_ext = E1000_READ_REG(hw, E1000_IMIREXT(index));
-		if (!(imir_ext & E1000_IMIR_EXT_CTRL_BP)) {
-			if (imir_ext & E1000_IMIR_EXT_CTRL_UGR)
-				filter->tcp_flags |= TCP_UGR_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_ACK)
-				filter->tcp_flags |= TCP_ACK_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_PSH)
-				filter->tcp_flags |= TCP_PSH_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_RST)
-				filter->tcp_flags |= TCP_RST_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_SYN)
-				filter->tcp_flags |= TCP_SYN_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_FIN)
-				filter->tcp_flags |= TCP_FIN_FLAG;
-		} else
-			filter->tcp_flags = 0;
-		return 0;
+	filter = igb_5tuple_filter_lookup_82576(&filter_info->fivetuple_list,
+					 &filter_5tuple);
+	if (filter == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
 	}
-	return -ENOENT;
+
+	filter_info->fivetuple_mask &= ~(1 << filter->index);
+	TAILQ_REMOVE(&filter_info->fivetuple_list, filter, entries);
+	rte_free(filter);
+
+	E1000_WRITE_REG(hw, E1000_FTQF(filter->index),
+			E1000_FTQF_VF_BP | E1000_FTQF_MASK);
+	E1000_WRITE_REG(hw, E1000_DAQF(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_SAQF(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_SPQF(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_IMIR(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(filter->index), 0);
+	return 0;
 }
 
 static int
@@ -3046,6 +3187,175 @@ eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+/*
+ * igb_add_del_ntuple_filter - 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.
+ */
+static int
+igb_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter,
+			bool add)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
+
+	switch (ntuple_filter->flags) {
+	case RTE_5TUPLE_FLAGS:
+	case (RTE_5TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82576)
+			return -ENOTSUP;
+		if (add)
+			ret = igb_add_5tuple_filter_82576(dev,
+							  ntuple_filter);
+		else
+			ret = igb_remove_5tuple_filter_82576(dev,
+							     ntuple_filter);
+		break;
+	case RTE_2TUPLE_FLAGS:
+	case (RTE_2TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82580 && hw->mac.type != e1000_i350)
+			return -ENOTSUP;
+		if (add)
+			ret = igb_add_2tuple_filter(dev, ntuple_filter);
+		else
+			ret = igb_remove_2tuple_filter(dev, ntuple_filter);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * igb_get_ntuple_filter - get a ntuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * ntuple_filter: Pointer to struct rte_eth_ntuple_filter
+ *
+ * @return
+ *    - On success, zero.
+ *    - On failure, a negative value.
+ */
+static int
+igb_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_5tuple_filter_info filter_5tuple;
+	struct e1000_2tuple_filter_info filter_2tuple;
+	struct e1000_5tuple_filter *p_5tuple_filter;
+	struct e1000_2tuple_filter *p_2tuple_filter;
+	int ret;
+
+	switch (ntuple_filter->flags) {
+	case RTE_5TUPLE_FLAGS:
+	case (RTE_5TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82576)
+			return -ENOTSUP;
+		memset(&filter_5tuple,
+			0,
+			sizeof(struct e1000_5tuple_filter_info));
+		ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+						    &filter_5tuple);
+		if (ret < 0)
+			return ret;
+		p_5tuple_filter = igb_5tuple_filter_lookup_82576(
+					&filter_info->fivetuple_list,
+					&filter_5tuple);
+		if (p_5tuple_filter == NULL) {
+			PMD_DRV_LOG(ERR, "filter doesn't exist.");
+			return -ENOENT;
+		}
+		ntuple_filter->queue = p_5tuple_filter->queue;
+		break;
+	case RTE_2TUPLE_FLAGS:
+	case (RTE_2TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82580 && hw->mac.type != e1000_i350)
+			return -ENOTSUP;
+		memset(&filter_2tuple,
+			0,
+			sizeof(struct e1000_2tuple_filter_info));
+		ret = ntuple_filter_to_2tuple(ntuple_filter, &filter_2tuple);
+		if (ret < 0)
+			return ret;
+		p_2tuple_filter = igb_2tuple_filter_lookup(
+					&filter_info->twotuple_list,
+					&filter_2tuple);
+		if (p_2tuple_filter == NULL) {
+			PMD_DRV_LOG(ERR, "filter doesn't exist.");
+			return -ENOENT;
+		}
+		ntuple_filter->queue = p_2tuple_filter->queue;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * igb_ntuple_filter_handle - Handle operations for ntuple filter.
+ * @dev: pointer to rte_eth_dev structure
+ * @filter_op:operation will be taken.
+ * @arg: a pointer to specific structure corresponding to the filter_op
+ */
+static int
+igb_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
+
+	MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+	if (filter_op == RTE_ETH_FILTER_NOP)
+		return 0;
+
+	if (arg == NULL) {
+		PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
+			    filter_op);
+		return -EINVAL;
+	}
+
+	switch (filter_op) {
+	case RTE_ETH_FILTER_ADD:
+		ret = igb_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			TRUE);
+		break;
+	case RTE_ETH_FILTER_DELETE:
+		ret = igb_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			FALSE);
+		break;
+	case RTE_ETH_FILTER_GET:
+		ret = igb_get_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
 static inline int
 igb_ethertype_filter_lookup(struct e1000_filter_info *filter_info,
 			uint16_t ethertype)
@@ -3235,6 +3545,9 @@ eth_igb_filter_ctrl(struct rte_eth_dev *dev,
 	int ret = -EINVAL;
 
 	switch (filter_type) {
+	case RTE_ETH_FILTER_NTUPLE:
+		ret = igb_ntuple_filter_handle(dev, filter_op, arg);
+		break;
 	case RTE_ETH_FILTER_ETHERTYPE:
 		ret = igb_ethertype_filter_handle(dev, filter_op, arg);
 		break;
-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 4/6] testpmd: new commands for ntuple filter
  2015-01-22  7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
                     ` (2 preceding siblings ...)
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 3/6] e1000: ntuple filter functions replace old ones for 2tuple and " Jingjing Wu
@ 2015-01-22  7:38   ` Jingjing Wu
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 5/6] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-22  7:38 UTC (permalink / raw)
  To: dev

Following commands of 5tuple and 2tuple filter are removed:
 - add_2tuple_filter (port_id) protocol (pro_value) (pro_mask)
   dst_port (port_value) (port_mask) flags (flg_value) priority (prio
   queue (queue_id) index (idx)
 - remove_2tuple_filter (port_id) index (idx)
 - get_2tuple_filter (port_id) index (idx)
 - add_5tuple_filter (port_id) dst_ip (dst_address) src_ip (src_addres
   dst_port (dst_port_value) src_port (src_port_value) protocol (prot
   mask (mask_value) flags (flags_value) priority (prio_value)"
   queue (queue_id) index (idx)
 - remove_5tuple_filter (port_id) index (idx)
 - get_5tuple_filter (port_id) index (idx)

New commands are added for 5tuple and 2tuple filter by using filter_ctrl API
and new ntuple filter structure:
 - 2tuple_filter (port_id) (add|del)
   dst_port (dst_port_value) protocol (protocol_value)
   mask (mask_value) tcp_flags (tcp_flags_value)
   priority (prio_value) queue (queue_id)
 - 5tuple_filter (port_id) (add|del)
   dst_ip (dst_address) src_ip (src_address)
   dst_port (dst_port_value) src_port (src_port_value)
   protocol (protocol_value)
   mask (mask_value) tcp_flags (tcp_flags_value)
   priority (prio_value) queue (queue_id)

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c | 406 ++++++++++++++++++++++---------------------------
 app/test-pmd/config.c  |  65 --------
 2 files changed, 186 insertions(+), 285 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 4beb404..790b142 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -659,28 +659,19 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" (ether_type) (drop|fwd) queue (queue_id)\n"
 			"    Add/Del an ethertype filter.\n\n"
 
-			"add_2tuple_filter (port_id) protocol (pro_value) (pro_mask)"
-			" dst_port (port_value) (port_mask) flags (flg_value) priority (prio_value)"
-			" queue (queue_id) index (idx)\n"
-			"    add a 2tuple filter.\n\n"
-
-			"remove_2tuple_filter (port_id) index (idx)\n"
-			"    remove a 2tuple filter.\n\n"
-
-			"get_2tuple_filter (port_id) index (idx)\n"
-			"    get info of a 2tuple filter.\n\n"
-
-			"add_5tuple_filter (port_id) dst_ip (dst_address) src_ip (src_address)"
-			" dst_port (dst_port_value) src_port (src_port_value) protocol (protocol_value)"
-			" mask (mask_value) flags (flags_value) priority (prio_value)"
-			" queue (queue_id) index (idx)\n"
-			"    add a 5tuple filter.\n\n"
-
-			"remove_5tuple_filter (port_id) index (idx)\n"
-			"    remove a 5tuple filter.\n\n"
-
-			"get_5tuple_filter (port_id) index (idx)\n"
-			"    get info of a 5tuple filter.\n\n"
+			"2tuple_filter (port_id) (add|del)"
+			" dst_port (dst_port_value) protocol (protocol_value)"
+			" mask (mask_value) tcp_flags (tcp_flags_value)"
+			" priority (prio_value) queue (queue_id)\n"
+			"    Add/Del a 2tuple filter.\n\n"
+
+			"5tuple_filter (port_id) (add|del)"
+			" dst_ip (dst_address) src_ip (src_address)"
+			" dst_port (dst_port_value) src_port (src_port_value)"
+			" protocol (protocol_value)"
+			" mask (mask_value) tcp_flags (tcp_flags_value)"
+			" priority (prio_value) queue (queue_id)\n"
+			"    Add/Del a 5tuple filter.\n\n"
 
 			"add_syn_filter (port_id) priority (high|low) queue (queue_id)"
 			"    add syn filter.\n\n"
@@ -7357,21 +7348,20 @@ cmdline_parse_inst_t cmd_get_syn_filter = {
 /* *** ADD/REMOVE A 2tuple FILTER *** */
 struct cmd_2tuple_filter_result {
 	cmdline_fixed_string_t filter;
-	uint8_t port_id;
-	cmdline_fixed_string_t protocol;
-	uint8_t protocol_value;
-	uint8_t protocol_mask;
+	uint8_t  port_id;
+	cmdline_fixed_string_t ops;
 	cmdline_fixed_string_t dst_port;
 	uint16_t dst_port_value;
-	uint16_t dst_port_mask;
-	cmdline_fixed_string_t flags;
-	uint8_t flags_value;
+	cmdline_fixed_string_t protocol;
+	uint8_t protocol_value;
+	cmdline_fixed_string_t mask;
+	uint8_t  mask_value;
+	cmdline_fixed_string_t tcp_flags;
+	uint8_t tcp_flags_value;
 	cmdline_fixed_string_t priority;
-	uint8_t priority_value;
+	uint8_t  priority_value;
 	cmdline_fixed_string_t queue;
-	uint16_t queue_id;
-	cmdline_fixed_string_t index;
-	uint16_t index_value;
+	uint16_t  queue_id;
 };
 
 static void
@@ -7379,59 +7369,92 @@ cmd_2tuple_filter_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
 			__attribute__((unused)) void *data)
 {
-	int ret = 0;
-	struct rte_2tuple_filter filter;
+	struct rte_eth_ntuple_filter filter;
 	struct cmd_2tuple_filter_result *res = parsed_result;
+	int ret = 0;
 
-	memset(&filter, 0, sizeof(struct rte_2tuple_filter));
+	ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
+	if (ret < 0) {
+		printf("ntuple filter is not supported on port %u.\n",
+			res->port_id);
+		return;
+	}
 
-	if (!strcmp(res->filter, "add_2tuple_filter")) {
-		/* need convert to big endian. */
-		filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
-		filter.protocol = res->protocol_value;
-		filter.dst_port_mask = (res->dst_port_mask) ? 0 : 1;
-		filter.protocol_mask = (res->protocol_mask) ? 0 : 1;
-		filter.priority = res->priority_value;
-		filter.tcp_flags = res->flags_value;
-		ret = rte_eth_dev_add_2tuple_filter(res->port_id,
-			res->index_value, &filter, res->queue_id);
-	} else if (!strcmp(res->filter, "remove_2tuple_filter"))
-		ret = rte_eth_dev_remove_2tuple_filter(res->port_id,
-			res->index_value);
-	else if (!strcmp(res->filter, "get_2tuple_filter"))
-		get_2tuple_filter(res->port_id, res->index_value);
+	memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
 
+	filter.flags = RTE_2TUPLE_FLAGS;
+	filter.dst_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
+	filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
+	filter.proto = res->protocol_value;
+	filter.priority = res->priority_value;
+	if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
+		printf("nonzero tcp_flags is only meaningful"
+			" when protocol is TCP.\n");
+		return;
+	}
+	if (res->tcp_flags_value > TCP_FLAG_ALL) {
+		printf("invalid TCP flags.\n");
+		return;
+	}
+
+	if (res->tcp_flags_value != 0) {
+		filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
+		filter.tcp_flags = res->tcp_flags_value;
+	}
+
+	/* need convert to big endian. */
+	filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
+	filter.queue = res->queue_id;
+
+	if (!strcmp(res->ops, "add"))
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_ADD,
+				&filter);
+	else
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_DELETE,
+				&filter);
 	if (ret < 0)
-		printf("2tuple filter setting error: (%s)\n", strerror(-ret));
+		printf("2tuple filter programming error: (%s)\n",
+			strerror(-ret));
+
 }
 
+cmdline_parse_token_string_t cmd_2tuple_filter_filter =
+	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+				 filter, "2tuple_filter");
 cmdline_parse_token_num_t cmd_2tuple_filter_port_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
 				port_id, UINT8);
-cmdline_parse_token_string_t cmd_2tuple_filter_protocol =
+cmdline_parse_token_string_t cmd_2tuple_filter_ops =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				 protocol, "protocol");
-cmdline_parse_token_num_t cmd_2tuple_filter_protocol_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				 protocol_value, UINT8);
-cmdline_parse_token_num_t cmd_2tuple_filter_protocol_mask =
-	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				protocol_mask, UINT8);
+				 ops, "add#del");
 cmdline_parse_token_string_t cmd_2tuple_filter_dst_port =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
 				dst_port, "dst_port");
 cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
 				dst_port_value, UINT16);
-cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_mask =
+cmdline_parse_token_string_t cmd_2tuple_filter_protocol =
+	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+				protocol, "protocol");
+cmdline_parse_token_num_t cmd_2tuple_filter_protocol_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				dst_port_mask, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_flags =
+				protocol_value, UINT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_mask =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				flags, "flags");
-cmdline_parse_token_num_t cmd_2tuple_filter_flags_value =
+				mask, "mask");
+cmdline_parse_token_num_t cmd_2tuple_filter_mask_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				flags_value, UINT8);
+				mask_value, INT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_tcp_flags =
+	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+				tcp_flags, "tcp_flags");
+cmdline_parse_token_num_t cmd_2tuple_filter_tcp_flags_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+				tcp_flags_value, UINT8);
 cmdline_parse_token_string_t cmd_2tuple_filter_priority =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
 				priority, "priority");
@@ -7444,67 +7467,27 @@ cmdline_parse_token_string_t cmd_2tuple_filter_queue =
 cmdline_parse_token_num_t cmd_2tuple_filter_queue_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
 				queue_id, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_index =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				index, "index");
-cmdline_parse_token_num_t cmd_2tuple_filter_index_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				index_value, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_add_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				filter, "add_2tuple_filter");
-cmdline_parse_inst_t cmd_add_2tuple_filter = {
+
+cmdline_parse_inst_t cmd_2tuple_filter = {
 	.f = cmd_2tuple_filter_parsed,
 	.data = NULL,
 	.help_str = "add a 2tuple filter",
 	.tokens = {
-		(void *)&cmd_2tuple_filter_add_filter,
+		(void *)&cmd_2tuple_filter_filter,
 		(void *)&cmd_2tuple_filter_port_id,
-		(void *)&cmd_2tuple_filter_protocol,
-		(void *)&cmd_2tuple_filter_protocol_value,
-		(void *)&cmd_2tuple_filter_protocol_mask,
+		(void *)&cmd_2tuple_filter_ops,
 		(void *)&cmd_2tuple_filter_dst_port,
 		(void *)&cmd_2tuple_filter_dst_port_value,
-		(void *)&cmd_2tuple_filter_dst_port_mask,
-		(void *)&cmd_2tuple_filter_flags,
-		(void *)&cmd_2tuple_filter_flags_value,
+		(void *)&cmd_2tuple_filter_protocol,
+		(void *)&cmd_2tuple_filter_protocol_value,
+		(void *)&cmd_2tuple_filter_mask,
+		(void *)&cmd_2tuple_filter_mask_value,
+		(void *)&cmd_2tuple_filter_tcp_flags,
+		(void *)&cmd_2tuple_filter_tcp_flags_value,
 		(void *)&cmd_2tuple_filter_priority,
 		(void *)&cmd_2tuple_filter_priority_value,
 		(void *)&cmd_2tuple_filter_queue,
 		(void *)&cmd_2tuple_filter_queue_id,
-		(void *)&cmd_2tuple_filter_index,
-		(void *)&cmd_2tuple_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_2tuple_filter_remove_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				filter, "remove_2tuple_filter");
-cmdline_parse_inst_t cmd_remove_2tuple_filter = {
-	.f = cmd_2tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "remove a 2tuple filter",
-	.tokens = {
-		(void *)&cmd_2tuple_filter_remove_filter,
-		(void *)&cmd_2tuple_filter_port_id,
-		(void *)&cmd_2tuple_filter_index,
-		(void *)&cmd_2tuple_filter_index_value,
-		NULL,
-	},
-};
-cmdline_parse_token_string_t cmd_2tuple_filter_get_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				filter, "get_2tuple_filter");
-cmdline_parse_inst_t cmd_get_2tuple_filter = {
-	.f = cmd_2tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "get a 2tuple filter",
-	.tokens = {
-		(void *)&cmd_2tuple_filter_get_filter,
-		(void *)&cmd_2tuple_filter_port_id,
-		(void *)&cmd_2tuple_filter_index,
-		(void *)&cmd_2tuple_filter_index_value,
 		NULL,
 	},
 };
@@ -7513,6 +7496,7 @@ cmdline_parse_inst_t cmd_get_2tuple_filter = {
 struct cmd_5tuple_filter_result {
 	cmdline_fixed_string_t filter;
 	uint8_t  port_id;
+	cmdline_fixed_string_t ops;
 	cmdline_fixed_string_t dst_ip;
 	cmdline_ipaddr_t dst_ip_value;
 	cmdline_fixed_string_t src_ip;
@@ -7525,14 +7509,12 @@ struct cmd_5tuple_filter_result {
 	uint8_t protocol_value;
 	cmdline_fixed_string_t mask;
 	uint8_t  mask_value;
-	cmdline_fixed_string_t flags;
-	uint8_t flags_value;
+	cmdline_fixed_string_t tcp_flags;
+	uint8_t tcp_flags_value;
 	cmdline_fixed_string_t priority;
 	uint8_t  priority_value;
 	cmdline_fixed_string_t queue;
 	uint16_t  queue_id;
-	cmdline_fixed_string_t index;
-	uint16_t  index_value;
 };
 
 static void
@@ -7540,62 +7522,92 @@ cmd_5tuple_filter_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
 			__attribute__((unused)) void *data)
 {
-	int ret = 0;
-	struct rte_5tuple_filter filter;
+	struct rte_eth_ntuple_filter filter;
 	struct cmd_5tuple_filter_result *res = parsed_result;
+	int ret = 0;
 
-	memset(&filter, 0, sizeof(struct rte_5tuple_filter));
+	ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
+	if (ret < 0) {
+		printf("ntuple filter is not supported on port %u.\n",
+			res->port_id);
+		return;
+	}
 
-	if (!strcmp(res->filter, "add_5tuple_filter")) {
-		filter.dst_ip_mask = (res->mask_value & 0x10) ? 0 : 1;
-		filter.src_ip_mask = (res->mask_value & 0x08) ? 0 : 1;
-		filter.dst_port_mask = (res->mask_value & 0x04) ? 0 : 1;
-		filter.src_port_mask = (res->mask_value & 0x02) ? 0 : 1;
-		filter.protocol = res->protocol_value;
-		filter.protocol_mask = (res->mask_value & 0x01) ? 0 : 1;
-		filter.priority = res->priority_value;
-		filter.tcp_flags = res->flags_value;
+	memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
+
+	filter.flags = RTE_5TUPLE_FLAGS;
+	filter.dst_ip_mask = (res->mask_value & 0x10) ? UINT32_MAX : 0;
+	filter.src_ip_mask = (res->mask_value & 0x08) ? UINT32_MAX : 0;
+	filter.dst_port_mask = (res->mask_value & 0x04) ? UINT16_MAX : 0;
+	filter.src_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
+	filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
+	filter.proto = res->protocol_value;
+	filter.priority = res->priority_value;
+	if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
+		printf("nonzero tcp_flags is only meaningful"
+			" when protocol is TCP.\n");
+		return;
+	}
+	if (res->tcp_flags_value > TCP_FLAG_ALL) {
+		printf("invalid TCP flags.\n");
+		return;
+	}
 
-		if (res->dst_ip_value.family == AF_INET)
-			/* no need to convert, already big endian. */
-			filter.dst_ip = res->dst_ip_value.addr.ipv4.s_addr;
-		else {
-			if (filter.dst_ip_mask == 0) {
-				printf("can not support ipv6 involved compare.\n");
-				return;
-			}
-			filter.dst_ip = 0;
+	if (res->tcp_flags_value != 0) {
+		filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
+		filter.tcp_flags = res->tcp_flags_value;
+	}
+
+	if (res->dst_ip_value.family == AF_INET)
+		/* no need to convert, already big endian. */
+		filter.dst_ip = res->dst_ip_value.addr.ipv4.s_addr;
+	else {
+		if (filter.dst_ip_mask == 0) {
+			printf("can not support ipv6 involved compare.\n");
+			return;
 		}
+		filter.dst_ip = 0;
+	}
 
-		if (res->src_ip_value.family == AF_INET)
-			/* no need to convert, already big endian. */
-			filter.src_ip = res->src_ip_value.addr.ipv4.s_addr;
-		else {
-			if (filter.src_ip_mask == 0) {
-				printf("can not support ipv6 involved compare.\n");
-				return;
-			}
-			filter.src_ip = 0;
+	if (res->src_ip_value.family == AF_INET)
+		/* no need to convert, already big endian. */
+		filter.src_ip = res->src_ip_value.addr.ipv4.s_addr;
+	else {
+		if (filter.src_ip_mask == 0) {
+			printf("can not support ipv6 involved compare.\n");
+			return;
 		}
-		/* need convert to big endian. */
-		filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
-		filter.src_port = rte_cpu_to_be_16(res->src_port_value);
+		filter.src_ip = 0;
+	}
+	/* need convert to big endian. */
+	filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
+	filter.src_port = rte_cpu_to_be_16(res->src_port_value);
+	filter.queue = res->queue_id;
 
-		ret = rte_eth_dev_add_5tuple_filter(res->port_id,
-			res->index_value, &filter, res->queue_id);
-	} else if (!strcmp(res->filter, "remove_5tuple_filter"))
-		ret = rte_eth_dev_remove_5tuple_filter(res->port_id,
-			res->index_value);
-	else if (!strcmp(res->filter, "get_5tuple_filter"))
-		get_5tuple_filter(res->port_id, res->index_value);
+	if (!strcmp(res->ops, "add"))
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_ADD,
+				&filter);
+	else
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_DELETE,
+				&filter);
 	if (ret < 0)
-		printf("5tuple filter setting error: (%s)\n", strerror(-ret));
+		printf("5tuple filter programming error: (%s)\n",
+			strerror(-ret));
 }
 
-
+cmdline_parse_token_string_t cmd_5tuple_filter_filter =
+	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+				 filter, "5tuple_filter");
 cmdline_parse_token_num_t cmd_5tuple_filter_port_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
 				port_id, UINT8);
+cmdline_parse_token_string_t cmd_5tuple_filter_ops =
+	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+				 ops, "add#del");
 cmdline_parse_token_string_t cmd_5tuple_filter_dst_ip =
 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
 				dst_ip, "dst_ip");
@@ -7632,12 +7644,12 @@ cmdline_parse_token_string_t cmd_5tuple_filter_mask =
 cmdline_parse_token_num_t cmd_5tuple_filter_mask_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
 				mask_value, INT8);
-cmdline_parse_token_string_t cmd_5tuple_filter_flags =
+cmdline_parse_token_string_t cmd_5tuple_filter_tcp_flags =
 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				flags, "flags");
-cmdline_parse_token_num_t cmd_5tuple_filter_flags_value =
+				tcp_flags, "tcp_flags");
+cmdline_parse_token_num_t cmd_5tuple_filter_tcp_flags_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
-				flags_value, UINT8);
+				tcp_flags_value, UINT8);
 cmdline_parse_token_string_t cmd_5tuple_filter_priority =
 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
 				priority, "priority");
@@ -7650,23 +7662,15 @@ cmdline_parse_token_string_t cmd_5tuple_filter_queue =
 cmdline_parse_token_num_t cmd_5tuple_filter_queue_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
 				queue_id, UINT16);
-cmdline_parse_token_string_t cmd_5tuple_filter_index =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				index, "index");
-cmdline_parse_token_num_t cmd_5tuple_filter_index_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
-				index_value, UINT16);
 
-cmdline_parse_token_string_t cmd_5tuple_filter_add_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				 filter, "add_5tuple_filter");
-cmdline_parse_inst_t cmd_add_5tuple_filter = {
+cmdline_parse_inst_t cmd_5tuple_filter = {
 	.f = cmd_5tuple_filter_parsed,
 	.data = NULL,
-	.help_str = "add a 5tuple filter",
+	.help_str = "add/del a 5tuple filter",
 	.tokens = {
-		(void *)&cmd_5tuple_filter_add_filter,
+		(void *)&cmd_5tuple_filter_filter,
 		(void *)&cmd_5tuple_filter_port_id,
+		(void *)&cmd_5tuple_filter_ops,
 		(void *)&cmd_5tuple_filter_dst_ip,
 		(void *)&cmd_5tuple_filter_dst_ip_value,
 		(void *)&cmd_5tuple_filter_src_ip,
@@ -7679,46 +7683,12 @@ cmdline_parse_inst_t cmd_add_5tuple_filter = {
 		(void *)&cmd_5tuple_filter_protocol_value,
 		(void *)&cmd_5tuple_filter_mask,
 		(void *)&cmd_5tuple_filter_mask_value,
-		(void *)&cmd_5tuple_filter_flags,
-		(void *)&cmd_5tuple_filter_flags_value,
+		(void *)&cmd_5tuple_filter_tcp_flags,
+		(void *)&cmd_5tuple_filter_tcp_flags_value,
 		(void *)&cmd_5tuple_filter_priority,
 		(void *)&cmd_5tuple_filter_priority_value,
 		(void *)&cmd_5tuple_filter_queue,
 		(void *)&cmd_5tuple_filter_queue_id,
-		(void *)&cmd_5tuple_filter_index,
-		(void *)&cmd_5tuple_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_5tuple_filter_remove_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				filter, "remove_5tuple_filter");
-cmdline_parse_inst_t cmd_remove_5tuple_filter = {
-	.f = cmd_5tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "remove a 5tuple filter",
-	.tokens = {
-		(void *)&cmd_5tuple_filter_remove_filter,
-		(void *)&cmd_5tuple_filter_port_id,
-		(void *)&cmd_5tuple_filter_index,
-		(void *)&cmd_5tuple_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_5tuple_filter_get_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				filter, "get_5tuple_filter");
-cmdline_parse_inst_t cmd_get_5tuple_filter = {
-	.f = cmd_5tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "get a 5tuple filter",
-	.tokens = {
-		(void *)&cmd_5tuple_filter_get_filter,
-		(void *)&cmd_5tuple_filter_port_id,
-		(void *)&cmd_5tuple_filter_index,
-		(void *)&cmd_5tuple_filter_index_value,
 		NULL,
 	},
 };
@@ -8792,12 +8762,8 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_add_syn_filter,
 	(cmdline_parse_inst_t *)&cmd_remove_syn_filter,
 	(cmdline_parse_inst_t *)&cmd_get_syn_filter,
-	(cmdline_parse_inst_t *)&cmd_add_2tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_remove_2tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_get_2tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_add_5tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_remove_5tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_get_5tuple_filter,
+	(cmdline_parse_inst_t *)&cmd_2tuple_filter,
+	(cmdline_parse_inst_t *)&cmd_5tuple_filter,
 	(cmdline_parse_inst_t *)&cmd_add_flex_filter,
 	(cmdline_parse_inst_t *)&cmd_remove_flex_filter,
 	(cmdline_parse_inst_t *)&cmd_get_flex_filter,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index c40f819..441ad93 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2186,73 +2186,8 @@ get_syn_filter(uint8_t port_id)
 		filter.hig_pri ? "high" : "low",
 		rx_queue);
 }
-void
-get_2tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_2tuple_filter filter;
-	int ret = 0;
-	uint16_t rx_queue;
-
-	memset(&filter, 0, sizeof(filter));
-	ret = rte_eth_dev_get_2tuple_filter(port_id, index,
-				&filter, &rx_queue);
-	if (ret < 0) {
-		if (ret == (-ENOENT))
-			printf("filter[%d] is not enabled\n", index);
-		else
-			printf("get 2tuple filter fails(%s)\n", strerror(-ret));
-		return;
-	} else {
-		printf("filter[%d]:\n", index);
-		printf("    Destination Port:     0x%04x    mask: %d\n",
-			rte_be_to_cpu_16(filter.dst_port),
-			filter.dst_port_mask ? 0 : 1);
-		printf("    protocol:  0x%02x     mask:%d     tcp_flags: 0x%02x\n",
-			filter.protocol, filter.protocol_mask ? 0 : 1,
-			filter.tcp_flags);
-		printf("    priority: %d    queue: %d\n",
-			filter.priority, rx_queue);
-	}
-}
 
 void
-get_5tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_5tuple_filter filter;
-	int ret = 0;
-	uint16_t rx_queue;
-
-	memset(&filter, 0, sizeof(filter));
-	ret = rte_eth_dev_get_5tuple_filter(port_id, index,
-				&filter, &rx_queue);
-	if (ret < 0) {
-		if (ret == (-ENOENT))
-			printf("filter[%d] is not enabled\n", index);
-		else
-			printf("get 5tuple filter fails(%s)\n", strerror(-ret));
-		return;
-	} else {
-		printf("filter[%d]:\n", index);
-		printf("    Destination IP:  0x%08x    mask: %d\n",
-			(unsigned)rte_be_to_cpu_32(filter.dst_ip),
-			filter.dst_ip_mask ? 0 : 1);
-		printf("    Source IP:       0x%08x    mask: %d\n",
-			(unsigned)rte_be_to_cpu_32(filter.src_ip),
-			filter.src_ip_mask ? 0 : 1);
-		printf("    Destination Port:       0x%04x    mask: %d\n",
-			rte_be_to_cpu_16(filter.dst_port),
-			filter.dst_port_mask ? 0 : 1);
-		printf("    Source Port:       0x%04x    mask: %d\n",
-			rte_be_to_cpu_16(filter.src_port),
-			filter.src_port_mask ? 0 : 1);
-		printf("    protocol:           0x%02x    mask: %d\n",
-			filter.protocol,
-			filter.protocol_mask ? 0 : 1);
-		printf("    priority: %d    flags: 0x%02x    queue: %d\n",
-			filter.priority, filter.tcp_flags, rx_queue);
-	}
-}
-void
 get_flex_filter(uint8_t port_id, uint16_t index)
 
 {
-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 5/6] ethdev: remove old APIs and structures of 5tuple and 2tuple filters
  2015-01-22  7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
                     ` (3 preceding siblings ...)
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 4/6] testpmd: new commands for ntuple filter Jingjing Wu
@ 2015-01-22  7:38   ` Jingjing Wu
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 6/6] doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter Jingjing Wu
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-22  7:38 UTC (permalink / raw)
  To: dev

Following structures are removed:
 - rte_2tuple_filter
 - rte_5tuple_filter
Following APIs are removed:
 - rte_eth_dev_add_2tuple_filter
 - rte_eth_dev_remove_2tuple_filter
 - rte_eth_dev_get_2tuple_filter
 - rte_eth_dev_add_5tuple_filter
 - rte_eth_dev_remove_5tuple_filter
 - rte_eth_dev_get_5tuple_filter
It also move macros TCP_*_FLAG to rte_eth_ctrl.h, and removes the macro
TCP_UGR_FLAG which is duplicated with TCP_URG_FLAG.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h |   7 ++
 lib/librte_ether/rte_ethdev.c   | 116 ------------------------
 lib/librte_ether/rte_ethdev.h   | 194 ----------------------------------------
 3 files changed, 7 insertions(+), 310 deletions(-)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 3465c68..e4b9b52 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -139,6 +139,13 @@ struct rte_eth_ethertype_filter {
 		RTE_NTUPLE_FLAGS_DST_PORT | \
 		RTE_NTUPLE_FLAGS_PROTO)
 
+#define TCP_URG_FLAG 0x20
+#define TCP_ACK_FLAG 0x10
+#define TCP_PSH_FLAG 0x08
+#define TCP_RST_FLAG 0x04
+#define TCP_SYN_FLAG 0x02
+#define TCP_FIN_FLAG 0x01
+#define TCP_FLAG_ALL 0x3F
 
 /**
  * A structure used to define the ntuple filter entry
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index ea3a1fb..a2e71e0 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3056,122 +3056,6 @@ rte_eth_dev_get_syn_filter(uint8_t port_id,
 }
 
 int
-rte_eth_dev_add_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-	if (filter->protocol != IPPROTO_TCP &&
-		filter->tcp_flags != 0){
-		PMD_DEBUG_TRACE("tcp flags is 0x%x, but the protocol value"
-			" is not TCP\n",
-			filter->tcp_flags);
-		return -EINVAL;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_2tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->add_2tuple_filter)(dev, index, filter, rx_queue);
-}
-
-int
-rte_eth_dev_remove_2tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_2tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->remove_2tuple_filter)(dev, index);
-}
-
-int
-rte_eth_dev_get_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (filter == NULL || rx_queue == NULL)
-		return -EINVAL;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_2tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->get_2tuple_filter)(dev, index, filter, rx_queue);
-}
-
-int
-rte_eth_dev_add_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	if (filter->protocol != IPPROTO_TCP &&
-		filter->tcp_flags != 0){
-		PMD_DEBUG_TRACE("tcp flags is 0x%x, but the protocol value"
-			" is not TCP\n",
-			filter->tcp_flags);
-		return -EINVAL;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_5tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->add_5tuple_filter)(dev, index, filter, rx_queue);
-}
-
-int
-rte_eth_dev_remove_5tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_5tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->remove_5tuple_filter)(dev, index);
-}
-
-int
-rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (filter == NULL || rx_queue == NULL)
-		return -EINVAL;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_5tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->get_5tuple_filter)(dev, index, filter,
-						rx_queue);
-}
-
-int
 rte_eth_dev_add_flex_filter(uint8_t port_id, uint16_t index,
 			struct rte_flex_filter *filter, uint16_t rx_queue)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 5992e43..c50ae67 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -963,16 +963,6 @@ struct rte_eth_dev_callback;
 /** @internal Structure to keep track of registered callbacks */
 TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 
-
-#define TCP_URG_FLAG 0x20
-#define TCP_UGR_FLAG 0x20
-#define TCP_ACK_FLAG 0x10
-#define TCP_PSH_FLAG 0x08
-#define TCP_RST_FLAG 0x04
-#define TCP_SYN_FLAG 0x02
-#define TCP_FIN_FLAG 0x01
-#define TCP_FLAG_ALL 0x3F
-
 /**
  *  A structure used to define an syn filter.
  */
@@ -982,18 +972,6 @@ struct rte_syn_filter {
 };
 
 /**
- *  A structure used to define a 2tuple filter.
- */
-struct rte_2tuple_filter {
-	uint16_t dst_port;        /**< big endian. */
-	uint8_t protocol;
-	uint8_t tcp_flags;
-	uint16_t priority;        /**< used when more than one filter matches. */
-	uint8_t dst_port_mask:1,  /**< if mask is 1b, means not compare. */
-		protocol_mask:1;
-};
-
-/**
  *  A structure used to define a flex filter.
  */
 struct rte_flex_filter {
@@ -1004,25 +982,6 @@ struct rte_flex_filter {
 	uint8_t priority;
 };
 
-/**
- *  A structure used to define a 5tuple filter.
- */
-struct rte_5tuple_filter {
-	uint32_t dst_ip;         /**< destination IP address in big endian. */
-	uint32_t src_ip;         /**< source IP address in big endian. */
-	uint16_t dst_port;       /**< destination port in big endian. */
-	uint16_t src_port;       /**< source Port big endian. */
-	uint8_t protocol;        /**< l4 protocol. */
-	uint8_t tcp_flags;       /**< tcp flags. */
-	uint16_t priority;       /**< seven evels (001b-111b), 111b is highest,
-				      used when more than one filter matches. */
-	uint8_t dst_ip_mask:1,   /**< if mask is 1b, do not compare dst ip. */
-		src_ip_mask:1,   /**< if mask is 1b, do not compare src ip. */
-		dst_port_mask:1, /**< if mask is 1b, do not compare dst port. */
-		src_port_mask:1, /**< if mask is 1b, do not compare src port. */
-		protocol_mask:1; /**< if mask is 1b, do not compare protocol. */
-};
-
 /*
  * Definitions of all functions exported by an Ethernet driver through the
  * the generic structure of type *eth_dev_ops* supplied in the *rte_eth_dev*
@@ -1365,33 +1324,6 @@ typedef int (*eth_get_syn_filter_t)(struct rte_eth_dev *dev,
 			struct rte_syn_filter *filter, uint16_t *rx_queue);
 /**< @internal Get syn filter rule on an Ethernet device */
 
-typedef int (*eth_add_2tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_2tuple_filter *filter,
-			uint16_t rx_queue);
-/**< @internal Setup a new 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_remove_2tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index);
-/**< @internal Remove a 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_get_2tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_2tuple_filter *filter,
-			uint16_t *rx_queue);
-/**< @internal Get a 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_add_5tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_5tuple_filter *filter,
-			uint16_t rx_queue);
-/**< @internal Setup a new 5tuple filter rule on an Ethernet device */
-
-typedef int (*eth_remove_5tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index);
-/**< @internal Remove a 5tuple filter rule on an Ethernet device */
-
-typedef int (*eth_get_5tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_5tuple_filter *filter,
-			uint16_t *rx_queue);
-/**< @internal Get a 5tuple filter rule on an Ethernet device */
 
 typedef int (*eth_add_flex_filter_t)(struct rte_eth_dev *dev,
 			uint16_t index, struct rte_flex_filter *filter,
@@ -1511,12 +1443,6 @@ struct eth_dev_ops {
 	eth_add_syn_filter_t           add_syn_filter;       /**< add syn filter. */
 	eth_remove_syn_filter_t        remove_syn_filter;    /**< remove syn filter. */
 	eth_get_syn_filter_t           get_syn_filter;       /**< get syn filter. */
-	eth_add_2tuple_filter_t        add_2tuple_filter;    /**< add 2tuple filter. */
-	eth_remove_2tuple_filter_t     remove_2tuple_filter; /**< remove 2tuple filter. */
-	eth_get_2tuple_filter_t        get_2tuple_filter;    /**< get 2tuple filter. */
-	eth_add_5tuple_filter_t        add_5tuple_filter;    /**< add 5tuple filter. */
-	eth_remove_5tuple_filter_t     remove_5tuple_filter; /**< remove 5tuple filter. */
-	eth_get_5tuple_filter_t        get_5tuple_filter;    /**< get 5tuple filter. */
 	eth_add_flex_filter_t          add_flex_filter;      /**< add flex filter. */
 	eth_remove_flex_filter_t       remove_flex_filter;   /**< remove flex filter. */
 	eth_get_flex_filter_t          get_flex_filter;      /**< get flex filter. */
@@ -3450,126 +3376,6 @@ int rte_eth_dev_get_syn_filter(uint8_t port_id,
 			struct rte_syn_filter *filter, uint16_t *rx_queue);
 
 /**
- * Add a new 2tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
- * @param filter
- *   The pointer to the structure describing the 2tuple filter rule.
- *   The *rte_2tuple_filter* structure includes the values of the different
- *   fields to match: protocol, dst_port and
- *   tcp_flags if the protocol is tcp type.
- * @param rx_queue
- *   The index of the RX queue where to store RX packets matching the added
- *   2tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_add_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue);
-
-/**
- * remove a 2tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_remove_2tuple_filter(uint8_t port_id, uint16_t index);
-
-/**
- * Get an 2tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
- * @param filter
- *   A pointer to a structure of type *rte_2tuple_filter* to be filled with
- *   the information of the 2tuple filter.
- * @param rx_queue
- *   A pointer to get the queue index.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- *   - (-ENOENT) if no enabled filter in this index.
- */
-int rte_eth_dev_get_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue);
-
-/**
- * Add a new 5tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
- * @param filter
- *   The pointer to the structure describing the 5tuple filter rule.
- *   The *rte_5tuple_filter* structure includes the values of the different
- *   fields to match: dst src IP, dst src port, protocol and relative masks
- * @param rx_queue
- *   The index of the RX queue where to store RX packets matching the added
- *   5tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_add_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue);
-
-/**
- * remove a 5tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_remove_5tuple_filter(uint8_t port_id, uint16_t index);
-
-/**
- * Get an 5tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
- * @param filter
- *   A pointer to a structure of type *rte_5tuple_filter* to be filled with
- *   the information of the 5tuple filter.
- * @param rx_queue
- *   A pointer to get the queue index.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue);
-
-/**
  * Add a new flex filter rule on an Ethernet device.
  *
  * @param port_id
-- 
1.9.3

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

* [dpdk-dev] [PATCH v2 6/6] doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter
  2015-01-22  7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
                     ` (4 preceding siblings ...)
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 5/6] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
@ 2015-01-22  7:38   ` Jingjing Wu
  2015-01-28 14:28   ` [dpdk-dev] [PATCH v2 0/6] new ntuple filter replaces 2tuple and 5tuple filters De Lara Guarch, Pablo
  2015-02-10  4:48   ` [dpdk-dev] [PATCH v3 " Jingjing Wu
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-01-22  7:38 UTC (permalink / raw)
  To: dev

document of new commands:
 - 2tuple_filter (port_id) (add|del)
   dst_port (dst_port_value) protocol (protocol_value)
   mask (mask_value) tcp_flags (tcp_flags_value)
   priority (prio_value) queue (queue_id)
 - 5tuple_filter (port_id) (add|del)
   dst_ip (dst_address) src_ip (src_address)
   dst_port (dst_port_value) src_port (src_port_value)
   protocol (protocol_value)
   mask (mask_value) tcp_flags (tcp_flags_value)
   priority (prio_value) queue (queue_id)

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 99 ++++++-----------------------
 1 file changed, 21 insertions(+), 78 deletions(-)

diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index be935c2..56d7c82 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1448,76 +1448,48 @@ Example:
         priority: disable, 0
         queue: 3
 
-add_2tuple_filter
+2tuple_filter
 ~~~~~~~~~~~~~~~~~
 
-Add a 2-tuple filter,
+Add or delete a 2-tuple filter,
 which identify packets by specific protocol and destination TCP/UDP port
 and forwards packets into one of the receive queues.
 
-add_2tuple_filter (port_id) protocol (pro_value) (pro_mask) dst_port (port_value) (port_mask)
-flags (flg_value) priority (prio_value) queue (queue_id) index (idx)
+2tuple_filter (port_id) (add|del) dst_port (dst_port_value) protocol (protocol_value)
+mask (mask_value) tcp_flags (tcp_flags_value) priority (prio_value) queue (queue_id)
 
 The available information parameters are:
 
 *   port_id: the port which the 2-tuple filter assigned on.
 
-*   pro_value: IP L4 protocol
+*   dst_port_value: destination port in L4.
 
-*   pro_mask: protocol participates in the match or not, 1 means participate
+*   protocol_value: IP L4 protocol.
 
-*   port_value: destination port in L4.
+*   mask_value: participates in the match or not by bit for field above, 1b means participate.
 
-*   port_mask: destination port participates in the match or not, 1 means participate.
+*   tcp_flags_value: TCP control bits. The non-zero value is invalid, when the pro_value is not set to 0x06 (TCP).
 
-*   flg_value: TCP control bits. The non-zero value is invalid, when the pro_value is not set to 0x06 (TCP).
+*   prio_value: priority of this filter.
 
-*   prio_value: the priority of this filter.
-
-*   queue_id: The receive queue associated with this 2-tuple filter
+*   queue_id: The receive queue associated with this 2-tuple filter.
 
-*   index: the index of this 2-tuple filter
-
-Example:
+Example, to add/remove an 2tuple filter rule:
 
 .. code-block:: console
 
-    testpmd> add_2tuple_filter 0 protocol 0x06 1 dst_port 32 1 flags 0x02 priority 3 queue 3 index 0
-
-remove_2tuple_filter
-~~~~~~~~~~~~~~~~~~~~
-
-Remove a 2-tuple filter
-
-remove_2tuple_filter (port_id) index (idx)
+    testpmd> 2tuple_filter 0 add dst_port 32 protocol 0x06 mask 0x03 tcp_flags 0x02 priority 3 queue 3
+    testpmd> 2tuple_filter 0 del dst_port 32 protocol 0x06 mask 0x03 tcp_flags 0x02 priority 3 queue 3
 
-get_2tuple_filter
+5tuple_filter
 ~~~~~~~~~~~~~~~~~
 
-Get and display a 2-tuple filter
-
-get_2tuple_filter (port_id) index (idx)
-
-Example:
-
-.. code-block:: console
-
-    testpmd> get_2tuple_filter 0 index 0
-
-    filter[0]:
-        Destination Port: 0x0020 mask: 1
-        protocol: 0x06 mask:1 tcp_flags: 0x02
-        priority: 3   queue: 3
-
-add_5tuple_filter
-~~~~~~~~~~~~~~~~~
-
-Add a 5-tuple filter,
+Add or delete a 5-tuple filter,
 which consists of a 5-tuple (protocol, source and destination IP addresses, source and destination TCP/UDP/SCTP port)
 and routes packets into one of the receive queues.
 
-add_5tuple_filter (port_id) dst_ip (dst_address) src_ip (src_address) dst_port (dst_port_value) src_port (src_port_value)
-protocol (protocol_value) mask (mask_value) flags (flags_value) priority (prio_value) queue (queue_id) index (idx)
+5tuple_filter (port_id) (add|del) dst_ip (dst_address) src_ip (src_address) dst_port (dst_port_value) src_port (src_port_value)
+protocol (protocol_value) mask (mask_value) tcp_flags (tcp_flags_value) priority (prio_value) queue (queue_id)
 
 The available information parameters are:
 
@@ -1535,47 +1507,18 @@ The available information parameters are:
 
 *   mask_value: participates in the match or not by bit for field above, 1b means participate
 
-*   flags_value: TCP control bits. The non-zero value is invalid, when the protocol_value is not set to 0x06 (TCP).
+*   tcp_flags_value: TCP control bits. The non-zero value is invalid, when the protocol_value is not set to 0x06 (TCP).
 
 *   prio_value: the priority of this filter.
 
 *   queue_id: The receive queue associated with this 5-tuple filter.
 
-*   index: the index of this 5-tuple filter
-
-Example:
-
-.. code-block:: console
-
-    testpmd> add_5tuple_filter 1 dst_ip 2.2.2.5 src_ip 2.2.2.4 dst_port 64 src_port 32 protocol 0x06 mask 0x1F flags 0x0 priority 3 queue 3 index 0
-
-remove_5tuple_filter
-~~~~~~~~~~~~~~~~~~~~
-
-Remove a 5-tuple filter
-
-remove_5tuple_filter (port_id) index (idx)
-
-get_5tuple_filter
-~~~~~~~~~~~~~~~~~
-
-Get and display a 5-tuple filter
-
-get_5tuple_filter (port_id) index (idx)
-
-Example:
+Example, to add/remove an 5tuple filter rule:
 
 .. code-block:: console
 
-    testpmd> get_5tuple_filter 1 index 0
-
-    filter[0]:
-        Destination IP: 0x02020205 mask: 1
-        Source IP: 0x02020204 mask: 1
-        Destination Port: 0x0040 mask: 1
-        Source Port: 0x0020 mask: 1
-        protocol: 0x06 mask: 1
-        priority: 3 flags: 0x00 queue: 3
+    testpmd> 5tuple_filter 0 add dst_ip 2.2.2.5 src_ip 2.2.2.4 dst_port 64 src_port 32 protocol 0x06 mask 0x1F flags 0x0 priority 3 queue 3
+    testpmd> 5tuple_filter 0 del dst_ip 2.2.2.5 src_ip 2.2.2.4 dst_port 64 src_port 32 protocol 0x06 mask 0x1F flags 0x0 priority 3 queue 3
 
 add_syn_filter
 ~~~~~~~~~~~~~~
-- 
1.9.3

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

* Re: [dpdk-dev] [PATCH v2 0/6] new ntuple filter replaces 2tuple and 5tuple filters
  2015-01-22  7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
                     ` (5 preceding siblings ...)
  2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 6/6] doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter Jingjing Wu
@ 2015-01-28 14:28   ` De Lara Guarch, Pablo
  2015-01-30  8:22     ` Wu, Jingjing
  2015-02-10  4:48   ` [dpdk-dev] [PATCH v3 " Jingjing Wu
  7 siblings, 1 reply; 27+ messages in thread
From: De Lara Guarch, Pablo @ 2015-01-28 14:28 UTC (permalink / raw)
  To: Wu, Jingjing, dev



> -----Original Message-----
> From: Wu, Jingjing
> Sent: Thursday, January 22, 2015 7:38 AM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; De Lara Guarch, Pablo; Cao, Min; Xu, HuilongX
> Subject: [PATCH v2 0/6] new ntuple filter replaces 2tuple and 5tuple filters
> 
> v2 changes:
>   - remove the code which is already applied in patch "Integrate ethertype
>     filter in igb/ixgbe driver to new API".
>   - modify commands' description in doc testpmd_funcs.rst.
> 
> The patch set uses filter_ctrl API to replace old 2tuple and 5tuple filter APIs.
> It defines ntuple filter to combine 2tuple and 5tuple types.
> It uses new functions and structure to replace old ones in igb/ixgbe driver,
> new commands to replace old ones in testpmd, and removes the old APIs.
> It removes the filter's index parameters from user interface, only the
> filter's key and assigned queue are visible to user.
> 
> Jingjing Wu (6):
>   ethdev: define ntuple filter type and its structure
>   ixgbe: ntuple filter functions replace old ones for 5tuple filter
>   e1000: ntuple filter functions replace old ones for 2tuple and 5tuple
>     filter
>   testpmd: new commands for ntuple filter
>   ethdev: remove old APIs and structures of 5tuple and 2tuple filters
>   doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter
> 
>  app/test-pmd/cmdline.c                      | 406 ++++++-------
>  app/test-pmd/config.c                       |  65 ---
>  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  99 +---
>  lib/librte_ether/rte_eth_ctrl.h             |  57 ++
>  lib/librte_ether/rte_ethdev.c               | 116 ----
>  lib/librte_ether/rte_ethdev.h               | 192 ------
>  lib/librte_pmd_e1000/e1000_ethdev.h         |  69 ++-
>  lib/librte_pmd_e1000/igb_ethdev.c           | 869 +++++++++++++++++++------
> ---
>  lib/librte_pmd_ixgbe/ixgbe_ethdev.c         | 468 +++++++++++----
>  lib/librte_pmd_ixgbe/ixgbe_ethdev.h         |  52 +-
>  10 files changed, 1300 insertions(+), 1093 deletions(-)
> 
> --
> 1.9.3

Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>

Just mind that the last patch (changing the documentation) does not apply properly,
 as there was another patch (from you I think), that modifies that document.
Could you send another version of the last patch? 
Not sure if that's OK or if it is better to send the full patchset again.
 

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

* Re: [dpdk-dev] [PATCH v2 0/6] new ntuple filter replaces 2tuple and 5tuple filters
  2015-01-28 14:28   ` [dpdk-dev] [PATCH v2 0/6] new ntuple filter replaces 2tuple and 5tuple filters De Lara Guarch, Pablo
@ 2015-01-30  8:22     ` Wu, Jingjing
  0 siblings, 0 replies; 27+ messages in thread
From: Wu, Jingjing @ 2015-01-30  8:22 UTC (permalink / raw)
  To: De Lara Guarch, Pablo, dev



> -----Original Message-----
> From: De Lara Guarch, Pablo
> Sent: Wednesday, January 28, 2015 10:29 PM
> To: Wu, Jingjing; dev@dpdk.org
> Cc: Cao, Min; Xu, HuilongX
> Subject: RE: [PATCH v2 0/6] new ntuple filter replaces 2tuple and 5tuple
> filters
> 
> 
> 
> > -----Original Message-----
> > From: Wu, Jingjing
> > Sent: Thursday, January 22, 2015 7:38 AM
> > To: dev@dpdk.org
> > Cc: Wu, Jingjing; De Lara Guarch, Pablo; Cao, Min; Xu, HuilongX
> > Subject: [PATCH v2 0/6] new ntuple filter replaces 2tuple and 5tuple
> > filters
> >
> > v2 changes:
> >   - remove the code which is already applied in patch "Integrate ethertype
> >     filter in igb/ixgbe driver to new API".
> >   - modify commands' description in doc testpmd_funcs.rst.
> >
> > The patch set uses filter_ctrl API to replace old 2tuple and 5tuple filter APIs.
> > It defines ntuple filter to combine 2tuple and 5tuple types.
> > It uses new functions and structure to replace old ones in igb/ixgbe
> > driver, new commands to replace old ones in testpmd, and removes the
> old APIs.
> > It removes the filter's index parameters from user interface, only the
> > filter's key and assigned queue are visible to user.
> >
> > Jingjing Wu (6):
> >   ethdev: define ntuple filter type and its structure
> >   ixgbe: ntuple filter functions replace old ones for 5tuple filter
> >   e1000: ntuple filter functions replace old ones for 2tuple and 5tuple
> >     filter
> >   testpmd: new commands for ntuple filter
> >   ethdev: remove old APIs and structures of 5tuple and 2tuple filters
> >   doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter
> >
> >  app/test-pmd/cmdline.c                      | 406 ++++++-------
> >  app/test-pmd/config.c                       |  65 ---
> >  doc/guides/testpmd_app_ug/testpmd_funcs.rst |  99 +---
> >  lib/librte_ether/rte_eth_ctrl.h             |  57 ++
> >  lib/librte_ether/rte_ethdev.c               | 116 ----
> >  lib/librte_ether/rte_ethdev.h               | 192 ------
> >  lib/librte_pmd_e1000/e1000_ethdev.h         |  69 ++-
> >  lib/librte_pmd_e1000/igb_ethdev.c           | 869 +++++++++++++++++++---
> ---
> > ---
> >  lib/librte_pmd_ixgbe/ixgbe_ethdev.c         | 468 +++++++++++----
> >  lib/librte_pmd_ixgbe/ixgbe_ethdev.h         |  52 +-
> >  10 files changed, 1300 insertions(+), 1093 deletions(-)
> >
> > --
> > 1.9.3
> 
> Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
> 
> Just mind that the last patch (changing the documentation) does not apply
> properly,  as there was another patch (from you I think), that modifies that
> document.
> Could you send another version of the last patch?
> Not sure if that's OK or if it is better to send the full patchset again.
> 

Thank you, Pablo.
Yes. It's due to another patch of doc change is applied before this one.
But I think many patches will update this the document. Let's wait to
see whether there are more comments about this patch set at first. 

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

* [dpdk-dev] [PATCH v3 0/6] new ntuple filter replaces 2tuple and 5tuple filters
  2015-01-22  7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
                     ` (6 preceding siblings ...)
  2015-01-28 14:28   ` [dpdk-dev] [PATCH v2 0/6] new ntuple filter replaces 2tuple and 5tuple filters De Lara Guarch, Pablo
@ 2015-02-10  4:48   ` Jingjing Wu
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 1/6] ethdev: define ntuple filter type and its structure Jingjing Wu
                       ` (7 more replies)
  7 siblings, 8 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-02-10  4:48 UTC (permalink / raw)
  To: dev

v2 changes:
  - remove the code which is already applied in patch "Integrate ethertype
    filter in igb/ixgbe driver to new API".
  - modify commands' description in doc testpmd_funcs.rst.

v3 change:
  - remove the UINT32_BIT definition in ixgbe driver

The patch set uses new filter_ctrl API to replace old 2tuple and 5tuple filter APIs.
It defines ntuple filter to combine 2tuple and 5tuple types. 
It uses new functions and structure to replace old ones in igb/ixgbe driver,
new commands to replace old ones in testpmd, and removes the old APIs.
It removes the filter's index parameters from user interface, only the
filter's key and assigned queue are visible to user.

Jingjing Wu (6):
  ethdev: define ntuple filter type and its structure
  ixgbe: ntuple filter functions replace old ones for 5tuple filter
  e1000: ntuple filter functions replace old ones for 2tuple and 5tuple
    filter
  testpmd: new commands for ntuple filter
  ethdev: remove old APIs and structures of 5tuple and 2tuple filters
  doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter

 app/test-pmd/cmdline.c                      | 406 ++++++-------
 app/test-pmd/config.c                       |  65 ---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  99 +---
 lib/librte_ether/rte_eth_ctrl.h             |  57 ++
 lib/librte_ether/rte_ethdev.c               | 116 ----
 lib/librte_ether/rte_ethdev.h               | 192 ------
 lib/librte_pmd_e1000/e1000_ethdev.h         |  69 ++-
 lib/librte_pmd_e1000/igb_ethdev.c           | 869 +++++++++++++++++++---------
 lib/librte_pmd_ixgbe/ixgbe_ethdev.c         | 468 +++++++++++----
 lib/librte_pmd_ixgbe/ixgbe_ethdev.h         |  52 +-
 10 files changed, 1300 insertions(+), 1093 deletions(-)

-- 
1.9.3

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

* [dpdk-dev] [PATCH v3 1/6] ethdev: define ntuple filter type and its structure
  2015-02-10  4:48   ` [dpdk-dev] [PATCH v3 " Jingjing Wu
@ 2015-02-10  4:48     ` Jingjing Wu
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 2/6] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
                       ` (6 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-02-10  4:48 UTC (permalink / raw)
  To: dev

This patch defines ntuple filter type RTE_ETH_FILTER_NTUPLE and its structure rte_eth_ntuple_filter.
It also corrects the typo TCP_UGR_FLAG to TCP_URG_FLAG

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h | 50 +++++++++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h   |  2 ++
 2 files changed, 52 insertions(+)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 0ce241e..808e532 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -53,6 +53,7 @@ enum rte_filter_type {
 	RTE_ETH_FILTER_NONE = 0,
 	RTE_ETH_FILTER_MACVLAN,
 	RTE_ETH_FILTER_ETHERTYPE,
+	RTE_ETH_FILTER_NTUPLE,
 	RTE_ETH_FILTER_TUNNEL,
 	RTE_ETH_FILTER_FDIR,
 	RTE_ETH_FILTER_HASH,
@@ -117,6 +118,55 @@ struct rte_eth_ethertype_filter {
 };
 
 /**
+ * Define all structures for ntuple Filter type.
+ */
+
+#define RTE_NTUPLE_FLAGS_DST_IP    0x0001 /**< If set, dst_ip is part of ntuple */
+#define RTE_NTUPLE_FLAGS_SRC_IP    0x0002 /**< If set, src_ip is part of ntuple */
+#define RTE_NTUPLE_FLAGS_DST_PORT  0x0004 /**< If set, dst_port is part of ntuple */
+#define RTE_NTUPLE_FLAGS_SRC_PORT  0x0008 /**< If set, src_port is part of ntuple */
+#define RTE_NTUPLE_FLAGS_PROTO     0x0010 /**< If set, protocol is part of ntuple */
+#define RTE_NTUPLE_FLAGS_TCP_FLAG  0x0020 /**< If set, tcp flag is involved */
+
+#define RTE_5TUPLE_FLAGS ( \
+		RTE_NTUPLE_FLAGS_DST_IP | \
+		RTE_NTUPLE_FLAGS_SRC_IP | \
+		RTE_NTUPLE_FLAGS_DST_PORT | \
+		RTE_NTUPLE_FLAGS_SRC_PORT | \
+		RTE_NTUPLE_FLAGS_PROTO)
+
+#define RTE_2TUPLE_FLAGS ( \
+		RTE_NTUPLE_FLAGS_DST_PORT | \
+		RTE_NTUPLE_FLAGS_PROTO)
+
+
+/**
+ * A structure used to define the ntuple filter entry
+ * to support RTE_ETH_FILTER_NTUPLE with RTE_ETH_FILTER_ADD,
+ * RTE_ETH_FILTER_DELETE and RTE_ETH_FILTER_GET operations.
+ */
+struct rte_eth_ntuple_filter {
+	uint16_t flags;          /**< Flags from RTE_NTUPLE_FLAGS_* */
+	uint32_t dst_ip;         /**< Destination IP address in big endian. */
+	uint32_t dst_ip_mask;    /**< Mask of destination IP address. */
+	uint32_t src_ip;         /**< Source IP address in big endian. */
+	uint32_t src_ip_mask;    /**< Mask of destination IP address. */
+	uint16_t dst_port;       /**< Destination port in big endian. */
+	uint16_t dst_port_mask;  /**< Mask of destination port. */
+	uint16_t src_port;       /**< Source Port in big endian. */
+	uint16_t src_port_mask;  /**< Mask of source port. */
+	uint8_t proto;           /**< L4 protocol. */
+	uint8_t proto_mask;      /**< Mask of L4 protocol. */
+	/** tcp_flags only meaningful when the proto is TCP.
+	    The packet matched above ntuple fields and contain
+	    any set bit in tcp_flags will hit this filter. */
+	uint8_t tcp_flags;
+	uint16_t priority;       /**< seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint16_t queue;          /**< Queue assigned to when match*/
+};
+
+/**
  * Tunneled type.
  */
 enum rte_eth_tunnel_type {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 1200c1c..5992e43 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -963,6 +963,8 @@ struct rte_eth_dev_callback;
 /** @internal Structure to keep track of registered callbacks */
 TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 
+
+#define TCP_URG_FLAG 0x20
 #define TCP_UGR_FLAG 0x20
 #define TCP_ACK_FLAG 0x10
 #define TCP_PSH_FLAG 0x08
-- 
1.9.3

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

* [dpdk-dev] [PATCH v3 2/6] ixgbe: ntuple filter functions replace old ones for 5tuple filter
  2015-02-10  4:48   ` [dpdk-dev] [PATCH v3 " Jingjing Wu
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 1/6] ethdev: define ntuple filter type and its structure Jingjing Wu
@ 2015-02-10  4:48     ` Jingjing Wu
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 3/6] e1000: ntuple filter functions replace old ones for 2tuple and " Jingjing Wu
                       ` (5 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-02-10  4:48 UTC (permalink / raw)
  To: dev

This patch defines new functions dealing with ntuple filters which is
corresponding to 5tuple in HW.
It removes old functions which deal with 5tuple filters.
Ntuple filter is dealt with through entrance ixgbe_dev_filter_ctrl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 468 ++++++++++++++++++++++++++----------
 lib/librte_pmd_ixgbe/ixgbe_ethdev.h |  52 +++-
 2 files changed, 389 insertions(+), 131 deletions(-)

diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
index b341dd0..35ae573 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
@@ -231,14 +231,18 @@ static int ixgbe_add_syn_filter(struct rte_eth_dev *dev,
 static int ixgbe_remove_syn_filter(struct rte_eth_dev *dev);
 static int ixgbe_get_syn_filter(struct rte_eth_dev *dev,
 			struct rte_syn_filter *filter, uint16_t *rx_queue);
-static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue);
-static int ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index);
-static int ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue);
-
-static int ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
+static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev,
+			struct ixgbe_5tuple_filter *filter);
+static void ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
+			struct ixgbe_5tuple_filter *filter);
+static int ixgbe_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter,
+			bool add);
+static int ixgbe_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg);
+static int ixgbe_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter);
 static int ixgbe_add_del_ethertype_filter(struct rte_eth_dev *dev,
 			struct rte_eth_ethertype_filter *filter,
 			bool add);
@@ -251,6 +255,7 @@ static int ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,
 		     enum rte_filter_type filter_type,
 		     enum rte_filter_op filter_op,
 		     void *arg);
+static int ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
 
 /*
  * Define VF Stats MACRO for Non "cleared on read" register
@@ -386,9 +391,6 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.add_syn_filter	         = ixgbe_add_syn_filter,
 	.remove_syn_filter       = ixgbe_remove_syn_filter,
 	.get_syn_filter          = ixgbe_get_syn_filter,
-	.add_5tuple_filter       = ixgbe_add_5tuple_filter,
-	.remove_5tuple_filter    = ixgbe_remove_5tuple_filter,
-	.get_5tuple_filter       = ixgbe_get_5tuple_filter,
 	.filter_ctrl             = ixgbe_dev_filter_ctrl,
 };
 
@@ -736,6 +738,8 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 		IXGBE_DEV_PRIVATE_TO_HWSTRIP_BITMAP(eth_dev->data->dev_private);
 	struct ixgbe_dcb_config *dcb_config =
 		IXGBE_DEV_PRIVATE_TO_DCB_CFG(eth_dev->data->dev_private);
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
 	uint32_t ctrl_ext;
 	uint16_t csum;
 	int diag, i;
@@ -917,6 +921,11 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 	/* enable support intr */
 	ixgbe_enable_intr(eth_dev);
 
+	/* initialize 5tuple filter list */
+	TAILQ_INIT(&filter_info->fivetuple_list);
+	memset(filter_info->fivetuple_mask, 0,
+		sizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);
+
 	return 0;
 }
 
@@ -1612,6 +1621,9 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
 		IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 	struct ixgbe_vf_info *vfinfo =
 		*IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct ixgbe_5tuple_filter *p_5tuple, *p_5tuple_next;
 	int vf;
 
 	PMD_INIT_FUNC_TRACE();
@@ -1641,6 +1653,18 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
 	/* Clear recorded link status */
 	memset(&link, 0, sizeof(link));
 	rte_ixgbe_dev_atomic_write_link_status(dev, &link);
+
+	/* Remove all ntuple filters of the device */
+	for (p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list);
+	     p_5tuple != NULL; p_5tuple = p_5tuple_next) {
+		p_5tuple_next = TAILQ_NEXT(p_5tuple, entries);
+		TAILQ_REMOVE(&filter_info->fivetuple_list,
+			     p_5tuple, entries);
+		rte_free(p_5tuple);
+	}
+	memset(filter_info->fivetuple_mask, 0,
+		sizeof(uint32_t) * IXGBE_5TUPLE_ARRAY_SIZE);
+
 }
 
 /*
@@ -3823,62 +3847,69 @@ revert_protocol_type(enum ixgbe_5tuple_protocol protocol)
  *    - On failure, a negative value.
  */
 static int
-ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue)
+ixgbe_add_5tuple_filter(struct rte_eth_dev *dev,
+			struct ixgbe_5tuple_filter *filter)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t ftqf, sdpqf = 0;
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	int i, idx, shift;
+	uint32_t ftqf, sdpqf;
 	uint32_t l34timir = 0;
 	uint8_t mask = 0xff;
 
-	if (hw->mac.type != ixgbe_mac_82599EB)
+	/*
+	 * look for an unused 5tuple filter index,
+	 * and insert the filter to list.
+	 */
+	for (i = 0; i < IXGBE_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 >= IXGBE_MAX_FTQF_FILTERS) {
+		PMD_DRV_LOG(ERR, "5tuple filters are full.");
 		return -ENOSYS;
-
-	if (index >= IXGBE_MAX_FTQF_FILTERS ||
-		rx_queue >= IXGBE_MAX_RX_QUEUE_NUM ||
-		filter->priority > IXGBE_5TUPLE_MAX_PRI ||
-		filter->priority < IXGBE_5TUPLE_MIN_PRI)
-		return -EINVAL;  /* filter index is out of range. */
-
-	if (filter->tcp_flags) {
-		PMD_INIT_LOG(INFO, "82599EB not tcp flags in 5tuple");
-		return -EINVAL;
 	}
 
-	ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index));
-	if (ftqf & IXGBE_FTQF_QUEUE_ENABLE)
-		return -EINVAL;  /* filter index is in use. */
-
-	ftqf = 0;
-	sdpqf = (uint32_t)(filter->dst_port << IXGBE_SDPQF_DSTPORT_SHIFT);
-	sdpqf = sdpqf | (filter->src_port & IXGBE_SDPQF_SRCPORT);
+	sdpqf = (uint32_t)(filter->filter_info.dst_port <<
+				IXGBE_SDPQF_DSTPORT_SHIFT);
+	sdpqf = sdpqf | (filter->filter_info.src_port & IXGBE_SDPQF_SRCPORT);
 
-	ftqf |= (uint32_t)(convert_protocol_type(filter->protocol) &
+	ftqf = (uint32_t)(filter->filter_info.proto &
 		IXGBE_FTQF_PROTOCOL_MASK);
-	ftqf |= (uint32_t)((filter->priority & IXGBE_FTQF_PRIORITY_MASK) <<
-		IXGBE_FTQF_PRIORITY_SHIFT);
-	if (filter->src_ip_mask == 0) /* 0 means compare. */
+	ftqf |= (uint32_t)((filter->filter_info.priority &
+		IXGBE_FTQF_PRIORITY_MASK) << IXGBE_FTQF_PRIORITY_SHIFT);
+	if (filter->filter_info.src_ip_mask == 0) /* 0 means compare. */
 		mask &= IXGBE_FTQF_SOURCE_ADDR_MASK;
-	if (filter->dst_ip_mask == 0)
+	if (filter->filter_info.dst_ip_mask == 0)
 		mask &= IXGBE_FTQF_DEST_ADDR_MASK;
-	if (filter->src_port_mask == 0)
+	if (filter->filter_info.src_port_mask == 0)
 		mask &= IXGBE_FTQF_SOURCE_PORT_MASK;
-	if (filter->dst_port_mask == 0)
+	if (filter->filter_info.dst_port_mask == 0)
 		mask &= IXGBE_FTQF_DEST_PORT_MASK;
-	if (filter->protocol_mask == 0)
+	if (filter->filter_info.proto_mask == 0)
 		mask &= IXGBE_FTQF_PROTOCOL_COMP_MASK;
 	ftqf |= mask << IXGBE_FTQF_5TUPLE_MASK_SHIFT;
 	ftqf |= IXGBE_FTQF_POOL_MASK_EN;
 	ftqf |= IXGBE_FTQF_QUEUE_ENABLE;
 
-	IXGBE_WRITE_REG(hw, IXGBE_DAQF(index), filter->dst_ip);
-	IXGBE_WRITE_REG(hw, IXGBE_SAQF(index), filter->src_ip);
-	IXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), sdpqf);
-	IXGBE_WRITE_REG(hw, IXGBE_FTQF(index), ftqf);
+	IXGBE_WRITE_REG(hw, IXGBE_DAQF(idx), filter->filter_info.dst_ip);
+	IXGBE_WRITE_REG(hw, IXGBE_SAQF(idx), filter->filter_info.src_ip);
+	IXGBE_WRITE_REG(hw, IXGBE_SDPQF(idx), sdpqf);
+	IXGBE_WRITE_REG(hw, IXGBE_FTQF(idx), ftqf);
 
 	l34timir |= IXGBE_L34T_IMIR_RESERVE;
-	l34timir |= (uint32_t)(rx_queue << IXGBE_L34T_IMIR_QUEUE_SHIFT);
-	IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), l34timir);
+	l34timir |= (uint32_t)(filter->queue <<
+				IXGBE_L34T_IMIR_QUEUE_SHIFT);
+	IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(i), l34timir);
 	return 0;
 }
 
@@ -3887,92 +3918,27 @@ ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
+ * filter: the pointer of the filter will be removed.
  */
-static int
+static void
 ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index)
+			struct ixgbe_5tuple_filter *filter)
 {
 	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	uint16_t index = filter->index;
 
-	if (hw->mac.type != ixgbe_mac_82599EB)
-		return -ENOSYS;
-
-	if (index >= IXGBE_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	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);
 
 	IXGBE_WRITE_REG(hw, IXGBE_DAQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_SAQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_FTQF(index), 0);
 	IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), 0);
-	return 0;
-}
-
-/*
- * get a 5tuple filter
- *
- * @param
- * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates
- * filter: ponter to the filter that returns.
- * *rx_queue: pointer of the queue id the filter assigned to.
- *
- * @return
- *    - On success, zero.
- *    - On failure, a negative value.
- */
-static int
-ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue)
-{
-	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t sdpqf, ftqf, l34timir;
-	uint8_t mask;
-	enum ixgbe_5tuple_protocol proto;
-
-	if (hw->mac.type != ixgbe_mac_82599EB)
-		return -ENOSYS;
-
-	if (index >= IXGBE_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
-
-	ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index));
-	if (ftqf & IXGBE_FTQF_QUEUE_ENABLE) {
-		proto = (enum ixgbe_5tuple_protocol)(ftqf & IXGBE_FTQF_PROTOCOL_MASK);
-		filter->protocol = revert_protocol_type(proto);
-		filter->priority = (ftqf >> IXGBE_FTQF_PRIORITY_SHIFT) &
-					IXGBE_FTQF_PRIORITY_MASK;
-		mask = (uint8_t)((ftqf >> IXGBE_FTQF_5TUPLE_MASK_SHIFT) &
-					IXGBE_FTQF_5TUPLE_MASK_MASK);
-		filter->src_ip_mask =
-			(mask & IXGBE_FTQF_SOURCE_ADDR_MASK) ? 1 : 0;
-		filter->dst_ip_mask =
-			(mask & IXGBE_FTQF_DEST_ADDR_MASK) ? 1 : 0;
-		filter->src_port_mask =
-			(mask & IXGBE_FTQF_SOURCE_PORT_MASK) ? 1 : 0;
-		filter->dst_port_mask =
-			(mask & IXGBE_FTQF_DEST_PORT_MASK) ? 1 : 0;
-		filter->protocol_mask =
-			(mask & IXGBE_FTQF_PROTOCOL_COMP_MASK) ? 1 : 0;
-
-		sdpqf = IXGBE_READ_REG(hw, IXGBE_SDPQF(index));
-		filter->dst_port = (sdpqf & IXGBE_SDPQF_DSTPORT) >>
-					IXGBE_SDPQF_DSTPORT_SHIFT;
-		filter->src_port = sdpqf & IXGBE_SDPQF_SRCPORT;
-		filter->dst_ip = IXGBE_READ_REG(hw, IXGBE_DAQF(index));
-		filter->src_ip = IXGBE_READ_REG(hw, IXGBE_SAQF(index));
-
-		l34timir = IXGBE_READ_REG(hw, IXGBE_L34T_IMIR(index));
-		*rx_queue = (l34timir & IXGBE_L34T_IMIR_QUEUE) >>
-					IXGBE_L34T_IMIR_QUEUE_SHIFT;
-		return 0;
-	}
-	return -ENOENT;
 }
 
 static int
@@ -4009,6 +3975,263 @@ ixgbevf_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+#define MAC_TYPE_FILTER_SUP_EXT(type)    do {\
+	if ((type) != ixgbe_mac_82599EB && (type) != ixgbe_mac_X540)\
+		return -ENOTSUP;\
+} while (0)
+
+static inline struct ixgbe_5tuple_filter *
+ixgbe_5tuple_filter_lookup(struct ixgbe_5tuple_filter_list *filter_list,
+			struct ixgbe_5tuple_filter_info *key)
+{
+	struct ixgbe_5tuple_filter *it;
+
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct ixgbe_5tuple_filter_info)) == 0) {
+			return it;
+		}
+	}
+	return NULL;
+}
+
+/* translate elements in struct rte_eth_ntuple_filter to struct ixgbe_5tuple_filter_info*/
+static inline int
+ntuple_filter_to_5tuple(struct rte_eth_ntuple_filter *filter,
+			struct ixgbe_5tuple_filter_info *filter_info)
+{
+	if (filter->queue >= IXGBE_MAX_RX_QUEUE_NUM ||
+		filter->priority > IXGBE_5TUPLE_MAX_PRI ||
+		filter->priority < IXGBE_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.
+ */
+static int
+ixgbe_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter,
+			bool add)
+{
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct ixgbe_5tuple_filter_info filter_5tuple;
+	struct ixgbe_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 ixgbe_5tuple_filter_info));
+	ret = ntuple_filter_to_5tuple(ntuple_filter, &filter_5tuple);
+	if (ret < 0)
+		return ret;
+
+	filter = ixgbe_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("ixgbe_5tuple_filter",
+				sizeof(struct ixgbe_5tuple_filter), 0);
+		if (filter == NULL)
+			return -ENOMEM;
+		(void)rte_memcpy(&filter->filter_info,
+				 &filter_5tuple,
+				 sizeof(struct ixgbe_5tuple_filter_info));
+		filter->queue = ntuple_filter->queue;
+		ret = ixgbe_add_5tuple_filter(dev, filter);
+		if (ret < 0) {
+			rte_free(filter);
+			return ret;
+		}
+	} else
+		ixgbe_remove_5tuple_filter(dev, filter);
+
+	return 0;
+}
+
+/*
+ * get a ntuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * ntuple_filter: Pointer to struct rte_eth_ntuple_filter
+ *
+ * @return
+ *    - On success, zero.
+ *    - On failure, a negative value.
+ */
+static int
+ixgbe_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
+{
+	struct ixgbe_filter_info *filter_info =
+		IXGBE_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct ixgbe_5tuple_filter_info filter_5tuple;
+	struct ixgbe_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 ixgbe_5tuple_filter_info));
+	ret = ntuple_filter_to_5tuple(ntuple_filter, &filter_5tuple);
+	if (ret < 0)
+		return ret;
+
+	filter = ixgbe_5tuple_filter_lookup(&filter_info->fivetuple_list,
+					 &filter_5tuple);
+	if (filter == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
+	}
+	ntuple_filter->queue = filter->queue;
+	return 0;
+}
+
+/*
+ * ixgbe_ntuple_filter_handle - Handle operations for ntuple filter.
+ * @dev: pointer to rte_eth_dev structure
+ * @filter_op:operation will be taken.
+ * @arg: a pointer to specific structure corresponding to the filter_op
+ *
+ * @return
+ *    - On success, zero.
+ *    - On failure, a negative value.
+ */
+static int
+ixgbe_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg)
+{
+	struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
+
+	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+
+	if (filter_op == RTE_ETH_FILTER_NOP)
+		return 0;
+
+	if (arg == NULL) {
+		PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
+			    filter_op);
+		return -EINVAL;
+	}
+
+	switch (filter_op) {
+	case RTE_ETH_FILTER_ADD:
+		ret = ixgbe_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			TRUE);
+		break;
+	case RTE_ETH_FILTER_DELETE:
+		ret = ixgbe_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			FALSE);
+		break;
+	case RTE_ETH_FILTER_GET:
+		ret = ixgbe_get_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
 #define MAC_TYPE_FILTER_SUP(type)    do {\
 	if ((type) != ixgbe_mac_82599EB && (type) != ixgbe_mac_X540 &&\
 		(type) != ixgbe_mac_X550)\
@@ -4210,6 +4433,9 @@ ixgbe_dev_filter_ctrl(struct rte_eth_dev *dev,
 	int ret = -EINVAL;
 
 	switch (filter_type) {
+	case RTE_ETH_FILTER_NTUPLE:
+		ret = ixgbe_ntuple_filter_handle(dev, filter_op, arg);
+		break;
 	case RTE_ETH_FILTER_ETHERTYPE:
 		ret = ixgbe_ethertype_filter_handle(dev, filter_op, arg);
 		break;
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
index 1383194..814195e 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
@@ -163,12 +163,54 @@ struct ixgbe_vf_info {
 };
 
 /*
+ *  Possible l4type of 5tuple filters.
+ */
+enum ixgbe_5tuple_protocol {
+	IXGBE_FILTER_PROTOCOL_TCP = 0,
+	IXGBE_FILTER_PROTOCOL_UDP,
+	IXGBE_FILTER_PROTOCOL_SCTP,
+	IXGBE_FILTER_PROTOCOL_NONE,
+};
+
+TAILQ_HEAD(ixgbe_5tuple_filter_list, ixgbe_5tuple_filter);
+
+struct ixgbe_5tuple_filter_info {
+	uint32_t dst_ip;
+	uint32_t src_ip;
+	uint16_t dst_port;
+	uint16_t src_port;
+	enum ixgbe_5tuple_protocol proto;        /* l4 protocol. */
+	uint8_t priority;        /* seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint8_t dst_ip_mask:1,   /* if mask is 1b, do not compare dst ip. */
+		src_ip_mask:1,   /* if mask is 1b, do not compare src ip. */
+		dst_port_mask:1, /* if mask is 1b, do not compare dst port. */
+		src_port_mask:1, /* if mask is 1b, do not compare src port. */
+		proto_mask:1;    /* if mask is 1b, do not compare protocol. */
+};
+
+/* 5tuple filter structure */
+struct ixgbe_5tuple_filter {
+	TAILQ_ENTRY(ixgbe_5tuple_filter) entries;
+	uint16_t index;       /* the index of 5tuple filter */
+	struct ixgbe_5tuple_filter_info filter_info;
+	uint16_t queue;       /* rx queue assigned to */
+};
+
+#define IXGBE_5TUPLE_ARRAY_SIZE \
+	(RTE_ALIGN(IXGBE_MAX_FTQF_FILTERS, (sizeof(uint32_t) * NBBY)) / \
+	 (sizeof(uint32_t) * NBBY))
+
+/*
  * Structure to store filters' info.
  */
 struct ixgbe_filter_info {
 	uint8_t ethertype_mask;  /* Bit mask for every used ethertype filter */
 	/* store used ethertype filters*/
 	uint16_t ethertype_filters[IXGBE_MAX_ETQF_FILTERS];
+	/* Bit mask for every used 5tuple filter */
+	uint32_t fivetuple_mask[IXGBE_5TUPLE_ARRAY_SIZE];
+	struct ixgbe_5tuple_filter_list fivetuple_list;
 };
 
 /*
@@ -192,16 +234,6 @@ struct ixgbe_adapter {
 	struct ixgbe_filter_info    filter;
 };
 
-/*
- *  Possible l4type of 5tuple filters.
- */
-enum ixgbe_5tuple_protocol {
-	IXGBE_FILTER_PROTOCOL_TCP = 0,
-	IXGBE_FILTER_PROTOCOL_UDP,
-	IXGBE_FILTER_PROTOCOL_SCTP,
-	IXGBE_FILTER_PROTOCOL_NONE,
-};
-
 #define IXGBE_DEV_PRIVATE_TO_HW(adapter)\
 	(&((struct ixgbe_adapter *)adapter)->hw)
 
-- 
1.9.3

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

* [dpdk-dev] [PATCH v3 3/6] e1000: ntuple filter functions replace old ones for 2tuple and 5tuple filter
  2015-02-10  4:48   ` [dpdk-dev] [PATCH v3 " Jingjing Wu
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 1/6] ethdev: define ntuple filter type and its structure Jingjing Wu
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 2/6] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
@ 2015-02-10  4:48     ` Jingjing Wu
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 4/6] testpmd: new commands for ntuple filter Jingjing Wu
                       ` (4 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-02-10  4:48 UTC (permalink / raw)
  To: dev

This patch defines new functions dealing with ntuple filters which is
corresponding to 2tuple filter for 82580 and i350 in HW, and to 5tuple
filter for 82576 in HW.
It removes old functions which deal with 2tuple and 5tuple filters in igb driver.
Ntuple filter is dealt with through entrance eth_igb_filter_ctrl.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_pmd_e1000/e1000_ethdev.h |  69 ++-
 lib/librte_pmd_e1000/igb_ethdev.c   | 869 ++++++++++++++++++++++++------------
 2 files changed, 647 insertions(+), 291 deletions(-)

diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h
index d155e77..571a70d 100644
--- a/lib/librte_pmd_e1000/e1000_ethdev.h
+++ b/lib/librte_pmd_e1000/e1000_ethdev.h
@@ -67,14 +67,6 @@
 
 #define E1000_IMIR_DSTPORT             0x0000FFFF
 #define E1000_IMIR_PRIORITY            0xE0000000
-#define E1000_IMIR_EXT_SIZE_BP         0x00001000
-#define E1000_IMIR_EXT_CTRL_UGR        0x00002000
-#define E1000_IMIR_EXT_CTRL_ACK        0x00004000
-#define E1000_IMIR_EXT_CTRL_PSH        0x00008000
-#define E1000_IMIR_EXT_CTRL_RST        0x00010000
-#define E1000_IMIR_EXT_CTRL_SYN        0x00020000
-#define E1000_IMIR_EXT_CTRL_FIN        0x00040000
-#define E1000_IMIR_EXT_CTRL_BP         0x00080000
 #define E1000_MAX_TTQF_FILTERS         8
 #define E1000_2TUPLE_MAX_PRI           7
 
@@ -96,11 +88,6 @@
 #define E1000_MAX_FTQF_FILTERS           8
 #define E1000_FTQF_PROTOCOL_MASK         0x000000FF
 #define E1000_FTQF_5TUPLE_MASK_SHIFT     28
-#define E1000_FTQF_PROTOCOL_COMP_MASK    0x10000000
-#define E1000_FTQF_SOURCE_ADDR_MASK      0x20000000
-#define E1000_FTQF_DEST_ADDR_MASK        0x40000000
-#define E1000_FTQF_SOURCE_PORT_MASK      0x80000000
-#define E1000_FTQF_VF_MASK_EN            0x00008000
 #define E1000_FTQF_QUEUE_MASK            0x03ff0000
 #define E1000_FTQF_QUEUE_SHIFT           16
 #define E1000_FTQF_QUEUE_ENABLE          0x00000100
@@ -131,6 +118,56 @@ struct e1000_vf_info {
 	uint16_t tx_rate;
 };
 
+TAILQ_HEAD(e1000_5tuple_filter_list, e1000_5tuple_filter);
+TAILQ_HEAD(e1000_2tuple_filter_list, e1000_2tuple_filter);
+
+struct e1000_5tuple_filter_info {
+	uint32_t dst_ip;
+	uint32_t src_ip;
+	uint16_t dst_port;
+	uint16_t src_port;
+	uint8_t proto;           /* l4 protocol. */
+	/* the packet matched above 5tuple and contain any set bit will hit this filter. */
+	uint8_t tcp_flags;
+	uint8_t priority;        /* seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint8_t dst_ip_mask:1,   /* if mask is 1b, do not compare dst ip. */
+		src_ip_mask:1,   /* if mask is 1b, do not compare src ip. */
+		dst_port_mask:1, /* if mask is 1b, do not compare dst port. */
+		src_port_mask:1, /* if mask is 1b, do not compare src port. */
+		proto_mask:1;    /* if mask is 1b, do not compare protocol. */
+};
+
+struct e1000_2tuple_filter_info {
+	uint16_t dst_port;
+	uint8_t proto;           /* l4 protocol. */
+	/* the packet matched above 2tuple and contain any set bit will hit this filter. */
+	uint8_t tcp_flags;
+	uint8_t priority;        /* seven levels (001b-111b), 111b is highest,
+				      used when more than one filter matches. */
+	uint8_t dst_ip_mask:1,   /* if mask is 1b, do not compare dst ip. */
+		src_ip_mask:1,   /* if mask is 1b, do not compare src ip. */
+		dst_port_mask:1, /* if mask is 1b, do not compare dst port. */
+		src_port_mask:1, /* if mask is 1b, do not compare src port. */
+		proto_mask:1;    /* if mask is 1b, do not compare protocol. */
+};
+
+/* 5tuple filter structure */
+struct e1000_5tuple_filter {
+	TAILQ_ENTRY(e1000_5tuple_filter) entries;
+	uint16_t index;       /* the index of 5tuple filter */
+	struct e1000_5tuple_filter_info filter_info;
+	uint16_t queue;       /* rx queue assigned to */
+};
+
+/* 2tuple filter structure */
+struct e1000_2tuple_filter {
+	TAILQ_ENTRY(e1000_2tuple_filter) entries;
+	uint16_t index;         /* the index of 2tuple filter */
+	struct e1000_2tuple_filter_info filter_info;
+	uint16_t queue;       /* rx queue assigned to */
+};
+
 /*
  * Structure to store filters' info.
  */
@@ -138,6 +175,12 @@ struct e1000_filter_info {
 	uint8_t ethertype_mask; /* Bit mask for every used ethertype filter */
 	/* store used ethertype filters*/
 	uint16_t ethertype_filters[E1000_MAX_ETQF_FILTERS];
+	/* Bit mask for every used 5tuple filter */
+	uint8_t fivetuple_mask;
+	struct e1000_5tuple_filter_list fivetuple_list;
+	/* Bit mask for every used 2tuple filter */
+	uint8_t twotuple_mask;
+	struct e1000_2tuple_filter_list twotuple_list;
 };
 
 /*
diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c
index 2a268b8..51f47cc 100644
--- a/lib/librte_pmd_e1000/igb_ethdev.c
+++ b/lib/librte_pmd_e1000/igb_ethdev.c
@@ -154,14 +154,10 @@ static int eth_igb_add_syn_filter(struct rte_eth_dev *dev,
 static int eth_igb_remove_syn_filter(struct rte_eth_dev *dev);
 static int eth_igb_get_syn_filter(struct rte_eth_dev *dev,
 			struct rte_syn_filter *filter, uint16_t *rx_queue);
-static int eth_igb_add_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue);
-static int eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index);
-static int eth_igb_get_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue);
+static int igb_add_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_remove_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
 static int eth_igb_add_flex_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_flex_filter *filter, uint16_t rx_queue);
@@ -170,14 +166,18 @@ static int eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
 static int eth_igb_get_flex_filter(struct rte_eth_dev *dev,
 			uint16_t index,
 			struct rte_flex_filter *filter, uint16_t *rx_queue);
-static int eth_igb_add_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue);
-static int eth_igb_remove_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index);
-static int eth_igb_get_5tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue);
+static int igb_add_5tuple_filter_82576(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_remove_5tuple_filter_82576(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter);
+static int igb_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter,
+			bool add);
+static int igb_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *filter);
+static int igb_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg);
 static int igb_add_del_ethertype_filter(struct rte_eth_dev *dev,
 			struct rte_eth_ethertype_filter *filter,
 			bool add);
@@ -268,15 +268,9 @@ static struct eth_dev_ops eth_igb_ops = {
 	.add_syn_filter          = eth_igb_add_syn_filter,
 	.remove_syn_filter       = eth_igb_remove_syn_filter,
 	.get_syn_filter          = eth_igb_get_syn_filter,
-	.add_2tuple_filter       = eth_igb_add_2tuple_filter,
-	.remove_2tuple_filter    = eth_igb_remove_2tuple_filter,
-	.get_2tuple_filter       = eth_igb_get_2tuple_filter,
 	.add_flex_filter         = eth_igb_add_flex_filter,
 	.remove_flex_filter      = eth_igb_remove_flex_filter,
 	.get_flex_filter         = eth_igb_get_flex_filter,
-	.add_5tuple_filter       = eth_igb_add_5tuple_filter,
-	.remove_5tuple_filter    = eth_igb_remove_5tuple_filter,
-	.get_5tuple_filter       = eth_igb_get_5tuple_filter,
 	.filter_ctrl             = eth_igb_filter_ctrl,
 };
 
@@ -470,6 +464,8 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 		E1000_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
 	struct e1000_vfta * shadow_vfta =
 			E1000_DEV_PRIVATE_TO_VFTA(eth_dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(eth_dev->data->dev_private);
 	uint32_t ctrl_ext;
 
 	pci_dev = eth_dev->pci_dev;
@@ -601,6 +597,12 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 	/* enable support intr */
 	igb_intr_enable(eth_dev);
 
+	/* initialize ntuple filter list */
+	TAILQ_INIT(&filter_info->twotuple_list);
+	filter_info->twotuple_mask = 0;
+	TAILQ_INIT(&filter_info->fivetuple_list);
+	filter_info->fivetuple_mask = 0;
+
 	return 0;
 
 err_late:
@@ -926,7 +928,11 @@ static void
 eth_igb_stop(struct rte_eth_dev *dev)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
 	struct rte_eth_link link;
+	struct e1000_5tuple_filter *p_5tuple, *p_5tuple_next;
+	struct e1000_2tuple_filter *p_2tuple, *p_2tuple_next;
 
 	igb_intr_disable(hw);
 	igb_pf_reset_hw(hw);
@@ -949,6 +955,24 @@ eth_igb_stop(struct rte_eth_dev *dev)
 	/* clear the recorded link status */
 	memset(&link, 0, sizeof(link));
 	rte_igb_dev_atomic_write_link_status(dev, &link);
+
+	/* Remove all ntuple filters of the device */
+	for (p_5tuple = TAILQ_FIRST(&filter_info->fivetuple_list);
+	     p_5tuple != NULL; p_5tuple = p_5tuple_next) {
+		p_5tuple_next = TAILQ_NEXT(p_5tuple, entries);
+		TAILQ_REMOVE(&filter_info->fivetuple_list,
+			     p_5tuple, entries);
+		rte_free(p_5tuple);
+	}
+	filter_info->fivetuple_mask = 0;
+	for (p_2tuple = TAILQ_FIRST(&filter_info->twotuple_list);
+	     p_2tuple != NULL; p_2tuple = p_2tuple_next) {
+		p_2tuple_next = TAILQ_NEXT(p_2tuple, entries);
+		TAILQ_REMOVE(&filter_info->twotuple_list,
+			     p_2tuple, entries);
+		rte_free(p_2tuple);
+	}
+	filter_info->twotuple_mask = 0;
 }
 
 static void
@@ -2491,165 +2515,209 @@ eth_igb_get_syn_filter(struct rte_eth_dev *dev,
 		return -ENOSYS; \
 } while (0)
 
-/*
- * add a 2tuple 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
-eth_igb_add_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue)
+/* translate elements in struct rte_eth_ntuple_filter to struct e1000_2tuple_filter_info*/
+static inline int
+ntuple_filter_to_2tuple(struct rte_eth_ntuple_filter *filter,
+			struct e1000_2tuple_filter_info *filter_info)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t ttqf, imir = 0;
-	uint32_t imir_ext = 0;
-
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
-
-	if (index >= E1000_MAX_TTQF_FILTERS ||
-		rx_queue >= IGB_MAX_RX_QUEUE_NUM ||
-		filter->priority > E1000_2TUPLE_MAX_PRI)
+	if (filter->queue >= IGB_MAX_RX_QUEUE_NUM)
+		return -EINVAL;
+	if (filter->priority > E1000_2TUPLE_MAX_PRI)
 		return -EINVAL;  /* filter index is out of range. */
-	if  (filter->tcp_flags > TCP_FLAG_ALL)
+	if (filter->tcp_flags > TCP_FLAG_ALL)
 		return -EINVAL;  /* flags is invalid. */
 
-	ttqf = E1000_READ_REG(hw, E1000_TTQF(index));
-	if (ttqf & E1000_TTQF_QUEUE_ENABLE)
-		return -EINVAL;  /* filter index is in use. */
-
-	imir = (uint32_t)(filter->dst_port & E1000_IMIR_DSTPORT);
-	if (filter->dst_port_mask == 1) /* 1b means not compare. */
-		imir |= E1000_IMIR_PORT_BP;
-	else
-		imir &= ~E1000_IMIR_PORT_BP;
+	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;
+	}
 
-	imir |= filter->priority << E1000_IMIR_PRIORITY_SHIFT;
+	switch (filter->proto_mask) {
+	case UINT8_MAX:
+		filter_info->proto_mask = 0;
+		filter_info->proto = filter->proto;
+		break;
+	case 0:
+		filter_info->proto_mask = 1;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid protocol mask.");
+		return -EINVAL;
+	}
 
-	ttqf = 0;
-	ttqf |= E1000_TTQF_QUEUE_ENABLE;
-	ttqf |= (uint32_t)(rx_queue << E1000_TTQF_QUEUE_SHIFT);
-	ttqf |= (uint32_t)(filter->protocol & E1000_TTQF_PROTOCOL_MASK);
-	if (filter->protocol_mask == 1)
-		ttqf |= E1000_TTQF_MASK_ENABLE;
+	filter_info->priority = (uint8_t)filter->priority;
+	if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG)
+		filter_info->tcp_flags = filter->tcp_flags;
 	else
-		ttqf &= ~E1000_TTQF_MASK_ENABLE;
+		filter_info->tcp_flags = 0;
 
-	imir_ext |= E1000_IMIR_EXT_SIZE_BP;
-	/* tcp flags bits setting. */
-	if (filter->tcp_flags & TCP_FLAG_ALL) {
-		if (filter->tcp_flags & TCP_UGR_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_UGR;
-		if (filter->tcp_flags & TCP_ACK_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_ACK;
-		if (filter->tcp_flags & TCP_PSH_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_PSH;
-		if (filter->tcp_flags & TCP_RST_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_RST;
-		if (filter->tcp_flags & TCP_SYN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_SYN;
-		if (filter->tcp_flags & TCP_FIN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_FIN;
-		imir_ext &= ~E1000_IMIR_EXT_CTRL_BP;
-	} else
-		imir_ext |= E1000_IMIR_EXT_CTRL_BP;
-	E1000_WRITE_REG(hw, E1000_IMIR(index), imir);
-	E1000_WRITE_REG(hw, E1000_TTQF(index), ttqf);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), imir_ext);
 	return 0;
 }
 
+static inline struct e1000_2tuple_filter *
+igb_2tuple_filter_lookup(struct e1000_2tuple_filter_list *filter_list,
+			struct e1000_2tuple_filter_info *key)
+{
+	struct e1000_2tuple_filter *it;
+
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct e1000_2tuple_filter_info)) == 0) {
+			return it;
+		}
+	}
+	return NULL;
+}
+
 /*
- * remove a 2tuple filter
+ * igb_add_2tuple_filter - add a 2tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
+ * ntuple_filter: ponter to the filter that will be added.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
-			uint16_t index)
+igb_add_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_2tuple_filter *filter;
+	uint32_t ttqf = E1000_TTQF_DISABLE_MASK;
+	uint32_t imir, imir_ext = E1000_IMIREXT_SIZE_BP;
+	int i, ret;
+
+	filter = rte_zmalloc("e1000_2tuple_filter",
+			sizeof(struct e1000_2tuple_filter), 0);
+	if (filter == NULL)
+		return -ENOMEM;
 
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+	ret = ntuple_filter_to_2tuple(ntuple_filter,
+				      &filter->filter_info);
+	if (ret < 0) {
+		rte_free(filter);
+		return ret;
+	}
+	if (igb_2tuple_filter_lookup(&filter_info->twotuple_list,
+					 &filter->filter_info) != NULL) {
+		PMD_DRV_LOG(ERR, "filter exists.");
+		rte_free(filter);
+		return -EEXIST;
+	}
+	filter->queue = ntuple_filter->queue;
 
-	if (index >= E1000_MAX_TTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range */
+	/*
+	 * look for an unused 2tuple filter index,
+	 * and insert the filter to list.
+	 */
+	for (i = 0; i < E1000_MAX_TTQF_FILTERS; i++) {
+		if (!(filter_info->twotuple_mask & (1 << i))) {
+			filter_info->twotuple_mask |= 1 << i;
+			filter->index = i;
+			TAILQ_INSERT_TAIL(&filter_info->twotuple_list,
+					  filter,
+					  entries);
+			break;
+		}
+	}
+	if (i >= E1000_MAX_TTQF_FILTERS) {
+		PMD_DRV_LOG(ERR, "2tuple filters are full.");
+		rte_free(filter);
+		return -ENOSYS;
+	}
+
+	imir = (uint32_t)(filter->filter_info.dst_port & E1000_IMIR_DSTPORT);
+	if (filter->filter_info.dst_port_mask == 1) /* 1b means not compare. */
+		imir |= E1000_IMIR_PORT_BP;
+	else
+		imir &= ~E1000_IMIR_PORT_BP;
 
-	E1000_WRITE_REG(hw, E1000_TTQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIR(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), 0);
+	imir |= filter->filter_info.priority << E1000_IMIR_PRIORITY_SHIFT;
+
+	ttqf |= E1000_TTQF_QUEUE_ENABLE;
+	ttqf |= (uint32_t)(filter->queue << E1000_TTQF_QUEUE_SHIFT);
+	ttqf |= (uint32_t)(filter->filter_info.proto & E1000_TTQF_PROTOCOL_MASK);
+	if (filter->filter_info.proto_mask == 0)
+		ttqf &= ~E1000_TTQF_MASK_ENABLE;
+
+	/* tcp flags bits setting. */
+	if (filter->filter_info.tcp_flags & TCP_FLAG_ALL) {
+		if (filter->filter_info.tcp_flags & TCP_URG_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_URG;
+		if (filter->filter_info.tcp_flags & TCP_ACK_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_ACK;
+		if (filter->filter_info.tcp_flags & TCP_PSH_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_PSH;
+		if (filter->filter_info.tcp_flags & TCP_RST_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_RST;
+		if (filter->filter_info.tcp_flags & TCP_SYN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_SYN;
+		if (filter->filter_info.tcp_flags & TCP_FIN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_FIN;
+	} else
+		imir_ext |= E1000_IMIREXT_CTRL_BP;
+	E1000_WRITE_REG(hw, E1000_IMIR(i), imir);
+	E1000_WRITE_REG(hw, E1000_TTQF(i), ttqf);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(i), imir_ext);
 	return 0;
 }
 
 /*
- * get a 2tuple filter
+ * igb_remove_2tuple_filter - remove a 2tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates.
- * filter: ponter to the filter that returns.
- * *rx_queue: pointer of the queue id the filter assigned to.
+ * ntuple_filter: ponter to the filter that will be removed.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_get_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue)
+igb_remove_2tuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t imir, ttqf, imir_ext;
-
-	MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_2tuple_filter_info filter_2tuple;
+	struct e1000_2tuple_filter *filter;
+	int ret;
 
-	if (index >= E1000_MAX_TTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	memset(&filter_2tuple, 0, sizeof(struct e1000_2tuple_filter_info));
+	ret = ntuple_filter_to_2tuple(ntuple_filter,
+				      &filter_2tuple);
+	if (ret < 0)
+		return ret;
 
-	ttqf = E1000_READ_REG(hw, E1000_TTQF(index));
-	if (ttqf & E1000_TTQF_QUEUE_ENABLE) {
-		imir = E1000_READ_REG(hw, E1000_IMIR(index));
-		filter->protocol = ttqf & E1000_TTQF_PROTOCOL_MASK;
-		filter->protocol_mask = (ttqf & E1000_TTQF_MASK_ENABLE) ? 1 : 0;
-		*rx_queue = (ttqf & E1000_TTQF_RX_QUEUE_MASK) >>
-				E1000_TTQF_QUEUE_SHIFT;
-		filter->dst_port = (uint16_t)(imir & E1000_IMIR_DSTPORT);
-		filter->dst_port_mask = (imir & E1000_IMIR_PORT_BP) ? 1 : 0;
-		filter->priority = (imir & E1000_IMIR_PRIORITY) >>
-			E1000_IMIR_PRIORITY_SHIFT;
-
-		imir_ext = E1000_READ_REG(hw, E1000_IMIREXT(index));
-		if (!(imir_ext & E1000_IMIR_EXT_CTRL_BP)) {
-			if (imir_ext & E1000_IMIR_EXT_CTRL_UGR)
-				filter->tcp_flags |= TCP_UGR_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_ACK)
-				filter->tcp_flags |= TCP_ACK_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_PSH)
-				filter->tcp_flags |= TCP_PSH_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_RST)
-				filter->tcp_flags |= TCP_RST_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_SYN)
-				filter->tcp_flags |= TCP_SYN_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_FIN)
-				filter->tcp_flags |= TCP_FIN_FLAG;
-		} else
-			filter->tcp_flags = 0;
-		return 0;
+	filter = igb_2tuple_filter_lookup(&filter_info->twotuple_list,
+					 &filter_2tuple);
+	if (filter == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
 	}
-	return -ENOENT;
+
+	filter_info->twotuple_mask &= ~(1 << filter->index);
+	TAILQ_REMOVE(&filter_info->twotuple_list, filter, entries);
+	rte_free(filter);
+
+	E1000_WRITE_REG(hw, E1000_TTQF(filter->index), E1000_TTQF_DISABLE_MASK);
+	E1000_WRITE_REG(hw, E1000_IMIR(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(filter->index), 0);
+	return 0;
 }
 
 /*
@@ -2807,192 +2875,265 @@ eth_igb_get_flex_filter(struct rte_eth_dev *dev, uint16_t index,
 	return -ENOENT;
 }
 
-/*
- * 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
-eth_igb_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue)
+/* translate elements in struct rte_eth_ntuple_filter to struct e1000_5tuple_filter_info*/
+static inline int
+ntuple_filter_to_5tuple_82576(struct rte_eth_ntuple_filter *filter,
+			struct e1000_5tuple_filter_info *filter_info)
 {
-	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t ftqf, spqf = 0;
-	uint32_t imir = 0;
-	uint32_t imir_ext = 0;
+	if (filter->queue >= IGB_MAX_RX_QUEUE_NUM_82576)
+		return -EINVAL;
+	if (filter->priority > E1000_2TUPLE_MAX_PRI)
+		return -EINVAL;  /* filter index is out of range. */
+	if (filter->tcp_flags > TCP_FLAG_ALL)
+		return -EINVAL;  /* flags is invalid. */
 
-	if (hw->mac.type != e1000_82576)
-		return -ENOSYS;
+	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;
+	}
 
-	if (index >= E1000_MAX_FTQF_FILTERS ||
-		rx_queue >= IGB_MAX_RX_QUEUE_NUM_82576)
-		return -EINVAL;  /* filter index is out of range. */
+	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;
+	}
 
-	ftqf = E1000_READ_REG(hw, E1000_FTQF(index));
-	if (ftqf & E1000_FTQF_QUEUE_ENABLE)
-		return -EINVAL;  /* filter index is in use. */
-
-	ftqf = 0;
-	ftqf |= filter->protocol & E1000_FTQF_PROTOCOL_MASK;
-	if (filter->src_ip_mask == 1) /* 1b means not compare. */
-		ftqf |= E1000_FTQF_SOURCE_ADDR_MASK;
-	if (filter->dst_ip_mask == 1)
-		ftqf |= E1000_FTQF_DEST_ADDR_MASK;
-	if (filter->src_port_mask == 1)
-		ftqf |= E1000_FTQF_SOURCE_PORT_MASK;
-	if (filter->protocol_mask == 1)
-		ftqf |= E1000_FTQF_PROTOCOL_COMP_MASK;
-	ftqf |= (rx_queue << E1000_FTQF_QUEUE_SHIFT) & E1000_FTQF_QUEUE_MASK;
-	ftqf |= E1000_FTQF_VF_MASK_EN;
-	ftqf |= E1000_FTQF_QUEUE_ENABLE;
-	E1000_WRITE_REG(hw, E1000_FTQF(index), ftqf);
-	E1000_WRITE_REG(hw, E1000_DAQF(index), filter->dst_ip);
-	E1000_WRITE_REG(hw, E1000_SAQF(index), filter->src_ip);
+	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;
+	}
 
-	spqf |= filter->src_port & E1000_SPQF_SRCPORT;
-	E1000_WRITE_REG(hw, E1000_SPQF(index), spqf);
+	switch (filter->proto_mask) {
+	case UINT8_MAX:
+		filter_info->proto_mask = 0;
+		filter_info->proto = filter->proto;
+		break;
+	case 0:
+		filter_info->proto_mask = 1;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "invalid protocol mask.");
+		return -EINVAL;
+	}
 
-	imir |= (uint32_t)(filter->dst_port & E1000_IMIR_DSTPORT);
-	if (filter->dst_port_mask == 1) /* 1b means not compare. */
-		imir |= E1000_IMIR_PORT_BP;
+	filter_info->priority = (uint8_t)filter->priority;
+	if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG)
+		filter_info->tcp_flags = filter->tcp_flags;
 	else
-		imir &= ~E1000_IMIR_PORT_BP;
-	imir |= filter->priority << E1000_IMIR_PRIORITY_SHIFT;
+		filter_info->tcp_flags = 0;
 
-	imir_ext |= E1000_IMIR_EXT_SIZE_BP;
-	/* tcp flags bits setting. */
-	if (filter->tcp_flags & TCP_FLAG_ALL) {
-		if (filter->tcp_flags & TCP_UGR_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_UGR;
-		if (filter->tcp_flags & TCP_ACK_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_ACK;
-		if (filter->tcp_flags & TCP_PSH_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_PSH;
-		if (filter->tcp_flags & TCP_RST_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_RST;
-		if (filter->tcp_flags & TCP_SYN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_SYN;
-		if (filter->tcp_flags & TCP_FIN_FLAG)
-			imir_ext |= E1000_IMIR_EXT_CTRL_FIN;
-	} else
-		imir_ext |= E1000_IMIR_EXT_CTRL_BP;
-	E1000_WRITE_REG(hw, E1000_IMIR(index), imir);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), imir_ext);
 	return 0;
 }
 
+static inline struct e1000_5tuple_filter *
+igb_5tuple_filter_lookup_82576(struct e1000_5tuple_filter_list *filter_list,
+			struct e1000_5tuple_filter_info *key)
+{
+	struct e1000_5tuple_filter *it;
+
+	TAILQ_FOREACH(it, filter_list, entries) {
+		if (memcmp(key, &it->filter_info,
+			sizeof(struct e1000_5tuple_filter_info)) == 0) {
+			return it;
+		}
+	}
+	return NULL;
+}
+
 /*
- * remove a 5tuple filter
+ * igb_add_5tuple_filter_82576 - add a 5tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates
+ * ntuple_filter: ponter to the filter that will be added.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_remove_5tuple_filter(struct rte_eth_dev *dev,
-				uint16_t index)
+igb_add_5tuple_filter_82576(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_5tuple_filter *filter;
+	uint32_t ftqf = E1000_FTQF_VF_BP | E1000_FTQF_MASK;
+	uint32_t spqf, imir, imir_ext = E1000_IMIREXT_SIZE_BP;
+	uint8_t i;
+	int ret;
+
+	filter = rte_zmalloc("e1000_5tuple_filter",
+			sizeof(struct e1000_5tuple_filter), 0);
+	if (filter == NULL)
+		return -ENOMEM;
+
+	ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+					    &filter->filter_info);
+	if (ret < 0) {
+		rte_free(filter);
+		return ret;
+	}
 
-	if (hw->mac.type != e1000_82576)
+	if (igb_5tuple_filter_lookup_82576(&filter_info->fivetuple_list,
+					 &filter->filter_info) != NULL) {
+		PMD_DRV_LOG(ERR, "filter exists.");
+		rte_free(filter);
+		return -EEXIST;
+	}
+	filter->queue = ntuple_filter->queue;
+
+	/*
+	 * look for an unused 5tuple filter index,
+	 * and insert the filter to list.
+	 */
+	for (i = 0; i < E1000_MAX_FTQF_FILTERS; i++) {
+		if (!(filter_info->fivetuple_mask & (1 << i))) {
+			filter_info->fivetuple_mask |= 1 << i;
+			filter->index = i;
+			TAILQ_INSERT_TAIL(&filter_info->fivetuple_list,
+					  filter,
+					  entries);
+			break;
+		}
+	}
+	if (i >= E1000_MAX_FTQF_FILTERS) {
+		PMD_DRV_LOG(ERR, "5tuple filters are full.");
+		rte_free(filter);
 		return -ENOSYS;
+	}
 
-	if (index >= E1000_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	ftqf |= filter->filter_info.proto & E1000_FTQF_PROTOCOL_MASK;
+	if (filter->filter_info.src_ip_mask == 0) /* 0b means compare. */
+		ftqf &= ~E1000_FTQF_MASK_SOURCE_ADDR_BP;
+	if (filter->filter_info.dst_ip_mask == 0)
+		ftqf &= ~E1000_FTQF_MASK_DEST_ADDR_BP;
+	if (filter->filter_info.src_port_mask == 0)
+		ftqf &= ~E1000_FTQF_MASK_SOURCE_PORT_BP;
+	if (filter->filter_info.proto_mask == 0)
+		ftqf &= ~E1000_FTQF_MASK_PROTO_BP;
+	ftqf |= (filter->queue << E1000_FTQF_QUEUE_SHIFT) &
+		E1000_FTQF_QUEUE_MASK;
+	ftqf |= E1000_FTQF_QUEUE_ENABLE;
+	E1000_WRITE_REG(hw, E1000_FTQF(i), ftqf);
+	E1000_WRITE_REG(hw, E1000_DAQF(i), filter->filter_info.dst_ip);
+	E1000_WRITE_REG(hw, E1000_SAQF(i), filter->filter_info.src_ip);
+
+	spqf = filter->filter_info.src_port & E1000_SPQF_SRCPORT;
+	E1000_WRITE_REG(hw, E1000_SPQF(i), spqf);
 
-	E1000_WRITE_REG(hw, E1000_FTQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_DAQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_SAQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_SPQF(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIR(index), 0);
-	E1000_WRITE_REG(hw, E1000_IMIREXT(index), 0);
+	imir = (uint32_t)(filter->filter_info.dst_port & E1000_IMIR_DSTPORT);
+	if (filter->filter_info.dst_port_mask == 1) /* 1b means not compare. */
+		imir |= E1000_IMIR_PORT_BP;
+	else
+		imir &= ~E1000_IMIR_PORT_BP;
+	imir |= filter->filter_info.priority << E1000_IMIR_PRIORITY_SHIFT;
+
+	/* tcp flags bits setting. */
+	if (filter->filter_info.tcp_flags & TCP_FLAG_ALL) {
+		if (filter->filter_info.tcp_flags & TCP_URG_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_URG;
+		if (filter->filter_info.tcp_flags & TCP_ACK_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_ACK;
+		if (filter->filter_info.tcp_flags & TCP_PSH_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_PSH;
+		if (filter->filter_info.tcp_flags & TCP_RST_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_RST;
+		if (filter->filter_info.tcp_flags & TCP_SYN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_SYN;
+		if (filter->filter_info.tcp_flags & TCP_FIN_FLAG)
+			imir_ext |= E1000_IMIREXT_CTRL_FIN;
+	} else
+		imir_ext |= E1000_IMIREXT_CTRL_BP;
+	E1000_WRITE_REG(hw, E1000_IMIR(i), imir);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(i), imir_ext);
 	return 0;
 }
 
 /*
- * get a 5tuple filter
+ * igb_remove_5tuple_filter_82576 - remove a 5tuple filter
  *
  * @param
  * dev: Pointer to struct rte_eth_dev.
- * index: the index the filter allocates
- * filter: ponter to the filter that returns
- * *rx_queue: pointer of the queue id the filter assigned to
+ * ntuple_filter: ponter to the filter that will be removed.
  *
  * @return
  *    - On success, zero.
  *    - On failure, a negative value.
  */
 static int
-eth_igb_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue)
+igb_remove_5tuple_filter_82576(struct rte_eth_dev *dev,
+				struct rte_eth_ntuple_filter *ntuple_filter)
 {
 	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
-	uint32_t spqf, ftqf, imir, imir_ext;
-
-	if (hw->mac.type != e1000_82576)
-		return -ENOSYS;
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_5tuple_filter_info filter_5tuple;
+	struct e1000_5tuple_filter *filter;
+	int ret;
 
-	if (index >= E1000_MAX_FTQF_FILTERS)
-		return -EINVAL;  /* filter index is out of range. */
+	memset(&filter_5tuple, 0, sizeof(struct e1000_5tuple_filter_info));
+	ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+					    &filter_5tuple);
+	if (ret < 0)
+		return ret;
 
-	ftqf = E1000_READ_REG(hw, E1000_FTQF(index));
-	if (ftqf & E1000_FTQF_QUEUE_ENABLE) {
-		filter->src_ip_mask =
-			(ftqf & E1000_FTQF_SOURCE_ADDR_MASK) ? 1 : 0;
-		filter->dst_ip_mask =
-			(ftqf & E1000_FTQF_DEST_ADDR_MASK) ? 1 : 0;
-		filter->src_port_mask =
-			(ftqf & E1000_FTQF_SOURCE_PORT_MASK) ? 1 : 0;
-		filter->protocol_mask =
-			(ftqf & E1000_FTQF_PROTOCOL_COMP_MASK) ? 1 : 0;
-		filter->protocol =
-			(uint8_t)ftqf & E1000_FTQF_PROTOCOL_MASK;
-		*rx_queue = (uint16_t)((ftqf & E1000_FTQF_QUEUE_MASK) >>
-				E1000_FTQF_QUEUE_SHIFT);
-
-		spqf = E1000_READ_REG(hw, E1000_SPQF(index));
-		filter->src_port = spqf & E1000_SPQF_SRCPORT;
-
-		filter->dst_ip = E1000_READ_REG(hw, E1000_DAQF(index));
-		filter->src_ip = E1000_READ_REG(hw, E1000_SAQF(index));
-
-		imir = E1000_READ_REG(hw, E1000_IMIR(index));
-		filter->dst_port_mask = (imir & E1000_IMIR_PORT_BP) ? 1 : 0;
-		filter->dst_port = (uint16_t)(imir & E1000_IMIR_DSTPORT);
-		filter->priority = (imir & E1000_IMIR_PRIORITY) >>
-			E1000_IMIR_PRIORITY_SHIFT;
-
-		imir_ext = E1000_READ_REG(hw, E1000_IMIREXT(index));
-		if (!(imir_ext & E1000_IMIR_EXT_CTRL_BP)) {
-			if (imir_ext & E1000_IMIR_EXT_CTRL_UGR)
-				filter->tcp_flags |= TCP_UGR_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_ACK)
-				filter->tcp_flags |= TCP_ACK_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_PSH)
-				filter->tcp_flags |= TCP_PSH_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_RST)
-				filter->tcp_flags |= TCP_RST_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_SYN)
-				filter->tcp_flags |= TCP_SYN_FLAG;
-			if (imir_ext & E1000_IMIR_EXT_CTRL_FIN)
-				filter->tcp_flags |= TCP_FIN_FLAG;
-		} else
-			filter->tcp_flags = 0;
-		return 0;
+	filter = igb_5tuple_filter_lookup_82576(&filter_info->fivetuple_list,
+					 &filter_5tuple);
+	if (filter == NULL) {
+		PMD_DRV_LOG(ERR, "filter doesn't exist.");
+		return -ENOENT;
 	}
-	return -ENOENT;
+
+	filter_info->fivetuple_mask &= ~(1 << filter->index);
+	TAILQ_REMOVE(&filter_info->fivetuple_list, filter, entries);
+	rte_free(filter);
+
+	E1000_WRITE_REG(hw, E1000_FTQF(filter->index),
+			E1000_FTQF_VF_BP | E1000_FTQF_MASK);
+	E1000_WRITE_REG(hw, E1000_DAQF(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_SAQF(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_SPQF(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_IMIR(filter->index), 0);
+	E1000_WRITE_REG(hw, E1000_IMIREXT(filter->index), 0);
+	return 0;
 }
 
 static int
@@ -3045,6 +3186,175 @@ eth_igb_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	return 0;
 }
 
+/*
+ * igb_add_del_ntuple_filter - 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.
+ */
+static int
+igb_add_del_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter,
+			bool add)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
+
+	switch (ntuple_filter->flags) {
+	case RTE_5TUPLE_FLAGS:
+	case (RTE_5TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82576)
+			return -ENOTSUP;
+		if (add)
+			ret = igb_add_5tuple_filter_82576(dev,
+							  ntuple_filter);
+		else
+			ret = igb_remove_5tuple_filter_82576(dev,
+							     ntuple_filter);
+		break;
+	case RTE_2TUPLE_FLAGS:
+	case (RTE_2TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82580 && hw->mac.type != e1000_i350)
+			return -ENOTSUP;
+		if (add)
+			ret = igb_add_2tuple_filter(dev, ntuple_filter);
+		else
+			ret = igb_remove_2tuple_filter(dev, ntuple_filter);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * igb_get_ntuple_filter - get a ntuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * ntuple_filter: Pointer to struct rte_eth_ntuple_filter
+ *
+ * @return
+ *    - On success, zero.
+ *    - On failure, a negative value.
+ */
+static int
+igb_get_ntuple_filter(struct rte_eth_dev *dev,
+			struct rte_eth_ntuple_filter *ntuple_filter)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct e1000_filter_info *filter_info =
+		E1000_DEV_PRIVATE_TO_FILTER_INFO(dev->data->dev_private);
+	struct e1000_5tuple_filter_info filter_5tuple;
+	struct e1000_2tuple_filter_info filter_2tuple;
+	struct e1000_5tuple_filter *p_5tuple_filter;
+	struct e1000_2tuple_filter *p_2tuple_filter;
+	int ret;
+
+	switch (ntuple_filter->flags) {
+	case RTE_5TUPLE_FLAGS:
+	case (RTE_5TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82576)
+			return -ENOTSUP;
+		memset(&filter_5tuple,
+			0,
+			sizeof(struct e1000_5tuple_filter_info));
+		ret = ntuple_filter_to_5tuple_82576(ntuple_filter,
+						    &filter_5tuple);
+		if (ret < 0)
+			return ret;
+		p_5tuple_filter = igb_5tuple_filter_lookup_82576(
+					&filter_info->fivetuple_list,
+					&filter_5tuple);
+		if (p_5tuple_filter == NULL) {
+			PMD_DRV_LOG(ERR, "filter doesn't exist.");
+			return -ENOENT;
+		}
+		ntuple_filter->queue = p_5tuple_filter->queue;
+		break;
+	case RTE_2TUPLE_FLAGS:
+	case (RTE_2TUPLE_FLAGS | RTE_NTUPLE_FLAGS_TCP_FLAG):
+		if (hw->mac.type != e1000_82580 && hw->mac.type != e1000_i350)
+			return -ENOTSUP;
+		memset(&filter_2tuple,
+			0,
+			sizeof(struct e1000_2tuple_filter_info));
+		ret = ntuple_filter_to_2tuple(ntuple_filter, &filter_2tuple);
+		if (ret < 0)
+			return ret;
+		p_2tuple_filter = igb_2tuple_filter_lookup(
+					&filter_info->twotuple_list,
+					&filter_2tuple);
+		if (p_2tuple_filter == NULL) {
+			PMD_DRV_LOG(ERR, "filter doesn't exist.");
+			return -ENOENT;
+		}
+		ntuple_filter->queue = p_2tuple_filter->queue;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * igb_ntuple_filter_handle - Handle operations for ntuple filter.
+ * @dev: pointer to rte_eth_dev structure
+ * @filter_op:operation will be taken.
+ * @arg: a pointer to specific structure corresponding to the filter_op
+ */
+static int
+igb_ntuple_filter_handle(struct rte_eth_dev *dev,
+				enum rte_filter_op filter_op,
+				void *arg)
+{
+	struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	int ret;
+
+	MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+	if (filter_op == RTE_ETH_FILTER_NOP)
+		return 0;
+
+	if (arg == NULL) {
+		PMD_DRV_LOG(ERR, "arg shouldn't be NULL for operation %u.",
+			    filter_op);
+		return -EINVAL;
+	}
+
+	switch (filter_op) {
+	case RTE_ETH_FILTER_ADD:
+		ret = igb_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			TRUE);
+		break;
+	case RTE_ETH_FILTER_DELETE:
+		ret = igb_add_del_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg,
+			FALSE);
+		break;
+	case RTE_ETH_FILTER_GET:
+		ret = igb_get_ntuple_filter(dev,
+			(struct rte_eth_ntuple_filter *)arg);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "unsupported operation %u.", filter_op);
+		ret = -EINVAL;
+		break;
+	}
+	return ret;
+}
+
 static inline int
 igb_ethertype_filter_lookup(struct e1000_filter_info *filter_info,
 			uint16_t ethertype)
@@ -3234,6 +3544,9 @@ eth_igb_filter_ctrl(struct rte_eth_dev *dev,
 	int ret = -EINVAL;
 
 	switch (filter_type) {
+	case RTE_ETH_FILTER_NTUPLE:
+		ret = igb_ntuple_filter_handle(dev, filter_op, arg);
+		break;
 	case RTE_ETH_FILTER_ETHERTYPE:
 		ret = igb_ethertype_filter_handle(dev, filter_op, arg);
 		break;
-- 
1.9.3

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

* [dpdk-dev] [PATCH v3 4/6] testpmd: new commands for ntuple filter
  2015-02-10  4:48   ` [dpdk-dev] [PATCH v3 " Jingjing Wu
                       ` (2 preceding siblings ...)
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 3/6] e1000: ntuple filter functions replace old ones for 2tuple and " Jingjing Wu
@ 2015-02-10  4:48     ` Jingjing Wu
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 5/6] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
                       ` (3 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-02-10  4:48 UTC (permalink / raw)
  To: dev

Following commands of 5tuple and 2tuple filter are removed:
 - add_2tuple_filter (port_id) protocol (pro_value) (pro_mask)
   dst_port (port_value) (port_mask) flags (flg_value) priority (prio_value)
   queue (queue_id) index (idx)
 - remove_2tuple_filter (port_id) index (idx)
 - get_2tuple_filter (port_id) index (idx)
 - add_5tuple_filter (port_id) dst_ip (dst_address) src_ip (src_address)
   dst_port (dst_port_value) src_port (src_port_value) protocol (protocol_value)
   mask (mask_value) flags (flags_value) priority (prio_value)"
   queue (queue_id) index (idx)
 - remove_5tuple_filter (port_id) index (idx)
 - get_5tuple_filter (port_id) index (idx)

New commands are added for 5tuple and 2tuple filter by using filter_ctrl API
and new ntuple filter structure:
 - 2tuple_filter (port_id) (add|del)
   dst_port (dst_port_value) protocol (protocol_value)
   mask (mask_value) tcp_flags (tcp_flags_value)
   priority (prio_value) queue (queue_id)
 - 5tuple_filter (port_id) (add|del)
   dst_ip (dst_address) src_ip (src_address)
   dst_port (dst_port_value) src_port (src_port_value)
   protocol (protocol_value)
   mask (mask_value) tcp_flags (tcp_flags_value)
   priority (prio_value) queue (queue_id)

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 app/test-pmd/cmdline.c | 406 ++++++++++++++++++++++---------------------------
 app/test-pmd/config.c  |  65 --------
 2 files changed, 186 insertions(+), 285 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 590e427..c96f4d1 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -660,28 +660,19 @@ static void cmd_help_long_parsed(void *parsed_result,
 			" (ether_type) (drop|fwd) queue (queue_id)\n"
 			"    Add/Del an ethertype filter.\n\n"
 
-			"add_2tuple_filter (port_id) protocol (pro_value) (pro_mask)"
-			" dst_port (port_value) (port_mask) flags (flg_value) priority (prio_value)"
-			" queue (queue_id) index (idx)\n"
-			"    add a 2tuple filter.\n\n"
-
-			"remove_2tuple_filter (port_id) index (idx)\n"
-			"    remove a 2tuple filter.\n\n"
-
-			"get_2tuple_filter (port_id) index (idx)\n"
-			"    get info of a 2tuple filter.\n\n"
-
-			"add_5tuple_filter (port_id) dst_ip (dst_address) src_ip (src_address)"
-			" dst_port (dst_port_value) src_port (src_port_value) protocol (protocol_value)"
-			" mask (mask_value) flags (flags_value) priority (prio_value)"
-			" queue (queue_id) index (idx)\n"
-			"    add a 5tuple filter.\n\n"
-
-			"remove_5tuple_filter (port_id) index (idx)\n"
-			"    remove a 5tuple filter.\n\n"
-
-			"get_5tuple_filter (port_id) index (idx)\n"
-			"    get info of a 5tuple filter.\n\n"
+			"2tuple_filter (port_id) (add|del)"
+			" dst_port (dst_port_value) protocol (protocol_value)"
+			" mask (mask_value) tcp_flags (tcp_flags_value)"
+			" priority (prio_value) queue (queue_id)\n"
+			"    Add/Del a 2tuple filter.\n\n"
+
+			"5tuple_filter (port_id) (add|del)"
+			" dst_ip (dst_address) src_ip (src_address)"
+			" dst_port (dst_port_value) src_port (src_port_value)"
+			" protocol (protocol_value)"
+			" mask (mask_value) tcp_flags (tcp_flags_value)"
+			" priority (prio_value) queue (queue_id)\n"
+			"    Add/Del a 5tuple filter.\n\n"
 
 			"add_syn_filter (port_id) priority (high|low) queue (queue_id)"
 			"    add syn filter.\n\n"
@@ -7373,21 +7364,20 @@ cmdline_parse_inst_t cmd_get_syn_filter = {
 /* *** ADD/REMOVE A 2tuple FILTER *** */
 struct cmd_2tuple_filter_result {
 	cmdline_fixed_string_t filter;
-	uint8_t port_id;
-	cmdline_fixed_string_t protocol;
-	uint8_t protocol_value;
-	uint8_t protocol_mask;
+	uint8_t  port_id;
+	cmdline_fixed_string_t ops;
 	cmdline_fixed_string_t dst_port;
 	uint16_t dst_port_value;
-	uint16_t dst_port_mask;
-	cmdline_fixed_string_t flags;
-	uint8_t flags_value;
+	cmdline_fixed_string_t protocol;
+	uint8_t protocol_value;
+	cmdline_fixed_string_t mask;
+	uint8_t  mask_value;
+	cmdline_fixed_string_t tcp_flags;
+	uint8_t tcp_flags_value;
 	cmdline_fixed_string_t priority;
-	uint8_t priority_value;
+	uint8_t  priority_value;
 	cmdline_fixed_string_t queue;
-	uint16_t queue_id;
-	cmdline_fixed_string_t index;
-	uint16_t index_value;
+	uint16_t  queue_id;
 };
 
 static void
@@ -7395,59 +7385,92 @@ cmd_2tuple_filter_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
 			__attribute__((unused)) void *data)
 {
-	int ret = 0;
-	struct rte_2tuple_filter filter;
+	struct rte_eth_ntuple_filter filter;
 	struct cmd_2tuple_filter_result *res = parsed_result;
+	int ret = 0;
 
-	memset(&filter, 0, sizeof(struct rte_2tuple_filter));
+	ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
+	if (ret < 0) {
+		printf("ntuple filter is not supported on port %u.\n",
+			res->port_id);
+		return;
+	}
 
-	if (!strcmp(res->filter, "add_2tuple_filter")) {
-		/* need convert to big endian. */
-		filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
-		filter.protocol = res->protocol_value;
-		filter.dst_port_mask = (res->dst_port_mask) ? 0 : 1;
-		filter.protocol_mask = (res->protocol_mask) ? 0 : 1;
-		filter.priority = res->priority_value;
-		filter.tcp_flags = res->flags_value;
-		ret = rte_eth_dev_add_2tuple_filter(res->port_id,
-			res->index_value, &filter, res->queue_id);
-	} else if (!strcmp(res->filter, "remove_2tuple_filter"))
-		ret = rte_eth_dev_remove_2tuple_filter(res->port_id,
-			res->index_value);
-	else if (!strcmp(res->filter, "get_2tuple_filter"))
-		get_2tuple_filter(res->port_id, res->index_value);
+	memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
 
+	filter.flags = RTE_2TUPLE_FLAGS;
+	filter.dst_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
+	filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
+	filter.proto = res->protocol_value;
+	filter.priority = res->priority_value;
+	if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
+		printf("nonzero tcp_flags is only meaningful"
+			" when protocol is TCP.\n");
+		return;
+	}
+	if (res->tcp_flags_value > TCP_FLAG_ALL) {
+		printf("invalid TCP flags.\n");
+		return;
+	}
+
+	if (res->tcp_flags_value != 0) {
+		filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
+		filter.tcp_flags = res->tcp_flags_value;
+	}
+
+	/* need convert to big endian. */
+	filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
+	filter.queue = res->queue_id;
+
+	if (!strcmp(res->ops, "add"))
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_ADD,
+				&filter);
+	else
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_DELETE,
+				&filter);
 	if (ret < 0)
-		printf("2tuple filter setting error: (%s)\n", strerror(-ret));
+		printf("2tuple filter programming error: (%s)\n",
+			strerror(-ret));
+
 }
 
+cmdline_parse_token_string_t cmd_2tuple_filter_filter =
+	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+				 filter, "2tuple_filter");
 cmdline_parse_token_num_t cmd_2tuple_filter_port_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
 				port_id, UINT8);
-cmdline_parse_token_string_t cmd_2tuple_filter_protocol =
+cmdline_parse_token_string_t cmd_2tuple_filter_ops =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				 protocol, "protocol");
-cmdline_parse_token_num_t cmd_2tuple_filter_protocol_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				 protocol_value, UINT8);
-cmdline_parse_token_num_t cmd_2tuple_filter_protocol_mask =
-	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				protocol_mask, UINT8);
+				 ops, "add#del");
 cmdline_parse_token_string_t cmd_2tuple_filter_dst_port =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
 				dst_port, "dst_port");
 cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
 				dst_port_value, UINT16);
-cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_mask =
+cmdline_parse_token_string_t cmd_2tuple_filter_protocol =
+	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+				protocol, "protocol");
+cmdline_parse_token_num_t cmd_2tuple_filter_protocol_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				dst_port_mask, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_flags =
+				protocol_value, UINT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_mask =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				flags, "flags");
-cmdline_parse_token_num_t cmd_2tuple_filter_flags_value =
+				mask, "mask");
+cmdline_parse_token_num_t cmd_2tuple_filter_mask_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				flags_value, UINT8);
+				mask_value, INT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_tcp_flags =
+	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+				tcp_flags, "tcp_flags");
+cmdline_parse_token_num_t cmd_2tuple_filter_tcp_flags_value =
+	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+				tcp_flags_value, UINT8);
 cmdline_parse_token_string_t cmd_2tuple_filter_priority =
 	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
 				priority, "priority");
@@ -7460,67 +7483,27 @@ cmdline_parse_token_string_t cmd_2tuple_filter_queue =
 cmdline_parse_token_num_t cmd_2tuple_filter_queue_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
 				queue_id, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_index =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				index, "index");
-cmdline_parse_token_num_t cmd_2tuple_filter_index_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
-				index_value, UINT16);
-cmdline_parse_token_string_t cmd_2tuple_filter_add_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				filter, "add_2tuple_filter");
-cmdline_parse_inst_t cmd_add_2tuple_filter = {
+
+cmdline_parse_inst_t cmd_2tuple_filter = {
 	.f = cmd_2tuple_filter_parsed,
 	.data = NULL,
 	.help_str = "add a 2tuple filter",
 	.tokens = {
-		(void *)&cmd_2tuple_filter_add_filter,
+		(void *)&cmd_2tuple_filter_filter,
 		(void *)&cmd_2tuple_filter_port_id,
-		(void *)&cmd_2tuple_filter_protocol,
-		(void *)&cmd_2tuple_filter_protocol_value,
-		(void *)&cmd_2tuple_filter_protocol_mask,
+		(void *)&cmd_2tuple_filter_ops,
 		(void *)&cmd_2tuple_filter_dst_port,
 		(void *)&cmd_2tuple_filter_dst_port_value,
-		(void *)&cmd_2tuple_filter_dst_port_mask,
-		(void *)&cmd_2tuple_filter_flags,
-		(void *)&cmd_2tuple_filter_flags_value,
+		(void *)&cmd_2tuple_filter_protocol,
+		(void *)&cmd_2tuple_filter_protocol_value,
+		(void *)&cmd_2tuple_filter_mask,
+		(void *)&cmd_2tuple_filter_mask_value,
+		(void *)&cmd_2tuple_filter_tcp_flags,
+		(void *)&cmd_2tuple_filter_tcp_flags_value,
 		(void *)&cmd_2tuple_filter_priority,
 		(void *)&cmd_2tuple_filter_priority_value,
 		(void *)&cmd_2tuple_filter_queue,
 		(void *)&cmd_2tuple_filter_queue_id,
-		(void *)&cmd_2tuple_filter_index,
-		(void *)&cmd_2tuple_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_2tuple_filter_remove_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				filter, "remove_2tuple_filter");
-cmdline_parse_inst_t cmd_remove_2tuple_filter = {
-	.f = cmd_2tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "remove a 2tuple filter",
-	.tokens = {
-		(void *)&cmd_2tuple_filter_remove_filter,
-		(void *)&cmd_2tuple_filter_port_id,
-		(void *)&cmd_2tuple_filter_index,
-		(void *)&cmd_2tuple_filter_index_value,
-		NULL,
-	},
-};
-cmdline_parse_token_string_t cmd_2tuple_filter_get_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
-				filter, "get_2tuple_filter");
-cmdline_parse_inst_t cmd_get_2tuple_filter = {
-	.f = cmd_2tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "get a 2tuple filter",
-	.tokens = {
-		(void *)&cmd_2tuple_filter_get_filter,
-		(void *)&cmd_2tuple_filter_port_id,
-		(void *)&cmd_2tuple_filter_index,
-		(void *)&cmd_2tuple_filter_index_value,
 		NULL,
 	},
 };
@@ -7529,6 +7512,7 @@ cmdline_parse_inst_t cmd_get_2tuple_filter = {
 struct cmd_5tuple_filter_result {
 	cmdline_fixed_string_t filter;
 	uint8_t  port_id;
+	cmdline_fixed_string_t ops;
 	cmdline_fixed_string_t dst_ip;
 	cmdline_ipaddr_t dst_ip_value;
 	cmdline_fixed_string_t src_ip;
@@ -7541,14 +7525,12 @@ struct cmd_5tuple_filter_result {
 	uint8_t protocol_value;
 	cmdline_fixed_string_t mask;
 	uint8_t  mask_value;
-	cmdline_fixed_string_t flags;
-	uint8_t flags_value;
+	cmdline_fixed_string_t tcp_flags;
+	uint8_t tcp_flags_value;
 	cmdline_fixed_string_t priority;
 	uint8_t  priority_value;
 	cmdline_fixed_string_t queue;
 	uint16_t  queue_id;
-	cmdline_fixed_string_t index;
-	uint16_t  index_value;
 };
 
 static void
@@ -7556,62 +7538,92 @@ cmd_5tuple_filter_parsed(void *parsed_result,
 			__attribute__((unused)) struct cmdline *cl,
 			__attribute__((unused)) void *data)
 {
-	int ret = 0;
-	struct rte_5tuple_filter filter;
+	struct rte_eth_ntuple_filter filter;
 	struct cmd_5tuple_filter_result *res = parsed_result;
+	int ret = 0;
 
-	memset(&filter, 0, sizeof(struct rte_5tuple_filter));
+	ret = rte_eth_dev_filter_supported(res->port_id, RTE_ETH_FILTER_NTUPLE);
+	if (ret < 0) {
+		printf("ntuple filter is not supported on port %u.\n",
+			res->port_id);
+		return;
+	}
 
-	if (!strcmp(res->filter, "add_5tuple_filter")) {
-		filter.dst_ip_mask = (res->mask_value & 0x10) ? 0 : 1;
-		filter.src_ip_mask = (res->mask_value & 0x08) ? 0 : 1;
-		filter.dst_port_mask = (res->mask_value & 0x04) ? 0 : 1;
-		filter.src_port_mask = (res->mask_value & 0x02) ? 0 : 1;
-		filter.protocol = res->protocol_value;
-		filter.protocol_mask = (res->mask_value & 0x01) ? 0 : 1;
-		filter.priority = res->priority_value;
-		filter.tcp_flags = res->flags_value;
+	memset(&filter, 0, sizeof(struct rte_eth_ntuple_filter));
+
+	filter.flags = RTE_5TUPLE_FLAGS;
+	filter.dst_ip_mask = (res->mask_value & 0x10) ? UINT32_MAX : 0;
+	filter.src_ip_mask = (res->mask_value & 0x08) ? UINT32_MAX : 0;
+	filter.dst_port_mask = (res->mask_value & 0x04) ? UINT16_MAX : 0;
+	filter.src_port_mask = (res->mask_value & 0x02) ? UINT16_MAX : 0;
+	filter.proto_mask = (res->mask_value & 0x01) ? UINT8_MAX : 0;
+	filter.proto = res->protocol_value;
+	filter.priority = res->priority_value;
+	if (res->tcp_flags_value != 0 && filter.proto != IPPROTO_TCP) {
+		printf("nonzero tcp_flags is only meaningful"
+			" when protocol is TCP.\n");
+		return;
+	}
+	if (res->tcp_flags_value > TCP_FLAG_ALL) {
+		printf("invalid TCP flags.\n");
+		return;
+	}
 
-		if (res->dst_ip_value.family == AF_INET)
-			/* no need to convert, already big endian. */
-			filter.dst_ip = res->dst_ip_value.addr.ipv4.s_addr;
-		else {
-			if (filter.dst_ip_mask == 0) {
-				printf("can not support ipv6 involved compare.\n");
-				return;
-			}
-			filter.dst_ip = 0;
+	if (res->tcp_flags_value != 0) {
+		filter.flags |= RTE_NTUPLE_FLAGS_TCP_FLAG;
+		filter.tcp_flags = res->tcp_flags_value;
+	}
+
+	if (res->dst_ip_value.family == AF_INET)
+		/* no need to convert, already big endian. */
+		filter.dst_ip = res->dst_ip_value.addr.ipv4.s_addr;
+	else {
+		if (filter.dst_ip_mask == 0) {
+			printf("can not support ipv6 involved compare.\n");
+			return;
 		}
+		filter.dst_ip = 0;
+	}
 
-		if (res->src_ip_value.family == AF_INET)
-			/* no need to convert, already big endian. */
-			filter.src_ip = res->src_ip_value.addr.ipv4.s_addr;
-		else {
-			if (filter.src_ip_mask == 0) {
-				printf("can not support ipv6 involved compare.\n");
-				return;
-			}
-			filter.src_ip = 0;
+	if (res->src_ip_value.family == AF_INET)
+		/* no need to convert, already big endian. */
+		filter.src_ip = res->src_ip_value.addr.ipv4.s_addr;
+	else {
+		if (filter.src_ip_mask == 0) {
+			printf("can not support ipv6 involved compare.\n");
+			return;
 		}
-		/* need convert to big endian. */
-		filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
-		filter.src_port = rte_cpu_to_be_16(res->src_port_value);
+		filter.src_ip = 0;
+	}
+	/* need convert to big endian. */
+	filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
+	filter.src_port = rte_cpu_to_be_16(res->src_port_value);
+	filter.queue = res->queue_id;
 
-		ret = rte_eth_dev_add_5tuple_filter(res->port_id,
-			res->index_value, &filter, res->queue_id);
-	} else if (!strcmp(res->filter, "remove_5tuple_filter"))
-		ret = rte_eth_dev_remove_5tuple_filter(res->port_id,
-			res->index_value);
-	else if (!strcmp(res->filter, "get_5tuple_filter"))
-		get_5tuple_filter(res->port_id, res->index_value);
+	if (!strcmp(res->ops, "add"))
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_ADD,
+				&filter);
+	else
+		ret = rte_eth_dev_filter_ctrl(res->port_id,
+				RTE_ETH_FILTER_NTUPLE,
+				RTE_ETH_FILTER_DELETE,
+				&filter);
 	if (ret < 0)
-		printf("5tuple filter setting error: (%s)\n", strerror(-ret));
+		printf("5tuple filter programming error: (%s)\n",
+			strerror(-ret));
 }
 
-
+cmdline_parse_token_string_t cmd_5tuple_filter_filter =
+	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+				 filter, "5tuple_filter");
 cmdline_parse_token_num_t cmd_5tuple_filter_port_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
 				port_id, UINT8);
+cmdline_parse_token_string_t cmd_5tuple_filter_ops =
+	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+				 ops, "add#del");
 cmdline_parse_token_string_t cmd_5tuple_filter_dst_ip =
 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
 				dst_ip, "dst_ip");
@@ -7648,12 +7660,12 @@ cmdline_parse_token_string_t cmd_5tuple_filter_mask =
 cmdline_parse_token_num_t cmd_5tuple_filter_mask_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
 				mask_value, INT8);
-cmdline_parse_token_string_t cmd_5tuple_filter_flags =
+cmdline_parse_token_string_t cmd_5tuple_filter_tcp_flags =
 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				flags, "flags");
-cmdline_parse_token_num_t cmd_5tuple_filter_flags_value =
+				tcp_flags, "tcp_flags");
+cmdline_parse_token_num_t cmd_5tuple_filter_tcp_flags_value =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
-				flags_value, UINT8);
+				tcp_flags_value, UINT8);
 cmdline_parse_token_string_t cmd_5tuple_filter_priority =
 	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
 				priority, "priority");
@@ -7666,23 +7678,15 @@ cmdline_parse_token_string_t cmd_5tuple_filter_queue =
 cmdline_parse_token_num_t cmd_5tuple_filter_queue_id =
 	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
 				queue_id, UINT16);
-cmdline_parse_token_string_t cmd_5tuple_filter_index =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				index, "index");
-cmdline_parse_token_num_t cmd_5tuple_filter_index_value =
-	TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
-				index_value, UINT16);
 
-cmdline_parse_token_string_t cmd_5tuple_filter_add_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				 filter, "add_5tuple_filter");
-cmdline_parse_inst_t cmd_add_5tuple_filter = {
+cmdline_parse_inst_t cmd_5tuple_filter = {
 	.f = cmd_5tuple_filter_parsed,
 	.data = NULL,
-	.help_str = "add a 5tuple filter",
+	.help_str = "add/del a 5tuple filter",
 	.tokens = {
-		(void *)&cmd_5tuple_filter_add_filter,
+		(void *)&cmd_5tuple_filter_filter,
 		(void *)&cmd_5tuple_filter_port_id,
+		(void *)&cmd_5tuple_filter_ops,
 		(void *)&cmd_5tuple_filter_dst_ip,
 		(void *)&cmd_5tuple_filter_dst_ip_value,
 		(void *)&cmd_5tuple_filter_src_ip,
@@ -7695,46 +7699,12 @@ cmdline_parse_inst_t cmd_add_5tuple_filter = {
 		(void *)&cmd_5tuple_filter_protocol_value,
 		(void *)&cmd_5tuple_filter_mask,
 		(void *)&cmd_5tuple_filter_mask_value,
-		(void *)&cmd_5tuple_filter_flags,
-		(void *)&cmd_5tuple_filter_flags_value,
+		(void *)&cmd_5tuple_filter_tcp_flags,
+		(void *)&cmd_5tuple_filter_tcp_flags_value,
 		(void *)&cmd_5tuple_filter_priority,
 		(void *)&cmd_5tuple_filter_priority_value,
 		(void *)&cmd_5tuple_filter_queue,
 		(void *)&cmd_5tuple_filter_queue_id,
-		(void *)&cmd_5tuple_filter_index,
-		(void *)&cmd_5tuple_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_5tuple_filter_remove_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				filter, "remove_5tuple_filter");
-cmdline_parse_inst_t cmd_remove_5tuple_filter = {
-	.f = cmd_5tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "remove a 5tuple filter",
-	.tokens = {
-		(void *)&cmd_5tuple_filter_remove_filter,
-		(void *)&cmd_5tuple_filter_port_id,
-		(void *)&cmd_5tuple_filter_index,
-		(void *)&cmd_5tuple_filter_index_value,
-		NULL,
-	},
-};
-
-cmdline_parse_token_string_t cmd_5tuple_filter_get_filter =
-	TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
-				filter, "get_5tuple_filter");
-cmdline_parse_inst_t cmd_get_5tuple_filter = {
-	.f = cmd_5tuple_filter_parsed,
-	.data = NULL,
-	.help_str = "get a 5tuple filter",
-	.tokens = {
-		(void *)&cmd_5tuple_filter_get_filter,
-		(void *)&cmd_5tuple_filter_port_id,
-		(void *)&cmd_5tuple_filter_index,
-		(void *)&cmd_5tuple_filter_index_value,
 		NULL,
 	},
 };
@@ -9121,12 +9091,8 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_add_syn_filter,
 	(cmdline_parse_inst_t *)&cmd_remove_syn_filter,
 	(cmdline_parse_inst_t *)&cmd_get_syn_filter,
-	(cmdline_parse_inst_t *)&cmd_add_2tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_remove_2tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_get_2tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_add_5tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_remove_5tuple_filter,
-	(cmdline_parse_inst_t *)&cmd_get_5tuple_filter,
+	(cmdline_parse_inst_t *)&cmd_2tuple_filter,
+	(cmdline_parse_inst_t *)&cmd_5tuple_filter,
 	(cmdline_parse_inst_t *)&cmd_add_flex_filter,
 	(cmdline_parse_inst_t *)&cmd_remove_flex_filter,
 	(cmdline_parse_inst_t *)&cmd_get_flex_filter,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index c40f819..441ad93 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -2186,73 +2186,8 @@ get_syn_filter(uint8_t port_id)
 		filter.hig_pri ? "high" : "low",
 		rx_queue);
 }
-void
-get_2tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_2tuple_filter filter;
-	int ret = 0;
-	uint16_t rx_queue;
-
-	memset(&filter, 0, sizeof(filter));
-	ret = rte_eth_dev_get_2tuple_filter(port_id, index,
-				&filter, &rx_queue);
-	if (ret < 0) {
-		if (ret == (-ENOENT))
-			printf("filter[%d] is not enabled\n", index);
-		else
-			printf("get 2tuple filter fails(%s)\n", strerror(-ret));
-		return;
-	} else {
-		printf("filter[%d]:\n", index);
-		printf("    Destination Port:     0x%04x    mask: %d\n",
-			rte_be_to_cpu_16(filter.dst_port),
-			filter.dst_port_mask ? 0 : 1);
-		printf("    protocol:  0x%02x     mask:%d     tcp_flags: 0x%02x\n",
-			filter.protocol, filter.protocol_mask ? 0 : 1,
-			filter.tcp_flags);
-		printf("    priority: %d    queue: %d\n",
-			filter.priority, rx_queue);
-	}
-}
 
 void
-get_5tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_5tuple_filter filter;
-	int ret = 0;
-	uint16_t rx_queue;
-
-	memset(&filter, 0, sizeof(filter));
-	ret = rte_eth_dev_get_5tuple_filter(port_id, index,
-				&filter, &rx_queue);
-	if (ret < 0) {
-		if (ret == (-ENOENT))
-			printf("filter[%d] is not enabled\n", index);
-		else
-			printf("get 5tuple filter fails(%s)\n", strerror(-ret));
-		return;
-	} else {
-		printf("filter[%d]:\n", index);
-		printf("    Destination IP:  0x%08x    mask: %d\n",
-			(unsigned)rte_be_to_cpu_32(filter.dst_ip),
-			filter.dst_ip_mask ? 0 : 1);
-		printf("    Source IP:       0x%08x    mask: %d\n",
-			(unsigned)rte_be_to_cpu_32(filter.src_ip),
-			filter.src_ip_mask ? 0 : 1);
-		printf("    Destination Port:       0x%04x    mask: %d\n",
-			rte_be_to_cpu_16(filter.dst_port),
-			filter.dst_port_mask ? 0 : 1);
-		printf("    Source Port:       0x%04x    mask: %d\n",
-			rte_be_to_cpu_16(filter.src_port),
-			filter.src_port_mask ? 0 : 1);
-		printf("    protocol:           0x%02x    mask: %d\n",
-			filter.protocol,
-			filter.protocol_mask ? 0 : 1);
-		printf("    priority: %d    flags: 0x%02x    queue: %d\n",
-			filter.priority, filter.tcp_flags, rx_queue);
-	}
-}
-void
 get_flex_filter(uint8_t port_id, uint16_t index)
 
 {
-- 
1.9.3

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

* [dpdk-dev] [PATCH v3 5/6] ethdev: remove old APIs and structures of 5tuple and 2tuple filters
  2015-02-10  4:48   ` [dpdk-dev] [PATCH v3 " Jingjing Wu
                       ` (3 preceding siblings ...)
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 4/6] testpmd: new commands for ntuple filter Jingjing Wu
@ 2015-02-10  4:48     ` Jingjing Wu
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 6/6] doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter Jingjing Wu
                       ` (2 subsequent siblings)
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-02-10  4:48 UTC (permalink / raw)
  To: dev

Following structures are removed:
 - rte_2tuple_filter
 - rte_5tuple_filter
Following APIs are removed:
 - rte_eth_dev_add_2tuple_filter
 - rte_eth_dev_remove_2tuple_filter
 - rte_eth_dev_get_2tuple_filter
 - rte_eth_dev_add_5tuple_filter
 - rte_eth_dev_remove_5tuple_filter
 - rte_eth_dev_get_5tuple_filter
It also move macros TCP_*_FLAG to rte_eth_ctrl.h, and removes the macro
TCP_UGR_FLAG which is duplicated with TCP_URG_FLAG.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 lib/librte_ether/rte_eth_ctrl.h |   7 ++
 lib/librte_ether/rte_ethdev.c   | 116 ------------------------
 lib/librte_ether/rte_ethdev.h   | 194 ----------------------------------------
 3 files changed, 7 insertions(+), 310 deletions(-)

diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 808e532..ff7baa2 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -139,6 +139,13 @@ struct rte_eth_ethertype_filter {
 		RTE_NTUPLE_FLAGS_DST_PORT | \
 		RTE_NTUPLE_FLAGS_PROTO)
 
+#define TCP_URG_FLAG 0x20
+#define TCP_ACK_FLAG 0x10
+#define TCP_PSH_FLAG 0x08
+#define TCP_RST_FLAG 0x04
+#define TCP_SYN_FLAG 0x02
+#define TCP_FIN_FLAG 0x01
+#define TCP_FLAG_ALL 0x3F
 
 /**
  * A structure used to define the ntuple filter entry
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index ea3a1fb..a2e71e0 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3056,122 +3056,6 @@ rte_eth_dev_get_syn_filter(uint8_t port_id,
 }
 
 int
-rte_eth_dev_add_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-	if (filter->protocol != IPPROTO_TCP &&
-		filter->tcp_flags != 0){
-		PMD_DEBUG_TRACE("tcp flags is 0x%x, but the protocol value"
-			" is not TCP\n",
-			filter->tcp_flags);
-		return -EINVAL;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_2tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->add_2tuple_filter)(dev, index, filter, rx_queue);
-}
-
-int
-rte_eth_dev_remove_2tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_2tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->remove_2tuple_filter)(dev, index);
-}
-
-int
-rte_eth_dev_get_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (filter == NULL || rx_queue == NULL)
-		return -EINVAL;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_2tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->get_2tuple_filter)(dev, index, filter, rx_queue);
-}
-
-int
-rte_eth_dev_add_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	if (filter->protocol != IPPROTO_TCP &&
-		filter->tcp_flags != 0){
-		PMD_DEBUG_TRACE("tcp flags is 0x%x, but the protocol value"
-			" is not TCP\n",
-			filter->tcp_flags);
-		return -EINVAL;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_5tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->add_5tuple_filter)(dev, index, filter, rx_queue);
-}
-
-int
-rte_eth_dev_remove_5tuple_filter(uint8_t port_id, uint16_t index)
-{
-	struct rte_eth_dev *dev;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_5tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->remove_5tuple_filter)(dev, index);
-}
-
-int
-rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue)
-{
-	struct rte_eth_dev *dev;
-
-	if (filter == NULL || rx_queue == NULL)
-		return -EINVAL;
-
-	if (port_id >= nb_ports) {
-		PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
-		return -ENODEV;
-	}
-
-	dev = &rte_eth_devices[port_id];
-	FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_5tuple_filter, -ENOTSUP);
-	return (*dev->dev_ops->get_5tuple_filter)(dev, index, filter,
-						rx_queue);
-}
-
-int
 rte_eth_dev_add_flex_filter(uint8_t port_id, uint16_t index,
 			struct rte_flex_filter *filter, uint16_t rx_queue)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 5992e43..c50ae67 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -963,16 +963,6 @@ struct rte_eth_dev_callback;
 /** @internal Structure to keep track of registered callbacks */
 TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
 
-
-#define TCP_URG_FLAG 0x20
-#define TCP_UGR_FLAG 0x20
-#define TCP_ACK_FLAG 0x10
-#define TCP_PSH_FLAG 0x08
-#define TCP_RST_FLAG 0x04
-#define TCP_SYN_FLAG 0x02
-#define TCP_FIN_FLAG 0x01
-#define TCP_FLAG_ALL 0x3F
-
 /**
  *  A structure used to define an syn filter.
  */
@@ -982,18 +972,6 @@ struct rte_syn_filter {
 };
 
 /**
- *  A structure used to define a 2tuple filter.
- */
-struct rte_2tuple_filter {
-	uint16_t dst_port;        /**< big endian. */
-	uint8_t protocol;
-	uint8_t tcp_flags;
-	uint16_t priority;        /**< used when more than one filter matches. */
-	uint8_t dst_port_mask:1,  /**< if mask is 1b, means not compare. */
-		protocol_mask:1;
-};
-
-/**
  *  A structure used to define a flex filter.
  */
 struct rte_flex_filter {
@@ -1004,25 +982,6 @@ struct rte_flex_filter {
 	uint8_t priority;
 };
 
-/**
- *  A structure used to define a 5tuple filter.
- */
-struct rte_5tuple_filter {
-	uint32_t dst_ip;         /**< destination IP address in big endian. */
-	uint32_t src_ip;         /**< source IP address in big endian. */
-	uint16_t dst_port;       /**< destination port in big endian. */
-	uint16_t src_port;       /**< source Port big endian. */
-	uint8_t protocol;        /**< l4 protocol. */
-	uint8_t tcp_flags;       /**< tcp flags. */
-	uint16_t priority;       /**< seven evels (001b-111b), 111b is highest,
-				      used when more than one filter matches. */
-	uint8_t dst_ip_mask:1,   /**< if mask is 1b, do not compare dst ip. */
-		src_ip_mask:1,   /**< if mask is 1b, do not compare src ip. */
-		dst_port_mask:1, /**< if mask is 1b, do not compare dst port. */
-		src_port_mask:1, /**< if mask is 1b, do not compare src port. */
-		protocol_mask:1; /**< if mask is 1b, do not compare protocol. */
-};
-
 /*
  * Definitions of all functions exported by an Ethernet driver through the
  * the generic structure of type *eth_dev_ops* supplied in the *rte_eth_dev*
@@ -1365,33 +1324,6 @@ typedef int (*eth_get_syn_filter_t)(struct rte_eth_dev *dev,
 			struct rte_syn_filter *filter, uint16_t *rx_queue);
 /**< @internal Get syn filter rule on an Ethernet device */
 
-typedef int (*eth_add_2tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_2tuple_filter *filter,
-			uint16_t rx_queue);
-/**< @internal Setup a new 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_remove_2tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index);
-/**< @internal Remove a 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_get_2tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_2tuple_filter *filter,
-			uint16_t *rx_queue);
-/**< @internal Get a 2tuple filter rule on an Ethernet device */
-
-typedef int (*eth_add_5tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_5tuple_filter *filter,
-			uint16_t rx_queue);
-/**< @internal Setup a new 5tuple filter rule on an Ethernet device */
-
-typedef int (*eth_remove_5tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index);
-/**< @internal Remove a 5tuple filter rule on an Ethernet device */
-
-typedef int (*eth_get_5tuple_filter_t)(struct rte_eth_dev *dev,
-			uint16_t index, struct rte_5tuple_filter *filter,
-			uint16_t *rx_queue);
-/**< @internal Get a 5tuple filter rule on an Ethernet device */
 
 typedef int (*eth_add_flex_filter_t)(struct rte_eth_dev *dev,
 			uint16_t index, struct rte_flex_filter *filter,
@@ -1511,12 +1443,6 @@ struct eth_dev_ops {
 	eth_add_syn_filter_t           add_syn_filter;       /**< add syn filter. */
 	eth_remove_syn_filter_t        remove_syn_filter;    /**< remove syn filter. */
 	eth_get_syn_filter_t           get_syn_filter;       /**< get syn filter. */
-	eth_add_2tuple_filter_t        add_2tuple_filter;    /**< add 2tuple filter. */
-	eth_remove_2tuple_filter_t     remove_2tuple_filter; /**< remove 2tuple filter. */
-	eth_get_2tuple_filter_t        get_2tuple_filter;    /**< get 2tuple filter. */
-	eth_add_5tuple_filter_t        add_5tuple_filter;    /**< add 5tuple filter. */
-	eth_remove_5tuple_filter_t     remove_5tuple_filter; /**< remove 5tuple filter. */
-	eth_get_5tuple_filter_t        get_5tuple_filter;    /**< get 5tuple filter. */
 	eth_add_flex_filter_t          add_flex_filter;      /**< add flex filter. */
 	eth_remove_flex_filter_t       remove_flex_filter;   /**< remove flex filter. */
 	eth_get_flex_filter_t          get_flex_filter;      /**< get flex filter. */
@@ -3450,126 +3376,6 @@ int rte_eth_dev_get_syn_filter(uint8_t port_id,
 			struct rte_syn_filter *filter, uint16_t *rx_queue);
 
 /**
- * Add a new 2tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
- * @param filter
- *   The pointer to the structure describing the 2tuple filter rule.
- *   The *rte_2tuple_filter* structure includes the values of the different
- *   fields to match: protocol, dst_port and
- *   tcp_flags if the protocol is tcp type.
- * @param rx_queue
- *   The index of the RX queue where to store RX packets matching the added
- *   2tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_add_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t rx_queue);
-
-/**
- * remove a 2tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_remove_2tuple_filter(uint8_t port_id, uint16_t index);
-
-/**
- * Get an 2tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 2tuple filter.
- * @param filter
- *   A pointer to a structure of type *rte_2tuple_filter* to be filled with
- *   the information of the 2tuple filter.
- * @param rx_queue
- *   A pointer to get the queue index.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 2tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- *   - (-ENOENT) if no enabled filter in this index.
- */
-int rte_eth_dev_get_2tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_2tuple_filter *filter, uint16_t *rx_queue);
-
-/**
- * Add a new 5tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
- * @param filter
- *   The pointer to the structure describing the 5tuple filter rule.
- *   The *rte_5tuple_filter* structure includes the values of the different
- *   fields to match: dst src IP, dst src port, protocol and relative masks
- * @param rx_queue
- *   The index of the RX queue where to store RX packets matching the added
- *   5tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_add_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t rx_queue);
-
-/**
- * remove a 5tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_remove_5tuple_filter(uint8_t port_id, uint16_t index);
-
-/**
- * Get an 5tuple filter rule on an Ethernet device.
- *
- * @param port_id
- *   The port identifier of the Ethernet device.
- * @param index
- *   The identifier of 5tuple filter.
- * @param filter
- *   A pointer to a structure of type *rte_5tuple_filter* to be filled with
- *   the information of the 5tuple filter.
- * @param rx_queue
- *   A pointer to get the queue index.
- * @return
- *   - (0) if successful.
- *   - (-ENOTSUP) if hardware doesn't support 5tuple filter.
- *   - (-ENODEV) if *port_id* invalid.
- *   - (-EINVAL) if the filter information is not correct.
- */
-int rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
-			struct rte_5tuple_filter *filter, uint16_t *rx_queue);
-
-/**
  * Add a new flex filter rule on an Ethernet device.
  *
  * @param port_id
-- 
1.9.3

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

* [dpdk-dev] [PATCH v3 6/6] doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter
  2015-02-10  4:48   ` [dpdk-dev] [PATCH v3 " Jingjing Wu
                       ` (4 preceding siblings ...)
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 5/6] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
@ 2015-02-10  4:48     ` Jingjing Wu
  2015-02-13  2:59     ` [dpdk-dev] [PATCH v3 0/6] new ntuple filter replaces 2tuple and 5tuple filters Xu, HuilongX
  2015-02-20 17:29     ` De Lara Guarch, Pablo
  7 siblings, 0 replies; 27+ messages in thread
From: Jingjing Wu @ 2015-02-10  4:48 UTC (permalink / raw)
  To: dev

document of new commands:
 - 2tuple_filter (port_id) (add|del)
   dst_port (dst_port_value) protocol (protocol_value)
   mask (mask_value) tcp_flags (tcp_flags_value)
   priority (prio_value) queue (queue_id)
 - 5tuple_filter (port_id) (add|del)
   dst_ip (dst_address) src_ip (src_address)
   dst_port (dst_port_value) src_port (src_port_value)
   protocol (protocol_value)
   mask (mask_value) tcp_flags (tcp_flags_value)
   priority (prio_value) queue (queue_id)

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 99 ++++++-----------------------
 1 file changed, 21 insertions(+), 78 deletions(-)

diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 218835a..1a3de02 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1421,76 +1421,48 @@ Example, to add/remove an ethertype filter rule:
     testpmd> ethertype_filter 0 add mac_ignr ethertype 0x0806 fwd queue 3
     testpmd> ethertype_filter 0 del mac_ignr ethertype 0x0806 fwd queue 3
 
-add_2tuple_filter
+2tuple_filter
 ~~~~~~~~~~~~~~~~~
 
-Add a 2-tuple filter,
+Add or delete a 2-tuple filter,
 which identify packets by specific protocol and destination TCP/UDP port
 and forwards packets into one of the receive queues.
 
-add_2tuple_filter (port_id) protocol (pro_value) (pro_mask) dst_port (port_value) (port_mask)
-flags (flg_value) priority (prio_value) queue (queue_id) index (idx)
+2tuple_filter (port_id) (add|del) dst_port (dst_port_value) protocol (protocol_value)
+mask (mask_value) tcp_flags (tcp_flags_value) priority (prio_value) queue (queue_id)
 
 The available information parameters are:
 
 *   port_id: the port which the 2-tuple filter assigned on.
 
-*   pro_value: IP L4 protocol
+*   dst_port_value: destination port in L4.
 
-*   pro_mask: protocol participates in the match or not, 1 means participate
+*   protocol_value: IP L4 protocol.
 
-*   port_value: destination port in L4.
+*   mask_value: participates in the match or not by bit for field above, 1b means participate.
 
-*   port_mask: destination port participates in the match or not, 1 means participate.
+*   tcp_flags_value: TCP control bits. The non-zero value is invalid, when the pro_value is not set to 0x06 (TCP).
 
-*   flg_value: TCP control bits. The non-zero value is invalid, when the pro_value is not set to 0x06 (TCP).
+*   prio_value: priority of this filter.
 
-*   prio_value: the priority of this filter.
-
-*   queue_id: The receive queue associated with this 2-tuple filter
+*   queue_id: The receive queue associated with this 2-tuple filter.
 
-*   index: the index of this 2-tuple filter
-
-Example:
+Example, to add/remove an 2tuple filter rule:
 
 .. code-block:: console
 
-    testpmd> add_2tuple_filter 0 protocol 0x06 1 dst_port 32 1 flags 0x02 priority 3 queue 3 index 0
-
-remove_2tuple_filter
-~~~~~~~~~~~~~~~~~~~~
-
-Remove a 2-tuple filter
-
-remove_2tuple_filter (port_id) index (idx)
+    testpmd> 2tuple_filter 0 add dst_port 32 protocol 0x06 mask 0x03 tcp_flags 0x02 priority 3 queue 3
+    testpmd> 2tuple_filter 0 del dst_port 32 protocol 0x06 mask 0x03 tcp_flags 0x02 priority 3 queue 3
 
-get_2tuple_filter
+5tuple_filter
 ~~~~~~~~~~~~~~~~~
 
-Get and display a 2-tuple filter
-
-get_2tuple_filter (port_id) index (idx)
-
-Example:
-
-.. code-block:: console
-
-    testpmd> get_2tuple_filter 0 index 0
-
-    filter[0]:
-        Destination Port: 0x0020 mask: 1
-        protocol: 0x06 mask:1 tcp_flags: 0x02
-        priority: 3   queue: 3
-
-add_5tuple_filter
-~~~~~~~~~~~~~~~~~
-
-Add a 5-tuple filter,
+Add or delete a 5-tuple filter,
 which consists of a 5-tuple (protocol, source and destination IP addresses, source and destination TCP/UDP/SCTP port)
 and routes packets into one of the receive queues.
 
-add_5tuple_filter (port_id) dst_ip (dst_address) src_ip (src_address) dst_port (dst_port_value) src_port (src_port_value)
-protocol (protocol_value) mask (mask_value) flags (flags_value) priority (prio_value) queue (queue_id) index (idx)
+5tuple_filter (port_id) (add|del) dst_ip (dst_address) src_ip (src_address) dst_port (dst_port_value) src_port (src_port_value)
+protocol (protocol_value) mask (mask_value) tcp_flags (tcp_flags_value) priority (prio_value) queue (queue_id)
 
 The available information parameters are:
 
@@ -1508,47 +1480,18 @@ The available information parameters are:
 
 *   mask_value: participates in the match or not by bit for field above, 1b means participate
 
-*   flags_value: TCP control bits. The non-zero value is invalid, when the protocol_value is not set to 0x06 (TCP).
+*   tcp_flags_value: TCP control bits. The non-zero value is invalid, when the protocol_value is not set to 0x06 (TCP).
 
 *   prio_value: the priority of this filter.
 
 *   queue_id: The receive queue associated with this 5-tuple filter.
 
-*   index: the index of this 5-tuple filter
-
-Example:
-
-.. code-block:: console
-
-    testpmd> add_5tuple_filter 1 dst_ip 2.2.2.5 src_ip 2.2.2.4 dst_port 64 src_port 32 protocol 0x06 mask 0x1F flags 0x0 priority 3 queue 3 index 0
-
-remove_5tuple_filter
-~~~~~~~~~~~~~~~~~~~~
-
-Remove a 5-tuple filter
-
-remove_5tuple_filter (port_id) index (idx)
-
-get_5tuple_filter
-~~~~~~~~~~~~~~~~~
-
-Get and display a 5-tuple filter
-
-get_5tuple_filter (port_id) index (idx)
-
-Example:
+Example, to add/remove an 5tuple filter rule:
 
 .. code-block:: console
 
-    testpmd> get_5tuple_filter 1 index 0
-
-    filter[0]:
-        Destination IP: 0x02020205 mask: 1
-        Source IP: 0x02020204 mask: 1
-        Destination Port: 0x0040 mask: 1
-        Source Port: 0x0020 mask: 1
-        protocol: 0x06 mask: 1
-        priority: 3 flags: 0x00 queue: 3
+    testpmd> 5tuple_filter 0 add dst_ip 2.2.2.5 src_ip 2.2.2.4 dst_port 64 src_port 32 protocol 0x06 mask 0x1F flags 0x0 priority 3 queue 3
+    testpmd> 5tuple_filter 0 del dst_ip 2.2.2.5 src_ip 2.2.2.4 dst_port 64 src_port 32 protocol 0x06 mask 0x1F flags 0x0 priority 3 queue 3
 
 add_syn_filter
 ~~~~~~~~~~~~~~
-- 
1.9.3

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

* Re: [dpdk-dev] [PATCH v3 0/6] new ntuple filter replaces 2tuple and 5tuple filters
  2015-02-10  4:48   ` [dpdk-dev] [PATCH v3 " Jingjing Wu
                       ` (5 preceding siblings ...)
  2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 6/6] doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter Jingjing Wu
@ 2015-02-13  2:59     ` Xu, HuilongX
  2015-02-20 17:29     ` De Lara Guarch, Pablo
  7 siblings, 0 replies; 27+ messages in thread
From: Xu, HuilongX @ 2015-02-13  2:59 UTC (permalink / raw)
  To: Wu, Jingjing, dev

Tested-by:huilong xu <huilongx.xu@intel.com>

- Tested Commit: 2250cc5a191906c914221ff4f0da7b5d699b4175
 - OS: Fedora20  3.11.10-301.fc20.x86_64
 - GCC: gcc version 4.8.3 20140911 (Red Hat 4.8.3-7) (GCC)
 - CPU: Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz
 - NIC: Intel Corporation 82599EB 10-Gigabit Network Connection [8086:10fb]
        Intel Corporation I350 Gigabit Network Connection [8086:1521]
        Intel Corporation 82580 Gigabit Network Connection [8086:150e]

 - Default x86_64-native-linuxapp-gcc configuration
 - Total 2 cases, 2 passed, 0 failed
 
 - Case: five_tuple_filter
   Description: Check specified tcp package receive by specified queue. Test NIC 82599EB
   Command / instruction:
 	Start testpmd 
 		testpmd -c ffff -n 4 -- -i --disable-rss --rxq=4 --txq=4 --portmask=0x3 --nb-cores=8 --nb-ports=2
		 
 	set queue map:
 		set stat_qmap rx 0 0 0
 		set stat_qmap rx 1 0 0
		set stat_qmap rx 0 1 1
 		set stat_qmap rx 1 1 1
		set stat_qmap rx 0 2 2
 		set stat_qmap rx 1 2 2
		set stat_qmap rx 0 3 3
 		set stat_qmap rx 1 3 3
       set vlan offload:
             vlan set strip off 0
             vlan set strip off 1
             vlan set filter off 0
             vlan set filter off 1
       set flush rx on:
             set flush_rx on
        start testpmd:
             start
 	 add five tuple filter:
             5tuple_filter 0 add dst_ip 2.2.2.5 src_ip 2.2.2.4 dst_port 1 src_port 1 protocol 0x06 mask 0x1f tcp_flags 0x0 priority 3 queue 3 
 	Send packets with tcp inner L4 data,dstip 2.2.2.5, scrip 2.2.2.4,dstport 1, srcport 1, protocol 0x06
       test result:
 		testpmd can receive the package by port 0 queue 3
       remove five tuple filter:
              5tuple _filter 0 del dst_ip 2.2.2.5 src_ip 2.2.2.4 dst_port 1 src_port 1 protocol 0x06 mask 0x1f tcp_flags 0x0 priority 3 queue 3 

      Send packets with tcp inner L4 data,dstip 2.2.2.5, scrip 2.2.2.4,dstport 1, srcport 1, protocol 0x06
       test result:
 		testpmd can receive the package by port 0 queue 0 

- Case: twotuple_filter
   Description: Check specified udp package receive by specified queue. Test NIC i350 and 82580
   Command / instruction:
 	Start testpmd 
 		testpmd -c ffff -n 4 -- -i --disable-rss --rxq=4 --txq=4 --portmask=0x3 --nb-cores=8 --nb-ports=2
		 
 	set queue map:
 		set stat_qmap rx 0 0 0
 		set stat_qmap rx 1 0 0
		set stat_qmap rx 0 1 1
 		set stat_qmap rx 1 1 1
		set stat_qmap rx 0 2 2
 		set stat_qmap rx 1 2 2
		set stat_qmap rx 0 3 3
 		set stat_qmap rx 1 3 3
       set vlan offload:
             vlan set strip off 0
             vlan set strip off 1
             vlan set filter off 0
             vlan set filter off 1
       set flush rx on:
             set flush_rx on
        start testpmd:
             start
 	 add two tuple filter:
             2tuple_filter 0 add dst_port 64 protocol 0x11 mask 1 tcp_flags 0 priority 3 queue 1 
 	Send packets with udp inner L4 data,dstport 64,  protocol 0x11
       test result:
 		testpmd can receive the package by port 0 queue 1
       remove five tuple filter:
              5tuple 2tuple_filter 0 del dst_port 64 protocol 0x11 mask 1 tcp_flags 0 priority 3 queue 1  

      Send packets with tcp inner L4 data, dstport 64 ,protocol 0x11
       test result:
 		testpmd can receive the package by port 0 queue 0

-----Original Message-----
From: Wu, Jingjing 
Sent: Tuesday, February 10, 2015 12:48 PM
To: dev@dpdk.org
Cc: Wu, Jingjing; De Lara Guarch, Pablo; Cao, Min; Xu, HuilongX
Subject: [PATCH v3 0/6] new ntuple filter replaces 2tuple and 5tuple filters

v2 changes:
  - remove the code which is already applied in patch "Integrate ethertype
    filter in igb/ixgbe driver to new API".
  - modify commands' description in doc testpmd_funcs.rst.

v3 change:
  - remove the UINT32_BIT definition in ixgbe driver

The patch set uses new filter_ctrl API to replace old 2tuple and 5tuple filter APIs.
It defines ntuple filter to combine 2tuple and 5tuple types. 
It uses new functions and structure to replace old ones in igb/ixgbe driver,
new commands to replace old ones in testpmd, and removes the old APIs.
It removes the filter's index parameters from user interface, only the
filter's key and assigned queue are visible to user.

Jingjing Wu (6):
  ethdev: define ntuple filter type and its structure
  ixgbe: ntuple filter functions replace old ones for 5tuple filter
  e1000: ntuple filter functions replace old ones for 2tuple and 5tuple
    filter
  testpmd: new commands for ntuple filter
  ethdev: remove old APIs and structures of 5tuple and 2tuple filters
  doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter

 app/test-pmd/cmdline.c                      | 406 ++++++-------
 app/test-pmd/config.c                       |  65 ---
 doc/guides/testpmd_app_ug/testpmd_funcs.rst |  99 +---
 lib/librte_ether/rte_eth_ctrl.h             |  57 ++
 lib/librte_ether/rte_ethdev.c               | 116 ----
 lib/librte_ether/rte_ethdev.h               | 192 ------
 lib/librte_pmd_e1000/e1000_ethdev.h         |  69 ++-
 lib/librte_pmd_e1000/igb_ethdev.c           | 869 +++++++++++++++++++---------
 lib/librte_pmd_ixgbe/ixgbe_ethdev.c         | 468 +++++++++++----
 lib/librte_pmd_ixgbe/ixgbe_ethdev.h         |  52 +-
 10 files changed, 1300 insertions(+), 1093 deletions(-)

-- 
1.9.3

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

* Re: [dpdk-dev] [PATCH v3 0/6] new ntuple filter replaces 2tuple and 5tuple filters
  2015-02-10  4:48   ` [dpdk-dev] [PATCH v3 " Jingjing Wu
                       ` (6 preceding siblings ...)
  2015-02-13  2:59     ` [dpdk-dev] [PATCH v3 0/6] new ntuple filter replaces 2tuple and 5tuple filters Xu, HuilongX
@ 2015-02-20 17:29     ` De Lara Guarch, Pablo
  2015-02-22  3:10       ` Thomas Monjalon
  7 siblings, 1 reply; 27+ messages in thread
From: De Lara Guarch, Pablo @ 2015-02-20 17:29 UTC (permalink / raw)
  To: Wu, Jingjing, dev



> -----Original Message-----
> From: Wu, Jingjing
> Sent: Tuesday, February 10, 2015 4:48 AM
> To: dev@dpdk.org
> Cc: Wu, Jingjing; De Lara Guarch, Pablo; Cao, Min; Xu, HuilongX
> Subject: [PATCH v3 0/6] new ntuple filter replaces 2tuple and 5tuple filters
> 
> v2 changes:
>   - remove the code which is already applied in patch "Integrate ethertype
>     filter in igb/ixgbe driver to new API".
>   - modify commands' description in doc testpmd_funcs.rst.
> 
> v3 change:
>   - remove the UINT32_BIT definition in ixgbe driver

Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>

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

* Re: [dpdk-dev] [PATCH v3 0/6] new ntuple filter replaces 2tuple and 5tuple filters
  2015-02-20 17:29     ` De Lara Guarch, Pablo
@ 2015-02-22  3:10       ` Thomas Monjalon
  0 siblings, 0 replies; 27+ messages in thread
From: Thomas Monjalon @ 2015-02-22  3:10 UTC (permalink / raw)
  To: Wu, Jingjing; +Cc: dev

2015-02-20 17:29, De Lara Guarch, Pablo:
> From: Wu, Jingjing
> > 
> > v2 changes:
> >   - remove the code which is already applied in patch "Integrate ethertype
> >     filter in igb/ixgbe driver to new API".
> >   - modify commands' description in doc testpmd_funcs.rst.
> > 
> > v3 change:
> >   - remove the UINT32_BIT definition in ixgbe driver
> 
> Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>

Applied, thanks.
There were a lot of conflicts. Thanks for checking all is ok.
I also removed old functions from version map.

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

end of thread, other threads:[~2015-02-22  3:10 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-15  1:45 [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters Jingjing Wu
2015-01-15  1:45 ` [dpdk-dev] [PATCH 1/5] ethdev: define ntuple filter type and its structure Jingjing Wu
2015-01-15  1:45 ` [dpdk-dev] [PATCH 2/5] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
2015-01-15  1:45 ` [dpdk-dev] [PATCH 3/5] e1000: ntuple filter functions replace old ones for 2tuple and " Jingjing Wu
2015-01-15  1:46 ` [dpdk-dev] [PATCH 4/5] testpmd: new commands for ntuple filter Jingjing Wu
2015-01-15  1:46 ` [dpdk-dev] [PATCH 5/5] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
2015-01-21 12:18 ` [dpdk-dev] [PATCH 0/5] new ntuple filter replaces 2tuple and 5tuple filters De Lara Guarch, Pablo
2015-01-22  0:28   ` Wu, Jingjing
2015-01-22  7:38 ` [dpdk-dev] [PATCH v2 0/6] " Jingjing Wu
2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 1/6] ethdev: define ntuple filter type and its structure Jingjing Wu
2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 2/6] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 3/6] e1000: ntuple filter functions replace old ones for 2tuple and " Jingjing Wu
2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 4/6] testpmd: new commands for ntuple filter Jingjing Wu
2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 5/6] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
2015-01-22  7:38   ` [dpdk-dev] [PATCH v2 6/6] doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter Jingjing Wu
2015-01-28 14:28   ` [dpdk-dev] [PATCH v2 0/6] new ntuple filter replaces 2tuple and 5tuple filters De Lara Guarch, Pablo
2015-01-30  8:22     ` Wu, Jingjing
2015-02-10  4:48   ` [dpdk-dev] [PATCH v3 " Jingjing Wu
2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 1/6] ethdev: define ntuple filter type and its structure Jingjing Wu
2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 2/6] ixgbe: ntuple filter functions replace old ones for 5tuple filter Jingjing Wu
2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 3/6] e1000: ntuple filter functions replace old ones for 2tuple and " Jingjing Wu
2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 4/6] testpmd: new commands for ntuple filter Jingjing Wu
2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 5/6] ethdev: remove old APIs and structures of 5tuple and 2tuple filters Jingjing Wu
2015-02-10  4:48     ` [dpdk-dev] [PATCH v3 6/6] doc: commands changed in testpmd_funcs for 2tuple amd 5tuple filter Jingjing Wu
2015-02-13  2:59     ` [dpdk-dev] [PATCH v3 0/6] new ntuple filter replaces 2tuple and 5tuple filters Xu, HuilongX
2015-02-20 17:29     ` De Lara Guarch, Pablo
2015-02-22  3:10       ` 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).