git: f801346706ea - stable/14 - ip6: add SO_BINTIME support
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 29 Sep 2025 15:13:34 UTC
The branch stable/14 has been updated by jtl:
URL: https://cgit.FreeBSD.org/src/commit/?id=f801346706ea75401614df2dba3f85ecea2af03e
commit f801346706ea75401614df2dba3f85ecea2af03e
Author: Jonathan T. Looney <jtl@FreeBSD.org>
AuthorDate: 2025-09-12 17:49:17 +0000
Commit: Jonathan T. Looney <jtl@FreeBSD.org>
CommitDate: 2025-09-29 15:12:49 +0000
ip6: add SO_BINTIME support
This adds support for obtaining timestamps from IPv6 packets using the
SO_BINTIME socket option, bringing it in parity with IPv4 behavior.
Enable testing the SO_BINTIME option in the relevant (manual) regression
test.
PR: 289423
Reviewed by: markj
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D52504
(cherry picked from commit cd02a8a9f8be2085d5242606a79668dc3720e7b0)
---
sys/netinet6/ip6_input.c | 53 +++++++++++++++-------
.../regression/sockets/udp_pingpong/udp_pingpong.c | 8 ++--
2 files changed, 39 insertions(+), 22 deletions(-)
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index b3f10ddc5ea7..2db1b4723edc 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1193,8 +1193,8 @@ ip6_savecontrol_v4(struct inpcb *inp, struct mbuf *m, struct mbuf **mp,
{
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
-#ifdef SO_TIMESTAMP
- if ((inp->inp_socket->so_options & SO_TIMESTAMP) != 0) {
+#if defined(SO_TIMESTAMP) && defined(SO_BINTIME)
+ if ((inp->inp_socket->so_options & (SO_TIMESTAMP | SO_BINTIME)) != 0) {
union {
struct timeval tv;
struct bintime bt;
@@ -1202,47 +1202,66 @@ ip6_savecontrol_v4(struct inpcb *inp, struct mbuf *m, struct mbuf **mp,
} t;
struct bintime boottimebin, bt1;
struct timespec ts1;
+ int ts_clock;
bool stamped;
+ ts_clock = inp->inp_socket->so_ts_clock;
stamped = false;
- switch (inp->inp_socket->so_ts_clock) {
- case SO_TS_REALTIME_MICRO:
+
+ /*
+ * Handle BINTIME first. We create the same output options
+ * for both SO_BINTIME and the case where SO_TIMESTAMP is
+ * set with the timestamp clock set to SO_TS_BINTIME.
+ */
+ if ((inp->inp_socket->so_options & SO_BINTIME) != 0 ||
+ ts_clock == SO_TS_BINTIME) {
if ((m->m_flags & (M_PKTHDR | M_TSTMP)) == (M_PKTHDR |
M_TSTMP)) {
mbuf_tstmp2timespec(m, &ts1);
- timespec2bintime(&ts1, &bt1);
+ timespec2bintime(&ts1, &t.bt);
getboottimebin(&boottimebin);
- bintime_add(&bt1, &boottimebin);
- bintime2timeval(&bt1, &t.tv);
+ bintime_add(&t.bt, &boottimebin);
} else {
- microtime(&t.tv);
+ bintime(&t.bt);
}
- *mp = sbcreatecontrol(&t.tv, sizeof(t.tv),
- SCM_TIMESTAMP, SOL_SOCKET, M_NOWAIT);
+ *mp = sbcreatecontrol(&t.bt, sizeof(t.bt), SCM_BINTIME,
+ SOL_SOCKET, M_NOWAIT);
if (*mp != NULL) {
mp = &(*mp)->m_next;
stamped = true;
}
- break;
- case SO_TS_BINTIME:
+ /*
+ * Suppress other timestamps if SO_TIMESTAMP is not
+ * set.
+ */
+ if ((inp->inp_socket->so_options & SO_TIMESTAMP) == 0)
+ ts_clock = SO_TS_BINTIME;
+ }
+
+ switch (ts_clock) {
+ case SO_TS_REALTIME_MICRO:
if ((m->m_flags & (M_PKTHDR | M_TSTMP)) == (M_PKTHDR |
M_TSTMP)) {
mbuf_tstmp2timespec(m, &ts1);
- timespec2bintime(&ts1, &t.bt);
+ timespec2bintime(&ts1, &bt1);
getboottimebin(&boottimebin);
- bintime_add(&t.bt, &boottimebin);
+ bintime_add(&bt1, &boottimebin);
+ bintime2timeval(&bt1, &t.tv);
} else {
- bintime(&t.bt);
+ microtime(&t.tv);
}
- *mp = sbcreatecontrol(&t.bt, sizeof(t.bt), SCM_BINTIME,
- SOL_SOCKET, M_NOWAIT);
+ *mp = sbcreatecontrol(&t.tv, sizeof(t.tv),
+ SCM_TIMESTAMP, SOL_SOCKET, M_NOWAIT);
if (*mp != NULL) {
mp = &(*mp)->m_next;
stamped = true;
}
break;
+ case SO_TS_BINTIME:
+ break;
+
case SO_TS_REALTIME:
if ((m->m_flags & (M_PKTHDR | M_TSTMP)) == (M_PKTHDR |
M_TSTMP)) {
diff --git a/tools/regression/sockets/udp_pingpong/udp_pingpong.c b/tools/regression/sockets/udp_pingpong/udp_pingpong.c
index 9babe144adcb..23ba8403be6d 100644
--- a/tools/regression/sockets/udp_pingpong/udp_pingpong.c
+++ b/tools/regression/sockets/udp_pingpong/udp_pingpong.c
@@ -602,11 +602,9 @@ main(void)
test_run(TT_TIMESTAMP, i, 1,
"send()/recvmsg(), setsockopt(SO_TIMESTAMP, 1)");
printf("OK\n");
- if (i == 0) {
- test_run(TT_BINTIME, i, 1,
- "send()/recvmsg(), setsockopt(SO_BINTIME, 1)");
- printf("OK\n");
- }
+ test_run(TT_BINTIME, i, 1,
+ "send()/recvmsg(), setsockopt(SO_BINTIME, 1)");
+ printf("OK\n");
test_run(TT_REALTIME_MICRO, i, 1,
"send()/recvmsg(), setsockopt(SO_TS_CLOCK, SO_TS_REALTIME_MICRO)");
printf("OK\n");