OSDN Git Service

net/mlx5e: Allow to match on mpls parameters
authorEli Cohen <eli@mellanox.com>
Wed, 29 Jan 2020 14:21:16 +0000 (16:21 +0200)
committerSaeed Mahameed <saeedm@mellanox.com>
Fri, 22 May 2020 23:46:19 +0000 (16:46 -0700)
Support matching on MPLS over UDP parameters using misc2 section of
match parameters.

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

index ff296c0..98ee62e 100644 (file)
@@ -73,6 +73,55 @@ static int parse_tunnel(struct mlx5e_priv *priv,
                        void *headers_c,
                        void *headers_v)
 {
+       struct flow_rule *rule = flow_cls_offload_flow_rule(f);
+       struct flow_match_enc_keyid enc_keyid;
+       struct flow_match_mpls match;
+       void *misc2_c;
+       void *misc2_v;
+
+       misc2_c = MLX5_ADDR_OF(fte_match_param, spec->match_criteria,
+                              misc_parameters_2);
+       misc2_v = MLX5_ADDR_OF(fte_match_param, spec->match_value,
+                              misc_parameters_2);
+
+       if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_MPLS))
+               return 0;
+
+       if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_KEYID))
+               return 0;
+
+       flow_rule_match_enc_keyid(rule, &enc_keyid);
+
+       if (!enc_keyid.mask->keyid)
+               return 0;
+
+       if (!(MLX5_CAP_GEN(priv->mdev, flex_parser_protocols) &
+             MLX5_FLEX_PROTO_CW_MPLS_UDP))
+               return -EOPNOTSUPP;
+
+       flow_rule_match_mpls(rule, &match);
+
+       MLX5_SET(fte_match_set_misc2, misc2_c,
+                outer_first_mpls_over_udp.mpls_label, match.mask->mpls_label);
+       MLX5_SET(fte_match_set_misc2, misc2_v,
+                outer_first_mpls_over_udp.mpls_label, match.key->mpls_label);
+
+       MLX5_SET(fte_match_set_misc2, misc2_c,
+                outer_first_mpls_over_udp.mpls_exp, match.mask->mpls_tc);
+       MLX5_SET(fte_match_set_misc2, misc2_v,
+                outer_first_mpls_over_udp.mpls_exp, match.key->mpls_tc);
+
+       MLX5_SET(fte_match_set_misc2, misc2_c,
+                outer_first_mpls_over_udp.mpls_s_bos, match.mask->mpls_bos);
+       MLX5_SET(fte_match_set_misc2, misc2_v,
+                outer_first_mpls_over_udp.mpls_s_bos, match.key->mpls_bos);
+
+       MLX5_SET(fte_match_set_misc2, misc2_c,
+                outer_first_mpls_over_udp.mpls_ttl, match.mask->mpls_ttl);
+       MLX5_SET(fte_match_set_misc2, misc2_v,
+                outer_first_mpls_over_udp.mpls_ttl, match.key->mpls_ttl);
+       spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_2;
+
        return 0;
 }
 
index 2cebbd0..801fcd1 100644 (file)
@@ -2073,6 +2073,20 @@ static int mlx5e_flower_parse_meta(struct net_device *filter_dev,
        return 0;
 }
 
+static bool skip_key_basic(struct net_device *filter_dev,
+                          struct flow_cls_offload *f)
+{
+       /* When doing mpls over udp decap, the user needs to provide
+        * MPLS_UC as the protocol in order to be able to match on mpls
+        * label fields.  However, the actual ethertype is IP so we want to
+        * avoid matching on this, otherwise we'll fail the match.
+        */
+       if (netif_is_bareudp(filter_dev) && f->common.chain_index == 0)
+               return true;
+
+       return false;
+}
+
 static int __parse_cls_flower(struct mlx5e_priv *priv,
                              struct mlx5e_tc_flow *flow,
                              struct mlx5_flow_spec *spec,
@@ -2117,7 +2131,8 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
              BIT(FLOW_DISSECTOR_KEY_IP)  |
              BIT(FLOW_DISSECTOR_KEY_CT) |
              BIT(FLOW_DISSECTOR_KEY_ENC_IP) |
-             BIT(FLOW_DISSECTOR_KEY_ENC_OPTS))) {
+             BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) |
+             BIT(FLOW_DISSECTOR_KEY_MPLS))) {
                NL_SET_ERR_MSG_MOD(extack, "Unsupported key");
                netdev_warn(priv->netdev, "Unsupported key used: 0x%x\n",
                            dissector->used_keys);
@@ -2147,7 +2162,8 @@ static int __parse_cls_flower(struct mlx5e_priv *priv,
        if (err)
                return err;
 
-       if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
+       if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC) &&
+           !skip_key_basic(filter_dev, f)) {
                struct flow_match_basic match;
 
                flow_rule_match_basic(rule, &match);