Skip to content

Commit 146c196

Browse files
rleonkuba-moo
authored andcommitted
net/mlx5e: Create IPsec table with tunnel support only when encap is disabled
Current hardware doesn't support double encapsulation which is happening when IPsec packet offload tunnel mode is configured together with eswitch encap option. Any user attempt to add new SA/policy after he/she sets encap mode, will generate the following FW syndrome: mlx5_core 0000:08:00.0: mlx5_cmd_out_err:803:(pid 1904): CREATE_FLOW_TABLE(0x930) op_mod(0x0) failed, status bad parameter(0x3), syndrome (0xa43321), err(-22) Make sure that we block encap changes before creating flow steering tables. This is applicable only for packet offload in tunnel mode, while packet offload in transport mode and crypto offload, don't have such limitation as they don't perform encapsulation. Reviewed-by: Raed Salem <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Reviewed-by: Simon Horman <[email protected]> Reviewed-by: Sridhar Samudrala <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent acc1092 commit 146c196

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,14 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
668668
if (err)
669669
goto err_hw_ctx;
670670

671+
if (x->props.mode == XFRM_MODE_TUNNEL &&
672+
x->xso.type == XFRM_DEV_OFFLOAD_PACKET &&
673+
!mlx5e_ipsec_fs_tunnel_enabled(sa_entry)) {
674+
NL_SET_ERR_MSG_MOD(extack, "Packet offload tunnel mode is disabled due to encap settings");
675+
err = -EINVAL;
676+
goto err_add_rule;
677+
}
678+
671679
/* We use *_bh() variant because xfrm_timer_handler(), which runs
672680
* in softirq context, can reach our state delete logic and we need
673681
* xa_erase_bh() there.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry);
251251
int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry);
252252
void mlx5e_accel_ipsec_fs_del_pol(struct mlx5e_ipsec_pol_entry *pol_entry);
253253
void mlx5e_accel_ipsec_fs_modify(struct mlx5e_ipsec_sa_entry *sa_entry);
254+
bool mlx5e_ipsec_fs_tunnel_enabled(struct mlx5e_ipsec_sa_entry *sa_entry);
254255

255256
int mlx5_ipsec_create_sa_ctx(struct mlx5e_ipsec_sa_entry *sa_entry);
256257
void mlx5_ipsec_free_sa_ctx(struct mlx5e_ipsec_sa_entry *sa_entry);

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

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <linux/netdevice.h>
55
#include "en.h"
66
#include "en/fs.h"
7+
#include "eswitch.h"
78
#include "ipsec.h"
89
#include "fs_core.h"
910
#include "lib/ipsec_fs_roce.h"
@@ -38,6 +39,7 @@ struct mlx5e_ipsec_rx {
3839
struct mlx5e_ipsec_rule status;
3940
struct mlx5e_ipsec_fc *fc;
4041
struct mlx5_fs_chains *chains;
42+
u8 allow_tunnel_mode : 1;
4143
};
4244

4345
struct mlx5e_ipsec_tx {
@@ -47,6 +49,7 @@ struct mlx5e_ipsec_tx {
4749
struct mlx5_flow_namespace *ns;
4850
struct mlx5e_ipsec_fc *fc;
4951
struct mlx5_fs_chains *chains;
52+
u8 allow_tunnel_mode : 1;
5053
};
5154

5255
/* IPsec RX flow steering */
@@ -254,7 +257,8 @@ static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
254257
mlx5_del_flow_rules(rx->sa.rule);
255258
mlx5_destroy_flow_group(rx->sa.group);
256259
mlx5_destroy_flow_table(rx->ft.sa);
257-
260+
if (rx->allow_tunnel_mode)
261+
mlx5_eswitch_unblock_encap(mdev);
258262
mlx5_del_flow_rules(rx->status.rule);
259263
mlx5_modify_header_dealloc(mdev, rx->status.modify_hdr);
260264
mlx5_destroy_flow_table(rx->ft.status);
@@ -305,6 +309,8 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
305309

