forked from luck/tmp_suning_uos_patched
net: ensure correct skb->tstamp in various fragmenters
Thomas found that some forwarded packets would be stuck in FQ packet scheduler because their skb->tstamp contained timestamps far in the future. We thought we addressed this point in commit8203e2d844
("net: clear skb->tstamp in forwarding paths") but there is still an issue when/if a packet needs to be fragmented. In order to meet EDT requirements, we have to make sure all fragments get the original skb->tstamp. Note that this original skb->tstamp should be zero in forwarding path, but might have a non zero value in output path if user decided so. Fixes:fb420d5d91
("tcp/fq: move back to CLOCK_MONOTONIC") Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: Thomas Bartschies <Thomas.Bartschies@cvk.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
63158ac0ba
commit
9669fffc14
|
@ -33,6 +33,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk,
|
|||
{
|
||||
int frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size;
|
||||
unsigned int hlen, ll_rs, mtu;
|
||||
ktime_t tstamp = skb->tstamp;
|
||||
struct ip_frag_state state;
|
||||
struct iphdr *iph;
|
||||
int err;
|
||||
|
@ -80,6 +81,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk,
|
|||
if (iter.frag)
|
||||
ip_fraglist_prepare(skb, &iter);
|
||||
|
||||
skb->tstamp = tstamp;
|
||||
err = output(net, sk, data, skb);
|
||||
if (err || !iter.frag)
|
||||
break;
|
||||
|
@ -104,6 +106,7 @@ static int nf_br_ip_fragment(struct net *net, struct sock *sk,
|
|||
goto blackhole;
|
||||
}
|
||||
|
||||
skb2->tstamp = tstamp;
|
||||
err = output(net, sk, data, skb2);
|
||||
if (err)
|
||||
goto blackhole;
|
||||
|
|
|
@ -771,6 +771,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
|||
struct rtable *rt = skb_rtable(skb);
|
||||
unsigned int mtu, hlen, ll_rs;
|
||||
struct ip_fraglist_iter iter;
|
||||
ktime_t tstamp = skb->tstamp;
|
||||
struct ip_frag_state state;
|
||||
int err = 0;
|
||||
|
||||
|
@ -846,6 +847,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
|||
ip_fraglist_prepare(skb, &iter);
|
||||
}
|
||||
|
||||
skb->tstamp = tstamp;
|
||||
err = output(net, sk, skb);
|
||||
|
||||
if (!err)
|
||||
|
@ -900,6 +902,7 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
|||
/*
|
||||
* Put this fragment into the sending queue.
|
||||
*/
|
||||
skb2->tstamp = tstamp;
|
||||
err = output(net, sk, skb2);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
|
|
@ -768,6 +768,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
|||
inet6_sk(skb->sk) : NULL;
|
||||
struct ip6_frag_state state;
|
||||
unsigned int mtu, hlen, nexthdr_offset;
|
||||
ktime_t tstamp = skb->tstamp;
|
||||
int hroom, err = 0;
|
||||
__be32 frag_id;
|
||||
u8 *prevhdr, nexthdr = 0;
|
||||
|
@ -855,6 +856,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
|||
if (iter.frag)
|
||||
ip6_fraglist_prepare(skb, &iter);
|
||||
|
||||
skb->tstamp = tstamp;
|
||||
err = output(net, sk, skb);
|
||||
if (!err)
|
||||
IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
|
||||
|
@ -913,6 +915,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
|||
/*
|
||||
* Put this fragment into the sending queue.
|
||||
*/
|
||||
frag->tstamp = tstamp;
|
||||
err = output(net, sk, frag);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
|
|
@ -119,6 +119,7 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
|||
struct sk_buff *))
|
||||
{
|
||||
int frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size;
|
||||
ktime_t tstamp = skb->tstamp;
|
||||
struct ip6_frag_state state;
|
||||
u8 *prevhdr, nexthdr = 0;
|
||||
unsigned int mtu, hlen;
|
||||
|
@ -183,6 +184,7 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
|||
if (iter.frag)
|
||||
ip6_fraglist_prepare(skb, &iter);
|
||||
|
||||
skb->tstamp = tstamp;
|
||||
err = output(net, sk, data, skb);
|
||||
if (err || !iter.frag)
|
||||
break;
|
||||
|
@ -215,6 +217,7 @@ int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
|||
goto blackhole;
|
||||
}
|
||||
|
||||
skb2->tstamp = tstamp;
|
||||
err = output(net, sk, data, skb2);
|
||||
if (err)
|
||||
goto blackhole;
|
||||
|
|
Loading…
Reference in New Issue
Block a user