]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: atlantic: correct L3L4 filter flow_type masking and IPv6 handling
authorSukhdeep Singh <sukhdeeps@marvell.com>
Wed, 10 Jun 2026 11:54:37 +0000 (17:24 +0530)
committerJakub Kicinski <kuba@kernel.org>
Mon, 15 Jun 2026 22:38:42 +0000 (15:38 -0700)
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>
drivers/net/ethernet/aquantia/atlantic/aq_filters.c

index e419c73b32ce54b6c8794efc17ee8520a9d7485d..eef52f23166dd8ab9218483d78b75e7e809e2680 100644 (file)
@@ -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;