netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jiri Bohac <jbohac@suse.cz>
To: Steffen Klassert <steffen.klassert@secunet.com>,
	Herbert Xu <herbert@gondor.apana.org.au>,
	"David S. Miller" <davem@davemloft.net>
Cc: netdev@vger.kernel.org
Subject: xfrm: UFO + ESP = double fragmentation
Date: Sat, 30 Jan 2016 00:44:24 +0100	[thread overview]
Message-ID: <20160129234424.GC7907@midget.suse.cz> (raw)

Hi,

I'm seeing wrong fragmentation on locally generated UDPv6 packets
going out over ESP (transport mode):

UFO is turned on on the outgoing interface and MTU is 1500.
When 8 kB is written to a UDP socket, udpv6_sendmsg() calls
ip_append_data() which generates a single 8 kB GSO skb.

Through ip6_send_skb() it reaches xfrm_output(). Since
skb_is_gso(skb) is nonzero, xfrm_output_gso() is called.
It immediatelly segments the skb via skb_gso_segment() and then
calls xfrm_output2() on each individual segment.

This is wrong. RFC4303 says:
	3.3.4.  Fragmentation
	   If necessary, fragmentation is performed after ESP
	   processing within an IPsec implementation.  Thus,
	   transport mode ESP is applied only to whole IP
	   datagrams (not to IP fragments).

Instead, xfrm_output_gso() applies the transform to each segment.
Since both the fragmentation header _and_ the ESP headers now
don't fit in the MTU and the ESP-encapsulated segments
are fragmented for a second time in ip6_finish_output().

The outcome is:
- the original 8k UDP packet is split into 6 ESP fragments
- the first 5 ESP fragments are 1508 bytes each, thus fragmented
  again into two fragments 

The destination host replies with ICMP parameter problem.

How is this supposed to work?
This hack fixes this specific case:

--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -198,7 +198,7 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
 	int err;
 
 	if (skb_is_gso(skb))
-		return xfrm_output_gso(net, sk, skb);
+		return xfrm_output2(net, sk, skb);
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		err = skb_checksum_help(skb);


Is there a situation when xfrm_output_gso() does the right thing?

Thanks,

-- 
Jiri Bohac <jbohac@suse.cz>
SUSE Labs, SUSE CZ

             reply	other threads:[~2016-01-29 23:44 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-29 23:44 Jiri Bohac [this message]
2016-01-30  4:21 ` xfrm: UFO + ESP = double fragmentation Herbert Xu
2016-03-16 16:00   ` [PATCH] xfrm: don't segment UFO packets Jiri Bohac
2016-03-17  5:03     ` Herbert Xu
2016-03-17  9:41       ` Jiri Bohac
2016-03-17 10:24         ` Steffen Klassert
2016-03-17 10:49           ` Jiri Bohac
2016-03-17 11:01             ` Steffen Klassert
2016-03-17 17:08           ` Jiri Bohac
2016-03-18  2:36             ` Herbert Xu
2016-03-18  8:05               ` Steffen Klassert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160129234424.GC7907@midget.suse.cz \
    --to=jbohac@suse.cz \
    --cc=davem@davemloft.net \
    --cc=herbert@gondor.apana.org.au \
    --cc=netdev@vger.kernel.org \
    --cc=steffen.klassert@secunet.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).