Skip to contentSkip to conversation

mlxsw: Add port range matching support

PATCH Applied Petr Machata 3 participants 13 messages Jul 11, 2023 – Jul 15, 2023

Subsystems (5)
lore
Share & tools
lore

Petr Machata

author maintainer
#0 lore raw

cover mlxsw: Add port range matching support

Ido Schimmel writes:

Add port range matching support in mlxsw as part of tc-flower offload.

Patches #1-#7 gradually add port range matching support in mlxsw. See patch #3 to understand how port range matching is implemented in the device.

Patches #8-#10 add selftests.

Ido Schimmel (10):
mlxsw: reg: Add Policy-Engine Port Range Register
mlxsw: resource: Add resource identifier for port range registers
mlxsw: spectrum_port_range: Add port range core
mlxsw: spectrum_port_range: Add devlink resource support
mlxsw: spectrum_acl: Add port range key element
mlxsw: spectrum_acl: Pass main driver structure to
mlxsw_sp_acl_rulei_destroy()
mlxsw: spectrum_flower: Add ability to match on port ranges
selftests: mlxsw: Add scale test for port ranges
selftests: mlxsw: Test port range registers' occupancy
selftests: forwarding: Add test cases for flower port range matching

 drivers/net/ethernet/mellanox/mlxsw/Makefile  |   2 +-
 .../mellanox/mlxsw/core_acl_flex_keys.c       |   1 +
 .../mellanox/mlxsw/core_acl_flex_keys.h       |   1 +
 drivers/net/ethernet/mellanox/mlxsw/reg.h     |  73 ++++++
 .../net/ethernet/mellanox/mlxsw/resources.h   |   2 +
 .../net/ethernet/mellanox/mlxsw/spectrum.c    |  39 +++
 .../net/ethernet/mellanox/mlxsw/spectrum.h    |  25 +-
 .../mellanox/mlxsw/spectrum1_acl_tcam.c       |   4 +-
 .../ethernet/mellanox/mlxsw/spectrum_acl.c    |  11 +-
 .../mellanox/mlxsw/spectrum_acl_flex_keys.c   |   3 +
 .../ethernet/mellanox/mlxsw/spectrum_flower.c |  68 ++++++
 .../mellanox/mlxsw/spectrum_port_range.c      | 200 +++++++++++++++
 .../drivers/net/mlxsw/port_range_occ.sh       | 111 +++++++++
 .../drivers/net/mlxsw/port_range_scale.sh     |  95 ++++++++
 .../net/mlxsw/spectrum-2/port_range_scale.sh  |   1 +
 .../net/mlxsw/spectrum-2/resource_scale.sh    |   1 +
 .../net/mlxsw/spectrum/port_range_scale.sh    |  16 ++
 .../net/mlxsw/spectrum/resource_scale.sh      |   1 +
 .../testing/selftests/net/forwarding/Makefile |   1 +
 .../net/forwarding/tc_flower_port_range.sh    | 228 ++++++++++++++++++
 20 files changed, 876 insertions(+), 7 deletions(-)
 create mode 100644 drivers/net/ethernet/mellanox/mlxsw/spectrum_port_range.c
 create mode 100755 tools/testing/selftests/drivers/net/mlxsw/port_range_occ.sh
 create mode 100644 tools/testing/selftests/drivers/net/mlxsw/port_range_scale.sh
 create mode 120000 tools/testing/selftests/drivers/net/mlxsw/spectrum-2/port_range_scale.sh
 create mode 100644 tools/testing/selftests/drivers/net/mlxsw/spectrum/port_range_scale.sh
 create mode 100755 tools/testing/selftests/net/forwarding/tc_flower_port_range.sh
Signature · 1 line
2.40.1
author maintainer
#1 lore raw

PATCH 1/10 mlxsw: reg: Add Policy-Engine Port Range Register

From: Ido Schimmel <[email protected]>

Add the Policy-Engine Port Range Register that is used for configuring port range identification.

---
 drivers/net/ethernet/mellanox/mlxsw/reg.h | 73 +++++++++++++++++++++++
 1 file changed, 73 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/reg.h +73 -0
index 17160e867bef..0802ef964d78 100644
@@ -2790,6 +2790,78 @@ static inline void mlxsw_reg_ptar_unpack(char *payload, char *tcam_region_info)
 	mlxsw_reg_ptar_tcam_region_info_memcpy_from(payload, tcam_region_info);
 }
 
