diff options
| author | Sukhdeep Singh <sukhdeeps@marvell.com> | 2026-06-10 17:24:37 +0530 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-06-15 15:38:42 -0700 |
| commit | 9ed479cd9fd38f1e71da2eaff6fd949a765ac2ae (patch) | |
| tree | 0b75fbdf1f75bb1308d998fc1bd814e249d2ee61 | |
| parent | f34c6b3a3c3d98f34918e1d2ea846a5acccac6d1 (diff) | |
net: atlantic: correct L3L4 filter flow_type masking and IPv6 handling
Correct three issues in aq_set_data_fl3l4() required for the AQC113
PTP filter path introduced later in this series:
1. Mask FLOW_EXT from flow_type before the protocol switch statement.
Flow types with FLOW_EXT set (e.g. TCP_V4_FLOW | FLOW_EXT) fall
through to the default case and skip protocol comparison flags.
2. Extend the L3 address comparison check to cover all four IPv6
words. The original code only checked ip_src[0]/ip_dst[0] and
required !is_ipv6, so CMP_SRC_ADDR_L3/CMP_DEST_ADDR_L3 were never
set for IPv6 filters.
3. Use explicit flow type checks for port extraction instead of
negating IP_USER_FLOW/IPV6_USER_FLOW. The old check did not mask
FLOW_EXT, so IP_USER_FLOW | FLOW_EXT would incorrectly attempt
port extraction. Use the actual flow type to pick the correct
union member directly.
Signed-off-by: Sukhdeep Singh <sukhdeeps@marvell.com>
Link: https://patch.msgid.link/20260610115448.272-2-sukhdeeps@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/ethernet/aquantia/atlantic/aq_filters.c | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c index e419c73b32ce..eef52f23166d 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c @@ -472,6 +472,7 @@ static int aq_set_data_fl3l4(struct aq_nic_s *aq_nic, { struct aq_hw_rx_fltrs_s *rx_fltrs = aq_get_hw_rx_fltrs(aq_nic); const struct ethtool_rx_flow_spec *fsp = &aq_rx_fltr->aq_fsp; + u32 flow = fsp->flow_type & ~FLOW_EXT; memset(data, 0, sizeof(*data)); @@ -490,7 +491,7 @@ static int aq_set_data_fl3l4(struct aq_nic_s *aq_nic, data->cmd |= HW_ATL_RX_ENABLE_FLTR_L3L4; - switch (fsp->flow_type) { + switch (flow) { case TCP_V4_FLOW: case TCP_V6_FLOW: data->cmd |= HW_ATL_RX_ENABLE_CMP_PROT_L4; @@ -527,23 +528,23 @@ static int aq_set_data_fl3l4(struct aq_nic_s *aq_nic, } data->cmd |= HW_ATL_RX_ENABLE_L3_IPV6; } - if (fsp->flow_type != IP_USER_FLOW && - fsp->flow_type != IPV6_USER_FLOW) { - if (!data->is_ipv6) { - data->p_dst = - ntohs(fsp->h_u.tcp_ip4_spec.pdst); - data->p_src = - ntohs(fsp->h_u.tcp_ip4_spec.psrc); - } else { - data->p_dst = - ntohs(fsp->h_u.tcp_ip6_spec.pdst); - data->p_src = - ntohs(fsp->h_u.tcp_ip6_spec.psrc); - } + if (flow == TCP_V4_FLOW || flow == UDP_V4_FLOW || + flow == SCTP_V4_FLOW) { + data->p_dst = ntohs(fsp->h_u.tcp_ip4_spec.pdst); + data->p_src = ntohs(fsp->h_u.tcp_ip4_spec.psrc); + } + if (flow == TCP_V6_FLOW || flow == UDP_V6_FLOW || + flow == SCTP_V6_FLOW) { + data->p_dst = ntohs(fsp->h_u.tcp_ip6_spec.pdst); + data->p_src = ntohs(fsp->h_u.tcp_ip6_spec.psrc); } - if (data->ip_src[0] && !data->is_ipv6) + if (data->ip_src[0] || + (data->is_ipv6 && (data->ip_src[1] || data->ip_src[2] || + data->ip_src[3]))) data->cmd |= HW_ATL_RX_ENABLE_CMP_SRC_ADDR_L3; - if (data->ip_dst[0] && !data->is_ipv6) + if (data->ip_dst[0] || + (data->is_ipv6 && (data->ip_dst[1] || data->ip_dst[2] || + data->ip_dst[3]))) data->cmd |= HW_ATL_RX_ENABLE_CMP_DEST_ADDR_L3; if (data->p_dst) data->cmd |= HW_ATL_RX_ENABLE_CMP_DEST_PORT_L4; |
