Skip to contentSkip to conversation

Extend XFRM core to allow full offload configuration

PATCH Superseded Leon Romanovsky 5 participants 45 messages Aug 16, 2022 – Aug 26, 2022

Subsystems (8)

v2 of 10 Superseded Latest is v10 →

lore
Share & tools
lore
#0 lore raw

v2 cover Extend XFRM core to allow full offload configuration

From: Leon Romanovsky <[email protected]>

Changelog:
v2:
* Rebased to latest 6.0-rc1
* Add an extra check in TX datapath patch to validate packets before forwarding to HW.
* Added policy cleanup logic in case of netdev down event
v1: https://lore.kernel.org/all/[email protected]
* Moved comment to be before if (...) in third patch.
v0: https://lore.kernel.org/all/[email protected]
-----------------------------------------------------------------------

The following series extends XFRM core code to handle new type of IPsec offload - full offload.

In this mode, the HW is going to be responsible for whole data path, so both policy and state should be offloaded.

Thanks

Leon Romanovsky (6):
xfrm: add new full offload flag
xfrm: allow state full offload mode
xfrm: add an interface to offload policy
xfrm: add TX datapath support for IPsec full offload mode
xfrm: add RX datapath protection for IPsec full offload mode
xfrm: enforce separation between priorities of HW/SW policies

 .../inline_crypto/ch_ipsec/chcr_ipsec.c       |   4 +
 .../net/ethernet/intel/ixgbe/ixgbe_ipsec.c    |   5 +
 drivers/net/ethernet/intel/ixgbevf/ipsec.c    |   5 +
 .../mellanox/mlx5/core/en_accel/ipsec.c       |   4 +
 drivers/net/netdevsim/ipsec.c                 |   5 +
 include/linux/netdevice.h                     |   3 +
 include/net/netns/xfrm.h                      |   8 +-
 include/net/xfrm.h                            | 104 +++++++---
 include/uapi/linux/xfrm.h                     |   6 +
 net/xfrm/xfrm_device.c                        | 101 +++++++++-
 net/xfrm/xfrm_output.c                        |  20 ++
 net/xfrm/xfrm_policy.c                        | 180 ++++++++++++++++++
 net/xfrm/xfrm_user.c                          |  19 ++
 13 files changed, 434 insertions(+), 30 deletions(-)
Signature · 1 line
2.37.2
#1 lore raw

PATCH v2 1/6 xfrm: add new full offload flag

From: Leon Romanovsky <[email protected]>

In the next patches, the xfrm core code will be extended to support new type of offload - full offload. In that mode, both policy and state should be specially configured in order to perform whole offloaded data path.

Full offload takes care of encryption, decryption, encapsulation and other operations with headers.

As this mode is new for XFRM policy flow, we can "start fresh" with flag bits and release first and second bit for future use.

---
 include/net/xfrm.h        | 7 +++++++
 include/uapi/linux/xfrm.h | 6 ++++++
 net/xfrm/xfrm_device.c    | 3 +++
 net/xfrm/xfrm_user.c      | 2 ++
 4 files changed, 18 insertions(+)
include/net/xfrm.h +7 -0
index 6e8fa98f786f..b4d487053dfd 100644
@@ -131,12 +131,19 @@ enum {
 	XFRM_DEV_OFFLOAD_OUT,
 };
 
+enum {
+	XFRM_DEV_OFFLOAD_UNSPECIFIED,
+	XFRM_DEV_OFFLOAD_CRYPTO,
+	XFRM_DEV_OFFLOAD_FULL,
+};
+
 struct xfrm_dev_offload {
 	struct net_device	*dev;
 	netdevice_tracker	dev_tracker;
 	struct net_device	*real_dev;
 	unsigned long		offload_handle;
 	u8			dir : 2;
+	u8			type : 2;
 };
 
 struct xfrm_mode {
include/uapi/linux/xfrm.h +6 -0
index b1f3e6a8f11a..3b084246d610 100644
@@ -519,6 +519,12 @@ struct xfrm_user_offload {
  */
 #define XFRM_OFFLOAD_IPV6	1
 #define XFRM_OFFLOAD_INBOUND	2
+/* Two bits above are relevant for state path only, while
+ * offload is used for both policy and state flows.
+ *
+ * In policy offload mode, they are free and can be safely reused.
+ */
+#define XFRM_OFFLOAD_FULL	4
 
 struct xfrm_userpolicy_default {
 #define XFRM_USERPOLICY_UNSPEC	0
net/xfrm/xfrm_device.c +3 -0
index 637ca8838436..6d1124eb1ec8 100644
@@ -270,12 +270,15 @@ 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;
+
 	err = dev->xfrmdev_ops->xdo_dev_state_add(x);
 	if (err) {
 		xso->dev = NULL;
 		xso->dir = 0;
 		xso->real_dev = NULL;
 		netdev_put(dev, &xso->dev_tracker);
+		xso->type = XFRM_DEV_OFFLOAD_UNSPECIFIED;
 
 		if (err != -EOPNOTSUPP)
 			return err;
net/xfrm/xfrm_user.c +2 -0
index 2ff017117730..9c0aef815730 100644
@@ -854,6 +854,8 @@ static int copy_user_offload(struct xfrm_dev_offload *xso, struct sk_buff *skb)
 	xuo->ifindex = xso->dev->ifindex;
 	if (xso->dir == XFRM_DEV_OFFLOAD_IN)
 		xuo->flags = XFRM_OFFLOAD_INBOUND;
+	if (xso->type == XFRM_DEV_OFFLOAD_FULL)
+		xuo->flags |= XFRM_OFFLOAD_FULL;
 
 	return 0;
 }
Signature · 1 line
2.37.2
#2 lore raw

PATCH v2 2/6 xfrm: allow state full offload mode

In reply to Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Allow users to configure xfrm states with full offload mode. The full 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 full mode can't be configured.

---
 .../inline_crypto/ch_ipsec/chcr_ipsec.c       |  4 ++++
 .../net/ethernet/intel/ixgbe/ixgbe_ipsec.c    |  5 ++++
 drivers/net/ethernet/intel/ixgbevf/ipsec.c    |  5 ++++
 .../mellanox/mlx5/core/en_accel/ipsec.c       |  4 ++++
 drivers/net/netdevsim/ipsec.c                 |  5 ++++
 net/xfrm/xfrm_device.c                        | 24 +++++++++++++++----
 6 files changed, 42 insertions(+), 5 deletions(-)
drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c +4 -0
index 585590520076..ca21794281d6 100644
@@ -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) {
drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c +5 -0
index 774de63dd93a..53a969e34883 100644
@@ -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;
 
drivers/net/ethernet/intel/ixgbevf/ipsec.c +5 -0
index 9984ebc62d78..c1cf540d162a 100644
@@ -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;
 
drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +4 -0
index 2a8fd7020622..c182b640b80d 100644
@@ -256,6 +256,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;
 }
 
drivers/net/netdevsim/ipsec.c +5 -0
index 386336a38f34..b93baf5c8bee 100644
@@ -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) {
net/xfrm/xfrm_device.c +19 -5
index 6d1124eb1ec8..5b04e5cdca64 100644
@@ -215,6 +215,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_full_offload;
 
 	if (!x->type_offload)
 		return -EINVAL;
@@ -223,9 +224,11 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
 	if (x->encap || x->tfcpad)
 		return -EINVAL;
 
-	if (xuo->flags & ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND))
+	if (xuo->flags &
+	    ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND | XFRM_OFFLOAD_FULL))
 		return -EINVAL;
 
+	is_full_offload = xuo->flags & XFRM_OFFLOAD_FULL;
 	dev = dev_get_by_index(net, xuo->ifindex);
 	if (!dev) {
 		if (!(xuo->flags & XFRM_OFFLOAD_INBOUND)) {
@@ -240,7 +243,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_full_offload) ? -EINVAL : 0;
 
 		dev = dst->dev;
 
@@ -251,7 +254,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_full_offload) ? -EINVAL : 0;
 	}
 
 	if (x->props.flags & XFRM_STATE_ESN &&
@@ -270,7 +273,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_full_offload)
+		xso->type = XFRM_DEV_OFFLOAD_FULL;
+	else
+		xso->type = XFRM_DEV_OFFLOAD_CRYPTO;
 
 	err = dev->xfrmdev_ops->xdo_dev_state_add(x);
 	if (err) {
@@ -280,7 +286,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 full 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 full offload mode.
+		 */
+		WARN_ON(err == -EOPNOTSUPP && is_full_offload);
+		if (err != -EOPNOTSUPP || is_full_offload)
 			return err;
 	}
 
Signature · 1 line
2.37.2
maintainer
#3 lore raw

Re: [PATCH xfrm-next v2 2/6] xfrm: allow state full offload mode

Quoted 11 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Allow users to configure xfrm states with full offload mode. The full 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 full mode can't be configured.

This one needs to be ACKed by the driver maintainers.

#4 lore raw

Re: [PATCH xfrm-next v2 2/6] xfrm: allow state full offload mode

Quoted 7 lines · Steffen Klassert
Quoted 6 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Allow users to configure xfrm states with full offload mode. The full mode must be requested both for policy and state, and such requires us to do not implement fallback.

Quoted 7 lines
Quoted 5 lines

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

This one needs to be ACKed by the driver maintainers.

Why? Only crypto is supported in upstream kernel.

Thanks

maintainer
#5 lore raw

Re: [PATCH xfrm-next v2 2/6] xfrm: allow state full offload mode

Quoted 11 lines · Leon Romanovsky
Quoted 10 lines · Steffen Klassert
Quoted 9 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Allow users to configure xfrm states with full offload mode. The full 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 full mode can't be configured.

Quoted 6 lines
Quoted 4 lines
Quoted 2 lines

This one needs to be ACKed by the driver maintainers.

Why? Only crypto is supported in upstream kernel.

Because it touches code hat is under their maintainance. They should at least be CCed on this patch.

#6 lore raw

Re: [PATCH xfrm-next v2 2/6] xfrm: allow state full offload mode

Quoted 15 lines · Steffen Klassert
Quoted 14 lines · Leon Romanovsky
Quoted 13 lines · Steffen Klassert
Quoted 11 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Allow users to configure xfrm states with full offload mode. The full 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 full mode can't be configured.

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

This one needs to be ACKed by the driver maintainers.

Why? Only crypto is supported in upstream kernel.

Because it touches code hat is under their maintainance. They should at least be CCed on this patch.

No problem, will do.

Thanks

#7 lore raw

PATCH v2 3/6 xfrm: add an interface to offload policy

In reply to Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Extend netlink interface to add and delete XFRM policy from the device. This functionality is a first step to implement full IPsec offload solution.

---
 include/linux/netdevice.h |  3 ++
 include/net/xfrm.h        | 42 ++++++++++++++++++++++++
 net/xfrm/xfrm_device.c    | 61 ++++++++++++++++++++++++++++++++++-
 net/xfrm/xfrm_policy.c    | 67 +++++++++++++++++++++++++++++++++++++++
 net/xfrm/xfrm_user.c      | 17 ++++++++++
 5 files changed, 189 insertions(+), 1 deletion(-)
