Currently, `ixgbe_parse_fdir_filter_normal()` checks the MAC type before
checking whether the `RTE_FLOW_ITEM_TYPE_SCTP` item carries a mask. On
`ixgbe_mac_X550`, `ixgbe_mac_X550EM_x`, `ixgbe_mac_X550EM_a` and
`ixgbe_mac_E610`, this makes `item->mask` mandatory and rejects
protocol-only SCTP patterns.

These devices can still match SCTP by protocol without L4 port masks.
Only SCTP port masking is MAC type dependent, but the current check order
makes the protocol-only path available only on older MAC types.

Fix this by checking whether a mask is present first. Keep the MAC type
check only for SCTP port masks, and accept protocol-only SCTP matching on
X550 and E610 as well.

Fixes: 86e19565f5e2 ("net/ixgbe: fix SCTP port support")
Cc: [email protected]
Cc: [email protected]

Signed-off-by: Anatoly Burakov <[email protected]>
---
 drivers/net/intel/ixgbe/ixgbe_flow.c | 86 ++++++++++++++--------------
 1 file changed, 42 insertions(+), 44 deletions(-)

diff --git a/drivers/net/intel/ixgbe/ixgbe_flow.c 
b/drivers/net/intel/ixgbe/ixgbe_flow.c
index c3abba4a90..71da5ac72e 100644
--- a/drivers/net/intel/ixgbe/ixgbe_flow.c
+++ b/drivers/net/intel/ixgbe/ixgbe_flow.c
@@ -2180,57 +2180,55 @@ ixgbe_parse_fdir_filter_normal(struct rte_eth_dev *dev,
                        return -rte_errno;
                }
 
-               /* only some mac types support sctp port */
-               if (hw->mac.type == ixgbe_mac_X550 ||
-                   hw->mac.type == ixgbe_mac_X550EM_x ||
-                   hw->mac.type == ixgbe_mac_X550EM_a ||
-                   hw->mac.type == ixgbe_mac_E610) {
-                       /**
-                        * Only care about src & dst ports,
-                        * others should be masked.
-                        */
-                       if (!item->mask) {
-                               memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
-                               rte_flow_error_set(error, EINVAL,
-                                       RTE_FLOW_ERROR_TYPE_ITEM,
-                                       item, "Not supported by fdir filter");
-                               return -rte_errno;
-                       }
-                       rule->b_mask = TRUE;
-                       sctp_mask = item->mask;
-                       if (sctp_mask->hdr.tag ||
-                               sctp_mask->hdr.cksum) {
-                               memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
-                               rte_flow_error_set(error, EINVAL,
-                                       RTE_FLOW_ERROR_TYPE_ITEM,
-                                       item, "Not supported by fdir filter");
-                               return -rte_errno;
-                       }
-                       rule->mask.src_port_mask = sctp_mask->hdr.src_port;
-                       rule->mask.dst_port_mask = sctp_mask->hdr.dst_port;
+               sctp_mask = item->mask;
+               if (sctp_mask != NULL) {
+                       /* only some mac types support sctp port masking */
+                       if (hw->mac.type == ixgbe_mac_X550 ||
+                           hw->mac.type == ixgbe_mac_X550EM_x ||
+                           hw->mac.type == ixgbe_mac_X550EM_a ||
+                           hw->mac.type == ixgbe_mac_E610) {
+                               /**
+                                * Only care about src & dst ports,
+                                * others should be masked.
+                                */
+                               rule->b_mask = TRUE;
+                               if (sctp_mask->hdr.tag ||
+                                   sctp_mask->hdr.cksum) {
+                                       memset(rule, 0, sizeof(struct 
ixgbe_fdir_rule));
+                                       rte_flow_error_set(error, EINVAL,
+                                               RTE_FLOW_ERROR_TYPE_ITEM,
+                                               item, "Not supported by fdir 
filter");
+                                       return -rte_errno;
+                               }
+                               rule->mask.src_port_mask = 
sctp_mask->hdr.src_port;
+                               rule->mask.dst_port_mask = 
sctp_mask->hdr.dst_port;
 
-                       if (item->spec) {
-                               rule->b_spec = TRUE;
-                               sctp_spec = item->spec;
-                               rule->ixgbe_fdir.formatted.src_port =
-                                       sctp_spec->hdr.src_port;
-                               rule->ixgbe_fdir.formatted.dst_port =
-                                       sctp_spec->hdr.dst_port;
-                       }
-               /* others even sctp port is not supported */
-               } else {
-                       sctp_mask = item->mask;
-                       if (sctp_mask &&
-                               (sctp_mask->hdr.src_port ||
-                                sctp_mask->hdr.dst_port ||
-                                sctp_mask->hdr.tag ||
-                                sctp_mask->hdr.cksum)) {
+                               if (item->spec) {
+                                       rule->b_spec = TRUE;
+                                       sctp_spec = item->spec;
+                                       rule->ixgbe_fdir.formatted.src_port =
+                                               sctp_spec->hdr.src_port;
+                                       rule->ixgbe_fdir.formatted.dst_port =
+                                               sctp_spec->hdr.dst_port;
+                               }
+                       /* others even sctp port masking is not supported */
+                       } else if (sctp_mask->hdr.src_port ||
+                                  sctp_mask->hdr.dst_port ||
+                                  sctp_mask->hdr.tag ||
+                                  sctp_mask->hdr.cksum) {
                                memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
                                rte_flow_error_set(error, EINVAL,
                                        RTE_FLOW_ERROR_TYPE_ITEM,
                                        item, "Not supported by fdir filter");
                                return -rte_errno;
                        }
+               } else if (item->spec != NULL) {
+                       /* No port mask means protocol-only match; spec is 
invalid. */
+                       memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
+                       rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ITEM,
+                               item, "Not supported by fdir filter");
+                       return -rte_errno;
                }
 
                item = next_no_fuzzy_pattern(pattern, item);
-- 
2.47.3

Reply via email to