net/mlx5: fix GENEVE protocol type translation
When application creates several flows to match on GENEVE tunnel
without explicitly specifying GENEVE protocol type value in
flow rules, PMD will translate that to zero mask.
RDMA-CORE cannot distinguish between different inner flow types and
produces identical matchers for each zero mask.
The patch extracts inner header type from flow rule and forces it
in GENEVE protocol type, if application did not specify
any without explicitly specifying GENEVE protocol type value in
flow rules, protocol type value.
Fixes: e59a5dbcfd
("net/mlx5: add flow match on GENEVE item")
Cc: stable@dpdk.org
Signed-off-by: Gregory Etelson <getelson@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
This commit is contained in:
parent
a21d616b99
commit
690391dd0e
@ -93,6 +93,20 @@ static int
|
||||
flow_dv_jump_tbl_resource_release(struct rte_eth_dev *dev,
|
||||
uint32_t rix_jump);
|
||||
|
||||
static inline uint16_t
|
||||
mlx5_translate_tunnel_etypes(uint64_t pattern_flags)
|
||||
{
|
||||
if (pattern_flags & MLX5_FLOW_LAYER_INNER_L2)
|
||||
return RTE_ETHER_TYPE_TEB;
|
||||
else if (pattern_flags & MLX5_FLOW_LAYER_INNER_L3_IPV4)
|
||||
return RTE_ETHER_TYPE_IPV4;
|
||||
else if (pattern_flags & MLX5_FLOW_LAYER_INNER_L3_IPV6)
|
||||
return RTE_ETHER_TYPE_IPV6;
|
||||
else if (pattern_flags & MLX5_FLOW_LAYER_MPLS)
|
||||
return RTE_ETHER_TYPE_MPLS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int16_t
|
||||
flow_dv_get_esw_manager_vport_id(struct rte_eth_dev *dev)
|
||||
{
|
||||
@ -9038,49 +9052,39 @@ flow_dv_translate_item_vxlan_gpe(void *matcher, void *key,
|
||||
|
||||
static void
|
||||
flow_dv_translate_item_geneve(void *matcher, void *key,
|
||||
const struct rte_flow_item *item, int inner)
|
||||
const struct rte_flow_item *item,
|
||||
uint64_t pattern_flags)
|
||||
{
|
||||
static const struct rte_flow_item_geneve empty_geneve = {0,};
|
||||
const struct rte_flow_item_geneve *geneve_m = item->mask;
|
||||
const struct rte_flow_item_geneve *geneve_v = item->spec;
|
||||
void *headers_m;
|
||||
void *headers_v;
|
||||
/* GENEVE flow item validation allows single tunnel item */
|
||||
void *headers_m = MLX5_ADDR_OF(fte_match_param, matcher, outer_headers);
|
||||
void *headers_v = MLX5_ADDR_OF(fte_match_param, key, outer_headers);
|
||||
void *misc_m = MLX5_ADDR_OF(fte_match_param, matcher, misc_parameters);
|
||||
void *misc_v = MLX5_ADDR_OF(fte_match_param, key, misc_parameters);
|
||||
uint16_t dport;
|
||||
uint16_t gbhdr_m;
|
||||
uint16_t gbhdr_v;
|
||||
char *vni_m;
|
||||
char *vni_v;
|
||||
size_t size, i;
|
||||
char *vni_m = MLX5_ADDR_OF(fte_match_set_misc, misc_m, geneve_vni);
|
||||
char *vni_v = MLX5_ADDR_OF(fte_match_set_misc, misc_v, geneve_vni);
|
||||
size_t size = sizeof(geneve_m->vni), i;
|
||||
uint16_t protocol_m, protocol_v;
|
||||
|
||||
if (inner) {
|
||||
headers_m = MLX5_ADDR_OF(fte_match_param, matcher,
|
||||
inner_headers);
|
||||
headers_v = MLX5_ADDR_OF(fte_match_param, key, inner_headers);
|
||||
} else {
|
||||
headers_m = MLX5_ADDR_OF(fte_match_param, matcher,
|
||||
outer_headers);
|
||||
headers_v = MLX5_ADDR_OF(fte_match_param, key, outer_headers);
|
||||
}
|
||||
dport = MLX5_UDP_PORT_GENEVE;
|
||||
if (!MLX5_GET16(fte_match_set_lyr_2_4, headers_v, udp_dport)) {
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_m, udp_dport, 0xFFFF);
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport, dport);
|
||||
MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport,
|
||||
MLX5_UDP_PORT_GENEVE);
|
||||
}
|
||||
if (!geneve_v) {
|
||||
geneve_v = &empty_geneve;
|
||||
geneve_m = &empty_geneve;
|
||||
} else {
|
||||
if (!geneve_m)
|
||||
geneve_m = &rte_flow_item_geneve_mask;
|
||||
}
|
||||
if (!geneve_v)
|
||||
return;
|
||||
if (!geneve_m)
|
||||
geneve_m = &rte_flow_item_geneve_mask;
|
||||
size = sizeof(geneve_m->vni);
|
||||
vni_m = MLX5_ADDR_OF(fte_match_set_misc, misc_m, geneve_vni);
|
||||
vni_v = MLX5_ADDR_OF(fte_match_set_misc, misc_v, geneve_vni);
|
||||
memcpy(vni_m, geneve_m->vni, size);
|
||||
for (i = 0; i < size; ++i)
|
||||
vni_v[i] = vni_m[i] & geneve_v->vni[i];
|
||||
MLX5_SET(fte_match_set_misc, misc_m, geneve_protocol_type,
|
||||
rte_be_to_cpu_16(geneve_m->protocol));
|
||||
MLX5_SET(fte_match_set_misc, misc_v, geneve_protocol_type,
|
||||
rte_be_to_cpu_16(geneve_v->protocol & geneve_m->protocol));
|
||||
gbhdr_m = rte_be_to_cpu_16(geneve_m->ver_opt_len_o_c_rsvd0);
|
||||
gbhdr_v = rte_be_to_cpu_16(geneve_v->ver_opt_len_o_c_rsvd0);
|
||||
MLX5_SET(fte_match_set_misc, misc_m, geneve_oam,
|
||||
@ -9092,6 +9096,16 @@ flow_dv_translate_item_geneve(void *matcher, void *key,
|
||||
MLX5_SET(fte_match_set_misc, misc_v, geneve_opt_len,
|
||||
MLX5_GENEVE_OPTLEN_VAL(gbhdr_v) &
|
||||
MLX5_GENEVE_OPTLEN_VAL(gbhdr_m));
|
||||
protocol_m = rte_be_to_cpu_16(geneve_m->protocol);
|
||||
protocol_v = rte_be_to_cpu_16(geneve_v->protocol);
|
||||
if (!protocol_m) {
|
||||
/* Force next protocol to prevent matchers duplication */
|
||||
protocol_m = 0xFFFF;
|
||||
protocol_v = mlx5_translate_tunnel_etypes(pattern_flags);
|
||||
}
|
||||
MLX5_SET(fte_match_set_misc, misc_m, geneve_protocol_type, protocol_m);
|
||||
MLX5_SET(fte_match_set_misc, misc_v, geneve_protocol_type,
|
||||
protocol_m & protocol_v);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -13449,10 +13463,9 @@ flow_dv_translate(struct rte_eth_dev *dev,
|
||||
tunnel_item = items;
|
||||
break;
|
||||
case RTE_FLOW_ITEM_TYPE_GENEVE:
|
||||
flow_dv_translate_item_geneve(match_mask, match_value,
|
||||
items, tunnel);
|
||||
matcher.priority = MLX5_TUNNEL_PRIO_GET(rss_desc);
|
||||
last_item = MLX5_FLOW_LAYER_GENEVE;
|
||||
tunnel_item = items;
|
||||
break;
|
||||
case RTE_FLOW_ITEM_TYPE_GENEVE_OPT:
|
||||
ret = flow_dv_translate_item_geneve_opt(dev, match_mask,
|
||||
@ -13581,6 +13594,9 @@ flow_dv_translate(struct rte_eth_dev *dev,
|
||||
if (item_flags & MLX5_FLOW_LAYER_VXLAN_GPE)
|
||||
flow_dv_translate_item_vxlan_gpe(match_mask, match_value,
|
||||
tunnel_item, item_flags);
|
||||
else if (item_flags & MLX5_FLOW_LAYER_GENEVE)
|
||||
flow_dv_translate_item_geneve(match_mask, match_value,
|
||||
tunnel_item, item_flags);
|
||||
#ifdef RTE_LIBRTE_MLX5_DEBUG
|
||||
MLX5_ASSERT(!flow_dv_check_valid_spec(matcher.mask.buf,
|
||||
dev_flow->dv.value.buf));
|
||||
|
Loading…
Reference in New Issue
Block a user