net/mlx5e: Support pedit on mpls over UDP decap
authorEli Cohen <eli@mellanox.com>
Wed, 8 Apr 2020 06:01:33 +0000 (09:01 +0300)
committerSaeed Mahameed <saeedm@mellanox.com>
Fri, 22 May 2020 23:46:23 +0000 (16:46 -0700)
Allow to modify ethernet headers while decapsulating mpls over UDP
packets. This is implemented using the same reformat object used for
decapsulation.

Signed-off-by: Eli Cohen <eli@mellanox.com>
Reviewed-by: Roi Dayan <roid@mellanox.com>
Reviewed-by: Paul Blakey <paulb@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

index a6b18f0444e7beb42af4881e68026dfa708053de..cc669ea450aeb66fcd04de2d677379e404401cb3 100644 (file)
@@ -2900,10 +2900,12 @@ void dealloc_mod_hdr_actions(struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts)
 
 static const struct pedit_headers zero_masks = {};
 
-static int parse_tc_pedit_action(struct mlx5e_priv *priv,
-                                const struct flow_action_entry *act, int namespace,
-                                struct pedit_headers_action *hdrs,
-                                struct netlink_ext_ack *extack)
+static int
+parse_pedit_to_modify_hdr(struct mlx5e_priv *priv,
+                         const struct flow_action_entry *act, int namespace,
+                         struct mlx5e_tc_flow_parse_attr *parse_attr,
+                         struct pedit_headers_action *hdrs,
+                         struct netlink_ext_ack *extack)
 {
        u8 cmd = (act->id == FLOW_ACTION_MANGLE) ? 0 : 1;
        int err = -EOPNOTSUPP;
@@ -2939,6 +2941,46 @@ out_err:
        return err;
 }
 
+static int
+parse_pedit_to_reformat(struct mlx5e_priv *priv,
+                       const struct flow_action_entry *act,
+                       struct mlx5e_tc_flow_parse_attr *parse_attr,
+                       struct netlink_ext_ack *extack)
+{
+       u32 mask, val, offset;
+       u32 *p;
+
+       if (act->id != FLOW_ACTION_MANGLE)
+               return -EOPNOTSUPP;
+
+       if (act->mangle.htype != FLOW_ACT_MANGLE_HDR_TYPE_ETH) {
+               NL_SET_ERR_MSG_MOD(extack, "Only Ethernet modification is supported");
+               return -EOPNOTSUPP;
+       }
+
+       mask = ~act->mangle.mask;
+       val = act->mangle.val;
+       offset = act->mangle.offset;
+       p = (u32 *)&parse_attr->eth;
+       *(p + (offset >> 2)) |= (val & mask);
+
+       return 0;
+}
+
+static int parse_tc_pedit_action(struct mlx5e_priv *priv,
+                                const struct flow_action_entry *act, int namespace,
+                                struct mlx5e_tc_flow_parse_attr *parse_attr,
+                                struct pedit_headers_action *hdrs,
+                                struct mlx5e_tc_flow *flow,
+                                struct netlink_ext_ack *extack)
+{
+       if (flow && flow_flag_test(flow, L3_TO_L2_DECAP))
+               return parse_pedit_to_reformat(priv, act, parse_attr, extack);
+
+       return parse_pedit_to_modify_hdr(priv, act, namespace,
+                                        parse_attr, hdrs, extack);
+}
+
 static int alloc_tc_pedit_action(struct mlx5e_priv *priv, int namespace,
                                 struct mlx5e_tc_flow_parse_attr *parse_attr,
                                 struct pedit_headers_action *hdrs,
@@ -3197,7 +3239,7 @@ static int add_vlan_rewrite_action(struct mlx5e_priv *priv, int namespace,
                return -EOPNOTSUPP;
        }
 
-       err = parse_tc_pedit_action(priv, &pedit_act, namespace, hdrs, NULL);
+       err = parse_tc_pedit_action(priv, &pedit_act, namespace, parse_attr, hdrs, NULL, extack);
        *action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
 
        return err;
@@ -3263,7 +3305,7 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv,
                case FLOW_ACTION_MANGLE:
                case FLOW_ACTION_ADD:
                        err = parse_tc_pedit_action(priv, act, MLX5_FLOW_NAMESPACE_KERNEL,
-                                                   hdrs, extack);
+                                                   parse_attr, hdrs, NULL, extack);
                        if (err)
                                return err;
 
@@ -3932,16 +3974,15 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
                        break;
                case FLOW_ACTION_MANGLE:
                case FLOW_ACTION_ADD:
-                       if (flow_flag_test(flow, L3_TO_L2_DECAP))
-                               return -EOPNOTSUPP;
-
                        err = parse_tc_pedit_action(priv, act, MLX5_FLOW_NAMESPACE_FDB,
-                                                   hdrs, extack);
+                                                   parse_attr, hdrs, flow, extack);
                        if (err)
                                return err;
 
-                       action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
-                       attr->split_count = attr->out_count;
+                       if (!flow_flag_test(flow, L3_TO_L2_DECAP)) {
+                               action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
+                               attr->split_count = attr->out_count;
+                       }
                        break;
                case FLOW_ACTION_CSUM:
                        if (csum_offload_supported(priv, action,