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--