summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/netinet6/ip6_input.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-08-09 14:02:09 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-09-21 10:29:38 +0200
commitbb80d9df8bac71eedee1a6787ca63aef972a7e48 (patch)
tree1b5cb9443c5ead5706c35afb618abbbd1592315e /freebsd/sys/netinet6/ip6_input.c
parentUpdate to FreeBSD head 2017-10-01 (diff)
downloadrtems-libbsd-bb80d9df8bac71eedee1a6787ca63aef972a7e48.tar.bz2
Update to FreeBSD head 2017-12-01
Git mirror commit e724f51f811a4b2bd29447f8b85ab5c2f9b88266. Update #3472.
Diffstat (limited to 'freebsd/sys/netinet6/ip6_input.c')
-rw-r--r--freebsd/sys/netinet6/ip6_input.c72
1 files changed, 64 insertions, 8 deletions
diff --git a/freebsd/sys/netinet6/ip6_input.c b/freebsd/sys/netinet6/ip6_input.c
index 3d502674..c22f2015 100644
--- a/freebsd/sys/netinet6/ip6_input.c
+++ b/freebsd/sys/netinet6/ip6_input.c
@@ -1,6 +1,8 @@
#include <machine/rtems-bsd-kernel-space.h>
/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
@@ -1223,43 +1225,97 @@ ip6_savecontrol_v4(struct inpcb *inp, struct mbuf *m, struct mbuf **mp,
struct bintime bt;
struct timespec ts;
} t;
+ struct bintime boottimebin, bt1;
+ struct timespec ts1;
+ bool stamped;
+ stamped = false;
switch (inp->inp_socket->so_ts_clock) {
case SO_TS_REALTIME_MICRO:
- microtime(&t.tv);
+ if ((m->m_flags & (M_PKTHDR | M_TSTMP)) == (M_PKTHDR |
+ M_TSTMP)) {
+ mbuf_tstmp2timespec(m, &ts1);
+ timespec2bintime(&ts1, &bt1);
+ getboottimebin(&boottimebin);
+ bintime_add(&bt1, &boottimebin);
+ bintime2timeval(&bt1, &t.tv);
+ } else {
+ microtime(&t.tv);
+ }
*mp = sbcreatecontrol((caddr_t) &t.tv, sizeof(t.tv),
SCM_TIMESTAMP, SOL_SOCKET);
- if (*mp)
+ if (*mp != NULL) {
mp = &(*mp)->m_next;
+ stamped = true;
+ }
break;
case SO_TS_BINTIME:
- bintime(&t.bt);
+ if ((m->m_flags & (M_PKTHDR | M_TSTMP)) == (M_PKTHDR |
+ M_TSTMP)) {
+ mbuf_tstmp2timespec(m, &ts1);
+ timespec2bintime(&ts1, &t.bt);
+ getboottimebin(&boottimebin);
+ bintime_add(&t.bt, &boottimebin);
+ } else {
+ bintime(&t.bt);
+ }
*mp = sbcreatecontrol((caddr_t)&t.bt, sizeof(t.bt),
SCM_BINTIME, SOL_SOCKET);
- if (*mp)
+ if (*mp != NULL) {
mp = &(*mp)->m_next;
+ stamped = true;
+ }
break;
case SO_TS_REALTIME:
- nanotime(&t.ts);
+ if ((m->m_flags & (M_PKTHDR | M_TSTMP)) == (M_PKTHDR |
+ M_TSTMP)) {
+ mbuf_tstmp2timespec(m, &t.ts);
+ getboottimebin(&boottimebin);
+ bintime2timespec(&boottimebin, &ts1);
+ timespecadd(&t.ts, &ts1, &t.ts);
+ } else {
+ nanotime(&t.ts);
+ }
*mp = sbcreatecontrol((caddr_t)&t.ts, sizeof(t.ts),
SCM_REALTIME, SOL_SOCKET);
- if (*mp)
+ if (*mp != NULL) {
mp = &(*mp)->m_next;
+ stamped = true;
+ }
break;
case SO_TS_MONOTONIC:
- nanouptime(&t.ts);
+ if ((m->m_flags & (M_PKTHDR | M_TSTMP)) == (M_PKTHDR |
+ M_TSTMP))
+ mbuf_tstmp2timespec(m, &t.ts);
+ else
+ nanouptime(&t.ts);
*mp = sbcreatecontrol((caddr_t)&t.ts, sizeof(t.ts),
SCM_MONOTONIC, SOL_SOCKET);
- if (*mp)
+ if (*mp != NULL) {
mp = &(*mp)->m_next;
+ stamped = true;
+ }
break;
default:
panic("unknown (corrupted) so_ts_clock");
}
+ if (stamped && (m->m_flags & (M_PKTHDR | M_TSTMP)) ==
+ (M_PKTHDR | M_TSTMP)) {
+ struct sock_timestamp_info sti;
+
+ bzero(&sti, sizeof(sti));
+ sti.st_info_flags = ST_INFO_HW;
+ if ((m->m_flags & M_TSTMP_HPREC) != 0)
+ sti.st_info_flags |= ST_INFO_HW_HPREC;
+ *mp = sbcreatecontrol((caddr_t)&sti, sizeof(sti),
+ SCM_TIME_INFO, SOL_SOCKET);
+ if (*mp != NULL)
+ mp = &(*mp)->m_next;
+ }
}
#endif