306310
/* Create FT */
307311
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_TUNNEL)
312+
rx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
313+
if (rx->allow_tunnel_mode)
308314
flags = MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
309315
ft = ipsec_ft_create(ns, MLX5E_ACCEL_FS_ESP_FT_LEVEL, MLX5E_NIC_PRIO, 2,
310316
flags);
@@ -362,6 +368,8 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
362368
err_fs:
363369
mlx5_destroy_flow_table(rx->ft.sa);
364370
err_fs_ft:
371+
if (rx->allow_tunnel_mode)
372+
mlx5_eswitch_unblock_encap(mdev);
365373
mlx5_del_flow_rules(rx->status.rule);
366374
mlx5_modify_header_dealloc(mdev, rx->status.modify_hdr);
367375
err_add:
@@ -496,7 +504,8 @@ static int ipsec_counter_rule_tx(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_
496504
}
497505

498506
/* IPsec TX flow steering */
499-
static void tx_destroy(struct mlx5e_ipsec_tx *tx, struct mlx5_ipsec_fs *roce)
507+
static void tx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,
508+
struct mlx5_ipsec_fs *roce)
500509
{
501510
mlx5_ipsec_fs_roce_tx_destroy(roce);
502511
if (tx->chains) {
@@ -508,6 +517,8 @@ static void tx_destroy(struct mlx5e_ipsec_tx *tx, struct mlx5_ipsec_fs *roce)
508517
}
509518

510519
mlx5_destroy_flow_table(tx->ft.sa);
520+
if (tx->allow_tunnel_mode)
521+
mlx5_eswitch_unblock_encap(mdev);
511522
mlx5_del_flow_rules(tx->status.rule);
512523
mlx5_destroy_flow_table(tx->ft.status);
513524
}
@@ -530,6 +541,8 @@ static int tx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,
530541
goto err_status_rule;
531542

532543
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_TUNNEL)
544+
tx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
545+
if (tx->allow_tunnel_mode)
533546
flags = MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
534547
ft = ipsec_ft_create(tx->ns, 1, 0, 4, flags);
535548
if (IS_ERR(ft)) {
@@ -581,6 +594,8 @@ static int tx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,
581594
err_pol_ft:
582595
mlx5_destroy_flow_table(tx->ft.sa);
583596
err_sa_ft:
597+
if (tx->allow_tunnel_mode)
598+
mlx5_eswitch_unblock_encap(mdev);
584599
mlx5_del_flow_rules(tx->status.rule);
585600
err_status_rule:
586601
mlx5_destroy_flow_table(tx->ft.status);
@@ -609,7 +624,7 @@ static void tx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx)
609624
if (--tx->ft.refcnt)
610625
return;
611626

612-
tx_destroy(tx, ipsec->roce);
627+
tx_destroy(ipsec->mdev, tx, ipsec->roce);
613628
}
614629

615630
static struct mlx5_flow_table *tx_ft_get_policy(struct mlx5_core_dev *mdev,
@@ -1603,3 +1618,15 @@ void mlx5e_accel_ipsec_fs_modify(struct mlx5e_ipsec_sa_entry *sa_entry)
16031618
mlx5e_accel_ipsec_fs_del_rule(sa_entry);
16041619
memcpy(sa_entry, &sa_entry_shadow, sizeof(*sa_entry));
16051620
}
1621+
1622+
bool mlx5e_ipsec_fs_tunnel_enabled(struct mlx5e_ipsec_sa_entry *sa_entry)
1623+
{
1624+
struct mlx5e_ipsec_rx *rx =
1625+
ipsec_rx(sa_entry->ipsec, sa_entry->attrs.family);
1626+
struct mlx5e_ipsec_tx *tx = sa_entry->ipsec->tx;
1627+
1628+
if (sa_entry->attrs.dir == XFRM_DEV_OFFLOAD_OUT)
1629+
return tx->allow_tunnel_mode;
1630+
1631+
return rx->allow_tunnel_mode;
1632+
}

0 commit comments

Comments
 (0)