int flags);
int tcp_set_rcvlowat(struct sock *sk, int val);
int tcp_set_window_clamp(struct sock *sk, int val);
-void tcp_update_recv_tstamps(struct sk_buff *skb,
- struct scm_timestamping_internal *tss);
+
+static inline void
+tcp_update_recv_tstamps(struct sk_buff *skb,
+ struct scm_timestamping_internal *tss)
+{
+ tss->ts[0] = skb->tstamp;
+ tss->ts[2] = skb_hwtstamps(skb)->hwtstamp;
+}
+
void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
struct scm_timestamping_internal *tss);
void tcp_data_ready(struct sock *sk);
int i;
for (i = 0; i < ARRAY_SIZE(tss.ts); i++) {
- tss.ts[i].tv_sec = tss_internal->ts[i].tv_sec;
- tss.ts[i].tv_nsec = tss_internal->ts[i].tv_nsec;
+ struct timespec64 tv = ktime_to_timespec64(tss_internal->ts[i]);
+
+ tss.ts[i].tv_sec = tv.tv_sec;
+ tss.ts[i].tv_nsec = tv.tv_nsec;
}
put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_NEW, sizeof(tss), &tss);
int i;
for (i = 0; i < ARRAY_SIZE(tss.ts); i++) {
- tss.ts[i].tv_sec = tss_internal->ts[i].tv_sec;
- tss.ts[i].tv_nsec = tss_internal->ts[i].tv_nsec;
+ struct timespec64 tv = ktime_to_timespec64(tss_internal->ts[i]);
+
+ tss.ts[i].tv_sec = tv.tv_sec;
+ tss.ts[i].tv_nsec = tv.tv_nsec;
}
put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPING_OLD, sizeof(tss), &tss);
}
EXPORT_IPV6_MOD(tcp_set_rcvlowat);
-void tcp_update_recv_tstamps(struct sk_buff *skb,
- struct scm_timestamping_internal *tss)
-{
- if (skb->tstamp)
- tss->ts[0] = ktime_to_timespec64(skb->tstamp);
- else
- tss->ts[0] = (struct timespec64) {0};
-
- if (skb_hwtstamps(skb)->hwtstamp)
- tss->ts[2] = ktime_to_timespec64(skb_hwtstamps(skb)->hwtstamp);
- else
- tss->ts[2] = (struct timespec64) {0};
-}
-
#ifdef CONFIG_MMU
static const struct vm_operations_struct tcp_vm_ops = {
};
{
int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
u32 tsflags = READ_ONCE(sk->sk_tsflags);
- bool has_timestamping = false;
- if (tss->ts[0].tv_sec || tss->ts[0].tv_nsec) {
+ if (tss->ts[0]) {
if (sock_flag(sk, SOCK_RCVTSTAMP)) {
+ struct timespec64 tv = ktime_to_timespec64(tss->ts[0]);
+
if (sock_flag(sk, SOCK_RCVTSTAMPNS)) {
if (new_tstamp) {
struct __kernel_timespec kts = {
- .tv_sec = tss->ts[0].tv_sec,
- .tv_nsec = tss->ts[0].tv_nsec,
+ .tv_sec = tv.tv_sec,
+ .tv_nsec = tv.tv_nsec,
};
put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
sizeof(kts), &kts);
} else {
struct __kernel_old_timespec ts_old = {
- .tv_sec = tss->ts[0].tv_sec,
- .tv_nsec = tss->ts[0].tv_nsec,
+ .tv_sec = tv.tv_sec,
+ .tv_nsec = tv.tv_nsec,
};
put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
sizeof(ts_old), &ts_old);
} else {
if (new_tstamp) {
struct __kernel_sock_timeval stv = {
- .tv_sec = tss->ts[0].tv_sec,
- .tv_usec = tss->ts[0].tv_nsec / 1000,
+ .tv_sec = tv.tv_sec,
+ .tv_usec = tv.tv_nsec / 1000,
};
put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
sizeof(stv), &stv);
} else {
- struct __kernel_old_timeval tv = {
- .tv_sec = tss->ts[0].tv_sec,
- .tv_usec = tss->ts[0].tv_nsec / 1000,
+ struct __kernel_old_timeval otv = {
+ .tv_sec = tv.tv_sec,
+ .tv_usec = tv.tv_nsec / 1000,
};
put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
- sizeof(tv), &tv);
+ sizeof(otv), &otv);
}
}
}
- if (tsflags & SOF_TIMESTAMPING_SOFTWARE &&
+ if (!(tsflags & SOF_TIMESTAMPING_SOFTWARE &&
(tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ||
- !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER)))
- has_timestamping = true;
- else
- tss->ts[0] = (struct timespec64) {0};
+ !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER))))
+ tss->ts[0] = 0;
}
- if (tss->ts[2].tv_sec || tss->ts[2].tv_nsec) {
- if (tsflags & SOF_TIMESTAMPING_RAW_HARDWARE &&
+ if (tss->ts[2]) {
+ if (!(tsflags & SOF_TIMESTAMPING_RAW_HARDWARE &&
(tsflags & SOF_TIMESTAMPING_RX_HARDWARE ||
- !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER)))
- has_timestamping = true;
- else
- tss->ts[2] = (struct timespec64) {0};
+ !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER))))
+ tss->ts[2] = 0;
}
- if (has_timestamping) {
- tss->ts[1] = (struct timespec64) {0};
+ if (tss->ts[0] | tss->ts[2]) {
+ tss->ts[1] = 0;
if (sock_flag(sk, SOCK_TSTAMP_NEW))
put_cmsg_scm_timestamping64(msg, tss);
else
{
int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
- struct scm_timestamping_internal tss;
- int empty = 1, false_tstamp = 0;
struct skb_shared_hwtstamps *shhwtstamps =
skb_hwtstamps(skb);
- int if_index;
+ struct scm_timestamping_internal tss;
+ int if_index, false_tstamp = 0;
ktime_t hwtstamp;
u32 tsflags;
memset(&tss, 0, sizeof(tss));
tsflags = READ_ONCE(sk->sk_tsflags);
- if ((tsflags & SOF_TIMESTAMPING_SOFTWARE &&
- (tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ||
- skb_is_err_queue(skb) ||
- !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER))) &&
- ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
- empty = 0;
+ if (tsflags & SOF_TIMESTAMPING_SOFTWARE &&
+ (tsflags & SOF_TIMESTAMPING_RX_SOFTWARE ||
+ skb_is_err_queue(skb) ||
+ !(tsflags & SOF_TIMESTAMPING_OPT_RX_FILTER)))
+ tss.ts[0] = skb->tstamp;
+
if (shhwtstamps &&
(tsflags & SOF_TIMESTAMPING_RAW_HARDWARE &&
(tsflags & SOF_TIMESTAMPING_RX_HARDWARE ||
hwtstamp = ptp_convert_timestamp(&hwtstamp,
READ_ONCE(sk->sk_bind_phc));
- if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) {
- empty = 0;
+ if (hwtstamp) {
+ tss.ts[2] = hwtstamp;
if ((tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
!skb_is_err_queue(skb))
put_ts_pktinfo(msg, skb, if_index);
}
}
- if (!empty) {
+ if (tss.ts[0] | tss.ts[2]) {
if (sock_flag(sk, SOCK_TSTAMP_NEW))
put_cmsg_scm_timestamping64(msg, &tss);
else