Use the common attr and action parsing infrastructure in ethertype. This
allows us to remove some checks as they are no longer necessary (such as
whether DROP flag was set - if we do not accept DROP actions, we do not set
the DROP flag), as well as make some checks more stringent (such as
rejecting more than one action).

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

diff --git a/drivers/net/intel/ixgbe/ixgbe_flow.c 
b/drivers/net/intel/ixgbe/ixgbe_flow.c
index cd8d46019f..7695d57e2a 100644
--- a/drivers/net/intel/ixgbe/ixgbe_flow.c
+++ b/drivers/net/intel/ixgbe/ixgbe_flow.c
@@ -43,6 +43,8 @@
 #include "base/ixgbe_phy.h"
 #include "rte_pmd_ixgbe.h"
 
+#include "../common/flow_check.h"
+
 
 #define IXGBE_MIN_N_TUPLE_PRIO 1
 #define IXGBE_MAX_N_TUPLE_PRIO 7
@@ -133,6 +135,41 @@ const struct rte_flow_action *next_no_void_action(
        }
 }
 
+/*
+ * All ixgbe engines mostly check the same stuff, so use a common check.
+ */
+static int
+ixgbe_flow_actions_check(const struct ci_flow_actions *actions,
+               const struct ci_flow_actions_check_param *param,
+               struct rte_flow_error *error)
+{
+       const struct rte_flow_action *action;
+       struct rte_eth_dev *dev = (struct rte_eth_dev *)param->driver_ctx;
+       size_t idx;
+
+       for (idx = 0; idx < actions->count; idx++) {
+               action = actions->actions[idx];
+
+               switch(action->type) {
+               case RTE_FLOW_ACTION_TYPE_QUEUE:
+               {
+                       const struct rte_flow_action_queue *queue = 
action->conf;
+                       if (queue->index >= dev->data->nb_rx_queues) {
+                               return rte_flow_error_set(error, EINVAL,
+                                               RTE_FLOW_ERROR_TYPE_ACTION,
+                                               action,
+                                               "queue index out of range");
+                       }
+                       break;
+               }
+               default:
+                       /* no specific validation */
+                       break;
+               }
+       }
+       return 0;
+}
+
 /**
  * Please be aware there's an assumption for all the parsers.
  * rte_flow_item is using big endian, rte_flow_attr and
@@ -712,38 +749,14 @@ ixgbe_parse_ntuple_filter(struct rte_eth_dev *dev,
  * item->last should be NULL.
  */
 static int
-cons_parse_ethertype_filter(const struct rte_flow_attr *attr,
-                           const struct rte_flow_item *pattern,
-                           const struct rte_flow_action *actions,
-                           struct rte_eth_ethertype_filter *filter,
-                           struct rte_flow_error *error)
+cons_parse_ethertype_filter(const struct rte_flow_item *pattern,
+               const struct rte_flow_action *action,
+               struct rte_eth_ethertype_filter *filter,
+               struct rte_flow_error *error)
 {
        const struct rte_flow_item *item;
-       const struct rte_flow_action *act;
        const struct rte_flow_item_eth *eth_spec;
        const struct rte_flow_item_eth *eth_mask;
-       const struct rte_flow_action_queue *act_q;
-
-       if (!pattern) {
-               rte_flow_error_set(error, EINVAL,
-                               RTE_FLOW_ERROR_TYPE_ITEM_NUM,
-                               NULL, "NULL pattern.");
-               return -rte_errno;
-       }
-
-       if (!actions) {
-               rte_flow_error_set(error, EINVAL,
-                               RTE_FLOW_ERROR_TYPE_ACTION_NUM,
-                               NULL, "NULL action.");
-               return -rte_errno;
-       }
-
-       if (!attr) {
-               rte_flow_error_set(error, EINVAL,
-                                  RTE_FLOW_ERROR_TYPE_ATTR,
-                                  NULL, "NULL attribute.");
-               return -rte_errno;
-       }
 
        item = next_no_void_pattern(pattern, NULL);
        /* The first non-void item should be MAC. */
@@ -813,87 +826,30 @@ cons_parse_ethertype_filter(const struct rte_flow_attr 
*attr,
                return -rte_errno;
        }
 
-       /* Parse action */
-
-       act = next_no_void_action(actions, NULL);
-       if (act->type != RTE_FLOW_ACTION_TYPE_QUEUE &&
-           act->type != RTE_FLOW_ACTION_TYPE_DROP) {
-               rte_flow_error_set(error, EINVAL,
-                               RTE_FLOW_ERROR_TYPE_ACTION,
-                               act, "Not supported action.");
-               return -rte_errno;
-       }
-
-       if (act->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
-               act_q = (const struct rte_flow_action_queue *)act->conf;
-               filter->queue = act_q->index;
-       } else {
-               filter->flags |= RTE_ETHTYPE_FLAGS_DROP;
-       }
-
-       /* Check if the next non-void item is END */
-       act = next_no_void_action(actions, act);
-       if (act->type != RTE_FLOW_ACTION_TYPE_END) {
-               rte_flow_error_set(error, EINVAL,
-                               RTE_FLOW_ERROR_TYPE_ACTION,
-                               act, "Not supported action.");
-               return -rte_errno;
-       }
-
-       /* Parse attr */
-       /* Must be input direction */
-       if (!attr->ingress) {
-               rte_flow_error_set(error, EINVAL,
-                               RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
-                               attr, "Only support ingress.");
-               return -rte_errno;
-       }
-
-       /* Not supported */
-       if (attr->egress) {
-               rte_flow_error_set(error, EINVAL,
-                               RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
-                               attr, "Not support egress.");
-               return -rte_errno;
-       }
-
-       /* Not supported */
-       if (attr->transfer) {
-               rte_flow_error_set(error, EINVAL,
-                               RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
-                               attr, "No support for transfer.");
-               return -rte_errno;
-       }
-
-       /* Not supported */
-       if (attr->priority) {
-               rte_flow_error_set(error, EINVAL,
-                               RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
-                               attr, "Not support priority.");
-               return -rte_errno;
-       }
-
-       /* Not supported */
-       if (attr->group) {
-               rte_flow_error_set(error, EINVAL,
-                               RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
-                               attr, "Not support group.");
-               return -rte_errno;
-       }
+       filter->queue = ((const struct rte_flow_action_queue 
*)action->conf)->index;
 
        return 0;
 }
 
 static int
