These filters are mashed together even though they almost do not share any
code at all between each other. Separate security filter from ntuple filter
and parse it separately.

Signed-off-by: Anatoly Burakov <[email protected]>
---
 drivers/net/intel/ixgbe/ixgbe_flow.c | 194 ++++++++++++++++-----------
 1 file changed, 114 insertions(+), 80 deletions(-)

diff --git a/drivers/net/intel/ixgbe/ixgbe_flow.c 
b/drivers/net/intel/ixgbe/ixgbe_flow.c
index 491e8bccc5..78f40b5c37 100644
--- a/drivers/net/intel/ixgbe/ixgbe_flow.c
+++ b/drivers/net/intel/ixgbe/ixgbe_flow.c
@@ -214,74 +214,6 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
        memset(&eth_null, 0, sizeof(struct rte_flow_item_eth));
        memset(&vlan_null, 0, sizeof(struct rte_flow_item_vlan));
 
-       /**
-        *  Special case for flow action type RTE_FLOW_ACTION_TYPE_SECURITY
-        */
-       act = next_no_void_action(actions, NULL);
-       if (act->type == RTE_FLOW_ACTION_TYPE_SECURITY) {
-               const void *conf = act->conf;
-               const struct rte_flow_action_security *sec_act;
-               struct rte_security_session *session;
-               struct ip_spec spec;
-
-               if (conf == NULL) {
-                       rte_flow_error_set(error, EINVAL,
-                               RTE_FLOW_ERROR_TYPE_ACTION_CONF,
-                               act, "NULL security conf.");
-                       return -rte_errno;
-               }
-               /* check if the next not void item is END */
-               act = next_no_void_action(actions, act);
-               if (act->type != RTE_FLOW_ACTION_TYPE_END) {
-                       memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
-                       rte_flow_error_set(error, EINVAL,
-                               RTE_FLOW_ERROR_TYPE_ACTION,
-                               act, "Not supported action.");
-                       return -rte_errno;
-               }
-
-               /* get the IP pattern*/
-               item = next_no_void_pattern(pattern, NULL);
-               while (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
-                               item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
-                       if (item->last ||
-                                       item->type == RTE_FLOW_ITEM_TYPE_END) {
-                               rte_flow_error_set(error, EINVAL,
-                                       RTE_FLOW_ERROR_TYPE_ITEM,
-                                       item, "IP pattern missing.");
-                               return -rte_errno;
-                       }
-                       item = next_no_void_pattern(pattern, item);
-               }
-               if (item->spec == NULL) {
-                       rte_flow_error_set(error, EINVAL,
-                                       RTE_FLOW_ERROR_TYPE_ITEM_SPEC, item,
-                                       "NULL IP pattern.");
-                       return -rte_errno;
-               }
-
-               filter->proto = IPPROTO_ESP;
-               sec_act = (const struct rte_flow_action_security *)conf;
-               spec.is_ipv6 = item->type == RTE_FLOW_ITEM_TYPE_IPV6;
-               if (spec.is_ipv6) {
-                       const struct rte_flow_item_ipv6 *ipv6 = item->spec;
-                       spec.spec.ipv6 = *ipv6;
-               } else {
-                       const struct rte_flow_item_ipv4 *ipv4 = item->spec;
-                       spec.spec.ipv4 = *ipv4;
-               }
-
-               /*
-                * we get pointer to security session from security action,
-                * which is const. however, we do need to act on the session, so
-                * either we do some kind of pointer based lookup to get session
-                * pointer internally (which quickly gets unwieldy for lots of
-                * flows case), or we simply cast away constness.
-                */
-               session = RTE_CAST_PTR(struct rte_security_session *, 
sec_act->security_session);
-               return ixgbe_crypto_add_ingress_sa_from_flow(session, &spec);
-       }
-
        /* the first not void item can be MAC or IPv4 */
        item = next_no_void_pattern(pattern, NULL);
 
@@ -640,6 +572,104 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
        return 0;
 }
 
