Subject: Re: CVS commit: syssrc/sys/compat/linux/common (Was: Re: linux emul
To: None <itojun@netbsd.org>
From: Jaromir Dolecek <jdolecek@netbsd.org>
List: tech-kern
Date: 11/29/2002 12:04:47
I think the committed change isn't correct (did not really test yet, just
looking at the sources). Return value of sys_socket() function is
errno, not the descriptor. The descriptor is in *retval. Also, I
think it's not necessary to close the descriptor and return EINVAL
if the V6ONLY setsockopt call fails. AFAICS, the code with the change
currently always fails, and closes stdin.
Following is refined version of what was committed. It only
tries to setup the socket option if sys_socket() call succeeded
and when the sysctl net.inet6.ip6.v6only is set to 1. It also
calls sosetopt() directly, rather than using stackgap. It ignores
any error in sosetopt(), since the error wouldn't be fatal.
This was not really tested yet; I'll try it with netscape7
pkg to confirm it works fine with the change, and commit tomorrow
unless someone would object to it.
Jaromir
Index: linux_socket.c
===================================================================
RCS file: /cvsroot/syssrc/sys/compat/linux/common/linux_socket.c,v
retrieving revision 1.41
diff -u -p -r1.41 linux_socket.c
--- linux_socket.c 2002/11/29 01:34:55 1.41
+++ linux_socket.c 2002/11/29 10:58:41
@@ -80,6 +80,11 @@ __KERNEL_RCSID(0, "$NetBSD: linux_socket
#include <sys/syscallargs.h>
+#ifdef INET6
+#include <netinet/ip6.h>
+#include <netinet6/ip6_var.h>
+#endif
+
#include <compat/linux/common/linux_types.h>
#include <compat/linux/common/linux_util.h>
#include <compat/linux/common/linux_signal.h>
@@ -215,44 +220,41 @@ linux_sys_socket(p, v, retval)
syscallarg(int) protocol;
} */ *uap = v;
struct sys_socket_args bsa;
- int s;
+ int error;
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;
- s = sys_socket(p, &bsa, retval);
+ error = sys_socket(p, &bsa, retval);
#ifdef INET6
/*
- * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by default.
- * XXX interaction with native sysctl net.inet6.ip6.v6only?
+ * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by
+ * default and some apps depend on this. So, set V6ONLY to 0
+ * for Linux apps if the sysctl value is set to 1.
*/
- if (SCARG(&bsa, domain) == PF_INET6) {
- struct sys_setsockopt_args bsoa;
- struct sys_close_args bca;
- caddr_t sg;
- const int off = 0;
-
- SCARG(&bsoa, s) = s;
- SCARG(&bsoa, level) = IPPROTO_IPV6;
- SCARG(&bsoa, name) = IPV6_V6ONLY;
- sg = stackgap_init(p, 0);
- SCARG(&bsoa, val) = stackgap_alloc(p, &sg, sizeof(off));
- SCARG(&bsoa, valsize) = sizeof(off);
- /* LINTED const cast */
- if (copyout(&off, (void *)SCARG(&bsoa, val), sizeof(off)) ||
- sys_setsockopt(p, &bsoa, retval)) {
- SCARG(&bca, fd) = s;
- sys_close(p, &bca, retval);
- *retval = -1;
- return (EINVAL); /*XXX*/
+ if (!error && ip6_v6only && SCARG(&bsa, domain) == PF_INET6) {
+ struct file *fp;
+
+ if (getsock(p->p_fd, *retval, &fp) == 0) {
+ struct mbuf *m;
+
+ m = m_get(M_WAIT, MT_SOOPTS);
+ m->m_len = sizeof(int);
+ *mtod(m, int *) = 0;
+
+ /* ignore error */
+ (void) sosetopt((struct socket *)fp->f_data,
+ IPPROTO_IPV6, IPV6_V6ONLY, m);
+
+ FILE_UNUSE(fp, p);
}
}
#endif
- return s;
+ return (error);
}
int
Jun-ichiro itojun Hagino wrote:
> Module Name: syssrc
> Committed By: itojun
> Date: Fri Nov 29 01:34:55 UTC 2002
>
> Modified Files:
> syssrc/sys/compat/linux/common: linux_socket.c
>
> Log Message:
> setsockopt(IPPROTO_IPV6, IPV6_V6ONLY, 0) for AF_INET6 sockets,
> to meet with the default behavior of linux.
> review: fvdl/christos
> XXX interactions with net.inet6.ip6.v6only?
--
Jaromir Dolecek <jdolecek@NetBSD.org> http://www.NetBSD.org/
-=- We should be mindful of the potential goal, but as the tantric -=-
-=- Buddhist masters say, ``You may notice during meditation that you -=-
-=- sometimes levitate or glow. Do not let this distract you.'' -=-