git: 847542c60c2b - main - mlx5: Add modify header support to flow rules

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 15 Nov 2023 23:09:06 UTC
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=847542c60c2b3d922d636cc36ce51714032f9825

commit 847542c60c2b3d922d636cc36ce51714032f9825
Author:     Mark Bloch <mbloch@nvidia.com>
AuthorDate: 2023-02-19 11:15:00 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-11-15 23:08:16 +0000

    mlx5: Add modify header support to flow rules
    
    Allow attaching a modify header to a flow rule.
    
    Signed-off-by: Mark Bloch <mbloch@nvidia.com>
    Sponsored by:   NVidia networking
    MFC after:      1 week
---
 sys/dev/mlx5/fs.h                     | 2 ++
 sys/dev/mlx5/mlx5_core/mlx5_fs_cmd.c  | 9 ++++++++-
 sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c | 4 ++++
 sys/dev/mlx5/mlx5_ifc.h               | 1 +
 4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/sys/dev/mlx5/fs.h b/sys/dev/mlx5/fs.h
index 7ed7a5380cf1..bb087718d12f 100644
--- a/sys/dev/mlx5/fs.h
+++ b/sys/dev/mlx5/fs.h
@@ -84,11 +84,13 @@ struct mlx5_flow_destination {
 
 enum mlx5_flow_act_actions {
 	MLX5_FLOW_ACT_ACTIONS_FLOW_TAG = 1 << 0,
+	MLX5_FLOW_ACT_ACTIONS_MODIFY_HDR = 1 << 1,
 };
 
 struct mlx5_flow_act {
 	u32 actions; /* See enum mlx5_flow_act_actions */
 	u32 flow_tag;
+	struct mlx5_modify_hdr *modify_hdr;
 };
 
 #define FT_NAME_STR_SZ 20
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_fs_cmd.c b/sys/dev/mlx5/mlx5_core/mlx5_fs_cmd.c
index 5ac0c95c7bca..22bc945a4b62 100644
--- a/sys/dev/mlx5/mlx5_core/mlx5_fs_cmd.c
+++ b/sys/dev/mlx5/mlx5_core/mlx5_fs_cmd.c
@@ -179,10 +179,12 @@ int mlx5_cmd_fs_set_fte(struct mlx5_core_dev *dev,
 	int opmod = 0;
 	int modify_mask = 0;
 	int atomic_mod_cap;
+	u32 prm_action = 0;
 
 	if (action != MLX5_FLOW_CONTEXT_ACTION_FWD_DEST)
 		dest_size = 0;
 
+	prm_action = action;
 	inlen = MLX5_ST_SZ_BYTES(set_fte_in) +
 		dest_size * MLX5_ST_SZ_BYTES(dest_format_struct);
 
@@ -221,7 +223,11 @@ int mlx5_cmd_fs_set_fte(struct mlx5_core_dev *dev,
 	MLX5_SET(flow_context, in_flow_context, group_id, group_id);
 	if (flow_act->actions & MLX5_FLOW_ACT_ACTIONS_FLOW_TAG)
 		MLX5_SET(flow_context, in_flow_context, flow_tag, flow_act->flow_tag);
-	MLX5_SET(flow_context, in_flow_context, action, action);
+	if (flow_act->actions & MLX5_FLOW_ACT_ACTIONS_MODIFY_HDR) {
+		MLX5_SET(flow_context, in_flow_context, modify_header_id,
+			 flow_act->modify_hdr->id);
+		prm_action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
+	}
 	MLX5_SET(flow_context, in_flow_context, destination_list_size,
 		 dest_size);
 	in_match_value = MLX5_ADDR_OF(flow_context, in_flow_context,
@@ -244,6 +250,7 @@ int mlx5_cmd_fs_set_fte(struct mlx5_core_dev *dev,
 		}
 	}
 
+	MLX5_SET(flow_context, in_flow_context, action, prm_action);
 	err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
 	if (!err)
 		*fte_status |= FS_FTE_STATUS_EXISTING;
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c b/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c
index 8e203a9662bb..7c3eb1e86d6d 100644
--- a/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c
+++ b/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c
@@ -1760,6 +1760,10 @@ static bool check_conflicting_actions(const struct mlx5_flow_act *act1,
 	    act1->flow_tag != act2->flow_tag)
 		return true;
 
+	/* Can even have complex actions in merged rules */
+	if (action1 & MLX5_FLOW_ACT_ACTIONS_MODIFY_HDR)
+		return true;
+
 	return false;
 }
 
diff --git a/sys/dev/mlx5/mlx5_ifc.h b/sys/dev/mlx5/mlx5_ifc.h
index 340e3b2e2d03..9534ac3d1c94 100644
--- a/sys/dev/mlx5/mlx5_ifc.h
+++ b/sys/dev/mlx5/mlx5_ifc.h
@@ -2264,6 +2264,7 @@ enum {
 	MLX5_FLOW_CONTEXT_ACTION_DROP      = 0x2,
 	MLX5_FLOW_CONTEXT_ACTION_FWD_DEST  = 0x4,
 	MLX5_FLOW_CONTEXT_ACTION_COUNT     = 0x8,
+	MLX5_FLOW_CONTEXT_ACTION_MOD_HDR   = 0x40,
 };
 
 struct mlx5_ifc_flow_context_bits {