From: Florian Westphal <fw@strlen.de>
To: David Woodhouse <dwmw2@infradead.org>
Cc: Florian Westphal <fw@strlen.de>, netdev <netdev@vger.kernel.org>,
johannes@sipsolutions.net
Subject: Re: IPv6 routing/fragmentation panic
Date: Wed, 16 Sep 2015 15:27:33 +0200 [thread overview]
Message-ID: <20150916132733.GQ24810@breakpoint.cc> (raw)
In-Reply-To: <1442398145.131189.46.camel@infradead.org>
David Woodhouse <dwmw2@infradead.org> wrote:
> On Wed, 2015-09-16 at 01:48 +0200, Florian Westphal wrote:
> >
> > What I don't understand is why you see this with fragmented ipv6
> > packets only (and not with all ipv6 forwarded skbs).
> >
> > Something like this copy-pastry from ip_finish_output2 should fix it:
>
> That works; thanks.
>
> Tested-by: David Woodhouse <David.Woodhouse@intel.com>
>
> A little extra debugging output shows that the offending fragments were
> arriving here with skb_headroom(skb)==10. Which is reasonable, being
> the Solos ADSL card's header of 8 bytes followed by 2 bytes of PPP
> frame type.
>
> The non-fragmented packets, on the other hand, are arriving with a
> headroom of 42 bytes. Could something else already have reallocated
> them before they get that far?
Yep. I missed
if (skb_cow(skb, dst->dev->hard_header_len)) {
call in ip6_forward().
Problem is of course that we only expand headroom of the skb
and not of the fragment(s) stored in that skbs frag list.
So we have several options for a fix.
- expand headroom in ip6_finish_output2, like we do for ipv4
- expand headroom in ip6_fragment
- defer to slowpath if frags don't have enough headroom.
The latter is the smallest patch and would not add test for locally
generated, non-fragmented skbs.
(not even compile tested)
David, could you test this? I'd do an official patch submission then.
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -586,6 +586,7 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
frag_id = ipv6_select_ident(net, &ipv6_hdr(skb)->daddr,
&ipv6_hdr(skb)->saddr);
+ hroom = LL_RESERVED_SPACE(rt->dst.dev);
if (skb_has_frag_list(skb)) {
int first_len = skb_pagelen(skb);
struct sk_buff *frag2;
@@ -599,7 +600,7 @@ int ip6_fragment(struct sock *sk, struct sk_buff *skb,
/* Correct geometry. */
if (frag->len > mtu ||
((frag->len & 7) && frag->next) ||
- skb_headroom(frag) < hlen)
+ skb_headroom(frag) < (hlen + hroom))
goto slow_path_clean;
/* Partially cloned skb? */
@@ -724,7 +725,6 @@ slow_path:
*/
*prevhdr = NEXTHDR_FRAGMENT;
- hroom = LL_RESERVED_SPACE(rt->dst.dev);
troom = rt->dst.dev->needed_tailroom;
/*
next prev parent reply other threads:[~2015-09-16 13:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-15 15:53 IPv6 routing/fragmentation panic David Woodhouse
2015-09-15 16:07 ` Michal Kubecek
2015-09-15 23:48 ` Florian Westphal
2015-09-16 10:09 ` David Woodhouse
2015-09-16 13:27 ` Florian Westphal [this message]
2015-09-16 13:34 ` David Woodhouse
2015-09-16 14:00 ` David Woodhouse
2015-09-16 15:30 ` Florian Westphal
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=20150916132733.GQ24810@breakpoint.cc \
--to=fw@strlen.de \
--cc=dwmw2@infradead.org \
--cc=johannes@sipsolutions.net \
--cc=netdev@vger.kernel.org \
/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 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.