+/* PPRR - Policy-Engine Port Range Register
+ * ----------------------------------------
+ * This register is used for configuring port range identification.
+ */
+#define MLXSW_REG_PPRR_ID 0x3008
+#define MLXSW_REG_PPRR_LEN 0x14
+
+MLXSW_REG_DEFINE(pprr, MLXSW_REG_PPRR_ID, MLXSW_REG_PPRR_LEN);
+
+/* reg_pprr_ipv4
+ * Apply port range register to IPv4 packets.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, pprr, ipv4, 0x00, 31, 1);
+
+/* reg_pprr_ipv6
+ * Apply port range register to IPv6 packets.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, pprr, ipv6, 0x00, 30, 1);
+
+/* reg_pprr_src
+ * Apply port range register to source L4 ports.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, pprr, src, 0x00, 29, 1);
+
+/* reg_pprr_dst
+ * Apply port range register to destination L4 ports.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, pprr, dst, 0x00, 28, 1);
+
+/* reg_pprr_tcp
+ * Apply port range register to TCP packets.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, pprr, tcp, 0x00, 27, 1);
+
+/* reg_pprr_udp
+ * Apply port range register to UDP packets.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, pprr, udp, 0x00, 26, 1);
+
+/* reg_pprr_register_index
+ * Index of Port Range Register being accessed.
+ * Range is 0..cap_max_acl_l4_port_range-1.
+ * Access: Index
+ */
+MLXSW_ITEM32(reg, pprr, register_index, 0x00, 0, 8);
+
+/* reg_prrr_port_range_min
+ * Minimum port range for comparison.
+ * Match is defined as:
+ * port_range_min <= packet_port <= port_range_max.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, pprr, port_range_min, 0x04, 16, 16);
+
+/* reg_prrr_port_range_max
+ * Maximum port range for comparison.
+ * Access: RW
+ */
+MLXSW_ITEM32(reg, pprr, port_range_max, 0x04, 0, 16);
+
+static inline void mlxsw_reg_pprr_pack(char *payload, u8 register_index)
+{
+	MLXSW_REG_ZERO(pprr, payload);
+	mlxsw_reg_pprr_register_index_set(payload, register_index);
+}
+
 /* PPBS - Policy-Engine Policy Based Switching Register
  * ----------------------------------------------------
  * This register retrieves and sets Policy Based Switching Table entries.
@@ -12810,6 +12882,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
 	MLXSW_REG(pacl),
 	MLXSW_REG(pagt),
 	MLXSW_REG(ptar),
+	MLXSW_REG(pprr),
 	MLXSW_REG(ppbs),
 	MLXSW_REG(prcr),
 	MLXSW_REG(pefa),
Signature · 1 line
2.40.1
author maintainer
#2 lore raw

PATCH 2/10 mlxsw: resource: Add resource identifier for port range registers

In reply to Petr Machata

From: Ido Schimmel <[email protected]>

Add a resource identifier for maximum number of layer 4 port range register so that it could be later used to query the information from firmware.

---
 drivers/net/ethernet/mellanox/mlxsw/resources.h | 2 ++
 1 file changed, 2 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/resources.h +2 -0
index 19ae0d1c74a8..89dd2777ec4d 100644
@@ -39,6 +39,7 @@ enum mlxsw_res_id {
 	MLXSW_RES_ID_ACL_FLEX_KEYS,
 	MLXSW_RES_ID_ACL_MAX_ACTION_PER_RULE,
 	MLXSW_RES_ID_ACL_ACTIONS_PER_SET,
+	MLXSW_RES_ID_ACL_MAX_L4_PORT_RANGE,
 	MLXSW_RES_ID_ACL_MAX_ERPT_BANKS,
 	MLXSW_RES_ID_ACL_MAX_ERPT_BANK_SIZE,
 	MLXSW_RES_ID_ACL_MAX_LARGE_KEY_ID,
@@ -99,6 +100,7 @@ static u16 mlxsw_res_ids[] = {
 	[MLXSW_RES_ID_ACL_FLEX_KEYS] = 0x2910,
 	[MLXSW_RES_ID_ACL_MAX_ACTION_PER_RULE] = 0x2911,
 	[MLXSW_RES_ID_ACL_ACTIONS_PER_SET] = 0x2912,
+	[MLXSW_RES_ID_ACL_MAX_L4_PORT_RANGE] = 0x2920,
 	[MLXSW_RES_ID_ACL_MAX_ERPT_BANKS] = 0x2940,
 	[MLXSW_RES_ID_ACL_MAX_ERPT_BANK_SIZE] = 0x2941,
 	[MLXSW_RES_ID_ACL_MAX_LARGE_KEY_ID] = 0x2942,
Signature · 1 line
2.40.1
author maintainer
#3 lore raw

PATCH 3/10 mlxsw: spectrum_port_range: Add port range core

In reply to Petr Machata

From: Ido Schimmel <[email protected]>

The Spectrum ASICs have a fixed number of port range registers, each of which maintains the following parameters:

* Minimum and maximum port.
* Apply port range for source port, destination port or both.
* Apply port range for TCP, UDP or both.
* Apply port range for IPv4, IPv6 or both.

Implement a port range core which takes care of the allocation and configuration of these registers and exposes an API that allows in-driver consumers (e.g., the ACL code) to request matching on a range of either source or destination port.

These registers are going to be used for port range matching in the flower classifier that already matches on EtherType being IPv4 / IPv6 and IP protocol being TCP / UDP. As such, there is no need to limit these registers to a specific EtherType or IP protocol, which will increase the likelihood of a register being shared by multiple flower filters.

It is unlikely that a filter will match on the same range of both source and destination ports, which is why each register is only configured to match on either source or destination port. If a filter requires matching on a range of both source and destination ports, it will utilize two port range registers and match on the output of both.

For efficient lookup and traversal, use XArray to store the allocated port range registers. The XArray uses RCU and an internal spinlock to synchronise access, so there is no need for a dedicate lock.

---
 drivers/net/ethernet/mellanox/mlxsw/Makefile  |   2 +-
 .../net/ethernet/mellanox/mlxsw/spectrum.c    |   9 +
 .../net/ethernet/mellanox/mlxsw/spectrum.h    |  15 ++
 .../mellanox/mlxsw/spectrum_port_range.c      | 181 ++++++++++++++++++
 4 files changed, 206 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/ethernet/mellanox/mlxsw/spectrum_port_range.c
drivers/net/ethernet/mellanox/mlxsw/Makefile +1 -1
index 3ca9fce759ea..71cad6bb6e62 100644
@@ -29,7 +29,7 @@ mlxsw_spectrum-objs		:= spectrum.o spectrum_buffers.o \
 				   spectrum_nve.o spectrum_nve_vxlan.o \
 				   spectrum_dpipe.o spectrum_trap.o \
 				   spectrum_ethtool.o spectrum_policer.o \
-				   spectrum_pgt.o
+				   spectrum_pgt.o spectrum_port_range.o
 mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB)	+= spectrum_dcb.o
 mlxsw_spectrum-$(CONFIG_PTP_1588_CLOCK)		+= spectrum_ptp.o
 obj-$(CONFIG_MLXSW_MINIMAL)	+= mlxsw_minimal.o
drivers/net/ethernet/mellanox/mlxsw/spectrum.c +9 -0
index 25a01dafde1b..c0edcc91f178 100644
@@ -3188,6 +3188,12 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
 		goto err_nve_init;
 	}
 
+	err = mlxsw_sp_port_range_init(mlxsw_sp);
+	if (err) {
+		dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize port ranges\n");
+		goto err_port_range_init;
+	}
+
 	err = mlxsw_sp_acl_init(mlxsw_sp);
 	if (err) {
 		dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize ACL\n");
@@ -3280,6 +3286,8 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
 err_router_init:
 	mlxsw_sp_acl_fini(mlxsw_sp);
 err_acl_init:
+	mlxsw_sp_port_range_fini(mlxsw_sp);
+err_port_range_init:
 	mlxsw_sp_nve_fini(mlxsw_sp);
 err_nve_init:
 	mlxsw_sp_ipv6_addr_ht_fini(mlxsw_sp);
@@ -3462,6 +3470,7 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
 	}
 	mlxsw_sp_router_fini(mlxsw_sp);
 	mlxsw_sp_acl_fini(mlxsw_sp);
+	mlxsw_sp_port_range_fini(mlxsw_sp);
 	mlxsw_sp_nve_fini(mlxsw_sp);
 	mlxsw_sp_ipv6_addr_ht_fini(mlxsw_sp);
 	mlxsw_sp_afa_fini(mlxsw_sp);
drivers/net/ethernet/mellanox/mlxsw/spectrum.h +15 -0
index 231e364cbb7c..fe6c6e02a484 100644
@@ -175,6 +175,7 @@ struct mlxsw_sp {
 	struct mlxsw_sp_acl *acl;
 	struct mlxsw_sp_fid_core *fid_core;
 	struct mlxsw_sp_policer_core *policer_core;
+	struct mlxsw_sp_port_range_core *pr_core;
 	struct mlxsw_sp_kvdl *kvdl;
 	struct mlxsw_sp_nve *nve;
 	struct notifier_block netdevice_nb;
@@ -1484,4 +1485,18 @@ int mlxsw_sp_pgt_entry_port_set(struct mlxsw_sp *mlxsw_sp, u16 mid,
 int mlxsw_sp_pgt_init(struct mlxsw_sp *mlxsw_sp);
 void mlxsw_sp_pgt_fini(struct mlxsw_sp *mlxsw_sp);
 
+/* spectrum_port_range.c */
+struct mlxsw_sp_port_range {
+	u16 min;
+	u16 max;
+	u8 source:1;	/* Source or destination */
+};
+
+int mlxsw_sp_port_range_reg_get(struct mlxsw_sp *mlxsw_sp,
+				const struct mlxsw_sp_port_range *range,
+				struct netlink_ext_ack *extack,
+				u8 *p_prr_index);
+void mlxsw_sp_port_range_reg_put(struct mlxsw_sp *mlxsw_sp, u8 prr_index);
+int mlxsw_sp_port_range_init(struct mlxsw_sp *mlxsw_sp);
+void mlxsw_sp_port_range_fini(struct mlxsw_sp *mlxsw_sp);
 #endif
