[dpdk-dev,11/13] net/bnxt: fix bug with duplicate pattern for 5tuple filter

Message ID 20180108202437.56305-12-ajit.khaparde@broadcom.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Ajit Khaparde Jan. 8, 2018, 8:24 p.m. UTC
  From: Somnath Kotur <somnath.kotur@broadcom.com>

When user re-issues same 5 tuple filter pattern cmd with different
destination queue, it would flag it as an existing match.
However, when deletion on this filter was attempted, it would crash
as the 'vnic' from which the filter was being removed from would be
different.  Fix by updating the filter in the scenario where there
is a pattern match and only the destination queue varies.

Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)
  

Patch

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 049d98b1d..41b23cc4f 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1962,7 +1962,8 @@  parse_ntuple_filter(struct bnxt *bp,
 
 static struct bnxt_filter_info*
 bnxt_match_ntuple_filter(struct bnxt *bp,
-			 struct bnxt_filter_info *bfilter)
+			 struct bnxt_filter_info *bfilter,
+			 struct bnxt_vnic_info **mvnic)
 {
 	struct bnxt_filter_info *mfilter = NULL;
 	int i;
@@ -1981,8 +1982,11 @@  bnxt_match_ntuple_filter(struct bnxt *bp,
 			    bfilter->dst_port == mfilter->dst_port &&
 			    bfilter->dst_port_mask == mfilter->dst_port_mask &&
 			    bfilter->flags == mfilter->flags &&
-			    bfilter->enables == mfilter->enables)
+			    bfilter->enables == mfilter->enables) {
+				if (mvnic)
+					*mvnic = vnic;
 				return mfilter;
+			}
 		}
 	}
 	return NULL;
@@ -1994,7 +1998,7 @@  bnxt_cfg_ntuple_filter(struct bnxt *bp,
 		       enum rte_filter_op filter_op)
 {
 	struct bnxt_filter_info *bfilter, *mfilter, *filter1;
-	struct bnxt_vnic_info *vnic, *vnic0;
+	struct bnxt_vnic_info *vnic, *vnic0, *mvnic;
 	int ret;
 
 	if (nfilter->flags != RTE_5TUPLE_FLAGS) {
@@ -2032,12 +2036,22 @@  bnxt_cfg_ntuple_filter(struct bnxt *bp,
 	bfilter->ethertype = 0x800;
 	bfilter->enables |= NTUPLE_FLTR_ALLOC_INPUT_EN_ETHERTYPE;
 
-	mfilter = bnxt_match_ntuple_filter(bp, bfilter);
+	mfilter = bnxt_match_ntuple_filter(bp, bfilter, &mvnic);
 
-	if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD) {
-		RTE_LOG(ERR, PMD, "filter exists.");
+	if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD &&
+	    bfilter->dst_id == mfilter->dst_id) {
+		RTE_LOG(ERR, PMD, "filter exists.\n");
 		ret = -EEXIST;
 		goto free_filter;
+	} else if (mfilter != NULL && filter_op == RTE_ETH_FILTER_ADD &&
+		   bfilter->dst_id != mfilter->dst_id) {
+		mfilter->dst_id = vnic->fw_vnic_id;
+		ret = bnxt_hwrm_set_ntuple_filter(bp, mfilter->dst_id, mfilter);
+		STAILQ_REMOVE(&mvnic->filter, mfilter, bnxt_filter_info, next);
+		STAILQ_INSERT_TAIL(&vnic->filter, mfilter, next);
+		RTE_LOG(ERR, PMD, "filter with matching pattern exists.\n");
+		RTE_LOG(ERR, PMD, " Updated it to the new destination queue\n");
+		goto free_filter;
 	}
 	if (mfilter == NULL && filter_op == RTE_ETH_FILTER_DELETE) {
 		RTE_LOG(ERR, PMD, "filter doesn't exist.");
@@ -2059,11 +2073,11 @@  bnxt_cfg_ntuple_filter(struct bnxt *bp,
 		}
 		ret = bnxt_hwrm_clear_ntuple_filter(bp, mfilter);
 
-		STAILQ_REMOVE(&vnic->filter, mfilter, bnxt_filter_info,
-			      next);
+		STAILQ_REMOVE(&vnic->filter, mfilter, bnxt_filter_info, next);
 		bnxt_free_filter(bp, mfilter);
-		bfilter->fw_l2_filter_id = -1;
+		mfilter->fw_l2_filter_id = -1;
 		bnxt_free_filter(bp, bfilter);
+		bfilter->fw_l2_filter_id = -1;
 	}
 
 	return 0;