FDIR creation programs the hardware rule before inserting its software
hash entry. If insertion fails, creation returns without removing the
hardware rule or releasing its counter, and MARK parsing may remain
enabled despite no flow handle being returned.

Reserve the hash entry before programming the rule, and release the
counter if reservation fails. Remove the reserved entry if hardware
programming fails. Enable MARK parsing only after both steps succeed.

Fixes: 1a2fc1799f09 ("net/ice: reject duplicated flow for flow director")
Cc: [email protected]

Signed-off-by: Anatoly Burakov <[email protected]>
---
 drivers/net/intel/ice/ice_fdir_filter.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/net/intel/ice/ice_fdir_filter.c 
b/drivers/net/intel/ice/ice_fdir_filter.c
index 517c32cecf..63a0d9fb1f 100644
--- a/drivers/net/intel/ice/ice_fdir_filter.c
+++ b/drivers/net/intel/ice/ice_fdir_filter.c
@@ -1654,8 +1654,18 @@ ice_fdir_create_filter(struct ice_adapter *ad,
                filter->input.cnt_index = filter->counter->hw_index;
        }
 
+       /* Reserve the software entry before installing the hardware rule. */
+       ret = ice_fdir_entry_insert(pf, entry, &key);
+       if (ret) {
+               rte_flow_error_set(error, -ret,
+                                  RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+                                  "Insert entry to table failed.");
+               goto free_counter;
+       }
+
        ret = ice_fdir_add_del_filter(pf, filter, true);
        if (ret) {
+               ice_fdir_entry_del(pf, &key);
                rte_flow_error_set(error, -ret,
                                   RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
                                   "Add filter rule failed.");
@@ -1666,14 +1676,6 @@ ice_fdir_create_filter(struct ice_adapter *ad,
                ice_fdir_rx_parsing_enable(ad, 1);
 
        memcpy(entry, filter, sizeof(*entry));
-       ret = ice_fdir_entry_insert(pf, entry, &key);
-       if (ret) {
-               rte_flow_error_set(error, -ret,
-                                  RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
-                                  "Insert entry to table failed.");
-               goto free_entry;
-       }
-
        flow->rule = entry;
        ice_fdir_cnt_update(pf, filter->input.flow_type, is_tun, true);
 
-- 
2.52.0

Reply via email to