Commit ffb0753b authored by Yevgeny Kliteynik's avatar Yevgeny Kliteynik Committed by Saeed Mahameed

net/mlx5: DR, Don't allow match on IP w/o matching on full ethertype/ip_version

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: 26d688e3 ("net/mlx5: DR, Add Steering entry (STE) utilities")
Signed-off-by: default avatarYevgeny Kliteynik <kliteyn@nvidia.com>
Reviewed-by: default avatarAlex Vesker <valex@nvidia.com>
Signed-off-by: default avatarSaeed Mahameed <saeedm@nvidia.com>
parent 0aec12d9
...@@ -13,18 +13,6 @@ static bool dr_mask_is_dmac_set(struct mlx5dr_match_spec *spec) ...@@ -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); 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) static bool dr_mask_is_l3_base_set(struct mlx5dr_match_spec *spec)
{ {
return (spec->ip_protocol || spec->frag || spec->tcp_flags || return (spec->ip_protocol || spec->frag || spec->tcp_flags ||
...@@ -503,11 +491,11 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher, ...@@ -503,11 +491,11 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher,
&mask, inner, rx); &mask, inner, rx);
if (outer_ipv == DR_RULE_IPV6) { 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++], mlx5dr_ste_build_eth_l3_ipv6_dst(ste_ctx, &sb[idx++],
&mask, inner, rx); &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++], mlx5dr_ste_build_eth_l3_ipv6_src(ste_ctx, &sb[idx++],
&mask, inner, rx); &mask, inner, rx);
...@@ -610,11 +598,11 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher, ...@@ -610,11 +598,11 @@ static int dr_matcher_set_ste_builders(struct mlx5dr_matcher *matcher,
&mask, inner, rx); &mask, inner, rx);
if (inner_ipv == DR_RULE_IPV6) { 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++], mlx5dr_ste_build_eth_l3_ipv6_dst(ste_ctx, &sb[idx++],
&mask, inner, rx); &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++], mlx5dr_ste_build_eth_l3_ipv6_src(ste_ctx, &sb[idx++],
&mask, inner, rx); &mask, inner, rx);
......
...@@ -602,12 +602,34 @@ int mlx5dr_ste_set_action_decap_l3_list(struct mlx5dr_ste_ctx *ste_ctx, ...@@ -602,12 +602,34 @@ int mlx5dr_ste_set_action_decap_l3_list(struct mlx5dr_ste_ctx *ste_ctx,
used_hw_action_num); 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, int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn,
u8 match_criteria, u8 match_criteria,
struct mlx5dr_match_param *mask, struct mlx5dr_match_param *mask,
struct mlx5dr_match_param *value) 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) { if (mask->misc.source_port && mask->misc.source_port != 0xffff) {
mlx5dr_err(dmn, mlx5dr_err(dmn,
"Partial mask source_port is not supported\n"); "Partial mask source_port is not supported\n");
...@@ -621,6 +643,14 @@ int mlx5dr_ste_build_pre_check(struct mlx5dr_domain *dmn, ...@@ -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; return 0;
} }
......
...@@ -798,6 +798,16 @@ struct mlx5dr_match_param { ...@@ -798,6 +798,16 @@ struct mlx5dr_match_param {
(_misc3)->icmpv4_code || \ (_misc3)->icmpv4_code || \
(_misc3)->icmpv4_header_data) (_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 { struct mlx5dr_esw_caps {
u64 drop_icm_address_rx; u64 drop_icm_address_rx;
u64 drop_icm_address_tx; u64 drop_icm_address_tx;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment