aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-02-19 12:18:37 -0500
committerPatrick McHardy <kaber@trash.net>2010-02-19 12:18:37 -0500
commit9e2dcf72023d1447f09c47d77c99b0c49659e5ce (patch)
tree38fdd50b7344f1cc6447a8420df313e74e0ccf7c /net/ipv6
parent64507fdbc29c3a622180378210ecea8659b14e40 (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.c8
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