|
@@ -106,6 +106,7 @@
|
|
|
#include <linux/sockios.h>
|
|
|
#include <linux/atalk.h>
|
|
|
#include <net/busy_poll.h>
|
|
|
+#include <linux/errqueue.h>
|
|
|
|
|
|
#ifdef CONFIG_NET_RX_BUSY_POLL
|
|
|
unsigned int sysctl_net_busy_read __read_mostly;
|
|
@@ -697,7 +698,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
|
|
|
struct sk_buff *skb)
|
|
|
{
|
|
|
int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
|
|
|
- struct timespec ts[3];
|
|
|
+ struct scm_timestamping tss;
|
|
|
int empty = 1;
|
|
|
struct skb_shared_hwtstamps *shhwtstamps =
|
|
|
skb_hwtstamps(skb);
|
|
@@ -714,24 +715,25 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
|
|
|
put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP,
|
|
|
sizeof(tv), &tv);
|
|
|
} else {
|
|
|
- skb_get_timestampns(skb, &ts[0]);
|
|
|
+ struct timespec ts;
|
|
|
+ skb_get_timestampns(skb, &ts);
|
|
|
put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS,
|
|
|
- sizeof(ts[0]), &ts[0]);
|
|
|
+ sizeof(ts), &ts);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- memset(ts, 0, sizeof(ts));
|
|
|
- if (sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE) &&
|
|
|
- ktime_to_timespec_cond(skb->tstamp, ts + 0))
|
|
|
+ memset(&tss, 0, sizeof(tss));
|
|
|
+ if ((sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE) ||
|
|
|
+ skb_shinfo(skb)->tx_flags & SKBTX_ANY_SW_TSTAMP) &&
|
|
|
+ ktime_to_timespec_cond(skb->tstamp, tss.ts + 0))
|
|
|
empty = 0;
|
|
|
if (shhwtstamps &&
|
|
|
sock_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE) &&
|
|
|
- ktime_to_timespec_cond(shhwtstamps->hwtstamp, ts + 2))
|
|
|
+ ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2))
|
|
|
empty = 0;
|
|
|
if (!empty)
|
|
|
put_cmsg(msg, SOL_SOCKET,
|
|
|
- SCM_TIMESTAMPING, sizeof(ts), &ts);
|
|
|
+ SCM_TIMESTAMPING, sizeof(tss), &tss);
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
|
|
|
|