Subject: Re: OpenVPN + tun(4) problem
To: None <current-users@NetBSD.org>
From: DEGROOTE Arnaud <degroote@enseirb.fr>
List: current-users
Date: 03/13/2006 09:58:40
--BOKacYhQ+x31HxR3
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline

Please try the following patch. It is not really clean and complety
untested but it may solve the issue. I will propose a better patch this
night if I have a few time. 

Note that you don't need any patch now to use tun and ipv6 on
NetBSD-current. 

-- 
Degroote Arnaud
ENSEIRB Informatique
degroote@enseirb.fr

--BOKacYhQ+x31HxR3
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename=patch_tun

--- tun.c.orig	2006-03-13 09:45:00.035515131 +0100
+++ tun.c	2006-03-13 09:51:52.532346890 +0100
@@ -1504,6 +1504,63 @@
     }
 }
 
+
+static inline int
+netbsd_modify_read_write_return (int len)
+{
+  if (len > 0)
+    return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0;
+  else
+    return len;
+}
+
+int
+write_tun (struct tuntap* tt, uint8_t *buf, int len)
+{
+  if (tt->type == DEV_TYPE_TUN)
+    {
+      uint32_t type;
+      struct iovec iv[2];
+      struct ip *iph;
+
+      iph = (struct ip *) buf;
+
+      if (tt->ipv6 && iph->ip_v == 6)
+        type = htonl (AF_INET6);
+      else 
+        type = htonl (AF_INET);
+
+      iv[0].iov_base = (char *)&type;
+      iv[0].iov_len = sizeof (type);
+      iv[1].iov_base = buf;
+      iv[1].iov_len = len;
+
+      return netbsd_modify_read_write_return (writev (tt->fd, iv, 2));
+    }
+  else
+    return write (tt->fd, buf, len);
+}
+
+int
+read_tun (struct tuntap* tt, uint8_t *buf, int len)
+{
+  if (tt->type == DEV_TYPE_TUN)
+    {
+      uint32_t type;
+      struct iovec iv[2];
+
+      iv[0].iov_base = (char *)&type;
+      iv[0].iov_len = sizeof (type);
+      iv[1].iov_base = buf;
+      iv[1].iov_len = len;
+
+      return netbsd_modify_read_write_return (readv (tt->fd, iv, 2));
+    }
+  else
+    return read (tt->fd, buf, len);
+}
+
+#if 0
 int
 write_tun (struct tuntap* tt, uint8_t *buf, int len)
 {
@@ -1515,6 +1572,7 @@
 {
     return read (tt->fd, buf, len);
 }
+#endif
 
 #elif defined(TARGET_FREEBSD)
 

--BOKacYhQ+x31HxR3--