drivers/net/ethernet/mellanox/mlxsw/spectrum_port_range.c new file +181 -0

181 lines not on this page · raw message

Signature · 1 line
2.40.1
author maintainer
#4 lore raw

PATCH 4/10 mlxsw: spectrum_port_range: Add devlink resource support

In reply to Petr Machata

From: Ido Schimmel <[email protected]>

Expose via devlink-resource the maximum number of port range registers and their current occupancy. Besides the observability benefits, this resource will be used by subsequent patches for scale and occupancy tests.

---
 .../net/ethernet/mellanox/mlxsw/spectrum.c    | 30 +++++++++++++++++++
 .../net/ethernet/mellanox/mlxsw/spectrum.h    |  1 +
 .../mellanox/mlxsw/spectrum_port_range.c      | 19 ++++++++++++
 3 files changed, 50 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/spectrum.c +30 -0
index c0edcc91f178..86e2f0ed64d3 100644
@@ -3739,6 +3739,26 @@ static int mlxsw_sp_resources_rifs_register(struct mlxsw_core *mlxsw_core)
 				      &size_params);
 }
 
+static int
+mlxsw_sp_resources_port_range_register(struct mlxsw_core *mlxsw_core)
+{
+	struct devlink *devlink = priv_to_devlink(mlxsw_core);
+	struct devlink_resource_size_params size_params;
+	u64 max;
+
+	if (!MLXSW_CORE_RES_VALID(mlxsw_core, ACL_MAX_L4_PORT_RANGE))
+		return -EIO;
+
+	max = MLXSW_CORE_RES_GET(mlxsw_core, ACL_MAX_L4_PORT_RANGE);
+	devlink_resource_size_params_init(&size_params, max, max, 1,
+					  DEVLINK_RESOURCE_UNIT_ENTRY);
+
+	return devl_resource_register(devlink, "port_range_registers", max,
+				      MLXSW_SP_RESOURCE_PORT_RANGE_REGISTERS,
+				      DEVLINK_RESOURCE_ID_PARENT_TOP,
+				      &size_params);
+}
+
 static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
 {
 	int err;
@@ -3767,8 +3787,13 @@ static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
 	if (err)
 		goto err_resources_rifs_register;
 
+	err = mlxsw_sp_resources_port_range_register(mlxsw_core);
+	if (err)
+		goto err_resources_port_range_register;
+
 	return 0;
 
+err_resources_port_range_register:
 err_resources_rifs_register:
 err_resources_rif_mac_profile_register:
 err_policer_resources_register:
@@ -3806,8 +3831,13 @@ static int mlxsw_sp2_resources_register(struct mlxsw_core *mlxsw_core)
 	if (err)
 		goto err_resources_rifs_register;
 
+	err = mlxsw_sp_resources_port_range_register(mlxsw_core);
+	if (err)
+		goto err_resources_port_range_register;
+
 	return 0;
 
+err_resources_port_range_register:
 err_resources_rifs_register:
 err_resources_rif_mac_profile_register:
 err_policer_resources_register:
drivers/net/ethernet/mellanox/mlxsw/spectrum.h +1 -0
index fe6c6e02a484..a74652ea4d7c 100644
@@ -69,6 +69,7 @@ enum mlxsw_sp_resource_id {
 	MLXSW_SP_RESOURCE_SINGLE_RATE_POLICERS,
 	MLXSW_SP_RESOURCE_RIF_MAC_PROFILES,
 	MLXSW_SP_RESOURCE_RIFS,
+	MLXSW_SP_RESOURCE_PORT_RANGE_REGISTERS,
 };
 
 struct mlxsw_sp_port;
drivers/net/ethernet/mellanox/mlxsw/spectrum_port_range.c +19 -0
index a12a62632721..2d193de12be6 100644
@@ -5,6 +5,7 @@
 #include <linux/netlink.h>
 #include <linux/refcount.h>
 #include <linux/xarray.h>
+#include <net/devlink.h>
 
 #include "spectrum.h"
 
@@ -17,6 +18,7 @@ struct mlxsw_sp_port_range_reg {
 struct mlxsw_sp_port_range_core {
 	struct xarray prr_xa;
 	struct xa_limit prr_ids;
+	atomic_t prr_count;
 };
 
 static int
@@ -71,6 +73,8 @@ mlxsw_sp_port_range_reg_create(struct mlxsw_sp *mlxsw_sp,
 		goto err_reg_configure;
 	}
 
+	atomic_inc(&pr_core->prr_count);
+
 	return prr;
 
 err_reg_configure:
@@ -85,6 +89,7 @@ static void mlxsw_sp_port_range_reg_destroy(struct mlxsw_sp *mlxsw_sp,
 {
 	struct mlxsw_sp_port_range_core *pr_core = mlxsw_sp->pr_core;
 
+	atomic_dec(&pr_core->prr_count);
 	xa_erase(&pr_core->prr_xa, prr->index);
 	kfree(prr);
 }
@@ -145,6 +150,13 @@ void mlxsw_sp_port_range_reg_put(struct mlxsw_sp *mlxsw_sp, u8 prr_index)
 	mlxsw_sp_port_range_reg_destroy(mlxsw_sp, prr);
 }
 
+static u64 mlxsw_sp_port_range_reg_occ_get(void *priv)
+{
+	struct mlxsw_sp_port_range_core *pr_core = priv;
+
+	return atomic_read(&pr_core->prr_count);
+}
+
 int mlxsw_sp_port_range_init(struct mlxsw_sp *mlxsw_sp)
 {
 	struct mlxsw_sp_port_range_core *pr_core;
@@ -168,6 +180,11 @@ int mlxsw_sp_port_range_init(struct mlxsw_sp *mlxsw_sp)
 	pr_core->prr_ids.max = max - 1;
 	xa_init_flags(&pr_core->prr_xa, XA_FLAGS_ALLOC);
 
+	devl_resource_occ_get_register(priv_to_devlink(core),
+				       MLXSW_SP_RESOURCE_PORT_RANGE_REGISTERS,
+				       mlxsw_sp_port_range_reg_occ_get,
+				       pr_core);
+
 	return 0;
 }
 
@@ -175,6 +192,8 @@ void mlxsw_sp_port_range_fini(struct mlxsw_sp *mlxsw_sp)
 {
 	struct mlxsw_sp_port_range_core *pr_core = mlxsw_sp->pr_core;
 
+	devl_resource_occ_get_unregister(priv_to_devlink(mlxsw_sp->core),
+					 MLXSW_SP_RESOURCE_PORT_RANGE_REGISTERS);
 	WARN_ON(!xa_empty(&pr_core->prr_xa));
 	xa_destroy(&pr_core->prr_xa);
 	kfree(pr_core);
Signature · 1 line
2.40.1
author maintainer
#5 lore raw

PATCH 5/10 mlxsw: spectrum_acl: Add port range key element

In reply to Petr Machata

From: Ido Schimmel <[email protected]>

Add the port range key element to supported key blocks so that it could be used to match on the output of the port range registers. Each bit in the element can be used to match on the output of the port range register with the corresponding index.

---
 drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c     | 1 +
 drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h     | 1 +
 drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c | 3 +++
 3 files changed, 5 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c +1 -0
index f0b2963ebac3..7870327d921b 100644
@@ -43,6 +43,7 @@ static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
 	MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_32_63, 0x38, 4),
 	MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_0_31, 0x3C, 4),
 	MLXSW_AFK_ELEMENT_INFO_U32(FDB_MISS, 0x40, 0, 1),
+	MLXSW_AFK_ELEMENT_INFO_U32(L4_PORT_RANGE, 0x40, 1, 16),
 };
 
 struct mlxsw_afk {
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h +1 -0
index 65a4abadc7db..2eac7582c31a 100644
@@ -36,6 +36,7 @@ enum mlxsw_afk_element {
 	MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB,
 	MLXSW_AFK_ELEMENT_VIRT_ROUTER_LSB,
 	MLXSW_AFK_ELEMENT_FDB_MISS,
+	MLXSW_AFK_ELEMENT_L4_PORT_RANGE,
 	MLXSW_AFK_ELEMENT_MAX,
 };
 
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c +3 -0
index 4dea39f2b304..b7f58605b6c7 100644
@@ -31,12 +31,14 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac_ex[] = {
 
 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_sip[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x00, 4),
+	MLXSW_AFK_ELEMENT_INST_U32(L4_PORT_RANGE, 0x04, 16, 16),
 	MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
 	MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
 };
 
 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_dip[] = {
 	MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x00, 4),
+	MLXSW_AFK_ELEMENT_INST_U32(L4_PORT_RANGE, 0x04, 16, 16),
 	MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
 	MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
 };
