diff options
author | Patrick McHardy <kaber@trash.net> | 2010-02-19 12:18:37 -0500 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-02-19 12:18:37 -0500 |
commit | 9e2dcf72023d1447f09c47d77c99b0c49659e5ce (patch) | |
tree | 38fdd50b7344f1cc6447a8420df313e74e0ccf7c /net/ipv6 | |
parent | 64507fdbc29c3a622180378210ecea8659b14e40 (diff) |
netfilter: nf_conntrack_reasm: properly handle packets fragmented into a single fragment
When an ICMPV6_PKT_TOOBIG message is received with a MTU below 1280,
all further packets include a fragment header.
Unlike regular defragmentation, conntrack also needs to "reassemble"
those fragments in order to obtain a packet without the fragment
header for connection tracking. Currently nf_conntrack_reasm checks
whether a fragment has either IP6_MF set or an offset != 0, which
makes it ignore those fragments.
Remove the invalid check and make reassembly handle fragment queues
containing only a single fragment.
Reported-and-tested-by: Ulrich Weber <uweber@astaro.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/netfilter/nf_conntrack_reasm.c | 8 |
1 files changed, 1 insertions, 7 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index ad1fcda6898b..f1171b744650 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c | |||
@@ -469,7 +469,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) | |||
469 | 469 | ||
470 | /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */ | 470 | /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */ |
471 | fp = skb_shinfo(head)->frag_list; | 471 | fp = skb_shinfo(head)->frag_list; |
472 | if (NFCT_FRAG6_CB(fp)->orig == NULL) | 472 | if (fp && NFCT_FRAG6_CB(fp)->orig == NULL) |
473 | /* at above code, head skb is divided into two skbs. */ | 473 | /* at above code, head skb is divided into two skbs. */ |
474 | fp = fp->next; | 474 | fp = fp->next; |
475 | 475 | ||
@@ -595,12 +595,6 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user) | |||
595 | hdr = ipv6_hdr(clone); | 595 | hdr = ipv6_hdr(clone); |
596 | fhdr = (struct frag_hdr *)skb_transport_header(clone); | 596 | fhdr = (struct frag_hdr *)skb_transport_header(clone); |
597 | 597 | ||
598 | if (!(fhdr->frag_off & htons(0xFFF9))) { | ||
599 | pr_debug("Invalid fragment offset\n"); | ||
600 | /* It is not a fragmented frame */ | ||
601 | goto ret_orig; | ||
602 | } | ||
603 | |||
604 | if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh) | 598 | if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh) |
605 | nf_ct_frag6_evictor(); | 599 | nf_ct_frag6_evictor(); |
606 | 600 | ||