Skip to content

Commit 75d6d8b

Browse files
committed
Merge branch 'devlink-mlx5-add-port-function-attributes-for-ipsec'
Saeed Mahameed says: ==================== {devlink,mlx5}: Add port function attributes for ipsec From Dima: Introduce hypervisor-level control knobs to set the functionality of PCI VF devices passed through to guests. The administrator of a hypervisor host may choose to change the settings of a port function from the defaults configured by the device firmware. The software stack has two types of IPsec offload - crypto and packet. Specifically, the ip xfrm command has sub-commands for "state" and "policy" that have an "offload" parameter. With ip xfrm state, both crypto and packet offload types are supported, while ip xfrm policy can only be offloaded in packet mode. The series introduces two new boolean attributes of a port function: ipsec_crypto and ipsec_packet. The goal is to provide a similar level of granularity for controlling VF IPsec offload capabilities, which would be aligned with the software model. This will allow users to decide if they want both types of offload enabled for a VF, just one of them, or none at all (which is the default). At a high level, the difference between the two knobs is that with ipsec_crypto, only XFRM state can be offloaded. Specifically, only the crypto operation (Encrypt/Decrypt) is offloaded. With ipsec_packet, both XFRM state and policy can be offloaded. Furthermore, in addition to crypto operation offload, IPsec encapsulation is also offloaded. For XFRM state, choosing between crypto and packet offload types is possible. From the HW perspective, different resources may be required for each offload type. Examples of when a user prefers to enable IPsec packet offload for a VF when using switchdev mode: $ devlink port show pci/0000:06:00.0/1 pci/0000:06:00.0/1: type eth netdev enp6s0pf0vf0 flavour pcivf pfnum 0 vfnum 0 function: hw_addr 00:00:00:00:00:00 roce enable migratable disable ipsec_crypto disable ipsec_packet disable $ devlink port function set pci/0000:06:00.0/1 ipsec_packet enable $ devlink port show pci/0000:06:00.0/1 pci/0000:06:00.0/1: type eth netdev enp6s0pf0vf0 flavour pcivf pfnum 0 vfnum 0 function: hw_addr 00:00:00:00:00:00 roce enable migratable disable ipsec_crypto disable ipsec_packet enable This enables the corresponding IPsec capability of the function before it's enumerated, so when the driver reads the capability from the device firmware, it is enabled. The driver is then able to configure corresponding features and ops of the VF net device to support IPsec state and policy offloading. v2: https://lore.kernel.org/netdev/20230421104901.897946-1-dchumak@nvidia.com/ ==================== Link: https://lore.kernel.org/r/20230825062836.103744-1-saeed@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents aa05346 + b691b11 commit 75d6d8b

15 files changed

Lines changed: 898 additions & 108 deletions

File tree

Documentation/networking/device_drivers/ethernet/mellanox/mlx5/switchdev.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,26 @@ explicitly enable the VF migratable capability.
190190
mlx5 driver support devlink port function attr mechanism to setup migratable
191191
capability. (refer to Documentation/networking/devlink/devlink-port.rst)
192192

193+
IPsec crypto capability setup
194+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
195+
User who wants mlx5 PCI VFs to be able to perform IPsec crypto offloading need
196+
to explicitly enable the VF ipsec_crypto capability. Enabling IPsec capability
197+
for VFs is supported starting with ConnectX6dx devices and above. When a VF has
198+
IPsec capability enabled, any IPsec offloading is blocked on the PF.
199+
200+
mlx5 driver support devlink port function attr mechanism to setup ipsec_crypto
201+
capability. (refer to Documentation/networking/devlink/devlink-port.rst)
202+
203+
IPsec packet capability setup
204+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
205+
User who wants mlx5 PCI VFs to be able to perform IPsec packet offloading need
206+
to explicitly enable the VF ipsec_packet capability. Enabling IPsec capability
207+
for VFs is supported starting with ConnectX6dx devices and above. When a VF has
208+
IPsec capability enabled, any IPsec offloading is blocked on the PF.
209+
210+
mlx5 driver support devlink port function attr mechanism to setup ipsec_packet
211+
capability. (refer to Documentation/networking/devlink/devlink-port.rst)
212+
193213
SF state setup
194214
--------------
195215

Documentation/networking/devlink/devlink-port.rst

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ Users may also set the RoCE capability of the function using
128128
Users may also set the function as migratable using
129129
'devlink port function set migratable' command.
130130

131+
Users may also set the IPsec crypto capability of the function using
132+
`devlink port function set ipsec_crypto` command.
133+
134+
Users may also set the IPsec packet capability of the function using
135+
`devlink port function set ipsec_packet` command.
136+
131137
Function attributes
132138
===================
133139

