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