diff options
author | Miroslav Lichvar <mlichvar@redhat.com> | 2022-01-05 11:33:26 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-01-06 13:18:08 +0100 |
commit | 007747a984ea5e895b7d8b056b24ebf431e1e71d (patch) | |
tree | 219ac440129b5f84954ac55c7dc63d47554f3750 /net/socket.c | |
parent | net: dsa: warn about dsa_port and dsa_switch bit fields being non atomic (diff) | |
download | linux-007747a984ea5e895b7d8b056b24ebf431e1e71d.tar.xz linux-007747a984ea5e895b7d8b056b24ebf431e1e71d.zip |
net: fix SOF_TIMESTAMPING_BIND_PHC to work with multiple sockets
When multiple sockets using the SOF_TIMESTAMPING_BIND_PHC flag received
a packet with a hardware timestamp (e.g. multiple PTP instances in
different PTP domains using the UDPv4/v6 multicast or L2 transport),
the timestamps received on some sockets were corrupted due to repeated
conversion of the same timestamp (by the same or different vclocks).
Fix ptp_convert_timestamp() to not modify the shared skb timestamp
and return the converted timestamp as a ktime_t instead. If the
conversion fails, return 0 to not confuse the application with
timestamps corresponding to an unexpected PHC.
Fixes: d7c088265588 ("net: socket: support hardware timestamp conversion to PHC bound")
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Yangbo Lu <yangbo.lu@nxp.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to '')
-rw-r--r-- | net/socket.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/socket.c b/net/socket.c index 5e644c858428..50cf75730fd7 100644 --- a/net/socket.c +++ b/net/socket.c @@ -830,6 +830,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, int empty = 1, false_tstamp = 0; struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); + ktime_t hwtstamp; /* Race occurred between timestamp enabling and packet receiving. Fill in the current time for now. */ @@ -878,10 +879,12 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && !skb_is_swtx_tstamp(skb, false_tstamp)) { if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC) - ptp_convert_timestamp(shhwtstamps, sk->sk_bind_phc); + hwtstamp = ptp_convert_timestamp(shhwtstamps, + sk->sk_bind_phc); + else + hwtstamp = shhwtstamps->hwtstamp; - if (ktime_to_timespec64_cond(shhwtstamps->hwtstamp, - tss.ts + 2)) { + if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) { empty = 0; if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) && |