include/linux/netdevice.h +3 -0
index 1a3cb93c3dcc..401c52aeab0e 100644
@@ -1012,6 +1012,9 @@ struct xfrmdev_ops {
 	bool	(*xdo_dev_offload_ok) (struct sk_buff *skb,
 				       struct xfrm_state *x);
 	void	(*xdo_dev_state_advance_esn) (struct xfrm_state *x);
+	int	(*xdo_dev_policy_add) (struct xfrm_policy *x);
+	void	(*xdo_dev_policy_delete) (struct xfrm_policy *x);
+	void	(*xdo_dev_policy_free) (struct xfrm_policy *x);
 };
 #endif
 
include/net/xfrm.h +42 -0

78 lines not on this page · raw message

net/xfrm/xfrm_device.c +60 -1

74 lines not on this page · raw message

net/xfrm/xfrm_policy.c +67 -0

97 lines not on this page · raw message

net/xfrm/xfrm_user.c +17 -0
index 9c0aef815730..698ff84da6ba 100644
@@ -1747,6 +1747,14 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us
 	if (attrs[XFRMA_IF_ID])
 		xp->if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
 
+	/* configure the hardware if offload is requested */
+	if (attrs[XFRMA_OFFLOAD_DEV]) {
+		err = xfrm_dev_policy_add(net, xp,
+				nla_data(attrs[XFRMA_OFFLOAD_DEV]), p->dir);
+		if (err)
+			goto error;
+	}
+
 	return xp;
  error:
 	*errp = err;
@@ -1785,6 +1793,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
 	xfrm_audit_policy_add(xp, err ? 0 : 1, true);
 
 	if (err) {
+		xfrm_dev_policy_delete(xp);
 		security_xfrm_policy_free(xp->security);
 		kfree(xp);
 		return err;
@@ -1897,6 +1906,8 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
 		err = xfrm_mark_put(skb, &xp->mark);
 	if (!err)
 		err = xfrm_if_id_put(skb, xp->if_id);
+	if (!err && xp->xdo.dev)
+		err = copy_user_offload(&xp->xdo, skb);
 	if (err) {
 		nlmsg_cancel(skb, nlh);
 		return err;
@@ -3213,6 +3224,8 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,
 		err = xfrm_mark_put(skb, &xp->mark);
 	if (!err)
 		err = xfrm_if_id_put(skb, xp->if_id);
+	if (!err && xp->xdo.dev)
+		err = copy_user_offload(&xp->xdo, skb);
 	if (err) {
 		nlmsg_cancel(skb, nlh);
 		return err;
@@ -3331,6 +3344,8 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
 		err = xfrm_mark_put(skb, &xp->mark);
 	if (!err)
 		err = xfrm_if_id_put(skb, xp->if_id);
+	if (!err && xp->xdo.dev)
+		err = copy_user_offload(&xp->xdo, skb);
 	if (err) {
 		nlmsg_cancel(skb, nlh);
 		return err;
@@ -3414,6 +3429,8 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, const struct km_e
 		err = xfrm_mark_put(skb, &xp->mark);
 	if (!err)
 		err = xfrm_if_id_put(skb, xp->if_id);
+	if (!err && xp->xdo.dev)
+		err = copy_user_offload(&xp->xdo, skb);
 	if (err)
 		goto out_free_skb;
 
Signature · 1 line
2.37.2
#8 lore raw

PATCH v2 4/6 xfrm: add TX datapath support for IPsec full offload mode

In reply to Leon Romanovsky

From: Leon Romanovsky <[email protected]>

In IPsec full mode, the device is going to encrypt and encapsulate packets that are associated with offloaded policy. After successful policy lookup to indicate if packets should be offloaded or not, the stack forwards packets to the device to do the magic.

---
 net/xfrm/xfrm_device.c | 13 +++++++++++++
 net/xfrm/xfrm_output.c | 20 ++++++++++++++++++++
 2 files changed, 33 insertions(+)
net/xfrm/xfrm_device.c +13 -0
index 1cc482e9c87d..db5ebd36f68c 100644
@@ -120,6 +120,16 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
 	if (xo->flags & XFRM_GRO || x->xso.dir == XFRM_DEV_OFFLOAD_IN)
 		return skb;
 
+	/* The packet was sent to HW IPsec full offload engine,
+	 * but to wrong device. Drop the packet, so it won't skip
+	 * XFRM stack.
+	 */
+	if (x->xso.type == XFRM_DEV_OFFLOAD_FULL && x->xso.dev != dev) {
+		kfree_skb(skb);
+		dev_core_stats_tx_dropped_inc(dev);
+		return NULL;
+	}
+
 	/* This skb was already validated on the upper/virtual dev */
 	if ((x->xso.dev != dev) && (x->xso.real_dev == dev))
 		return skb;
@@ -366,6 +376,9 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
 	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
 	struct net_device *dev = x->xso.dev;
 
+	if (x->xso.type == XFRM_DEV_OFFLOAD_FULL)
+		goto ok;
+
 	if (!x->type_offload || x->encap)
 		return false;
 
net/xfrm/xfrm_output.c +20 -0
index 555ab35cd119..27a8dac9ca7d 100644
@@ -719,6 +719,26 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
 		break;
 	}
 
+	if (x->xso.type == XFRM_DEV_OFFLOAD_FULL) {
+		struct dst_entry *dst = skb_dst_pop(skb);
+
+		if (!dst || !xfrm_dev_offload_ok(skb, x)) {
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
+			kfree_skb(skb);
+			return -EHOSTUNREACH;
+		}
+
+		skb_dst_set(skb, dst);
+		err = skb_dst(skb)->ops->local_out(net, skb->sk, skb);
+		if (unlikely(err != 1))
+			return err;
+
+		if (!skb_dst(skb)->xfrm)
+			return dst_output(net, skb->sk, skb);
+
+		return 0;
+	}
+
 	secpath_reset(skb);
 
 	if (xfrm_dev_offload_ok(skb, x)) {
Signature · 1 line
2.37.2
maintainer
#9 lore raw

Re: [PATCH xfrm-next v2 4/6] xfrm: add TX datapath support for IPsec full offload mode

Quoted 21 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

In IPsec full mode, the device is going to encrypt and encapsulate packets that are associated with offloaded policy. After successful policy lookup to indicate if packets should be offloaded or not, the stack forwards packets to the device to do the magic.

---
 net/xfrm/xfrm_device.c | 13 +++++++++++++
 net/xfrm/xfrm_output.c | 20 ++++++++++++++++++++
 2 files changed, 33 insertions(+)
net/xfrm/xfrm_device.c +0 -0
index 1cc482e9c87d..db5ebd36f68c 100644

net/xfrm/xfrm_device.c bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x) · line 380

Quoted 5 lines
net/xfrm/xfrm_device.c +2 -0
@@ -366,6 +376,9 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
 	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
 	struct net_device *dev = x->xso.dev;
 
+	if (x->xso.type == XFRM_DEV_OFFLOAD_FULL)
+		goto ok;

You skip the PMTU checks here. I've seen that you check the packet length against the device MTU in one of your mlx5 patches, but that does not help if the PMTU is below.

Quoted 17 lines
net/xfrm/xfrm_output.c +8 -0
index 555ab35cd119..27a8dac9ca7d 100644
@@ -719,6 +719,26 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
 		break;
 	}
 
+	if (x->xso.type == XFRM_DEV_OFFLOAD_FULL) {
+		struct dst_entry *dst = skb_dst_pop(skb);
+
+		if (!dst || !xfrm_dev_offload_ok(skb, x)) {
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
+			kfree_skb(skb);
+			return -EHOSTUNREACH;
+		}

net/xfrm/xfrm_output.c int xfrm_output(struct sock *sk, struct sk_buff *skb) · line 739

Quoted 10 lines
net/xfrm/xfrm_output.c +10 -0
+
+		skb_dst_set(skb, dst);
+		err = skb_dst(skb)->ops->local_out(net, skb->sk, skb);
+		if (unlikely(err != 1))
+			return err;
+
+		if (!skb_dst(skb)->xfrm)
+			return dst_output(net, skb->sk, skb);
+
+		return 0;

You leak skb here. Also, this skb needs another tfm because skb_dst(skb)->xfrm is set.

#10 lore raw

Re: [PATCH xfrm-next v2 4/6] xfrm: add TX datapath support for IPsec full offload mode

Quoted 25 lines · Steffen Klassert
Quoted 24 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

In IPsec full mode, the device is going to encrypt and encapsulate packets that are associated with offloaded policy. After successful policy lookup to indicate if packets should be offloaded or not, the stack forwards packets to the device to do the magic.

---
 net/xfrm/xfrm_device.c | 13 +++++++++++++
 net/xfrm/xfrm_output.c | 20 ++++++++++++++++++++
 2 files changed, 33 insertions(+)
net/xfrm/xfrm_device.c +0 -0
index 1cc482e9c87d..db5ebd36f68c 100644
@@ -366,6 +376,9 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
 	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
 	struct net_device *dev = x->xso.dev;
 
Quoted 6 lines

net/xfrm/xfrm_device.c bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x) · line 380

Quoted 2 lines
net/xfrm/xfrm_device.c +2 -0
+	if (x->xso.type == XFRM_DEV_OFFLOAD_FULL)
+		goto ok;

You skip the PMTU checks here. I've seen that you check the packet length against the device MTU in one of your mlx5 patches, but that does not help if the PMTU is below.

If device supports transformation of the packet, this packet won't be counted as XFRM anymore. I'm not sure that we need to perform XFRM specific checks.

Quoted 23 lines
Quoted 23 lines
net/xfrm/xfrm_output.c +13 -0
index 555ab35cd119..27a8dac9ca7d 100644
@@ -719,6 +719,26 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
 		break;
 	}
 
+	if (x->xso.type == XFRM_DEV_OFFLOAD_FULL) {
+		struct dst_entry *dst = skb_dst_pop(skb);
+
+		if (!dst || !xfrm_dev_offload_ok(skb, x)) {
+			XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
+			kfree_skb(skb);
+			return -EHOSTUNREACH;
+		}
+
+		skb_dst_set(skb, dst);
+		err = skb_dst(skb)->ops->local_out(net, skb->sk, skb);
+		if (unlikely(err != 1))
+			return err;
Quoted 8 lines

net/xfrm/xfrm_output.c int xfrm_output(struct sock *sk, struct sk_buff *skb) · line 739

Quoted 5 lines
net/xfrm/xfrm_output.c +5 -0
+
+		if (!skb_dst(skb)->xfrm)
+			return dst_output(net, skb->sk, skb);
+
+		return 0;

You leak skb here. Also, this skb needs another tfm because skb_dst(skb)->xfrm is set.

I will fix, thanks.

Quoted 1 line
maintainer
#11 lore raw

Re: [PATCH xfrm-next v2 4/6] xfrm: add TX datapath support for IPsec full offload mode

Quoted 33 lines · Leon Romanovsky
Quoted 25 lines · Steffen Klassert
Quoted 24 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

In IPsec full mode, the device is going to encrypt and encapsulate packets that are associated with offloaded policy. After successful policy lookup to indicate if packets should be offloaded or not, the stack forwards packets to the device to do the magic.

---
 net/xfrm/xfrm_device.c | 13 +++++++++++++
 net/xfrm/xfrm_output.c | 20 ++++++++++++++++++++
 2 files changed, 33 insertions(+)
net/xfrm/xfrm_device.c +0 -0
index 1cc482e9c87d..db5ebd36f68c 100644
@@ -366,6 +376,9 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
 	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
 	struct net_device *dev = x->xso.dev;
 
Quoted 6 lines

net/xfrm/xfrm_device.c bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x) · line 380

Quoted 2 lines
net/xfrm/xfrm_device.c +2 -0
+	if (x->xso.type == XFRM_DEV_OFFLOAD_FULL)
+		goto ok;

You skip the PMTU checks here. I've seen that you check the packet length against the device MTU in one of your mlx5 patches, but that does not help if the PMTU is below.

Quoted 3 lines

If device supports transformation of the packet, this packet won't be counted as XFRM anymore. I'm not sure that we need to perform XFRM specific checks.

This is not xfrm specific, it makes sure that the packet you want to send fits into the PMTU.

#12 lore raw

Re: [PATCH xfrm-next v2 4/6] xfrm: add TX datapath support for IPsec full offload mode

Quoted 34 lines · Steffen Klassert
Quoted 33 lines · Leon Romanovsky
Quoted 31 lines · Steffen Klassert
Quoted 21 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

In IPsec full mode, the device is going to encrypt and encapsulate packets that are associated with offloaded policy. After successful policy lookup to indicate if packets should be offloaded or not, the stack forwards packets to the device to do the magic.

---
 net/xfrm/xfrm_device.c | 13 +++++++++++++
 net/xfrm/xfrm_output.c | 20 ++++++++++++++++++++
 2 files changed, 33 insertions(+)
net/xfrm/xfrm_device.c +0 -0
index 1cc482e9c87d..db5ebd36f68c 100644

net/xfrm/xfrm_device.c bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x) · line 380

