devlink: Expose port function commands to control IPsec crypto offloads

Expose port function commands to enable / disable IPsec crypto offloads,
this is used to control the port IPsec capabilities.

When IPsec crypto is disabled for a function of the port (default),
function cannot offload any IPsec crypto operations (Encrypt/Decrypt and
XFRM state offloading). When enabled, IPsec crypto operations can be
offloaded by the function of the port.

Example of a PCI VF port which supports IPsec crypto offloads:

$ 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 ipsec_crypto disable

$ devlink port function set pci/0000:06:00.0/1 ipsec_crypto 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 ipsec_crypto enable

Signed-off-by: Dima Chumak <dchumak@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Link: https://lore.kernel.org/r/20230825062836.103744-2-saeed@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Dima Chumak 2023-08-24 23:28:29 -07:00 committed by Jakub Kicinski
parent aa05346dad
commit 62b6442c58
4 changed files with 96 additions and 0 deletions

View File

@ -128,6 +128,9 @@ Users may also set the RoCE capability of the function using
Users may also set the function as migratable using
'devlink port function set migratable' command.
Users may also set the IPsec crypto capability of the function using
`devlink port function set ipsec_crypto` command.
Function attributes
===================
@ -240,6 +243,30 @@ Attach VF to the VM.
Start the VM.
Perform live migration.
IPsec crypto capability setup
-----------------------------
When user enables IPsec crypto capability for a VF, user application can offload
XFRM state crypto operation (Encrypt/Decrypt) to this VF.
When IPsec crypto capability is disabled (default) for a VF, the XFRM state is
processed in software by the kernel.
- Get IPsec crypto capability of the VF device::
$ devlink port show pci/0000:06:00.0/2
pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1
function:
hw_addr 00:00:00:00:00:00 ipsec_crypto disabled
- Set IPsec crypto capability of the VF device::
$ devlink port function set pci/0000:06:00.0/2 ipsec_crypto enable
$ devlink port show pci/0000:06:00.0/2
pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1
function:
hw_addr 00:00:00:00:00:00 ipsec_crypto enabled
Subfunction
============

View File

@ -1583,6 +1583,15 @@ void devlink_free(struct devlink *devlink);
* Should be used by device drivers set
* the admin state of a function managed
* by the devlink port.
* @port_fn_ipsec_crypto_get: Callback used to get port function's ipsec_crypto
* capability. Should be used by device drivers
* to report the current state of ipsec_crypto
* capability of a function managed by the devlink
* port.
* @port_fn_ipsec_crypto_set: Callback used to set port function's ipsec_crypto
* capability. Should be used by device drivers to
* enable/disable ipsec_crypto capability of a
* function managed by the devlink port.
*
* Note: Driver should return -EOPNOTSUPP if it doesn't support
* port function (@port_fn_*) handling for a particular port.
@ -1620,6 +1629,12 @@ struct devlink_port_ops {
int (*port_fn_state_set)(struct devlink_port *port,
enum devlink_port_fn_state state,
struct netlink_ext_ack *extack);
int (*port_fn_ipsec_crypto_get)(struct devlink_port *devlink_port,
bool *is_enable,
struct netlink_ext_ack *extack);
int (*port_fn_ipsec_crypto_set)(struct devlink_port *devlink_port,
bool enable,
struct netlink_ext_ack *extack);
};
void devlink_port_init(struct devlink *devlink,

View File

@ -661,6 +661,7 @@ enum devlink_resource_unit {
enum devlink_port_fn_attr_cap {
DEVLINK_PORT_FN_ATTR_CAP_ROCE_BIT,
DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT,
DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT,
/* Add new caps above */
__DEVLINK_PORT_FN_ATTR_CAPS_MAX,
@ -669,6 +670,7 @@ enum devlink_port_fn_attr_cap {
#define DEVLINK_PORT_FN_CAP_ROCE _BITUL(DEVLINK_PORT_FN_ATTR_CAP_ROCE_BIT)
#define DEVLINK_PORT_FN_CAP_MIGRATABLE \
_BITUL(DEVLINK_PORT_FN_ATTR_CAP_MIGRATABLE_BIT)
#define DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO _BITUL(DEVLINK_PORT_FN_ATTR_CAP_IPSEC_CRYPTO_BIT)
enum devlink_port_function_attr {
DEVLINK_PORT_FUNCTION_ATTR_UNSPEC,

View File

@ -492,6 +492,28 @@ static int devlink_port_fn_migratable_fill(struct devlink_port *devlink_port,
return 0;
}
static int devlink_port_fn_ipsec_crypto_fill(struct devlink_port *devlink_port,
struct nla_bitfield32 *caps,
struct netlink_ext_ack *extack)
{
bool is_enable;
int err;
if (!devlink_port->ops->port_fn_ipsec_crypto_get ||
devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF)
return 0;
err = devlink_port->ops->port_fn_ipsec_crypto_get(devlink_port, &is_enable, extack);
if (err) {
if (err == -EOPNOTSUPP)
return 0;
return err;
}
devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO, is_enable);
return 0;
}
static int devlink_port_fn_caps_fill(struct devlink_port *devlink_port,
struct sk_buff *msg,
struct netlink_ext_ack *extack,
@ -508,6 +530,10 @@ static int devlink_port_fn_caps_fill(struct devlink_port *devlink_port,
if (err)
return err;
err = devlink_port_fn_ipsec_crypto_fill(devlink_port, &caps, extack);
if (err)
return err;
if (!caps.selector)
return 0;
err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value,
@ -838,6 +864,13 @@ devlink_port_fn_roce_set(struct devlink_port *devlink_port, bool enable,
extack);
}
static int
devlink_port_fn_ipsec_crypto_set(struct devlink_port *devlink_port, bool enable,
struct netlink_ext_ack *extack)
{
return devlink_port->ops->port_fn_ipsec_crypto_set(devlink_port, enable, extack);
}
static int devlink_port_fn_caps_set(struct devlink_port *devlink_port,
const struct nlattr *attr,
struct netlink_ext_ack *extack)
@ -862,6 +895,13 @@ static int devlink_port_fn_caps_set(struct devlink_port *devlink_port,
if (err)
return err;
}
if (caps.selector & DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO) {
err = devlink_port_fn_ipsec_crypto_set(devlink_port, caps_value &
DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO,
extack);
if (err)
return err;
}
return 0;
}
@ -1226,6 +1266,18 @@ static int devlink_port_function_validate(struct devlink_port *devlink_port,
return -EOPNOTSUPP;
}
}
if (caps.selector & DEVLINK_PORT_FN_CAP_IPSEC_CRYPTO) {
if (!ops->port_fn_ipsec_crypto_set) {
NL_SET_ERR_MSG_ATTR(extack, attr,
"Port doesn't support ipsec_crypto function attribute");
return -EOPNOTSUPP;
}
if (devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) {
NL_SET_ERR_MSG_ATTR(extack, attr,
"ipsec_crypto function attribute supported for VFs only");
return -EOPNOTSUPP;
}
}
}
return 0;
}