All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH ipsec-next 0/3] xfrm: add offload support for esp beet mode
@ 2020-03-26  9:02 Xin Long
  2020-03-26  9:02 ` [PATCH ipsec-next 1/3] esp4: add gso_segment for esp4 " Xin Long
  2020-03-27  7:51 ` [PATCH ipsec-next 0/3] xfrm: add offload support for esp beet mode Steffen Klassert
  0 siblings, 2 replies; 5+ messages in thread
From: Xin Long @ 2020-03-26  9:02 UTC (permalink / raw)
  To: netdev
  Cc: Steffen Klassert, Herbert Xu, David S. Miller, Florian Westphal,
	Sabrina Dubroca

This patchset is to add gso_segment functions for esp4 and esp6
beet mode, and prep function for both, and tested with 6 cases:

  1. IPv4 INNER ADDRESSES
     - OUTER v4 ADDRESSES
     - OUTER v6 ADDRESSES

  2. IPv4 INNER ADDRESSES with options
     - OUTER v4 ADDRESSES
     - OUTER v6 ADDRESSES

  3. IPv6 INNER ADDRESSES
     - OUTER v4 ADDRESSES
     - OUTER v6 ADDRESSES

With this patchset, an esp beet mode skb would be segmented and
encryped until it arrives in dev_queue_xmit()/validate_xmit_skb().

Xin Long (3):
  esp4: add gso_segment for esp4 beet mode
  esp6: add gso_segment for esp6 beet mode
  xfrm: add prep for esp beet mode offload

 net/ipv4/esp4_offload.c | 32 ++++++++++++++++++++++++++++++++
 net/ipv6/esp6_offload.c | 36 ++++++++++++++++++++++++++++++++++++
 net/xfrm/xfrm_device.c  | 28 +++++++++++++++++++++++++++-
 3 files changed, 95 insertions(+), 1 deletion(-)

-- 
2.1.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH ipsec-next 1/3] esp4: add gso_segment for esp4 beet mode
  2020-03-26  9:02 [PATCH ipsec-next 0/3] xfrm: add offload support for esp beet mode Xin Long
@ 2020-03-26  9:02 ` Xin Long
  2020-03-26  9:02   ` [PATCH ipsec-next 2/3] esp6: add gso_segment for esp6 " Xin Long
  2020-03-27  7:51 ` [PATCH ipsec-next 0/3] xfrm: add offload support for esp beet mode Steffen Klassert
  1 sibling, 1 reply; 5+ messages in thread
From: Xin Long @ 2020-03-26  9:02 UTC (permalink / raw)
  To: netdev
  Cc: Steffen Klassert, Herbert Xu, David S. Miller, Florian Westphal,
	Sabrina Dubroca

Similar to xfrm4_tunnel/transport_gso_segment(), _gso_segment()
is added to do gso_segment for esp4 beet mode. Before calling
inet_offloads[proto]->callbacks.gso_segment, it needs to do:

  - Get the upper proto from ph header to get its gso_segment
    when xo->proto is IPPROTO_BEETPH.

  - Add SKB_GSO_TCPV4 to gso_type if x->sel.family == AF_INET6
    and the proto == IPPROTO_TCP, so that the current tcp ipv4
    packet can be segmented.

  - Calculate a right value for skb->transport_header and move
    skb->data to the transport header position.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/ipv4/esp4_offload.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
index e2e219c..731022c 100644
--- a/net/ipv4/esp4_offload.c
+++ b/net/ipv4/esp4_offload.c
@@ -132,6 +132,36 @@ static struct sk_buff *xfrm4_transport_gso_segment(struct xfrm_state *x,
 	return segs;
 }
 
+static struct sk_buff *xfrm4_beet_gso_segment(struct xfrm_state *x,
+					      struct sk_buff *skb,
+					      netdev_features_t features)
+{
+	struct xfrm_offload *xo = xfrm_offload(skb);
+	struct sk_buff *segs = ERR_PTR(-EINVAL);
+	const struct net_offload *ops;
+	int proto = xo->proto;
+
+	skb->transport_header += x->props.header_len;
+
+	if (proto == IPPROTO_BEETPH) {
+		struct ip_beet_phdr *ph = (struct ip_beet_phdr *)skb->data;
+
+		skb->transport_header += ph->hdrlen * 8;
+		proto = ph->nexthdr;
+	} else if (x->sel.family != AF_INET6) {
+		skb->transport_header -= IPV4_BEET_PHMAXLEN;
+	} else if (proto == IPPROTO_TCP) {
+		skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
+	}
+
+	__skb_pull(skb, skb_transport_offset(skb));
+	ops = rcu_dereference(inet_offloads[proto]);
+	if (likely(ops && ops->callbacks.gso_segment))
+		segs = ops->callbacks.gso_segment(skb, features);
+
+	return segs;
+}
+
 static struct sk_buff *xfrm4_outer_mode_gso_segment(struct xfrm_state *x,
 						    struct sk_buff *skb,
 						    netdev_features_t features)
@@ -141,6 +171,8 @@ static struct sk_buff *xfrm4_outer_mode_gso_segment(struct xfrm_state *x,
 		return xfrm4_tunnel_gso_segment(x, skb, features);
 	case XFRM_MODE_TRANSPORT:
 		return xfrm4_transport_gso_segment(x, skb, features);
+	case XFRM_MODE_BEET:
+		return xfrm4_beet_gso_segment(x, skb, features);
 	}
 
 	return ERR_PTR(-EOPNOTSUPP);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH ipsec-next 2/3] esp6: add gso_segment for esp6 beet mode
  2020-03-26  9:02 ` [PATCH ipsec-next 1/3] esp4: add gso_segment for esp4 " Xin Long
