@@ -32,13 +32,17 @@ struct mlx5e_ipsec_tx {
32
32
u8 allow_tunnel_mode : 1 ;
33
33
};
34
34
35
+ struct mlx5e_ipsec_status_checks {
36
+ struct mlx5_flow_group * drop_all_group ;
37
+ struct mlx5e_ipsec_drop all ;
38
+ };
39
+
35
40
struct mlx5e_ipsec_rx {
36
41
struct mlx5e_ipsec_ft ft ;
37
42
struct mlx5e_ipsec_miss pol ;
38
43
struct mlx5e_ipsec_miss sa ;
39
44
struct mlx5e_ipsec_rule status ;
40
- struct mlx5e_ipsec_miss status_drop ;
41
- struct mlx5_fc * status_drop_cnt ;
45
+ struct mlx5e_ipsec_status_checks status_drops ;
42
46
struct mlx5e_ipsec_fc * fc ;
43
47
struct mlx5_fs_chains * chains ;
44
48
u8 allow_tunnel_mode : 1 ;
@@ -143,9 +147,9 @@ static struct mlx5_flow_table *ipsec_ft_create(struct mlx5_flow_namespace *ns,
143
147
static void ipsec_rx_status_drop_destroy (struct mlx5e_ipsec * ipsec ,
144
148
struct mlx5e_ipsec_rx * rx )
145
149
{
146
- mlx5_del_flow_rules (rx -> status_drop .rule );
147
- mlx5_destroy_flow_group ( rx -> status_drop . group );
148
- mlx5_fc_destroy ( ipsec -> mdev , rx -> status_drop_cnt );
150
+ mlx5_del_flow_rules (rx -> status_drops . all .rule );
151
+ mlx5_fc_destroy ( ipsec -> mdev , rx -> status_drops . all . fc );
152
+ mlx5_destroy_flow_group ( rx -> status_drops . drop_all_group );
149
153
}
150
154
151
155
static void ipsec_rx_status_pass_destroy (struct mlx5e_ipsec * ipsec ,
@@ -161,8 +165,149 @@ static void ipsec_rx_status_pass_destroy(struct mlx5e_ipsec *ipsec,
161
165
#endif
162
166
}
163
167
164
- static int ipsec_rx_status_drop_create (struct mlx5e_ipsec * ipsec ,
165
- struct mlx5e_ipsec_rx * rx )
168
+ static int rx_add_rule_drop_auth_trailer (struct mlx5e_ipsec_sa_entry * sa_entry ,
169
+ struct mlx5e_ipsec_rx * rx )
170
+ {
171
+ struct mlx5e_ipsec * ipsec = sa_entry -> ipsec ;
172
+ struct mlx5_flow_table * ft = rx -> ft .status ;
173
+ struct mlx5_core_dev * mdev = ipsec -> mdev ;
174
+ struct mlx5_flow_destination dest = {};
175
+ struct mlx5_flow_act flow_act = {};
176
+ struct mlx5_flow_handle * rule ;
177
+ struct mlx5_fc * flow_counter ;
178
+ struct mlx5_flow_spec * spec ;
179
+ int err ;
180
+
181
+ spec = kvzalloc (sizeof (* spec ), GFP_KERNEL );
182
+ if (!spec )
183
+ return - ENOMEM ;
184
+
185
+ flow_counter = mlx5_fc_create (mdev , true);
186
+ if (IS_ERR (flow_counter )) {
187
+ err = PTR_ERR (flow_counter );
188
+ mlx5_core_err (mdev ,
189
+ "Failed to add ipsec rx status drop rule counter, err=%d\n" , err );
190
+ goto err_cnt ;
191
+ }
192
+ sa_entry -> ipsec_rule .auth .fc = flow_counter ;
193
+
194
+ flow_act .action = MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT ;
195
+ flow_act .flags = FLOW_ACT_NO_APPEND ;
196
+ dest .type = MLX5_FLOW_DESTINATION_TYPE_COUNTER ;
197
+ dest .counter_id = mlx5_fc_id (flow_counter );
198
+ if (rx == ipsec -> rx_esw )
199
+ spec -> flow_context .flow_source = MLX5_FLOW_CONTEXT_FLOW_SOURCE_UPLINK ;
200
+
201
+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria , misc_parameters_2 .ipsec_syndrome );
202
+ MLX5_SET (fte_match_param , spec -> match_value , misc_parameters_2 .ipsec_syndrome , 1 );
203
+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria , misc_parameters_2 .metadata_reg_c_2 );
204
+ MLX5_SET (fte_match_param , spec -> match_value ,
205
+ misc_parameters_2 .metadata_reg_c_2 ,
206
+ sa_entry -> ipsec_obj_id | BIT (31 ));
207
+ spec -> match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2 ;
208
+ rule = mlx5_add_flow_rules (ft , spec , & flow_act , & dest , 1 );
209
+ if (IS_ERR (rule )) {
210
+ err = PTR_ERR (rule );
211
+ mlx5_core_err (mdev ,
212
+ "Failed to add ipsec rx status drop rule, err=%d\n" , err );
213
+ goto err_rule ;
214
+ }
215
+ sa_entry -> ipsec_rule .auth .rule = rule ;
216
+
217
+ flow_counter = mlx5_fc_create (mdev , true);
218
+ if (IS_ERR (flow_counter )) {
219
+ err = PTR_ERR (flow_counter );
220
+ mlx5_core_err (mdev ,
221
+ "Failed to add ipsec rx status drop rule counter, err=%d\n" , err );
222
+ goto err_cnt_2 ;
223
+ }
224
+ sa_entry -> ipsec_rule .trailer .fc = flow_counter ;
225
+
226
+ dest .counter_id = mlx5_fc_id (flow_counter );
227
+ MLX5_SET (fte_match_param , spec -> match_value , misc_parameters_2 .ipsec_syndrome , 2 );
228
+ rule = mlx5_add_flow_rules (ft , spec , & flow_act , & dest , 1 );
229
+ if (IS_ERR (rule )) {
230
+ err = PTR_ERR (rule );
231
+ mlx5_core_err (mdev ,
232
+ "Failed to add ipsec rx status drop rule, err=%d\n" , err );
233
+ goto err_rule_2 ;
234
+ }
235
+ sa_entry -> ipsec_rule .trailer .rule = rule ;
236
+
237
+ kvfree (spec );
238
+ return 0 ;
239
+
240
+ err_rule_2 :
241
+ mlx5_fc_destroy (mdev , sa_entry -> ipsec_rule .trailer .fc );
242
+ err_cnt_2 :
243
+ mlx5_del_flow_rules (sa_entry -> ipsec_rule .auth .rule );
244
+ err_rule :
245
+ mlx5_fc_destroy (mdev , sa_entry -> ipsec_rule .auth .fc );
246
+ err_cnt :
247
+ kvfree (spec );
248
+ return err ;
249
+ }
250
+
251
+ static int rx_add_rule_drop_replay (struct mlx5e_ipsec_sa_entry * sa_entry , struct mlx5e_ipsec_rx * rx )
252
+ {
253
+ struct mlx5e_ipsec * ipsec = sa_entry -> ipsec ;
254
+ struct mlx5_flow_table * ft = rx -> ft .status ;
255
+ struct mlx5_core_dev * mdev = ipsec -> mdev ;
256
+ struct mlx5_flow_destination dest = {};
257
+ struct mlx5_flow_act flow_act = {};
258
+ struct mlx5_flow_handle * rule ;
259
+ struct mlx5_fc * flow_counter ;
260
+ struct mlx5_flow_spec * spec ;
261
+ int err ;
262
+
263
+ spec = kvzalloc (sizeof (* spec ), GFP_KERNEL );
264
+ if (!spec )
265
+ return - ENOMEM ;
266
+
267
+ flow_counter = mlx5_fc_create (mdev , true);
268
+ if (IS_ERR (flow_counter )) {
269
+ err = PTR_ERR (flow_counter );
270
+ mlx5_core_err (mdev ,
271
+ "Failed to add ipsec rx status drop rule counter, err=%d\n" , err );
272
+ goto err_cnt ;
273
+ }
274
+
275
+ flow_act .action = MLX5_FLOW_CONTEXT_ACTION_DROP | MLX5_FLOW_CONTEXT_ACTION_COUNT ;
276
+ flow_act .flags = FLOW_ACT_NO_APPEND ;
277
+ dest .type = MLX5_FLOW_DESTINATION_TYPE_COUNTER ;
278
+ dest .counter_id = mlx5_fc_id (flow_counter );
279
+ if (rx == ipsec -> rx_esw )
280
+ spec -> flow_context .flow_source = MLX5_FLOW_CONTEXT_FLOW_SOURCE_UPLINK ;
281
+
282
+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria , misc_parameters_2 .metadata_reg_c_4 );
283
+ MLX5_SET (fte_match_param , spec -> match_value , misc_parameters_2 .metadata_reg_c_4 , 1 );
284
+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria , misc_parameters_2 .metadata_reg_c_2 );
285
+ MLX5_SET (fte_match_param , spec -> match_value , misc_parameters_2 .metadata_reg_c_2 ,
286
+ sa_entry -> ipsec_obj_id | BIT (31 ));
287
+ spec -> match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2 ;
288
+ rule = mlx5_add_flow_rules (ft , spec , & flow_act , & dest , 1 );
289
+ if (IS_ERR (rule )) {
290
+ err = PTR_ERR (rule );
291
+ mlx5_core_err (mdev ,
292
+ "Failed to add ipsec rx status drop rule, err=%d\n" , err );
293
+ goto err_rule ;
294
+ }
295
+
296
+ sa_entry -> ipsec_rule .replay .rule = rule ;
297
+ sa_entry -> ipsec_rule .replay .fc = flow_counter ;
298
+
299
+ kvfree (spec );
300
+ return 0 ;
301
+
302
+ err_rule :
303
+ mlx5_fc_destroy (mdev , flow_counter );
304
+ err_cnt :
305
+ kvfree (spec );
306
+ return err ;
307
+ }
308
+
309
+ static int ipsec_rx_status_drop_all_create (struct mlx5e_ipsec * ipsec ,
310
+ struct mlx5e_ipsec_rx * rx )
166
311
{
167
312
int inlen = MLX5_ST_SZ_BYTES (create_flow_group_in );
168
313
struct mlx5_flow_table * ft = rx -> ft .status ;
@@ -214,9 +359,9 @@ static int ipsec_rx_status_drop_create(struct mlx5e_ipsec *ipsec,
214
359
goto err_rule ;
215
360
}
216
361
217
- rx -> status_drop . group = g ;
218
- rx -> status_drop .rule = rule ;
219
- rx -> status_drop_cnt = flow_counter ;
362
+ rx -> status_drops . drop_all_group = g ;
363
+ rx -> status_drops . all .rule = rule ;
364
+ rx -> status_drops . all . fc = flow_counter ;
220
365
221
366
kvfree (flow_group_in );
222
367
kvfree (spec );
@@ -247,8 +392,12 @@ static int ipsec_rx_status_pass_create(struct mlx5e_ipsec *ipsec,
247
392
248
393
MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria ,
249
394
misc_parameters_2 .ipsec_syndrome );
395
+ MLX5_SET_TO_ONES (fte_match_param , spec -> match_criteria ,
396
+ misc_parameters_2 .metadata_reg_c_4 );
250
397
MLX5_SET (fte_match_param , spec -> match_value ,
251
398
misc_parameters_2 .ipsec_syndrome , 0 );
399
+ MLX5_SET (fte_match_param , spec -> match_value ,
400
+ misc_parameters_2 .metadata_reg_c_4 , 0 );
252
401
if (rx == ipsec -> rx_esw )
253
402
spec -> flow_context .flow_source = MLX5_FLOW_CONTEXT_FLOW_SOURCE_UPLINK ;
254
403
spec -> match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2 ;
@@ -285,7 +434,7 @@ static int mlx5_ipsec_rx_status_create(struct mlx5e_ipsec *ipsec,
285
434
{
286
435
int err ;
287
436
288
- err = ipsec_rx_status_drop_create (ipsec , rx );
437
+ err = ipsec_rx_status_drop_all_create (ipsec , rx );
289
438
if (err )
290
439
return err ;
291
440
@@ -529,7 +678,7 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
529
678
if (err )
530
679
return err ;
531
680
532
- ft = ipsec_ft_create (attr .ns , attr .status_level , attr .prio , 1 , 0 );
681
+ ft = ipsec_ft_create (attr .ns , attr .status_level , attr .prio , 3 , 0 );
533
682
if (IS_ERR (ft )) {
534
683
err = PTR_ERR (ft );
535
684
goto err_fs_ft_status ;
@@ -1159,29 +1308,48 @@ static int setup_modify_header(struct mlx5e_ipsec *ipsec, int type, u32 val, u8
1159
1308
struct mlx5_flow_act * flow_act )
1160
1309
{
1161
1310
enum mlx5_flow_namespace_type ns_type = ipsec_fs_get_ns (ipsec , type , dir );
1162
- u8 action [MLX5_UN_SZ_BYTES (set_add_copy_action_in_auto )] = {};
1311
+ u8 action [3 ][ MLX5_UN_SZ_BYTES (set_add_copy_action_in_auto )] = {};
1163
1312
struct mlx5_core_dev * mdev = ipsec -> mdev ;
1164
1313
struct mlx5_modify_hdr * modify_hdr ;
1314
+ u8 num_of_actions = 1 ;
1165
1315
1166
- MLX5_SET (set_action_in , action , action_type , MLX5_ACTION_TYPE_SET );
1316
+ MLX5_SET (set_action_in , action [ 0 ] , action_type , MLX5_ACTION_TYPE_SET );
1167
1317
switch (dir ) {
1168
1318
case XFRM_DEV_OFFLOAD_IN :
1169
- MLX5_SET (set_action_in , action , field ,
1319
+ MLX5_SET (set_action_in , action [ 0 ] , field ,
1170
1320
MLX5_ACTION_IN_FIELD_METADATA_REG_B );
1321
+
1322
+ num_of_actions ++ ;
1323
+ MLX5_SET (set_action_in , action [1 ], action_type , MLX5_ACTION_TYPE_SET );
1324
+ MLX5_SET (set_action_in , action [1 ], field , MLX5_ACTION_IN_FIELD_METADATA_REG_C_2 );
1325
+ MLX5_SET (set_action_in , action [1 ], data , val );
1326
+ MLX5_SET (set_action_in , action [1 ], offset , 0 );
1327
+ MLX5_SET (set_action_in , action [1 ], length , 32 );
1328
+
1329
+ if (type == XFRM_DEV_OFFLOAD_CRYPTO ) {
1330
+ num_of_actions ++ ;
1331
+ MLX5_SET (set_action_in , action [2 ], action_type ,
1332
+ MLX5_ACTION_TYPE_SET );
1333
+ MLX5_SET (set_action_in , action [2 ], field ,
1334
+ MLX5_ACTION_IN_FIELD_METADATA_REG_C_4 );
1335
+ MLX5_SET (set_action_in , action [2 ], data , 0 );
1336
+ MLX5_SET (set_action_in , action [2 ], offset , 0 );
1337
+ MLX5_SET (set_action_in , action [2 ], length , 32 );
1338
+ }
1171
1339
break ;
1172
1340
case XFRM_DEV_OFFLOAD_OUT :
1173
- MLX5_SET (set_action_in , action , field ,
1341
+ MLX5_SET (set_action_in , action [ 0 ] , field ,
1174
1342
MLX5_ACTION_IN_FIELD_METADATA_REG_C_4 );
1175
1343
break ;
1176
1344
default :
1177
1345
return - EINVAL ;
1178
1346
}
1179
1347
1180
- MLX5_SET (set_action_in , action , data , val );
1181
- MLX5_SET (set_action_in , action , offset , 0 );
1182
- MLX5_SET (set_action_in , action , length , 32 );
1348
+ MLX5_SET (set_action_in , action [ 0 ] , data , val );
1349
+ MLX5_SET (set_action_in , action [ 0 ] , offset , 0 );
1350
+ MLX5_SET (set_action_in , action [ 0 ] , length , 32 );
1183
1351
1184
- modify_hdr = mlx5_modify_header_alloc (mdev , ns_type , 1 , action );
1352
+ modify_hdr = mlx5_modify_header_alloc (mdev , ns_type , num_of_actions , action );
1185
1353
if (IS_ERR (modify_hdr )) {
1186
1354
mlx5_core_err (mdev , "Failed to allocate modify_header %ld\n" ,
1187
1355
PTR_ERR (modify_hdr ));
@@ -1479,6 +1647,15 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
1479
1647
mlx5_core_err (mdev , "fail to add RX ipsec rule err=%d\n" , err );
1480
1648
goto err_add_flow ;
1481
1649
}
1650
+ if (attrs -> type == XFRM_DEV_OFFLOAD_PACKET )
1651
+ err = rx_add_rule_drop_replay (sa_entry , rx );
1652
+ if (err )
1653
+ goto err_add_replay ;
1654
+
1655
+ err = rx_add_rule_drop_auth_trailer (sa_entry , rx );
1656
+ if (err )
1657
+ goto err_drop_reason ;
1658
+
1482
1659
kvfree (spec );
1483
1660
1484
1661
sa_entry -> ipsec_rule .rule = rule ;
@@ -1487,6 +1664,13 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
1487
1664
sa_entry -> ipsec_rule .pkt_reformat = flow_act .pkt_reformat ;
1488
1665
return 0 ;
1489
1666
1667
+ err_drop_reason :
1668
+ if (sa_entry -> ipsec_rule .replay .rule ) {
1669
+ mlx5_del_flow_rules (sa_entry -> ipsec_rule .replay .rule );
1670
+ mlx5_fc_destroy (mdev , sa_entry -> ipsec_rule .replay .fc );
1671
+ }
1672
+ err_add_replay :
1673
+ mlx5_del_flow_rules (rule );
1490
1674
err_add_flow :
1491
1675
mlx5_fc_destroy (mdev , counter );
1492
1676
err_add_cnt :
@@ -1994,6 +2178,17 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
1994
2178
1995
2179
if (ipsec_rule -> modify_hdr )
1996
2180
mlx5_modify_header_dealloc (mdev , ipsec_rule -> modify_hdr );
2181
+
2182
+ mlx5_del_flow_rules (ipsec_rule -> trailer .rule );
2183
+ mlx5_fc_destroy (mdev , ipsec_rule -> trailer .fc );
2184
+
2185
+ mlx5_del_flow_rules (ipsec_rule -> auth .rule );
2186
+ mlx5_fc_destroy (mdev , ipsec_rule -> auth .fc );
2187
+
2188
+ if (ipsec_rule -> replay .rule ) {
2189
+ mlx5_del_flow_rules (ipsec_rule -> replay .rule );
2190
+ mlx5_fc_destroy (mdev , ipsec_rule -> replay .fc );
2191
+ }
1997
2192
mlx5_esw_ipsec_rx_id_mapping_remove (sa_entry );
1998
2193
rx_ft_put (sa_entry -> ipsec , sa_entry -> attrs .family , sa_entry -> attrs .type );
1999
2194
}
0 commit comments