Quoted 5 lines
net/xfrm/xfrm_device.c +2 -0
@@ -366,6 +376,9 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x)
 	struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
 	struct net_device *dev = x->xso.dev;
 
+	if (x->xso.type == XFRM_DEV_OFFLOAD_FULL)
+		goto ok;

You skip the PMTU checks here. I've seen that you check the packet length against the device MTU in one of your mlx5 patches, but that does not help if the PMTU is below.

Quoted 6 lines
Quoted 3 lines

If device supports transformation of the packet, this packet won't be counted as XFRM anymore. I'm not sure that we need to perform XFRM specific checks.

This is not xfrm specific, it makes sure that the packet you want to send fits into the PMTU.

I will add.

Thanks

#13 lore raw

PATCH v2 5/6 xfrm: add RX datapath protection for IPsec full offload mode

In reply to Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Traffic received by device with enabled IPsec full offload should be forwarded to the stack only after decryption, packet headers and trailers removed.

Such packets are expected to be seen as normal (non-XFRM) ones, while not-supported packets should be dropped by the HW.

---
 include/net/xfrm.h | 55 +++++++++++++++++++++++++++-------------------
 1 file changed, 32 insertions(+), 23 deletions(-)
include/net/xfrm.h +32 -23
index 587697eb1d31..b64853df7262 100644
@@ -1094,6 +1094,29 @@ xfrm_state_addr_cmp(const struct xfrm_tmpl *tmpl, const struct xfrm_state *x, un
 	return !0;
 }
 
+#ifdef CONFIG_XFRM
+static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
+{
+	struct sec_path *sp = skb_sec_path(skb);
+
+	return sp->xvec[sp->len - 1];
+}
+#endif
+
+static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
+{
+#ifdef CONFIG_XFRM
+	struct sec_path *sp = skb_sec_path(skb);
+
+	if (!sp || !sp->olen || sp->len != sp->olen)
+		return NULL;
+
+	return &sp->ovec[sp->olen - 1];
+#else
+	return NULL;
+#endif
+}
+
 #ifdef CONFIG_XFRM
 int __xfrm_policy_check(struct sock *, int dir, struct sk_buff *skb,
 			unsigned short family);
@@ -1125,6 +1148,15 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
 {
 	struct net *net = dev_net(skb->dev);
 	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
+	struct xfrm_offload *xo = xfrm_offload(skb);
+	struct xfrm_state *x;
+
+	if (xo) {
+		x = xfrm_input_state(skb);
+		if (x->xso.type == XFRM_DEV_OFFLOAD_FULL)
+			return (xo->flags & CRYPTO_DONE) &&
+			       (xo->status & CRYPTO_SUCCESS);
+	}
 
 	if (sk && sk->sk_policy[XFRM_POLICY_IN])
 		return __xfrm_policy_check(sk, ndir, skb, family);
@@ -1860,29 +1892,6 @@ static inline void xfrm_states_delete(struct xfrm_state **states, int n)
 }
 #endif
 
-#ifdef CONFIG_XFRM
-static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
-{
-	struct sec_path *sp = skb_sec_path(skb);
-
-	return sp->xvec[sp->len - 1];
-}
-#endif
-
-static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
-{
-#ifdef CONFIG_XFRM
-	struct sec_path *sp = skb_sec_path(skb);
-
-	if (!sp || !sp->olen || sp->len != sp->olen)
-		return NULL;
-
-	return &sp->ovec[sp->olen - 1];
-#else
-	return NULL;
-#endif
-}
-
 void __init xfrm_dev_init(void);
 
 #ifdef CONFIG_XFRM_OFFLOAD
Signature · 1 line
2.37.2
maintainer
#14 lore raw

Re: [PATCH xfrm-next v2 5/6] xfrm: add RX datapath protection for IPsec full offload mode

Quoted 18 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Traffic received by device with enabled IPsec full offload should be forwarded to the stack only after decryption, packet headers and trailers removed.

Such packets are expected to be seen as normal (non-XFRM) ones, while not-supported packets should be dropped by the HW.

