netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH ipsec-next 0/5] xfrm: support ipv6 nexthdrs process in transport and beet modes
@ 2020-04-01  8:59 Xin Long
  2020-04-01  8:59 ` [PATCH ipsec-next 1/5] xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input Xin Long
  2020-04-01  9:34 ` [PATCH ipsec-next 0/5] xfrm: support ipv6 nexthdrs process in transport and beet modes Steffen Klassert
  0 siblings, 2 replies; 7+ messages in thread
From: Xin Long @ 2020-04-01  8:59 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert, Herbert Xu, David S. Miller, Sabrina Dubroca

For esp transport and beet modes, when the inner ipv6 nexthdrs
are set, the 'proto' and 'transport_header' are needed to fix
in some places, so that the packet can be sent and received
properly, and no panicks are caused.

Note that the inner ipv6 nexthdrs problems don't affect tunnel
mode, as in which ESP nexthdr proto is always IP(6).

Xin Long (5):
  xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input
  xfrm: do pskb_pull properly in __xfrm_transport_prep
  esp6: get the right proto for transport mode in esp6_gso_encap
  esp6: support ipv6 nexthdrs process for beet gso segment
  esp4: support ipv6 nexthdrs process for beet gso segment

 net/ipv4/esp4_offload.c | 14 ++++++++++----
 net/ipv6/esp6_offload.c | 19 ++++++++++++++++---
 net/xfrm/xfrm_device.c  |  8 +++-----
 net/xfrm/xfrm_input.c   |  2 +-
 4 files changed, 30 insertions(+), 13 deletions(-)

-- 
2.1.0


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

* [PATCH ipsec-next 1/5] xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input
  2020-04-01  8:59 [PATCH ipsec-next 0/5] xfrm: support ipv6 nexthdrs process in transport and beet modes Xin Long
@ 2020-04-01  8:59 ` Xin Long
  2020-04-01  8:59   ` [PATCH ipsec-next 2/5] xfrm: do pskb_pull properly in __xfrm_transport_prep Xin Long
  2020-04-01  9:34 ` [PATCH ipsec-next 0/5] xfrm: support ipv6 nexthdrs process in transport and beet modes Steffen Klassert
  1 sibling, 1 reply; 7+ messages in thread
From: Xin Long @ 2020-04-01  8:59 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert, Herbert Xu, David S. Miller, Sabrina Dubroca

For beet mode, when it's ipv6 inner address with nexthdrs set,
the packet format might be:

    ----------------------------------------------------
    | outer  |     | dest |     |      |  ESP    | ESP |
    | IP hdr | ESP | opts.| TCP | Data | Trailer | ICV |
    ----------------------------------------------------

The nexthdr from ESP could be NEXTHDR_HOP(0), so it should
continue processing the packet when nexthdr returns 0 in
xfrm_input(). Otherwize, when ipv6 nexthdr is set, the
packet will be droppped.

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

diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index aa35f23..8a202c44 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -644,7 +644,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
 		dev_put(skb->dev);
 
 		spin_lock(&x->lock);
-		if (nexthdr <= 0) {
+		if (nexthdr < 0) {
 			if (nexthdr == -EBADMSG) {
 				xfrm_audit_state_icvfail(x, skb,
 							 x->type->proto);
-- 
2.1.0


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

* [PATCH ipsec-next 2/5] xfrm: do pskb_pull properly in __xfrm_transport_prep
  2020-04-01  8:59 ` [PATCH ipsec-next 1/5] xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input Xin Long
@ 2020-04-01  8:59   ` Xin Long
  2020-04-01  8:59     ` [PATCH ipsec-next 3/5] esp6: get the right proto for transport mode in esp6_gso_encap Xin Long
  0 siblings, 1 reply; 7+ messages in thread
From: Xin Long @ 2020-04-01  8:59 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert, Herbert Xu, David S. Miller, Sabrina Dubroca

