Skip to content

Commit 1762f13

Browse files
Jianbo Liukuba-moo
Jianbo Liu
authored andcommitted
net/mlx5e: Support IPsec packet offload for RX in switchdev mode
As decryption must be done first, add new prio for IPsec offload in FDB, and put it just lower than BYPASS prio and higher than TC prio. Three levels are added for RX. The first one is for ip xfrm policy. SA table is created in the second level for ip xfrm state. The status table is created in the last to check the decryption result. If success, packets continue with the next process, or dropped otherwise. For now, the set of reg c1 is removed for swtichdev mode, and the datapath process will be added in the next patch. Signed-off-by: Jianbo Liu <[email protected]> Signed-off-by: Leon Romanovsky <[email protected]> Link: https://lore.kernel.org/r/c91063554cf643fb50b99cf093e8a9bf11729de5.1690802064.git.leon@kernel.org Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 6e12526 commit 1762f13

File tree

8 files changed

+313
-47
lines changed

8 files changed

+313
-47
lines changed

drivers/net/ethernet/mellanox/mlx5/core/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ mlx5_core-$(CONFIG_MLX5_ESWITCH) += esw/acl/helper.o \
7575
esw/acl/egress_lgcy.o esw/acl/egress_ofld.o \
7676
esw/acl/ingress_lgcy.o esw/acl/ingress_ofld.o
7777

78+
ifneq ($(CONFIG_MLX5_EN_IPSEC),)
79+
mlx5_core-$(CONFIG_MLX5_ESWITCH) += esw/ipsec_fs.o
80+
endif
81+
7882
mlx5_core-$(CONFIG_MLX5_BRIDGE) += esw/bridge.o esw/bridge_mcast.o esw/bridge_debugfs.o \
7983
en/rep/bridge.o
8084

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

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ struct mlx5e_ipsec_sw_stats {
143143
atomic64_t ipsec_tx_drop_trailer;
144144
};
145145

146-
struct mlx5e_ipsec_rx;
146+
struct mlx5e_ipsec_fc;
147147
struct mlx5e_ipsec_tx;
148148

