Subject: Re: linux emul & net config
To: None <port-i386@netbsd.org>
From: Christos Zoulas <christos@zoulas.com>
List: port-i386
Date: 11/29/2002 00:30:09
In article <20021128234434.127CE7B1@starfruit.itojun.org>,
Jun-ichiro itojun Hagino <tech-net@netbsd.org> wrote:
>>>> >From the pkg MESSAGE:
>>>>         Please note that if you have INET6 enabled in your kernel, you
>>>>         will need to set net.inet6.ip6.v6only = 0, using sysctl(8).
>>	i will try to do something about it.  (let linux emulation layer
>>	handle it)
>
>	by default, linux AF_INET6 socket accepts IPv4 traffic via IPv4 mapped
>	address.  netbsd disables it by default.
>	the following diff should automagically configures linux-emulation
>	sockets to accept IPv4 traffic via IPv4 mapped address.
>
>	i'm not an emulation guy, so i need someone to review this.
>	specifically error handling.
>
>itojun
>
>
>Index: linux_socket.c
>===================================================================
>RCS file: /cvsroot/syssrc/sys/compat/linux/common/linux_socket.c,v
>retrieving revision 1.39
>diff -u -r1.39 linux_socket.c
>--- linux_socket.c	2002/05/12 18:30:32	1.39
>+++ linux_socket.c	2002/11/28 23:42:27
>@@ -215,13 +215,33 @@
> 		syscallarg(int) protocol;
> 	} */ *uap = v;
> 	struct sys_socket_args bsa;
>+	int s;
> 
> 	SCARG(&bsa, protocol) = SCARG(uap, protocol);
> 	SCARG(&bsa, type) = SCARG(uap, type);
> 	SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain));
> 	if (SCARG(&bsa, domain) == -1)
> 		return EINVAL;
>-	return sys_socket(p, &bsa, retval);
>+	s = sys_socket(p, &bsa, retval);
>+	if (SCARG(&bsa, protocol) == PF_INET6) {
>+		struct sys_setsockopt_args bsoa;
>+		struct sys_close_args bca;
>+		int error;
>+		const int off = 0;
>+
>+		SCARG(&bsoa, s) = s;
>+		SCARG(&bsoa, level) = IPPROTO_IPV6;
>+		SCARG(&bsoa, name) = IPV6_V6ONLY;
>+		SCARG(&bsoa, val) = &off;
>+		SCARG(&bsoa, valsize) = sizeof(off);

Val needs to point to a userland buffer. Like:

		caddr_t *sg = stackgap_init(p, 0);
		SCARG(&bsoa, val) = stackgap_alloc(p, &sg, sizeof(off));
		if ((error = copyout(&off, SCARG(&bsoa, val),
		    sizeof(off))) != 0 ||
		    (error = sys_setsockopt(p, &bsoa, retval)) != 0) {

>+			SCARG(&bca, fd) = s;
>+			(void)sys_close(p, &bca, retval);
>+			return (error);
>+		}
>+	}
>+	return s;
> }
> 
> int