@ 2020-03-26  9:02   ` Xin Long
  2020-03-26  9:02     ` [PATCH ipsec-next 3/3] xfrm: add prep for esp beet mode offload Xin Long
  0 siblings, 1 reply; 5+ messages in thread
From: Xin Long @ 2020-03-26  9:02 UTC (permalink / raw)
  To: netdev
  Cc: Steffen Klassert, Herbert Xu, David S. Miller, Florian Westphal,
	Sabrina Dubroca

Similar to xfrm6_tunnel/transport_gso_segment(), _gso_segment()
is added to do gso_segment for esp6 beet mode. Before calling
inet6_offloads[proto]->callbacks.gso_segment, it needs to do:

  - Get the upper proto from ph header to get its gso_segment
    when xo->proto is IPPROTO_BEETPH.

  - Add SKB_GSO_TCPV6 to gso_type if x->sel.family != AF_INET6
    and the proto == IPPROTO_TCP, so that the current tcp ipv6
    packet can be segmented.

  - Calculate a right value for skb->transport_header and move
    skb->data to the transport header position.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/ipv6/esp6_offload.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
index fd53505..8eab2c8 100644
--- a/net/ipv6/esp6_offload.c
+++ b/net/ipv6/esp6_offload.c
@@ -159,6 +159,40 @@ static struct sk_buff *xfrm6_transport_gso_segment(struct xfrm_state *x,
 	return segs;
 }
 
+static struct sk_buff *xfrm6_beet_gso_segment(struct xfrm_state *x,
+					      struct sk_buff *skb,
+					      netdev_features_t features)
+{
+	struct xfrm_offload *xo = xfrm_offload(skb);
+	struct sk_buff *segs = ERR_PTR(-EINVAL);
+	const struct net_offload *ops;
+	int proto = xo->proto;
+
+	skb->transport_header += x->props.header_len;
+
+	if (proto == IPPROTO_BEETPH) {
+		struct ip_beet_phdr *ph = (struct ip_beet_phdr *)skb->data;
+
+		skb->transport_header += ph->hdrlen * 8;
+		proto = ph->nexthdr;
+	}
+
+	if (x->sel.family != AF_INET6) {
+		skb->transport_header -=
+			(sizeof(struct ipv6hdr) - sizeof(struct iphdr));
+
+		if (proto == IPPROTO_TCP)
+			skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6;
+	}
+
+	__skb_pull(skb, skb_transport_offset(skb));
+	ops = rcu_dereference(inet6_offloads[proto]);
+	if (likely(ops && ops->callbacks.gso_segment))
+		segs = ops->callbacks.gso_segment(skb, features);
+
+	return segs;
+}
+
 static struct sk_buff *xfrm6_outer_mode_gso_segment(struct xfrm_state *x,
 						    struct sk_buff *skb,
 						    netdev_features_t features)
@@ -168,6 +202,8 @@ static struct sk_buff *xfrm6_outer_mode_gso_segment(struct xfrm_state *x,
 		return xfrm6_tunnel_gso_segment(x, skb, features);
 	case XFRM_MODE_TRANSPORT:
 		return xfrm6_transport_gso_segment(x, skb, features);
+	case XFRM_MODE_BEET:
+		return xfrm6_beet_gso_segment(x, skb, features);
 	}
 
 	return ERR_PTR(-EOPNOTSUPP);
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH ipsec-next 3/3] xfrm: add prep for esp beet mode offload
  2020-03-26  9:02   ` [PATCH ipsec-next 2/3] esp6: add gso_segment for esp6 " Xin Long
@ 2020-03-26  9:02     ` Xin Long
  0 siblings, 0 replies; 5+ messages in thread
From: Xin Long @ 2020-03-26  9:02 UTC (permalink / raw)
  To: netdev
  Cc: Steffen Klassert, Herbert Xu, David S. Miller, Florian Westphal,
	Sabrina Dubroca

Like __xfrm_transport/mode_tunnel_prep(), this patch is to add
__xfrm_mode_beet_prep() to fix the transport_header for gso
segments, and reset skb mac_len, and pull skb data to the
proto inside esp.

