Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[platform/kernel/linux-rpi.git] / drivers / net / ethernet / mellanox / mlx5 / core / fs_core.c
index 35d89ed..e3960cd 100644 (file)
@@ -1580,9 +1580,22 @@ static struct mlx5_flow_rule *find_flow_rule(struct fs_fte *fte,
        return NULL;
 }
 
-static bool check_conflicting_actions(u32 action1, u32 action2)
+static bool check_conflicting_actions_vlan(const struct mlx5_fs_vlan *vlan0,
+                                          const struct mlx5_fs_vlan *vlan1)
 {
-       u32 xored_actions = action1 ^ action2;
+       return vlan0->ethtype != vlan1->ethtype ||
+              vlan0->vid != vlan1->vid ||
+              vlan0->prio != vlan1->prio;
+}
+
+static bool check_conflicting_actions(const struct mlx5_flow_act *act1,
+                                     const struct mlx5_flow_act *act2)
+{
+       u32 action1 = act1->action;
+       u32 action2 = act2->action;
+       u32 xored_actions;
+
+       xored_actions = action1 ^ action2;
 
        /* if one rule only wants to count, it's ok */
        if (action1 == MLX5_FLOW_CONTEXT_ACTION_COUNT ||
@@ -1599,6 +1612,22 @@ static bool check_conflicting_actions(u32 action1, u32 action2)
                             MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2))
                return true;
 
+       if (action1 & MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT &&
+           act1->pkt_reformat != act2->pkt_reformat)
+               return true;
+
+       if (action1 & MLX5_FLOW_CONTEXT_ACTION_MOD_HDR &&
+           act1->modify_hdr != act2->modify_hdr)
+               return true;
+
+       if (action1 & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH &&
+           check_conflicting_actions_vlan(&act1->vlan[0], &act2->vlan[0]))
+               return true;
+
+       if (action1 & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2 &&
+           check_conflicting_actions_vlan(&act1->vlan[1], &act2->vlan[1]))
+               return true;
+
        return false;
 }
 
@@ -1606,7 +1635,7 @@ static int check_conflicting_ftes(struct fs_fte *fte,
                                  const struct mlx5_flow_context *flow_context,
                                  const struct mlx5_flow_act *flow_act)
 {
-       if (check_conflicting_actions(flow_act->action, fte->action.action)) {
+       if (check_conflicting_actions(flow_act, &fte->action)) {
                mlx5_core_warn(get_dev(&fte->node),
                               "Found two FTEs with conflicting actions\n");
                return -EEXIST;