]> git.itanic.dy.fi Git - linux-stable/commitdiff
net/mlx5: DR, Don't allow match on IP w/o matching on full ethertype/ip_version
authorYevgeny Kliteynik <kliteyn@nvidia.com>
Thu, 13 Jan 2022 12:52:48 +0000 (14:52 +0200)
committerSaeed Mahameed <saeedm@nvidia.com>
Thu, 24 Feb 2022 00:08:10 +0000 (16:08 -0800)
Currently SMFS allows adding rule with matching on src/dst IP w/o matching
on full ethertype or ip_version, which is not supported by HW.
This patch fixes this issue and adds the check as it is done in DMFS.

Fixes: 26d688e33f88 ("net/mlx5: DR, Add Steering entry (STE) utilities")
Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
Reviewed-by: Alex Vesker <valex@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h

index e87cf498c77bf37a1127eb1699d72349afccd5fe..38971fe1dfe1b5aa8176e87475f2c463d0bcbd6e 100644 (file)
@@ -13,18 +13,6 @@ static bool dr_mask_is_dmac_set(struct mlx5dr_match_spec *spec)
        return (spec->dmac_47_16 || spec->dmac_15_0);
 }
 
-static bool dr_mask_is_src_addr_set(struct mlx5dr_match_spec *spec)
-{
-       return (spec->src_ip_127_96 || spec->src_ip_95_64 ||
-               spec->src_ip_63_32 || spec->src_ip_31_0);
-}
-
-static bool dr_mask_is_dst_addr_set(struct mlx5dr_match_spec *spec)
-{
-       return (spec->dst_ip_127_96 || spec->dst_ip_95_64 ||
-               spec->dst_ip_63_32 || spec->dst_ip_31_0);
-}
-
 static bool dr_mask_is_l3_base_set(struct mlx5dr_match_spec *spec)
 {
        return (spec->ip_protocol || spec->frag || spec->tcp_flags ||
@@ -503,11 +491,11 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher,
                                                    &mask, inner, rx);
 
                if (outer_ipv == DR_RULE_IPV6) {
-                       if (dr_mask_is_dst_addr_set(&mask.outer))
+                       if (DR_MASK_IS_DST_IP_SET(&mask.outer))
                                mlx5dr_ste_build_eth_l3_ipv6_dst(ste_ctx, &sb[idx++],
                                                                 &mask, inner, rx);
 
-                       if (dr_mask_is_src_addr_set(&mask.outer))
+                       if (DR_MASK_IS_SRC_IP_SET(&mask.outer))
                                mlx5dr_ste_build_eth_l3_ipv6_src(ste_ctx, &sb[idx++],
                                                                 &mask, inner, rx);
 
@@ -610,11 +598,11 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher,
                                                    &mask, inner, rx);
 
                if (inner_ipv == DR_RULE_IPV6) {
-                       if (dr_mask_is_dst_addr_set(&mask.inner))
+                       if (DR_MASK_IS_DST_IP_SET(&mask.inner))
                                mlx5dr_ste_build_eth_l3_ipv6_dst(ste_ctx, &sb[idx++],
                                                                 &mask, inner, rx);
 
-                       if (dr_mask_is_src_addr_set(&mask.inner))
+                       if (DR_MASK_IS_SRC_IP_SET(&mask.inner))
                                mlx5dr_ste_build_eth_l3_ipv6_src(ste_ctx, &sb[idx++],
                                                                 &mask, inner, rx);
 
index 7e61742e58a0e2cf521e3568ce0acc263a63a5cf..187e29b409b6cfa23f36354fdb153dc770859820 100644 (file)
@@ -602,12 +602,34 @@ int mlx5dr_ste_set_action_decap_l3_list(struct mlx5dr_ste_ctx *ste_ctx,
                                                 used_hw_action_num);
 }
 
+static int dr_ste_build_pre_check_spec(struct mlx5dr_domain *dmn,
+                                      struct mlx5dr_match_spec *spec)
+{
+       if (spec->ip_version) {
+               if (spec->ip_version != 0xf) {
+                       mlx5dr_err(dmn,
+                                  "Partial ip_version mask with src/dst IP is not supported\n");
+                       return -EINVAL;
+               }
+       } else if (spec->ethertype != 0xffff &&
+                  (DR_MASK_IS_SRC_IP_SET(spec) || DR_MASK_IS_DST_IP_SET(spec))) {
+               mlx5dr_err(dmn,
+                          "Partial/no ethertype mask with src/dst IP is not supported\n");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn,
                               u8 match_criteria,
                               struct mlx5dr_match_param *mask,
                               struct mlx5dr_match_param *value)
 {
-       if (!value && (match_criteria & DR_MATCHER_CRITERIA_MISC)) {
+       if (value)
+               return 0;
+
+       if (match_criteria & DR_MATCHER_CRITERIA_MISC) {
                if (mask->misc.source_port && mask->misc.source_port != 0xffff) {
                        mlx5dr_err(dmn,
                                   "Partial mask source_port is not supported\n");
@@ -621,6 +643,14 @@ int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn,
                }
        }
 
+       if ((match_criteria & DR_MATCHER_CRITERIA_OUTER) &&
+           dr_ste_build_pre_check_spec(dmn, &mask->outer))
+               return -EINVAL;
+
+       if ((match_criteria & DR_MATCHER_CRITERIA_INNER) &&
+           dr_ste_build_pre_check_spec(dmn, &mask->inner))
+               return -EINVAL;
+
        return 0;
 }
 
index 1b3d484b99be19e2f2632da3f65cd0c1bb7a4e8e..55fcb751e24a43616c6c55c066936446c064fe3b 100644 (file)
@@ -798,6 +798,16 @@ struct mlx5dr_match_param {
                                       (_misc3)->icmpv4_code || \
                                       (_misc3)->icmpv4_header_data)
 
+#define DR_MASK_IS_SRC_IP_SET(_spec) ((_spec)->src_ip_127_96 || \
+                                     (_spec)->src_ip_95_64  || \
+                                     (_spec)->src_ip_63_32  || \
+                                     (_spec)->src_ip_31_0)
+
+#define DR_MASK_IS_DST_IP_SET(_spec) ((_spec)->dst_ip_127_96 || \
+                                     (_spec)->dst_ip_95_64  || \
+                                     (_spec)->dst_ip_63_32  || \
+                                     (_spec)->dst_ip_31_0)
+
 struct mlx5dr_esw_caps {
        u64 drop_icm_address_rx;
        u64 drop_icm_address_tx;