Home | History | Annotate | Line # | Download | only in net
if_tun.c revision 1.106
      1 /*	$NetBSD: if_tun.c,v 1.106 2008/04/24 15:35:30 ad Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1988, Julian Onions <jpo (at) cs.nott.ac.uk>
      5  * Nottingham University 1987.
      6  *
      7  * This source may be freely distributed, however I would be interested
      8  * in any changes that are made.
      9  *
     10  * This driver takes packets off the IP i/f and hands them up to a
     11  * user process to have its wicked way with. This driver has its
     12  * roots in a similar driver written by Phil Cockcroft (formerly) at
     13  * UCL. This driver is based much more on read/write/poll mode of
     14  * operation though.
     15  */
     16 
     17 #include <sys/cdefs.h>
     18 __KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1.106 2008/04/24 15:35:30 ad Exp $");
     19 
     20 #include "opt_inet.h"
     21 
     22 #include <sys/param.h>
     23 #include <sys/proc.h>
     24 #include <sys/systm.h>
     25 #include <sys/mbuf.h>
     26 #include <sys/buf.h>
     27 #include <sys/protosw.h>
     28 #include <sys/socket.h>
     29 #include <sys/ioctl.h>
     30 #include <sys/errno.h>
     31 #include <sys/syslog.h>
     32 #include <sys/select.h>
     33 #include <sys/poll.h>
     34 #include <sys/file.h>
     35 #include <sys/signalvar.h>
     36 #include <sys/conf.h>
     37 #include <sys/kauth.h>
     38 #include <sys/simplelock.h>
     39 #include <sys/cpu.h>
     40 
     41 #include <net/if.h>
     42 #include <net/if_types.h>
     43 #include <net/netisr.h>
     44 #include <net/route.h>
     45 
     46 
     47 #ifdef INET
     48 #include <netinet/in.h>
     49 #include <netinet/in_systm.h>
     50 #include <netinet/in_var.h>
     51 #include <netinet/ip.h>
     52 #include <netinet/if_inarp.h>
     53 #endif
     54 
     55 
     56 #include "bpfilter.h"
     57 #if NBPFILTER > 0
     58 #include <sys/time.h>
     59 #include <net/bpf.h>
     60 #endif
     61 
     62 #include <net/if_tun.h>
     63 
     64 #define TUNDEBUG	if (tundebug) printf
     65 int	tundebug = 0;
     66 
     67 extern int ifqmaxlen;
     68 void	tunattach(int);
     69 
     70 static LIST_HEAD(, tun_softc) tun_softc_list;
     71 static LIST_HEAD(, tun_softc) tunz_softc_list;
     72 static struct simplelock tun_softc_lock;
     73 
     74 static int	tun_ioctl(struct ifnet *, u_long, void *);
     75 static int	tun_output(struct ifnet *, struct mbuf *,
     76 			const struct sockaddr *, struct rtentry *rt);
     77 static int	tun_clone_create(struct if_clone *, int);
     78 static int	tun_clone_destroy(struct ifnet *);
     79 
     80 static struct if_clone tun_cloner =
     81     IF_CLONE_INITIALIZER("tun", tun_clone_create, tun_clone_destroy);
     82 
     83 static void tunattach0(struct tun_softc *);
     84 static void tuninit(struct tun_softc *);
     85 static void tun_i_softintr(void *);
     86 static void tun_o_softintr(void *);
     87 #ifdef ALTQ
     88 static void tunstart(struct ifnet *);
     89 #endif
     90 static struct tun_softc *tun_find_unit(dev_t);
     91 static struct tun_softc *tun_find_zunit(int);
     92 
     93 static dev_type_open(tunopen);
     94 static dev_type_close(tunclose);
     95 static dev_type_read(tunread);
     96 static dev_type_write(tunwrite);
     97 static dev_type_ioctl(tunioctl);
     98 static dev_type_poll(tunpoll);
     99 static dev_type_kqfilter(tunkqfilter);
    100 
    101 const struct cdevsw tun_cdevsw = {
    102 	tunopen, tunclose, tunread, tunwrite, tunioctl,
    103 	nostop, notty, tunpoll, nommap, tunkqfilter, D_OTHER,
    104 };
    105 
    106 void
    107 tunattach(int unused)
    108 {
    109 
    110 	simple_lock_init(&tun_softc_lock);
    111 	LIST_INIT(&tun_softc_list);
    112 	LIST_INIT(&tunz_softc_list);
    113 	if_clone_attach(&tun_cloner);
    114 }
    115 
    116 /*
    117  * Find driver instance from dev_t.
    118  * Call at splnet().
    119  * Returns with tp locked (if found).
    120  */
    121 static struct tun_softc *
    122 tun_find_unit(dev_t dev)
    123 {
    124 	struct tun_softc *tp;
    125 	int unit = minor(dev);
    126 
    127 	simple_lock(&tun_softc_lock);
    128 	LIST_FOREACH(tp, &tun_softc_list, tun_list)
    129 		if (unit == tp->tun_unit)
    130 			break;
    131 	if (tp)
    132 		simple_lock(&tp->tun_lock);
    133 	simple_unlock(&tun_softc_lock);
    134 
    135 	return (tp);
    136 }
    137 
    138 /*
    139  * Find zombie driver instance by unit number.
    140  * Call at splnet().
    141  * Remove tp from list and return it unlocked (if found).
    142  */
    143 static struct tun_softc *
    144 tun_find_zunit(int unit)
    145 {
    146 	struct tun_softc *tp;
    147 
    148 	simple_lock(&tun_softc_lock);
    149 	LIST_FOREACH(tp, &tunz_softc_list, tun_list)
    150 		if (unit == tp->tun_unit)
    151 			break;
    152 	if (tp)
    153 		LIST_REMOVE(tp, tun_list);
    154 	simple_unlock(&tun_softc_lock);
    155 #ifdef DIAGNOSTIC
    156 	if (tp != NULL && (tp->tun_flags & (TUN_INITED|TUN_OPEN)) != TUN_OPEN)
    157 		printf("tun%d: inconsistent flags: %x\n", unit, tp->tun_flags);
    158 #endif
    159 
    160 	return (tp);
    161 }
    162 
    163 static int
    164 tun_clone_create(struct if_clone *ifc, int unit)
    165 {
    166 	struct tun_softc *tp;
    167 
    168 	if ((tp = tun_find_zunit(unit)) == NULL) {
    169 		/* Allocate a new instance */
    170 		tp = malloc(sizeof(struct tun_softc), M_DEVBUF, M_WAITOK);
    171 		(void)memset(tp, 0, sizeof(struct tun_softc));
    172 
    173 		tp->tun_unit = unit;
    174 		simple_lock_init(&tp->tun_lock);
    175 		selinit(&tp->tun_rsel);
    176 		selinit(&tp->tun_wsel);
    177 	} else {
    178 		/* Revive tunnel instance; clear ifp part */
    179 		(void)memset(&tp->tun_if, 0, sizeof(struct ifnet));
    180 	}
    181 
    182 	(void)snprintf(tp->tun_if.if_xname, sizeof(tp->tun_if.if_xname),
    183 			"%s%d", ifc->ifc_name, unit);
    184 	tunattach0(tp);
    185 	tp->tun_flags |= TUN_INITED;
    186 	tp->tun_osih = softint_establish(SOFTINT_CLOCK, tun_o_softintr, tp);
    187 	tp->tun_isih = softint_establish(SOFTINT_CLOCK, tun_i_softintr, tp);
    188 
    189 	simple_lock(&tun_softc_lock);
    190 	LIST_INSERT_HEAD(&tun_softc_list, tp, tun_list);
    191 	simple_unlock(&tun_softc_lock);
    192 
    193 	return (0);
    194 }
    195 
    196 static void
    197 tunattach0(struct tun_softc *tp)
    198 {
    199 	struct ifnet *ifp;
    200 
    201 	ifp = &tp->tun_if;
    202 	ifp->if_softc = tp;
    203 	ifp->if_mtu = TUNMTU;
    204 	ifp->if_ioctl = tun_ioctl;
    205 	ifp->if_output = tun_output;
    206 #ifdef ALTQ
    207 	ifp->if_start = tunstart;
    208 #endif
    209 	ifp->if_flags = IFF_POINTOPOINT;
    210 	ifp->if_type = IFT_TUNNEL;
    211 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
    212 	ifp->if_collisions = 0;
    213 	ifp->if_ierrors = 0;
    214 	ifp->if_oerrors = 0;
    215 	ifp->if_ipackets = 0;
    216 	ifp->if_opackets = 0;
    217 	ifp->if_ibytes   = 0;
    218 	ifp->if_obytes   = 0;
    219 	ifp->if_dlt = DLT_NULL;
    220 	IFQ_SET_READY(&ifp->if_snd);
    221 	if_attach(ifp);
    222 	if_alloc_sadl(ifp);
    223 #if NBPFILTER > 0
    224 	bpfattach(ifp, DLT_NULL, sizeof(uint32_t));
    225 #endif
    226 }
    227 
    228 static int
    229 tun_clone_destroy(struct ifnet *ifp)
    230 {
    231 	struct tun_softc *tp = (void *)ifp;
    232 	int s, zombie = 0;
    233 
    234 	s = splnet();
    235 	simple_lock(&tun_softc_lock);
    236 	simple_lock(&tp->tun_lock);
    237 	LIST_REMOVE(tp, tun_list);
    238 	if (tp->tun_flags & TUN_OPEN) {
    239 		/* Hang on to storage until last close */
    240 		zombie = 1;
    241 		tp->tun_flags &= ~TUN_INITED;
    242 		LIST_INSERT_HEAD(&tunz_softc_list, tp, tun_list);
    243 	}
    244 	simple_unlock(&tun_softc_lock);
    245 
    246 	IF_PURGE(&ifp->if_snd);
    247 	ifp->if_flags &= ~IFF_RUNNING;
    248 
    249 	if (tp->tun_flags & TUN_RWAIT) {
    250 		tp->tun_flags &= ~TUN_RWAIT;
    251 		wakeup((void *)tp);
    252 	}
    253 	selnotify(&tp->tun_rsel, 0, 0);
    254 
    255 	simple_unlock(&tp->tun_lock);
    256 	splx(s);
    257 
    258 	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
    259 		fownsignal(tp->tun_pgid, SIGIO, POLL_HUP, 0, NULL);
    260 
    261 #if NBPFILTER > 0
    262 	bpfdetach(ifp);
    263 #endif
    264 	if_detach(ifp);
    265 
    266 	if (!zombie) {
    267 		seldestroy(&tp->tun_rsel);
    268 		seldestroy(&tp->tun_wsel);
    269 		softint_disestablish(tp->tun_osih);
    270 		softint_disestablish(tp->tun_isih);
    271 		free(tp, M_DEVBUF);
    272 	}
    273 
    274 	return (0);
    275 }
    276 
    277 /*
    278  * tunnel open - must be superuser & the device must be
    279  * configured in
    280  */
    281 static int
    282 tunopen(dev_t dev, int flag, int mode, struct lwp *l)
    283 {
    284 	struct ifnet	*ifp;
    285 	struct tun_softc *tp;
    286 	int	s, error;
    287 
    288 	if ((error = kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER,
    289 	    NULL)) != 0)
    290 		return (error);
    291 
    292 	s = splnet();
    293 	tp = tun_find_unit(dev);
    294 
    295 	if (tp == NULL) {
    296 		(void)tun_clone_create(&tun_cloner, minor(dev));
    297 		tp = tun_find_unit(dev);
    298 		if (tp == NULL) {
    299 			error = ENXIO;
    300 			goto out_nolock;
    301 		}
    302 	}
    303 
    304 	if (tp->tun_flags & TUN_OPEN) {
    305 		error = EBUSY;
    306 		goto out;
    307 	}
    308 
    309 	ifp = &tp->tun_if;
    310 	tp->tun_flags |= TUN_OPEN;
    311 	TUNDEBUG("%s: open\n", ifp->if_xname);
    312 out:
    313 	simple_unlock(&tp->tun_lock);
    314 out_nolock:
    315 	splx(s);
    316 	return (error);
    317 }
    318 
    319 /*
    320  * tunclose - close the device - mark i/f down & delete
    321  * routing info
    322  */
    323 int
    324 tunclose(dev_t dev, int flag, int mode,
    325     struct lwp *l)
    326 {
    327 	int	s;
    328 	struct tun_softc *tp;
    329 	struct ifnet	*ifp;
    330 
    331 	s = splnet();
    332 	if ((tp = tun_find_zunit(minor(dev))) != NULL) {
    333 		/* interface was "destroyed" before the close */
    334 		seldestroy(&tp->tun_rsel);
    335 		seldestroy(&tp->tun_wsel);
    336 		softint_disestablish(tp->tun_osih);
    337 		softint_disestablish(tp->tun_isih);
    338 		free(tp, M_DEVBUF);
    339 		goto out_nolock;
    340 	}
    341 
    342 	if ((tp = tun_find_unit(dev)) == NULL)
    343 		goto out_nolock;
    344 
    345 	ifp = &tp->tun_if;
    346 
    347 	tp->tun_flags &= ~TUN_OPEN;
    348 
    349 	/*
    350 	 * junk all pending output
    351 	 */
    352 	IFQ_PURGE(&ifp->if_snd);
    353 
    354 	if (ifp->if_flags & IFF_UP) {
    355 		if_down(ifp);
    356 		if (ifp->if_flags & IFF_RUNNING) {
    357 			/* find internet addresses and delete routes */
    358 			struct ifaddr *ifa;
    359 			IFADDR_FOREACH(ifa, ifp) {
    360 #if defined(INET) || defined(INET6)
    361 				if (ifa->ifa_addr->sa_family == AF_INET ||
    362 				    ifa->ifa_addr->sa_family == AF_INET6) {
    363 					rtinit(ifa, (int)RTM_DELETE,
    364 					       tp->tun_flags & TUN_DSTADDR
    365 							? RTF_HOST
    366 							: 0);
    367 				}
    368 #endif
    369 			}
    370 		}
    371 	}
    372 	tp->tun_pgid = 0;
    373 	selnotify(&tp->tun_rsel, 0, 0);
    374 
    375 	TUNDEBUG ("%s: closed\n", ifp->if_xname);
    376 	simple_unlock(&tp->tun_lock);
    377 out_nolock:
    378 	splx(s);
    379 	return (0);
    380 }
    381 
    382 /*
    383  * Call at splnet() with tp locked.
    384  */
    385 static void
    386 tuninit(struct tun_softc *tp)
    387 {
    388 	struct ifnet	*ifp = &tp->tun_if;
    389 	struct ifaddr	*ifa;
    390 
    391 	TUNDEBUG("%s: tuninit\n", ifp->if_xname);
    392 
    393 	ifp->if_flags |= IFF_UP | IFF_RUNNING;
    394 
    395 	tp->tun_flags &= ~(TUN_IASET|TUN_DSTADDR);
    396 	IFADDR_FOREACH(ifa, ifp) {
    397 #ifdef INET
    398 		if (ifa->ifa_addr->sa_family == AF_INET) {
    399 			struct sockaddr_in *sin;
    400 
    401 			sin = satosin(ifa->ifa_addr);
    402 			if (sin && sin->sin_addr.s_addr)
    403 				tp->tun_flags |= TUN_IASET;
    404 
    405 			if (ifp->if_flags & IFF_POINTOPOINT) {
    406 				sin = satosin(ifa->ifa_dstaddr);
    407 				if (sin && sin->sin_addr.s_addr)
    408 					tp->tun_flags |= TUN_DSTADDR;
    409 			}
    410 		}
    411 #endif
    412 #ifdef INET6
    413 		if (ifa->ifa_addr->sa_family == AF_INET6) {
    414 			struct sockaddr_in6 *sin;
    415 
    416 			sin = (struct sockaddr_in6 *)ifa->ifa_addr;
    417 			if (!IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr))
    418 				tp->tun_flags |= TUN_IASET;
    419 
    420 			if (ifp->if_flags & IFF_POINTOPOINT) {
    421 				sin = (struct sockaddr_in6 *)ifa->ifa_dstaddr;
    422 				if (sin &&
    423 				    !IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr))
    424 					tp->tun_flags |= TUN_DSTADDR;
    425 			} else
    426 				tp->tun_flags &= ~TUN_DSTADDR;
    427 		}
    428 #endif /* INET6 */
    429 	}
    430 
    431 	return;
    432 }
    433 
    434 /*
    435  * Process an ioctl request.
    436  */
    437 static int
    438 tun_ioctl(struct ifnet *ifp, u_long cmd, void *data)
    439 {
    440 	int		error = 0, s;
    441 	struct tun_softc *tp = (struct tun_softc *)(ifp->if_softc);
    442 	struct ifreq *ifr = data;
    443 
    444 	s = splnet();
    445 	simple_lock(&tp->tun_lock);
    446 
    447 	switch (cmd) {
    448 	case SIOCSIFADDR:
    449 		tuninit(tp);
    450 		TUNDEBUG("%s: address set\n", ifp->if_xname);
    451 		break;
    452 	case SIOCSIFDSTADDR:
    453 		tuninit(tp);
    454 		TUNDEBUG("%s: destination address set\n", ifp->if_xname);
    455 		break;
    456 	case SIOCSIFBRDADDR:
    457 		TUNDEBUG("%s: broadcast address set\n", ifp->if_xname);
    458 		break;
    459 	case SIOCSIFMTU:
    460 		if (ifr->ifr_mtu > TUNMTU || ifr->ifr_mtu < 576) {
    461 			error = EINVAL;
    462 			break;
    463 		}
    464 		TUNDEBUG("%s: interface mtu set\n", ifp->if_xname);
    465 		if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
    466 			error = 0;
    467 		break;
    468 	case SIOCADDMULTI:
    469 	case SIOCDELMULTI:
    470 		if (ifr == NULL) {
    471 	        	error = EAFNOSUPPORT;           /* XXX */
    472 			break;
    473 		}
    474 		switch (ifreq_getaddr(cmd, ifr)->sa_family) {
    475 #ifdef INET
    476 		case AF_INET:
    477 			break;
    478 #endif
    479 #ifdef INET6
    480 		case AF_INET6:
    481 			break;
    482 #endif
    483 		default:
    484 			error = EAFNOSUPPORT;
    485 			break;
    486 		}
    487 		break;
    488 	case SIOCSIFFLAGS:
    489 		break;
    490 	default:
    491 		error = EINVAL;
    492 	}
    493 
    494 	simple_unlock(&tp->tun_lock);
    495 	splx(s);
    496 	return (error);
    497 }
    498 
    499 /*
    500  * tun_output - queue packets from higher level ready to put out.
    501  */
    502 static int
    503 tun_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,
    504     struct rtentry *rt)
    505 {
    506 	struct tun_softc *tp = ifp->if_softc;
    507 	int		s;
    508 	int		error;
    509 #if defined(INET) || defined(INET6)
    510 	int		mlen;
    511 	uint32_t	*af;
    512 #endif
    513 	ALTQ_DECL(struct altq_pktattr pktattr;)
    514 
    515 	s = splnet();
    516 	simple_lock(&tp->tun_lock);
    517 	TUNDEBUG ("%s: tun_output\n", ifp->if_xname);
    518 
    519 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
    520 		TUNDEBUG ("%s: not ready 0%o\n", ifp->if_xname,
    521 			  tp->tun_flags);
    522 		m_freem (m0);
    523 		error = EHOSTDOWN;
    524 		goto out;
    525 	}
    526 
    527 	/*
    528 	 * if the queueing discipline needs packet classification,
    529 	 * do it before prepending link headers.
    530 	 */
    531 	IFQ_CLASSIFY(&ifp->if_snd, m0, dst->sa_family, &pktattr);
    532 
    533 #if NBPFILTER > 0
    534 	if (ifp->if_bpf)
    535 		bpf_mtap_af(ifp->if_bpf, dst->sa_family, m0);
    536 #endif
    537 
    538 	switch(dst->sa_family) {
    539 #ifdef INET6
    540 	case AF_INET6:
    541 #endif
    542 #ifdef INET
    543 	case AF_INET:
    544 #endif
    545 #if defined(INET) || defined(INET6)
    546 		if (tp->tun_flags & TUN_PREPADDR) {
    547 			/* Simple link-layer header */
    548 			M_PREPEND(m0, dst->sa_len, M_DONTWAIT);
    549 			if (m0 == NULL) {
    550 				IF_DROP(&ifp->if_snd);
    551 				error = ENOBUFS;
    552 				goto out;
    553 			}
    554 			bcopy(dst, mtod(m0, char *), dst->sa_len);
    555 		}
    556 
    557 		if (tp->tun_flags & TUN_IFHEAD) {
    558 			/* Prepend the address family */
    559 			M_PREPEND(m0, sizeof(*af), M_DONTWAIT);
    560 			if (m0 == NULL) {
    561 				IF_DROP(&ifp->if_snd);
    562 				error = ENOBUFS;
    563 				goto out;
    564 			}
    565 			af = mtod(m0,uint32_t *);
    566 			*af = htonl(dst->sa_family);
    567 		} else {
    568 #ifdef INET
    569 			if (dst->sa_family != AF_INET)
    570 #endif
    571 			{
    572 				m_freem(m0);
    573 				error = EAFNOSUPPORT;
    574 				goto out;
    575 			}
    576 		}
    577 		/* FALLTHROUGH */
    578 	case AF_UNSPEC:
    579 		IFQ_ENQUEUE(&ifp->if_snd, m0, &pktattr, error);
    580 		if (error) {
    581 			ifp->if_collisions++;
    582 			error = EAFNOSUPPORT;
    583 			goto out;
    584 		}
    585 		mlen = m0->m_pkthdr.len;
    586 		ifp->if_opackets++;
    587 		ifp->if_obytes += mlen;
    588 		break;
    589 #endif
    590 	default:
    591 		m_freem(m0);
    592 		error = EAFNOSUPPORT;
    593 		goto out;
    594 	}
    595 
    596 	if (tp->tun_flags & TUN_RWAIT) {
    597 		tp->tun_flags &= ~TUN_RWAIT;
    598 		wakeup((void *)tp);
    599 	}
    600 	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
    601 		softint_schedule(tp->tun_isih);
    602 
    603 	selnotify(&tp->tun_rsel, 0, 0);
    604 out:
    605 	simple_unlock(&tp->tun_lock);
    606 	splx(s);
    607 	return (0);
    608 }
    609 
    610 static void
    611 tun_i_softintr(void *cookie)
    612 {
    613 	struct tun_softc *tp = cookie;
    614 
    615 	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
    616 		fownsignal(tp->tun_pgid, SIGIO, POLL_IN, POLLIN|POLLRDNORM,
    617 		    NULL);
    618 }
    619 
    620 static void
    621 tun_o_softintr(void *cookie)
    622 {
    623 	struct tun_softc *tp = cookie;
    624 
    625 	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
    626 		fownsignal(tp->tun_pgid, SIGIO, POLL_OUT, POLLOUT|POLLWRNORM,
    627 		    NULL);
    628 }
    629 
    630 /*
    631  * the cdevsw interface is now pretty minimal.
    632  */
    633 int
    634 tunioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
    635 {
    636 	struct tun_softc *tp;
    637 	int s, error = 0;
    638 
    639 	s = splnet();
    640 	tp = tun_find_unit(dev);
    641 
    642 	/* interface was "destroyed" already */
    643 	if (tp == NULL) {
    644 		error = ENXIO;
    645 		goto out_nolock;
    646 	}
    647 
    648 	switch (cmd) {
    649 	case TUNSDEBUG:
    650 		tundebug = *(int *)data;
    651 		break;
    652 
    653 	case TUNGDEBUG:
    654 		*(int *)data = tundebug;
    655 		break;
    656 
    657 	case TUNSIFMODE:
    658 		switch (*(int *)data & (IFF_POINTOPOINT|IFF_BROADCAST)) {
    659 		case IFF_POINTOPOINT:
    660 		case IFF_BROADCAST:
    661 			if (tp->tun_if.if_flags & IFF_UP) {
    662 				error = EBUSY;
    663 				goto out;
    664 			}
    665 			tp->tun_if.if_flags &=
    666 				~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
    667 			tp->tun_if.if_flags |= *(int *)data;
    668 			break;
    669 		default:
    670 			error = EINVAL;
    671 			goto out;
    672 		}
    673 		break;
    674 
    675 	case TUNSLMODE:
    676 		if (*(int *)data) {
    677 			tp->tun_flags |= TUN_PREPADDR;
    678 			tp->tun_flags &= ~TUN_IFHEAD;
    679 		} else
    680 			tp->tun_flags &= ~TUN_PREPADDR;
    681 		break;
    682 
    683 	case TUNSIFHEAD:
    684 		if (*(int *)data) {
    685 			tp->tun_flags |= TUN_IFHEAD;
    686 			tp->tun_flags &= ~TUN_PREPADDR;
    687 		} else
    688 			tp->tun_flags &= ~TUN_IFHEAD;
    689 		break;
    690 
    691 	case TUNGIFHEAD:
    692 		*(int *)data = (tp->tun_flags & TUN_IFHEAD);
    693 		break;
    694 
    695 	case FIONBIO:
    696 		if (*(int *)data)
    697 			tp->tun_flags |= TUN_NBIO;
    698 		else
    699 			tp->tun_flags &= ~TUN_NBIO;
    700 		break;
    701 
    702 	case FIOASYNC:
    703 		if (*(int *)data)
    704 			tp->tun_flags |= TUN_ASYNC;
    705 		else
    706 			tp->tun_flags &= ~TUN_ASYNC;
    707 		break;
    708 
    709 	case FIONREAD:
    710 		if (tp->tun_if.if_snd.ifq_head)
    711 			*(int *)data = tp->tun_if.if_snd.ifq_head->m_pkthdr.len;
    712 		else
    713 			*(int *)data = 0;
    714 		break;
    715 
    716 	case TIOCSPGRP:
    717 	case FIOSETOWN:
    718 		error = fsetown(&tp->tun_pgid, cmd, data);
    719 		break;
    720 
    721 	case TIOCGPGRP:
    722 	case FIOGETOWN:
    723 		error = fgetown(tp->tun_pgid, cmd, data);
    724 		break;
    725 
    726 	default:
    727 		error = ENOTTY;
    728 	}
    729 
    730 out:
    731 	simple_unlock(&tp->tun_lock);
    732 out_nolock:
    733 	splx(s);
    734 	return (error);
    735 }
    736 
    737 /*
    738  * The cdevsw read interface - reads a packet at a time, or at
    739  * least as much of a packet as can be read.
    740  */
    741 int
    742 tunread(dev_t dev, struct uio *uio, int ioflag)
    743 {
    744 	struct tun_softc *tp;
    745 	struct ifnet	*ifp;
    746 	struct mbuf	*m, *m0;
    747 	int		error = 0, len, s, index;
    748 
    749 	s = splnet();
    750 	tp = tun_find_unit(dev);
    751 
    752 	/* interface was "destroyed" already */
    753 	if (tp == NULL) {
    754 		error = ENXIO;
    755 		goto out_nolock;
    756 	}
    757 
    758 	index = tp->tun_if.if_index;
    759 	ifp = &tp->tun_if;
    760 
    761 	TUNDEBUG ("%s: read\n", ifp->if_xname);
    762 	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
    763 		TUNDEBUG ("%s: not ready 0%o\n", ifp->if_xname, tp->tun_flags);
    764 		error = EHOSTDOWN;
    765 		goto out;
    766 	}
    767 
    768 	tp->tun_flags &= ~TUN_RWAIT;
    769 
    770 	do {
    771 		IFQ_DEQUEUE(&ifp->if_snd, m0);
    772 		if (m0 == 0) {
    773 			if (tp->tun_flags & TUN_NBIO) {
    774 				error = EWOULDBLOCK;
    775 				goto out;
    776 			}
    777 			tp->tun_flags |= TUN_RWAIT;
    778 			if (ltsleep((void *)tp, PZERO|PCATCH|PNORELOCK,
    779 					"tunread", 0, &tp->tun_lock) != 0) {
    780 				error = EINTR;
    781 				goto out_nolock;
    782 			} else {
    783 				/*
    784 				 * Maybe the interface was destroyed while
    785 				 * we were sleeping, so let's ensure that
    786 				 * we're looking at the same (valid) tun
    787 				 * interface before looping.
    788 				 */
    789 				tp = tun_find_unit(dev);
    790 				if (tp == NULL) {
    791 					error = ENXIO;
    792 					goto out_nolock;
    793 				}
    794 				if (tp->tun_if.if_index != index) {
    795 					error = ENXIO;
    796 					goto out;
    797 				}
    798 			}
    799 		}
    800 	} while (m0 == 0);
    801 
    802 	simple_unlock(&tp->tun_lock);
    803 	splx(s);
    804 
    805 	/* Copy the mbuf chain */
    806 	while (m0 && uio->uio_resid > 0 && error == 0) {
    807 		len = min(uio->uio_resid, m0->m_len);
    808 		if (len != 0)
    809 			error = uiomove(mtod(m0, void *), len, uio);
    810 		MFREE(m0, m);
    811 		m0 = m;
    812 	}
    813 
    814 	if (m0) {
    815 		TUNDEBUG("Dropping mbuf\n");
    816 		m_freem(m0);
    817 	}
    818 	if (error)
    819 		ifp->if_ierrors++;
    820 
    821 	return (error);
    822 
    823 out:
    824 	simple_unlock(&tp->tun_lock);
    825 out_nolock:
    826 	splx(s);
    827 	return (error);
    828 }
    829 
    830 /*
    831  * the cdevsw write interface - an atomic write is a packet - or else!
    832  */
    833 int
    834 tunwrite(dev_t dev, struct uio *uio, int ioflag)
    835 {
    836 	struct tun_softc *tp;
    837 	struct ifnet	*ifp;
    838 	struct mbuf	*top, **mp, *m;
    839 	struct ifqueue	*ifq;
    840 	struct sockaddr	dst;
    841 	int		isr, error = 0, s, tlen, mlen;
    842 	uint32_t	family;
    843 
    844 	s = splnet();
    845 	tp = tun_find_unit(dev);
    846 
    847 	/* interface was "destroyed" already */
    848 	if (tp == NULL) {
    849 		error = ENXIO;
    850 		goto out_nolock;
    851 	}
    852 
    853 	/* Unlock until we've got the data */
    854 	simple_unlock(&tp->tun_lock);
    855 	splx(s);
    856 
    857 	ifp = &tp->tun_if;
    858 
    859 	TUNDEBUG("%s: tunwrite\n", ifp->if_xname);
    860 
    861 	if (tp->tun_flags & TUN_PREPADDR) {
    862 		if (uio->uio_resid < sizeof(dst)) {
    863 			error = EIO;
    864 			goto out0;
    865 		}
    866 		error = uiomove((void *)&dst, sizeof(dst), uio);
    867 		if (dst.sa_len > sizeof(dst)) {
    868 			/* Duh.. */
    869 			char discard;
    870 			int n = dst.sa_len - sizeof(dst);
    871 			while (n--)
    872 				if ((error = uiomove(&discard, 1, uio)) != 0) {
    873 					goto out0;
    874 				}
    875 		}
    876 	} else if (tp->tun_flags & TUN_IFHEAD) {
    877 		if (uio->uio_resid < sizeof(family)){
    878 			error = EIO;
    879 			goto out0;
    880 		}
    881 		error = uiomove((void *)&family, sizeof(family), uio);
    882 		dst.sa_family = ntohl(family);
    883 	} else {
    884 #ifdef INET
    885 		dst.sa_family = AF_INET;
    886 #endif
    887 	}
    888 
    889 	if (uio->uio_resid > TUNMTU) {
    890 		TUNDEBUG("%s: len=%lu!\n", ifp->if_xname,
    891 		    (unsigned long)uio->uio_resid);
    892 		error = EIO;
    893 		goto out0;
    894 	}
    895 
    896 	switch (dst.sa_family) {
    897 #ifdef INET
    898 	case AF_INET:
    899 		ifq = &ipintrq;
    900 		isr = NETISR_IP;
    901 		break;
    902 #endif
    903 #ifdef INET6
    904 	case AF_INET6:
    905 		ifq = &ip6intrq;
    906 		isr = NETISR_IPV6;
    907 		break;
    908 #endif
    909 	default:
    910 		error = EAFNOSUPPORT;
    911 		goto out0;
    912 	}
    913 
    914 	tlen = uio->uio_resid;
    915 
    916 	/* get a header mbuf */
    917 	MGETHDR(m, M_DONTWAIT, MT_DATA);
    918 	if (m == NULL) {
    919 		error = ENOBUFS;
    920 		goto out0;
    921 	}
    922 	mlen = MHLEN;
    923 
    924 	top = NULL;
    925 	mp = &top;
    926 	while (error == 0 && uio->uio_resid > 0) {
    927 		m->m_len = min(mlen, uio->uio_resid);
    928 		error = uiomove(mtod(m, void *), m->m_len, uio);
    929 		*mp = m;
    930 		mp = &m->m_next;
    931 		if (error == 0 && uio->uio_resid > 0) {
    932 			MGET(m, M_DONTWAIT, MT_DATA);
    933 			if (m == NULL) {
    934 				error = ENOBUFS;
    935 				break;
    936 			}
    937 			mlen = MLEN;
    938 		}
    939 	}
    940 	if (error) {
    941 		if (top != NULL)
    942 			m_freem (top);
    943 		ifp->if_ierrors++;
    944 		goto out0;
    945 	}
    946 
    947 	top->m_pkthdr.len = tlen;
    948 	top->m_pkthdr.rcvif = ifp;
    949 
    950 #if NBPFILTER > 0
    951 	if (ifp->if_bpf)
    952 		bpf_mtap_af(ifp->if_bpf, dst.sa_family, top);
    953 #endif
    954 
    955 	s = splnet();
    956 	simple_lock(&tp->tun_lock);
    957 	if ((tp->tun_flags & TUN_INITED) == 0) {
    958 		/* Interface was destroyed */
    959 		error = ENXIO;
    960 		goto out;
    961 	}
    962 	if (IF_QFULL(ifq)) {
    963 		IF_DROP(ifq);
    964 		ifp->if_collisions++;
    965 		m_freem(top);
    966 		error = ENOBUFS;
    967 		goto out;
    968 	}
    969 
    970 	IF_ENQUEUE(ifq, top);
    971 	ifp->if_ipackets++;
    972 	ifp->if_ibytes += tlen;
    973 	schednetisr(isr);
    974 out:
    975 	simple_unlock(&tp->tun_lock);
    976 out_nolock:
    977 	splx(s);
    978 out0:
    979 	return (error);
    980 }
    981 
    982 #ifdef ALTQ
    983 /*
    984  * Start packet transmission on the interface.
    985  * when the interface queue is rate-limited by ALTQ or TBR,
    986  * if_start is needed to drain packets from the queue in order
    987  * to notify readers when outgoing packets become ready.
    988  *
    989  * Should be called at splnet.
    990  */
    991 static void
    992 tunstart(struct ifnet *ifp)
    993 {
    994 	struct tun_softc *tp = ifp->if_softc;
    995 
    996 	if (!ALTQ_IS_ENABLED(&ifp->if_snd) && !TBR_IS_ENABLED(&ifp->if_snd))
    997 		return;
    998 
    999 	simple_lock(&tp->tun_lock);
   1000 	if (!IF_IS_EMPTY(&ifp->if_snd)) {
   1001 		if (tp->tun_flags & TUN_RWAIT) {
   1002 			tp->tun_flags &= ~TUN_RWAIT;
   1003 			wakeup((void *)tp);
   1004 		}
   1005 		if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
   1006 			softint_schedule(tp->tun_osih);
   1007 
   1008 		selnotify(&tp->tun_rsel, 0, 0);
   1009 	}
   1010 	simple_unlock(&tp->tun_lock);
   1011 }
   1012 #endif /* ALTQ */
   1013 /*
   1014  * tunpoll - the poll interface, this is only useful on reads
   1015  * really. The write detect always returns true, write never blocks
   1016  * anyway, it either accepts the packet or drops it.
   1017  */
   1018 int
   1019 tunpoll(dev_t dev, int events, struct lwp *l)
   1020 {
   1021 	struct tun_softc *tp;
   1022 	struct ifnet	*ifp;
   1023 	int		s, revents = 0;
   1024 
   1025 	s = splnet();
   1026 	tp = tun_find_unit(dev);
   1027 
   1028 	/* interface was "destroyed" already */
   1029 	if (tp == NULL)
   1030 		goto out_nolock;
   1031 
   1032 	ifp = &tp->tun_if;
   1033 
   1034 	TUNDEBUG("%s: tunpoll\n", ifp->if_xname);
   1035 
   1036 	if (events & (POLLIN | POLLRDNORM)) {
   1037 		if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
   1038 			TUNDEBUG("%s: tunpoll q=%d\n", ifp->if_xname,
   1039 			    ifp->if_snd.ifq_len);
   1040 			revents |= events & (POLLIN | POLLRDNORM);
   1041 		} else {
   1042 			TUNDEBUG("%s: tunpoll waiting\n", ifp->if_xname);
   1043 			selrecord(l, &tp->tun_rsel);
   1044 		}
   1045 	}
   1046 
   1047 	if (events & (POLLOUT | POLLWRNORM))
   1048 		revents |= events & (POLLOUT | POLLWRNORM);
   1049 
   1050 	simple_unlock(&tp->tun_lock);
   1051 out_nolock:
   1052 	splx(s);
   1053 	return (revents);
   1054 }
   1055 
   1056 static void
   1057 filt_tunrdetach(struct knote *kn)
   1058 {
   1059 	struct tun_softc *tp = kn->kn_hook;
   1060 	int s;
   1061 
   1062 	s = splnet();
   1063 	SLIST_REMOVE(&tp->tun_rsel.sel_klist, kn, knote, kn_selnext);
   1064 	splx(s);
   1065 }
   1066 
   1067 static int
   1068 filt_tunread(struct knote *kn, long hint)
   1069 {
   1070 	struct tun_softc *tp = kn->kn_hook;
   1071 	struct ifnet *ifp = &tp->tun_if;
   1072 	struct mbuf *m;
   1073 	int s;
   1074 
   1075 	s = splnet();
   1076 	IF_POLL(&ifp->if_snd, m);
   1077 	if (m == NULL) {
   1078 		splx(s);
   1079 		return (0);
   1080 	}
   1081 
   1082 	for (kn->kn_data = 0; m != NULL; m = m->m_next)
   1083 		kn->kn_data += m->m_len;
   1084 
   1085 	splx(s);
   1086 	return (1);
   1087 }
   1088 
   1089 static const struct filterops tunread_filtops =
   1090 	{ 1, NULL, filt_tunrdetach, filt_tunread };
   1091 
   1092 static const struct filterops tun_seltrue_filtops =
   1093 	{ 1, NULL, filt_tunrdetach, filt_seltrue };
   1094 
   1095 int
   1096 tunkqfilter(dev_t dev, struct knote *kn)
   1097 {
   1098 	struct tun_softc *tp;
   1099 	struct klist *klist;
   1100 	int rv = 0, s;
   1101 
   1102 	s = splnet();
   1103 	tp = tun_find_unit(dev);
   1104 	if (tp == NULL)
   1105 		goto out_nolock;
   1106 
   1107 	switch (kn->kn_filter) {
   1108 	case EVFILT_READ:
   1109 		klist = &tp->tun_rsel.sel_klist;
   1110 		kn->kn_fop = &tunread_filtops;
   1111 		break;
   1112 
   1113 	case EVFILT_WRITE:
   1114 		klist = &tp->tun_rsel.sel_klist;
   1115 		kn->kn_fop = &tun_seltrue_filtops;
   1116 		break;
   1117 
   1118 	default:
   1119 		rv = EINVAL;
   1120 		goto out;
   1121 	}
   1122 
   1123 	kn->kn_hook = tp;
   1124 
   1125 	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
   1126 
   1127 out:
   1128 	simple_unlock(&tp->tun_lock);
   1129 out_nolock:
   1130 	splx(s);
   1131 	return (rv);
   1132 }
   1133