if_tun.c revision 20559
1263367Semaste/*	$NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $	*/
2254721Semaste
3254721Semaste/*
4254721Semaste * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
5254721Semaste * Nottingham University 1987.
6254721Semaste *
7254721Semaste * This source may be freely distributed, however I would be interested
8254721Semaste * in any changes that are made.
9254721Semaste *
10254721Semaste * This driver takes packets off the IP i/f and hands them up to a
11254721Semaste * user process to have it's wicked way with. This driver has it's
12254721Semaste * roots in a similar driver written by Phil Cockcroft (formerly) at
13254721Semaste * UCL. This driver is based much more on read/write/select mode of
14254721Semaste * operation though.
15254721Semaste */
16269024Semaste
17254721Semaste#include "tun.h"
18254721Semaste#if NTUN > 0
19263363Semaste
20263363Semaste#include <sys/param.h>
21269024Semaste#include <sys/proc.h>
22269024Semaste#include <sys/systm.h>
23263363Semaste#include <sys/mbuf.h>
24263363Semaste#include <sys/buf.h>
25254721Semaste#include <sys/protosw.h>
26254721Semaste#include <sys/socket.h>
27254721Semaste#include <sys/ioctl.h>
28254721Semaste#include <sys/errno.h>
29254721Semaste#include <sys/syslog.h>
30254721Semaste#include <sys/select.h>
31254721Semaste#include <sys/file.h>
32254721Semaste#include <sys/signalvar.h>
33254721Semaste#include <sys/kernel.h>
34254721Semaste#include <sys/sysctl.h>
35254721Semaste#ifdef DEVFS
36254721Semaste#include <sys/devfsext.h>
37254721Semaste#endif /*DEVFS*/
38254721Semaste#include <sys/conf.h>
39254721Semaste
40254721Semaste#include <net/if.h>
41254721Semaste#include <net/netisr.h>
42254721Semaste#include <net/route.h>
43254721Semaste
44254721Semaste#ifdef INET
45254721Semaste#include <netinet/in.h>
46254721Semaste#include <netinet/in_systm.h>
47254721Semaste#include <netinet/in_var.h>
48254721Semaste#include <netinet/ip.h>
49254721Semaste#include <netinet/if_ether.h>
50254721Semaste#endif
51254721Semaste
52254721Semaste#ifdef NS
53254721Semaste#include <netns/ns.h>
54254721Semaste#include <netns/ns_if.h>
55254721Semaste#endif
56254721Semaste
57254721Semaste#include "bpfilter.h"
58254721Semaste#if NBPFILTER > 0
59254721Semaste#include <sys/time.h>
60254721Semaste#include <net/bpf.h>
61254721Semaste#endif
62254721Semaste
63254721Semaste#include <net/if_tun.h>
64254721Semaste
65254721Semastestatic void tunattach __P((void *));
66254721SemastePSEUDO_SET(tunattach, if_tun);
67254721Semaste
68254721Semaste#define TUNDEBUG	if (tundebug) printf
69254721Semastestatic int tundebug = 0;
70254721SemasteSYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
71254721Semaste
72254721Semastestatic struct tun_softc tunctl[NTUN];
73254721Semaste
74254721Semastestatic int tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *,
75254721Semaste	    struct rtentry *rt));
76254721Semastestatic int tunifioctl __P((struct ifnet *, int, caddr_t));
77254721Semastestatic int tuninit __P((int));
78254721Semaste
79254721Semastestatic	d_open_t	tunopen;
80254721Semastestatic	d_close_t	tunclose;
81254721Semastestatic	d_read_t	tunread;
82269024Semastestatic	d_write_t	tunwrite;
83269024Semastestatic	d_ioctl_t	tunioctl;
84269024Semastestatic	d_select_t	tunselect;
85269024Semaste
86269024Semaste#define CDEV_MAJOR 52
87254721Semastestatic struct cdevsw tun_cdevsw = {
88254721Semaste	tunopen,	tunclose,	tunread,	tunwrite,
89254721Semaste	tunioctl,	nullstop,	noreset,	nodevtotty,
90254721Semaste	tunselect,	nommap,		nostrategy,	"tun",	NULL,	-1
91263363Semaste};
92263363Semaste
93263363Semaste
94263363Semastestatic tun_devsw_installed = 0;
95263363Semaste#ifdef	DEVFS
96263363Semastestatic	void	*tun_devfs_token[NTUN];
97269024Semaste#endif
98269024Semaste
99269024Semastestatic void
100269024Semastetunattach(dummy)
101269024Semaste	void *dummy;
102263363Semaste{
103263363Semaste	register int i;
104263363Semaste	struct ifnet *ifp;
105263363Semaste	dev_t dev;
106263363Semaste
107263363Semaste	if ( tun_devsw_installed )
108263363Semaste		return;
109254721Semaste	dev = makedev(CDEV_MAJOR, 0);
110254721Semaste	cdevsw_add(&dev, &tun_cdevsw, NULL);
111254721Semaste	tun_devsw_installed = 1;
112254721Semaste	for ( i = 0; i < NTUN; i++ ) {
113269024Semaste#ifdef DEVFS
114269024Semaste		tun_devfs_token[i] = devfs_add_devswf(&tun_cdevsw, i, DV_CHR,
115269024Semaste						      UID_UUCP, GID_DIALER,
116269024Semaste						      0600, "tun%d", i);
117254721Semaste#endif
118254721Semaste		tunctl[i].tun_flags = TUN_INITED;
119254721Semaste
120254721Semaste		ifp = &tunctl[i].tun_if;
121254721Semaste		ifp->if_unit = i;
122254721Semaste		ifp->if_name = "tun";
123254721Semaste		ifp->if_mtu = TUNMTU;
124254721Semaste		ifp->if_ioctl = tunifioctl;
125254721Semaste		ifp->if_output = tunoutput;
126254721Semaste		ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
127254721Semaste		ifp->if_snd.ifq_maxlen = ifqmaxlen;
128254721Semaste		ifp->if_collisions = 0;
129254721Semaste		ifp->if_ierrors = 0;
130254721Semaste		ifp->if_oerrors = 0;
131254721Semaste		ifp->if_ipackets = 0;
132254721Semaste		ifp->if_opackets = 0;
133254721Semaste		if_attach(ifp);
134254721Semaste#if NBPFILTER > 0
135254721Semaste		bpfattach(ifp, DLT_NULL, sizeof(u_int));
136254721Semaste#endif
137254721Semaste	}
138254721Semaste}
139254721Semaste
140254721Semaste/*
141254721Semaste * tunnel open - must be superuser & the device must be
142254721Semaste * configured in
143254721Semaste */
144254721Semastestatic	int
145254721Semastetunopen(dev, flag, mode, p)
146254721Semaste	dev_t	dev;
147254721Semaste	int	flag, mode;
148254721Semaste	struct proc *p;
149254721Semaste{
150254721Semaste	struct ifnet	*ifp;
151254721Semaste	struct tun_softc *tp;
152254721Semaste	register int	unit, error;
153254721Semaste
154254721Semaste	error = suser(p->p_ucred, &p->p_acflag);
155254721Semaste	if (error)
156254721Semaste		return (error);
157269024Semaste
158254721Semaste	if ((unit = minor(dev)) >= NTUN)
159254721Semaste		return (ENXIO);
160254721Semaste	tp = &tunctl[unit];
161254721Semaste	if (tp->tun_flags & TUN_OPEN)
162254721Semaste		return EBUSY;
163254721Semaste	ifp = &tp->tun_if;
164254721Semaste	tp->tun_flags |= TUN_OPEN;
165254721Semaste	TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit);
166254721Semaste	return (0);
167254721Semaste}
168254721Semaste
169254721Semaste/*
170254721Semaste * tunclose - close the device - mark i/f down & delete
171269024Semaste * routing info
172269024Semaste */
173269024Semastestatic	int
174269024Semastetunclose(dev_t dev, int foo, int bar, struct proc *p)
175269024Semaste{
176269024Semaste	register int	unit = minor(dev), s;
177269024Semaste	struct tun_softc *tp = &tunctl[unit];
178269024Semaste	struct ifnet	*ifp = &tp->tun_if;
179269024Semaste	struct mbuf	*m;
180269024Semaste
181269024Semaste	tp->tun_flags &= ~TUN_OPEN;
182269024Semaste
183254721Semaste	/*
184254721Semaste	 * junk all pending output
185254721Semaste	 */
186254721Semaste	do {
187269024Semaste		s = splimp();
188269024Semaste		IF_DEQUEUE(&ifp->if_snd, m);
189269024Semaste		splx(s);
190269024Semaste		if (m)
191269024Semaste			m_freem(m);
192269024Semaste	} while (m);
193269024Semaste
194269024Semaste	if (ifp->if_flags & IFF_UP) {
195269024Semaste		s = splimp();
196254721Semaste		if_down(ifp);
197254721Semaste		if (ifp->if_flags & IFF_RUNNING) {
198254721Semaste		    /* find internet addresses and delete routes */
199254721Semaste		    register struct ifaddr *ifa;
200254721Semaste		    for (ifa = ifp->if_addrhead.tqh_first; ifa;
201254721Semaste			 ifa = ifa->ifa_link.tqe_next) {
202254721Semaste			if (ifa->ifa_addr->sa_family == AF_INET) {
203254721Semaste			    rtinit(ifa, (int)RTM_DELETE,
204254721Semaste				   tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
205254721Semaste			}
206254721Semaste		    }
207254721Semaste		}
208254721Semaste		splx(s);
209269024Semaste	}
210254721Semaste	tp->tun_pgrp = 0;
211254721Semaste	selwakeup(&tp->tun_rsel);
212254721Semaste
213254721Semaste	TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit);
214254721Semaste	return (0);
215254721Semaste}
216254721Semaste
217254721Semastestatic int
218254721Semastetuninit(unit)
219254721Semaste	int	unit;
220254721Semaste{
221263363Semaste	struct tun_softc *tp = &tunctl[unit];
222263363Semaste	struct ifnet	*ifp = &tp->tun_if;
223263363Semaste	register struct ifaddr *ifa;
224254721Semaste
225263363Semaste	TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit);
226254721Semaste
227254721Semaste	ifp->if_flags |= IFF_UP | IFF_RUNNING;
228254721Semaste	microtime(&ifp->if_lastchange);
229254721Semaste
230254721Semaste	for (ifa = ifp->if_addrhead.tqh_first; ifa;
231269024Semaste	     ifa = ifa->ifa_link.tqe_next)
232254721Semaste		if (ifa->ifa_addr->sa_family == AF_INET) {
233254721Semaste		    struct sockaddr_in *si;
234254721Semaste
235254721Semaste		    si = (struct sockaddr_in *)ifa->ifa_addr;
236254721Semaste		    if (si && si->sin_addr.s_addr)
237254721Semaste			    tp->tun_flags |= TUN_IASET;
238254721Semaste
239254721Semaste		    si = (struct sockaddr_in *)ifa->ifa_dstaddr;
240254721Semaste		    if (si && si->sin_addr.s_addr)
241254721Semaste			    tp->tun_flags |= TUN_DSTADDR;
242254721Semaste		}
243254721Semaste
244254721Semaste	return 0;
245254721Semaste}
246254721Semaste
247254721Semaste/*
248254721Semaste * Process an ioctl request.
249254721Semaste */
250254721Semasteint
251254721Semastetunifioctl(ifp, cmd, data)
252254721Semaste	struct ifnet *ifp;
253254721Semaste	int	cmd;
254254721Semaste	caddr_t	data;
255254721Semaste{
256254721Semaste	register struct ifreq *ifr = (struct ifreq *)data;
257254721Semaste	int		error = 0, s;
258254721Semaste
259254721Semaste	s = splimp();
260254721Semaste	switch(cmd) {
261254721Semaste	case SIOCSIFADDR:
262254721Semaste		tuninit(ifp->if_unit);
263254721Semaste		TUNDEBUG("%s%d: address set\n",
264254721Semaste			 ifp->if_name, ifp->if_unit);
265254721Semaste		break;
266254721Semaste	case SIOCSIFDSTADDR:
267254721Semaste		tuninit(ifp->if_unit);
268254721Semaste		TUNDEBUG("%s%d: destination address set\n",
269254721Semaste			 ifp->if_name, ifp->if_unit);
270254721Semaste		break;
271254721Semaste	case SIOCSIFMTU:
272254721Semaste		ifp->if_mtu = ifr->ifr_mtu;
273263367Semaste		TUNDEBUG("%s%d: mtu set\n",
274263367Semaste			 ifp->if_name, ifp->if_unit);
275263367Semaste		break;
276263367Semaste	case SIOCADDMULTI:
277263367Semaste	case SIOCDELMULTI:
278254721Semaste		if (ifr == 0) {
279254721Semaste			error = EAFNOSUPPORT;		/* XXX */
280263363Semaste			break;
281254721Semaste		}
282254721Semaste		switch (ifr->ifr_addr.sa_family) {
283263363Semaste
284263363Semaste#ifdef INET
285263363Semaste		case AF_INET:
286254721Semaste			break;
287254721Semaste#endif
288254721Semaste
289254721Semaste		default:
290263367Semaste			error = EAFNOSUPPORT;
291263367Semaste			break;
292263367Semaste		}
293263367Semaste		break;
294263367Semaste
295263367Semaste
296263367Semaste	default:
297263367Semaste		error = EINVAL;
298263367Semaste	}
299254721Semaste	splx(s);
300254721Semaste	return (error);
301254721Semaste}
302254721Semaste
303254721Semaste/*
304254721Semaste * tunoutput - queue packets from higher level ready to put out.
305254721Semaste */
306254721Semasteint
307254721Semastetunoutput(ifp, m0, dst, rt)
308254721Semaste	struct ifnet   *ifp;
309269024Semaste	struct mbuf    *m0;
310269024Semaste	struct sockaddr *dst;
311269024Semaste	struct rtentry *rt;
312269024Semaste{
313254721Semaste	struct tun_softc *tp = &tunctl[ifp->if_unit];
314254721Semaste	struct proc	*p;
315254721Semaste	int		s;
316254721Semaste
317263363Semaste	TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit);
318263363Semaste
319263363Semaste	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
320263363Semaste		TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
321263363Semaste			  ifp->if_unit, tp->tun_flags);
322263363Semaste		m_freem (m0);
323263363Semaste		return EHOSTDOWN;
324263363Semaste	}
325263363Semaste
326263363Semaste#if NBPFILTER > 0
327263363Semaste	/* BPF write needs to be handled specially */
328263367Semaste	if (dst->sa_family == AF_UNSPEC) {
329263363Semaste		dst->sa_family = *(mtod(m0, int *));
330263363Semaste		m0->m_len -= sizeof(int);
331263363Semaste		m0->m_pkthdr.len -= sizeof(int);
332263363Semaste		m0->m_data += sizeof(int);
333263363Semaste	}
334263363Semaste
335263363Semaste	if (ifp->if_bpf) {
336263363Semaste		/*
337263363Semaste		 * We need to prepend the address family as
338263363Semaste		 * a four byte field.  Cons up a dummy header
339263363Semaste		 * to pacify bpf.  This is safe because bpf
340263363Semaste		 * will only read from the mbuf (i.e., it won't
341263363Semaste		 * try to free it or keep a pointer to it).
342263363Semaste		 */
343263363Semaste		struct mbuf m;
344263363Semaste		u_int af = dst->sa_family;
345263363Semaste
346263363Semaste		m.m_next = m0;
347263363Semaste		m.m_len = 4;
348263363Semaste		m.m_data = (char *)&af;
349263363Semaste
350263363Semaste		bpf_mtap(ifp, &m);
351263363Semaste	}
352263363Semaste#endif
353263367Semaste
354263363Semaste	switch(dst->sa_family) {
355263363Semaste#ifdef INET
356263363Semaste	case AF_INET:
357263363Semaste		s = splimp();
358263363Semaste		if (IF_QFULL(&ifp->if_snd)) {
359263363Semaste			IF_DROP(&ifp->if_snd);
360263363Semaste			m_freem(m0);
361263363Semaste			splx(s);
362263363Semaste			ifp->if_collisions++;
363263363Semaste			return (ENOBUFS);
364254721Semaste		}
365254721Semaste		ifp->if_obytes += m0->m_pkthdr.len;
366254721Semaste		IF_ENQUEUE(&ifp->if_snd, m0);
367254721Semaste		splx(s);
368269024Semaste		ifp->if_opackets++;
369254721Semaste		break;
370269024Semaste#endif
371269024Semaste	default:
372254721Semaste		m_freem(m0);
373269024Semaste		return EAFNOSUPPORT;
374269024Semaste	}
375269024Semaste
376269024Semaste	if (tp->tun_flags & TUN_RWAIT) {
377269024Semaste		tp->tun_flags &= ~TUN_RWAIT;
378269024Semaste		wakeup((caddr_t)tp);
379269024Semaste	}
380269024Semaste	if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) {
381269024Semaste		if (tp->tun_pgrp > 0)
382269024Semaste			gsignal(tp->tun_pgrp, SIGIO);
383269024Semaste		else if ((p = pfind(-tp->tun_pgrp)) != 0)
384269024Semaste			psignal(p, SIGIO);
385269024Semaste	}
386254721Semaste	selwakeup(&tp->tun_rsel);
387254721Semaste	return 0;
388254721Semaste}
389254721Semaste
390254721Semaste/*
391254721Semaste * the cdevsw interface is now pretty minimal.
392254721Semaste */
393254721Semastestatic	int
394254721Semastetunioctl(dev, cmd, data, flag, p)
395254721Semaste	dev_t		dev;
396254721Semaste	int		cmd;
397254721Semaste	caddr_t		data;
398254721Semaste	int		flag;
399254721Semaste	struct proc	*p;
400254721Semaste{
401254721Semaste	int		unit = minor(dev), s;
402254721Semaste	struct tun_softc *tp = &tunctl[unit];
403254721Semaste 	struct tuninfo *tunp;
404254721Semaste
405254721Semaste	switch (cmd) {
406254721Semaste 	case TUNSIFINFO:
407254721Semaste 	        tunp = (struct tuninfo *)data;
408254721Semaste 		tp->tun_if.if_mtu = tunp->mtu;
409254721Semaste 		tp->tun_if.if_type = tunp->type;
410254721Semaste 		tp->tun_if.if_baudrate = tunp->baudrate;
411254721Semaste 		break;
412254721Semaste 	case TUNGIFINFO:
413254721Semaste 		tunp = (struct tuninfo *)data;
414254721Semaste 		tunp->mtu = tp->tun_if.if_mtu;
415254721Semaste 		tunp->type = tp->tun_if.if_type;
416254721Semaste 		tunp->baudrate = tp->tun_if.if_baudrate;
417254721Semaste 		break;
418254721Semaste	case TUNSDEBUG:
419254721Semaste		tundebug = *(int *)data;
420254721Semaste		break;
421254721Semaste	case TUNGDEBUG:
422254721Semaste		*(int *)data = tundebug;
423254721Semaste		break;
424254721Semaste	case FIONBIO:
425254721Semaste		if (*(int *)data)
426254721Semaste			tp->tun_flags |= TUN_NBIO;
427254721Semaste		else
428254721Semaste			tp->tun_flags &= ~TUN_NBIO;
429254721Semaste		break;
430254721Semaste	case FIOASYNC:
431254721Semaste		if (*(int *)data)
432254721Semaste			tp->tun_flags |= TUN_ASYNC;
433254721Semaste		else
434254721Semaste			tp->tun_flags &= ~TUN_ASYNC;
435254721Semaste		break;
436254721Semaste	case FIONREAD:
437254721Semaste		s = splimp();
438254721Semaste		if (tp->tun_if.if_snd.ifq_head) {
439254721Semaste			struct mbuf *mb = tp->tun_if.if_snd.ifq_head;
440254721Semaste			for( *(int *)data = 0; mb != 0; mb = mb->m_next)
441254721Semaste				*(int *)data += mb->m_len;
442254721Semaste		} else
443254721Semaste			*(int *)data = 0;
444254721Semaste		splx(s);
445254721Semaste		break;
446254721Semaste	case TIOCSPGRP:
447254721Semaste		tp->tun_pgrp = *(int *)data;
448254721Semaste		break;
449254721Semaste	case TIOCGPGRP:
450254721Semaste		*(int *)data = tp->tun_pgrp;
451254721Semaste		break;
452254721Semaste	default:
453254721Semaste		return (ENOTTY);
454254721Semaste	}
455254721Semaste	return (0);
456254721Semaste}
457254721Semaste
458254721Semaste/*
459254721Semaste * The cdevsw read interface - reads a packet at a time, or at
460254721Semaste * least as much of a packet as can be read.
461254721Semaste */
462254721Semastestatic	int
463254721Semastetunread(dev_t dev, struct uio *uio, int flag)
464254721Semaste{
465254721Semaste	int		unit = minor(dev);
466254721Semaste	struct tun_softc *tp = &tunctl[unit];
467254721Semaste	struct ifnet	*ifp = &tp->tun_if;
468254721Semaste	struct mbuf	*m, *m0;
469254721Semaste	int		error=0, len, s;
470254721Semaste
471254721Semaste	TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
472254721Semaste	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
473254721Semaste		TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
474254721Semaste			  ifp->if_unit, tp->tun_flags);
475254721Semaste		return EHOSTDOWN;
476254721Semaste	}
477254721Semaste
478254721Semaste	tp->tun_flags &= ~TUN_RWAIT;
479254721Semaste
480254721Semaste	s = splimp();
481254721Semaste	do {
482254721Semaste		IF_DEQUEUE(&ifp->if_snd, m0);
483254721Semaste		if (m0 == 0) {
484254721Semaste			if (tp->tun_flags & TUN_NBIO) {
485254721Semaste				splx(s);
486254721Semaste				return EWOULDBLOCK;
487254721Semaste			}
488254721Semaste			tp->tun_flags |= TUN_RWAIT;
489254721Semaste			if( error = tsleep((caddr_t)tp, PCATCH | (PZERO + 1),
490254721Semaste					"tunread", 0)) {
491254721Semaste				splx(s);
492254721Semaste				return error;
493254721Semaste			}
494254721Semaste		}
495254721Semaste	} while (m0 == 0);
496254721Semaste	splx(s);
497254721Semaste
498254721Semaste	while (m0 && uio->uio_resid > 0 && error == 0) {
499254721Semaste		len = min(uio->uio_resid, m0->m_len);
500254721Semaste		if (len == 0)
501254721Semaste			break;
502254721Semaste		error = uiomove(mtod(m0, caddr_t), len, uio);
503254721Semaste		MFREE(m0, m);
504254721Semaste		m0 = m;
505254721Semaste	}
506254721Semaste
507254721Semaste	if (m0) {
508254721Semaste		TUNDEBUG("Dropping mbuf\n");
509254721Semaste		m_freem(m0);
510254721Semaste	}
511254721Semaste	return error;
512254721Semaste}
513254721Semaste
514254721Semaste/*
515254721Semaste * the cdevsw write interface - an atomic write is a packet - or else!
516254721Semaste */
517254721Semastestatic	int
518254721Semastetunwrite(dev_t dev, struct uio *uio, int flag)
519254721Semaste{
520254721Semaste	int		unit = minor (dev);
521254721Semaste	struct ifnet	*ifp = &tunctl[unit].tun_if;
522254721Semaste	struct mbuf	*top, **mp, *m;
523254721Semaste	int		error=0, s, tlen, mlen;
524254721Semaste
525254721Semaste	TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
526254721Semaste
527254721Semaste	if (uio->uio_resid < 0 || uio->uio_resid > ifp->if_mtu) {
528254721Semaste		TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit,
529254721Semaste		    uio->uio_resid);
530254721Semaste		return EIO;
531254721Semaste	}
532254721Semaste	tlen = uio->uio_resid;
533254721Semaste
534254721Semaste	/* get a header mbuf */
535254721Semaste	MGETHDR(m, M_DONTWAIT, MT_DATA);
536254721Semaste	if (m == NULL)
537254721Semaste		return ENOBUFS;
538254721Semaste	mlen = MHLEN;
539254721Semaste
540254721Semaste	top = 0;
541254721Semaste	mp = &top;
542254721Semaste	while (error == 0 && uio->uio_resid > 0) {
543254721Semaste		m->m_len = min(mlen, uio->uio_resid);
544254721Semaste		error = uiomove(mtod (m, caddr_t), m->m_len, uio);
545254721Semaste		*mp = m;
546254721Semaste		mp = &m->m_next;
547254721Semaste		if (uio->uio_resid > 0) {
548254721Semaste			MGET (m, M_DONTWAIT, MT_DATA);
549254721Semaste			if (m == 0) {
550254721Semaste				error = ENOBUFS;
551254721Semaste				break;
552254721Semaste			}
553254721Semaste			mlen = MLEN;
554254721Semaste		}
555254721Semaste	}
556254721Semaste	if (error) {
557254721Semaste		if (top)
558254721Semaste			m_freem (top);
559254721Semaste		return error;
560254721Semaste	}
561254721Semaste
562254721Semaste	top->m_pkthdr.len = tlen;
563254721Semaste	top->m_pkthdr.rcvif = ifp;
564254721Semaste
565254721Semaste#if NBPFILTER > 0
566263363Semaste	if (ifp->if_bpf) {
567263363Semaste		/*
568263363Semaste		 * We need to prepend the address family as
569263363Semaste		 * a four byte field.  Cons up a dummy header
570263363Semaste		 * to pacify bpf.  This is safe because bpf
571254721Semaste		 * will only read from the mbuf (i.e., it won't
572254721Semaste		 * try to free it or keep a pointer to it).
573254721Semaste		 */
574254721Semaste		struct mbuf m;
575254721Semaste		u_int af = AF_INET;
576254721Semaste
577254721Semaste		m.m_next = top;
578254721Semaste		m.m_len = 4;
579263363Semaste		m.m_data = (char *)&af;
580254721Semaste
581254721Semaste		bpf_mtap(ifp, &m);
582254721Semaste	}
583254721Semaste#endif
584254721Semaste
585254721Semaste	s = splimp();
586254721Semaste	if (IF_QFULL (&ipintrq)) {
587254721Semaste		IF_DROP(&ipintrq);
588254721Semaste		splx(s);
589254721Semaste		ifp->if_collisions++;
590254721Semaste		m_freem(top);
591254721Semaste		return ENOBUFS;
592254721Semaste	}
593254721Semaste	IF_ENQUEUE(&ipintrq, top);
594254721Semaste	splx(s);
595254721Semaste	ifp->if_ibytes += tlen;
596254721Semaste	ifp->if_ipackets++;
597254721Semaste	schednetisr(NETISR_IP);
598254721Semaste	return error;
599254721Semaste}
600254721Semaste
601254721Semaste/*
602254721Semaste * tunselect - the select interface, this is only useful on reads
603254721Semaste * really. The write detect always returns true, write never blocks
604254721Semaste * anyway, it either accepts the packet or drops it.
605254721Semaste */
606254721Semastestatic	int
607254721Semastetunselect(dev_t dev, int rw, struct proc *p)
608254721Semaste{
609254721Semaste	int		unit = minor(dev), s;
610254721Semaste	struct tun_softc *tp = &tunctl[unit];
611254721Semaste	struct ifnet	*ifp = &tp->tun_if;
612254721Semaste
613254721Semaste	s = splimp();
614254721Semaste	TUNDEBUG("%s%d: tunselect\n", ifp->if_name, ifp->if_unit);
615254721Semaste
616254721Semaste	switch (rw) {
617254721Semaste	case FREAD:
618254721Semaste		if (ifp->if_snd.ifq_len > 0) {
619254721Semaste			splx(s);
620254721Semaste			TUNDEBUG("%s%d: tunselect q=%d\n", ifp->if_name,
621254721Semaste			    ifp->if_unit, ifp->if_snd.ifq_len);
622254721Semaste			return 1;
623254721Semaste		}
624254721Semaste		selrecord(p, &tp->tun_rsel);
625254721Semaste		break;
626254721Semaste	case FWRITE:
627254721Semaste		splx(s);
628254721Semaste		return 1;
629254721Semaste	}
630254721Semaste	splx(s);
631254721Semaste	TUNDEBUG("%s%d: tunselect waiting\n", ifp->if_name, ifp->if_unit);
632254721Semaste	return 0;
633254721Semaste}
634254721Semaste
635254721Semaste
636254721Semaste#endif  /* NTUN */
637254721Semaste