1
1
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2
2
// Copyright (c) 2021, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3
3
4
+ #include "en_tc.h"
4
5
#include "post_act.h"
5
6
#include "mlx5_core.h"
6
7
@@ -9,8 +10,20 @@ struct mlx5e_post_act {
9
10
struct mlx5_fs_chains * chains ;
10
11
struct mlx5_flow_table * ft ;
11
12
struct mlx5e_priv * priv ;
13
+ struct xarray ids ;
12
14
};
13
15
16
+ struct mlx5e_post_act_handle {
17
+ enum mlx5_flow_namespace_type ns_type ;
18
+ struct mlx5_flow_attr * attr ;
19
+ struct mlx5_flow_handle * rule ;
20
+ u32 id ;
21
+ };
22
+
23
+ #define MLX5_POST_ACTION_BITS (mlx5e_tc_attr_to_reg_mappings[FTEID_TO_REG].mlen)
24
+ #define MLX5_POST_ACTION_MAX GENMASK(MLX5_POST_ACTION_BITS - 1, 0)
25
+ #define MLX5_POST_ACTION_MASK MLX5_POST_ACTION_MAX
26
+
14
27
struct mlx5e_post_act *
15
28
mlx5e_tc_post_act_init (struct mlx5e_priv * priv , struct mlx5_fs_chains * chains ,
16
29
enum mlx5_flow_namespace_type ns_type )
@@ -43,6 +56,7 @@ mlx5e_tc_post_act_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
43
56
post_act -> chains = chains ;
44
57
post_act -> ns_type = ns_type ;
45
58
post_act -> priv = priv ;
59
+ xa_init_flags (& post_act -> ids , XA_FLAGS_ALLOC1 );
46
60
return post_act ;
47
61
48
62
err_ft :
@@ -57,6 +71,94 @@ mlx5e_tc_post_act_destroy(struct mlx5e_post_act *post_act)
57
71
if (IS_ERR_OR_NULL (post_act ))
58
72
return ;
59
73
74
+ xa_destroy (& post_act -> ids );
60
75
mlx5_chains_destroy_global_table (post_act -> chains , post_act -> ft );
61
76
kfree (post_act );
62
77
}
78
+
79
+ struct mlx5e_post_act_handle *
80
+ mlx5e_tc_post_act_add (struct mlx5e_post_act * post_act , struct mlx5_flow_attr * attr )
81
+ {
82
+ u32 attr_sz = ns_to_attr_sz (post_act -> ns_type );
83
+ struct mlx5e_post_act_handle * handle = NULL ;
84
+ struct mlx5_flow_attr * post_attr = NULL ;
85
+ struct mlx5_flow_spec * spec = NULL ;
86
+ int err ;
87
+
88
+ handle = kzalloc (sizeof (* handle ), GFP_KERNEL );
89
+ spec = kvzalloc (sizeof (* spec ), GFP_KERNEL );
90
+ post_attr = mlx5_alloc_flow_attr (post_act -> ns_type );
91
+ if (!handle || !spec || !post_attr ) {
92
+ kfree (post_attr );
93
+ kvfree (spec );
94
+ kfree (handle );
95
+ return ERR_PTR (- ENOMEM );
96
+ }
97
+
98
+ memcpy (post_attr , attr , attr_sz );
99
+ post_attr -> chain = 0 ;
100
+ post_attr -> prio = 0 ;
101
+ post_attr -> ft = post_act -> ft ;
102
+ post_attr -> inner_match_level = MLX5_MATCH_NONE ;
103
+ post_attr -> outer_match_level = MLX5_MATCH_NONE ;
104
+ post_attr -> action &= ~(MLX5_FLOW_CONTEXT_ACTION_DECAP );
105
+
106
+ handle -> ns_type = post_act -> ns_type ;
107
+ /* Splits were handled before post action */
108
+ if (handle -> ns_type == MLX5_FLOW_NAMESPACE_FDB )
109
+ post_attr -> esw_attr -> split_count = 0 ;
110
+
111
+ err = xa_alloc (& post_act -> ids , & handle -> id , post_attr ,
112
+ XA_LIMIT (1 , MLX5_POST_ACTION_MAX ), GFP_KERNEL );
113
+ if (err )
114
+ goto err_xarray ;
115
+
116
+ /* Post action rule matches on fte_id and executes original rule's
117
+ * tc rule action
118
+ */
119
+ mlx5e_tc_match_to_reg_match (spec , FTEID_TO_REG ,
120
+ handle -> id , MLX5_POST_ACTION_MASK );
121
+
122
+ handle -> rule = mlx5_tc_rule_insert (post_act -> priv , spec , post_attr );
123
+ if (IS_ERR (handle -> rule )) {
124
+ err = PTR_ERR (handle -> rule );
125
+ netdev_warn (post_act -> priv -> netdev , "Failed to add post action rule" );
126
+ goto err_rule ;
127
+ }
128
+ handle -> attr = post_attr ;
129
+
130
+ kvfree (spec );
131
+ return handle ;
132
+
133
+ err_rule :
134
+ xa_erase (& post_act -> ids , handle -> id );
135
+ err_xarray :
136
+ kfree (post_attr );
137
+ kvfree (spec );
138
+ kfree (handle );
139
+ return ERR_PTR (err );
140
+ }
141
+
142
+ void
143
+ mlx5e_tc_post_act_del (struct mlx5e_post_act * post_act , struct mlx5e_post_act_handle * handle )
144
+ {
145
+ mlx5_tc_rule_delete (post_act -> priv , handle -> rule , handle -> attr );
146
+ xa_erase (& post_act -> ids , handle -> id );
147
+ kfree (handle -> attr );
148
+ kfree (handle );
149
+ }
150
+
151
+ struct mlx5_flow_table *
152
+ mlx5e_tc_post_act_get_ft (struct mlx5e_post_act * post_act )
153
+ {
154
+ return post_act -> ft ;
155
+ }
156
+
157
+ /* Allocate a header modify action to write the post action handle fte id to a register. */
158
+ int
159
+ mlx5e_tc_post_act_set_handle (struct mlx5_core_dev * dev ,
160
+ struct mlx5e_post_act_handle * handle ,
161
+ struct mlx5e_tc_mod_hdr_acts * acts )
162
+ {
163
+ return mlx5e_tc_match_to_reg_set (dev , acts , handle -> ns_type , FTEID_TO_REG , handle -> id );
164
+ }
0 commit comments