forked from Minki/linux
net: ip: Handle delivery_time in ip defrag
A latter patch will postpone the delivery_time clearing until the stack knows the skb is being delivered locally. That will allow other kernel forwarding path (e.g. ip[6]_forward) to keep the delivery_time also. An earlier attempt was to do skb_clear_delivery_time() in ip_local_deliver() and ip6_input(). The discussion [0] requested to move it one step later into ip_local_deliver_finish() and ip6_input_finish() so that the delivery_time can be kept for the ip_vs forwarding path also. To do that, this patch also needs to take care of the (rcv) timestamp usecase in ip_is_fragment(). It needs to expect delivery_time in the skb->tstamp, so it needs to save the mono_delivery_time bit in inet_frag_queue such that the delivery_time (if any) can be restored in the final defragmented skb. [Note that it will only happen when the locally generated skb is looping from egress to ingress over a virtual interface (e.g. veth, loopback...), skb->tstamp may have the delivery time before it is known that it will be delivered locally and received by another sk.] [0]: https://lore.kernel.org/netdev/ca728d81-80e8-3767-d5e-d44f6ad96e43@ssi.bg/ Signed-off-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d98d58a002
commit
8672406eb5
@ -70,6 +70,7 @@ struct frag_v6_compare_key {
|
||||
* @stamp: timestamp of the last received fragment
|
||||
* @len: total length of the original datagram
|
||||
* @meat: length of received fragments so far
|
||||
* @mono_delivery_time: stamp has a mono delivery time (EDT)
|
||||
* @flags: fragment queue flags
|
||||
* @max_size: maximum received fragment size
|
||||
* @fqdir: pointer to struct fqdir
|
||||
@ -90,6 +91,7 @@ struct inet_frag_queue {
|
||||
ktime_t stamp;
|
||||
int len;
|
||||
int meat;
|
||||
u8 mono_delivery_time;
|
||||
__u8 flags;
|
||||
u16 max_size;
|
||||
struct fqdir *fqdir;
|
||||
|
@ -572,6 +572,7 @@ void inet_frag_reasm_finish(struct inet_frag_queue *q, struct sk_buff *head,
|
||||
skb_mark_not_on_list(head);
|
||||
head->prev = NULL;
|
||||
head->tstamp = q->stamp;
|
||||
head->mono_delivery_time = q->mono_delivery_time;
|
||||
}
|
||||
EXPORT_SYMBOL(inet_frag_reasm_finish);
|
||||
|
||||
|
@ -349,6 +349,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
|
||||
qp->iif = dev->ifindex;
|
||||
|
||||
qp->q.stamp = skb->tstamp;
|
||||
qp->q.mono_delivery_time = skb->mono_delivery_time;
|
||||
qp->q.meat += skb->len;
|
||||
qp->ecn |= ecn;
|
||||
add_frag_mem_limit(qp->q.fqdir, skb->truesize);
|
||||
|
Loading…
Reference in New Issue
Block a user