mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-04 01:20:01 -04:00
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 <vdogaru@nvidia.com> Reviewed-by: Yevgeny Kliteynik <kliteyn@nvidia.com> Signed-off-by: Mark Bloch <mbloch@nvidia.com> Link: https://patch.msgid.link/20250422092540.182091-3-mbloch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
5f2f8d8b68
commit
6991a975e4
@@ -509,9 +509,9 @@ static int
|
||||
hws_definer_conv_outer(struct mlx5hws_definer_conv_data *cd,
|
||||
u32 *match_param)
|
||||
{
|
||||
bool is_ipv6, smac_set, dmac_set, ip_addr_set, ip_ver_set;
|
||||
struct mlx5hws_definer_fc *fc = cd->fc;
|
||||
struct mlx5hws_definer_fc *curr_fc;
|
||||
bool is_ipv6, smac_set, dmac_set;
|
||||
u32 *s_ipv6, *d_ipv6;
|
||||
|
||||
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,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ip_addr_set = HWS_IS_FLD_SET_SZ(match_param,
|
||||
outer_headers.src_ipv4_src_ipv6,
|
||||
0x80) ||
|
||||
HWS_IS_FLD_SET_SZ(match_param,
|
||||
outer_headers.dst_ipv4_dst_ipv6, 0x80);
|
||||
ip_ver_set = HWS_IS_FLD_SET(match_param, outer_headers.ip_version) ||
|
||||
HWS_IS_FLD_SET(match_param, outer_headers.ethertype);
|
||||
|
||||
if (ip_addr_set && !ip_ver_set) {
|
||||
mlx5hws_err(cd->ctx,
|
||||
"Unsupported match on IP address without version or ethertype\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* L2 Check ethertype */
|
||||
HWS_SET_HDR(fc, match_param, ETH_TYPE_O,
|
||||
outer_headers.ethertype,
|
||||
@@ -573,6 +587,12 @@ hws_definer_conv_outer(struct mlx5hws_definer_conv_data *cd,
|
||||
is_ipv6 = s_ipv6[0] || s_ipv6[1] || s_ipv6[2] ||
|
||||
d_ipv6[0] || d_ipv6[1] || d_ipv6[2];
|
||||
|
||||
/* IHL is an IPv4-specific field. */
|
||||
if (is_ipv6 && HWS_IS_FLD_SET(match_param, outer_headers.ipv4_ihl)) {
|
||||
mlx5hws_err(cd->ctx, "Unsupported match on IPv6 address and IPv4 IHL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (is_ipv6) {
|
||||
/* Handle IPv6 source address */
|
||||
HWS_SET_HDR(fc, match_param, IPV6_SRC_127_96_O,
|
||||
@@ -662,9 +682,9 @@ static int
|
||||
hws_definer_conv_inner(struct mlx5hws_definer_conv_data *cd,
|
||||
u32 *match_param)
|
||||
{
|
||||
bool is_ipv6, smac_set, dmac_set, ip_addr_set, ip_ver_set;
|
||||
struct mlx5hws_definer_fc *fc = cd->fc;
|
||||
struct mlx5hws_definer_fc *curr_fc;
|
||||
bool is_ipv6, smac_set, dmac_set;
|
||||
u32 *s_ipv6, *d_ipv6;
|
||||
|
||||
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,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ip_addr_set = HWS_IS_FLD_SET_SZ(match_param,
|
||||
inner_headers.src_ipv4_src_ipv6,
|
||||
0x80) ||
|
||||
HWS_IS_FLD_SET_SZ(match_param,
|
||||
inner_headers.dst_ipv4_dst_ipv6, 0x80);
|
||||
ip_ver_set = HWS_IS_FLD_SET(match_param, inner_headers.ip_version) ||
|
||||
HWS_IS_FLD_SET(match_param, inner_headers.ethertype);
|
||||
|
||||
if (ip_addr_set && !ip_ver_set) {
|
||||
mlx5hws_err(cd->ctx,
|
||||
"Unsupported match on IP address without version or ethertype\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* L2 Check ethertype */
|
||||
HWS_SET_HDR(fc, match_param, ETH_TYPE_I,
|
||||
inner_headers.ethertype,
|
||||
@@ -728,6 +762,12 @@ hws_definer_conv_inner(struct mlx5hws_definer_conv_data *cd,
|
||||
is_ipv6 = s_ipv6[0] || s_ipv6[1] || s_ipv6[2] ||
|
||||
d_ipv6[0] || d_ipv6[1] || d_ipv6[2];
|
||||
|
||||
/* IHL is an IPv4-specific field. */
|
||||
if (is_ipv6 && HWS_IS_FLD_SET(match_param, inner_headers.ipv4_ihl)) {
|
||||
mlx5hws_err(cd->ctx, "Unsupported match on IPv6 address and IPv4 IHL\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (is_ipv6) {
|
||||
/* Handle IPv6 source address */
|
||||
HWS_SET_HDR(fc, match_param, IPV6_SRC_127_96_I,
|
||||
|
||||
Reference in New Issue
Block a user