IPsec flow parsing leaves the pattern-match item allocated after
extracting its metadata. It also leaves the parsed flow item allocated
when no metadata output is requested.

Free the pattern-match item after parsing and free the parsed flow item
when it cannot be returned to the caller. Propagate pattern-match failure
and report a parsing error when no flow item was produced.

Fixes: 6bc987ecb860 ("net/iavf: support IPsec inline crypto")
Cc: [email protected]

Signed-off-by: Anatoly Burakov <[email protected]>
---
 drivers/net/intel/iavf/iavf_ipsec_crypto.c | 28 +++++++++++++++-------
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/drivers/net/intel/iavf/iavf_ipsec_crypto.c 
b/drivers/net/intel/iavf/iavf_ipsec_crypto.c
index f7e391a74a..be0a0d0df6 100644
--- a/drivers/net/intel/iavf/iavf_ipsec_crypto.c
+++ b/drivers/net/intel/iavf/iavf_ipsec_crypto.c
@@ -1942,6 +1942,7 @@ iavf_ipsec_flow_parse(struct iavf_adapter *ad,
                .max_actions = 1,
        };
        struct iavf_pattern_match_item *item = NULL;
+       struct iavf_ipsec_flow_item *fi = NULL;
        int ret = -1;
 
        ret = ci_flow_check_attr(attr, NULL, error);
@@ -1953,17 +1954,28 @@ iavf_ipsec_flow_parse(struct iavf_adapter *ad,
                return ret;
 
        item = iavf_search_pattern_match_item(pattern, array, array_len, error);
-       if (item && item->meta) {
+       if (item == NULL)
+               return -rte_errno;
+
+       if (item->meta != NULL) {
                const struct rte_security_session *session = 
parsed_actions.actions[0]->conf;
                uint32_t type = (uint64_t)(item->meta);
-               struct iavf_ipsec_flow_item *fi =
-                               iavf_ipsec_flow_item_parse(ad, pattern, 
session, type);
-               if (fi && meta) {
-                       *meta = fi;
-                       ret = 0;
-               }
+
+               fi = iavf_ipsec_flow_item_parse(ad, pattern, session, type);
        }
-       return ret;
+       rte_free(item);
+
+       if (fi == NULL)
+               return rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+                               "Invalid IPsec flow.");
+
+       if (meta != NULL)
+               *meta = fi;
+       else
+               rte_free(fi);
+
+       return 0;
 }
 
 /*
-- 
2.52.0

Reply via email to