@@ -240,6 +246,55 @@ Attach VF to the VM.
240246
Start the VM.
241247
Perform live migration.
242248

249+
IPsec crypto capability setup
250+
-----------------------------
251+
When user enables IPsec crypto capability for a VF, user application can offload
252+
XFRM state crypto operation (Encrypt/Decrypt) to this VF.
253+
254+
When IPsec crypto capability is disabled (default) for a VF, the XFRM state is
255+
processed in software by the kernel.
256+
257+
- Get IPsec crypto capability of the VF device::
258+
259+
$ devlink port show pci/0000:06:00.0/2
260+
pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1
261+
function:
262+
hw_addr 00:00:00:00:00:00 ipsec_crypto disabled
263+
264+
- Set IPsec crypto capability of the VF device::
265+
266+
$ devlink port function set pci/0000:06:00.0/2 ipsec_crypto enable
267+
268+
$ devlink port show pci/0000:06:00.0/2
269+
pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1
270+
function:
271+
hw_addr 00:00:00:00:00:00 ipsec_crypto enabled
272+
273+
IPsec packet capability setup
274+
-----------------------------
275+
When user enables IPsec packet capability for a VF, user application can offload
276+
XFRM state and policy crypto operation (Encrypt/Decrypt) to this VF, as well as
277+
IPsec encapsulation.
278+
279+
When IPsec packet capability is disabled (default) for a VF, the XFRM state and
280+
policy is processed in software by the kernel.
281+
282+
- Get IPsec packet capability of the VF device::
283+
284+
$ devlink port show pci/0000:06:00.0/2
285+
pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1
286+
function:
287+
hw_addr 00:00:00:00:00:00 ipsec_packet disabled
288+
289+
- Set IPsec packet capability of the VF device::
290+
291+
$ devlink port function set pci/0000:06:00.0/2 ipsec_packet enable
292+
293+
$ devlink port show pci/0000:06:00.0/2
294+
pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1
295+
function:
296+
hw_addr 00:00:00:00:00:00 ipsec_packet enabled
297+
243298
Subfunction
244299
============
245300

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ mlx5_core-$(CONFIG_MLX5_TC_SAMPLE) += en/tc/sample.o
6969
#
7070
mlx5_core-$(CONFIG_MLX5_ESWITCH) += eswitch.o eswitch_offloads.o eswitch_offloads_termtbl.o \
7171
ecpf.o rdma.o esw/legacy.o \
72-
esw/devlink_port.o esw/vporttbl.o esw/qos.o
72+
esw/devlink_port.o esw/vporttbl.o esw/qos.o esw/ipsec.o
7373

7474
mlx5_core-$(CONFIG_MLX5_ESWITCH) += esw/acl/helper.o \
7575
esw/acl/egress_lgcy.o esw/acl/egress_ofld.o \

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <net/netevent.h>
3939

4040
#include "en.h"
41+
#include "eswitch.h"
4142
#include "ipsec.h"
4243
#include "ipsec_rxtx.h"
4344
#include "en_rep.h"
@@ -670,6 +671,11 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
670671
if (err)
671672
goto err_xfrm;
672673

674+
if (!mlx5_eswitch_block_ipsec(priv->mdev)) {
675+
err = -EBUSY;
676+
goto err_xfrm;
677+
}
678+
673679
/* check esn */
674680
if (x->props.flags & XFRM_STATE_ESN)
675681
mlx5e_ipsec_update_esn_state(sa_entry);
@@ -678,7 +684,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
678684

679685
err = mlx5_ipsec_create_work(sa_entry);
680686
if (err)
681-
goto err_xfrm;
687+
goto unblock_ipsec;
682688

683689
err = mlx5e_ipsec_create_dwork(sa_entry);
684690
if (err)
@@ -735,6 +741,8 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x,
735741
if (sa_entry->work)
736742
kfree(sa_entry->work->data);
737743
kfree(sa_entry->work);
744+
unblock_ipsec:
745+
mlx5_eswitch_unblock_ipsec(priv->mdev);
738746
err_xfrm:
739747
kfree(sa_entry);
740748
NL_SET_ERR_MSG_WEAK_MOD(extack, "Device failed to offload this state");
@@ -764,6 +772,7 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x)
764772
static void mlx5e_xfrm_free_state(struct xfrm_state *x)
765773
{
766774
struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
775+
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
767776

768777
if (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ)
769778
goto sa_entry_free;
@@ -780,6 +789,7 @@ static void mlx5e_xfrm_free_state(struct xfrm_state *x)
780789
if (sa_entry->work)
781790
kfree(sa_entry->work->data);
782791
kfree(sa_entry->work);
792+
mlx5_eswitch_unblock_ipsec(ipsec->mdev);
783793
sa_entry_free:
784794
kfree(sa_entry);
785795
}
@@ -1055,6 +1065,11 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
10551065
pol_entry->x = x;
10561066
pol_entry->ipsec = priv->ipsec;
10571067