include/net/xfrm.h +2 -0
@@ -1125,6 +1148,15 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
 {
 	struct net *net = dev_net(skb->dev);
 	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
+	struct xfrm_offload *xo = xfrm_offload(skb);
+	struct xfrm_state *x;

include/net/xfrm.h static inline int __xfrm_policy_check2(struct sock *sk, int dir, · line 1162

Quoted 10 lines
include/net/xfrm.h +7 -0
+
+	if (xo) {
+		x = xfrm_input_state(skb);
+		if (x->xso.type == XFRM_DEV_OFFLOAD_FULL)
+			return (xo->flags & CRYPTO_DONE) &&
+			       (xo->status & CRYPTO_SUCCESS);
+	}
 
 	if (sk && sk->sk_policy[XFRM_POLICY_IN])
 		return __xfrm_policy_check(sk, ndir, skb, family);

What happens here if there is a socket policy configured?

#15 lore raw

Re: [PATCH xfrm-next v2 5/6] xfrm: add RX datapath protection for IPsec full offload mode

Quoted 27 lines · Steffen Klassert
Quoted 26 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Traffic received by device with enabled IPsec full offload should be forwarded to the stack only after decryption, packet headers and trailers removed.

Such packets are expected to be seen as normal (non-XFRM) ones, while not-supported packets should be dropped by the HW.

include/net/xfrm.h +9 -0
@@ -1125,6 +1148,15 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
 {
 	struct net *net = dev_net(skb->dev);
 	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
+	struct xfrm_offload *xo = xfrm_offload(skb);
+	struct xfrm_state *x;
+
+	if (xo) {
+		x = xfrm_input_state(skb);
+		if (x->xso.type == XFRM_DEV_OFFLOAD_FULL)
+			return (xo->flags & CRYPTO_DONE) &&
+			       (xo->status & CRYPTO_SUCCESS);
+	}
 
Quoted 4 lines

include/net/xfrm.h static inline int __xfrm_policy_check2(struct sock *sk, int dir, · line 1162

Quoted 2 lines
include/net/xfrm.h +0 -0
 	if (sk && sk->sk_policy[XFRM_POLICY_IN])
 		return __xfrm_policy_check(sk, ndir, skb, family);

What happens here if there is a socket policy configured?

No change, we don't support offload of socket policies.

Thanks

maintainer
#16 lore raw

Re: [PATCH xfrm-next v2 5/6] xfrm: add RX datapath protection for IPsec full offload mode

Quoted 28 lines · Leon Romanovsky
Quoted 27 lines · Steffen Klassert
Quoted 26 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Traffic received by device with enabled IPsec full offload should be forwarded to the stack only after decryption, packet headers and trailers removed.

Such packets are expected to be seen as normal (non-XFRM) ones, while not-supported packets should be dropped by the HW.

include/net/xfrm.h +9 -0
@@ -1125,6 +1148,15 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
 {
 	struct net *net = dev_net(skb->dev);
 	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
+	struct xfrm_offload *xo = xfrm_offload(skb);
+	struct xfrm_state *x;
+
+	if (xo) {
+		x = xfrm_input_state(skb);
+		if (x->xso.type == XFRM_DEV_OFFLOAD_FULL)
+			return (xo->flags & CRYPTO_DONE) &&
+			       (xo->status & CRYPTO_SUCCESS);
+	}
 
Quoted 6 lines
Quoted 4 lines

include/net/xfrm.h static inline int __xfrm_policy_check2(struct sock *sk, int dir, · line 1162

Quoted 2 lines
include/net/xfrm.h +0 -0
 	if (sk && sk->sk_policy[XFRM_POLICY_IN])
 		return __xfrm_policy_check(sk, ndir, skb, family);

What happens here if there is a socket policy configured?

No change, we don't support offload of socket policies.

But the user can confugure it, so it should be enforced regardless if we had an offload before.

#17 lore raw

Re: [PATCH xfrm-next v2 5/6] xfrm: add RX datapath protection for IPsec full offload mode

Quoted 34 lines · Steffen Klassert
Quoted 33 lines · Leon Romanovsky
Quoted 31 lines · Steffen Klassert
Quoted 18 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Traffic received by device with enabled IPsec full offload should be forwarded to the stack only after decryption, packet headers and trailers removed.

Such packets are expected to be seen as normal (non-XFRM) ones, while not-supported packets should be dropped by the HW.

include/net/xfrm.h +2 -0
@@ -1125,6 +1148,15 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
 {
 	struct net *net = dev_net(skb->dev);
 	int ndir = dir | (reverse ? XFRM_POLICY_MASK + 1 : 0);
+	struct xfrm_offload *xo = xfrm_offload(skb);
+	struct xfrm_state *x;

include/net/xfrm.h static inline int __xfrm_policy_check2(struct sock *sk, int dir, · line 1162

Quoted 10 lines
include/net/xfrm.h +7 -0
+
+	if (xo) {
+		x = xfrm_input_state(skb);
+		if (x->xso.type == XFRM_DEV_OFFLOAD_FULL)
+			return (xo->flags & CRYPTO_DONE) &&
+			       (xo->status & CRYPTO_SUCCESS);
+	}
 
 	if (sk && sk->sk_policy[XFRM_POLICY_IN])
 		return __xfrm_policy_check(sk, ndir, skb, family);

What happens here if there is a socket policy configured?

Quoted 4 lines
Quoted 1 line

No change, we don't support offload of socket policies.

But the user can confugure it, so it should be enforced regardless if we had an offload before.

Thanks, I'll see how it can be resolved.

#18 lore raw

PATCH v2 6/6 xfrm: enforce separation between priorities of HW/SW policies

In reply to Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Devices that implement IPsec full offload mode offload policies too. In RX path, it causes to the situation that HW can't effectively handle mixed SW and HW priorities unless users make sure that HW offloaded policies have higher priorities.

In order to make sure that users have coherent picture, let's require that HW offloaded policies have always (both RX and TX) higher priorities than SW ones.

To do not over engineer the code, HW policies are treated as SW ones and don't take into account netdev to allow reuse of same priorities for different devices.

---
 include/net/netns/xfrm.h |   8 ++-
 net/xfrm/xfrm_policy.c   | 113 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+), 1 deletion(-)
include/net/netns/xfrm.h +7 -1
index bd7c3be4af5d..f0cfa0faf611 100644
@@ -29,6 +29,11 @@ struct xfrm_policy_hthresh {
 	u8			rbits6;
 };
 
+struct xfrm_policy_prio {
+	u32 max_sw_prio;
+	u32 min_hw_prio;
+};
+
 struct netns_xfrm {
 	struct list_head	state_all;
 	/*
@@ -52,7 +57,7 @@ struct netns_xfrm {
 	unsigned int		policy_idx_hmask;
 	struct hlist_head	policy_inexact[XFRM_POLICY_MAX];
 	struct xfrm_policy_hash	policy_bydst[XFRM_POLICY_MAX];
-	unsigned int		policy_count[XFRM_POLICY_MAX * 2];
+	unsigned int		policy_count[XFRM_POLICY_MAX * 3];
 	struct work_struct	policy_hash_work;
 	struct xfrm_policy_hthresh policy_hthresh;
 	struct list_head	inexact_bins;
@@ -67,6 +72,7 @@ struct netns_xfrm {
 	u32			sysctl_acq_expires;
 
 	u8			policy_default[XFRM_POLICY_MAX];
+	struct xfrm_policy_prio	policy_prio[XFRM_POLICY_MAX];
 
 #ifdef CONFIG_SYSCTL
 	struct ctl_table_header	*sysctl_hdr;
net/xfrm/xfrm_policy.c +113 -0

168 lines not on this page · raw message

Signature · 1 line
2.37.2
maintainer
#19 lore raw
In reply to Leon Romanovsky
Quoted 5 lines · On Tue, 16 Aug 2022 11:59:21 +0300 Leon Romanovsky wrote:

The following series extends XFRM core code to handle new type of IPsec offload - full offload.

In this mode, the HW is going to be responsible for whole data path, so both policy and state should be offloaded.

This is making a precedent for full tunnel offload in netdev, right? Could you indulge us with a more detailed description, motivation, performance results, where the behavior of offload may differ (if at all), what visibility users have, how SW and HW work together on the datapath? Documentation would be great.

#20 lore raw
Quoted 8 lines · Jakub Kicinski
Quoted 5 lines · On Tue, 16 Aug 2022 11:59:21 +0300 Leon Romanovsky wrote:

The following series extends XFRM core code to handle new type of IPsec offload - full offload.

In this mode, the HW is going to be responsible for whole data path, so both policy and state should be offloaded.

This is making a precedent for full tunnel offload in netdev, right?

Not really. SW IPsec supports two modes: tunnel and transport.

However HW and SW stack supports only offload of transport mode. This is the case for already merged IPsec crypto offload mode and the case for this full offload.

Quoted 4 lines

Could you indulge us with a more detailed description, motivation, performance results, where the behavior of offload may differ (if at all), what visibility users have, how SW and HW work together on the datapath? Documentation would be great.

IPsec full offload is actually improved version of IPsec crypto mode, In full mode, HW is responsible to trim/add headers in addition to decrypt/encrypt. In this mode, the packet arrives to the stack as already decrypted and vice versa for TX (exits to HW as not-encrypted).

My main motivation is to perform IPsec on RoCE traffic and in our preliminary results, we are able to do IPsec full offload in line rate. The same goes for ETH traffic.

Regarding behavior differences - they are not expected.

We (Raed and me) tried very hard to make sure that IPsec full offload will behave exactly as SW path.

There are some limitations to reduce complexity, but they can be removed later if needs will arise. Right now, none of them are "real" limitations for various *swarn forks, which we extend as well.

Some of them:
1. Request to have reqid for policy and state. I use reqid for HW matching between policy and state.
2. Automatic separation between HW and SW priorities, because HW sees packet first.
3. Only main template is supported.
4. No fallback to SW if IPsec HW failed to handle packet. HW should drop such packet.

Visibility:
Users can see the mode through iproute2
https://lore.kernel.org/netdev/[email protected]/
and see statistics through ethtool.

Documentation will come as well. I assume that IPsec folks are familiar with this topic as it was discussed in IPsec coffee hour.

Thanks

maintainer
#21 lore raw
Quoted 8 lines · On Wed, 17 Aug 2022 08:22:02 +0300 Leon Romanovsky wrote:
Quoted 1 line · Jakub Kicinski

This is making a precedent for full tunnel offload in netdev, right?

Not really. SW IPsec supports two modes: tunnel and transport.

However HW and SW stack supports only offload of transport mode. This is the case for already merged IPsec crypto offload mode and the case for this full offload.

My point is on what you called "full offload" vs "crypto offload". The policy so far has always been that Linux networking stack should populate all the headers and instruct the device to do crypto, no header insertion. Obviously we do header insertion in switch/router offloads but that's different and stateless.

I believe the reasoning was to provide as much flexibility and control to the software as possible while retaining most of the performance gains.

You must provide a clear analysis (as in examination in data) and discussion (as in examination in writing) if you're intending to change the "let's keep packet formation in the SW" policy. What you got below is a good start but not sufficient.

Quoted 5 lines
Quoted 4 lines

Could you indulge us with a more detailed description, motivation, performance results, where the behavior of offload may differ (if at all), what visibility users have, how SW and HW work together on the datapath? Documentation would be great.

Quoted 8 lines

IPsec full offload is actually improved version of IPsec crypto mode, In full mode, HW is responsible to trim/add headers in addition to decrypt/encrypt. In this mode, the packet arrives to the stack as already decrypted and vice versa for TX (exits to HW as not-encrypted).

My main motivation is to perform IPsec on RoCE traffic and in our preliminary results, we are able to do IPsec full offload in line rate. The same goes for ETH traffic.

If the motivation is RoCE I personally see no reason to provide the configuration of this functionality via netdev interfaces, but I'll obviously leave the final decision to Steffen.

Quoted 5 lines

Regarding behavior differences - they are not expected.

We (Raed and me) tried very hard to make sure that IPsec full offload will behave exactly as SW path.

Quoted 7 lines

There are some limitations to reduce complexity, but they can be removed later if needs will arise. Right now, none of them are "real" limitations for various *swarn forks, which we extend as well.

Some of them:
1. Request to have reqid for policy and state. I use reqid for HW matching between policy and state.

reqid?

Quoted 2 lines

2. Automatic separation between HW and SW priorities, because HW sees packet first.

More detail needed on that.

Quoted 3 lines

3. Only main template is supported.
4. No fallback to SW if IPsec HW failed to handle packet. HW should drop such packet.

Not great for debug.

Quoted 4 lines

Visibility:
Users can see the mode through iproute2
https://lore.kernel.org/netdev/[email protected]/
and see statistics through ethtool.

Custom vendor stats?

Quoted 2 lines

Documentation will come as well. I assume that IPsec folks are familiar with this topic as it was discussed in IPsec coffee hour.

#22 lore raw
Quoted 16 lines · Jakub Kicinski
Quoted 8 lines · On Wed, 17 Aug 2022 08:22:02 +0300 Leon Romanovsky wrote:
Quoted 1 line · Jakub Kicinski

This is making a precedent for full tunnel offload in netdev, right?

Not really. SW IPsec supports two modes: tunnel and transport.

However HW and SW stack supports only offload of transport mode. This is the case for already merged IPsec crypto offload mode and the case for this full offload.

My point is on what you called "full offload" vs "crypto offload". The policy so far has always been that Linux networking stack should populate all the headers and instruct the device to do crypto, no header insertion. Obviously we do header insertion in switch/router offloads but that's different and stateless.

Quoted 3 lines

I believe the reasoning was to provide as much flexibility and control to the software as possible while retaining most of the performance gains.

I honestly don't know the reasoning, but "performance gains" are very limited as long as IPsec stack involved with various policy/state lookups. These lookups are expensive in terms of CPU and they can't hold 400 Gb/s line rate.

https://docs.nvidia.com/networking/display/connectx7en/Introduction#Introduction-ConnectX-7400GbEAdapterCards

Quoted 5 lines

You must provide a clear analysis (as in examination in data) and discussion (as in examination in writing) if you're intending to change the "let's keep packet formation in the SW" policy. What you got below is a good start but not sufficient.

Can you please point me to an example of such analysis, so I will know what is needed/expected?

Quoted 11 lines
Quoted 11 lines
Quoted 5 lines

Could you indulge us with a more detailed description, motivation, performance results, where the behavior of offload may differ (if at all), what visibility users have, how SW and HW work together on the datapath? Documentation would be great.

IPsec full offload is actually improved version of IPsec crypto mode, In full mode, HW is responsible to trim/add headers in addition to decrypt/encrypt. In this mode, the packet arrives to the stack as already decrypted and vice versa for TX (exits to HW as not-encrypted).

Quoted 7 lines
Quoted 3 lines

My main motivation is to perform IPsec on RoCE traffic and in our preliminary results, we are able to do IPsec full offload in line rate. The same goes for ETH traffic.

If the motivation is RoCE I personally see no reason to provide the configuration of this functionality via netdev interfaces, but I'll obviously leave the final decision to Steffen.

This is not limited to RoCE, our customers use this offload for ethernet traffic as well.

RoCE is a good example of traffic that performs all headers magic in HW, without SW involved.

IPsec clearly belongs to netdev and we don't want to duplicate netdev functionality in RDMA. Like I said above, this feature is needed for regular ETH traffic as well.

Right now, RoCE and iWARP devices are based on netdev and long-standing agreement ( >20 years ????) that all netdev configurations are done there they belong - in netdev.

If you think that RDMA<->netdev binding should be untied and netdev functionality should be duplicated, feel free to submit topic to LPC and/or catch me and/or Jason to discuss it during the venue.

Quoted 10 lines
Quoted 10 lines

Regarding behavior differences - they are not expected.

We (Raed and me) tried very hard to make sure that IPsec full offload will behave exactly as SW path.

There are some limitations to reduce complexity, but they can be removed later if needs will arise. Right now, none of them are "real" limitations for various *swarn forks, which we extend as well.

Quoted 5 lines
Quoted 3 lines

Some of them:
1. Request to have reqid for policy and state. I use reqid for HW matching between policy and state.

reqid?

Policy and state are matched based on their selectors (src/deet IP, direction ...), but they independent. The reqid is XFRM identification that this specific policy is connected to this specific state.
https://www.man7.org/linux/man-pages/man8/ip-xfrm.8.html
https://docs.kernel.org/networking/xfrm_device.html
ip x s add ....
reqid 0x07 ...
offload dev eth4 dir in

IPsec SW allows to do not set this field. In offload mode, we want to be explicit and require from user to say which policy belongs to which state.

I personally never saw anyone who configures IPsec without reqid.

Quoted 5 lines
Quoted 3 lines

2. Automatic separation between HW and SW priorities, because HW sees packet first.

More detail needed on that.

I have description in the commit message of relevant commit.
https://lore.kernel.org/all/191be9b9c0367d4554b208533f5d75f498784889.1660639789.git.leonro@nvidia.com/
-----
Devices that implement IPsec full offload mode offload policies too. In RX path, it causes to the situation that HW can't effectively handle mixed SW and HW priorities unless users make sure that HW offloaded policies have higher priorities.

In order to make sure that users have coherent picture, let's require that HW offloaded policies have always (both RX and TX) higher priorities than SW ones.

To do not over engineer the code, HW policies are treated as SW ones and don't take into account netdev to allow reuse of same priorities for different devices.
-----

Quoted 6 lines
Quoted 4 lines

3. Only main template is supported.
4. No fallback to SW if IPsec HW failed to handle packet. HW should drop such packet.

Not great for debug.

For now, there are various vendor tools to inspect FW/HW state. We have some rough ideas on how can we improve it and forward bad packets to SW for analysis, but it is much advanced topic and needs this series to be merged first.

Quoted 7 lines
Quoted 5 lines

Visibility:
Users can see the mode through iproute2
https://lore.kernel.org/netdev/[email protected]/
and see statistics through ethtool.

Custom vendor stats?

XFRM doesn't have much to offer. There are bunch of LINUX_MIB_XFRM* counters, but nothing more.

Quoted 3 lines
Quoted 3 lines

Documentation will come as well. I assume that IPsec folks are familiar with this topic as it was discussed in IPsec coffee hour.

maintainer
#23 lore raw
Quoted 17 lines · Leon Romanovsky
Quoted 16 lines · Jakub Kicinski
Quoted 8 lines · On Wed, 17 Aug 2022 08:22:02 +0300 Leon Romanovsky wrote:
Quoted 1 line · Jakub Kicinski

This is making a precedent for full tunnel offload in netdev, right?

Not really. SW IPsec supports two modes: tunnel and transport.

However HW and SW stack supports only offload of transport mode. This is the case for already merged IPsec crypto offload mode and the case for this full offload.

My point is on what you called "full offload" vs "crypto offload". The policy so far has always been that Linux networking stack should populate all the headers and instruct the device to do crypto, no header insertion. Obviously we do header insertion in switch/router offloads but that's different and stateless.

Quoted 8 lines
Quoted 3 lines

I believe the reasoning was to provide as much flexibility and control to the software as possible while retaining most of the performance gains.

I honestly don't know the reasoning, but "performance gains" are very limited as long as IPsec stack involved with various policy/state lookups. These lookups are expensive in terms of CPU and they can't hold 400 Gb/s line rate.

Can you provide some performance results that show the difference between crypto and full offload? In particular because on the TX path, the full policy and state offload is done twice (in software to find the offloading device and then in hardware to match policy to state).

Quoted 8 lines

https://docs.nvidia.com/networking/display/connectx7en/Introduction#Introduction-ConnectX-7400GbEAdapterCards

Quoted 5 lines

You must provide a clear analysis (as in examination in data) and discussion (as in examination in writing) if you're intending to change the "let's keep packet formation in the SW" policy. What you got below is a good start but not sufficient.

I'm still a bit unease about this approach. I fear that doing parts of statefull IPsec procesing in software and parts in hardware will lead to all sort of problems. E.g. with this implementation the software has no stats, liftetime, lifebyte and packet count information but is responsible to do the IKE communication.

We might be able to sort out all problems during the upstraming process, but I still have no clear picture how this should work in the end with all corener cases this creates.

Also the name full offload is a bit missleading, because the software still has to hold all offloaded states and policies. In a full offload, the stack would IMO just act as a stub layer between IKE and hardware.

Quoted 6 lines
Quoted 5 lines
Quoted 3 lines

Some of them:
1. Request to have reqid for policy and state. I use reqid for HW matching between policy and state.

reqid?

Quoted 8 lines

Policy and state are matched based on their selectors (src/deet IP, direction ...), but they independent. The reqid is XFRM identification that this specific policy is connected to this specific state.
https://www.man7.org/linux/man-pages/man8/ip-xfrm.8.html
https://docs.kernel.org/networking/xfrm_device.html
ip x s add ....
reqid 0x07 ...
offload dev eth4 dir in

Can you elaborate this a bit more? Does that matching happen in hardware? The reqid is not a unique identifyer to match between policy and state. You MUST match the selectors as defined in
https://www.rfc-editor.org/rfc/rfc4301

#24 lore raw
Quoted 27 lines · Steffen Klassert
Quoted 17 lines · Leon Romanovsky
Quoted 16 lines · Jakub Kicinski
Quoted 8 lines · On Wed, 17 Aug 2022 08:22:02 +0300 Leon Romanovsky wrote:
Quoted 1 line · Jakub Kicinski

This is making a precedent for full tunnel offload in netdev, right?

Not really. SW IPsec supports two modes: tunnel and transport.

However HW and SW stack supports only offload of transport mode. This is the case for already merged IPsec crypto offload mode and the case for this full offload.

My point is on what you called "full offload" vs "crypto offload". The policy so far has always been that Linux networking stack should populate all the headers and instruct the device to do crypto, no header insertion. Obviously we do header insertion in switch/router offloads but that's different and stateless.

Quoted 8 lines
Quoted 3 lines

I believe the reasoning was to provide as much flexibility and control to the software as possible while retaining most of the performance gains.

I honestly don't know the reasoning, but "performance gains" are very limited as long as IPsec stack involved with various policy/state lookups. These lookups are expensive in terms of CPU and they can't hold 400 Gb/s line rate.

Quoted 5 lines

Can you provide some performance results that show the difference between crypto and full offload? In particular because on the TX path, the full policy and state offload is done twice (in software to find the offloading device and then in hardware to match policy to state).

I will prepare the numbers.

Quoted 16 lines
Quoted 9 lines

https://docs.nvidia.com/networking/display/connectx7en/Introduction#Introduction-ConnectX-7400GbEAdapterCards

Quoted 5 lines

You must provide a clear analysis (as in examination in data) and discussion (as in examination in writing) if you're intending to change the "let's keep packet formation in the SW" policy. What you got below is a good start but not sufficient.

I'm still a bit unease about this approach. I fear that doing parts of statefull IPsec procesing in software and parts in hardware will lead to all sort of problems. E.g. with this implementation the software has no stats, liftetime, lifebyte and packet count information but is responsible to do the IKE communication.

Quoted 3 lines

We might be able to sort out all problems during the upstraming process, but I still have no clear picture how this should work in the end with all corener cases this creates.

Like we discussed in IPsec coffee hour, there is no reliable way to synchronize SW and HW. This is why we offload both policy and state and skip stack completely.

Quoted 5 lines

Also the name full offload is a bit missleading, because the software still has to hold all offloaded states and policies. In a full offload, the stack would IMO just act as a stub layer between IKE and hardware.

It is just a name, I'm open to change it to any other name.

Quoted 16 lines
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines

Some of them:
1. Request to have reqid for policy and state. I use reqid for HW matching between policy and state.

reqid?

Quoted 8 lines

Policy and state are matched based on their selectors (src/deet IP, direction ...), but they independent. The reqid is XFRM identification that this specific policy is connected to this specific state.
https://www.man7.org/linux/man-pages/man8/ip-xfrm.8.html
https://docs.kernel.org/networking/xfrm_device.html
ip x s add ....
reqid 0x07 ...
offload dev eth4 dir in

Quoted 4 lines

Can you elaborate this a bit more? Does that matching happen in hardware? The reqid is not a unique identifyer to match between policy and state. You MUST match the selectors as defined in
https://www.rfc-editor.org/rfc/rfc4301

The reqid is needed for TX path and part of mlx5 flow steering logic.
https://lore.kernel.org/netdev/51ee028577396c051604703c46bd31d706b4b387.1660641154.git.leonro@nvidia.com/
I'm relying on it to make sure that both policy and state exist.

For everything else, I rely on selectors.

Thanks

Quoted 1 line
maintainer
#25 lore raw
In reply to Steffen Klassert
Quoted 11 lines · On Thu, 18 Aug 2022 12:10:31 +0200 Steffen Klassert wrote:
Quoted 4 lines
Quoted 4 lines

You must provide a clear analysis (as in examination in data) and discussion (as in examination in writing) if you're intending to change the "let's keep packet formation in the SW" policy. What you got below is a good start but not sufficient.

I'm still a bit unease about this approach. I fear that doing parts of statefull IPsec procesing in software and parts in hardware will lead to all sort of problems. E.g. with this implementation the software has no stats, liftetime, lifebyte and packet count information but is responsible to do the IKE communication.

Quoted 3 lines

We might be able to sort out all problems during the upstraming process, but I still have no clear picture how this should work in the end with all corener cases this creates.

Makes sense. I'm not sure any of the "deep and stateful offloads" we have can be considered a success so IMHO we can be selective in the approaches we accept.

Quoted 4 lines

Also the name full offload is a bit missleading, because the software still has to hold all offloaded states and policies. In a full offload, the stack would IMO just act as a stub layer between IKE and hardware.

maintainer
#26 lore raw
In reply to Leon Romanovsky
Quoted 7 lines · On Thu, 18 Aug 2022 08:24:13 +0300 Leon Romanovsky wrote:
Quoted 6 lines · Jakub Kicinski

My point is on what you called "full offload" vs "crypto offload". The policy so far has always been that Linux networking stack should populate all the headers and instruct the device to do crypto, no header insertion. Obviously we do header insertion in switch/router offloads but that's different and stateless.

Quoted 6 lines
Quoted 3 lines

I believe the reasoning was to provide as much flexibility and control to the software as possible while retaining most of the performance gains.

I honestly don't know the reasoning, but "performance gains" are very limited as long as IPsec stack involved with various policy/state

Herm. So you didn't bother figuring out what the current problems are but unsurprisingly the solution is "buy our product and let us do it"?

Quoted 5 lines

lookups. These lookups are expensive in terms of CPU and they can't hold 400 Gb/s line rate.

https://docs.nvidia.com/networking/display/connectx7en/Introduction#Introduction-ConnectX-7400GbEAdapterCards

Quoted 7 lines
Quoted 4 lines

You must provide a clear analysis (as in examination in data) and discussion (as in examination in writing) if you're intending to change the "let's keep packet formation in the SW" policy. What you got below is a good start but not sufficient.

Can you please point me to an example of such analysis, so I will know what is needed/expected?

I can't, as I said twice now, we don't have any "full crypto" offloads AFAIK.

Quoted 19 lines
Quoted 5 lines
Quoted 5 lines

IPsec full offload is actually improved version of IPsec crypto mode, In full mode, HW is responsible to trim/add headers in addition to decrypt/encrypt. In this mode, the packet arrives to the stack as already decrypted and vice versa for TX (exits to HW as not-encrypted).

Quoted 7 lines
Quoted 3 lines

My main motivation is to perform IPsec on RoCE traffic and in our preliminary results, we are able to do IPsec full offload in line rate. The same goes for ETH traffic.

If the motivation is RoCE I personally see no reason to provide the configuration of this functionality via netdev interfaces, but I'll obviously leave the final decision to Steffen.

This is not limited to RoCE, our customers use this offload for ethernet traffic as well.

RoCE is a good example of traffic that performs all headers magic in HW, without SW involved.

Quoted 7 lines

IPsec clearly belongs to netdev and we don't want to duplicate netdev functionality in RDMA. Like I said above, this feature is needed for regular ETH traffic as well.

Right now, RoCE and iWARP devices are based on netdev and long-standing agreement ( >20 years ????) that all netdev configurations are done there they belong - in netdev.

Let me be very clear - as far as I'm concerned no part of the RDMA stack belongs in netdev. What's there is there, but do not try to use that argument to justify more stuff.

If someone from the community thinks that I should have interest in working on / helping proprietary protocol stacks please let me know, because right now I have none.

#27 lore raw
Quoted 12 lines · Jakub Kicinski
Quoted 11 lines · On Thu, 18 Aug 2022 08:24:13 +0300 Leon Romanovsky wrote:
Quoted 9 lines · Jakub Kicinski

My point is on what you called "full offload" vs "crypto offload". The policy so far has always been that Linux networking stack should populate all the headers and instruct the device to do crypto, no header insertion. Obviously we do header insertion in switch/router offloads but that's different and stateless.

I believe the reasoning was to provide as much flexibility and control to the software as possible while retaining most of the performance gains.

Quoted 5 lines
Quoted 2 lines

I honestly don't know the reasoning, but "performance gains" are very limited as long as IPsec stack involved with various policy/state

Herm. So you didn't bother figuring out what the current problems are but unsurprisingly the solution is "buy our product and let us do it"?

Our hardware didn't support full offload back then and crypto mode was the one that was supported in our mlx5 FPGA offering. There are no "other" reasons from our side.

Quoted 11 lines
Quoted 11 lines

lookups. These lookups are expensive in terms of CPU and they can't hold 400 Gb/s line rate.

https://docs.nvidia.com/networking/display/connectx7en/Introduction#Introduction-ConnectX-7400GbEAdapterCards

Quoted 4 lines

You must provide a clear analysis (as in examination in data) and discussion (as in examination in writing) if you're intending to change the "let's keep packet formation in the SW" policy. What you got below is a good start but not sufficient.

Quoted 5 lines
Quoted 2 lines

Can you please point me to an example of such analysis, so I will know what is needed/expected?

I can't, as I said twice now, we don't have any "full crypto" offloads AFAIK.

No, I'm asking for an example of "clear analysis (as in examination in data)", as I don't understand this sentence. I'm not asking for "full crypto" examples.

This "discussion (as in examination in writing)" part is clear.

Quoted 28 lines
Quoted 20 lines
Quoted 6 lines
Quoted 6 lines

IPsec full offload is actually improved version of IPsec crypto mode, In full mode, HW is responsible to trim/add headers in addition to decrypt/encrypt. In this mode, the packet arrives to the stack as already decrypted and vice versa for TX (exits to HW as not-encrypted).

Quoted 7 lines
Quoted 3 lines

My main motivation is to perform IPsec on RoCE traffic and in our preliminary results, we are able to do IPsec full offload in line rate. The same goes for ETH traffic.

If the motivation is RoCE I personally see no reason to provide the configuration of this functionality via netdev interfaces, but I'll obviously leave the final decision to Steffen.

This is not limited to RoCE, our customers use this offload for ethernet traffic as well.

RoCE is a good example of traffic that performs all headers magic in HW, without SW involved.

Quoted 7 lines

IPsec clearly belongs to netdev and we don't want to duplicate netdev functionality in RDMA. Like I said above, this feature is needed for regular ETH traffic as well.

Right now, RoCE and iWARP devices are based on netdev and long-standing agreement ( >20 years ????) that all netdev configurations are done there they belong - in netdev.

Quoted 7 lines

Let me be very clear - as far as I'm concerned no part of the RDMA stack belongs in netdev. What's there is there, but do not try to use that argument to justify more stuff.

If someone from the community thinks that I should have interest in working on / helping proprietary protocol stacks please let me know, because right now I have none.

No one is asking from you to work on proprietary protocols.

RoCE is IBTA standard protocol and iWARP is IETF one. They both fully documented and backed by multiple vendors (Intel, IBM, Mellanox, Cavium ...).

There is also interoperability lab https://www.iol.unh.edu/ that runs various tests. In addition to distro interoperability labs testing.

I invite you to take a look on Jason's presentation "Challenges of the RDMA subsystem", which he gave 3 years ago, about RDMA and challenges with netdev.
https://lpc.events/event/4/contributions/364/

Thanks

maintainer
#28 lore raw
Quoted 9 lines · On Fri, 19 Aug 2022 08:52:26 +0300 Leon Romanovsky wrote:
Quoted 7 lines

Let me be very clear - as far as I'm concerned no part of the RDMA stack belongs in netdev. What's there is there, but do not try to use that argument to justify more stuff.

If someone from the community thinks that I should have interest in working on / helping proprietary protocol stacks please let me know, because right now I have none.

No one is asking from you to work on proprietary protocols.

That's not what I said. I don't know English grammar enough but you took the modifying (descriptive? genitive?) noun and treated it as the object.

I don't want to be in any way disrespectful to the technology you invest your time in. Or argue with any beliefs you have about it.

Quoted 11 lines

RoCE is IBTA standard protocol and iWARP is IETF one. They both fully documented and backed by multiple vendors (Intel, IBM, Mellanox, Cavium ...).

There is also interoperability lab https://www.iol.unh.edu/ that runs various tests. In addition to distro interoperability labs testing.

I invite you to take a look on Jason's presentation "Challenges of the RDMA subsystem", which he gave 3 years ago, about RDMA and challenges with netdev.
https://lpc.events/event/4/contributions/364/

I appreciate the invite, but it's not high enough on my list of interest to spend time on.

#29 lore raw
Quoted 7 lines · Jakub Kicinski
Quoted 4 lines

I invite you to take a look on Jason's presentation "Challenges of the RDMA subsystem", which he gave 3 years ago, about RDMA and challenges with netdev.
https://lpc.events/event/4/contributions/364/

I appreciate the invite, but it's not high enough on my list of interest to spend time on.

Regardless, RDMA doesn't really intersect with this netdev work for XFRM beyond the usual ways that RDMA IP traffic can be captured by or run parallel to netdev.

A significant use case here is for switchdev modes where the switch will subject traffic from a switch port to ESP, not unlike it already does with vlan, vxlan, etc and other already fully offloaded switching transforms.

Jason

maintainer
#30 lore raw
Quoted 8 lines · On Fri, 19 Aug 2022 13:01:22 -0300 Jason Gunthorpe wrote:

Regardless, RDMA doesn't really intersect with this netdev work for XFRM beyond the usual ways that RDMA IP traffic can be captured by or run parallel to netdev.

A significant use case here is for switchdev modes where the switch will subject traffic from a switch port to ESP, not unlike it already does with vlan, vxlan, etc and other already fully offloaded switching transforms.

Yup, that's what I thought you'd say. Can't argue with that use case if Steffen is satisfied with the technical aspects.

maintainer
#31 lore raw
Quoted 5 lines · Jakub Kicinski
Quoted 4 lines · On Fri, 19 Aug 2022 13:01:22 -0300 Jason Gunthorpe wrote:

Regardless, RDMA doesn't really intersect with this netdev work for XFRM beyond the usual ways that RDMA IP traffic can be captured by or run parallel to netdev.

Quoted 7 lines
Quoted 4 lines

A significant use case here is for switchdev modes where the switch will subject traffic from a switch port to ESP, not unlike it already does with vlan, vxlan, etc and other already fully offloaded switching transforms.

Yup, that's what I thought you'd say. Can't argue with that use case if Steffen is satisfied with the technical aspects.

Yes, everything that can help to overcome the performance problems can help and I'm interested in this type of offload. But we need to make sure the API is usable by the whole community, so I don't want an API for some special case one of the NIC vendors is interested in.

#32 lore raw
Quoted 11 lines · Steffen Klassert
Quoted 10 lines · Jakub Kicinski
Quoted 8 lines · On Fri, 19 Aug 2022 13:01:22 -0300 Jason Gunthorpe wrote:

Regardless, RDMA doesn't really intersect with this netdev work for XFRM beyond the usual ways that RDMA IP traffic can be captured by or run parallel to netdev.

A significant use case here is for switchdev modes where the switch will subject traffic from a switch port to ESP, not unlike it already does with vlan, vxlan, etc and other already fully offloaded switching transforms.

Quoted 8 lines
Quoted 2 lines

Yup, that's what I thought you'd say. Can't argue with that use case if Steffen is satisfied with the technical aspects.

Yes, everything that can help to overcome the performance problems can help and I'm interested in this type of offload. But we need to make sure the API is usable by the whole community, so I don't want an API for some special case one of the NIC vendors is interested in.

BTW, we have a performance data, I planned to send it as part of cover letter for v3, but it is worth to share it now.

================================================================================
Performance results:

TCP multi-stream, using iperf3 instance per-CPU.

 +----------------------+--------+--------+--------+--------+---------+---------+
 |                      | 1 CPU  | 2 CPUs | 4 CPUs | 8 CPUs | 16 CPUs | 32 CPUs |
 |                      +--------+--------+--------+--------+---------+---------+
 |                      |                   BW (Gbps)                           |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Baseline             | 27.9   | 59     | 93.1  | 92.8    | 93.7    | 94.4    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Software IPsec       | 6      | 11.9   | 23.3  | 45.9    | 83.8    | 91.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec crypto offload | 15     | 29.7   | 58.5  | 89.6    | 90.4    | 90.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec full offload   | 28     | 57     | 90.7  | 91      | 91.3    | 91.9    |
 +----------------------+--------+--------+-------+---------+---------+---------+

IPsec full offload mode behaves as baseline and reaches linerate with same amount of CPUs.

Setups details (similar for both sides):
* NIC: ConnectX6-DX dual port, 100 Gbps each. Single port used in the tests.
* CPU: Intel(R) Xeon(R) Platinum 8380 CPU @ 2.30GHz

Thanks

maintainer
#33 lore raw
Quoted 32 lines · On Mon, 22 Aug 2022 11:54:42 +0300 Leon Romanovsky wrote:
Quoted 9 lines · Steffen Klassert
Quoted 2 lines · Jakub Kicinski

Yup, that's what I thought you'd say. Can't argue with that use case if Steffen is satisfied with the technical aspects.

Yes, everything that can help to overcome the performance problems can help and I'm interested in this type of offload. But we need to make sure the API is usable by the whole community, so I don't want an API for some special case one of the NIC vendors is interested in.

BTW, we have a performance data, I planned to send it as part of cover letter for v3, but it is worth to share it now.

================================================================================
Performance results:

TCP multi-stream, using iperf3 instance per-CPU.

 +----------------------+--------+--------+--------+--------+---------+---------+
 |                      | 1 CPU  | 2 CPUs | 4 CPUs | 8 CPUs | 16 CPUs | 32 CPUs |
 |                      +--------+--------+--------+--------+---------+---------+
 |                      |                   BW (Gbps)                           |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Baseline             | 27.9   | 59     | 93.1  | 92.8    | 93.7    | 94.4    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Software IPsec       | 6      | 11.9   | 23.3  | 45.9    | 83.8    | 91.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec crypto offload | 15     | 29.7   | 58.5  | 89.6    | 90.4    | 90.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec full offload   | 28     | 57     | 90.7  | 91      | 91.3    | 91.9    |
 +----------------------+--------+--------+-------+---------+---------+---------+
Quoted 7 lines

IPsec full offload mode behaves as baseline and reaches linerate with same amount of CPUs.

Setups details (similar for both sides):
* NIC: ConnectX6-DX dual port, 100 Gbps each. Single port used in the tests.
* CPU: Intel(R) Xeon(R) Platinum 8380 CPU @ 2.30GHz

My questions about performance were more about where does the performance loss originate. Is it because of loss of GRO? Maybe sharing perf traces could answer some of those questions?

#34 lore raw
Quoted 33 lines · Jakub Kicinski
Quoted 32 lines · On Mon, 22 Aug 2022 11:54:42 +0300 Leon Romanovsky wrote:
Quoted 9 lines · Steffen Klassert
Quoted 2 lines · Jakub Kicinski

Yup, that's what I thought you'd say. Can't argue with that use case if Steffen is satisfied with the technical aspects.

Yes, everything that can help to overcome the performance problems can help and I'm interested in this type of offload. But we need to make sure the API is usable by the whole community, so I don't want an API for some special case one of the NIC vendors is interested in.

BTW, we have a performance data, I planned to send it as part of cover letter for v3, but it is worth to share it now.

================================================================================
Performance results:

TCP multi-stream, using iperf3 instance per-CPU.

 +----------------------+--------+--------+--------+--------+---------+---------+
 |                      | 1 CPU  | 2 CPUs | 4 CPUs | 8 CPUs | 16 CPUs | 32 CPUs |
 |                      +--------+--------+--------+--------+---------+---------+
 |                      |                   BW (Gbps)                           |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Baseline             | 27.9   | 59     | 93.1  | 92.8    | 93.7    | 94.4    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Software IPsec       | 6      | 11.9   | 23.3  | 45.9    | 83.8    | 91.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec crypto offload | 15     | 29.7   | 58.5  | 89.6    | 90.4    | 90.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec full offload   | 28     | 57     | 90.7  | 91      | 91.3    | 91.9    |
 +----------------------+--------+--------+-------+---------+---------+---------+
Quoted 3 lines
Quoted 3 lines

IPsec full offload mode behaves as baseline and reaches linerate with same amount of CPUs.

Just making sure: Baseline == "Clear text TCP" ?

Quoted 7 lines
Quoted 4 lines

Setups details (similar for both sides):
* NIC: ConnectX6-DX dual port, 100 Gbps each. Single port used in the tests.
* CPU: Intel(R) Xeon(R) Platinum 8380 CPU @ 2.30GHz

My questions about performance were more about where does the performance loss originate. Is it because of loss of GRO?

Performance loss between full and baseline ? it's hardly measurable .. less than 3% in the worst case.

Quoted 1 line

Maybe sharing perf traces could answer some of those questions?

maintainer
#35 lore raw
Quoted 5 lines · On Mon, 22 Aug 2022 14:27:16 -0700 Saeed Mahameed wrote:
Quoted 2 lines

My questions about performance were more about where does the performance loss originate. Is it because of loss of GRO?

Performance loss between full and baseline ? it's hardly measurable .. less than 3% in the worst case.

The loss for crypto only vs baseline is what I meant. Obviously if we offload everything the CPU perf may look great but we're giving up flexibility and ability to fix problems in SW.

maintainer
#36 lore raw
Quoted 10 lines · Jakub Kicinski
Quoted 5 lines · On Mon, 22 Aug 2022 14:27:16 -0700 Saeed Mahameed wrote:
Quoted 2 lines

My questions about performance were more about where does the performance loss originate. Is it because of loss of GRO?

Performance loss between full and baseline ? it's hardly measurable .. less than 3% in the worst case.

The loss for crypto only vs baseline is what I meant. Obviously if we offload everything the CPU perf may look great but we're giving up flexibility and ability to fix problems in SW.

The main difference between baseline TCP and crypto offload is the policy/state lookup and ESP encapsulation/decapsulation.

We don't loose GRO on crypto offload. The ESP header/trailer is stripped away in the GRO layer so that the inner TCP packet gets GRO. But we loose hardware LRO, as the ESP headers are not stripped in HW.

It would be really good to see where the bottlenecks are with crypto offload (RX or TX).

Also, it would be good to see why the full offload performs better. Some perf traces would be helpfull.

When I thought about possible offloads, I came to three different types:

1. encapsulation offload:
- Kernel does policy enforcement
- NIC does encapsulation
- NIC manages anti replay window and lifetime of SAs
- NIC sends lifetime and anti replay notifications to the kernel
- The Kernel talks to the keymanager

2. statefull offload with fallback:
- NIC handles the full datapath, but kernel can take over (fragments

     etc.)

- Kernel and NIC hold the full SA and policy database
- Kernel and NIC must sync the state (lifetime, replay window etc.) of SAs and policies
- The Kernel talks to the keymanager

3. statefull offload:
- NIC handles the full datapath
- NIC talks directly with the keymanager
- Kernel xfrm acts as a stub layer to pass messages from userspace to the NIC.

The offload that is implemented here comes option 2 closest. The statefull handling is shared between host and NIC. Unfortunalely, this is the most complicated one.

If just encapsulation/decapsulation brings the performance we could also go with option 1. That would be still a stateless offload.

Option 3 is what I would consider as a full offload. Kernel acts as a stateless stub layer, NIC does statefull IPsec.

#37 lore raw
Quoted 50 lines · Steffen Klassert
Quoted 10 lines · Jakub Kicinski
Quoted 5 lines · On Mon, 22 Aug 2022 14:27:16 -0700 Saeed Mahameed wrote:
Quoted 2 lines

My questions about performance were more about where does the performance loss originate. Is it because of loss of GRO?

Performance loss between full and baseline ? it's hardly measurable .. less than 3% in the worst case.

The loss for crypto only vs baseline is what I meant. Obviously if we offload everything the CPU perf may look great but we're giving up flexibility and ability to fix problems in SW.

The main difference between baseline TCP and crypto offload is the policy/state lookup and ESP encapsulation/decapsulation.

We don't loose GRO on crypto offload. The ESP header/trailer is stripped away in the GRO layer so that the inner TCP packet gets GRO. But we loose hardware LRO, as the ESP headers are not stripped in HW.

It would be really good to see where the bottlenecks are with crypto offload (RX or TX).

Also, it would be good to see why the full offload performs better. Some perf traces would be helpfull.

When I thought about possible offloads, I came to three different types:

1. encapsulation offload:
- Kernel does policy enforcement
- NIC does encapsulation
- NIC manages anti replay window and lifetime of SAs
- NIC sends lifetime and anti replay notifications to the kernel
- The Kernel talks to the keymanager

2. statefull offload with fallback:
- NIC handles the full datapath, but kernel can take over (fragments

     etc.)

- Kernel and NIC hold the full SA and policy database
- Kernel and NIC must sync the state (lifetime, replay window etc.) of SAs and policies
- The Kernel talks to the keymanager

3. statefull offload:
- NIC handles the full datapath
- NIC talks directly with the keymanager
- Kernel xfrm acts as a stub layer to pass messages from userspace to the NIC.

Quoted 3 lines

The offload that is implemented here comes option 2 closest. The statefull handling is shared between host and NIC. Unfortunalely, this is the most complicated one.

Our implementation something like option 2 but without fallback.

1. I didn't implement fallback for a number of reasons:
* It is almost impossible to keep in sync HW and SW states in linerate.
* IPv6 sets (require???) do-not-fragment bit.
2. NIC and kernel keep their SA and policy databases in sync to make sure that they both see coherent picture and for users to be able to use existing iproute2 tools.
3. Like any other offload, I want to make sure that kernel in the middle between our HW and user. This includes keymanager.

Quoted 4 lines

If just encapsulation/decapsulation brings the performance we could also go with option 1. That would be still a stateless offload.

Option 1 isn't sufficient for us as it doesn't support combination of TC and eswitch manager. In that mode, packets that arrive to uplink forwarded directly to representor without kernel involvement,

Quoted 4 lines

Option 3 is what I would consider as a full offload. Kernel acts as a stateless stub layer, NIC does statefull IPsec.

#38 lore raw
In reply to Saeed Mahameed
Quoted 34 lines · Saeed Mahameed
Quoted 33 lines · Jakub Kicinski
Quoted 32 lines · On Mon, 22 Aug 2022 11:54:42 +0300 Leon Romanovsky wrote:
Quoted 9 lines · Steffen Klassert
Quoted 2 lines · Jakub Kicinski

Yup, that's what I thought you'd say. Can't argue with that use case if Steffen is satisfied with the technical aspects.

Yes, everything that can help to overcome the performance problems can help and I'm interested in this type of offload. But we need to make sure the API is usable by the whole community, so I don't want an API for some special case one of the NIC vendors is interested in.

BTW, we have a performance data, I planned to send it as part of cover letter for v3, but it is worth to share it now.

================================================================================
Performance results:

TCP multi-stream, using iperf3 instance per-CPU.

 +----------------------+--------+--------+--------+--------+---------+---------+
 |                      | 1 CPU  | 2 CPUs | 4 CPUs | 8 CPUs | 16 CPUs | 32 CPUs |
 |                      +--------+--------+--------+--------+---------+---------+
 |                      |                   BW (Gbps)                           |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Baseline             | 27.9   | 59     | 93.1  | 92.8    | 93.7    | 94.4    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Software IPsec       | 6      | 11.9   | 23.3  | 45.9    | 83.8    | 91.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec crypto offload | 15     | 29.7   | 58.5  | 89.6    | 90.4    | 90.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec full offload   | 28     | 57     | 90.7  | 91      | 91.3    | 91.9    |
 +----------------------+--------+--------+-------+---------+---------+---------+
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines

IPsec full offload mode behaves as baseline and reaches linerate with same amount of CPUs.

Just making sure: Baseline == "Clear text TCP" ?

Yes, baseline is plain TCP without any encryption.

We can get higher numbers with Tariq's improvements, but it was not important to achieve maximum as we are interested to see differences between various modes.

Thanks

#39 lore raw
Quoted 39 lines · Leon Romanovsky
Quoted 38 lines · Saeed Mahameed
Quoted 36 lines · Jakub Kicinski
Quoted 35 lines · On Mon, 22 Aug 2022 11:54:42 +0300 Leon Romanovsky wrote:
Quoted 9 lines · Steffen Klassert
Quoted 2 lines · Jakub Kicinski

Yup, that's what I thought you'd say. Can't argue with that use case if Steffen is satisfied with the technical aspects.

Yes, everything that can help to overcome the performance problems can help and I'm interested in this type of offload. But we need to make sure the API is usable by the whole community, so I don't want an API for some special case one of the NIC vendors is interested in.

BTW, we have a performance data, I planned to send it as part of cover letter for v3, but it is worth to share it now.

================================================================================
Performance results:

TCP multi-stream, using iperf3 instance per-CPU.

 +----------------------+--------+--------+--------+--------+---------+---------+
 |                      | 1 CPU  | 2 CPUs | 4 CPUs | 8 CPUs | 16 CPUs | 32 CPUs |
 |                      +--------+--------+--------+--------+---------+---------+
 |                      |                   BW (Gbps)                           |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Baseline             | 27.9   | 59     | 93.1  | 92.8    | 93.7    | 94.4    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Software IPsec       | 6      | 11.9   | 23.3  | 45.9    | 83.8    | 91.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec crypto offload | 15     | 29.7   | 58.5  | 89.6    | 90.4    | 90.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec full offload   | 28     | 57     | 90.7  | 91      | 91.3    | 91.9    |
 +----------------------+--------+--------+-------+---------+---------+---------+

IPsec full offload mode behaves as baseline and reaches linerate with same amount of CPUs.

Quoted 7 lines
Quoted 1 line

Just making sure: Baseline == "Clear text TCP" ?

Yes, baseline is plain TCP without any encryption.

We can get higher numbers with Tariq's improvements, but it was not important to achieve maximum as we are interested to see differences between various modes.

BW is only part of the goal here, a significant metric is how much hypervisor CPU power is consumed by the ESP operation.

It is not any different than vlan or other encapsulating offloads where the ideal is to not interrupt the hypervisor CPU at all.

Jason

#40 lore raw
In reply to Jakub Kicinski
Quoted 36 lines · Jakub Kicinski
Quoted 35 lines · On Mon, 22 Aug 2022 11:54:42 +0300 Leon Romanovsky wrote:
Quoted 9 lines · Steffen Klassert
Quoted 2 lines · Jakub Kicinski

Yup, that's what I thought you'd say. Can't argue with that use case if Steffen is satisfied with the technical aspects.

Yes, everything that can help to overcome the performance problems can help and I'm interested in this type of offload. But we need to make sure the API is usable by the whole community, so I don't want an API for some special case one of the NIC vendors is interested in.

BTW, we have a performance data, I planned to send it as part of cover letter for v3, but it is worth to share it now.

================================================================================
Performance results:

TCP multi-stream, using iperf3 instance per-CPU.

 +----------------------+--------+--------+--------+--------+---------+---------+
 |                      | 1 CPU  | 2 CPUs | 4 CPUs | 8 CPUs | 16 CPUs | 32 CPUs |
 |                      +--------+--------+--------+--------+---------+---------+
 |                      |                   BW (Gbps)                           |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Baseline             | 27.9   | 59     | 93.1  | 92.8    | 93.7    | 94.4    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | Software IPsec       | 6      | 11.9   | 23.3  | 45.9    | 83.8    | 91.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec crypto offload | 15     | 29.7   | 58.5  | 89.6    | 90.4    | 90.8    |
 +----------------------+--------+--------+-------+---------+---------+---------+
 | IPsec full offload   | 28     | 57     | 90.7  | 91      | 91.3    | 91.9    |
 +----------------------+--------+--------+-------+---------+---------+---------+

IPsec full offload mode behaves as baseline and reaches linerate with same amount of CPUs.

Quoted 8 lines
Quoted 4 lines

Setups details (similar for both sides):
* NIC: ConnectX6-DX dual port, 100 Gbps each. Single port used in the tests.
* CPU: Intel(R) Xeon(R) Platinum 8380 CPU @ 2.30GHz

My questions about performance were more about where does the performance loss originate. Is it because of loss of GRO? Maybe sharing perf traces could answer some of those questions?

Crypto mode doesn't scale good in terms of CPUs.

CPU load data:
* Remind that this is 160 CPUs machine with 2 threads per-core

Baseline:
PROCESSES TOTAL_BW HOST_LOCAL_CPU HOST_REMOTE_CPU

1	   27.95     0.6	     1.1
2	   58.99     1	             2
4	   93.05     1.3	     3.2
8	   92.75     2	             3.4
16	   93.74     2.2	     4
32	   94.37     2.6	     4.5

IPsec crypto:
PROCESSES TOTAL_BW HOST_LOCAL_CPU HOST_REMOTE_CPU

1	   15.04	  0.7		  1.2
2	   29.68	  1.2		  2.1
4	   58.52	  2		  3.9
8	   89.58	  2.8		  5.1
16	   90.42	  3.1		  7.1
32	   90.81	  3.16		  6.9
maintainer
#41 lore raw
In reply to Leon Romanovsky

Hi Leon,

Quoted 13 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Changelog:
v2:
* Rebased to latest 6.0-rc1
* Add an extra check in TX datapath patch to validate packets before forwarding to HW.
* Added policy cleanup logic in case of netdev down event
v1: https://lore.kernel.org/all/[email protected]
* Moved comment to be before if (...) in third patch.
v0: https://lore.kernel.org/all/[email protected]
-----------------------------------------------------------------------

Quoted 5 lines

The following series extends XFRM core code to handle new type of IPsec offload - full offload.

In this mode, the HW is going to be responsible for whole data path, so both policy and state should be offloaded.

some general comments about the pachset:

As implemented, the software does not hold any state. I.e. there is no sync between hardware and software regarding stats, liftetime, lifebyte, packet counts and replay window. IKE rekeying and auditing is based on these, how should this be done?

I have not seen anything that catches configurations that stack multiple tunnels with the outer offloaded.

Where do we make sure that policy offloading device is the same as the state offloading device?

#42 lore raw
Quoted 22 lines · Steffen Klassert

Hi Leon,

Quoted 13 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Changelog:
v2:
* Rebased to latest 6.0-rc1
* Add an extra check in TX datapath patch to validate packets before forwarding to HW.
* Added policy cleanup logic in case of netdev down event
v1: https://lore.kernel.org/all/[email protected]
* Moved comment to be before if (...) in third patch.
v0: https://lore.kernel.org/all/[email protected]
-----------------------------------------------------------------------

Quoted 5 lines

The following series extends XFRM core code to handle new type of IPsec offload - full offload.

In this mode, the HW is going to be responsible for whole data path, so both policy and state should be offloaded.

Quoted 7 lines

some general comments about the pachset:

As implemented, the software does not hold any state. I.e. there is no sync between hardware and software regarding stats, liftetime, lifebyte, packet counts and replay window. IKE rekeying and auditing is based on these, how should this be done?

This is only rough idea as we only started to implement needed support in libreswan, but our plan is to configure IKE with highest possible priority

Quoted 6 lines

I have not seen anything that catches configurations that stack multiple tunnels with the outer offloaded.

Where do we make sure that policy offloading device is the same as the state offloading device?

It is configuration error and we don't check it. Should we?

Thanks

maintainer
#43 lore raw
Quoted 31 lines · Leon Romanovsky
Quoted 22 lines · Steffen Klassert

Hi Leon,

Quoted 13 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Changelog:
v2:
* Rebased to latest 6.0-rc1
* Add an extra check in TX datapath patch to validate packets before forwarding to HW.
* Added policy cleanup logic in case of netdev down event
v1: https://lore.kernel.org/all/[email protected]
* Moved comment to be before if (...) in third patch.
v0: https://lore.kernel.org/all/[email protected]
-----------------------------------------------------------------------

Quoted 5 lines

The following series extends XFRM core code to handle new type of IPsec offload - full offload.

In this mode, the HW is going to be responsible for whole data path, so both policy and state should be offloaded.

Quoted 7 lines

some general comments about the pachset:

As implemented, the software does not hold any state. I.e. there is no sync between hardware and software regarding stats, liftetime, lifebyte, packet counts and replay window. IKE rekeying and auditing is based on these, how should this be done?

Quoted 3 lines

This is only rough idea as we only started to implement needed support in libreswan, but our plan is to configure IKE with highest possible priority

If it is only a rough idea, then mark it as RFC. I want to see the whole picture before we merge it. And btw. tunnel mode belongs to the whoule picture too.

Quoted 9 lines
Quoted 7 lines

I have not seen anything that catches configurations that stack multiple tunnels with the outer offloaded.

Where do we make sure that policy offloading device is the same as the state offloading device?

It is configuration error and we don't check it. Should we?

We should at least make sure to not send out packets untransformed in this case.

#44 lore raw
Quoted 32 lines · Steffen Klassert
Quoted 31 lines · Leon Romanovsky
Quoted 29 lines · Steffen Klassert

Hi Leon,

Quoted 13 lines · Leon Romanovsky

From: Leon Romanovsky <[email protected]>

Changelog:
v2:
* Rebased to latest 6.0-rc1
* Add an extra check in TX datapath patch to validate packets before forwarding to HW.
* Added policy cleanup logic in case of netdev down event
v1: https://lore.kernel.org/all/[email protected]
* Moved comment to be before if (...) in third patch.
v0: https://lore.kernel.org/all/[email protected]
-----------------------------------------------------------------------

Quoted 5 lines

The following series extends XFRM core code to handle new type of IPsec offload - full offload.

In this mode, the HW is going to be responsible for whole data path, so both policy and state should be offloaded.

some general comments about the pachset:

As implemented, the software does not hold any state. I.e. there is no sync between hardware and software regarding stats, liftetime, lifebyte, packet counts and replay window. IKE rekeying and auditing is based on these, how should this be done?

Quoted 7 lines
Quoted 3 lines

This is only rough idea as we only started to implement needed support in libreswan, but our plan is to configure IKE with highest possible priority

If it is only a rough idea, then mark it as RFC. I want to see the whole picture before we merge it. And btw. tunnel mode belongs to the whoule picture too.

It is a rough in a sense that we don't have code to present yet. We did arch review of this IKE approach and it is how we are implementing it.

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

I have not seen anything that catches configurations that stack multiple tunnels with the outer offloaded.

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

Where do we make sure that policy offloading device is the same as the state offloading device?

It is configuration error and we don't check it. Should we?

We should at least make sure to not send out packets untransformed in this case.

In TX SW path, if state doesn't exist, the packets will be sent unencrypted. This "wrong" device configuration in offloaded path has same behavior as not having state at all.

Thanks