NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/57955: SO_TIMESTAMP doesn't work for ICMP6



>Number:         57955
>Category:       kern
>Synopsis:       Enabling SO_TIMESTAMP on ICMP6 socket doesn't work
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Feb 23 16:15:00 +0000 2024
>Originator:     Mouse
>Release:        Various: 4.0.1+, 5.2+, 9.1, and reportedly -current
>Organization:
	Dis-
>Environment:
	First noticed on
System: NetBSD Border.Rodents-Montreal.ORG 4.0.1 NetBSD 4.0.1 (BORDER) #0: Mon Jun 12 22:01:38 EDT 2023  mouse%Border.Rodents-Montreal.ORG@localhost:/home/mouse/kbuild/BORDER i386
Architecture: i386
Machine: i386
	Also observed on 5.2/amd64, 9.1/amd64, and, according to Martin
	Husemann on tech-net <20240223152756.GC9658%mail.duskware.de@localhost>,
	current on some unspecified architecture.
>Description:
	Enabling timestamps with setsockopt SOL_SOCKET/SO_TIMESTAMP
	doesn't work for AF_INET6/SOCK_RAW/IPPROTO_ICMPV6 sockets.  I
	suspect it will fail for other v6 sockets, but haven't tested
	it.

	"Doesn't work" here means, as far as I can tell, "is ignored as
	far as returned control messages are concerned"; with no other
	reason to generate control data, I get zero bytes of control
	data from recvmsg().
>How-To-Repeat:
	Fetch {ftp,http}://ftp.rodents-montreal.org/mouse/misc/test-icmp6.c

	Read it over, unless you trust me and the network between us to
	be non-malicious.  (It should have MD5
	801a051030b1b311c00ebdcaeac40f1e, SHA256
	07ece2c4590ff9a6d73e917a2cb071fa338dab418a110d90f5c2965c993e7f9a.)

	Build it.

	Run it (as root; it needs to create raw sockets - this is why I
	said to read it over first).

	Get "data 64, ctl 0" instead of ctl data containing a struct
	timeval.  (On my test 4.0.1 machine with the patch below, I get
	ctl 24.)
>Fix:
	This works for me on 4.0.1.  A quick glance at cvsweb makes me
	suspect something similar might work for -current.

	Even if it works, I am far from convinced this is the right
	fix.  I would not recommend committing it as-is unless someone
	who knows the v6 stack signs off on it.

	commit fcfe8180a98fae5ae07d96c291088fd147db42c6
	Author: Mouse <mouse%Rodents-Montreal.ORG@localhost>
	Date:   Fri Feb 23 10:58:18 2024 -0500
	
	    Make SO_TIMESTAMP work with ICMP6 (and other v6?) sockets.
	
	diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
	index edc09f6..4112bda 100644
	--- a/sys/netinet6/icmp6.c
	+++ b/sys/netinet6/icmp6.c
	@@ -1924,7 +1924,8 @@ icmp6_rip6_input(mp, off)
	 		if (last) {
	 			struct	mbuf *n;
	 			if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
	-				if (last->in6p_flags & IN6P_CONTROLOPTS)
	+				if ( (last->in6p_flags & IN6P_CONTROLOPTS) ||
	+				     (last->in6p_socket->so_options & SO_TIMESTAMP) )
	 					ip6_savecontrol(last, &opts, ip6, n);
	 				/* strip intermediate headers */
	 				m_adj(n, off);
	@@ -1943,7 +1944,8 @@ icmp6_rip6_input(mp, off)
	 		last = in6p;
	 	}
	 	if (last) {
	-		if (last->in6p_flags & IN6P_CONTROLOPTS)
	+		if ( (last->in6p_flags & IN6P_CONTROLOPTS) ||
	+		     (last->in6p_socket->so_options & SO_TIMESTAMP) )
	 			ip6_savecontrol(last, &opts, ip6, m);
	 		/* strip intermediate headers */
	 		m_adj(m, off);
	diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
	index 0a467e1..592de93 100644
	--- a/sys/netinet6/raw_ip6.c
	+++ b/sys/netinet6/raw_ip6.c
	@@ -217,7 +217,8 @@ rip6_input(mp, offp, proto)
	 			if (!ipsec6_in_reject(m,last)) 
	 #endif /* FAST_IPSEC */
	 			if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
	-				if (last->in6p_flags & IN6P_CONTROLOPTS)
	+				if ( (last->in6p_flags & IN6P_CONTROLOPTS) ||
	+				     (last->in6p_socket->so_options & SO_TIMESTAMP) )
	 					ip6_savecontrol(last, &opts, ip6, n);
	 				/* strip intermediate headers */
	 				m_adj(n, *offp);
	@@ -261,7 +262,8 @@ rip6_input(mp, offp, proto)
	 		} else
	 #endif /* FAST_IPSEC */
	 	if (last) {
	-		if (last->in6p_flags & IN6P_CONTROLOPTS)
	+		if ( (last->in6p_flags & IN6P_CONTROLOPTS) ||
	+		     (last->in6p_socket->so_options & SO_TIMESTAMP) )
	 			ip6_savecontrol(last, &opts, ip6, m);
	 		/* strip intermediate headers */
	 		m_adj(m, *offp);

/~\ The ASCII				  Mouse
\ / Ribbon Campaign
 X  Against HTML		mouse%rodents-montreal.org@localhost
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B



Home | Main Index | Thread Index | Old Index