-ixgbe_parse_ethertype_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_eth_ethertype_filter *filter,
-                            struct rte_flow_error *error)
+ixgbe_parse_ethertype_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_eth_ethertype_filter *filter, struct rte_flow_error 
*error)
 {
        int ret;
        struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ci_flow_actions parsed_actions;
+       struct ci_flow_actions_check_param ap_param = {
+               .allowed_types = (const enum rte_flow_action_type[]){
+                       /* only queue is allowed here */
+                       RTE_FLOW_ACTION_TYPE_QUEUE,
+                       RTE_FLOW_ACTION_TYPE_END
+               },
+               .max_actions = 1,
+               .driver_ctx = dev,
+               .check = ixgbe_flow_actions_check
+       };
+       const struct rte_flow_action *action;
 
        if (hw->mac.type != ixgbe_mac_82599EB &&
                        hw->mac.type != ixgbe_mac_X540 &&
@@ -903,19 +859,27 @@ ixgbe_parse_ethertype_filter(struct rte_eth_dev *dev,
                        hw->mac.type != ixgbe_mac_E610)
                return -ENOTSUP;
 
-       ret = cons_parse_ethertype_filter(attr, pattern,
-                                       actions, filter, error);
+       /* validate attributes */
+       ret = ci_flow_check_attr(attr, NULL, error);
+       if (ret)
+               return ret;
 
+       /* parse requested actions */
+       ret = ci_flow_check_actions(actions, &ap_param, &parsed_actions, error);
        if (ret)
                return ret;
 
-       if (filter->queue >= dev->data->nb_rx_queues) {
-               memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
-               rte_flow_error_set(error, EINVAL,
-                       RTE_FLOW_ERROR_TYPE_ITEM,
-                       NULL, "queue index much too big");
-               return -rte_errno;
+       /* only one action is supported */
+       if (parsed_actions.count > 1) {
+               return rte_flow_error_set(error, EINVAL, 
RTE_FLOW_ERROR_TYPE_ACTION,
+                                         parsed_actions.actions[1],
+                                         "Only one action can be specified at 
a time");
        }
+       action = parsed_actions.actions[0];
+
+       ret = cons_parse_ethertype_filter(pattern, action, filter, error);
+       if (ret)
+               return ret;
 
        if (filter->ether_type == RTE_ETHER_TYPE_IPV4 ||
                filter->ether_type == RTE_ETHER_TYPE_IPV6) {
@@ -934,14 +898,6 @@ ixgbe_parse_ethertype_filter(struct rte_eth_dev *dev,
                return -rte_errno;
        }
 
-       if (filter->flags & RTE_ETHTYPE_FLAGS_DROP) {
-               memset(filter, 0, sizeof(struct rte_eth_ethertype_filter));
-               rte_flow_error_set(error, EINVAL,
-                       RTE_FLOW_ERROR_TYPE_ITEM,
-                       NULL, "drop option is unsupported");
-               return -rte_errno;
-       }
-
        return 0;
 }
 
-- 
2.47.3

Reply via email to