Skip to content

Commit dfbd229

Browse files
PatrisiousHaddadrleon
authored andcommitted
net/mlx5: Configure IPsec steering for egress RoCEv2 MPV traffic
Add steering tables/rules in RDMA_TX master domain, to forward all traffic to IPsec crypto table in NIC domain. But in case the traffic is coming from the slave, have to first send the traffic to an alias table in order to switch gvmi and from there we can go to the appropriate gvmi crypto table in NIC domain. Signed-off-by: Patrisious Haddad <phaddad@nvidia.com> Reviewed-by: Mark Bloch <mbloch@nvidia.com> Link: https://lore.kernel.org/r/7ca5cf1ac5c6979359b8726e97510574e2b3d44d.1695296682.git.leon@kernel.org Signed-off-by: Leon Romanovsky <leon@kernel.org>
1 parent 69c08ef commit dfbd229

4 files changed

Lines changed: 225 additions & 7 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -562,7 +562,7 @@ static int ipsec_counter_rule_tx(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_
562562
static void tx_destroy(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
563563
struct mlx5_ipsec_fs *roce)
564564
{
565-
mlx5_ipsec_fs_roce_tx_destroy(roce);
565+
mlx5_ipsec_fs_roce_tx_destroy(roce, ipsec->mdev);
566566
if (tx->chains) {
567567
ipsec_chains_destroy(tx->chains);
568568
} else {

drivers/net/ethernet/mellanox/mlx5/core/fs_core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
#define LAG_MIN_LEVEL (OFFLOADS_MIN_LEVEL + KERNEL_RX_MACSEC_MIN_LEVEL + 1)
138138

139139
#define KERNEL_TX_IPSEC_NUM_PRIOS 1
140-
#define KERNEL_TX_IPSEC_NUM_LEVELS 3
140+
#define KERNEL_TX_IPSEC_NUM_LEVELS 4
141141
#define KERNEL_TX_IPSEC_MIN_LEVEL (KERNEL_TX_IPSEC_NUM_LEVELS)
142142

143143
#define KERNEL_TX_MACSEC_NUM_PRIOS 1
@@ -288,7 +288,7 @@ enum {
288288
#define RDMA_TX_BYPASS_MIN_LEVEL MLX5_BY_PASS_NUM_PRIOS
289289
#define RDMA_TX_COUNTERS_MIN_LEVEL (RDMA_TX_BYPASS_MIN_LEVEL + 1)
290290

291-
#define RDMA_TX_IPSEC_NUM_PRIOS 1
291+
#define RDMA_TX_IPSEC_NUM_PRIOS 2
292292
#define RDMA_TX_IPSEC_PRIO_NUM_LEVELS 1
293293
#define RDMA_TX_IPSEC_MIN_LEVEL (RDMA_TX_COUNTERS_MIN_LEVEL + RDMA_TX_IPSEC_NUM_PRIOS)
294294

drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec_fs_roce.c

Lines changed: 220 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
/* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
33

44
#include "fs_core.h"
5+
#include "fs_cmd.h"
6+
#include "en.h"
57
#include "lib/ipsec_fs_roce.h"
68
#include "mlx5_core.h"
79
#include <linux/random.h>
@@ -25,6 +27,8 @@ struct mlx5_ipsec_tx_roce {
2527
struct mlx5_flow_group *g;
2628
struct mlx5_flow_table *ft;
2729
struct mlx5_flow_handle *rule;
30+
struct mlx5_flow_table *goto_alias_ft;
31+
u32 alias_id;
2832
struct mlx5_flow_namespace *ns;
2933
};
3034

@@ -187,9 +191,200 @@ static int ipsec_fs_roce_tx_rule_setup(struct mlx5_core_dev *mdev,
187191
return err;
188192
}
189193

190-
void mlx5_ipsec_fs_roce_tx_destroy(struct mlx5_ipsec_fs *ipsec_roce)
194+
static int ipsec_fs_roce_tx_mpv_rule_setup(struct mlx5_core_dev *mdev,
195+
struct mlx5_ipsec_tx_roce *roce,
196+
struct mlx5_flow_table *pol_ft)
191197
{
198+
struct mlx5_flow_destination dst = {};
199+
MLX5_DECLARE_FLOW_ACT(flow_act);
200+
struct mlx5_flow_handle *rule;
201+
struct mlx5_flow_spec *spec;
202+
int err = 0;
203+
204+
spec = kvzalloc(sizeof(*spec), GFP_KERNEL);
205+
if (!spec)
206+
return -ENOMEM;
207+
208+
spec->match_criteria_enable = MLX5_MATCH_MISC_PARAMETERS;
209+
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, misc_parameters.source_vhca_port);
210+
MLX5_SET(fte_match_param, spec->match_value, misc_parameters.source_vhca_port,
211+
MLX5_CAP_GEN(mdev, native_port_num));
212+
213+
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
214+
dst.type = MLX5_FLOW_DESTINATION_TYPE_TABLE_TYPE;
215+
dst.ft = roce->goto_alias_ft;
216+
rule = mlx5_add_flow_rules(roce->ft, spec, &flow_act, &dst, 1);
217+
if (IS_ERR(rule)) {
218+
err = PTR_ERR(rule);
219+
mlx5_core_err(mdev, "Fail to add TX RoCE IPsec rule err=%d\n",
220+
err);
221+
goto out;
222+
}
223+
roce->rule = rule;
224+
225+
/* No need for miss rule, since on miss we go to next PRIO, in which
226+
* if master is configured, he will catch the traffic to go to his
227+
* encryption table.
228+
*/
229+
230+
out:
231+
kvfree(spec);
232+
return err;
233+
}
234+
235+
#define MLX5_TX_ROCE_GROUP_SIZE BIT(0)
236+
#define MLX5_IPSEC_RDMA_TX_FT_LEVEL 0
237+
#define MLX5_IPSEC_NIC_GOTO_ALIAS_FT_LEVEL 3 /* Since last used level in NIC ipsec is 2 */
238+
239+
static int ipsec_fs_roce_tx_mpv_create_ft(struct mlx5_core_dev *mdev,
240+
struct mlx5_ipsec_tx_roce *roce,
241+
struct mlx5_flow_table *pol_ft,
242+
struct mlx5e_priv *peer_priv)
243+
{
244+
struct mlx5_flow_namespace *roce_ns, *nic_ns;
245+
struct mlx5_flow_table_attr ft_attr = {};
246+
struct mlx5_flow_table next_ft;
247+
struct mlx5_flow_table *ft;
248+
int err;
249+
250+
roce_ns = mlx5_get_flow_namespace(peer_priv->mdev, MLX5_FLOW_NAMESPACE_RDMA_TX_IPSEC);
251+
if (!roce_ns)
252+
return -EOPNOTSUPP;
253+
254+
nic_ns = mlx5_get_flow_namespace(peer_priv->mdev, MLX5_FLOW_NAMESPACE_EGRESS_IPSEC);
255+
if (!nic_ns)
256+
return -EOPNOTSUPP;
257+
258+
err = ipsec_fs_create_aliased_ft(mdev, peer_priv->mdev, pol_ft, &roce->alias_id);
259+
if (err)
260+
return err;
261+
262+
next_ft.id = roce->alias_id;
263+
ft_attr.max_fte = 1;
264+
ft_attr.next_ft = &next_ft;
265+
ft_attr.level = MLX5_IPSEC_NIC_GOTO_ALIAS_FT_LEVEL;
266+
ft_attr.flags = MLX5_FLOW_TABLE_UNMANAGED;
267+
ft = mlx5_create_flow_table(nic_ns, &ft_attr);
268+
if (IS_ERR(ft)) {
269+
err = PTR_ERR(ft);
270+
mlx5_core_err(mdev, "Fail to create RoCE IPsec goto alias ft err=%d\n", err);
271+
goto destroy_alias;
272+
}
273+
274+
roce->goto_alias_ft = ft;
275+
276+
memset(&ft_attr, 0, sizeof(ft_attr));
277+
ft_attr.max_fte = 1;
278+
ft_attr.level = MLX5_IPSEC_RDMA_TX_FT_LEVEL;
279+
ft = mlx5_create_flow_table(roce_ns, &ft_attr);
280+
if (IS_ERR(ft)) {
281+
err = PTR_ERR(ft);
282+
mlx5_core_err(mdev, "Fail to create RoCE IPsec tx ft err=%d\n", err);
283+
goto destroy_alias_ft;
284+
}
285+
286+
roce->ft = ft;
287+
288+
return 0;
289+
290+
destroy_alias_ft:
291+
mlx5_destroy_flow_table(roce->goto_alias_ft);
292+
destroy_alias:
293+
mlx5_cmd_alias_obj_destroy(peer_priv->mdev, roce->alias_id,
294+
MLX5_GENERAL_OBJECT_TYPES_FLOW_TABLE_ALIAS);
295+
return err;
296+
}
297+
298+
static int ipsec_fs_roce_tx_mpv_create_group_rules(struct mlx5_core_dev *mdev,
299+
struct mlx5_ipsec_tx_roce *roce,
300+
struct mlx5_flow_table *pol_ft,
301+
u32 *in)
302+
{
303+
struct mlx5_flow_group *g;
304+
int ix = 0;
305+
int err;
306+
u8 *mc;
307+
308+
mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria);
309+
MLX5_SET_TO_ONES(fte_match_param, mc, misc_parameters.source_vhca_port);
310+
MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_MISC_PARAMETERS);
311+
312+
MLX5_SET_CFG(in, start_flow_index, ix);
313+
ix += MLX5_TX_ROCE_GROUP_SIZE;
314+
MLX5_SET_CFG(in, end_flow_index, ix - 1);
315+
g = mlx5_create_flow_group(roce->ft, in);
316+
if (IS_ERR(g)) {
317+
err = PTR_ERR(g);
318+
mlx5_core_err(mdev, "Fail to create RoCE IPsec tx group err=%d\n", err);
319+
return err;
320+
}
321+
roce->g = g;
322+
323+
err = ipsec_fs_roce_tx_mpv_rule_setup(mdev, roce, pol_ft);
324+
if (err) {
325+
mlx5_core_err(mdev, "Fail to create RoCE IPsec tx rules err=%d\n", err);
326+
goto destroy_group;
327+
}
328+
329+
return 0;
330+
331+
destroy_group:
332+
mlx5_destroy_flow_group(roce->g);
333+
return err;
334+
}
335+
336+
static int ipsec_fs_roce_tx_mpv_create(struct mlx5_core_dev *mdev,
337+
struct mlx5_ipsec_fs *ipsec_roce,
338+
struct mlx5_flow_table *pol_ft,
339+
u32 *in)
340+
{
341+
struct mlx5_devcom_comp_dev *tmp = NULL;
342+
struct mlx5_ipsec_tx_roce *roce;
343+
struct mlx5e_priv *peer_priv;
344+
int err;
345+
346+
if (!mlx5_devcom_for_each_peer_begin(*ipsec_roce->devcom))
347+
return -EOPNOTSUPP;
348+
349+
peer_priv = mlx5_devcom_get_next_peer_data(*ipsec_roce->devcom, &tmp);
350+
if (!peer_priv) {
351+
err = -EOPNOTSUPP;
352+
goto release_peer;
353+
}
354+
355+
roce = &ipsec_roce->tx;
356+
357+
err = ipsec_fs_roce_tx_mpv_create_ft(mdev, roce, pol_ft, peer_priv);
358+
if (err) {
359+
mlx5_core_err(mdev, "Fail to create RoCE IPsec tables err=%d\n", err);
360+
goto release_peer;
361+
}
362+
363+
err = ipsec_fs_roce_tx_mpv_create_group_rules(mdev, roce, pol_ft, in);
364+
if (err) {
365+
mlx5_core_err(mdev, "Fail to create RoCE IPsec tx group/rule err=%d\n", err);
366+
goto destroy_tables;
367+
}
368+
369+
mlx5_devcom_for_each_peer_end(*ipsec_roce->devcom);
370+
return 0;
371+
372+
destroy_tables:
373+
mlx5_destroy_flow_table(roce->ft);
374+
mlx5_destroy_flow_table(roce->goto_alias_ft);
375+
mlx5_cmd_alias_obj_destroy(peer_priv->mdev, roce->alias_id,
376+
MLX5_GENERAL_OBJECT_TYPES_FLOW_TABLE_ALIAS);
377+
release_peer:
378+
mlx5_devcom_for_each_peer_end(*ipsec_roce->devcom);
379+
return err;
380+
}
381+
382+
void mlx5_ipsec_fs_roce_tx_destroy(struct mlx5_ipsec_fs *ipsec_roce,
383+
struct mlx5_core_dev *mdev)
384+
{
385+
struct mlx5_devcom_comp_dev *tmp = NULL;
192386
struct mlx5_ipsec_tx_roce *tx_roce;
387+
struct mlx5e_priv *peer_priv;
193388

194389
if (!ipsec_roce)
195390
return;
@@ -199,9 +394,24 @@ void mlx5_ipsec_fs_roce_tx_destroy(struct mlx5_ipsec_fs *ipsec_roce)
199394
mlx5_del_flow_rules(tx_roce->rule);
200395
mlx5_destroy_flow_group(tx_roce->g);
201396
mlx5_destroy_flow_table(tx_roce->ft);
202-
}
203397

204-
#define MLX5_TX_ROCE_GROUP_SIZE BIT(0)
398+
if (!mlx5_core_is_mp_slave(mdev))
399+
return;
400+
401+
if (!mlx5_devcom_for_each_peer_begin(*ipsec_roce->devcom))
402+
return;
403+
404+
peer_priv = mlx5_devcom_get_next_peer_data(*ipsec_roce->devcom, &tmp);
405+
if (!peer_priv) {
406+
mlx5_devcom_for_each_peer_end(*ipsec_roce->devcom);
407+
return;
408+
}
409+
410+
mlx5_destroy_flow_table(tx_roce->goto_alias_ft);
411+
mlx5_cmd_alias_obj_destroy(peer_priv->mdev, tx_roce->alias_id,
412+
MLX5_GENERAL_OBJECT_TYPES_FLOW_TABLE_ALIAS);
413+
mlx5_devcom_for_each_peer_end(*ipsec_roce->devcom);
414+
}
205415

