examples/ipsec-secgw: replace strncpy with strlcpy
[dpdk.git] / drivers / net / enic / enic_flow.c
index b9f3658..525f3dd 100644 (file)
@@ -3,6 +3,7 @@
  */
 
 #include <errno.h>
+#include <stdint.h>
 #include <rte_log.h>
 #include <rte_ethdev_driver.h>
 #include <rte_flow_driver.h>
@@ -556,16 +557,21 @@ enic_copy_item_vlan_v2(const struct rte_flow_item *item,
        if (!spec)
                return 0;
 
-       /* Don't support filtering in tpid */
-       if (mask) {
-               if (mask->tpid != 0)
-                       return ENOTSUP;
-       } else {
+       if (!mask)
                mask = &rte_flow_item_vlan_mask;
-               RTE_ASSERT(mask->tpid == 0);
-       }
 
        if (*inner_ofst == 0) {
+               struct ether_hdr *eth_mask =
+                       (void *)gp->layer[FILTER_GENERIC_1_L2].mask;
+               struct ether_hdr *eth_val =
+                       (void *)gp->layer[FILTER_GENERIC_1_L2].val;
+
+               /* Outer TPID cannot be matched */
+               if (eth_mask->ether_type)
+                       return ENOTSUP;
+               eth_mask->ether_type = mask->inner_type;
+               eth_val->ether_type = spec->inner_type;
+
                /* Outer header. Use the vlan mask/val fields */
                gp->mask_vlan = mask->tci;
                gp->val_vlan = spec->tci;
@@ -964,6 +970,9 @@ static int
 enic_copy_action_v1(const struct rte_flow_action actions[],
                    struct filter_action_v2 *enic_action)
 {
+       enum { FATE = 1, };
+       uint32_t overlap = 0;
+
        FLOW_TRACE();
 
        for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
@@ -975,6 +984,10 @@ enic_copy_action_v1(const struct rte_flow_action actions[],
                        const struct rte_flow_action_queue *queue =
                                (const struct rte_flow_action_queue *)
                                actions->conf;
+
+                       if (overlap & FATE)
+                               return ENOTSUP;
+                       overlap |= FATE;
                        enic_action->rq_idx =
                                enic_rte_rq_idx_to_sop_idx(queue->index);
                        break;
@@ -984,6 +997,8 @@ enic_copy_action_v1(const struct rte_flow_action actions[],
                        break;
                }
        }
+       if (!(overlap & FATE))
+               return ENOTSUP;
        enic_action->type = FILTER_ACTION_RQ_STEERING;
        return 0;
 }
@@ -1001,6 +1016,9 @@ static int
 enic_copy_action_v2(const struct rte_flow_action actions[],
                    struct filter_action_v2 *enic_action)
 {
+       enum { FATE = 1, MARK = 2, };
+       uint32_t overlap = 0;
+
        FLOW_TRACE();
 
        for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
@@ -1009,6 +1027,10 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
                        const struct rte_flow_action_queue *queue =
                                (const struct rte_flow_action_queue *)
                                actions->conf;
+
+                       if (overlap & FATE)
+                               return ENOTSUP;
+                       overlap |= FATE;
                        enic_action->rq_idx =
                                enic_rte_rq_idx_to_sop_idx(queue->index);
                        enic_action->flags |= FILTER_ACTION_RQ_STEERING_FLAG;
@@ -1019,6 +1041,9 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
                                (const struct rte_flow_action_mark *)
                                actions->conf;
 
+                       if (overlap & MARK)
+                               return ENOTSUP;
+                       overlap |= MARK;
                        /* ENIC_MAGIC_FILTER_ID is reserved and is the highest
                         * in the range of allows mark ids.
                         */
@@ -1029,6 +1054,9 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
                        break;
                }
                case RTE_FLOW_ACTION_TYPE_FLAG: {
+                       if (overlap & MARK)
+                               return ENOTSUP;
+                       overlap |= MARK;
                        enic_action->filter_id = ENIC_MAGIC_FILTER_ID;
                        enic_action->flags |= FILTER_ACTION_FILTER_ID_FLAG;
                        break;
@@ -1044,6 +1072,8 @@ enic_copy_action_v2(const struct rte_flow_action actions[],
                        break;
                }
        }
+       if (!(overlap & FATE))
+               return ENOTSUP;
        enic_action->type = FILTER_ACTION_V2;
        return 0;
 }
@@ -1288,6 +1318,12 @@ enic_flow_parse(struct rte_eth_dev *dev,
                                           NULL,
                                           "egress is not supported");
                        return -rte_errno;
+               } else if (attrs->transfer) {
+                       rte_flow_error_set(error, ENOTSUP,
+                                          RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                                          NULL,
+                                          "transfer is not supported");
+                       return -rte_errno;
                } else if (!attrs->ingress) {
                        rte_flow_error_set(error, ENOTSUP,
                                           RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,