aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c50
1 files changed, 36 insertions, 14 deletions
diff --git a/net/socket.c b/net/socket.c
index d80d87a395ea..643a1648fcc2 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -669,7 +669,7 @@ static bool skb_is_err_queue(const struct sk_buff *skb)
669 * before the software timestamp is received, a hardware TX timestamp may be 669 * before the software timestamp is received, a hardware TX timestamp may be
670 * returned only if there is no software TX timestamp. Ignore false software 670 * returned only if there is no software TX timestamp. Ignore false software
671 * timestamps, which may be made in the __sock_recv_timestamp() call when the 671 * timestamps, which may be made in the __sock_recv_timestamp() call when the
672 * option SO_TIMESTAMP(NS) is enabled on the socket, even when the skb has a 672 * option SO_TIMESTAMP_OLD(NS) is enabled on the socket, even when the skb has a
673 * hardware timestamp. 673 * hardware timestamp.
674 */ 674 */
675static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp) 675static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp)
@@ -705,7 +705,9 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
705 struct sk_buff *skb) 705 struct sk_buff *skb)
706{ 706{
707 int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP); 707 int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP);
708 struct scm_timestamping tss; 708 int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
709 struct scm_timestamping_internal tss;
710
709 int empty = 1, false_tstamp = 0; 711 int empty = 1, false_tstamp = 0;
710 struct skb_shared_hwtstamps *shhwtstamps = 712 struct skb_shared_hwtstamps *shhwtstamps =
711 skb_hwtstamps(skb); 713 skb_hwtstamps(skb);
@@ -719,34 +721,54 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
719 721
720 if (need_software_tstamp) { 722 if (need_software_tstamp) {
721 if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) { 723 if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) {
722 struct timeval tv; 724 if (new_tstamp) {
723 skb_get_timestamp(skb, &tv); 725 struct __kernel_sock_timeval tv;
724 put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP, 726
725 sizeof(tv), &tv); 727 skb_get_new_timestamp(skb, &tv);
728 put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_NEW,
729 sizeof(tv), &tv);
730 } else {
731 struct __kernel_old_timeval tv;
732
733 skb_get_timestamp(skb, &tv);
734 put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,
735 sizeof(tv), &tv);
736 }
726 } else { 737 } else {
727 struct timespec ts; 738 if (new_tstamp) {
728 skb_get_timestampns(skb, &ts); 739 struct __kernel_timespec ts;
729 put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS, 740
730 sizeof(ts), &ts); 741 skb_get_new_timestampns(skb, &ts);
742 put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_NEW,
743 sizeof(ts), &ts);
744 } else {
745 struct timespec ts;
746
747 skb_get_timestampns(skb, &ts);
748 put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMPNS_OLD,
749 sizeof(ts), &ts);
750 }
731 } 751 }
732 } 752 }
733 753
734 memset(&tss, 0, sizeof(tss)); 754 memset(&tss, 0, sizeof(tss));
735 if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) && 755 if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
736 ktime_to_timespec_cond(skb->tstamp, tss.ts + 0)) 756 ktime_to_timespec64_cond(skb->tstamp, tss.ts + 0))
737 empty = 0; 757 empty = 0;
738 if (shhwtstamps && 758 if (shhwtstamps &&
739 (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && 759 (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) &&
740 !skb_is_swtx_tstamp(skb, false_tstamp) && 760 !skb_is_swtx_tstamp(skb, false_tstamp) &&
741 ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2)) { 761 ktime_to_timespec64_cond(shhwtstamps->hwtstamp, tss.ts + 2)) {
742 empty = 0; 762 empty = 0;
743 if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) && 763 if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) &&
744 !skb_is_err_queue(skb)) 764 !skb_is_err_queue(skb))
745 put_ts_pktinfo(msg, skb); 765 put_ts_pktinfo(msg, skb);
746 } 766 }
747 if (!empty) { 767 if (!empty) {
748 put_cmsg(msg, SOL_SOCKET, 768 if (sock_flag(sk, SOCK_TSTAMP_NEW))
749 SCM_TIMESTAMPING, sizeof(tss), &tss); 769 put_cmsg_scm_timestamping64(msg, &tss);
770 else
771 put_cmsg_scm_timestamping(msg, &tss);
750 772
751 if (skb_is_err_queue(skb) && skb->len && 773 if (skb_is_err_queue(skb) && skb->len &&
752 SKB_EXT_ERR(skb)->opt_stats) 774 SKB_EXT_ERR(skb)->opt_stats)