Skip to content

Commit c6c2bf5

Browse files
Jianbo Liukuba-moo
authored andcommitted
net/mlx5e: Support IPsec packet offload for TX in switchdev mode
The IPsec encryption is done at the last, so add new prio for IPsec offload in FDB, and put it just lower than the slow path prio and higher than the per-vport prio. Three levels are added for TX. The first one is for ip xfrm policy. The sa table is created in the second level for ip xfrm state. The status table is created at the last to count the number of packets encrypted. The rules, which forward packets to uplink, are changed to forward them to IPsec TX tables first. These rules are restored after those tables are destroyed, which is done immediately when there is no reference to them, just as what does in legacy mode. The support for slow path is added here, by refreshing uplink's channels. But, the handling for TC fast path, which is more complicated, will be added later. Besides, reg c4 is used instead to match reqid. Signed-off-by: Jianbo Liu <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Link: https://lore.kernel.org/r/cfd0e6ffaf0b8c55ebaa9fb0649b7c504b6b8ec6.1690802064.git.leon@kernel.org Signed-off-by: Jakub Kicinski <[email protected]>
1 parent f46e92d commit c6c2bf5

File tree

7 files changed

+101
-9
lines changed

7 files changed

+101
-9
lines changed

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

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "lib/ipsec_fs_roce.h"
1111
#include "lib/fs_chains.h"
1212
#include "esw/ipsec_fs.h"
13+
#include "en_rep.h"
1314

1415
#define NUM_IPSEC_FTE BIT(15)
1516
#define MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_SIZE 16
@@ -23,6 +24,7 @@ struct mlx5e_ipsec_fc {
2324
struct mlx5e_ipsec_tx {
2425
struct mlx5e_ipsec_ft ft;
2526
struct mlx5e_ipsec_miss pol;
27+
struct mlx5e_ipsec_miss sa;
2628
struct mlx5e_ipsec_rule status;
2729
struct mlx5_flow_namespace *ns;
2830
struct mlx5e_ipsec_fc *fc;
@@ -550,7 +552,7 @@ static int ipsec_counter_rule_tx(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_
550552
}
551553

552554
/* IPsec TX flow steering */
553-
static void tx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,
555+
static void tx_destroy(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
554556
struct mlx5_ipsec_fs *roce)
555557
{
556558
mlx5_ipsec_fs_roce_tx_destroy(roce);
@@ -562,9 +564,13 @@ static void tx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec_tx *tx,
562564
mlx5_destroy_flow_table(tx->ft.pol);
563565
}
564566

567+
if (tx == ipsec->tx_esw) {
568+
mlx5_del_flow_rules(tx->sa.rule);
569+
mlx5_destroy_flow_group(tx->sa.group);
570+
}
565571
mlx5_destroy_flow_table(tx->ft.sa);
566572
if (tx->allow_tunnel_mode)
567-
mlx5_eswitch_unblock_encap(mdev);
573+
mlx5_eswitch_unblock_encap(ipsec->mdev);
568574
mlx5_del_flow_rules(tx->status.rule);
569575
mlx5_destroy_flow_table(tx->ft.status);
570576
}
@@ -573,6 +579,11 @@ static void ipsec_tx_create_attr_set(struct mlx5e_ipsec *ipsec,
573579
struct mlx5e_ipsec_tx *tx,
574580
struct mlx5e_ipsec_tx_create_attr *attr)
575581
{
582+
if (tx == ipsec->tx_esw) {
583+
mlx5_esw_ipsec_tx_create_attr_set(ipsec, attr);
584+
return;
585+
}
586+
576587
attr->prio = 0;
577588
attr->pol_level = 0;
578589
attr->sa_level = 1;
@@ -611,6 +622,15 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
611622
}
612623
tx->ft.sa = ft;
613624

625+
if (tx == ipsec->tx_esw) {
626+
dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
627+
dest.vport.num = MLX5_VPORT_UPLINK;
628+
err = ipsec_miss_create(mdev, tx->ft.sa, &tx->sa, &dest);
629+
if (err)
630+
goto err_sa_miss;
631+
memset(&dest, 0, sizeof(dest));
632+
}
633+
614634
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_PRIO) {
615635
tx->chains = ipsec_chains_create(
616636
mdev, tx->ft.sa, attr.chains_ns, attr.prio, attr.pol_level,
@@ -652,6 +672,11 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
652672
mlx5_destroy_flow_table(tx->ft.pol);
653673
}
654674
err_pol_ft:
675+
if (tx == ipsec->tx_esw) {
676+
mlx5_del_flow_rules(tx->sa.rule);
677+
mlx5_destroy_flow_group(tx->sa.group);
678+
}
679+
err_sa_miss:
655680
mlx5_destroy_flow_table(tx->ft.sa);
656681
err_sa_ft:
657682
if (tx->allow_tunnel_mode)
@@ -662,6 +687,25 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
662687
return err;
663688
}
664689

