net: ipv6: Handle delivery_time in ipv6 defrag
authorMartin KaFai Lau <kafai@fb.com>
Wed, 2 Mar 2022 19:56:03 +0000 (11:56 -0800)
committerDavid S. Miller <davem@davemloft.net>
Thu, 3 Mar 2022 14:38:48 +0000 (14:38 +0000)
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>
net/ieee802154/6lowpan/reassembly.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/reassembly.c

index be6f06a..a91283d 100644 (file)
@@ -130,6 +130,7 @@ static int lowpan_frag_queue(struct lowpan_frag_queue *fq,
                goto err;
 
        fq->q.stamp = skb->tstamp;
+       fq->q.mono_delivery_time = skb->mono_delivery_time;
        if (frag_type == LOWPAN_DISPATCH_FRAG1)
                fq->q.flags |= INET_FRAG_FIRST_IN;
 
index 5c47be2..7dd3629 100644 (file)
@@ -264,6 +264,7 @@ static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb,
                fq->iif = dev->ifindex;
 
        fq->q.stamp = skb->tstamp;
+       fq->q.mono_delivery_time = skb->mono_delivery_time;
        fq->q.meat += skb->len;
        fq->ecn |= ecn;
        if (payload_len > fq->q.max_size)
index 28e4478..ff866f2 100644 (file)
@@ -194,6 +194,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
                fq->iif = dev->ifindex;
 
        fq->q.stamp = skb->tstamp;
+       fq->q.mono_delivery_time = skb->mono_delivery_time;
        fq->q.meat += skb->len;
        fq->ecn |= ecn;
        add_frag_mem_limit(fq->q.fqdir, skb->truesize);