@@ -205,6 +207,7 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_0[] = {
 
 static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_2[] = {
 	MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS, 0x04, 16, 9), /* TCP_CONTROL + TCP_ECN */
+	MLXSW_AFK_ELEMENT_INST_U32(L4_PORT_RANGE, 0x04, 0, 16),
 };
 
 static const struct mlxsw_afk_block mlxsw_sp2_afk_blocks[] = {
Signature · 1 line
2.40.1
author maintainer
#6 lore raw

PATCH 6/10 mlxsw: spectrum_acl: Pass main driver structure to mlxsw_sp_acl_rulei_destroy()

In reply to Petr Machata

From: Ido Schimmel <[email protected]>

The main driver structure will be needed in this function by a subsequent patch, so pass it. No functional changes intended.

---
 drivers/net/ethernet/mellanox/mlxsw/spectrum.h           | 3 ++-
 drivers/net/ethernet/mellanox/mlxsw/spectrum1_acl_tcam.c | 4 ++--
 drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c       | 5 +++--
 3 files changed, 7 insertions(+), 5 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum.h +2 -1
index a74652ea4d7c..4a1bf2d39fa0 100644
@@ -994,7 +994,8 @@ void mlxsw_sp_acl_ruleset_prio_get(struct mlxsw_sp_acl_ruleset *ruleset,
 struct mlxsw_sp_acl_rule_info *
 mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl,
 			  struct mlxsw_afa_block *afa_block);
-void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp_acl_rule_info *rulei);
+void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp *mlxsw_sp,
+				struct mlxsw_sp_acl_rule_info *rulei);
 int mlxsw_sp_acl_rulei_commit(struct mlxsw_sp_acl_rule_info *rulei);
 void mlxsw_sp_acl_rulei_priority(struct mlxsw_sp_acl_rule_info *rulei,
 				 unsigned int priority);