690+
static void ipsec_esw_tx_ft_policy_set(struct mlx5_core_dev *mdev,
691+
struct mlx5_flow_table *ft)
692+
{
693+
#ifdef CONFIG_MLX5_ESWITCH
694+
struct mlx5_eswitch *esw = mdev->priv.eswitch;
695+
struct mlx5e_rep_priv *uplink_rpriv;
696+
struct mlx5e_priv *priv;
697+
698+
esw->offloads.ft_ipsec_tx_pol = ft;
699+
uplink_rpriv = mlx5_eswitch_get_uplink_priv(esw, REP_ETH);
700+
priv = netdev_priv(uplink_rpriv->netdev);
701+
if (!priv->channels.num)
702+
return;
703+
704+
mlx5e_rep_deactivate_channels(priv);
705+
mlx5e_rep_activate_channels(priv);
706+
#endif
707+
}
708+
665709
static int tx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
666710
struct mlx5e_ipsec_tx *tx)
667711
{
@@ -674,6 +718,9 @@ static int tx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
674718
if (err)
675719
return err;
676720

721+
if (tx == ipsec->tx_esw)
722+
ipsec_esw_tx_ft_policy_set(mdev, tx->ft.pol);
723+
677724
skip:
678725
tx->ft.refcnt++;
679726
return 0;
@@ -684,7 +731,10 @@ static void tx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx)
684731
if (--tx->ft.refcnt)
685732
return;
686733

687-
tx_destroy(ipsec->mdev, tx, ipsec->roce);
734+
if (tx == ipsec->tx_esw)
735+
ipsec_esw_tx_ft_policy_set(ipsec->mdev, NULL);
736+
737+
tx_destroy(ipsec, tx, ipsec->roce);
688738
}
689739

690740
static struct mlx5_flow_table *tx_ft_get_policy(struct mlx5_core_dev *mdev,
@@ -842,15 +892,15 @@ static void setup_fte_reg_a(struct mlx5_flow_spec *spec)
842892
misc_parameters_2.metadata_reg_a, MLX5_ETH_WQE_FT_META_IPSEC);
843893
}
844894

845-
static void setup_fte_reg_c0(struct mlx5_flow_spec *spec, u32 reqid)
895+
static void setup_fte_reg_c4(struct mlx5_flow_spec *spec, u32 reqid)
846896
{
847897
/* Pass policy check before choosing this SA */
848898
spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_2;
849899

850-
MLX5_SET(fte_match_param, spec->match_criteria,
851-
misc_parameters_2.metadata_reg_c_0, reqid);
900+
MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria,
901+
misc_parameters_2.metadata_reg_c_4);
852902
MLX5_SET(fte_match_param, spec->match_value,
853-
misc_parameters_2.metadata_reg_c_0, reqid);
903+
misc_parameters_2.metadata_reg_c_4, reqid);
854904
}
855905

856906
static void setup_fte_upper_proto_match(struct mlx5_flow_spec *spec, struct upspec *upspec)
@@ -902,7 +952,7 @@ static int setup_modify_header(struct mlx5e_ipsec *ipsec, int type, u32 val, u8
902952
break;
903953
case XFRM_DEV_OFFLOAD_OUT:
904954
MLX5_SET(set_action_in, action, field,
905-
MLX5_ACTION_IN_FIELD_METADATA_REG_C_0);
955+
MLX5_ACTION_IN_FIELD_METADATA_REG_C_4);
906956
break;
907957
default:
908958
return -EINVAL;
@@ -1268,7 +1318,7 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
12681318
break;
12691319
case XFRM_DEV_OFFLOAD_PACKET:
12701320
if (attrs->reqid)
1271-
setup_fte_reg_c0(spec, attrs->reqid);
1321+
setup_fte_reg_c4(spec, attrs->reqid);
12721322
err = setup_pkt_reformat(ipsec, attrs, &flow_act);
12731323
if (err)
12741324
goto err_pkt_reformat;
@@ -1379,6 +1429,8 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
13791429
}
13801430

13811431
flow_act.flags |= FLOW_ACT_NO_APPEND;
1432+
if (tx == ipsec->tx_esw && tx->chains)
1433+
flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
13821434
dest[dstn].ft = tx->ft.sa;
13831435
dest[dstn].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
13841436
dstn++;

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ enum {
1212
MLX5_ESW_IPSEC_RX_ESP_FT_CHK_LEVEL,
1313
};
1414