1068+
if (!mlx5_eswitch_block_ipsec(priv->mdev)) {
1069+
err = -EBUSY;
1070+
goto ipsec_busy;
1071+
}
1072+
10581073
mlx5e_ipsec_build_accel_pol_attrs(pol_entry, &pol_entry->attrs);
10591074
err = mlx5e_accel_ipsec_fs_add_pol(pol_entry);
10601075
if (err)
@@ -1064,6 +1079,8 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
10641079
return 0;
10651080

10661081
err_fs:
1082+
mlx5_eswitch_unblock_ipsec(priv->mdev);
1083+
ipsec_busy:
10671084
kfree(pol_entry);
10681085
NL_SET_ERR_MSG_MOD(extack, "Device failed to offload this policy");
10691086
return err;
@@ -1074,6 +1091,7 @@ static void mlx5e_xfrm_del_policy(struct xfrm_policy *x)
10741091
struct mlx5e_ipsec_pol_entry *pol_entry = to_ipsec_pol_entry(x);
10751092

10761093
mlx5e_accel_ipsec_fs_del_pol(pol_entry);
1094+
mlx5_eswitch_unblock_ipsec(pol_entry->ipsec->mdev);
10771095
}
10781096

10791097
static void mlx5e_xfrm_free_policy(struct xfrm_policy *x)

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

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ static void rx_destroy(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
254254
mlx5_del_flow_rules(rx->sa.rule);
255255
mlx5_destroy_flow_group(rx->sa.group);
256256
mlx5_destroy_flow_table(rx->ft.sa);
257+
if (rx->allow_tunnel_mode)
258+
mlx5_eswitch_unblock_encap(mdev);
257259
if (rx == ipsec->rx_esw) {
258260
mlx5_esw_ipsec_rx_status_destroy(ipsec, rx);
259261
} else {
@@ -357,6 +359,8 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
357359
goto err_add;
358360

359361
/* Create FT */
362+
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_TUNNEL)
363+
rx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
360364
if (rx->allow_tunnel_mode)
361365
flags = MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
362366
ft = ipsec_ft_create(attr.ns, attr.sa_level, attr.prio, 2, flags);
@@ -411,6 +415,8 @@ static int rx_create(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
411415
err_fs:
412416
mlx5_destroy_flow_table(rx->ft.sa);
413417
err_fs_ft:
418+
if (rx->allow_tunnel_mode)
419+
mlx5_eswitch_unblock_encap(mdev);
414420
mlx5_del_flow_rules(rx->status.rule);
415421
mlx5_modify_header_dealloc(mdev, rx->status.modify_hdr);
416422
err_add:
@@ -428,26 +434,19 @@ static int rx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
428434
if (rx->ft.refcnt)
429435
goto skip;
430436

431-
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_TUNNEL)
432-
rx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
433-
434-
err = mlx5_eswitch_block_mode_trylock(mdev);
437+
err = mlx5_eswitch_block_mode(mdev);
435438
if (err)
436-
goto err_out;
439+
return err;
437440

438441
err = rx_create(mdev, ipsec, rx, family);
439-
mlx5_eswitch_block_mode_unlock(mdev, err);
440-
if (err)
441-
goto err_out;
442+
if (err) {
443+
mlx5_eswitch_unblock_mode(mdev);
444+
return err;
445+
}
442446

443447
skip:
444448
rx->ft.refcnt++;
445449
return 0;
446-
447-
err_out:
448-
if (rx->allow_tunnel_mode)
449-
mlx5_eswitch_unblock_encap(mdev);
450-
return err;
451450
}
452451

453452
static void rx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_rx *rx,
@@ -456,12 +455,8 @@ static void rx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_rx *rx,
456455
if (--rx->ft.refcnt)
457456
return;
458457

459-
mlx5_eswitch_unblock_mode_lock(ipsec->mdev);
460458
rx_destroy(ipsec->mdev, ipsec, rx, family);
461-
mlx5_eswitch_unblock_mode_unlock(ipsec->mdev);
462-
463-
if (rx->allow_tunnel_mode)
464-
mlx5_eswitch_unblock_encap(ipsec->mdev);
459+
mlx5_eswitch_unblock_mode(ipsec->mdev);
465460
}
466461

