... | ... |
@@ -888,6 +888,13 @@ do_ifconfig (struct tuntap *tt, |
888 | 888 |
|
889 | 889 |
#elif defined(TARGET_NETBSD) |
890 | 890 |
|
891 |
+/* whether or not NetBSD can do IPv6 can be seen by the availability of |
|
892 |
+ * the TUNSIFHEAD ioctl() - see next TARGET_NETBSD block for more details |
|
893 |
+ */ |
|
894 |
+#ifdef TUNSIFHEAD |
|
895 |
+# define NETBSD_MULTI_AF |
|
896 |
+#endif |
|
897 |
+ |
|
891 | 898 |
/* as on OpenBSD and Darwin, destroy and re-create tun0 interface |
892 | 899 |
*/ |
893 | 900 |
argv_printf (&argv, "%s %s destroy", IFCONFIG_PATH, actual ); |
... | ... |
@@ -922,6 +929,7 @@ do_ifconfig (struct tuntap *tt, |
922 | 922 |
|
923 | 923 |
if ( do_ipv6 ) |
924 | 924 |
{ |
925 |
+#ifdef NETBSD_MULTI_AF |
|
925 | 926 |
struct route_ipv6 r6; |
926 | 927 |
argv_printf (&argv, |
927 | 928 |
"%s %s inet6 %s/%d", |
... | ... |
@@ -939,6 +947,10 @@ do_ifconfig (struct tuntap *tt, |
939 | 939 |
r6.netbits = tt->netbits_ipv6; |
940 | 940 |
r6.gateway = tt->local_ipv6; |
941 | 941 |
add_route_ipv6 (&r6, tt, 0, es); |
942 |
+#else |
|
943 |
+ msg( M_INFO, "no IPv6 support for tun interfaces on NetBSD before 4.0 (if your system is newer, recompile openvpn)" ); |
|
944 |
+ tt->ipv6 = false; |
|
945 |
+#endif |
|
942 | 946 |
} |
943 | 947 |
tt->did_ifconfig = true; |
944 | 948 |
|
... | ... |
@@ -1951,46 +1963,39 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len) |
1951 | 1951 |
* NetBSD before 4.0 does not support IPv6 on tun out of the box, |
1952 | 1952 |
* but there exists a patch (sys/net/if_tun.c, 1.79->1.80, see PR 32944). |
1953 | 1953 |
* |
1954 |
- * When this patch is applied, only two things are left to openvpn: |
|
1955 |
- * 1. Activate multicasting (this has already been done |
|
1956 |
- * before by the kernel, but we make sure that nobody |
|
1957 |
- * has deactivated multicasting inbetween. |
|
1958 |
- * 2. Deactivate "link layer mode" (otherwise NetBSD |
|
1959 |
- * prepends the address family to the packet, and we |
|
1960 |
- * would run into the same trouble as with OpenBSD. |
|
1954 |
+ * NetBSD 4.0 and up do, but we need to put the tun interface into |
|
1955 |
+ * "multi_af" mode, which will prepend the address family to all packets |
|
1956 |
+ * (same as OpenBSD and FreeBSD). If this is not enabled, the kernel |
|
1957 |
+ * silently drops all IPv6 packets on output and gets confused on input. |
|
1961 | 1958 |
* |
1962 |
- * ... unfortunately, it doesn't work that way. If TUN_IFHEAD is disabled |
|
1963 |
- * ("no prepending of the AF"), then the kernel code just drops IPv6 packets |
|
1964 |
- * on output, and gets confused on input. |
|
1959 |
+ * On earlier versions, multi_af is not available at all, so we have |
|
1960 |
+ * two different NetBSD code variants here :-( |
|
1965 | 1961 |
* |
1966 |
- * So we have to do it the same way as FreeBSD and OpenBSD do it |
|
1967 |
- * (and we really should merge FreeBSD, NetBSD and OpenBSD together) |
|
1968 | 1962 |
*/ |
1969 | 1963 |
|
1970 |
-static inline int |
|
1971 |
-netbsd_modify_read_write_return (int len) |
|
1972 |
-{ |
|
1973 |
- if (len > 0) |
|
1974 |
- return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0; |
|
1975 |
- else |
|
1976 |
- return len; |
|
1977 |
-} |
|
1978 |
- |
|
1979 | 1964 |
void |
1980 | 1965 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
1981 | 1966 |
{ |
1967 |
+#ifdef NETBSD_MULTI_AF |
|
1982 | 1968 |
open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt); |
1969 |
+#else |
|
1970 |
+ open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt); |
|
1971 |
+#endif |
|
1972 |
+ |
|
1983 | 1973 |
if (tt->fd >= 0) |
1984 | 1974 |
{ |
1985 | 1975 |
int i = IFF_POINTOPOINT|IFF_MULTICAST; |
1986 | 1976 |
ioctl (tt->fd, TUNSIFMODE, &i); /* multicast on */ |
1987 | 1977 |
i = 0; |
1988 | 1978 |
ioctl (tt->fd, TUNSLMODE, &i); /* link layer mode off */ |
1979 |
+ |
|
1980 |
+#ifdef NETBSD_MULTI_AF |
|
1989 | 1981 |
i = 1; |
1990 | 1982 |
if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) /* multi-af mode on */ |
1991 | 1983 |
{ |
1992 | 1984 |
msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno)); |
1993 | 1985 |
} |
1986 |
+#endif |
|
1994 | 1987 |
} |
1995 | 1988 |
} |
1996 | 1989 |
|
... | ... |
@@ -2007,6 +2012,17 @@ close_tun (struct tuntap *tt) |
2007 | 2007 |
} |
2008 | 2008 |
} |
2009 | 2009 |
|
2010 |
+#ifdef NETBSD_MULTI_AF |
|
2011 |
+ |
|
2012 |
+static inline int |
|
2013 |
+netbsd_modify_read_write_return (int len) |
|
2014 |
+{ |
|
2015 |
+ if (len > 0) |
|
2016 |
+ return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0; |
|
2017 |
+ else |
|
2018 |
+ return len; |
|
2019 |
+} |
|
2020 |
+ |
|
2010 | 2021 |
int |
2011 | 2022 |
write_tun (struct tuntap* tt, uint8_t *buf, int len) |
2012 | 2023 |
{ |
... | ... |
@@ -2053,6 +2069,21 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len) |
2053 | 2053 |
return read (tt->fd, buf, len); |
2054 | 2054 |
} |
2055 | 2055 |
|
2056 |
+#else /* not NETBSD_MULTI_AF -> older code, IPv4 only */ |
|
2057 |
+ |
|
2058 |
+int |
|
2059 |
+write_tun (struct tuntap* tt, uint8_t *buf, int len) |
|
2060 |
+{ |
|
2061 |
+ return write (tt->fd, buf, len); |
|
2062 |
+} |
|
2063 |
+ |
|
2064 |
+int |
|
2065 |
+read_tun (struct tuntap* tt, uint8_t *buf, int len) |
|
2066 |
+{ |
|
2067 |
+ return read (tt->fd, buf, len); |
|
2068 |
+} |
|
2069 |
+#endif /* NETBSD_MULTI_AF */ |
|
2070 |
+ |
|
2056 | 2071 |
#elif defined(TARGET_FREEBSD) |
2057 | 2072 |
|
2058 | 2073 |
static inline int |