drivers/net/ethernet/mellanox/mlxsw/spectrum1_acl_tcam.c +2 -2
index 3a636f753607..dfcdd37e797b 100644
@@ -90,7 +90,7 @@ mlxsw_sp1_acl_ctcam_region_catchall_add(struct mlxsw_sp *mlxsw_sp,
 err_entry_add:
 err_rulei_commit:
 err_rulei_act_continue:
-	mlxsw_sp_acl_rulei_destroy(rulei);
+	mlxsw_sp_acl_rulei_destroy(mlxsw_sp, rulei);
 err_rulei_create:
 	mlxsw_sp_acl_ctcam_chunk_fini(&region->catchall.cchunk);
 	return err;
@@ -105,7 +105,7 @@ mlxsw_sp1_acl_ctcam_region_catchall_del(struct mlxsw_sp *mlxsw_sp,
 	mlxsw_sp_acl_ctcam_entry_del(mlxsw_sp, &region->cregion,
 				     &region->catchall.cchunk,
 				     &region->catchall.centry);
-	mlxsw_sp_acl_rulei_destroy(rulei);
+	mlxsw_sp_acl_rulei_destroy(mlxsw_sp, rulei);
 	mlxsw_sp_acl_ctcam_chunk_fini(&region->catchall.cchunk);
 }
 
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c +3 -2
index 0423ac262d89..7240b74b4883 100644
@@ -339,7 +339,8 @@ mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl,
 	return ERR_PTR(err);
 }
 
