IB/mlx5: Add support to match inner packet fields

Add support to match packet fields which are tunneled,
i.e. support matching the header of the inner packet which is the result of
or bit operation of the original header and the IB_FLOW_SPEC_INNER type.

The combination of IB_FLOW_SPEC_INNER | IB_FLOW_SPEC_VXLAN_TUNNEL is not
needed to be checked, because the IB core has this check already.

Signed-off-by: Moses Reuben <mosesr@mellanox.com>
Reviewed-by: Maor Gottlieb <maorg@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
Moses Reuben 2016-11-14 19:04:52 +02:00 committed by Doug Ledford
parent fbf46860b1
commit 2d1e697e9b
1 changed files with 78 additions and 53 deletions

View File

@ -1526,6 +1526,22 @@ static void set_proto(void *outer_c, void *outer_v, u8 mask, u8 val)
MLX5_SET(fte_match_set_lyr_2_4, outer_v, ip_protocol, val); MLX5_SET(fte_match_set_lyr_2_4, outer_v, ip_protocol, val);
} }
static void set_flow_label(void *misc_c, void *misc_v, u8 mask, u8 val,
bool inner)
{
if (inner) {
MLX5_SET(fte_match_set_misc,
misc_c, inner_ipv6_flow_label, mask);
MLX5_SET(fte_match_set_misc,
misc_v, inner_ipv6_flow_label, val);
} else {
MLX5_SET(fte_match_set_misc,
misc_c, outer_ipv6_flow_label, mask);
MLX5_SET(fte_match_set_misc,
misc_v, outer_ipv6_flow_label, val);
}
}
static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val) static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val)
{ {
MLX5_SET(fte_match_set_lyr_2_4, outer_c, ip_ecn, mask); MLX5_SET(fte_match_set_lyr_2_4, outer_c, ip_ecn, mask);
@ -1552,155 +1568,164 @@ static void set_tos(void *outer_c, void *outer_v, u8 mask, u8 val)
static int parse_flow_attr(u32 *match_c, u32 *match_v, static int parse_flow_attr(u32 *match_c, u32 *match_v,
const union ib_flow_spec *ib_spec) const union ib_flow_spec *ib_spec)
{ {
void *outer_headers_c = MLX5_ADDR_OF(fte_match_param, match_c,
outer_headers);
void *outer_headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
outer_headers);
void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c, void *misc_params_c = MLX5_ADDR_OF(fte_match_param, match_c,
misc_parameters); misc_parameters);
void *misc_params_v = MLX5_ADDR_OF(fte_match_param, match_v, void *misc_params_v = MLX5_ADDR_OF(fte_match_param, match_v,
misc_parameters); misc_parameters);
void *headers_c;
void *headers_v;
switch (ib_spec->type) { if (ib_spec->type & IB_FLOW_SPEC_INNER) {
headers_c = MLX5_ADDR_OF(fte_match_param, match_c,
inner_headers);
headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
inner_headers);
} else {
headers_c = MLX5_ADDR_OF(fte_match_param, match_c,
outer_headers);
headers_v = MLX5_ADDR_OF(fte_match_param, match_v,
outer_headers);
}
switch (ib_spec->type & ~IB_FLOW_SPEC_INNER) {
case IB_FLOW_SPEC_ETH: case IB_FLOW_SPEC_ETH:
if (FIELDS_NOT_SUPPORTED(ib_spec->eth.mask, LAST_ETH_FIELD)) if (FIELDS_NOT_SUPPORTED(ib_spec->eth.mask, LAST_ETH_FIELD))
return -ENOTSUPP; return -ENOTSUPP;
ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
dmac_47_16), dmac_47_16),
ib_spec->eth.mask.dst_mac); ib_spec->eth.mask.dst_mac);
ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
dmac_47_16), dmac_47_16),
ib_spec->eth.val.dst_mac); ib_spec->eth.val.dst_mac);
ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
smac_47_16), smac_47_16),
ib_spec->eth.mask.src_mac); ib_spec->eth.mask.src_mac);
ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, ether_addr_copy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
smac_47_16), smac_47_16),
ib_spec->eth.val.src_mac); ib_spec->eth.val.src_mac);
if (ib_spec->eth.mask.vlan_tag) { if (ib_spec->eth.mask.vlan_tag) {
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, MLX5_SET(fte_match_set_lyr_2_4, headers_c,
vlan_tag, 1); vlan_tag, 1);
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, MLX5_SET(fte_match_set_lyr_2_4, headers_v,
vlan_tag, 1); vlan_tag, 1);
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, MLX5_SET(fte_match_set_lyr_2_4, headers_c,
first_vid, ntohs(ib_spec->eth.mask.vlan_tag)); first_vid, ntohs(ib_spec->eth.mask.vlan_tag));
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, MLX5_SET(fte_match_set_lyr_2_4, headers_v,
first_vid, ntohs(ib_spec->eth.val.vlan_tag)); first_vid, ntohs(ib_spec->eth.val.vlan_tag));
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, MLX5_SET(fte_match_set_lyr_2_4, headers_c,
first_cfi, first_cfi,
ntohs(ib_spec->eth.mask.vlan_tag) >> 12); ntohs(ib_spec->eth.mask.vlan_tag) >> 12);
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, MLX5_SET(fte_match_set_lyr_2_4, headers_v,
first_cfi, first_cfi,
ntohs(ib_spec->eth.val.vlan_tag) >> 12); ntohs(ib_spec->eth.val.vlan_tag) >> 12);
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, MLX5_SET(fte_match_set_lyr_2_4, headers_c,
first_prio, first_prio,
ntohs(ib_spec->eth.mask.vlan_tag) >> 13); ntohs(ib_spec->eth.mask.vlan_tag) >> 13);
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, MLX5_SET(fte_match_set_lyr_2_4, headers_v,
first_prio, first_prio,
ntohs(ib_spec->eth.val.vlan_tag) >> 13); ntohs(ib_spec->eth.val.vlan_tag) >> 13);
} }
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, MLX5_SET(fte_match_set_lyr_2_4, headers_c,
ethertype, ntohs(ib_spec->eth.mask.ether_type)); ethertype, ntohs(ib_spec->eth.mask.ether_type));
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, MLX5_SET(fte_match_set_lyr_2_4, headers_v,
ethertype, ntohs(ib_spec->eth.val.ether_type)); ethertype, ntohs(ib_spec->eth.val.ether_type));
break; break;
case IB_FLOW_SPEC_IPV4: case IB_FLOW_SPEC_IPV4:
if (FIELDS_NOT_SUPPORTED(ib_spec->ipv4.mask, LAST_IPV4_FIELD)) if (FIELDS_NOT_SUPPORTED(ib_spec->ipv4.mask, LAST_IPV4_FIELD))
return -ENOTSUPP; return -ENOTSUPP;
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, MLX5_SET(fte_match_set_lyr_2_4, headers_c,
ethertype, 0xffff); ethertype, 0xffff);
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, MLX5_SET(fte_match_set_lyr_2_4, headers_v,
ethertype, ETH_P_IP); ethertype, ETH_P_IP);
memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
src_ipv4_src_ipv6.ipv4_layout.ipv4), src_ipv4_src_ipv6.ipv4_layout.ipv4),
&ib_spec->ipv4.mask.src_ip, &ib_spec->ipv4.mask.src_ip,
sizeof(ib_spec->ipv4.mask.src_ip)); sizeof(ib_spec->ipv4.mask.src_ip));
memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
src_ipv4_src_ipv6.ipv4_layout.ipv4), src_ipv4_src_ipv6.ipv4_layout.ipv4),
&ib_spec->ipv4.val.src_ip, &ib_spec->ipv4.val.src_ip,
sizeof(ib_spec->ipv4.val.src_ip)); sizeof(ib_spec->ipv4.val.src_ip));
memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
dst_ipv4_dst_ipv6.ipv4_layout.ipv4), dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
&ib_spec->ipv4.mask.dst_ip, &ib_spec->ipv4.mask.dst_ip,
sizeof(ib_spec->ipv4.mask.dst_ip)); sizeof(ib_spec->ipv4.mask.dst_ip));
memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
dst_ipv4_dst_ipv6.ipv4_layout.ipv4), dst_ipv4_dst_ipv6.ipv4_layout.ipv4),
&ib_spec->ipv4.val.dst_ip, &ib_spec->ipv4.val.dst_ip,
sizeof(ib_spec->ipv4.val.dst_ip)); sizeof(ib_spec->ipv4.val.dst_ip));
set_tos(outer_headers_c, outer_headers_v, set_tos(headers_c, headers_v,
ib_spec->ipv4.mask.tos, ib_spec->ipv4.val.tos); ib_spec->ipv4.mask.tos, ib_spec->ipv4.val.tos);
set_proto(outer_headers_c, outer_headers_v, set_proto(headers_c, headers_v,
ib_spec->ipv4.mask.proto, ib_spec->ipv4.val.proto); ib_spec->ipv4.mask.proto, ib_spec->ipv4.val.proto);
break; break;
case IB_FLOW_SPEC_IPV6: case IB_FLOW_SPEC_IPV6:
if (FIELDS_NOT_SUPPORTED(ib_spec->ipv6.mask, LAST_IPV6_FIELD)) if (FIELDS_NOT_SUPPORTED(ib_spec->ipv6.mask, LAST_IPV6_FIELD))
return -ENOTSUPP; return -ENOTSUPP;
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, MLX5_SET(fte_match_set_lyr_2_4, headers_c,
ethertype, 0xffff); ethertype, 0xffff);
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, MLX5_SET(fte_match_set_lyr_2_4, headers_v,
ethertype, ETH_P_IPV6); ethertype, ETH_P_IPV6);
memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
src_ipv4_src_ipv6.ipv6_layout.ipv6), src_ipv4_src_ipv6.ipv6_layout.ipv6),
&ib_spec->ipv6.mask.src_ip, &ib_spec->ipv6.mask.src_ip,
sizeof(ib_spec->ipv6.mask.src_ip)); sizeof(ib_spec->ipv6.mask.src_ip));
memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
src_ipv4_src_ipv6.ipv6_layout.ipv6), src_ipv4_src_ipv6.ipv6_layout.ipv6),
&ib_spec->ipv6.val.src_ip, &ib_spec->ipv6.val.src_ip,
sizeof(ib_spec->ipv6.val.src_ip)); sizeof(ib_spec->ipv6.val.src_ip));
memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_c,
dst_ipv4_dst_ipv6.ipv6_layout.ipv6), dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
&ib_spec->ipv6.mask.dst_ip, &ib_spec->ipv6.mask.dst_ip,
sizeof(ib_spec->ipv6.mask.dst_ip)); sizeof(ib_spec->ipv6.mask.dst_ip));
memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_v, memcpy(MLX5_ADDR_OF(fte_match_set_lyr_2_4, headers_v,
dst_ipv4_dst_ipv6.ipv6_layout.ipv6), dst_ipv4_dst_ipv6.ipv6_layout.ipv6),
&ib_spec->ipv6.val.dst_ip, &ib_spec->ipv6.val.dst_ip,
sizeof(ib_spec->ipv6.val.dst_ip)); sizeof(ib_spec->ipv6.val.dst_ip));
set_tos(outer_headers_c, outer_headers_v, set_tos(headers_c, headers_v,
ib_spec->ipv6.mask.traffic_class, ib_spec->ipv6.mask.traffic_class,
ib_spec->ipv6.val.traffic_class); ib_spec->ipv6.val.traffic_class);
set_proto(outer_headers_c, outer_headers_v, set_proto(headers_c, headers_v,
ib_spec->ipv6.mask.next_hdr, ib_spec->ipv6.mask.next_hdr,
ib_spec->ipv6.val.next_hdr); ib_spec->ipv6.val.next_hdr);
MLX5_SET(fte_match_set_misc, misc_params_c, set_flow_label(misc_params_c, misc_params_v,
outer_ipv6_flow_label, ntohl(ib_spec->ipv6.mask.flow_label),
ntohl(ib_spec->ipv6.mask.flow_label)); ntohl(ib_spec->ipv6.val.flow_label),
MLX5_SET(fte_match_set_misc, misc_params_v, ib_spec->type & IB_FLOW_SPEC_INNER);
outer_ipv6_flow_label,
ntohl(ib_spec->ipv6.val.flow_label));
break; break;
case IB_FLOW_SPEC_TCP: case IB_FLOW_SPEC_TCP:
if (FIELDS_NOT_SUPPORTED(ib_spec->tcp_udp.mask, if (FIELDS_NOT_SUPPORTED(ib_spec->tcp_udp.mask,
LAST_TCP_UDP_FIELD)) LAST_TCP_UDP_FIELD))
return -ENOTSUPP; return -ENOTSUPP;
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, ip_protocol, MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol,
0xff); 0xff);
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, ip_protocol, MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,
IPPROTO_TCP); IPPROTO_TCP);
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, tcp_sport, MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_sport,
ntohs(ib_spec->tcp_udp.mask.src_port)); ntohs(ib_spec->tcp_udp.mask.src_port));
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, tcp_sport, MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_sport,
ntohs(ib_spec->tcp_udp.val.src_port)); ntohs(ib_spec->tcp_udp.val.src_port));
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, tcp_dport, MLX5_SET(fte_match_set_lyr_2_4, headers_c, tcp_dport,
ntohs(ib_spec->tcp_udp.mask.dst_port)); ntohs(ib_spec->tcp_udp.mask.dst_port));
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, tcp_dport, MLX5_SET(fte_match_set_lyr_2_4, headers_v, tcp_dport,
ntohs(ib_spec->tcp_udp.val.dst_port)); ntohs(ib_spec->tcp_udp.val.dst_port));
break; break;
case IB_FLOW_SPEC_UDP: case IB_FLOW_SPEC_UDP:
@ -1708,19 +1733,19 @@ static int parse_flow_attr(u32 *match_c, u32 *match_v,
LAST_TCP_UDP_FIELD)) LAST_TCP_UDP_FIELD))
return -ENOTSUPP; return -ENOTSUPP;
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, ip_protocol, MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_protocol,
0xff); 0xff);
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, ip_protocol, MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_protocol,
IPPROTO_UDP); IPPROTO_UDP);
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, udp_sport, MLX5_SET(fte_match_set_lyr_2_4, headers_c, udp_sport,
ntohs(ib_spec->tcp_udp.mask.src_port)); ntohs(ib_spec->tcp_udp.mask.src_port));
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, udp_sport, MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_sport,
ntohs(ib_spec->tcp_udp.val.src_port)); ntohs(ib_spec->tcp_udp.val.src_port));
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_c, udp_dport, MLX5_SET(fte_match_set_lyr_2_4, headers_c, udp_dport,
ntohs(ib_spec->tcp_udp.mask.dst_port)); ntohs(ib_spec->tcp_udp.mask.dst_port));
MLX5_SET(fte_match_set_lyr_2_4, outer_headers_v, udp_dport, MLX5_SET(fte_match_set_lyr_2_4, headers_v, udp_dport,
ntohs(ib_spec->tcp_udp.val.dst_port)); ntohs(ib_spec->tcp_udp.val.dst_port));
break; break;
case IB_FLOW_SPEC_VXLAN_TUNNEL: case IB_FLOW_SPEC_VXLAN_TUNNEL: