Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9e2dcf72 authored by Patrick McHardy's avatar Patrick McHardy
Browse files

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: default avatarUlrich Weber <uweber@astaro.com>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent 64507fdb
Loading
Loading
Loading
Loading
+1 −7
Original line number Original line Diff line number Diff line
@@ -469,7 +469,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)


	/* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */
	/* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */
	fp = skb_shinfo(head)->frag_list;
	fp = skb_shinfo(head)->frag_list;
	if (NFCT_FRAG6_CB(fp)->orig == NULL)
	if (fp && NFCT_FRAG6_CB(fp)->orig == NULL)
		/* at above code, head skb is divided into two skbs. */
		/* at above code, head skb is divided into two skbs. */
		fp = fp->next;
		fp = fp->next;


@@ -595,12 +595,6 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
	hdr = ipv6_hdr(clone);
	hdr = ipv6_hdr(clone);
	fhdr = (struct frag_hdr *)skb_transport_header(clone);
	fhdr = (struct frag_hdr *)skb_transport_header(clone);


	if (!(fhdr->frag_off & htons(0xFFF9))) {
		pr_debug("Invalid fragment offset\n");
		/* It is not a fragmented frame */
		goto ret_orig;
	}

	if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
	if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
		nf_ct_frag6_evictor();
		nf_ct_frag6_evictor();