-void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp_acl_rule_info *rulei)
+void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp *mlxsw_sp,
+				struct mlxsw_sp_acl_rule_info *rulei)
 {
 	if (rulei->action_created)
 		mlxsw_afa_block_destroy(rulei->act_block);
@@ -834,7 +835,7 @@ void mlxsw_sp_acl_rule_destroy(struct mlxsw_sp *mlxsw_sp,
 {
 	struct mlxsw_sp_acl_ruleset *ruleset = rule->ruleset;
 
-	mlxsw_sp_acl_rulei_destroy(rule->rulei);
+	mlxsw_sp_acl_rulei_destroy(mlxsw_sp, rule->rulei);
 	kfree(rule);
 	mlxsw_sp_acl_ruleset_ref_dec(mlxsw_sp, ruleset);
 }
Signature · 1 line
2.40.1
author maintainer
#7 lore raw

PATCH 7/10 mlxsw: spectrum_flower: Add ability to match on port ranges

In reply to Petr Machata

From: Ido Schimmel <[email protected]>

Add the ability to match on port ranges by utilizing the previously added port range registers and the port range key element. Up to two port range registers can be used for each filter, one for source port and another for destination port.

---
 .../net/ethernet/mellanox/mlxsw/spectrum.h    |  6 +-
 .../ethernet/mellanox/mlxsw/spectrum_acl.c    |  6 ++
 .../ethernet/mellanox/mlxsw/spectrum_flower.c | 68 +++++++++++++++++++
 3 files changed, 79 insertions(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum.h +5 -1
index 4a1bf2d39fa0..c6231e62a371 100644
@@ -867,9 +867,13 @@ struct mlxsw_sp_acl_rule_info {
 	   egress_bind_blocker:1,
 	   counter_valid:1,
 	   policer_index_valid:1,
-	   ipv6_valid:1;
+	   ipv6_valid:1,
+	   src_port_range_reg_valid:1,
+	   dst_port_range_reg_valid:1;
 	unsigned int counter_index;
 	u16 policer_index;
+	u8 src_port_range_reg_index;
+	u8 dst_port_range_reg_index;
 	struct {
 		u32 prev_val;
 		enum mlxsw_sp_acl_mangle_field prev_field;
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c +6 -0
index 7240b74b4883..186161a3459d 100644
@@ -344,6 +344,12 @@ void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp *mlxsw_sp,
 {
 	if (rulei->action_created)
 		mlxsw_afa_block_destroy(rulei->act_block);
+	if (rulei->src_port_range_reg_valid)
+		mlxsw_sp_port_range_reg_put(mlxsw_sp,
+					    rulei->src_port_range_reg_index);
+	if (rulei->dst_port_range_reg_valid)
+		mlxsw_sp_port_range_reg_put(mlxsw_sp,
+					    rulei->dst_port_range_reg_index);
 	kfree(rulei);
 }
 
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +68 -0

86 lines not on this page · raw message

Signature · 1 line
2.40.1
author maintainer
#8 lore raw

PATCH 8/10 selftests: mlxsw: Add scale test for port ranges

In reply to Petr Machata

From: Ido Schimmel <[email protected]>

Query the maximum number of supported port range registers using devlink-resource and test that this number can be reached by configuring tc filters with different port ranges. Test that an error is returned in case the maximum number is exceeded.

---
 .../drivers/net/mlxsw/port_range_scale.sh     | 95 +++++++++++++++++++
 .../net/mlxsw/spectrum-2/port_range_scale.sh  |  1 +
 .../net/mlxsw/spectrum-2/resource_scale.sh    |  1 +
 .../net/mlxsw/spectrum/port_range_scale.sh    | 16 ++++
 .../net/mlxsw/spectrum/resource_scale.sh      |  1 +
 5 files changed, 114 insertions(+)
 create mode 100644 tools/testing/selftests/drivers/net/mlxsw/port_range_scale.sh
 create mode 120000 tools/testing/selftests/drivers/net/mlxsw/spectrum-2/port_range_scale.sh
 create mode 100644 tools/testing/selftests/drivers/net/mlxsw/spectrum/port_range_scale.sh
tools/testing/selftests/drivers/net/mlxsw/port_range_scale.sh new file +95 -0
new file mode 100644
index 000000000000..2a70840ff14b
@@ -0,0 +1,95 @@
+# SPDX-License-Identifier: GPL-2.0
+
+PORT_RANGE_NUM_NETIFS=2
+
+port_range_h1_create()
+{
+	simple_if_init $h1
+}
+
+port_range_h1_destroy()
+{
+	simple_if_fini $h1
+}
+
+port_range_switch_create()
+{
+	simple_if_init $swp1
+	tc qdisc add dev $swp1 clsact
+}
+
+port_range_switch_destroy()
+{
+	tc qdisc del dev $swp1 clsact
+	simple_if_fini $swp1
+}
+
+port_range_rules_create()
+{
+	local count=$1; shift
+	local should_fail=$1; shift
+	local batch_file="$(mktemp)"
+
+	for ((i = 0; i < count; ++i)); do
+		cat >> $batch_file <<-EOF
+			filter add dev $swp1 ingress \
+				prot ipv4 \
+				pref 1000 \
+				flower skip_sw \
+				ip_proto udp dst_port 1-$((100 + i)) \
+				action pass
+		EOF
+	done
+
+	tc -b $batch_file
+	check_err_fail $should_fail $? "Rule insertion"
+
+	rm -f $batch_file
+}
+
+__port_range_test()
+{
+	local count=$1; shift
+	local should_fail=$1; shift
+
+	port_range_rules_create $count $should_fail
+
+	offload_count=$(tc -j filter show dev $swp1 ingress |
+			jq "[.[] | select(.options.in_hw == true)] | length")
+	((offload_count == count))
+	check_err_fail $should_fail $? "port range offload count"
+}
+
+port_range_test()
+{
+	local count=$1; shift
+	local should_fail=$1; shift
+
+	if ! tc_offload_check $PORT_RANGE_NUM_NETIFS; then
+		check_err 1 "Could not test offloaded functionality"
+		return
+	fi
+
+	__port_range_test $count $should_fail
+}
+
+port_range_setup_prepare()
+{
+	h1=${NETIFS[p1]}
+	swp1=${NETIFS[p2]}
+
+	vrf_prepare
+
+	port_range_h1_create
+	port_range_switch_create
+}
+
+port_range_cleanup()
+{
+	pre_cleanup
+
+	port_range_switch_destroy
+	port_range_h1_destroy
+
+	vrf_cleanup
+}
tools/testing/selftests/drivers/net/mlxsw/spectrum-2/port_range_scale.sh new file +1 -0
new file mode 120000
index 000000000000..bd670d9dc4e5
@@ -0,0 +1 @@
+../spectrum/port_range_scale.sh
\ No newline at end of file
tools/testing/selftests/drivers/net/mlxsw/spectrum-2/resource_scale.sh +1 -0
index 688338bbeb97..a88d8a8c85f2 100755
@@ -33,6 +33,7 @@ ALL_TESTS="
 	port
 	rif_mac_profile
 	rif_counter
+	port_range
 "
 
 for current_test in ${TESTS:-$ALL_TESTS}; do
tools/testing/selftests/drivers/net/mlxsw/spectrum/port_range_scale.sh new file +16 -0
new file mode 100644
index 000000000000..d0847e8ea270
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0
+source ../port_range_scale.sh
+
+port_range_get_target()
+{
+	local should_fail=$1; shift
+	local target
+
+	target=$(devlink_resource_size_get port_range_registers)
+
+	if ((! should_fail)); then
+		echo $target
+	else
+		echo $((target + 1))
+	fi
+}
tools/testing/selftests/drivers/net/mlxsw/spectrum/resource_scale.sh +1 -0
index 95d9f710a630..f981c957f097 100755
@@ -30,6 +30,7 @@ ALL_TESTS="
 	port
 	rif_mac_profile
 	rif_counter
+	port_range
 "
 
 for current_test in ${TESTS:-$ALL_TESTS}; do
Signature · 1 line
2.40.1
author maintainer
#9 lore raw

PATCH 9/10 selftests: mlxsw: Test port range registers' occupancy

In reply to Petr Machata

From: Ido Schimmel <[email protected]>

Test that filters that match on the same port range, but with different combination of IPv4/IPv6 and TCP/UDP all use the same port range register by observing port range registers' occupancy via devlink-resource.

---
 .../drivers/net/mlxsw/port_range_occ.sh       | 111 ++++++++++++++++++
 1 file changed, 111 insertions(+)
 create mode 100755 tools/testing/selftests/drivers/net/mlxsw/port_range_occ.sh
tools/testing/selftests/drivers/net/mlxsw/port_range_occ.sh new file +111 -0
new file mode 100755
index 000000000000..b1f0781f6b25
@@ -0,0 +1,111 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Test that filters that match on the same port range, but with different
+# combination of IPv4/IPv6 and TCP/UDP all use the same port range register by
+# observing port range registers' occupancy via devlink-resource.
+
+lib_dir=$(dirname $0)/../../../net/forwarding
+
+ALL_TESTS="
+	port_range_occ_test
+"
+NUM_NETIFS=2
+source $lib_dir/lib.sh
+source $lib_dir/devlink_lib.sh
+
+h1_create()
+{
+	simple_if_init $h1
+}
+
+h1_destroy()
+{
+	simple_if_fini $h1
+}
+
+switch_create()
+{
+	simple_if_init $swp1
+	tc qdisc add dev $swp1 clsact
+}
+
+switch_destroy()
+{
+	tc qdisc del dev $swp1 clsact
+	simple_if_fini $swp1
+}
+
+setup_prepare()
+{
+	h1=${NETIFS[p1]}
+	swp1=${NETIFS[p2]}
+
+	vrf_prepare
+
+	h1_create
+	switch_create
+}
+
+cleanup()
+{
+	pre_cleanup
+
+	switch_destroy
+	h1_destroy
+
+	vrf_cleanup
+}
+
+port_range_occ_get()
+{
+	devlink_resource_occ_get port_range_registers
+}
+
+port_range_occ_test()
+{
+	RET=0
+
+	local occ=$(port_range_occ_get)
+
+	# Two port range registers are used, for source and destination port
+	# ranges.
+	tc filter add dev $swp1 ingress pref 1 handle 101 proto ip \
+		flower skip_sw ip_proto udp src_port 1-100 dst_port 1-100 \
+		action pass
+	(( occ + 2 == $(port_range_occ_get) ))
+	check_err $? "Got occupancy $(port_range_occ_get), expected $((occ + 2))"
+
+	tc filter add dev $swp1 ingress pref 1 handle 102 proto ip \
+		flower skip_sw ip_proto tcp src_port 1-100 dst_port 1-100 \
+		action pass
+	tc filter add dev $swp1 ingress pref 2 handle 103 proto ipv6 \
+		flower skip_sw ip_proto udp src_port 1-100 dst_port 1-100 \
+		action pass
+	tc filter add dev $swp1 ingress pref 2 handle 104 proto ipv6 \
+		flower skip_sw ip_proto tcp src_port 1-100 dst_port 1-100 \
+		action pass
+	(( occ + 2 == $(port_range_occ_get) ))
+	check_err $? "Got occupancy $(port_range_occ_get), expected $((occ + 2))"
+
+	tc filter del dev $swp1 ingress pref 2 handle 104 flower
+	tc filter del dev $swp1 ingress pref 2 handle 103 flower
+	tc filter del dev $swp1 ingress pref 1 handle 102 flower
+	(( occ + 2 == $(port_range_occ_get) ))
+	check_err $? "Got occupancy $(port_range_occ_get), expected $((occ + 2))"
+
+	tc filter del dev $swp1 ingress pref 1 handle 101 flower
+	(( occ == $(port_range_occ_get) ))
+	check_err $? "Got occupancy $(port_range_occ_get), expected $occ"
+
+	log_test "port range occupancy"
+}
+
+trap cleanup EXIT
+
+setup_prepare
+setup_wait
+
+tests_run
+
+exit $EXIT_STATUS
Signature · 1 line
2.40.1
author maintainer
#10 lore raw

PATCH 10/10 selftests: forwarding: Add test cases for flower port range matching

In reply to Petr Machata

From: Ido Schimmel <[email protected]>

Add test cases to verify that flower port range matching works correctly. Test both source and destination port ranges, with different combinations of IPv4/IPv6 and TCP/UDP, on both ingress and egress.

---
 .../testing/selftests/net/forwarding/Makefile |   1 +
 .../net/forwarding/tc_flower_port_range.sh    | 228 ++++++++++++++++++
 2 files changed, 229 insertions(+)
 create mode 100755 tools/testing/selftests/net/forwarding/tc_flower_port_range.sh
tools/testing/selftests/net/forwarding/Makefile +1 -0
index 770efbe24f0d..f49c6c3f6520 100644
@@ -85,6 +85,7 @@ TEST_PROGS = bridge_igmp.sh \
 	tc_flower.sh \
 	tc_flower_l2_miss.sh \
 	tc_flower_cfm.sh \
+	tc_flower_port_range.sh \
 	tc_mpls_l2vpn.sh \
 	tc_police.sh \
 	tc_shblocks.sh \
tools/testing/selftests/net/forwarding/tc_flower_port_range.sh new file +228 -0

228 lines not on this page · raw message

Signature · 1 line
2.40.1
#11 lore raw
In reply to Petr Machata
This series was applied to netdev/net-next.git (main) by Jakub Kicinski <[email protected]>:

Hello:

This series was applied to netdev/net-next.git (main) by Jakub Kicinski <[email protected]>:

Quoted 9 lines · On Tue, 11 Jul 2023 18:43:53 +0200 you wrote:

Ido Schimmel writes:

Add port range matching support in mlxsw as part of tc-flower offload.

Patches #1-#7 gradually add port range matching support in mlxsw. See patch #3 to understand how port range matching is implemented in the device.

[...]

Here is the summary with links:
- [net-next,01/10] mlxsw: reg: Add Policy-Engine Port Range Register

    https://git.kernel.org/netdev/net-next/c/f3b8bec7d29e
  - [net-next,02/10] mlxsw: resource: Add resource identifier for port range registers
    https://git.kernel.org/netdev/net-next/c/9f53a7602ac6
  - [net-next,03/10] mlxsw: spectrum_port_range: Add port range core
    https://git.kernel.org/netdev/net-next/c/b3eb04be7299
  - [net-next,04/10] mlxsw: spectrum_port_range: Add devlink resource support
    https://git.kernel.org/netdev/net-next/c/74d6786cf2dc
  - [net-next,05/10] mlxsw: spectrum_acl: Add port range key element
    https://git.kernel.org/netdev/net-next/c/d65f24c9fa69
  - [net-next,06/10] mlxsw: spectrum_acl: Pass main driver structure to mlxsw_sp_acl_rulei_destroy()
    https://git.kernel.org/netdev/net-next/c/898979c7238a
  - [net-next,07/10] mlxsw: spectrum_flower: Add ability to match on port ranges
    https://git.kernel.org/netdev/net-next/c/fe22f7410527
  - [net-next,08/10] selftests: mlxsw: Add scale test for port ranges
    https://git.kernel.org/netdev/net-next/c/45c5a384765b
  - [net-next,09/10] selftests: mlxsw: Test port range registers' occupancy
    https://git.kernel.org/netdev/net-next/c/0a1a818d8a1c
  - [net-next,10/10] selftests: forwarding: Add test cases for flower port range matching
    https://git.kernel.org/netdev/net-next/c/209218e4799b

You are awesome, thank you!

Signature · 2 lines
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
Reviewed-by on the v1 series
#12 lore raw
In reply to Petr Machata
Quoted 10 lines · Petr Machata

Ido Schimmel writes:

Add port range matching support in mlxsw as part of tc-flower offload.

Patches #1-#7 gradually add port range matching support in mlxsw. See patch #3 to understand how port range matching is implemented in the device.

Patches #8-#10 add selftests.

Quoted 12 lines

Ido Schimmel (10):
mlxsw: reg: Add Policy-Engine Port Range Register
mlxsw: resource: Add resource identifier for port range registers
mlxsw: spectrum_port_range: Add port range core
mlxsw: spectrum_port_range: Add devlink resource support
mlxsw: spectrum_acl: Add port range key element
mlxsw: spectrum_acl: Pass main driver structure to
mlxsw_sp_acl_rulei_destroy()
mlxsw: spectrum_flower: Add ability to match on port ranges
selftests: mlxsw: Add scale test for port ranges
selftests: mlxsw: Test port range registers' occupancy
selftests: forwarding: Add test cases for flower port range matching