For transport mode, when ipv6 nexthdr is set, the packet format might
be like:

    ----------------------------------------------------
    |        | dest |     |     |      |  ESP    | ESP |
    | IP6 hdr| opts.| ESP | TCP | Data | Trailer | ICV |
    ----------------------------------------------------

and in __xfrm_transport_prep():

  pskb_pull(skb, skb->mac_len + sizeof(ip6hdr) + x->props.header_len);

it will pull the data pointer to the wrong position, as it missed the
nexthdrs/dest opts.

This patch is to fix it by using:

  pskb_pull(skb, skb_transport_offset(skb) + x->props.header_len);

as we can be sure transport_header points to ESP header at that moment.

It also fixes a panic when packets with ipv6 nexthdr are sent over
esp6 transport mode:

  [  100.473845] kernel BUG at net/core/skbuff.c:4325!
  [  100.478517] RIP: 0010:__skb_to_sgvec+0x252/0x260
  [  100.494355] Call Trace:
  [  100.494829]  skb_to_sgvec+0x11/0x40
  [  100.495492]  esp6_output_tail+0x12e/0x550 [esp6]
  [  100.496358]  esp6_xmit+0x1d5/0x260 [esp6_offload]
  [  100.498029]  validate_xmit_xfrm+0x22f/0x2e0
  [  100.499604]  __dev_queue_xmit+0x589/0x910
  [  100.502928]  ip6_finish_output2+0x2a5/0x5a0
  [  100.503718]  ip6_output+0x6c/0x120
  [  100.505198]  xfrm_output_resume+0x4bf/0x530
  [  100.508683]  xfrm6_output+0x3a/0xc0
  [  100.513446]  inet6_csk_xmit+0xa1/0xf0
  [  100.517335]  tcp_sendmsg+0x27/0x40
  [  100.517977]  sock_sendmsg+0x3e/0x60
  [  100.518648]  __sys_sendto+0xee/0x160

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

diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index fa2a506..fbd2c21 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -25,12 +25,10 @@ static void __xfrm_transport_prep(struct xfrm_state *x, struct sk_buff *skb,
 	struct xfrm_offload *xo = xfrm_offload(skb);
 
 	skb_reset_mac_len(skb);
-	pskb_pull(skb, skb->mac_len + hsize + x->props.header_len);
-
-	if (xo->flags & XFRM_GSO_SEGMENT) {
-		skb_reset_transport_header(skb);
+	if (xo->flags & XFRM_GSO_SEGMENT)
 		skb->transport_header -= x->props.header_len;
-	}
+
+	pskb_pull(skb, skb_transport_offset(skb) + x->props.header_len);
 }
 
 static void __xfrm_mode_tunnel_prep(struct xfrm_state *x, struct sk_buff *skb,
-- 
2.1.0


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

* [PATCH ipsec-next 3/5] esp6: get the right proto for transport mode in esp6_gso_encap
  2020-04-01  8:59   ` [PATCH ipsec-next 2/5] xfrm: do pskb_pull properly in __xfrm_transport_prep Xin Long
@ 2020-04-01  8:59     ` Xin Long
  2020-04-01  8:59       ` [PATCH ipsec-next 4/5] esp6: support ipv6 nexthdrs process for beet gso segment Xin Long
  0 siblings, 1 reply; 7+ messages in thread
From: Xin Long @ 2020-04-01  8:59 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert, Herbert Xu, David S. Miller, Sabrina Dubroca

For transport mode, when ipv6 nexthdr is set, the packet format might
be like:

    ----------------------------------------------------
    |        | dest |     |     |      |  ESP    | ESP |
    | IP6 hdr| opts.| ESP | TCP | Data | Trailer | ICV |
    ----------------------------------------------------

What it wants to get for x-proto in esp6_gso_encap() is the proto that
will be set in ESP nexthdr. So it should skip all ipv6 nexthdrs and
get the real transport protocol. Othersize, the wrong proto number
will be set into ESP nexthdr.

This patch is to skip all ipv6 nexthdrs by calling ipv6_skip_exthdr()
in esp6_gso_encap().

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

diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
index 8eab2c8..b828508 100644
--- a/net/ipv6/esp6_offload.c
+++ b/net/ipv6/esp6_offload.c
@@ -123,9 +123,16 @@ static void esp6_gso_encap(struct xfrm_state *x, struct sk_buff *skb)
 	struct ip_esp_hdr *esph;
 	struct ipv6hdr *iph = ipv6_hdr(skb);
 	struct xfrm_offload *xo = xfrm_offload(skb);
-	int proto = iph->nexthdr;
+	u8 proto = iph->nexthdr;
 
 	skb_push(skb, -skb_network_offset(skb));
+
+	if (x->outer_mode.encap == XFRM_MODE_TRANSPORT) {
+		__be16 frag;
+
+		ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &proto, &frag);
+	}
+
 	esph = ip_esp_hdr(skb);
 	*skb_mac_header(skb) = IPPROTO_ESP;
 
-- 
2.1.0


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

* [PATCH ipsec-next 4/5] esp6: support ipv6 nexthdrs process for beet gso segment
  2020-04-01  8:59     ` [PATCH ipsec-next 3/5] esp6: get the right proto for transport mode in esp6_gso_encap Xin Long
@ 2020-04-01  8:59       ` Xin Long
  2020-04-01  8:59         ` [PATCH ipsec-next 5/5] esp4: " Xin Long
  0 siblings, 1 reply; 7+ messages in thread
From: Xin Long @ 2020-04-01  8:59 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert, Herbert Xu, David S. Miller, Sabrina Dubroca

For beet mode, when it's ipv6 inner address with nexthdrs set,
the packet format might be:

    ----------------------------------------------------
    | outer  |     | dest |     |      |  ESP    | ESP |
    | IP6 hdr| ESP | opts.| TCP | Data | Trailer | ICV |
    ----------------------------------------------------

Before doing gso segment in xfrm6_beet_gso_segment(), it should
skip all nexthdrs and get the real transport proto, and set
transport_header properly.

This patch is to fix it by simply calling ipv6_skip_exthdr()
in xfrm6_beet_gso_segment().

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

diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c
index b828508..021f58c 100644
--- a/net/ipv6/esp6_offload.c
+++ b/net/ipv6/esp6_offload.c
@@ -173,7 +173,7 @@ static struct sk_buff *xfrm6_beet_gso_segment(struct xfrm_state *x,
 	struct xfrm_offload *xo = xfrm_offload(skb);
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
 	const struct net_offload *ops;
-	int proto = xo->proto;
+	u8 proto = xo->proto;
 
 	skb->transport_header += x->props.header_len;
 
@@ -184,7 +184,13 @@ static struct sk_buff *xfrm6_beet_gso_segment(struct xfrm_state *x,
 		proto = ph->nexthdr;
 	}
 
-	if (x->sel.family != AF_INET6) {
+	if (x->sel.family == AF_INET6) {
+		int offset = skb_transport_offset(skb);
+		__be16 frag;
+
+		offset = ipv6_skip_exthdr(skb, offset, &proto, &frag);
+		skb->transport_header += offset;
+	} else {
 		skb->transport_header -=
 			(sizeof(struct ipv6hdr) - sizeof(struct iphdr));
 
-- 
2.1.0


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

* [PATCH ipsec-next 5/5] esp4: support ipv6 nexthdrs process for beet gso segment
  2020-04-01  8:59       ` [PATCH ipsec-next 4/5] esp6: support ipv6 nexthdrs process for beet gso segment Xin Long
@ 2020-04-01  8:59         ` Xin Long
  0 siblings, 0 replies; 7+ messages in thread
From: Xin Long @ 2020-04-01  8:59 UTC (permalink / raw)
  To: netdev; +Cc: Steffen Klassert, Herbert Xu, David S. Miller, Sabrina Dubroca

For beet mode, when it's ipv6 inner address with nexthdrs set,
the packet format might be:

    ----------------------------------------------------
    | outer  |     | dest |     |      |  ESP    | ESP |
    | IP hdr | ESP | opts.| TCP | Data | Trailer | ICV |
    ----------------------------------------------------

Before doing gso segment in xfrm4_beet_gso_segment(), the same
thing is needed as it does in xfrm6_beet_gso_segment() in last
patch 'esp6: support ipv6 nexthdrs process for beet gso segment'.

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

diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c
index 731022c..9dde4e3 100644
--- a/net/ipv4/esp4_offload.c
+++ b/net/ipv4/esp4_offload.c
@@ -139,7 +139,7 @@ static struct sk_buff *xfrm4_beet_gso_segment(struct xfrm_state *x,
 	struct xfrm_offload *xo = xfrm_offload(skb);
 	struct sk_buff *segs = ERR_PTR(-EINVAL);
 	const struct net_offload *ops;
-	int proto = xo->proto;
+	u8 proto = xo->proto;
 
 	skb->transport_header += x->props.header_len;
 
@@ -148,10 +148,16 @@ static struct sk_buff *xfrm4_beet_gso_segment(struct xfrm_state *x,
 
 		skb->transport_header += ph->hdrlen * 8;
 		proto = ph->nexthdr;
-	} else if (x->sel.family != AF_INET6) {
+	} else if (x->sel.family == AF_INET6) {
+		int offset = skb_transport_offset(skb);
+		__be16 frag;
+
+		offset = ipv6_skip_exthdr(skb, offset, &proto, &frag);
+		skb->transport_header += offset;
+		if (proto == IPPROTO_TCP)
+			skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4;
+	} else {
 		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));
-- 
2.1.0


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

* Re: [PATCH ipsec-next 0/5] xfrm: support ipv6 nexthdrs process in transport and beet modes
  2020-04-01  8:59 [PATCH ipsec-next 0/5] xfrm: support ipv6 nexthdrs process in transport and beet modes Xin Long
  2020-04-01  8:59 ` [PATCH ipsec-next 1/5] xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input Xin Long
@ 2020-04-01  9:34 ` Steffen Klassert
  1 sibling, 0 replies; 7+ messages in thread
From: Steffen Klassert @ 2020-04-01  9:34 UTC (permalink / raw)
  To: Xin Long; +Cc: netdev, Herbert Xu, David S. Miller, Sabrina Dubroca

On Wed, Apr 01, 2020 at 04:59:20PM +0800, Xin Long wrote:
> For esp transport and beet modes, when the inner ipv6 nexthdrs
> are set, the 'proto' and 'transport_header' are needed to fix
> in some places, so that the packet can be sent and received
> properly, and no panicks are caused.

Please separate the fixes and send them for inclusion
into the ipsec tree. Everything else has to wait until
after the merge window. net-next is closed and so is
ipsec-next.

Thanks!


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

end of thread, other threads:[~2020-04-01  9:34 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-01  8:59 [PATCH ipsec-next 0/5] xfrm: support ipv6 nexthdrs process in transport and beet modes Xin Long
2020-04-01  8:59 ` [PATCH ipsec-next 1/5] xfrm: allow to accept packets with ipv6 NEXTHDR_HOP in xfrm_input Xin Long
2020-04-01  8:59   ` [PATCH ipsec-next 2/5] xfrm: do pskb_pull properly in __xfrm_transport_prep Xin Long
2020-04-01  8:59     ` [PATCH ipsec-next 3/5] esp6: get the right proto for transport mode in esp6_gso_encap Xin Long
2020-04-01  8:59       ` [PATCH ipsec-next 4/5] esp6: support ipv6 nexthdrs process for beet gso segment Xin Long
2020-04-01  8:59         ` [PATCH ipsec-next 5/5] esp4: " Xin Long
2020-04-01  9:34 ` [PATCH ipsec-next 0/5] xfrm: support ipv6 nexthdrs process in transport and beet modes Steffen Klassert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).