467462
static struct mlx5e_ipsec_rx *rx_ft_get(struct mlx5_core_dev *mdev,
@@ -581,6 +576,8 @@ static void tx_destroy(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
581576
mlx5_destroy_flow_group(tx->sa.group);
582577
}
583578
mlx5_destroy_flow_table(tx->ft.sa);
579+
if (tx->allow_tunnel_mode)
580+
mlx5_eswitch_unblock_encap(ipsec->mdev);
584581
mlx5_del_flow_rules(tx->status.rule);
585582
mlx5_destroy_flow_table(tx->ft.status);
586583
}
@@ -621,6 +618,8 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
621618
if (err)
622619
goto err_status_rule;
623620

621+
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_TUNNEL)
622+
tx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
624623
if (tx->allow_tunnel_mode)
625624
flags = MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT;
626625
ft = ipsec_ft_create(tx->ns, attr.sa_level, attr.prio, 4, flags);
@@ -687,6 +686,8 @@ static int tx_create(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx,
687686
err_sa_miss:
688687
mlx5_destroy_flow_table(tx->ft.sa);
689688
err_sa_ft:
689+
if (tx->allow_tunnel_mode)
690+
mlx5_eswitch_unblock_encap(mdev);
690691
mlx5_del_flow_rules(tx->status.rule);
691692
err_status_rule:
692693
mlx5_destroy_flow_table(tx->ft.status);
@@ -720,52 +721,36 @@ static int tx_get(struct mlx5_core_dev *mdev, struct mlx5e_ipsec *ipsec,
720721
if (tx->ft.refcnt)
721722
goto skip;
722723

723-
if (mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_TUNNEL)
724-
tx->allow_tunnel_mode = mlx5_eswitch_block_encap(mdev);
725-
726-
err = mlx5_eswitch_block_mode_trylock(mdev);
724+
err = mlx5_eswitch_block_mode(mdev);
727725
if (err)
728-
goto err_out;
726+
return err;
729727

730728
err = tx_create(ipsec, tx, ipsec->roce);
731729
if (err) {
732-
mlx5_eswitch_block_mode_unlock(mdev, err);
733-
goto err_out;
730+
mlx5_eswitch_unblock_mode(mdev);
731+
return err;
734732
}
735733

736734
if (tx == ipsec->tx_esw)
737735
ipsec_esw_tx_ft_policy_set(mdev, tx->ft.pol);
738736

739-
mlx5_eswitch_block_mode_unlock(mdev, err);
740-
741737
skip:
742738
tx->ft.refcnt++;
743739
return 0;
744-
745-
err_out:
746-
if (tx->allow_tunnel_mode)
747-
mlx5_eswitch_unblock_encap(mdev);
748-
return err;
749740
}
750741

751742
static void tx_put(struct mlx5e_ipsec *ipsec, struct mlx5e_ipsec_tx *tx)
752743
{
753744
if (--tx->ft.refcnt)
754745
return;
755746

756-
mlx5_eswitch_unblock_mode_lock(ipsec->mdev);
757-
758747
if (tx == ipsec->tx_esw) {
759748
mlx5_esw_ipsec_restore_dest_uplink(ipsec->mdev);
760749
ipsec_esw_tx_ft_policy_set(ipsec->mdev, NULL);
761750
}
762751

763752
tx_destroy(ipsec, tx, ipsec->roce);
764-
765-
mlx5_eswitch_unblock_mode_unlock(ipsec->mdev);
766-
767-
if (tx->allow_tunnel_mode)
768-
mlx5_eswitch_unblock_encap(ipsec->mdev);
753+
mlx5_eswitch_unblock_mode(ipsec->mdev);
769754
}
770755

771756
static struct mlx5_flow_table *tx_ft_get_policy(struct mlx5_core_dev *mdev,

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ static const struct devlink_port_ops mlx5_esw_pf_vf_dl_port_ops = {
9292
.port_fn_roce_set = mlx5_devlink_port_fn_roce_set,
9393
.port_fn_migratable_get = mlx5_devlink_port_fn_migratable_get,
9494
.port_fn_migratable_set = mlx5_devlink_port_fn_migratable_set,
95+
#ifdef CONFIG_XFRM_OFFLOAD
96+
.port_fn_ipsec_crypto_get = mlx5_devlink_port_fn_ipsec_crypto_get,
97+
.port_fn_ipsec_crypto_set = mlx5_devlink_port_fn_ipsec_crypto_set,
98+
.port_fn_ipsec_packet_get = mlx5_devlink_port_fn_ipsec_packet_get,
99+
.port_fn_ipsec_packet_set = mlx5_devlink_port_fn_ipsec_packet_set,
100+
#endif /* CONFIG_XFRM_OFFLOAD */
95101
};
96102

97103
static void mlx5_esw_offloads_sf_devlink_port_attrs_set(struct mlx5_eswitch *esw,

0 commit comments

Comments
 (0)