149149
struct mlx5e_ipsec_work {
@@ -180,6 +180,38 @@ struct mlx5e_ipsec_rx_create_attr {
180180
enum mlx5_flow_namespace_type chains_ns;
181181
};
182182

183+
struct mlx5e_ipsec_ft {
184+
struct mutex mutex; /* Protect changes to this struct */
185+
struct mlx5_flow_table *pol;
186+
struct mlx5_flow_table *sa;
187+
struct mlx5_flow_table *status;
188+
u32 refcnt;
189+
};
190+
191+
struct mlx5e_ipsec_rule {
192+
struct mlx5_flow_handle *rule;
193+
struct mlx5_modify_hdr *modify_hdr;
194+
struct mlx5_pkt_reformat *pkt_reformat;
195+
struct mlx5_fc *fc;
196+
};
197+
198+
struct mlx5e_ipsec_miss {
199+
struct mlx5_flow_group *group;
200+
struct mlx5_flow_handle *rule;
201+
};
202+
203+
struct mlx5e_ipsec_rx {
204+
struct mlx5e_ipsec_ft ft;
205+
struct mlx5e_ipsec_miss pol;
206+
struct mlx5e_ipsec_miss sa;
207+
struct mlx5e_ipsec_rule status;
208+
struct mlx5e_ipsec_miss status_drop;
209+
struct mlx5_fc *status_drop_cnt;
210+
struct mlx5e_ipsec_fc *fc;
211+
struct mlx5_fs_chains *chains;
212+
u8 allow_tunnel_mode : 1;
213+
};
214+
183215
struct mlx5e_ipsec {
184216
struct mlx5_core_dev *mdev;
185217
struct xarray sadb;
@@ -205,13 +237,6 @@ struct mlx5e_ipsec_esn_state {
205237
u8 overlap: 1;
206238
};
207239

208-
struct mlx5e_ipsec_rule {
209-
struct mlx5_flow_handle *rule;
210-
struct mlx5_modify_hdr *modify_hdr;
211-
struct mlx5_pkt_reformat *pkt_reformat;
212-
struct mlx5_fc *fc;
213-
};
214-
215240
struct mlx5e_ipsec_limits {
216241
u64 round;
217242
u8 soft_limit_hit : 1;

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

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "fs_core.h"
1010
#include "lib/ipsec_fs_roce.h"
1111
#include "lib/fs_chains.h"
12+
#include "esw/ipsec_fs.h"
1213

1314
#define NUM_IPSEC_FTE BIT(15)
1415
#define MLX5_REFORMAT_TYPE_ADD_ESP_TRANSPORT_SIZE 16
@@ -19,29 +20,6 @@ struct mlx5e_ipsec_fc {
1920
struct mlx5_fc *drop;
2021
};
2122

22-
struct mlx5e_ipsec_ft {
23-
struct mutex mutex; /* Protect changes to this struct */
24-
struct mlx5_flow_table *pol;
25-
struct mlx5_flow_table *sa;
26-
struct mlx5_flow_table *status;
27-
u32 refcnt;
28-
};
29-
30-
struct mlx5e_ipsec_miss {
31-
struct mlx5_flow_group *group;
32-
struct mlx5_flow_handle *rule;
33-
};
34-
35-
struct mlx5e_ipsec_rx {
36-
struct mlx5e_ipsec_ft ft;
37-
struct mlx5e_ipsec_miss pol;
38-
struct mlx5e_ipsec_miss sa;
39-
struct mlx5e_ipsec_rule status;
40-
struct mlx5e_ipsec_fc *fc;
41-
struct mlx5_fs_chains *chains;
42-
u8 allow_tunnel_mode : 1;
43-
};
44-
4523
struct mlx5e_ipsec_tx {
4624
struct mlx5e_ipsec_ft ft;
4725
struct mlx5e_ipsec_miss pol;
@@ -259,9 +237,9 @@ static void ipsec_rx_ft_disconnect(struct mlx5e_ipsec *ipsec, u32 family)
259237
static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
260238
struct mlx5e_ipsec_rx *rx, u32 family)
261239
{
262-
263240
/* disconnect */
264-
ipsec_rx_ft_disconnect(ipsec, family);
241+
if (rx != ipsec->rx_esw)
242+
ipsec_rx_ft_disconnect(ipsec, family);
265243

266244
if (rx->chains) {
267245
ipsec_chains_destroy(rx->chains);
@@ -276,8 +254,12 @@ static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
276254
mlx5_destroy_flow_table(rx->ft.sa);
277255
if (rx->allow_tunnel_mode)
278256
mlx5_eswitch_unblock_encap(mdev);
279-
mlx5_del_flow_rules(rx->status.rule);
280-
mlx5_modify_header_dealloc(mdev, rx->status.modify_hdr);
257+
if (rx == ipsec->rx_esw) {
258+
mlx5_esw_ipsec_rx_status_destroy(ipsec, rx);
259+
} else {
260+
mlx5_del_flow_rules(rx->status.rule);
261+
mlx5_modify_header_dealloc(mdev, rx->status.modify_hdr);
262+
}
281263
mlx5_destroy_flow_table(rx->ft.status);
282264

283265
mlx5_ipsec_fs_roce_rx_destroy(ipsec->roce, family);
@@ -288,6 +270,13 @@ static void ipsec_rx_create_attr_set(struct mlx5e_ipsec *ipsec,
288270
u32 family,
289271
struct mlx5e_ipsec_rx_create_attr *attr)
290272
{
273+
if (rx == ipsec->rx_esw) {
274+
/* For packet offload in switchdev mode, RX & TX use FDB namespace */
275+
attr->ns = ipsec->tx_esw->ns;
276+
mlx5_esw_ipsec_rx_create_attr_set(ipsec, attr);
277+
return;
278+
}
279+
291280
attr->ns = mlx5e_fs_get_ns(ipsec->fs, false);
292281
attr->ttc = mlx5e_fs_get_ttc(ipsec->fs, false);
293282
attr->family = family;
@@ -306,6 +295,9 @@ static int ipsec_rx_status_pass_dest_get(struct mlx5e_ipsec *ipsec,
306295
struct mlx5_flow_table *ft;
307296
int err;
308297

298+
if (rx == ipsec->rx_esw)
299+
return mlx5_esw_ipsec_rx_status_pass_dest_get(ipsec, dest);
300+
309301
*dest = mlx5_ttc_get_default_dest(attr->ttc, family2tt(attr->family));
310302
err = mlx5_ipsec_fs_roce_rx_create(ipsec->mdev, ipsec->roce, attr->ns, dest,
311303
attr->family, MLX5E_ACCEL_FS_ESP_FT_ROCE_LEVEL,
@@ -357,7 +349,10 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
357349

358350
dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
359351
dest[1].counter_id = mlx5_fc_id(rx->fc->cnt);
360-
err = ipsec_status_rule(mdev, rx, dest);
352+
if (rx == ipsec->rx_esw)
353+
err = mlx5_esw_ipsec_rx_status_create(ipsec, rx, dest);
354+
else
355+
err = ipsec_status_rule(mdev, rx, dest);
361356
if (err)
362357
goto err_add;
363358

@@ -406,7 +401,8 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
406401

407402
connect:
408403
/* connect */
409-
ipsec_rx_ft_connect(ipsec, rx, &attr);
404+
if (rx != ipsec->rx_esw)
405+
ipsec_rx_ft_connect(ipsec, rx, &attr);
410406
return 0;
411407

412408
err_pol_miss:
@@ -864,18 +860,22 @@ static void setup_fte_upper_proto_match(struct mlx5_flow_spec *spec, struct upsp
864860
}
865861
}
866862

867-
static enum mlx5_flow_namespace_type ipsec_fs_get_ns(struct mlx5e_ipsec *ipsec, u8 dir)
863+
static enum mlx5_flow_namespace_type ipsec_fs_get_ns(struct mlx5e_ipsec *ipsec,
864+
int type, u8 dir)
868865
{
866+
if (ipsec->is_uplink_rep && type == XFRM_DEV_OFFLOAD_PACKET)
867+
return MLX5_FLOW_NAMESPACE_FDB;
868+
869869
if (dir == XFRM_DEV_OFFLOAD_IN)
870870
return MLX5_FLOW_NAMESPACE_KERNEL;
871871

872872
return MLX5_FLOW_NAMESPACE_EGRESS;
873873
}
874874

875-
static int setup_modify_header(struct mlx5e_ipsec *ipsec, u32 val, u8 dir,
875+
static int setup_modify_header(struct mlx5e_ipsec *ipsec, int type, u32 val, u8 dir,
876876
struct mlx5_flow_act *flow_act)
877877
{
878-
enum mlx5_flow_namespace_type ns_type = ipsec_fs_get_ns(ipsec, dir);
878+
enum mlx5_flow_namespace_type ns_type = ipsec_fs_get_ns(ipsec, type, dir);
879879
u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};
880880
struct mlx5_core_dev *mdev = ipsec->mdev;
881881
struct mlx5_modify_hdr *modify_hdr;
@@ -1085,7 +1085,8 @@ static int setup_pkt_reformat(struct mlx5e_ipsec *ipsec,
10851085
struct mlx5_accel_esp_xfrm_attrs *attrs,
10861086
struct mlx5_flow_act *flow_act)
10871087
{
1088-
enum mlx5_flow_namespace_type ns_type = ipsec_fs_get_ns(ipsec, attrs->dir);
1088+
enum mlx5_flow_namespace_type ns_type = ipsec_fs_get_ns(ipsec, attrs->type,
1089+
attrs->dir);
10891090
struct mlx5_pkt_reformat_params reformat_params = {};
10901091
struct mlx5_core_dev *mdev = ipsec->mdev;
10911092
struct mlx5_pkt_reformat *pkt_reformat;
@@ -1127,7 +1128,7 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
11271128
struct mlx5_flow_spec *spec;
11281129
struct mlx5e_ipsec_rx *rx;
11291130
struct mlx5_fc *counter;
1130-
int err;
1131+
int err = 0;
11311132

11321133
rx = rx_ft_get(mdev, ipsec, attrs->family, attrs->type);
11331134
if (IS_ERR(rx))
@@ -1148,8 +1149,10 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
11481149
setup_fte_esp(spec);
11491150
setup_fte_no_frags(spec);
11501151

1151-
err = setup_modify_header(ipsec, sa_entry->ipsec_obj_id | BIT(31),
1152-
XFRM_DEV_OFFLOAD_IN, &flow_act);
1152+
if (rx != ipsec->rx_esw)
1153+
err = setup_modify_header(ipsec, attrs->type,
1154+
sa_entry->ipsec_obj_id | BIT(31),
1155+
XFRM_DEV_OFFLOAD_IN, &flow_act);
11531156
if (err)
11541157
goto err_mod_header;
11551158

@@ -1340,7 +1343,7 @@ static int tx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
13401343
if (!attrs->reqid)
13411344
break;
13421345

1343-
err = setup_modify_header(ipsec, attrs->reqid,
1346+
err = setup_modify_header(ipsec, attrs->type, attrs->reqid,
13441347
XFRM_DEV_OFFLOAD_OUT, &flow_act);
13451348
if (err)
13461349
goto err_mod_header;
@@ -1388,6 +1391,7 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
13881391
{
13891392
struct mlx5_accel_pol_xfrm_attrs *attrs = &pol_entry->attrs;
13901393
struct mlx5_core_dev *mdev = mlx5e_ipsec_pol2dev(pol_entry);
1394+
struct mlx5e_ipsec *ipsec = pol_entry->ipsec;
13911395
struct mlx5_flow_destination dest[2];
13921396
struct mlx5_flow_act flow_act = {};
13931397
struct mlx5_flow_handle *rule;
@@ -1433,6 +1437,8 @@ static int rx_add_policy(struct mlx5e_ipsec_pol_entry *pol_entry)
14331437
}
14341438

14351439
flow_act.flags |= FLOW_ACT_NO_APPEND;
1440+
if (rx == ipsec->rx_esw && rx->chains)
1441+
flow_act.flags |= FLOW_ACT_IGNORE_FLOW_LEVEL;
14361442
dest[dstn].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
14371443
dest[dstn].ft = rx->ft.sa;
14381444
dstn++;

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev)
4545
MLX5_CAP_FLOWTABLE_NIC_RX(mdev, decap))
4646
caps |= MLX5_IPSEC_CAP_PACKET_OFFLOAD;
4747

48-
if (MLX5_CAP_FLOWTABLE_NIC_TX(mdev, ignore_flow_level) &&
49-
MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ignore_flow_level))
48+
if ((MLX5_CAP_FLOWTABLE_NIC_TX(mdev, ignore_flow_level) &&
49+
MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ignore_flow_level)) ||
50+
MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, ignore_flow_level))
5051
caps |= MLX5_IPSEC_CAP_PRIO;
5152

5253
if (MLX5_CAP_FLOWTABLE_NIC_TX(mdev,

0 commit comments

Comments
 (0)