aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/net/socket.c b/net/socket.c
index e034fe4164be..985ef06792d6 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -652,6 +652,16 @@ int kernel_sendmsg(struct socket *sock, struct msghdr *msg,
652} 652}
653EXPORT_SYMBOL(kernel_sendmsg); 653EXPORT_SYMBOL(kernel_sendmsg);
654 654
655static bool skb_is_err_queue(const struct sk_buff *skb)
656{
657 /* pkt_type of skbs enqueued on the error queue are set to
658 * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do
659 * in recvmsg, since skbs received on a local socket will never
660 * have a pkt_type of PACKET_OUTGOING.
661 */
662 return skb->pkt_type == PACKET_OUTGOING;
663}
664
655/* 665/*
656 * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP) 666 * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP)
657 */ 667 */
@@ -695,7 +705,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
695 put_cmsg(msg, SOL_SOCKET, 705 put_cmsg(msg, SOL_SOCKET,
696 SCM_TIMESTAMPING, sizeof(tss), &tss); 706 SCM_TIMESTAMPING, sizeof(tss), &tss);
697 707
698 if (skb->len && (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_STATS)) 708 if (skb_is_err_queue(skb) && skb->len &&
709 SKB_EXT_ERR(skb)->opt_stats)
699 put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS, 710 put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS,
700 skb->len, skb->data); 711 skb->len, skb->data);
701 } 712 }