netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 -next] ipv6: don't increase size when refragmenting forwarded ipv6 skbs
@ 2015-05-21 22:44 Florian Westphal
  2015-05-25 21:22 ` David Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Florian Westphal @ 2015-05-21 22:44 UTC (permalink / raw)
  To: netdev; +Cc: Florian Westphal

since commit 6aafeef03b9d ("netfilter: push reasm skb through instead of
original frag skbs") we will end up sometimes re-fragmenting skbs
that we've reassembled.

ipv6 defrag preserves the original skbs using the skb frag list, i.e. as long
as the skb frag list is preserved there is no problem since we keep
original geometry of fragments intact.

However, in the rare case where the frag list is munged or skb
is linearized, we might send larger fragments than what we originally
received.

A router in the path might then send packet-too-big errors even if
sender never sent fragments exceeding the reported mtu:

mtu 1500 - 1500:1400 - 1400:1280 - 1280
     A         R1         R2        B

1 - A sends to B, fragment size 1400
2 - R2 sends pkttoobig error for 1280
3 - A sends to B, fragment size 1280
4 - R2 sends pkttoobig error for 1280 again because it sees fragments of size 1400.

make sure ip6_fragment always caps MTU at largest packet size seen
when defragmented skb is forwarded.

Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
---
 changes since v2:
 update commit message: no problem unless skb frag list is munged/destroyed.
 move patch out of defrag patchset since this change is indepentent.

 net/ipv6/ip6_output.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index c217775..bf40b4b 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -564,18 +564,17 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
 	/* We must not fragment if the socket is set to force MTU discovery
 	 * or if the skb it not generated by a local socket.
 	 */
-	if (unlikely(!skb->ignore_df && skb->len > mtu) ||
-		     (IP6CB(skb)->frag_max_size &&
-		      IP6CB(skb)->frag_max_size > mtu)) {
-		if (skb->sk && dst_allfrag(skb_dst(skb)))
-			sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK);
+	if (unlikely(!skb->ignore_df && skb->len > mtu))
+		goto fail_toobig;
 
-		skb->dev = skb_dst(skb)->dev;
-		icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
-		IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
-			      IPSTATS_MIB_FRAGFAILS);
-		kfree_skb(skb);
-		return -EMSGSIZE;
+	if (IP6CB(skb)->frag_max_size) {
+		if (IP6CB(skb)->frag_max_size > mtu)
+			goto fail_toobig;
+
+		/* don't send fragments larger than what we received */
+		mtu = IP6CB(skb)->frag_max_size;
+		if (mtu < IPV6_MIN_MTU)
+			mtu = IPV6_MIN_MTU;
 	}
 
 	if (np && np->frag_size < mtu) {
@@ -815,6 +814,14 @@ slow_path:
 	consume_skb(skb);
 	return err;
 
+fail_toobig:
+	if (skb->sk && dst_allfrag(skb_dst(skb)))
+		sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK);
+
+	skb->dev = skb_dst(skb)->dev;
+	icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+	err = -EMSGSIZE;
+
 fail:
 	IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
 		      IPSTATS_MIB_FRAGFAILS);
-- 
2.0.5

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

* Re: [PATCH v3 -next] ipv6: don't increase size when refragmenting forwarded ipv6 skbs
  2015-05-21 22:44 [PATCH v3 -next] ipv6: don't increase size when refragmenting forwarded ipv6 skbs Florian Westphal
@ 2015-05-25 21:22 ` David Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David Miller @ 2015-05-25 21:22 UTC (permalink / raw)
  To: fw; +Cc: netdev

From: Florian Westphal <fw@strlen.de>
Date: Fri, 22 May 2015 00:44:16 +0200

> since commit 6aafeef03b9d ("netfilter: push reasm skb through instead of
> original frag skbs") we will end up sometimes re-fragmenting skbs
> that we've reassembled.
> 
> ipv6 defrag preserves the original skbs using the skb frag list, i.e. as long
> as the skb frag list is preserved there is no problem since we keep
> original geometry of fragments intact.
> 
> However, in the rare case where the frag list is munged or skb
> is linearized, we might send larger fragments than what we originally
> received.
> 
> A router in the path might then send packet-too-big errors even if
> sender never sent fragments exceeding the reported mtu:
> 
> mtu 1500 - 1500:1400 - 1400:1280 - 1280
>      A         R1         R2        B
> 
> 1 - A sends to B, fragment size 1400
> 2 - R2 sends pkttoobig error for 1280
> 3 - A sends to B, fragment size 1280
> 4 - R2 sends pkttoobig error for 1280 again because it sees fragments of size 1400.
> 
> make sure ip6_fragment always caps MTU at largest packet size seen
> when defragmented skb is forwarded.
> 
> Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
> Signed-off-by: Florian Westphal <fw@strlen.de>

Applied to net-next, thanks.

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

end of thread, other threads:[~2015-05-25 21:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-21 22:44 [PATCH v3 -next] ipv6: don't increase size when refragmenting forwarded ipv6 skbs Florian Westphal
2015-05-25 21:22 ` David Miller

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).