15+
enum {
16+
MLX5_ESW_IPSEC_TX_POL_FT_LEVEL,
17+
MLX5_ESW_IPSEC_TX_ESP_FT_LEVEL,
18+
MLX5_ESW_IPSEC_TX_ESP_FT_CNT_LEVEL,
19+
};
20+
1521
static void esw_ipsec_rx_status_drop_destroy(struct mlx5e_ipsec *ipsec,
1622
struct mlx5e_ipsec_rx *rx)
1723
{
@@ -251,3 +257,13 @@ int mlx5_esw_ipsec_rx_ipsec_obj_id_search(struct mlx5e_priv *priv, u32 id,
251257

252258
return 0;
253259
}
260+
261+
void mlx5_esw_ipsec_tx_create_attr_set(struct mlx5e_ipsec *ipsec,
262+
struct mlx5e_ipsec_tx_create_attr *attr)
263+
{
264+
attr->prio = FDB_CRYPTO_EGRESS;
265+
attr->pol_level = MLX5_ESW_IPSEC_TX_POL_FT_LEVEL;
266+
attr->sa_level = MLX5_ESW_IPSEC_TX_ESP_FT_LEVEL;
267+
attr->cnt_level = MLX5_ESW_IPSEC_TX_ESP_FT_CNT_LEVEL;
268+
attr->chains_ns = MLX5_FLOW_NAMESPACE_FDB;
269+
}

drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ int mlx5_esw_ipsec_rx_setup_modify_header(struct mlx5e_ipsec_sa_entry *sa_entry,
2222
void mlx5_esw_ipsec_rx_id_mapping_remove(struct mlx5e_ipsec_sa_entry *sa_entry);
2323
int mlx5_esw_ipsec_rx_ipsec_obj_id_search(struct mlx5e_priv *priv, u32 id,
2424
u32 *ipsec_obj_id);
25+
void mlx5_esw_ipsec_tx_create_attr_set(struct mlx5e_ipsec *ipsec,
26+
struct mlx5e_ipsec_tx_create_attr *attr);
2527
#else
2628
static inline void mlx5_esw_ipsec_rx_status_destroy(struct mlx5e_ipsec *ipsec,
2729
struct mlx5e_ipsec_rx *rx) {}
@@ -55,5 +57,8 @@ static inline int mlx5_esw_ipsec_rx_ipsec_obj_id_search(struct mlx5e_priv *priv,
5557
{
5658
return -EINVAL;
5759
}
60+
61+
static inline void mlx5_esw_ipsec_tx_create_attr_set(struct mlx5e_ipsec *ipsec,
62+
struct mlx5e_ipsec_tx_create_attr *attr) {}
5863
#endif /* CONFIG_MLX5_ESWITCH */
5964
#endif /* __MLX5_ESW_IPSEC_FS_H__ */

drivers/net/ethernet/mellanox/mlx5/core/eswitch.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ struct mlx5_esw_offload {
254254
struct mlx5_flow_group *vport_rx_group;
255255
struct mlx5_flow_group *vport_rx_drop_group;
256256
struct mlx5_flow_handle *vport_rx_drop_rule;
257+
struct mlx5_flow_table *ft_ipsec_tx_pol;
257258
struct xarray vport_reps;
258259
struct list_head peer_flows[MLX5_MAX_PORTS];
259260
struct mutex peer_mutex;

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,17 @@ mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *on_esw,
884884
dest.vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID;
885885
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
886886

887+
if (rep->vport == MLX5_VPORT_UPLINK && on_esw->offloads.ft_ipsec_tx_pol) {
888+
dest.ft = on_esw->offloads.ft_ipsec_tx_pol;
889+
flow_act.flags = FLOW_ACT_IGNORE_FLOW_LEVEL;
890+
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
891+
} else {
892+
dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
893+
dest.vport.num = rep->vport;
894+
dest.vport.vhca_id = MLX5_CAP_GEN(rep->esw->dev, vhca_id);
895+
dest.vport.flags |= MLX5_FLOW_DEST_VPORT_VHCA_ID;
896+
}
897+
887898
if (MLX5_CAP_ESW_FLOWTABLE(on_esw->dev, flow_source) &&
888899
rep->vport == MLX5_VPORT_UPLINK)
889900
spec->flow_context.flow_source = MLX5_FLOW_CONTEXT_FLOW_SOURCE_LOCAL_VPORT;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3015,6 +3015,12 @@ static int init_fdb_root_ns(struct mlx5_flow_steering *steering)
30153015
goto out_err;
30163016
}
30173017

3018+
maj_prio = fs_create_prio(&steering->fdb_root_ns->ns, FDB_CRYPTO_EGRESS, 3);
3019+
if (IS_ERR(maj_prio)) {
3020+
err = PTR_ERR(maj_prio);
3021+
goto out_err;
3022+
}
3023+
30183024
/* We put this priority last, knowing that nothing will get here
30193025
* unless explicitly forwarded to. This is possible because the
30203026
* slow path tables have catch all rules and nothing gets passed

include/linux/mlx5/fs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ enum {
115115
FDB_TC_MISS,
116116
FDB_BR_OFFLOAD,
117117
FDB_SLOW_PATH,
118+
FDB_CRYPTO_EGRESS,
118119
FDB_PER_VPORT,
119120
};
120121

0 commit comments

Comments
 (0)