Skip to content

Commit 91bafc6

Browse files
Jianbo Liukuba-moo
authored andcommitted
net/mlx5e: Handle IPsec offload for RX datapath in switchdev mode
Reuse tun opts bits in reg c1, to pass IPsec obj id to datapath. As this is only for RX SA and there are only 11 bits, xarray is used to map IPsec obj id to an index, which is between 1 and 0x7ff, and replace obj id to write to reg c1. Signed-off-by: Jianbo Liu <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Link: https://lore.kernel.org/r/43d60fbcc9cd672a97d7e2a2f7fe6a3d9e9a776d.1690802064.git.leon@kernel.org Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 1762f13 commit 91bafc6

File tree

8 files changed

+139
-3
lines changed

8 files changed

+139
-3
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/rep/tc.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -715,9 +715,20 @@ void mlx5e_rep_tc_receive(struct mlx5_cqe64 *cqe, struct mlx5e_rq *rq,
715715
uplink_priv = &uplink_rpriv->uplink_priv;
716716
ct_priv = uplink_priv->ct_priv;
717717

718-
if (!mlx5_ipsec_is_rx_flow(cqe) &&
719-
!mlx5e_tc_update_skb(cqe, skb, mapping_ctx, reg_c0, ct_priv, zone_restore_id, tunnel_id,
720-
&tc_priv))
718+
#ifdef CONFIG_MLX5_EN_IPSEC
719+
if (!(tunnel_id >> ESW_TUN_OPTS_BITS)) {
720+
u32 mapped_id;
721+
u32 metadata;
722+
723+
mapped_id = tunnel_id & ESW_IPSEC_RX_MAPPED_ID_MASK;
724+
if (mapped_id &&
725+
!mlx5_esw_ipsec_rx_make_metadata(priv, mapped_id, &metadata))
726+
mlx5e_ipsec_offload_handle_rx_skb(priv->netdev, skb, metadata);
727+
}
728+
#endif
729+
730+
if (!mlx5e_tc_update_skb(cqe, skb, mapping_ctx, reg_c0, ct_priv,
731+
zone_restore_id, tunnel_id, &tc_priv))
721732
goto free_skb;
722733

723734
forward:

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ struct mlx5e_ipsec_rx {
210210
struct mlx5e_ipsec_fc *fc;
211211
struct mlx5_fs_chains *chains;
212212
u8 allow_tunnel_mode : 1;
213+
struct xarray ipsec_obj_id_map;
213214
};
214215

215216
struct mlx5e_ipsec {
@@ -256,6 +257,7 @@ struct mlx5e_ipsec_sa_entry {
256257
struct mlx5e_ipsec_work *work;
257258
struct mlx5e_ipsec_dwork *dwork;
258259
struct mlx5e_ipsec_limits limits;
260+
u32 rx_mapped_id;
259261
};
260262

261263
struct mlx5_accel_pol_xfrm_attrs {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,9 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
11531153
err = setup_modify_header(ipsec, attrs->type,
11541154
sa_entry->ipsec_obj_id | BIT(31),
11551155
XFRM_DEV_OFFLOAD_IN, &flow_act);
1156+
else
1157+
err = mlx5_esw_ipsec_rx_setup_modify_header(sa_entry, &flow_act);
1158+
11561159
if (err)
11571160
goto err_mod_header;
11581161

@@ -1641,6 +1644,7 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
16411644
}
16421645

16431646
mlx5_modify_header_dealloc(mdev, ipsec_rule->modify_hdr);
1647+
mlx5_esw_ipsec_rx_id_mapping_remove(sa_entry);
16441648
rx_ft_put(sa_entry->ipsec, sa_entry->attrs.family, sa_entry->attrs.type);
16451649
}
16461650

@@ -1693,6 +1697,8 @@ void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec)
16931697
kfree(ipsec->rx_ipv6);
16941698

