Commit 7681a4f5 authored by Leon Romanovsky's avatar Leon Romanovsky Committed by Jakub Kicinski

xfrm: extend add state callback to set failure reason

Almost all validation logic is in the drivers, but they are
missing reliable way to convey failure reason to userspace
applications.

Let's use extack to return this information to users.
Signed-off-by: default avatarLeon Romanovsky <leonro@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 1bb70c5a
...@@ -64,7 +64,7 @@ Callbacks to implement ...@@ -64,7 +64,7 @@ Callbacks to implement
/* from include/linux/netdevice.h */ /* from include/linux/netdevice.h */
struct xfrmdev_ops { struct xfrmdev_ops {
/* Crypto and Packet offload callbacks */ /* 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_delete) (struct xfrm_state *x);
void (*xdo_dev_state_free) (struct xfrm_state *x); void (*xdo_dev_state_free) (struct xfrm_state *x);
bool (*xdo_dev_offload_ok) (struct sk_buff *skb, bool (*xdo_dev_offload_ok) (struct sk_buff *skb,
......
...@@ -419,8 +419,10 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev, ...@@ -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 * bond_ipsec_add_sa - program device with a security association
* @xs: pointer to transformer state struct * @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 net_device *bond_dev = xs->xso.dev;
struct bond_ipsec *ipsec; struct bond_ipsec *ipsec;
...@@ -454,7 +456,7 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs) ...@@ -454,7 +456,7 @@ static int bond_ipsec_add_sa(struct xfrm_state *xs)
} }
xs->xso.real_dev = slave->dev; 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) { if (!err) {
ipsec->xs = xs; ipsec->xs = xs;
INIT_LIST_HEAD(&ipsec->list); INIT_LIST_HEAD(&ipsec->list);
...@@ -494,7 +496,7 @@ static void bond_ipsec_add_sa_all(struct bonding *bond) ...@@ -494,7 +496,7 @@ static void bond_ipsec_add_sa_all(struct bonding *bond)
spin_lock_bh(&bond->ipsec_lock); spin_lock_bh(&bond->ipsec_lock);
list_for_each_entry(ipsec, &bond->ipsec_list, list) { list_for_each_entry(ipsec, &bond->ipsec_list, list) {
ipsec->xs->xso.real_dev = slave->dev; 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__); slave_warn(bond_dev, slave->dev, "%s: failed to add SA\n", __func__);
ipsec->xs->xso.real_dev = NULL; ipsec->xs->xso.real_dev = NULL;
} }
......
...@@ -6490,7 +6490,8 @@ static const struct tlsdev_ops cxgb4_ktls_ops = { ...@@ -6490,7 +6490,8 @@ static const struct tlsdev_ops cxgb4_ktls_ops = {
#if IS_ENABLED(CONFIG_CHELSIO_IPSEC_INLINE) #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); struct adapter *adap = netdev2adap(x->xso.dev);
int ret; int ret;
...@@ -6504,7 +6505,7 @@ static int cxgb4_xfrm_add_state(struct xfrm_state *x) ...@@ -6504,7 +6505,7 @@ static int cxgb4_xfrm_add_state(struct xfrm_state *x)
if (ret) if (ret)
goto out_unlock; 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: out_unlock:
mutex_unlock(&uld_mutex); mutex_unlock(&uld_mutex);
......
...@@ -80,7 +80,8 @@ static void *ch_ipsec_uld_add(const struct cxgb4_lld_info *infop); ...@@ -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_advance_esn_state(struct xfrm_state *x);
static void ch_ipsec_xfrm_free_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 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 = { static const struct xfrmdev_ops ch_ipsec_xfrmdev_ops = {
.xdo_dev_state_add = ch_ipsec_xfrm_add_state, .xdo_dev_state_add = ch_ipsec_xfrm_add_state,
...@@ -226,7 +227,8 @@ static int ch_ipsec_setkey(struct xfrm_state *x, ...@@ -226,7 +227,8 @@ static int ch_ipsec_setkey(struct xfrm_state *x,
* returns 0 on success, negative error if failed to send message to FPGA * returns 0 on success, negative error if failed to send message to FPGA
* positive error if FPGA returned a bad response * 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; struct ipsec_sa_entry *sa_entry;
int res = 0; int res = 0;
......
...@@ -557,8 +557,10 @@ static int ixgbe_ipsec_check_mgmt_ip(struct xfrm_state *xs) ...@@ -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 * ixgbe_ipsec_add_sa - program device with a security association
* @xs: pointer to transformer state struct * @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 net_device *dev = xs->xso.real_dev;
struct ixgbe_adapter *adapter = netdev_priv(dev); struct ixgbe_adapter *adapter = netdev_priv(dev);
...@@ -950,7 +952,7 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) ...@@ -950,7 +952,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)); memcpy(xs->aead->alg_name, aes_gcm_name, sizeof(aes_gcm_name));
/* set up the HW offload */ /* set up the HW offload */
err = ixgbe_ipsec_add_sa(xs); err = ixgbe_ipsec_add_sa(xs, NULL);
if (err) if (err)
goto err_aead; goto err_aead;
......
...@@ -257,8 +257,10 @@ static int ixgbevf_ipsec_parse_proto_keys(struct xfrm_state *xs, ...@@ -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 * ixgbevf_ipsec_add_sa - program device with a security association
* @xs: pointer to transformer state struct * @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 net_device *dev = xs->xso.real_dev;
struct ixgbevf_adapter *adapter; struct ixgbevf_adapter *adapter;
......
...@@ -298,7 +298,8 @@ static void _update_xfrm_state(struct work_struct *work) ...@@ -298,7 +298,8 @@ static void _update_xfrm_state(struct work_struct *work)
mlx5_accel_esp_modify_xfrm(sa_entry, &modify_work->attrs); 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 mlx5e_ipsec_sa_entry *sa_entry = NULL;
struct net_device *netdev = x->xso.real_dev; struct net_device *netdev = x->xso.real_dev;
......
...@@ -260,7 +260,8 @@ static void set_sha2_512hmac(struct nfp_ipsec_cfg_add_sa *cfg, int *trunc_len) ...@@ -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 net_device *netdev = x->xso.dev;
struct nfp_ipsec_cfg_mssg msg = {}; struct nfp_ipsec_cfg_mssg msg = {};
......
...@@ -125,7 +125,8 @@ static int nsim_ipsec_parse_proto_keys(struct xfrm_state *xs, ...@@ -125,7 +125,8 @@ static int nsim_ipsec_parse_proto_keys(struct xfrm_state *xs,
return 0; 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 nsim_ipsec *ipsec;
struct net_device *dev; struct net_device *dev;
......
...@@ -1035,7 +1035,7 @@ struct netdev_bpf { ...@@ -1035,7 +1035,7 @@ struct netdev_bpf {
#ifdef CONFIG_XFRM_OFFLOAD #ifdef CONFIG_XFRM_OFFLOAD
struct xfrmdev_ops { 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_delete) (struct xfrm_state *x);
void (*xdo_dev_state_free) (struct xfrm_state *x); void (*xdo_dev_state_free) (struct xfrm_state *x);
bool (*xdo_dev_offload_ok) (struct sk_buff *skb, bool (*xdo_dev_offload_ok) (struct sk_buff *skb,
......
...@@ -309,7 +309,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, ...@@ -309,7 +309,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
else else
xso->type = XFRM_DEV_OFFLOAD_CRYPTO; 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) { if (err) {
xso->dev = NULL; xso->dev = NULL;
xso->dir = 0; xso->dir = 0;
...@@ -325,10 +325,8 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, ...@@ -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. * authors to do not return -EOPNOTSUPP in packet offload mode.
*/ */
WARN_ON(err == -EOPNOTSUPP && is_packet_offload); WARN_ON(err == -EOPNOTSUPP && is_packet_offload);
if (err != -EOPNOTSUPP || is_packet_offload) { if (err != -EOPNOTSUPP || is_packet_offload)
NL_SET_ERR_MSG(extack, "Device failed to offload this state");
return err; return err;
}
} }
return 0; return 0;
......
...@@ -1274,7 +1274,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr, ...@@ -1274,7 +1274,7 @@ xfrm_state_find(const xfrm_address_t *daddr, const xfrm_address_t *saddr,
xso->real_dev = xdo->real_dev; xso->real_dev = xdo->real_dev;
netdev_tracker_alloc(xso->dev, &xso->dev_tracker, netdev_tracker_alloc(xso->dev, &xso->dev_tracker,
GFP_ATOMIC); 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) { if (error) {
xso->dir = 0; xso->dir = 0;
netdev_put(xso->dev, &xso->dev_tracker); netdev_put(xso->dev, &xso->dev_tracker);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment