Skip to content

Commit dddb49b

Browse files
PatrisiousHaddadSaeed Mahameed
authored andcommitted
net/mlx5e: Add IPsec and ASO syndromes check in HW
After IPsec decryption it isn't enough to only check the IPsec syndrome but need to also check the ASO syndrome in order to verify that the operation was actually successful. Verify that both syndromes are actually zero and in case not drop the packet and increment the appropriate flow counter for the drop reason. Fixes: 6b5c45e ("net/mlx5e: Configure IPsec packet offload flow steering") Signed-off-by: Patrisious Haddad <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]>
1 parent 5ad00de commit dddb49b

File tree

2 files changed

+223
-20
lines changed

2 files changed

+223
-20
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,19 @@ struct mlx5e_ipsec_ft {
189189
u32 refcnt;
190190
};
191191

192+
struct mlx5e_ipsec_drop {
193+
struct mlx5_flow_handle *rule;
194+
struct mlx5_fc *fc;
195+
};
196+
192197
struct mlx5e_ipsec_rule {
193198
struct mlx5_flow_handle *rule;
194199
struct mlx5_modify_hdr *modify_hdr;
195200
struct mlx5_pkt_reformat *pkt_reformat;
196201
struct mlx5_fc *fc;
202+
struct mlx5e_ipsec_drop replay;
203+
struct mlx5e_ipsec_drop auth;
204+
struct mlx5e_ipsec_drop trailer;
197205
};
198206

199207
struct mlx5e_ipsec_miss {

drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c

Lines changed: 215 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@ struct mlx5e_ipsec_tx {
3232
u8 allow_tunnel_mode : 1;
3333
};
3434

35+
struct mlx5e_ipsec_status_checks {
36+
struct mlx5_flow_group *drop_all_group;
37+
struct mlx5e_ipsec_drop all;
38+
};
39+
3540
struct mlx5e_ipsec_rx {
3641
struct mlx5e_ipsec_ft ft;
3742
struct mlx5e_ipsec_miss pol;
3843
struct mlx5e_ipsec_miss sa;
3944
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;
4246
struct mlx5e_ipsec_fc *fc;
4347
struct mlx5_fs_chains *chains;
4448
u8 allow_tunnel_mode : 1;
@@ -143,9 +147,9 @@ static struct mlx5_flow_table *ipsec_ft_create(struct mlx5_flow_namespace *ns,
143147
static void ipsec_rx_status_drop_destroy(struct mlx5e_ipsec *ipsec,
144148
struct mlx5e_ipsec_rx *rx)
145149
{
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);
149153
}
150154

151155
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,
161165
#endif
162166
}
163167

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)
166311
{
167312
int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
168313
struct mlx5_flow_table *ft = rx->ft.status;
@@ -214,9 +359,9 @@ static int ipsec_rx_status_drop_create(struct mlx5e_ipsec *ipsec,
214359
goto err_rule;
215360
}
216361

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;
220365

221366
kvfree(flow_group_in);
222367
kvfree(spec);
@@ -247,8 +392,12 @@ static int ipsec_rx_status_pass_create(struct mlx5e_ipsec *ipsec,
247392

248393
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
249394
misc_parameters_2.ipsec_syndrome);
395+
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
396+
misc_parameters_2.metadata_reg_c_4);
250397
MLX5_SET(fte_match_param, spec->match_value,
251398
misc_parameters_2.ipsec_syndrome, 0);
399+
MLX5_SET(fte_match_param, spec->match_value,
400+
misc_parameters_2.metadata_reg_c_4, 0);
252401
if (rx == ipsec->rx_esw)
253402
spec->flow_context.flow_source = MLX5_FLOW_CONTEXT_FLOW_SOURCE_UPLINK;
254403
spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS_2;
@@ -285,7 +434,7 @@ static int mlx5_ipsec_rx_status_create(struct mlx5e_ipsec *ipsec,
285434
{
286435
int err;
287436

288-
err = ipsec_rx_status_drop_create(ipsec, rx);
437+
err = ipsec_rx_status_drop_all_create(ipsec, rx);
289438
if (err)
290439
return err;
291440

@@ -529,7 +678,7 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
529678
if (err)
530679
return err;
531680

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);
533682
if (IS_ERR(ft)) {
534683
err = PTR_ERR(ft);
535684
goto err_fs_ft_status;
@@ -1159,29 +1308,48 @@ static int setup_modify_header(struct mlx5e_ipsec *ipsec, int type, u32 val, u8
11591308
struct mlx5_flow_act *flow_act)
11601309
{
11611310
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)] = {};
11631312
struct mlx5_core_dev *mdev = ipsec->mdev;
11641313
struct mlx5_modify_hdr *modify_hdr;
1314+
u8 num_of_actions = 1;
11651315

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);
11671317
switch (dir) {
11681318
case XFRM_DEV_OFFLOAD_IN:
1169-
MLX5_SET(set_action_in, action, field,
1319+
MLX5_SET(set_action_in, action[0], field,
11701320
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+
}
11711339
break;
11721340
case XFRM_DEV_OFFLOAD_OUT:
1173-
MLX5_SET(set_action_in, action, field,
1341+
MLX5_SET(set_action_in, action[0], field,
11741342
MLX5_ACTION_IN_FIELD_METADATA_REG_C_4);
11751343
break;
11761344
default:
11771345
return -EINVAL;
11781346
}
11791347

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);
11831351

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);
11851353
if (IS_ERR(modify_hdr)) {
11861354
mlx5_core_err(mdev, "Failed to allocate modify_header %ld\n",
11871355
PTR_ERR(modify_hdr));
@@ -1479,6 +1647,15 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
14791647
mlx5_core_err(mdev, "fail to add RX ipsec rule err=%d\n", err);
14801648
goto err_add_flow;
14811649
}
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+
14821659
kvfree(spec);
14831660

14841661
sa_entry->ipsec_rule.rule = rule;
@@ -1487,6 +1664,13 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
14871664
sa_entry->ipsec_rule.pkt_reformat = flow_act.pkt_reformat;
14881665
return 0;
14891666

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);
14901674
err_add_flow:
14911675
mlx5_fc_destroy(mdev, counter);
14921676
err_add_cnt:
@@ -1994,6 +2178,17 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
19942178

19952179
if (ipsec_rule->modify_hdr)
19962180
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+
}
19972192
mlx5_esw_ipsec_rx_id_mapping_remove(sa_entry);
19982193
rx_ft_put(sa_entry->ipsec, sa_entry->attrs.family, sa_entry->attrs.type);
19992194
}

0 commit comments

Comments
 (0)