16951699
if (ipsec->is_uplink_rep) {
1700+
xa_destroy(&ipsec->rx_esw->ipsec_obj_id_map);
1701+
16961702
mutex_destroy(&ipsec->tx_esw->ft.mutex);
16971703
WARN_ON(ipsec->tx_esw->ft.refcnt);
16981704
kfree(ipsec->tx_esw);
@@ -1753,6 +1759,7 @@ int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec)
17531759
mutex_init(&ipsec->tx_esw->ft.mutex);
17541760
mutex_init(&ipsec->rx_esw->ft.mutex);
17551761
ipsec->tx_esw->ns = ns_esw;
1762+
xa_init_flags(&ipsec->rx_esw->ipsec_obj_id_map, XA_FLAGS_ALLOC1);
17561763
} else if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_ROCE) {
17571764
ipsec->roce = mlx5_ipsec_fs_roce_init(mdev);
17581765
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "ipsec.h"
3838
#include "ipsec_rxtx.h"
3939
#include "en.h"
40+
#include "esw/ipsec_fs.h"
4041

4142
enum {
4243
MLX5E_IPSEC_TX_SYNDROME_OFFLOAD = 0x8,
@@ -355,3 +356,24 @@ void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
355356
atomic64_inc(&ipsec->sw_stats.ipsec_rx_drop_syndrome);
356357
}
357358
}
359+
360+
int mlx5_esw_ipsec_rx_make_metadata(struct mlx5e_priv *priv, u32 id, u32 *metadata)
361+
{
362+
struct mlx5e_ipsec *ipsec = priv->ipsec;
363+
u32 ipsec_obj_id;
364+
int err;
365+
366+
if (!ipsec || !ipsec->is_uplink_rep)
367+
return -EINVAL;
368+
369+
err = mlx5_esw_ipsec_rx_ipsec_obj_id_search(priv, id, &ipsec_obj_id);
370+
if (err) {
371+
atomic64_inc(&ipsec->sw_stats.ipsec_rx_drop_sadb_miss);
372+
return err;
373+
}
374+
375+
*metadata = MLX5_IPSEC_METADATA_CREATE(ipsec_obj_id,
376+
MLX5E_IPSEC_OFFLOAD_RX_SYNDROME_DECRYPTED);
377+
378+
return 0;
379+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#define MLX5_IPSEC_METADATA_MARKER(metadata) (((metadata) >> 31) & 0x1)
4444
#define MLX5_IPSEC_METADATA_SYNDROM(metadata) (((metadata) >> 24) & GENMASK(5, 0))
4545
#define MLX5_IPSEC_METADATA_HANDLE(metadata) ((metadata) & GENMASK(23, 0))
46+
#define MLX5_IPSEC_METADATA_CREATE(id, syndrome) ((id) | ((syndrome) << 24))
4647

4748
struct mlx5e_accel_tx_ipsec_state {
4849
struct xfrm_offload *xo;
@@ -67,6 +68,7 @@ void mlx5e_ipsec_handle_tx_wqe(struct mlx5e_tx_wqe *wqe,
6768
void mlx5e_ipsec_offload_handle_rx_skb(struct net_device *netdev,
6869
struct sk_buff *skb,
6970
u32 ipsec_meta_data);
71+
int mlx5_esw_ipsec_rx_make_metadata(struct mlx5e_priv *priv, u32 id, u32 *metadata);
7072
static inline unsigned int mlx5e_ipsec_tx_ids_len(struct mlx5e_accel_tx_ipsec_state *ipsec_st)
7173
{
7274
return ipsec_st->tailen;

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

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,72 @@ int mlx5_esw_ipsec_rx_status_pass_dest_get(struct mlx5e_ipsec *ipsec,
182182

183183
return 0;
184184
}
185+
186+
int mlx5_esw_ipsec_rx_setup_modify_header(struct mlx5e_ipsec_sa_entry *sa_entry,
187+
struct mlx5_flow_act *flow_act)
188+
{
189+
u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};
190+
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
191+
struct mlx5_core_dev *mdev = ipsec->mdev;
192+
struct mlx5_modify_hdr *modify_hdr;
193+
u32 mapped_id;
194+
int err;
195+
196+
err = xa_alloc_bh(&ipsec->rx_esw->ipsec_obj_id_map, &mapped_id,
197+
xa_mk_value(sa_entry->ipsec_obj_id),
198+
XA_LIMIT(1, ESW_IPSEC_RX_MAPPED_ID_MASK), 0);
199+
if (err)
200+
return err;
201+
202+
/* reuse tunnel bits for ipsec,
203+
* tun_id is always 0 and tun_opts is mapped to ipsec_obj_id.
204+
*/
205+
MLX5_SET(set_action_in, action, action_type, MLX5_ACTION_TYPE_SET);
206+
MLX5_SET(set_action_in, action, field,
207+
MLX5_ACTION_IN_FIELD_METADATA_REG_C_1);
208+
MLX5_SET(set_action_in, action, offset, ESW_ZONE_ID_BITS);
209+
MLX5_SET(set_action_in, action, length,
210+
ESW_TUN_ID_BITS + ESW_TUN_OPTS_BITS);
211+
MLX5_SET(set_action_in, action, data, mapped_id);
212+
213+
modify_hdr = mlx5_modify_header_alloc(mdev, MLX5_FLOW_NAMESPACE_FDB,
214+
1, action);
215+
if (IS_ERR(modify_hdr)) {
216+
err = PTR_ERR(modify_hdr);
217+
goto err_header_alloc;
218+
}
219+
220+
sa_entry->rx_mapped_id = mapped_id;
221+
flow_act->modify_hdr = modify_hdr;
222+
flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
223+
224+
return 0;
225+
226+
err_header_alloc:
227+
xa_erase_bh(&ipsec->rx_esw->ipsec_obj_id_map, mapped_id);
228+
return err;
229+
}
230+
231+
void mlx5_esw_ipsec_rx_id_mapping_remove(struct mlx5e_ipsec_sa_entry *sa_entry)
232+
{
233+
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
234+
235+
if (sa_entry->rx_mapped_id)
236+
xa_erase_bh(&ipsec->rx_esw->ipsec_obj_id_map,
237+
sa_entry->rx_mapped_id);
238+
}
239+
240+
int mlx5_esw_ipsec_rx_ipsec_obj_id_search(struct mlx5e_priv *priv, u32 id,
241+
u32 *ipsec_obj_id)
242+
{
243+
struct mlx5e_ipsec *ipsec = priv->ipsec;
244+
void *val;
245+
246+
val = xa_load(&ipsec->rx_esw->ipsec_obj_id_map, id);
247+
if (!val)
248+
return -ENOENT;
249+
250+
*ipsec_obj_id = xa_to_value(val);
251+
252+
return 0;
253+
}

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define __MLX5_ESW_IPSEC_FS_H__
66

77
struct mlx5e_ipsec;
8+
struct mlx5e_ipsec_sa_entry;
89

910
#ifdef CONFIG_MLX5_ESWITCH
1011
void mlx5_esw_ipsec_rx_status_destroy(struct mlx5e_ipsec *ipsec,
@@ -16,6 +17,11 @@ void mlx5_esw_ipsec_rx_create_attr_set(struct mlx5e_ipsec *ipsec,
1617
struct mlx5e_ipsec_rx_create_attr *attr);
1718
int mlx5_esw_ipsec_rx_status_pass_dest_get(struct mlx5e_ipsec *ipsec,
1819
struct mlx5_flow_destination *dest);
20+
int mlx5_esw_ipsec_rx_setup_modify_header(struct mlx5e_ipsec_sa_entry *sa_entry,
21+
struct mlx5_flow_act *flow_act);
22+
void mlx5_esw_ipsec_rx_id_mapping_remove(struct mlx5e_ipsec_sa_entry *sa_entry);
23+
int mlx5_esw_ipsec_rx_ipsec_obj_id_search(struct mlx5e_priv *priv, u32 id,
24+
u32 *ipsec_obj_id);
1925
#else
2026
static inline void mlx5_esw_ipsec_rx_status_destroy(struct mlx5e_ipsec *ipsec,
2127
struct mlx5e_ipsec_rx *rx) {}
@@ -35,5 +41,19 @@ static inline int mlx5_esw_ipsec_rx_status_pass_dest_get(struct mlx5e_ipsec *ips
3541
{
3642
return -EINVAL;
3743
}
44+
45+
static inline int mlx5_esw_ipsec_rx_setup_modify_header(struct mlx5e_ipsec_sa_entry *sa_entry,
46+
struct mlx5_flow_act *flow_act)
47+
{
48+
return -EINVAL;
49+
}
50+
51+
static inline void mlx5_esw_ipsec_rx_id_mapping_remove(struct mlx5e_ipsec_sa_entry *sa_entry) {}
52+
53+
static inline int mlx5_esw_ipsec_rx_ipsec_obj_id_search(struct mlx5e_priv *priv, u32 id,
54+
u32 *ipsec_obj_id)
55+
{
56+
return -EINVAL;
57+
}
3858
#endif /* CONFIG_MLX5_ESWITCH */
3959
#endif /* __MLX5_ESW_IPSEC_FS_H__ */

include/linux/mlx5/eswitch.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ u32 mlx5_eswitch_get_vport_metadata_for_set(struct mlx5_eswitch *esw,
144144
GENMASK(31 - ESW_TUN_ID_BITS - ESW_RESERVED_BITS, \
145145
ESW_TUN_OPTS_OFFSET + 1)
146146

147+
/* reuse tun_opts for the mapped ipsec obj id when tun_id is 0 (invalid) */
148+
#define ESW_IPSEC_RX_MAPPED_ID_MASK GENMASK(ESW_TUN_OPTS_BITS - 1, 0)
149+
147150
u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev);
148151
u16 mlx5_eswitch_get_total_vports(const struct mlx5_core_dev *dev);
149152
struct mlx5_core_dev *mlx5_eswitch_get_core_dev(struct mlx5_eswitch *esw);

0 commit comments

Comments
 (0)