206416
int mlx5_ipsec_fs_roce_tx_create(struct mlx5_core_dev *mdev,
207417
struct mlx5_ipsec_fs *ipsec_roce,
@@ -224,7 +434,14 @@ int mlx5_ipsec_fs_roce_tx_create(struct mlx5_core_dev *mdev,
224434
if (!in)
225435
return -ENOMEM;
226436

437+
if (mlx5_core_is_mp_slave(mdev)) {
438+
err = ipsec_fs_roce_tx_mpv_create(mdev, ipsec_roce, pol_ft, in);
439+
goto free_in;
440+
}
441+
227442
ft_attr.max_fte = 1;
443+
ft_attr.prio = 1;
444+
ft_attr.level = MLX5_IPSEC_RDMA_TX_FT_LEVEL;
228445
ft = mlx5_create_flow_table(roce->ns, &ft_attr);
229446
if (IS_ERR(ft)) {
230447
err = PTR_ERR(ft);

drivers/net/ethernet/mellanox/mlx5/core/lib/ipsec_fs_roce.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ int mlx5_ipsec_fs_roce_rx_create(struct mlx5_core_dev *mdev,
1717
struct mlx5_flow_namespace *ns,
1818
struct mlx5_flow_destination *default_dst,
1919
u32 family, u32 level, u32 prio);
20-
void mlx5_ipsec_fs_roce_tx_destroy(struct mlx5_ipsec_fs *ipsec_roce);
20+
void mlx5_ipsec_fs_roce_tx_destroy(struct mlx5_ipsec_fs *ipsec_roce,
21+
struct mlx5_core_dev *mdev);
2122
int mlx5_ipsec_fs_roce_tx_create(struct mlx5_core_dev *mdev,
2223
struct mlx5_ipsec_fs *ipsec_roce,
2324
struct mlx5_flow_table *pol_ft);

0 commit comments

Comments
 (0)