diff options
Diffstat (limited to 'sys/netinet6/ip6_input.c')
-rw-r--r-- | sys/netinet6/ip6_input.c | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 45fd23ea6c21..99dad1e7c309 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -235,6 +235,7 @@ ip6_vnet_init(void *arg __unused) &V_ip6_auto_linklocal); TUNABLE_INT_FETCH("net.inet6.ip6.accept_rtadv", &V_ip6_accept_rtadv); TUNABLE_INT_FETCH("net.inet6.ip6.no_radr", &V_ip6_no_radr); + TUNABLE_BOOL_FETCH("net.inet6.ip6.use_stableaddr", &V_ip6_use_stableaddr); CK_STAILQ_INIT(&V_in6_ifaddrhead); V_in6_ifaddrhashtbl = hashinit(IN6ADDR_NHASH, M_IFADDR, @@ -1197,8 +1198,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; @@ -1206,47 +1207,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)) { |