Subject: Re: kern/32944: Tun doesn't support ipv6 in 'normal' mode
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: DEGROOTE Arnaud <degroote@enseirb.fr>
List: netbsd-bugs
Date: 02/27/2006 19:55:02
The following reply was made to PR kern/32944; it has been noted by GNATS.
From: DEGROOTE Arnaud <degroote@enseirb.fr>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: kern/32944: Tun doesn't support ipv6 in 'normal' mode
Date: Mon, 27 Feb 2006 20:51:09 +0100
--sm4nu43k4a2Rpi4c
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: inline
On Mon, Feb 27, 2006 at 06:55:01PM +0000, Christos Zoulas wrote:
> Can you please re-send your patch as diff -u.
Sure, see the attached patch.
--
Degroote Arnaud
ENSEIRB Informatique
degroote@enseirb.fr
--sm4nu43k4a2Rpi4c
Content-Type: text/plain; charset=iso-8859-1
Content-Disposition: attachment; filename=patch_tun
Index: if_tun.c
===================================================================
RCS file: /pub/NetBSD-CVS/src/sys/net/if_tun.c,v
retrieving revision 1.79
diff -u -r1.79 if_tun.c
--- if_tun.c 5 Feb 2006 16:44:55 -0000 1.79
+++ if_tun.c 27 Feb 2006 19:18:11 -0000
@@ -52,6 +52,7 @@
#include <netinet/if_inarp.h>
#endif
+
#ifdef NS
#include <netns/ns.h>
#include <netns/ns_if.h>
@@ -345,8 +346,9 @@
/* find internet addresses and delete routes */
struct ifaddr *ifa;
IFADDR_FOREACH(ifa, ifp) {
-#ifdef INET
- if (ifa->ifa_addr->sa_family == AF_INET) {
+#if defined(INET) || defined(INET6)
+ if (ifa->ifa_addr->sa_family == AF_INET ||
+ ifa->ifa_addr->sa_family == AF_INET6) {
rtinit(ifa, (int)RTM_DELETE,
tp->tun_flags & TUN_DSTADDR
? RTF_HOST
@@ -396,6 +398,24 @@
}
}
#endif
+#ifdef INET6
+ if (ifa->ifa_addr->sa_family == AF_INET6) {
+ struct sockaddr_in6 *sin;
+
+ sin = (struct sockaddr_in6 *)ifa->ifa_addr;
+ if (!IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr))
+ tp->tun_flags |= TUN_IASET;
+
+ if (ifp->if_flags & IFF_POINTOPOINT) {
+ sin = (struct sockaddr_in6 *)ifa->ifa_dstaddr;
+ if (sin &&
+ !IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr))
+ tp->tun_flags |= TUN_DSTADDR;
+ } else
+ tp->tun_flags &= ~TUN_DSTADDR;
+ }
+#endif /* INET6 */
+
}
return;
@@ -447,6 +467,10 @@
case AF_INET:
break;
#endif
+#ifdef INET6
+ case AF_INET6:
+ break;
+#endif
default:
error = EAFNOSUPPORT;
break;
@@ -474,8 +498,9 @@
struct tun_softc *tp = ifp->if_softc;
int s;
int error;
-#ifdef INET
+#if defined(INET) || defined(INET6)
int mlen;
+ uint32_t * af;
#endif
ALTQ_DECL(struct altq_pktattr pktattr;)
@@ -519,7 +544,18 @@
goto out;
}
bcopy(dst, mtod(m0, char *), dst->sa_len);
- }
+ } else {
+ /* Prepend the adress family */
+ M_PREPEND(m0,sizeof(*af),M_DONTWAIT);
+ if (m0 == NULL) {
+ IF_DROP(&ifp->if_snd);
+ error = ENOBUFS;
+ goto out;
+ }
+ af = mtod(m0,uint32_t *);
+ *af = htonl(dst->sa_family);
+ }
+
/* FALLTHROUGH */
case AF_UNSPEC:
IFQ_ENQUEUE(&ifp->if_snd, m0, &pktattr, error);
@@ -753,6 +789,7 @@
struct ifqueue *ifq;
struct sockaddr dst;
int isr, error = 0, s, tlen, mlen;
+ uint32_t family;
s = splnet();
tp = tun_find_unit(dev);
@@ -787,9 +824,12 @@
}
}
} else {
-#ifdef INET
- dst.sa_family = AF_INET;
-#endif
+ if (uio->uio_resid < sizeof(family)){
+ error = EIO;
+ goto out0;
+ }
+ error = uiomove((caddr_t)&family,sizeof(family), uio);
+ dst.sa_family = ntohl(family);
}
if (uio->uio_resid > TUNMTU) {
@@ -854,7 +894,7 @@
#if NBPFILTER > 0
if (ifp->if_bpf)
- bpf_mtap_af(ifp->if_bpf, AF_INET, top);
+ bpf_mtap_af(ifp->if_bpf, dst.sa_family , top);
#endif
s = splnet();
--sm4nu43k4a2Rpi4c--