diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/skbuff.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 56db472e9b86..65a3798f43e6 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -3710,19 +3710,28 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3710 | struct sock *sk, int tstype) | 3710 | struct sock *sk, int tstype) |
3711 | { | 3711 | { |
3712 | struct sk_buff *skb; | 3712 | struct sk_buff *skb; |
3713 | bool tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY; | ||
3713 | 3714 | ||
3714 | if (!sk) | 3715 | if (!sk) |
3715 | return; | 3716 | return; |
3716 | 3717 | ||
3717 | if (hwtstamps) | 3718 | if (tsonly) |
3718 | *skb_hwtstamps(orig_skb) = *hwtstamps; | 3719 | skb = alloc_skb(0, GFP_ATOMIC); |
3719 | else | 3720 | else |
3720 | orig_skb->tstamp = ktime_get_real(); | 3721 | skb = skb_clone(orig_skb, GFP_ATOMIC); |
3721 | |||
3722 | skb = skb_clone(orig_skb, GFP_ATOMIC); | ||
3723 | if (!skb) | 3722 | if (!skb) |
3724 | return; | 3723 | return; |
3725 | 3724 | ||
3725 | if (tsonly) { | ||
3726 | skb_shinfo(skb)->tx_flags = skb_shinfo(orig_skb)->tx_flags; | ||
3727 | skb_shinfo(skb)->tskey = skb_shinfo(orig_skb)->tskey; | ||
3728 | } | ||
3729 | |||
3730 | if (hwtstamps) | ||
3731 | *skb_hwtstamps(skb) = *hwtstamps; | ||
3732 | else | ||
3733 | skb->tstamp = ktime_get_real(); | ||
3734 | |||
3726 | __skb_complete_tx_timestamp(skb, sk, tstype); | 3735 | __skb_complete_tx_timestamp(skb, sk, tstype); |
3727 | } | 3736 | } |
3728 | EXPORT_SYMBOL_GPL(__skb_tstamp_tx); | 3737 | EXPORT_SYMBOL_GPL(__skb_tstamp_tx); |