Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xfrm: allow state packet offload mode

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>

authored by

Leon Romanovsky and committed by
Steffen Klassert
62f6eca5 d14f28b8

+47 -5
+4
drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c
··· 283 283 pr_debug("Cannot offload xfrm states with geniv other than seqiv\n"); 284 284 return -EINVAL; 285 285 } 286 + if (x->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) { 287 + pr_debug("Unsupported xfrm offload\n"); 288 + return -EINVAL; 289 + } 286 290 287 291 sa_entry = kzalloc(sizeof(*sa_entry), GFP_KERNEL); 288 292 if (!sa_entry) {
+5
drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
··· 585 585 return -EINVAL; 586 586 } 587 587 588 + if (xs->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) { 589 + netdev_err(dev, "Unsupported ipsec offload type\n"); 590 + return -EINVAL; 591 + } 592 + 588 593 if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) { 589 594 struct rx_sa rsa; 590 595
+5
drivers/net/ethernet/intel/ixgbevf/ipsec.c
··· 280 280 return -EINVAL; 281 281 } 282 282 283 + if (xs->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) { 284 + netdev_err(dev, "Unsupported ipsec offload type\n"); 285 + return -EINVAL; 286 + } 287 + 283 288 if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) { 284 289 struct rx_sa rsa; 285 290
+4
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
··· 253 253 netdev_info(netdev, "Cannot offload xfrm states with geniv other than seqiv\n"); 254 254 return -EINVAL; 255 255 } 256 + if (x->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) { 257 + netdev_info(netdev, "Unsupported xfrm offload type\n"); 258 + return -EINVAL; 259 + } 256 260 return 0; 257 261 } 258 262
+5
drivers/net/ethernet/netronome/nfp/crypto/ipsec.c
··· 302 302 return -EINVAL; 303 303 } 304 304 305 + if (x->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) { 306 + nn_err(nn, "Unsupported xfrm offload tyoe\n"); 307 + return -EINVAL; 308 + } 309 + 305 310 cfg->spi = ntohl(x->id.spi); 306 311 307 312 /* Hash/Authentication */
+5
drivers/net/netdevsim/ipsec.c
··· 149 149 return -EINVAL; 150 150 } 151 151 152 + if (xs->xso.type != XFRM_DEV_OFFLOAD_CRYPTO) { 153 + netdev_err(dev, "Unsupported ipsec offload type\n"); 154 + return -EINVAL; 155 + } 156 + 152 157 /* find the first unused index */ 153 158 ret = nsim_ipsec_find_empty_idx(ipsec); 154 159 if (ret < 0) {
+19 -5
net/xfrm/xfrm_device.c
··· 229 229 struct xfrm_dev_offload *xso = &x->xso; 230 230 xfrm_address_t *saddr; 231 231 xfrm_address_t *daddr; 232 + bool is_packet_offload; 232 233 233 234 if (!x->type_offload) { 234 235 NL_SET_ERR_MSG(extack, "Type doesn't support offload"); ··· 242 241 return -EINVAL; 243 242 } 244 243 245 - if (xuo->flags & ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND)) { 244 + if (xuo->flags & 245 + ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND | XFRM_OFFLOAD_PACKET)) { 246 246 NL_SET_ERR_MSG(extack, "Unrecognized flags in offload request"); 247 247 return -EINVAL; 248 248 } 249 249 250 + is_packet_offload = xuo->flags & XFRM_OFFLOAD_PACKET; 250 251 dev = dev_get_by_index(net, xuo->ifindex); 251 252 if (!dev) { 252 253 if (!(xuo->flags & XFRM_OFFLOAD_INBOUND)) { ··· 263 260 x->props.family, 264 261 xfrm_smark_get(0, x)); 265 262 if (IS_ERR(dst)) 266 - return 0; 263 + return (is_packet_offload) ? -EINVAL : 0; 267 264 268 265 dev = dst->dev; 269 266 ··· 274 271 if (!dev->xfrmdev_ops || !dev->xfrmdev_ops->xdo_dev_state_add) { 275 272 xso->dev = NULL; 276 273 dev_put(dev); 277 - return 0; 274 + return (is_packet_offload) ? -EINVAL : 0; 278 275 } 279 276 280 277 if (x->props.flags & XFRM_STATE_ESN && ··· 294 291 else 295 292 xso->dir = XFRM_DEV_OFFLOAD_OUT; 296 293 297 - xso->type = XFRM_DEV_OFFLOAD_CRYPTO; 294 + if (is_packet_offload) 295 + xso->type = XFRM_DEV_OFFLOAD_PACKET; 296 + else 297 + xso->type = XFRM_DEV_OFFLOAD_CRYPTO; 298 298 299 299 err = dev->xfrmdev_ops->xdo_dev_state_add(x); 300 300 if (err) { ··· 307 301 netdev_put(dev, &xso->dev_tracker); 308 302 xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED; 309 303 310 - if (err != -EOPNOTSUPP) { 304 + /* User explicitly requested packet offload mode and configured 305 + * policy in addition to the XFRM state. So be civil to users, 306 + * and return an error instead of taking fallback path. 307 + * 308 + * This WARN_ON() can be seen as a documentation for driver 309 + * authors to do not return -EOPNOTSUPP in packet offload mode. 310 + */ 311 + WARN_ON(err == -EOPNOTSUPP && is_packet_offload); 312 + if (err != -EOPNOTSUPP || is_packet_offload) { 311 313 NL_SET_ERR_MSG(extack, "Device failed to offload this state"); 312 314 return err; 313 315 }