summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/xfrm_device.rst4
-rw-r--r--drivers/net/bonding/bond_main.c10
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c8
-rw-r--r--drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c34
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c27
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ipsec.c21
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c103
-rw-r--r--drivers/net/ethernet/netronome/nfp/crypto/ipsec.c41
-rw-r--r--drivers/net/netdevsim/ipsec.c14
-rw-r--r--include/linux/netdevice.h4
-rw-r--r--net/xfrm/xfrm_device.c9
-rw-r--r--net/xfrm/xfrm_state.c2
12 files changed, 137 insertions, 140 deletions
diff --git a/Documentation/networking/xfrm_device.rst b/Documentation/networking/xfrm_device.rst
index c43ace79e320..83abdfef4ec3 100644
--- a/Documentation/networking/xfrm_device.rst
+++ b/Documentation/networking/xfrm_device.rst
@@ -64,7 +64,7 @@ Callbacks to implement
/* from include/linux/netdevice.h */
struct xfrmdev_ops {
/* Crypto and Packet offload callbacks */
- int (*xdo_dev_state_add) (struct xfrm_state *x);
+ int (*xdo_dev_state_add) (struct xfrm_state *x, struct netlink_ext_ack *extack);
void (*xdo_dev_state_delete) (struct xfrm_state *x);
void (*xdo_dev_state_free) (struct xfrm_state *x);
bool (*xdo_dev_offload_ok) (struct sk_buff *skb,
@@ -73,7 +73,7 @@ Callbacks to implement
/* Solely packet offload callbacks */
void (*xdo_dev_state_update_curlft) (struct xfrm_state *x);
- int (*xdo_dev_policy_add) (struct xfrm_policy *x);
+ int (*xdo_dev_policy_add) (struct xfrm_policy *x, struct netlink_ext_ack *extack);
void (*xdo_dev_policy_delete) (struct xfrm_policy *x);
void (*xdo_dev_policy_free) (struct xfrm_policy *x);
};
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 0363ce597661..00646aa315c3 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -419,8 +419,10 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
/**
* bond_ipsec_add_sa - program device with a security association
* @xs: pointer to transformer state struct
+ * @extack: extack point to fill failure reason
**/
-static int bond_ipsec_add_sa(struct xfrm_state *xs)
+static int bond_ipsec_add_sa(struct xfrm_state *xs,
+ struct netlink_ext_ack *extack)
{
struct net_device *bond_dev = xs->xso.dev;
struct bond_ipsec *ipsec;
@@ -442,7 +444,7 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs)
if (!slave->dev->xfrmdev_ops ||
!slave->dev->xfrmdev_ops->xdo_dev_state_add ||
netif_is_bond_master(slave->dev)) {
- slave_warn(bond_dev, slave->dev, "Slave does not support ipsec offload\n");
+ NL_SET_ERR_MSG_MOD(extack, "Slave does not support ipsec offload");
rcu_read_unlock();
return -EINVAL;
}
@@ -454,7 +456,7 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs)
}
xs->xso.real_dev = slave->dev;
- err = slave->dev->xfrmdev_ops->xdo_dev_state_add(xs);
+ err = slave->dev->xfrmdev_ops->xdo_dev_state_add(xs, extack);
if (!err) {
ipsec->xs = xs;
INIT_LIST_HEAD(&ipsec->list);
@@ -494,7 +496,7 @@ static void bond_ipsec_add_sa_all(struct bonding *bond)
spin_lock_bh(&bond->ipsec_lock);
list_for_each_entry(ipsec, &bond->ipsec_list, list) {
ipsec->xs->xso.real_dev = slave->dev;
- if (slave->dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs)) {
+ if (slave->dev->xfrmdev_ops->xdo_dev_state_add(ipsec->xs, NULL)) {
slave_warn(bond_dev, slave->dev, "%s: failed to add SA\n", __func__);
ipsec->xs->xso.real_dev = NULL;
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
index 9cbce1faab26..7db2403c4c9c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
@@ -6490,21 +6490,21 @@ static const struct tlsdev_ops cxgb4_ktls_ops = {
#if IS_ENABLED(CONFIG_CHELSIO_IPSEC_INLINE)
-static int cxgb4_xfrm_add_state(struct xfrm_state *x)
+static int cxgb4_xfrm_add_state(struct xfrm_state *x,
+ struct netlink_ext_ack *extack)
{
struct adapter *adap = netdev2adap(x->xso.dev);
int ret;
if (!mutex_trylock(&uld_mutex)) {
- dev_dbg(adap->pdev_dev,
- "crypto uld critical resource is under use\n");
+ NL_SET_ERR_MSG_MOD(extack, "crypto uld critical resource is under use");
return -EBUSY;
}
ret = chcr_offload_state(adap, CXGB4_XFRMDEV_OPS);
if (ret)
goto out_unlock;
- ret = adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_add(x);
+ ret = adap->uld[CXGB4_ULD_IPSEC].xfrmdev_ops->xdo_dev_state_add(x, extack);
out_unlock:
mutex_unlock(&uld_mutex);
diff --git a/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c b/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c
index ca21794281d6..3731c93f8f95 100644
--- a/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c
+++ b/drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c
@@ -80,7 +80,8 @@ static void *ch_ipsec_uld_add(const struct cxgb4_lld_info *infop);
static void ch_ipsec_advance_esn_state(struct xfrm_state *x);
static void ch_ipsec_xfrm_free_state(struct xfrm_state *x);
static void ch_ipsec_xfrm_del_state(struct xfrm_state *x);
-static int ch_ipsec_xfrm_add_state(struct xfrm_state *x);
+static int ch_ipsec_xfrm_add_state(struct xfrm_state *x,
+ struct netlink_ext_ack *extack);
static const struct xfrmdev_ops ch_ipsec_xfrmdev_ops = {
.xdo_dev_state_add = ch_ipsec_xfrm_add_state,
@@ -226,65 +227,66 @@ out:
* returns 0 on success, negative error if failed to send message to FPGA
* positive error if FPGA returned a bad response
*/
-static int ch_ipsec_xfrm_add_state(struct xfrm_state *x)
+static int ch_ipsec_xfrm_add_state(struct xfrm_state *x,
+ struct netlink_ext_ack *extack)
{
struct ipsec_sa_entry *sa_entry;
int res = 0;
if (x->props.aalgo != SADB_AALG_NONE) {
- pr_debug("Cannot offload authenticated xfrm states\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload authenticated xfrm states");
return -EINVAL;
}
if (x->props.calgo != SADB_X_CALG_NONE) {
- pr_debug("Cannot offload compressed xfrm states\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload compressed xfrm states");
return -EINVAL;
}
if (x->props.family != AF_INET &&
x->props.family != AF_INET6) {
- pr_debug("Only IPv4/6 xfrm state offloaded\n");
+ NL_SET_ERR_MSG_MOD(extack, "Only IPv4/6 xfrm state offloaded");
return -EINVAL;
}
if (x->props.mode != XFRM_MODE_TRANSPORT &&
x->props.mode != XFRM_MODE_TUNNEL) {
- pr_debug("Only transport and tunnel xfrm offload\n");
+ NL_SET_ERR_MSG_MOD(extack, "Only transport and tunnel xfrm offload");
return -EINVAL;
}
if (x->id.proto != IPPROTO_ESP) {
- pr_debug("Only ESP xfrm state offloaded\n");
+ NL_SET_ERR_MSG_MOD(extack, "Only ESP xfrm state offloaded");
return -EINVAL;
}
if (x->encap) {
- pr_debug("Encapsulated xfrm state not offloaded\n");
+ NL_SET_ERR_MSG_MOD(extack, "Encapsulated xfrm state not offloaded");
return -EINVAL;
}
if (!x->aead) {
- pr_debug("Cannot offload xfrm states without aead\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states without aead");
return -EINVAL;
}
if (x->aead->alg_icv_len != 128 &&
x->aead->alg_icv_len != 96) {
- pr_debug("Cannot offload xfrm states with AEAD ICV length other than 96b & 128b\n");
- return -EINVAL;
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states with AEAD ICV length other than 96b & 128b");
+ return -EINVAL;
}
if ((x->aead->alg_key_len != 128 + 32) &&
(x->aead->alg_key_len != 256 + 32)) {
- pr_debug("cannot offload xfrm states with AEAD key length other than 128/256 bit\n");
+ NL_SET_ERR_MSG_MOD(extack, "cannot offload xfrm states with AEAD key length other than 128/256 bit");
return -EINVAL;
}
if (x->tfcpad) {
- pr_debug("Cannot offload xfrm states with tfc padding\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states with tfc padding");
return -EINVAL;
}
if (!x->geniv) {
- pr_debug("Cannot offload xfrm states without geniv\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states without geniv");
return -EINVAL;
}
if (strcmp(x->geniv, "seqiv")) {
- pr_debug("Cannot offload xfrm states with geniv other than seqiv\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states with geniv other than seqiv");
return -EINVAL;
}
if (x->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
- pr_debug("Unsupported xfrm offload\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported xfrm offload");
return -EINVAL;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
index 53a969e34883..13a6fca31004 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
@@ -557,8 +557,10 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs)
/**
* ixgbe_ipsec_add_sa - program device with a security association
* @xs: pointer to transformer state struct
+ * @extack: extack point to fill failure reason
**/
-static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
+static int ixgbe_ipsec_add_sa(struct xfrm_state *xs,
+ struct netlink_ext_ack *extack)
{
struct net_device *dev = xs->xso.real_dev;
struct ixgbe_adapter *adapter = netdev_priv(dev);
@@ -570,23 +572,22 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
int i;
if (xs->id.proto != IPPROTO_ESP && xs->id.proto != IPPROTO_AH) {
- netdev_err(dev, "Unsupported protocol 0x%04x for ipsec offload\n",
- xs->id.proto);
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported protocol for ipsec offload");
return -EINVAL;
}
if (xs->props.mode != XFRM_MODE_TRANSPORT) {
- netdev_err(dev, "Unsupported mode for ipsec offload\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported mode for ipsec offload");
return -EINVAL;
}
if (ixgbe_ipsec_check_mgmt_ip(xs)) {
- netdev_err(dev, "IPsec IP addr clash with mgmt filters\n");
+ NL_SET_ERR_MSG_MOD(extack, "IPsec IP addr clash with mgmt filters");
return -EINVAL;
}
if (xs->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
- netdev_err(dev, "Unsupported ipsec offload type\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported ipsec offload type");
return -EINVAL;
}
@@ -594,14 +595,14 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
struct rx_sa rsa;
if (xs->calg) {
- netdev_err(dev, "Compression offload not supported\n");
+ NL_SET_ERR_MSG_MOD(extack, "Compression offload not supported");
return -EINVAL;
}
/* find the first unused index */
ret = ixgbe_ipsec_find_empty_idx(ipsec, true);
if (ret < 0) {
- netdev_err(dev, "No space for SA in Rx table!\n");
+ NL_SET_ERR_MSG_MOD(extack, "No space for SA in Rx table!");
return ret;
}
sa_idx = (u16)ret;
@@ -616,7 +617,7 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
/* get the key and salt */
ret = ixgbe_ipsec_parse_proto_keys(xs, rsa.key, &rsa.salt);
if (ret) {
- netdev_err(dev, "Failed to get key data for Rx SA table\n");
+ NL_SET_ERR_MSG_MOD(extack, "Failed to get key data for Rx SA table");
return ret;
}
@@ -676,7 +677,7 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
} else {
/* no match and no empty slot */
- netdev_err(dev, "No space for SA in Rx IP SA table\n");
+ NL_SET_ERR_MSG_MOD(extack, "No space for SA in Rx IP SA table");
memset(&rsa, 0, sizeof(rsa));
return -ENOSPC;
}
@@ -711,7 +712,7 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
/* find the first unused index */
ret = ixgbe_ipsec_find_empty_idx(ipsec, false);
if (ret < 0) {
- netdev_err(dev, "No space for SA in Tx table\n");
+ NL_SET_ERR_MSG_MOD(extack, "No space for SA in Tx table");
return ret;
}
sa_idx = (u16)ret;
@@ -725,7 +726,7 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
ret = ixgbe_ipsec_parse_proto_keys(xs, tsa.key, &tsa.salt);
if (ret) {
- netdev_err(dev, "Failed to get key data for Tx SA table\n");
+ NL_SET_ERR_MSG_MOD(extack, "Failed to get key data for Tx SA table");
memset(&tsa, 0, sizeof(tsa));
return ret;
}
@@ -950,7 +951,7 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
memcpy(xs->aead->alg_name, aes_gcm_name, sizeof(aes_gcm_name));
/* set up the HW offload */
- err = ixgbe_ipsec_add_sa(xs);
+ err = ixgbe_ipsec_add_sa(xs, NULL);
if (err)
goto err_aead;
diff --git a/drivers/net/ethernet/intel/ixgbevf/ipsec.c b/drivers/net/ethernet/intel/ixgbevf/ipsec.c
index c1cf540d162a..66cf17f19408 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ipsec.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ipsec.c
@@ -257,8 +257,10 @@ static int ixgbevf_ipsec_parse_proto_keys(struct xfrm_state *xs,
/**
* ixgbevf_ipsec_add_sa - program device with a security association
* @xs: pointer to transformer state struct
+ * @extack: extack point to fill failure reason
**/
-static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
+static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs,
+ struct netlink_ext_ack *extack)
{
struct net_device *dev = xs->xso.real_dev;
struct ixgbevf_adapter *adapter;
@@ -270,18 +272,17 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
ipsec = adapter->ipsec;
if (xs->id.proto != IPPROTO_ESP && xs->id.proto != IPPROTO_AH) {
- netdev_err(dev, "Unsupported protocol 0x%04x for IPsec offload\n",
- xs->id.proto);
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported protocol for IPsec offload");
return -EINVAL;
}
if (xs->props.mode != XFRM_MODE_TRANSPORT) {
- netdev_err(dev, "Unsupported mode for ipsec offload\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported mode for ipsec offload");
return -EINVAL;
}
if (xs->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
- netdev_err(dev, "Unsupported ipsec offload type\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported ipsec offload type");
return -EINVAL;
}
@@ -289,14 +290,14 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
struct rx_sa rsa;
if (xs->calg) {
- netdev_err(dev, "Compression offload not supported\n");
+ NL_SET_ERR_MSG_MOD(extack, "Compression offload not supported");
return -EINVAL;
}
/* find the first unused index */
ret = ixgbevf_ipsec_find_empty_idx(ipsec, true);
if (ret < 0) {
- netdev_err(dev, "No space for SA in Rx table!\n");
+ NL_SET_ERR_MSG_MOD(extack, "No space for SA in Rx table!");
return ret;
}
sa_idx = (u16)ret;
@@ -311,7 +312,7 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
/* get the key and salt */
ret = ixgbevf_ipsec_parse_proto_keys(xs, rsa.key, &rsa.salt);
if (ret) {
- netdev_err(dev, "Failed to get key data for Rx SA table\n");
+ NL_SET_ERR_MSG_MOD(extack, "Failed to get key data for Rx SA table");
return ret;
}
@@ -350,7 +351,7 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
/* find the first unused index */
ret = ixgbevf_ipsec_find_empty_idx(ipsec, false);
if (ret < 0) {
- netdev_err(dev, "No space for SA in Tx table\n");
+ NL_SET_ERR_MSG_MOD(extack, "No space for SA in Tx table");
return ret;
}
sa_idx = (u16)ret;
@@ -364,7 +365,7 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
ret = ixgbevf_ipsec_parse_proto_keys(xs, tsa.key, &tsa.salt);
if (ret) {
- netdev_err(dev, "Failed to get key data for Tx SA table\n");
+ NL_SET_ERR_MSG_MOD(extack, "Failed to get key data for Tx SA table");
memset(&tsa, 0, sizeof(tsa));
return ret;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
index bb9023957f74..e84c3400ba1d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
@@ -162,91 +162,87 @@ void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
mlx5e_ipsec_init_limits(sa_entry, attrs);
}
-static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
+static int mlx5e_xfrm_validate_state(struct mlx5_core_dev *mdev,
+ struct xfrm_state *x,
+ struct netlink_ext_ack *extack)
{
- struct net_device *netdev = x->xso.real_dev;
- struct mlx5e_priv *priv;
-
- priv = netdev_priv(netdev);
-
if (x->props.aalgo != SADB_AALG_NONE) {
- netdev_info(netdev, "Cannot offload authenticated xfrm states\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload authenticated xfrm states");
return -EINVAL;
}
if (x->props.ealgo != SADB_X_EALG_AES_GCM_ICV16) {
- netdev_info(netdev, "Only AES-GCM-ICV16 xfrm state may be offloaded\n");
+ NL_SET_ERR_MSG_MOD(extack, "Only AES-GCM-ICV16 xfrm state may be offloaded");
return -EINVAL;
}
if (x->props.calgo != SADB_X_CALG_NONE) {
- netdev_info(netdev, "Cannot offload compressed xfrm states\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload compressed xfrm states");
return -EINVAL;
}
if (x->props.flags & XFRM_STATE_ESN &&
- !(mlx5_ipsec_device_caps(priv->mdev) & MLX5_IPSEC_CAP_ESN)) {
- netdev_info(netdev, "Cannot offload ESN xfrm states\n");
+ !(mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_ESN)) {
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload ESN xfrm states");
return -EINVAL;
}
if (x->props.family != AF_INET &&
x->props.family != AF_INET6) {
- netdev_info(netdev, "Only IPv4/6 xfrm states may be offloaded\n");
+ NL_SET_ERR_MSG_MOD(extack, "Only IPv4/6 xfrm states may be offloaded");
return -EINVAL;
}
if (x->id.proto != IPPROTO_ESP) {
- netdev_info(netdev, "Only ESP xfrm state may be offloaded\n");
+ NL_SET_ERR_MSG_MOD(extack, "Only ESP xfrm state may be offloaded");
return -EINVAL;
}
if (x->encap) {
- netdev_info(netdev, "Encapsulated xfrm state may not be offloaded\n");
+ NL_SET_ERR_MSG_MOD(extack, "Encapsulated xfrm state may not be offloaded");
return -EINVAL;
}
if (!x->aead) {
- netdev_info(netdev, "Cannot offload xfrm states without aead\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states without aead");
return -EINVAL;
}
if (x->aead->alg_icv_len != 128) {
- netdev_info(netdev, "Cannot offload xfrm states with AEAD ICV length other than 128bit\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states with AEAD ICV length other than 128bit");
return -EINVAL;
}
if ((x->aead->alg_key_len != 128 + 32) &&
(x->aead->alg_key_len != 256 + 32)) {
- netdev_info(netdev, "Cannot offload xfrm states with AEAD key length other than 128/256 bit\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states with AEAD key length other than 128/256 bit");
return -EINVAL;
}
if (x->tfcpad) {
- netdev_info(netdev, "Cannot offload xfrm states with tfc padding\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states with tfc padding");
return -EINVAL;
}
if (!x->geniv) {
- netdev_info(netdev, "Cannot offload xfrm states without geniv\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states without geniv");
return -EINVAL;
}
if (strcmp(x->geniv, "seqiv")) {
- netdev_info(netdev, "Cannot offload xfrm states with geniv other than seqiv\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload xfrm states with geniv other than seqiv");
return -EINVAL;
}
switch (x->xso.type) {
case XFRM_DEV_OFFLOAD_CRYPTO:
- if (!(mlx5_ipsec_device_caps(priv->mdev) &
- MLX5_IPSEC_CAP_CRYPTO)) {
- netdev_info(netdev, "Crypto offload is not supported\n");
+ if (!(mlx5_ipsec_device_caps(mdev) & MLX5_IPSEC_CAP_CRYPTO)) {
+ NL_SET_ERR_MSG_MOD(extack, "Crypto offload is not supported");
return -EINVAL;
}
if (x->props.mode != XFRM_MODE_TRANSPORT &&
x->props.mode != XFRM_MODE_TUNNEL) {
- netdev_info(netdev, "Only transport and tunnel xfrm states may be offloaded\n");
+ NL_SET_ERR_MSG_MOD(extack, "Only transport and tunnel xfrm states may be offloaded");
return -EINVAL;
}
break;
case XFRM_DEV_OFFLOAD_PACKET:
- if (!(mlx5_ipsec_device_caps(priv->mdev) &
+ if (!(mlx5_ipsec_device_caps(mdev) &
MLX5_IPSEC_CAP_PACKET_OFFLOAD)) {
- netdev_info(netdev, "Packet offload is not supported\n");
+ NL_SET_ERR_MSG_MOD(extack, "Packet offload is not supported");
return -EINVAL;
}
if (x->props.mode != XFRM_MODE_TRANSPORT) {
- netdev_info(netdev, "Only transport xfrm states may be offloaded in packet mode\n");
+ NL_SET_ERR_MSG_MOD(extack, "Only transport xfrm states may be offloaded in packet mode");
return -EINVAL;
}
@@ -254,35 +250,30 @@ static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
x->replay_esn->replay_window != 64 &&
x->replay_esn->replay_window != 128 &&
x->replay_esn->replay_window != 256) {
- netdev_info(netdev,
- "Unsupported replay window size %u\n",
- x->replay_esn->replay_window);
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported replay window size");
return -EINVAL;
}
if (!x->props.reqid) {
- netdev_info(netdev, "Cannot offload without reqid\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload without reqid");
return -EINVAL;
}
if (x->lft.hard_byte_limit != XFRM_INF ||
x->lft.soft_byte_limit != XFRM_INF) {
- netdev_info(netdev,
- "Device doesn't support limits in bytes\n");
+ NL_SET_ERR_MSG_MOD(extack, "Device doesn't support limits in bytes");
return -EINVAL;
}
if (x->lft.soft_packet_limit >= x->lft.hard_packet_limit &&
x->lft.hard_packet_limit != XFRM_INF) {
/* XFRM stack doesn't prevent such configuration :(. */
- netdev_info(netdev,
- "Hard packet limit must be greater than soft one\n");
+ NL_SET_ERR_MSG_MOD(extack, "Hard packet limit must be greater than soft one");
return -EINVAL;
}
break;
default:
- netdev_info(netdev, "Unsupported xfrm offload type %d\n",
- x->xso.type);
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported xfrm offload type");
return -EINVAL;
}
return 0;
@@ -298,7 +289,8 @@ static void _update_xfrm_state(struct work_struct *work)
mlx5_accel_esp_modify_xfrm(sa_entry, &modify_work->attrs);
}
-static int mlx5e_xfrm_add_state(struct xfrm_state *x)
+static int mlx5e_xfrm_add_state(struct xfrm_state *x,
+ struct netlink_ext_ack *extack)
{
struct mlx5e_ipsec_sa_entry *sa_entry = NULL;
struct net_device *netdev = x->xso.real_dev;
@@ -311,15 +303,13 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x)
return -EOPNOTSUPP;
ipsec = priv->ipsec;
- err = mlx5e_xfrm_validate_state(x);
+ err = mlx5e_xfrm_validate_state(priv->mdev, x, extack);
if (err)
return err;
sa_entry = kzalloc(sizeof(*sa_entry), GFP_KERNEL);
- if (!sa_entry) {
- err = -ENOMEM;
- goto out;
- }
+ if (!sa_entry)
+ return -ENOMEM;
sa_entry->x = x;
sa_entry->ipsec = ipsec;
@@ -360,7 +350,7 @@ err_hw_ctx:
mlx5_ipsec_free_sa_ctx(sa_entry);
err_xfrm:
kfree(sa_entry);
-out:
+ NL_SET_ERR_MSG_MOD(extack, "Device failed to offload this policy");
return err;
}
@@ -497,34 +487,33 @@ static void mlx5e_xfrm_update_curlft(struct xfrm_state *x)
mlx5e_ipsec_aso_update_curlft(sa_entry, &x->curlft.packets);
}
-static int mlx5e_xfrm_validate_policy(struct xfrm_policy *x)
+static int mlx5e_xfrm_validate_policy(struct xfrm_policy *x,
+ struct netlink_ext_ack *extack)
{
- struct net_device *netdev = x->xdo.real_dev;
-
if (x->type != XFRM_POLICY_TYPE_MAIN) {
- netdev_info(netdev, "Cannot offload non-main policy types\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload non-main policy types");
return -EINVAL;
}
/* Please pay attention that we support only one template */
if (x->xfrm_nr > 1) {
- netdev_info(netdev, "Cannot offload more than one template\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload more than one template");
return -EINVAL;
}
if (x->xdo.dir != XFRM_DEV_OFFLOAD_IN &&
x->xdo.dir != XFRM_DEV_OFFLOAD_OUT) {
- netdev_info(netdev, "Cannot offload forward policy\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload forward policy");
return -EINVAL;
}
if (!x->xfrm_vec[0].reqid) {
- netdev_info(netdev, "Cannot offload policy without reqid\n");
+ NL_SET_ERR_MSG_MOD(extack, "Cannot offload policy without reqid");
return -EINVAL;
}
if (x->xdo.type != XFRM_DEV_OFFLOAD_PACKET) {
- netdev_info(netdev, "Unsupported xfrm offload type\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported xfrm offload type");
return -EINVAL;
}
@@ -550,7 +539,8 @@ mlx5e_ipsec_build_accel_pol_attrs(struct mlx5e_ipsec_pol_entry *pol_entry,
attrs->reqid = x->xfrm_vec[0].reqid;
}
-static int mlx5e_xfrm_add_policy(struct xfrm_policy *x)
+static int mlx5e_xfrm_add_policy(struct xfrm_policy *x,
+ struct netlink_ext_ack *extack)
{
struct net_device *netdev = x->xdo.real_dev;
struct mlx5e_ipsec_pol_entry *pol_entry;
@@ -558,10 +548,12 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x)
int err;
priv = netdev_priv(netdev);
- if (!priv->ipsec)
+ if (!priv->ipsec) {
+ NL_SET_ERR_MSG_MOD(extack, "Device doesn't support IPsec packet offload");
return -EOPNOTSUPP;
+ }
- err = mlx5e_xfrm_validate_policy(x);
+ err = mlx5e_xfrm_validate_policy(x, extack);
if (err)
return err;
@@ -582,6 +574,7 @@ static int mlx5e_xfrm_add_policy(struct xfrm_policy *x)
err_fs:
kfree(pol_entry);
+ NL_SET_ERR_MSG_MOD(extack, "Device failed to offload this policy");
return err;
}
diff --git a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
index 4632268695cb..b44263177981 100644
--- a/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
+++ b/drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
@@ -260,7 +260,8 @@ static void set_sha2_512hmac(struct nfp_ipsec_cfg_add_sa *cfg, int *trunc_len)
}
}
-static int nfp_net_xfrm_add_state(struct xfrm_state *x)
+static int nfp_net_xfrm_add_state(struct xfrm_state *x,
+ struct netlink_ext_ack *extack)
{
struct net_device *netdev = x->xso.dev;
struct nfp_ipsec_cfg_mssg msg = {};
@@ -281,7 +282,7 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
cfg->ctrl_word.mode = NFP_IPSEC_PROTMODE_TRANSPORT;
break;
default:
- nn_err(nn, "Unsupported mode for xfrm offload\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported mode for xfrm offload");
return -EINVAL;
}
@@ -293,17 +294,17 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
cfg->ctrl_word.proto = NFP_IPSEC_PROTOCOL_AH;
break;
default:
- nn_err(nn, "Unsupported protocol for xfrm offload\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported protocol for xfrm offload");
return -EINVAL;
}
if (x->props.flags & XFRM_STATE_ESN) {
- nn_err(nn, "Unsupported XFRM_REPLAY_MODE_ESN for xfrm offload\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported XFRM_REPLAY_MODE_ESN for xfrm offload");
return -EINVAL;
}
if (x->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
- nn_err(nn, "Unsupported xfrm offload tyoe\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported xfrm offload type");
return -EINVAL;
}
@@ -320,7 +321,7 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
if (x->aead) {
trunc_len = -1;
} else {
- nn_err(nn, "Unsupported authentication algorithm\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported authentication algorithm");
return -EINVAL;
}
break;
@@ -344,19 +345,19 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
set_sha2_512hmac(cfg, &trunc_len);
break;
default:
- nn_err(nn, "Unsupported authentication algorithm\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported authentication algorithm");
return -EINVAL;
}
if (!trunc_len) {
- nn_err(nn, "Unsupported authentication algorithm trunc length\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported authentication algorithm trunc length");
return -EINVAL;
}
if (x->aalg) {
key_len = DIV_ROUND_UP(x->aalg->alg_key_len, BITS_PER_BYTE);
if (key_len > sizeof(cfg->auth_key)) {
- nn_err(nn, "Insufficient space for offloaded auth key\n");
+ NL_SET_ERR_MSG_MOD(extack, "Insufficient space for offloaded auth key");
return -EINVAL;
}
for (i = 0; i < key_len / sizeof(cfg->auth_key[0]) ; i++)
@@ -378,12 +379,12 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
case SADB_X_EALG_AES_GCM_ICV16:
case SADB_X_EALG_NULL_AES_GMAC:
if (!x->aead) {
- nn_err(nn, "Invalid AES key data\n");
+ NL_SET_ERR_MSG_MOD(extack, "Invalid AES key data");
return -EINVAL;
}
if (x->aead->alg_icv_len != 128) {
- nn_err(nn, "ICV must be 128bit with SADB_X_EALG_AES_GCM_ICV16\n");
+ NL_SET_ERR_MSG_MOD(extack, "ICV must be 128bit with SADB_X_EALG_AES_GCM_ICV16");
return -EINVAL;
}
cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CTR;
@@ -391,23 +392,23 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
/* Aead->alg_key_len includes 32-bit salt */
if (set_aes_keylen(cfg, x->props.ealgo, x->aead->alg_key_len - 32)) {
- nn_err(nn, "Unsupported AES key length %d\n", x->aead->alg_key_len);
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported AES key length");
return -EINVAL;
}
break;
case SADB_X_EALG_AESCBC:
cfg->ctrl_word.cimode = NFP_IPSEC_CIMODE_CBC;
if (!x->ealg) {
- nn_err(nn, "Invalid AES key data\n");
+ NL_SET_ERR_MSG_MOD(extack, "Invalid AES key data");
return -EINVAL;
}
if (set_aes_keylen(cfg, x->props.ealgo, x->ealg->alg_key_len) < 0) {
- nn_err(nn, "Unsupported AES key length %d\n", x->ealg->alg_key_len);
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported AES key length");
return -EINVAL;
}
break;
default:
- nn_err(nn, "Unsupported encryption algorithm for offload\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported encryption algorithm for offload");
return -EINVAL;
}
@@ -418,7 +419,7 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
key_len -= salt_len;
if (key_len > sizeof(cfg->ciph_key)) {
- nn_err(nn, "aead: Insufficient space for offloaded key\n");
+ NL_SET_ERR_MSG_MOD(extack, "aead: Insufficient space for offloaded key");
return -EINVAL;
}
@@ -434,7 +435,7 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
key_len = DIV_ROUND_UP(x->ealg->alg_key_len, BITS_PER_BYTE);
if (key_len > sizeof(cfg->ciph_key)) {
- nn_err(nn, "ealg: Insufficient space for offloaded key\n");
+ NL_SET_ERR_MSG_MOD(extack, "ealg: Insufficient space for offloaded key");
return -EINVAL;
}
for (i = 0; i < key_len / sizeof(cfg->ciph_key[0]) ; i++)
@@ -457,7 +458,7 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
}
break;
default:
- nn_err(nn, "Unsupported address family\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported address family");
return -EINVAL;
}
@@ -472,7 +473,7 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
err = xa_alloc(&nn->xa_ipsec, &saidx, x,
XA_LIMIT(0, NFP_NET_IPSEC_MAX_SA_CNT - 1), GFP_KERNEL);
if (err < 0) {
- nn_err(nn, "Unable to get sa_data number for IPsec\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unable to get sa_data number for IPsec");
return err;
}
@@ -480,7 +481,7 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
err = nfp_ipsec_cfg_cmd_issue(nn, NFP_IPSEC_CFG_MSSG_ADD_SA, saidx, &msg);
if (err) {
xa_erase(&nn->xa_ipsec, saidx);
- nn_err(nn, "Failed to issue IPsec command err ret=%d\n", err);
+ NL_SET_ERR_MSG_MOD(extack, "Failed to issue IPsec command");
return err;
}
diff --git a/drivers/net/netdevsim/ipsec.c b/drivers/net/netdevsim/ipsec.c
index b93baf5c8bee..f0d58092e7e9 100644
--- a/drivers/net/netdevsim/ipsec.c
+++ b/drivers/net/netdevsim/ipsec.c
@@ -125,7 +125,8 @@ static int nsim_ipsec_parse_proto_keys(struct xfrm_state *xs,
return 0;
}
-static int nsim_ipsec_add_sa(struct xfrm_state *xs)
+static int nsim_ipsec_add_sa(struct xfrm_state *xs,
+ struct netlink_ext_ack *extack)
{
struct nsim_ipsec *ipsec;
struct net_device *dev;
@@ -139,25 +140,24 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs)
ipsec = &ns->ipsec;
if (xs->id.proto != IPPROTO_ESP && xs->id.proto != IPPROTO_AH) {
- netdev_err(dev, "Unsupported protocol 0x%04x for ipsec offload\n",
- xs->id.proto);
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported protocol for ipsec offload");
return -EINVAL;
}
if (xs->calg) {
- netdev_err(dev, "Compression offload not supported\n");
+ NL_SET_ERR_MSG_MOD(extack, "Compression offload not supported");
return -EINVAL;
}
if (xs->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
- netdev_err(dev, "Unsupported ipsec offload type\n");
+ NL_SET_ERR_MSG_MOD(extack, "Unsupported ipsec offload type");
return -EINVAL;
}
/* find the first unused index */
ret = nsim_ipsec_find_empty_idx(ipsec);
if (ret < 0) {
- netdev_err(dev, "No space for SA in Rx table!\n");
+ NL_SET_ERR_MSG_MOD(extack, "No space for SA in Rx table!");
return ret;
}
sa_idx = (u16)ret;
@@ -172,7 +172,7 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs)
/* get the key and salt */
ret = nsim_ipsec_parse_proto_keys(xs, sa.key, &sa.salt);
if (ret) {
- netdev_err(dev, "Failed to get key data for SA table\n");
+ NL_SET_ERR_MSG_MOD(extack, "Failed to get key data for SA table");
return ret;
}
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index aad12a179e54..63b77cbc947e 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1035,14 +1035,14 @@ struct netdev_bpf {
#ifdef CONFIG_XFRM_OFFLOAD
struct xfrmdev_ops {
- int (*xdo_dev_state_add) (struct xfrm_state *x);
+ int (*xdo_dev_state_add) (struct xfrm_state *x, struct netlink_ext_ack *extack);
void (*xdo_dev_state_delete) (struct xfrm_state *x);
void (*xdo_dev_state_free) (struct xfrm_state *x);
bool (*xdo_dev_offload_ok) (struct sk_buff *skb,
struct xfrm_state *x);
void (*xdo_dev_state_advance_esn) (struct xfrm_state *x);
void (*xdo_dev_state_update_curlft) (struct xfrm_state *x);
- int (*xdo_dev_policy_add) (struct xfrm_policy *x);
+ int (*xdo_dev_policy_add) (struct xfrm_policy *x, struct netlink_ext_ack *extack);
void (*xdo_dev_policy_delete) (struct xfrm_policy *x);
void (*xdo_dev_policy_free) (struct xfrm_policy *x);
};
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 4aff76c6f12e..562b9d951598 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -309,7 +309,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
else
xso->type = XFRM_DEV_OFFLOAD_CRYPTO;
- err = dev->xfrmdev_ops->xdo_dev_state_add(x);
+ err = dev->xfrmdev_ops->xdo_dev_state_add(x, extack);
if (err) {
xso->dev = NULL;
xso->dir = 0;
@@ -325,10 +325,8 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
* authors to do not return -EOPNOTSUPP in packet offload mode.
*/
WARN_ON(err == -EOPNOTSUPP && is_packet_offload);
- if (err != -EOPNOTSUPP || is_packet_offload) {
- NL_SET_ERR_MSG(extack, "Device failed to offload this state");
+ if (err != -EOPNOTSUPP || is_packet_offload)
return err;
- }
}
return 0;
@@ -383,14 +381,13 @@ int xfrm_dev_policy_add(struct net *net, struct xfrm_policy *xp,
return -EINVAL;
}
- err = dev->xfrmdev_ops->xdo_dev_policy_add(xp);
+ err = dev->xfrmdev_ops->xdo_dev_policy_add(xp, extack);
if (err) {
xdo->dev = NULL;
xdo->real_dev = NULL;
xdo->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
xdo->dir = 0;
netdev_put(dev, &xdo->dev_tracker);
- NL_SET_ERR_MSG(extack, "Device failed to offload this policy");
return err;
}
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 89c731f4f0c7..59fffa02d1cc 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1274,7 +1274,7 @@ found:
xso->real_dev = xdo->real_dev;
netdev_tracker_alloc(xso->dev, &xso->dev_tracker,
GFP_ATOMIC);
- error = xso->dev->xfrmdev_ops->xdo_dev_state_add(x);
+ error = xso->dev->xfrmdev_ops->xdo_dev_state_add(x, NULL);
if (error) {
xso->dir = 0;
netdev_put(xso->dev, &xso->dev_tracker);