+static int
+ixgbe_parse_security_filter(struct rte_eth_dev *dev, const struct 
rte_flow_attr *attr,
+               const struct rte_flow_item pattern[], const struct 
rte_flow_action actions[],
+               struct rte_flow_error *error)
+{
+       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       const struct rte_flow_action_security *security;
+       struct rte_security_session *session;
+       const struct rte_flow_item *item;
+       const struct rte_flow_action *act;
+       struct ip_spec spec;
+
+       if (hw->mac.type != ixgbe_mac_82599EB &&
+                       hw->mac.type != ixgbe_mac_X540 &&
+                       hw->mac.type != ixgbe_mac_X550 &&
+                       hw->mac.type != ixgbe_mac_X550EM_x &&
+                       hw->mac.type != ixgbe_mac_X550EM_a &&
+                       hw->mac.type != ixgbe_mac_E610)
+               return -ENOTSUP;
+
+       if (pattern == NULL) {
+               rte_flow_error_set(error,
+                       EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM,
+                       NULL, "NULL pattern.");
+               return -rte_errno;
+       }
+       if (actions == NULL) {
+               rte_flow_error_set(error, EINVAL,
+                                  RTE_FLOW_ERROR_TYPE_ACTION_NUM,
+                                  NULL, "NULL action.");
+               return -rte_errno;
+       }
+       if (attr == NULL) {
+               rte_flow_error_set(error, EINVAL,
+                                  RTE_FLOW_ERROR_TYPE_ATTR,
+                                  NULL, "NULL attribute.");
+               return -rte_errno;
+       }
+
+       /* check if next non-void action is security */
+       act = next_no_void_action(actions, NULL);
+       if (act->type != RTE_FLOW_ACTION_TYPE_SECURITY) {
+               return rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ACTION,
+                               act, "Not supported action.");
+       }
+       security = act->conf;
+       if (security == NULL) {
+               return rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ACTION, act,
+                               "NULL security action config.");
+       }
+       /* check if the next not void item is END */
+       act = next_no_void_action(actions, act);
+       if (act->type != RTE_FLOW_ACTION_TYPE_END) {
+               return rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ACTION,
+                               act, "Not supported action.");
+       }
+
+       /* get the IP pattern*/
+       item = next_no_void_pattern(pattern, NULL);
+       while (item->type != RTE_FLOW_ITEM_TYPE_IPV4 &&
+                       item->type != RTE_FLOW_ITEM_TYPE_IPV6) {
+               if (item->last || item->type == RTE_FLOW_ITEM_TYPE_END) {
+                       rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ITEM,
+                               item, "IP pattern missing.");
+                       return -rte_errno;
+               }
+               item = next_no_void_pattern(pattern, item);
+       }
+       if (item->spec == NULL) {
+               rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ITEM_SPEC, item,
+                               "NULL IP pattern.");
+               return -rte_errno;
+       }
+       spec.is_ipv6 = item->type == RTE_FLOW_ITEM_TYPE_IPV6;
+       if (spec.is_ipv6) {
+               const struct rte_flow_item_ipv6 *ipv6 = item->spec;
+               spec.spec.ipv6 = *ipv6;
+       } else {
+               const struct rte_flow_item_ipv4 *ipv4 = item->spec;
+               spec.spec.ipv4 = *ipv4;
+       }
+
+       /*
+        * we get pointer to security session from security action,
+        * which is const. however, we do need to act on the session, so
+        * either we do some kind of pointer based lookup to get session
+        * pointer internally (which quickly gets unwieldy for lots of
+        * flows case), or we simply cast away constness.
+        */
+       session = RTE_CAST_PTR(struct rte_security_session *, 
security->security_session);
+       return ixgbe_crypto_add_ingress_sa_from_flow(session, &spec);
+}
+
 /* a specific function for ixgbe because the flags is specific */
 static int
 ixgbe_parse_ntuple_filter(struct rte_eth_dev *dev,
@@ -661,10 +691,6 @@ ixgbe_parse_ntuple_filter(struct rte_eth_dev *dev,
        if (ret)
                return ret;
 
-       /* ESP flow not really a flow*/
-       if (filter->proto == IPPROTO_ESP)
-               return 0;
-
        /* Ixgbe doesn't support tcp flags. */
        if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG) {
                memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
@@ -3099,18 +3125,19 @@ ixgbe_flow_create(struct rte_eth_dev *dev,
        TAILQ_INSERT_TAIL(&ixgbe_flow_list,
                                ixgbe_flow_mem_ptr, entries);
 
-       memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
-       ret = ixgbe_parse_ntuple_filter(dev, attr, pattern,
-                       actions, &ntuple_filter, error);
-
-       /* ESP flow not really a flow*/
-       if (ntuple_filter.proto == IPPROTO_ESP) {
-               if (ret != 0)
-                       goto out;
+       /**
+        *  Special case for flow action type RTE_FLOW_ACTION_TYPE_SECURITY
+        */
+       ret = ixgbe_parse_security_filter(dev, attr, pattern, actions, error);
+       if (!ret) {
                flow->is_security = true;
                return flow;
        }
 
+       memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
+       ret = ixgbe_parse_ntuple_filter(dev, attr, pattern,
+                       actions, &ntuple_filter, error);
+
        if (!ret) {
                ret = ixgbe_add_del_ntuple_filter(dev, &ntuple_filter, TRUE);
                if (!ret) {
@@ -3334,6 +3361,13 @@ ixgbe_flow_validate(struct rte_eth_dev *dev,
        struct ixgbe_rte_flow_rss_conf rss_conf;
        int ret;
 
+       /**
+        *  Special case for flow action type RTE_FLOW_ACTION_TYPE_SECURITY
+        */
+       ret = ixgbe_parse_security_filter(dev, attr, pattern, actions, error);
+       if (!ret)
+               return 0;
+
        memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter));
        ret = ixgbe_parse_ntuple_filter(dev, attr, pattern,
                                actions, &ntuple_filter, error);
-- 
2.47.3

Reply via email to