|
@@ -390,6 +390,7 @@ enum sock_flags {
|
|
SOCK_USE_WRITE_QUEUE, /* whether to call sk->sk_write_space in sock_wfree */
|
|
SOCK_USE_WRITE_QUEUE, /* whether to call sk->sk_write_space in sock_wfree */
|
|
SOCK_DBG, /* %SO_DEBUG setting */
|
|
SOCK_DBG, /* %SO_DEBUG setting */
|
|
SOCK_RCVTSTAMP, /* %SO_TIMESTAMP setting */
|
|
SOCK_RCVTSTAMP, /* %SO_TIMESTAMP setting */
|
|
|
|
+ SOCK_RCVTSTAMPNS, /* %SO_TIMESTAMPNS setting */
|
|
SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */
|
|
SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */
|
|
SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */
|
|
SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */
|
|
};
|
|
};
|
|
@@ -1283,21 +1284,17 @@ static inline int sock_intr_errno(long timeo)
|
|
return timeo == MAX_SCHEDULE_TIMEOUT ? -ERESTARTSYS : -EINTR;
|
|
return timeo == MAX_SCHEDULE_TIMEOUT ? -ERESTARTSYS : -EINTR;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+extern void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
|
|
|
|
+ struct sk_buff *skb);
|
|
|
|
+
|
|
static __inline__ void
|
|
static __inline__ void
|
|
sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
|
|
sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
|
|
{
|
|
{
|
|
ktime_t kt = skb->tstamp;
|
|
ktime_t kt = skb->tstamp;
|
|
|
|
|
|
- if (sock_flag(sk, SOCK_RCVTSTAMP)) {
|
|
|
|
- struct timeval tv;
|
|
|
|
- /* Race occurred between timestamp enabling and packet
|
|
|
|
- receiving. Fill in the current time for now. */
|
|
|
|
- if (kt.tv64 == 0)
|
|
|
|
- kt = ktime_get_real();
|
|
|
|
- skb->tstamp = kt;
|
|
|
|
- tv = ktime_to_timeval(kt);
|
|
|
|
- put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP, sizeof(tv), &tv);
|
|
|
|
- } else
|
|
|
|
|
|
+ if (sock_flag(sk, SOCK_RCVTSTAMP))
|
|
|
|
+ __sock_recv_timestamp(msg, sk, skb);
|
|
|
|
+ else
|
|
sk->sk_stamp = kt;
|
|
sk->sk_stamp = kt;
|
|
}
|
|
}
|
|
|
|
|