This patch also fixes a panic, reported by ltp:

  # modprobe esp4_offload
  # runltp -f net_stress.ipsec_tcp

  [ 2452.780511] kernel BUG at net/core/skbuff.c:109!
  [ 2452.799851] Call Trace:
  [ 2452.800298]  <IRQ>
  [ 2452.800705]  skb_push.cold.98+0x14/0x20
  [ 2452.801396]  esp_xmit+0x17b/0x270 [esp4_offload]
  [ 2452.802799]  validate_xmit_xfrm+0x22f/0x2e0
  [ 2452.804285]  __dev_queue_xmit+0x589/0x910
  [ 2452.806264]  __neigh_update+0x3d7/0xa50
  [ 2452.806958]  arp_process+0x259/0x810
  [ 2452.807589]  arp_rcv+0x18a/0x1c

It was caused by the skb going to esp_xmit with a wrong transport
header.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/xfrm/xfrm_device.c | 28 +++++++++++++++++++++++++++-
 1 file changed, 27 insertions(+), 1 deletion(-)

diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 50f567a..fa2a506 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -46,6 +46,25 @@ static void __xfrm_mode_tunnel_prep(struct xfrm_state *x, struct sk_buff *skb,
 	pskb_pull(skb, skb->mac_len + x->props.header_len);
 }
 
+static void __xfrm_mode_beet_prep(struct xfrm_state *x, struct sk_buff *skb,
+				  unsigned int hsize)
+{
+	struct xfrm_offload *xo = xfrm_offload(skb);
+	int phlen = 0;
+
+	if (xo->flags & XFRM_GSO_SEGMENT)
+		skb->transport_header = skb->network_header + hsize;
+
+	skb_reset_mac_len(skb);
+	if (x->sel.family != AF_INET6) {
+		phlen = IPV4_BEET_PHMAXLEN;
+		if (x->outer_mode.family == AF_INET6)
+			phlen += sizeof(struct ipv6hdr) - sizeof(struct iphdr);
+	}
+
+	pskb_pull(skb, skb->mac_len + hsize + (x->props.header_len - phlen));
+}
+
 /* Adjust pointers into the packet when IPsec is done at layer2 */
 static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb)
 {
@@ -66,9 +85,16 @@ static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb)
 			return __xfrm_transport_prep(x, skb,
 						     sizeof(struct ipv6hdr));
 		break;
+	case XFRM_MODE_BEET:
+		if (x->outer_mode.family == AF_INET)
+			return __xfrm_mode_beet_prep(x, skb,
+						     sizeof(struct iphdr));
+		if (x->outer_mode.family == AF_INET6)
+			return __xfrm_mode_beet_prep(x, skb,
+						     sizeof(struct ipv6hdr));
+		break;
 	case XFRM_MODE_ROUTEOPTIMIZATION:
 	case XFRM_MODE_IN_TRIGGER:
-	case XFRM_MODE_BEET:
 		break;
 	}
 }
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH ipsec-next 0/3] xfrm: add offload support for esp beet mode
  2020-03-26  9:02 [PATCH ipsec-next 0/3] xfrm: add offload support for esp beet mode Xin Long
  2020-03-26  9:02 ` [PATCH ipsec-next 1/3] esp4: add gso_segment for esp4 " Xin Long
@ 2020-03-27  7:51 ` Steffen Klassert
  1 sibling, 0 replies; 5+ messages in thread
From: Steffen Klassert @ 2020-03-27  7:51 UTC (permalink / raw)
  To: Xin Long
  Cc: netdev, Herbert Xu, David S. Miller, Florian Westphal, Sabrina Dubroca

On Thu, Mar 26, 2020 at 05:02:28PM +0800, Xin Long wrote:
> This patchset is to add gso_segment functions for esp4 and esp6
> beet mode, and prep function for both, and tested with 6 cases:
> 
>   1. IPv4 INNER ADDRESSES
>      - OUTER v4 ADDRESSES
>      - OUTER v6 ADDRESSES
> 
>   2. IPv4 INNER ADDRESSES with options
>      - OUTER v4 ADDRESSES
>      - OUTER v6 ADDRESSES
> 
>   3. IPv6 INNER ADDRESSES
>      - OUTER v4 ADDRESSES
>      - OUTER v6 ADDRESSES
> 
> With this patchset, an esp beet mode skb would be segmented and
> encryped until it arrives in dev_queue_xmit()/validate_xmit_skb().
> 
> Xin Long (3):
>   esp4: add gso_segment for esp4 beet mode
>   esp6: add gso_segment for esp6 beet mode
>   xfrm: add prep for esp beet mode offload

Series applied to ipsec-next, thanks a lot Xin!

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-03-27  7:51 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-26  9:02 [PATCH ipsec-next 0/3] xfrm: add offload support for esp beet mode Xin Long
2020-03-26  9:02 ` [PATCH ipsec-next 1/3] esp4: add gso_segment for esp4 " Xin Long
2020-03-26  9:02   ` [PATCH ipsec-next 2/3] esp6: add gso_segment for esp6 " Xin Long
2020-03-26  9:02     ` [PATCH ipsec-next 3/3] xfrm: add prep for esp beet mode offload Xin Long
2020-03-27  7:51 ` [PATCH ipsec-next 0/3] xfrm: add offload support for esp beet mode Steffen Klassert

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.