Skip to content

Commit 6991a97

Browse files
ddvladkuba-moo
authored andcommitted
net/mlx5: HWS, Harden IP version definer checks
Replicate some sanity checks that firmware does, since hardware steering does not go through firmware. When creating a definer, disallow matching on IP addresses without also matching on IP version. The latter can be satisfied by matching either on the version field in the IP header, or on the ethertype field. Also refuse to match IPv4 IHL alongside IPv6. Signed-off-by: Vlad Dogaru <[email protected]> Reviewed-by: Yevgeny Kliteynik <[email protected]> Signed-off-by: Mark Bloch <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 5f2f8d8 commit 6991a97

File tree

1 file changed

+42
-2
lines changed
  • drivers/net/ethernet/mellanox/mlx5/core/steering/hws

1 file changed

+42
-2
lines changed

drivers/net/ethernet/mellanox/mlx5/core/steering/hws/definer.c

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,9 +509,9 @@ static int
509509
hws_definer_conv_outer(struct mlx5hws_definer_conv_data *cd,
510510
u32 *match_param)
511511
{
512+
bool is_ipv6, smac_set, dmac_set, ip_addr_set, ip_ver_set;
512513
struct mlx5hws_definer_fc *fc = cd->fc;
513514
struct mlx5hws_definer_fc *curr_fc;
514-
bool is_ipv6, smac_set, dmac_set;
515515
u32 *s_ipv6, *d_ipv6;
516516

517517
if (HWS_IS_FLD_SET_SZ(match_param, outer_headers.l4_type, 0x2) ||
@@ -521,6 +521,20 @@ hws_definer_conv_outer(struct mlx5hws_definer_conv_data *cd,
521521
return -EINVAL;
522522
}
523523

524+
ip_addr_set = HWS_IS_FLD_SET_SZ(match_param,
525+
outer_headers.src_ipv4_src_ipv6,
526+
0x80) ||
527+
HWS_IS_FLD_SET_SZ(match_param,
528+
outer_headers.dst_ipv4_dst_ipv6, 0x80);
529+
ip_ver_set = HWS_IS_FLD_SET(match_param, outer_headers.ip_version) ||
530+
HWS_IS_FLD_SET(match_param, outer_headers.ethertype);
531+
532+
if (ip_addr_set && !ip_ver_set) {
533+
mlx5hws_err(cd->ctx,
534+
"Unsupported match on IP address without version or ethertype\n");
535+
return -EINVAL;
536+
}
537+
524538
/* L2 Check ethertype */
525539
HWS_SET_HDR(fc, match_param, ETH_TYPE_O,
526540
outer_headers.ethertype,
@@ -573,6 +587,12 @@ hws_definer_conv_outer(struct mlx5hws_definer_conv_data *cd,
573587
is_ipv6 = s_ipv6[0] || s_ipv6[1] || s_ipv6[2] ||
574588
d_ipv6[0] || d_ipv6[1] || d_ipv6[2];
575589

590+
/* IHL is an IPv4-specific field. */
591+
if (is_ipv6 && HWS_IS_FLD_SET(match_param, outer_headers.ipv4_ihl)) {
592+
mlx5hws_err(cd->ctx, "Unsupported match on IPv6 address and IPv4 IHL\n");
593+
return -EINVAL;
594+
}
595+
576596
if (is_ipv6) {
577597
/* Handle IPv6 source address */
578598
HWS_SET_HDR(fc, match_param, IPV6_SRC_127_96_O,
@@ -662,9 +682,9 @@ static int
662682
hws_definer_conv_inner(struct mlx5hws_definer_conv_data *cd,
663683
u32 *match_param)
664684
{
685+
bool is_ipv6, smac_set, dmac_set, ip_addr_set, ip_ver_set;
665686
struct mlx5hws_definer_fc *fc = cd->fc;
666687
struct mlx5hws_definer_fc *curr_fc;
667-
bool is_ipv6, smac_set, dmac_set;
668688
u32 *s_ipv6, *d_ipv6;
669689

670690
if (HWS_IS_FLD_SET_SZ(match_param, inner_headers.l4_type, 0x2) ||
@@ -674,6 +694,20 @@ hws_definer_conv_inner(struct mlx5hws_definer_conv_data *cd,
674694
return -EINVAL;
675695
}
676696

697+
ip_addr_set = HWS_IS_FLD_SET_SZ(match_param,
698+
inner_headers.src_ipv4_src_ipv6,
699+
0x80) ||
700+
HWS_IS_FLD_SET_SZ(match_param,
701+
inner_headers.dst_ipv4_dst_ipv6, 0x80);
702+
ip_ver_set = HWS_IS_FLD_SET(match_param, inner_headers.ip_version) ||
703+
HWS_IS_FLD_SET(match_param, inner_headers.ethertype);
704+
705+
if (ip_addr_set && !ip_ver_set) {
706+
mlx5hws_err(cd->ctx,
707+
"Unsupported match on IP address without version or ethertype\n");
708+
return -EINVAL;
709+
}
710+
677711
/* L2 Check ethertype */
678712
HWS_SET_HDR(fc, match_param, ETH_TYPE_I,
679713
inner_headers.ethertype,
@@ -728,6 +762,12 @@ hws_definer_conv_inner(struct mlx5hws_definer_conv_data *cd,
728762
is_ipv6 = s_ipv6[0] || s_ipv6[1] || s_ipv6[2] ||
729763
d_ipv6[0] || d_ipv6[1] || d_ipv6[2];
730764

765+
/* IHL is an IPv4-specific field. */
766+
if (is_ipv6 && HWS_IS_FLD_SET(match_param, inner_headers.ipv4_ihl)) {
767+
mlx5hws_err(cd->ctx, "Unsupported match on IPv6 address and IPv4 IHL\n");
768+
return -EINVAL;
769+
}
770+
731771
if (is_ipv6) {
732772
/* Handle IPv6 source address */
733773
HWS_SET_HDR(fc, match_param, IPV6_SRC_127_96_I,

0 commit comments

Comments
 (0)