Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: ipv6: Handle delivery_time in ipv6 defrag

A latter patch will postpone the delivery_time clearing until the stack
knows the skb is being delivered locally (i.e. calling
skb_clear_delivery_time() at ip_local_deliver_finish() for IPv4
and at ip6_input_finish() for IPv6). That will allow other kernel
forwarding path (e.g. ip[6]_forward) to keep the delivery_time also.

A very similar IPv6 defrag codes have been duplicated in
multiple places: regular IPv6, nf_conntrack, and 6lowpan.

Unlike the IPv4 defrag which is done before ip_local_deliver_finish(),
the regular IPv6 defrag is done after ip6_input_finish().
Thus, no change should be needed in the regular IPv6 defrag
logic because skb_clear_delivery_time() should have been called.

6lowpan also does not need special handling on delivery_time
because it is a non-inet packet_type.

However, cf_conntrack has a case in NF_INET_PRE_ROUTING that needs
to do the IPv6 defrag earlier. Thus, it needs to save the
mono_delivery_time bit in the inet_frag_queue which is similar
to how it is handled in the previous patch for the IPv4 defrag.

This patch chooses to do it consistently and stores the mono_delivery_time
in the inet_frag_queue for all cases such that it will be easier
for the future refactoring effort on the IPv6 reasm code.

Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Martin KaFai Lau and committed by
David S. Miller
335c8cf3 8672406e

+3
+1
net/ieee802154/6lowpan/reassembly.c
··· 130 130 goto err; 131 131 132 132 fq->q.stamp = skb->tstamp; 133 + fq->q.mono_delivery_time = skb->mono_delivery_time; 133 134 if (frag_type == LOWPAN_DISPATCH_FRAG1) 134 135 fq->q.flags |= INET_FRAG_FIRST_IN; 135 136
+1
net/ipv6/netfilter/nf_conntrack_reasm.c
··· 264 264 fq->iif = dev->ifindex; 265 265 266 266 fq->q.stamp = skb->tstamp; 267 + fq->q.mono_delivery_time = skb->mono_delivery_time; 267 268 fq->q.meat += skb->len; 268 269 fq->ecn |= ecn; 269 270 if (payload_len > fq->q.max_size)
+1
net/ipv6/reassembly.c
··· 194 194 fq->iif = dev->ifindex; 195 195 196 196 fq->q.stamp = skb->tstamp; 197 + fq->q.mono_delivery_time = skb->mono_delivery_time; 197 198 fq->q.meat += skb->len; 198 199 fq->ecn |= ecn; 199 200 add_frag_mem_limit(fq->q.fqdir, skb->truesize);