Skip to content

Commit

Permalink
xfrm: allow state packet offload mode
Browse files Browse the repository at this point in the history
Allow users to configure xfrm states with packet offload mode.
The packet mode must be requested both for policy and state, and
such requires us to do not implement fallback.

We explicitly return an error if requested packet mode can't
be configured.

Reviewed-by: Raed Salem <raeds@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
  • Loading branch information
Leon Romanovsky authored and Steffen Klassert committed Dec 5, 2022
1 parent d14f28b commit 62f6eca
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ static int ch_ipsec_xfrm_add_state(struct xfrm_state *x)
pr_debug("Cannot offload xfrm states with geniv other than seqiv\n");
return -EINVAL;
}
if (x->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
pr_debug("Unsupported xfrm offload\n");
return -EINVAL;
}

sa_entry = kzalloc(sizeof(*sa_entry), GFP_KERNEL);
if (!sa_entry) {
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,11 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs)
return -EINVAL;
}

if (xs->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
netdev_err(dev, "Unsupported ipsec offload type\n");
return -EINVAL;
}

if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) {
struct rx_sa rsa;

Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/intel/ixgbevf/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs)
return -EINVAL;
}

if (xs->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
netdev_err(dev, "Unsupported ipsec offload type\n");
return -EINVAL;
}

if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) {
struct rx_sa rsa;

Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@ static inline int mlx5e_xfrm_validate_state(struct xfrm_state *x)
netdev_info(netdev, "Cannot offload xfrm states with geniv other than seqiv\n");
return -EINVAL;
}
if (x->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
netdev_info(netdev, "Unsupported xfrm offload type\n");
return -EINVAL;
}
return 0;
}

Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,11 @@ static int nfp_net_xfrm_add_state(struct xfrm_state *x)
return -EINVAL;
}

if (x->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
nn_err(nn, "Unsupported xfrm offload tyoe\n");
return -EINVAL;
}

cfg->spi = ntohl(x->id.spi);

/* Hash/Authentication */
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/netdevsim/ipsec.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,11 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs)
return -EINVAL;
}

if (xs->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) {
netdev_err(dev, "Unsupported ipsec offload type\n");
return -EINVAL;
}

/* find the first unused index */
ret = nsim_ipsec_find_empty_idx(ipsec);
if (ret < 0) {
Expand Down
24 changes: 19 additions & 5 deletions net/xfrm/xfrm_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
struct xfrm_dev_offload *xso = &x->xso;
xfrm_address_t *saddr;
xfrm_address_t *daddr;
bool is_packet_offload;

if (!x->type_offload) {
NL_SET_ERR_MSG(extack, "Type doesn't support offload");
Expand All @@ -241,11 +242,13 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
return -EINVAL;
}

if (xuo->flags & ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND)) {
if (xuo->flags &
~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND | XFRM_OFFLOAD_PACKET)) {
NL_SET_ERR_MSG(extack, "Unrecognized flags in offload request");
return -EINVAL;
}

is_packet_offload = xuo->flags & XFRM_OFFLOAD_PACKET;
dev = dev_get_by_index(net, xuo->ifindex);
if (!dev) {
if (!(xuo->flags & XFRM_OFFLOAD_INBOUND)) {
Expand All @@ -260,7 +263,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
x->props.family,
xfrm_smark_get(0, x));
if (IS_ERR(dst))
return 0;
return (is_packet_offload) ? -EINVAL : 0;

dev = dst->dev;

Expand All @@ -271,7 +274,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
if (!dev->xfrmdev_ops || !dev->xfrmdev_ops->xdo_dev_state_add) {
xso->dev = NULL;
dev_put(dev);
return 0;
return (is_packet_offload) ? -EINVAL : 0;
}

if (x->props.flags & XFRM_STATE_ESN &&
Expand All @@ -291,7 +294,10 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
else
xso->dir = XFRM_DEV_OFFLOAD_OUT;

xso->type = XFRM_DEV_OFFLOAD_CRYPTO;
if (is_packet_offload)
xso->type = XFRM_DEV_OFFLOAD_PACKET;
else
xso->type = XFRM_DEV_OFFLOAD_CRYPTO;

err = dev->xfrmdev_ops->xdo_dev_state_add(x);
if (err) {
Expand All @@ -301,7 +307,15 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
netdev_put(dev, &xso->dev_tracker);
xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;

if (err != -EOPNOTSUPP) {
/* User explicitly requested packet offload mode and configured
* policy in addition to the XFRM state. So be civil to users,
* and return an error instead of taking fallback path.
*
* This WARN_ON() can be seen as a documentation for driver
* 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");
return err;
}
Expand Down

0 comments on commit 62f6eca

Please sign in to comment.