16735Samurai/*	$NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $	*/
26735Samurai
3139823Simp/*-
46053Samurai * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
56053Samurai * Nottingham University 1987.
66053Samurai *
76053Samurai * This source may be freely distributed, however I would be interested
86053Samurai * in any changes that are made.
96053Samurai *
106053Samurai * This driver takes packets off the IP i/f and hands them up to a
1135256Sdes * user process to have its wicked way with. This driver has it's
126053Samurai * roots in a similar driver written by Phil Cockcroft (formerly) at
1329365Speter * UCL. This driver is based much more on read/write/poll mode of
146053Samurai * operation though.
1551646Sphk *
1651646Sphk * $FreeBSD$
176053Samurai */
186053Samurai
19111999Sjlemon#include "opt_atalk.h"
2032350Seivind#include "opt_inet.h"
21111999Sjlemon#include "opt_inet6.h"
22111999Sjlemon#include "opt_ipx.h"
2332350Seivind
246735Samurai#include <sys/param.h>
25164033Srwatson#include <sys/priv.h>
266735Samurai#include <sys/proc.h>
276735Samurai#include <sys/systm.h>
28194368Sbz#include <sys/jail.h>
296735Samurai#include <sys/mbuf.h>
3071862Speter#include <sys/module.h>
316735Samurai#include <sys/socket.h>
32139208Sphk#include <sys/fcntl.h>
3324208Sbde#include <sys/filio.h>
3424208Sbde#include <sys/sockio.h>
3524208Sbde#include <sys/ttycom.h>
3629365Speter#include <sys/poll.h>
37139208Sphk#include <sys/selinfo.h>
387090Sbde#include <sys/signalvar.h>
3941086Struckman#include <sys/filedesc.h>
406735Samurai#include <sys/kernel.h>
4112706Sphk#include <sys/sysctl.h>
427747Swollman#include <sys/conf.h>
4331283Sbde#include <sys/uio.h>
4449829Sphk#include <sys/malloc.h>
45111888Sjlemon#include <sys/random.h>
466053Samurai
476053Samurai#include <net/if.h>
48166497Sbms#include <net/if_clone.h>
4963358Sbrian#include <net/if_types.h>
50111888Sjlemon#include <net/netisr.h>
516053Samurai#include <net/route.h>
52196019Srwatson#include <net/vnet.h>
536053Samurai#ifdef INET
546053Samurai#include <netinet/in.h>
556053Samurai#endif
566053Samurai#include <net/bpf.h>
576053Samurai#include <net/if_tun.h>
586053Samurai
59126077Sphk#include <sys/queue.h>
60186391Sqingli#include <sys/condvar.h>
61126077Sphk
62163606Srwatson#include <security/mac/mac_framework.h>
63163606Srwatson
64127591Srwatson/*
65127591Srwatson * tun_list is protected by global tunmtx.  Other mutable fields are
66127591Srwatson * protected by tun->tun_mtx, or by their owning subsystem.  tun_dev is
67127591Srwatson * static for the duration of a tunnel interface.
68127591Srwatson */
69126077Sphkstruct tun_softc {
70126077Sphk	TAILQ_ENTRY(tun_softc)	tun_list;
71130585Sphk	struct cdev *tun_dev;
72126077Sphk	u_short	tun_flags;		/* misc flags */
73126077Sphk#define	TUN_OPEN	0x0001
74126077Sphk#define	TUN_INITED	0x0002
75126077Sphk#define	TUN_RCOLL	0x0004
76126077Sphk#define	TUN_IASET	0x0008
77126077Sphk#define	TUN_DSTADDR	0x0010
78126077Sphk#define	TUN_LMODE	0x0020
79126077Sphk#define	TUN_RWAIT	0x0040
80126077Sphk#define	TUN_ASYNC	0x0080
81126077Sphk#define	TUN_IFHEAD	0x0100
82126077Sphk
83126077Sphk#define TUN_READY       (TUN_OPEN | TUN_INITED)
84126077Sphk
85127099Srwatson	/*
86127099Srwatson	 * XXXRW: tun_pid is used to exclusively lock /dev/tun.  Is this
87127099Srwatson	 * actually needed?  Can we just return EBUSY if already open?
88127099Srwatson	 * Problem is that this involved inherent races when a tun device
89127099Srwatson	 * is handed off from one process to another, as opposed to just
90127099Srwatson	 * being slightly stale informationally.
91127099Srwatson	 */
92127099Srwatson	pid_t	tun_pid;		/* owning pid */
93147256Sbrooks	struct	ifnet *tun_ifp;		/* the interface */
94126077Sphk	struct  sigio *tun_sigio;	/* information for async I/O */
95126077Sphk	struct	selinfo	tun_rsel;	/* read select */
96127591Srwatson	struct mtx	tun_mtx;	/* protect mutable softc fields */
97186391Sqingli	struct cv	tun_cv;		/* protect against ref'd dev destroy */
98126077Sphk};
99147256Sbrooks#define TUN2IFP(sc)	((sc)->tun_ifp)
100126077Sphk
101121778Sbrooks#define TUNDEBUG	if (tundebug) if_printf
10249829Sphk
103127580Srwatson/*
104127580Srwatson * All mutable global variables in if_tun are locked using tunmtx, with
105127580Srwatson * the exception of tundebug, which is used unlocked, and tunclones,
106127580Srwatson * which is static after setup.
107127580Srwatson */
108127580Srwatsonstatic struct mtx tunmtx;
109241610Sglebiusstatic const char tunname[] = "tun";
110241610Sglebiusstatic MALLOC_DEFINE(M_TUN, tunname, "Tunnel Interface");
11112706Sphkstatic int tundebug = 0;
112166497Sbmsstatic int tundclone = 1;
113126077Sphkstatic struct clonedevs *tunclones;
114126077Sphkstatic TAILQ_HEAD(,tun_softc)	tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
11513993SphkSYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
1166053Samurai
117166497SbmsSYSCTL_DECL(_net_link);
118227309Sedstatic SYSCTL_NODE(_net_link, OID_AUTO, tun, CTLFLAG_RW, 0,
119166497Sbms    "IP tunnel software network interface.");
120166497SbmsSYSCTL_INT(_net_link_tun, OID_AUTO, devfs_cloning, CTLFLAG_RW, &tundclone, 0,
121166497Sbms    "Enable legacy devfs interface creation.");
122166497Sbms
123166497SbmsTUNABLE_INT("net.link.tun.devfs_cloning", &tundclone);
124166497Sbms
125148868Srwatsonstatic void	tunclone(void *arg, struct ucred *cred, char *name,
126148868Srwatson		    int namelen, struct cdev **dev);
127166497Sbmsstatic void	tuncreate(const char *name, struct cdev *dev);
12877589Sbrianstatic int	tunifioctl(struct ifnet *, u_long, caddr_t);
129222651Sjhbstatic void	tuninit(struct ifnet *);
13077589Sbrianstatic int	tunmodevent(module_t, int, void *);
131249925Sglebiusstatic int	tunoutput(struct ifnet *, struct mbuf *,
132249925Sglebius		    const struct sockaddr *, struct route *ro);
13377589Sbrianstatic void	tunstart(struct ifnet *);
1346053Samurai
135166497Sbmsstatic int	tun_clone_create(struct if_clone *, int, caddr_t);
136166497Sbmsstatic void	tun_clone_destroy(struct ifnet *);
137241610Sglebiusstatic struct if_clone *tun_cloner;
138166497Sbms
13977589Sbrianstatic d_open_t		tunopen;
14077589Sbrianstatic d_close_t	tunclose;
14177589Sbrianstatic d_read_t		tunread;
14277589Sbrianstatic d_write_t	tunwrite;
14377589Sbrianstatic d_ioctl_t	tunioctl;
14477589Sbrianstatic d_poll_t		tunpoll;
145161103Srwatsonstatic d_kqfilter_t	tunkqfilter;
14612675Sjulian
147161103Srwatsonstatic int		tunkqread(struct knote *, long);
148161103Srwatsonstatic int		tunkqwrite(struct knote *, long);
149161103Srwatsonstatic void		tunkqdetach(struct knote *);
150161103Srwatson
151161103Srwatsonstatic struct filterops tun_read_filterops = {
152161103Srwatson	.f_isfd =	1,
153161103Srwatson	.f_attach =	NULL,
154161103Srwatson	.f_detach =	tunkqdetach,
155161103Srwatson	.f_event =	tunkqread,
156161103Srwatson};
157161103Srwatson
158161103Srwatsonstatic struct filterops tun_write_filterops = {
159161103Srwatson	.f_isfd =	1,
160161103Srwatson	.f_attach =	NULL,
161161103Srwatson	.f_detach =	tunkqdetach,
162161103Srwatson	.f_event =	tunkqwrite,
163161103Srwatson};
164161103Srwatson
16512675Sjulianstatic struct cdevsw tun_cdevsw = {
166126080Sphk	.d_version =	D_VERSION,
167226500Sed	.d_flags =	D_NEEDMINOR,
168111815Sphk	.d_open =	tunopen,
169111815Sphk	.d_close =	tunclose,
170111815Sphk	.d_read =	tunread,
171111815Sphk	.d_write =	tunwrite,
172111815Sphk	.d_ioctl =	tunioctl,
173111815Sphk	.d_poll =	tunpoll,
174161103Srwatson	.d_kqfilter =	tunkqfilter,
175241610Sglebius	.d_name =	tunname,
17612118Sbde};
1777747Swollman
178166497Sbmsstatic int
179166497Sbmstun_clone_create(struct if_clone *ifc, int unit, caddr_t params)
180166497Sbms{
181166497Sbms	struct cdev *dev;
182166497Sbms	int i;
183166497Sbms
184166497Sbms	/* find any existing device, or allocate new unit number */
185166497Sbms	i = clone_create(&tunclones, &tun_cdevsw, &unit, &dev, 0);
186166497Sbms	if (i) {
187166497Sbms		/* No preexisting struct cdev *, create one */
188183381Sed		dev = make_dev(&tun_cdevsw, unit,
189241610Sglebius		    UID_UUCP, GID_DIALER, 0600, "%s%d", tunname, unit);
190166497Sbms	}
191241610Sglebius	tuncreate(tunname, dev);
192166497Sbms
193166497Sbms	return (0);
194166497Sbms}
195166497Sbms
19610429Sbdestatic void
197148868Srwatsontunclone(void *arg, struct ucred *cred, char *name, int namelen,
198148868Srwatson    struct cdev **dev)
19964880Sphk{
200166497Sbms	char devname[SPECNAMELEN + 1];
201166497Sbms	int u, i, append_unit;
20264880Sphk
203130640Sphk	if (*dev != NULL)
20464880Sphk		return;
20577589Sbrian
206166497Sbms	/*
207166497Sbms	 * If tun cloning is enabled, only the superuser can create an
208166497Sbms	 * interface.
209166497Sbms	 */
210166497Sbms	if (!tundclone || priv_check_cred(cred, PRIV_NET_IFCREATE, 0) != 0)
211166497Sbms		return;
212166497Sbms
213241610Sglebius	if (strcmp(name, tunname) == 0) {
214126077Sphk		u = -1;
215241610Sglebius	} else if (dev_stdclone(name, NULL, tunname, &u) != 1)
21677589Sbrian		return;	/* Don't recognise the name */
217126077Sphk	if (u != -1 && u > IF_MAXUNIT)
218126077Sphk		return;	/* Unit number too high */
21977589Sbrian
220166497Sbms	if (u == -1)
221166497Sbms		append_unit = 1;
222166497Sbms	else
223166497Sbms		append_unit = 0;
224166497Sbms
225194252Sjamie	CURVNET_SET(CRED_TO_VNET(cred));
226126077Sphk	/* find any existing device, or allocate new unit number */
227126077Sphk	i = clone_create(&tunclones, &tun_cdevsw, &u, dev, 0);
228126077Sphk	if (i) {
229166497Sbms		if (append_unit) {
230221552Syongari			namelen = snprintf(devname, sizeof(devname), "%s%d",
231221552Syongari			    name, u);
232166497Sbms			name = devname;
233166497Sbms		}
234130585Sphk		/* No preexisting struct cdev *, create one */
235204464Skib		*dev = make_dev_credf(MAKEDEV_REF, &tun_cdevsw, u, cred,
236166497Sbms		    UID_UUCP, GID_DIALER, 0600, "%s", name);
23777589Sbrian	}
238166497Sbms
239166497Sbms	if_clone_create(name, namelen, NULL);
240183550Szec	CURVNET_RESTORE();
24164880Sphk}
24264880Sphk
243127580Srwatsonstatic void
244127580Srwatsontun_destroy(struct tun_softc *tp)
245127580Srwatson{
246130585Sphk	struct cdev *dev;
247127580Srwatson
248186391Sqingli	mtx_lock(&tp->tun_mtx);
249186497Sqingli	if ((tp->tun_flags & TUN_OPEN) != 0)
250186391Sqingli		cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx);
251186483Skmacy	else
252186483Skmacy		mtx_unlock(&tp->tun_mtx);
253186497Sqingli
254183550Szec	CURVNET_SET(TUN2IFP(tp)->if_vnet);
255127580Srwatson	dev = tp->tun_dev;
256147256Sbrooks	bpfdetach(TUN2IFP(tp));
257147256Sbrooks	if_detach(TUN2IFP(tp));
258147256Sbrooks	if_free(TUN2IFP(tp));
259127580Srwatson	destroy_dev(dev);
260225177Sattilio	seldrain(&tp->tun_rsel);
261256008Sglebius	knlist_clear(&tp->tun_rsel.si_note, 0);
262161103Srwatson	knlist_destroy(&tp->tun_rsel.si_note);
263127591Srwatson	mtx_destroy(&tp->tun_mtx);
264186391Sqingli	cv_destroy(&tp->tun_cv);
265127580Srwatson	free(tp, M_TUN);
266183550Szec	CURVNET_RESTORE();
267127580Srwatson}
268127580Srwatson
269166497Sbmsstatic void
270166497Sbmstun_clone_destroy(struct ifnet *ifp)
271166497Sbms{
272166497Sbms	struct tun_softc *tp = ifp->if_softc;
273166497Sbms
274166497Sbms	mtx_lock(&tunmtx);
275166497Sbms	TAILQ_REMOVE(&tunhead, tp, tun_list);
276166497Sbms	mtx_unlock(&tunmtx);
277166497Sbms	tun_destroy(tp);
278166497Sbms}
279166497Sbms
28071862Speterstatic int
281111742Sdestunmodevent(module_t mod, int type, void *data)
28275103Sbrian{
28375103Sbrian	static eventhandler_tag tag;
28475103Sbrian	struct tun_softc *tp;
28575103Sbrian
286111742Sdes	switch (type) {
287111742Sdes	case MOD_LOAD:
288127580Srwatson		mtx_init(&tunmtx, "tunmtx", NULL, MTX_DEF);
289126845Sphk		clone_setup(&tunclones);
29077589Sbrian		tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000);
29175103Sbrian		if (tag == NULL)
29275103Sbrian			return (ENOMEM);
293241610Sglebius		tun_cloner = if_clone_simple(tunname, tun_clone_create,
294241610Sglebius		    tun_clone_destroy, 0);
295111742Sdes		break;
296111742Sdes	case MOD_UNLOAD:
297241610Sglebius		if_clone_detach(tun_cloner);
29877589Sbrian		EVENTHANDLER_DEREGISTER(dev_clone, tag);
299204464Skib		drain_dev_clone_events();
30077589Sbrian
301127580Srwatson		mtx_lock(&tunmtx);
302127580Srwatson		while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
303126077Sphk			TAILQ_REMOVE(&tunhead, tp, tun_list);
304127580Srwatson			mtx_unlock(&tunmtx);
305127580Srwatson			tun_destroy(tp);
306127580Srwatson			mtx_lock(&tunmtx);
30775103Sbrian		}
308127580Srwatson		mtx_unlock(&tunmtx);
309126077Sphk		clone_cleanup(&tunclones);
310127580Srwatson		mtx_destroy(&tunmtx);
31175103Sbrian		break;
312132199Sphk	default:
313132199Sphk		return EOPNOTSUPP;
314111742Sdes	}
315111742Sdes	return 0;
316111742Sdes}
3176053Samurai
318111742Sdesstatic moduledata_t tun_mod = {
319111742Sdes	"if_tun",
320111742Sdes	tunmodevent,
321241394Skevlo	0
322111742Sdes};
3236053Samurai
32471862SpeterDECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
325254020SmarkjMODULE_VERSION(if_tun, 1);
32671862Speter
32749829Sphkstatic void
32877589Sbriantunstart(struct ifnet *ifp)
32969621Sjlemon{
33069621Sjlemon	struct tun_softc *tp = ifp->if_softc;
331131455Smlaier	struct mbuf *m;
33269621Sjlemon
333161103Srwatson	TUNDEBUG(ifp,"%s starting\n", ifp->if_xname);
334131455Smlaier	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
335131455Smlaier		IFQ_LOCK(&ifp->if_snd);
336131455Smlaier		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
337131455Smlaier		if (m == NULL) {
338131455Smlaier			IFQ_UNLOCK(&ifp->if_snd);
339131455Smlaier			return;
340131455Smlaier		}
341131455Smlaier		IFQ_UNLOCK(&ifp->if_snd);
342131455Smlaier	}
343131455Smlaier
344127591Srwatson	mtx_lock(&tp->tun_mtx);
34569621Sjlemon	if (tp->tun_flags & TUN_RWAIT) {
34669621Sjlemon		tp->tun_flags &= ~TUN_RWAIT;
347111748Sdes		wakeup(tp);
34869621Sjlemon	}
349213028Sjhb	selwakeuppri(&tp->tun_rsel, PZERO + 1);
350213028Sjhb	KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
351127591Srwatson	if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) {
352127591Srwatson		mtx_unlock(&tp->tun_mtx);
35395883Salfred		pgsigio(&tp->tun_sigio, SIGIO, 0);
354127591Srwatson	} else
355127591Srwatson		mtx_unlock(&tp->tun_mtx);
35669621Sjlemon}
35769621Sjlemon
358147256Sbrooks/* XXX: should return an error code so it can fail. */
35969621Sjlemonstatic void
360166497Sbmstuncreate(const char *name, struct cdev *dev)
36149829Sphk{
36249829Sphk	struct tun_softc *sc;
36349829Sphk	struct ifnet *ifp;
36449829Sphk
365184205Sdes	sc = malloc(sizeof(*sc), M_TUN, M_WAITOK | M_ZERO);
366127591Srwatson	mtx_init(&sc->tun_mtx, "tun_mtx", NULL, MTX_DEF);
367186391Sqingli	cv_init(&sc->tun_cv, "tun_condvar");
36849829Sphk	sc->tun_flags = TUN_INITED;
369126077Sphk	sc->tun_dev = dev;
370127580Srwatson	mtx_lock(&tunmtx);
371126077Sphk	TAILQ_INSERT_TAIL(&tunhead, sc, tun_list);
372127580Srwatson	mtx_unlock(&tunmtx);
37349829Sphk
374147256Sbrooks	ifp = sc->tun_ifp = if_alloc(IFT_PPP);
375147256Sbrooks	if (ifp == NULL)
376147256Sbrooks		panic("%s%d: failed to if_alloc() interface.\n",
377166497Sbms		    name, dev2unit(dev));
378166497Sbms	if_initname(ifp, name, dev2unit(dev));
37949829Sphk	ifp->if_mtu = TUNMTU;
38049829Sphk	ifp->if_ioctl = tunifioctl;
38149829Sphk	ifp->if_output = tunoutput;
38269621Sjlemon	ifp->if_start = tunstart;
38349829Sphk	ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
38449829Sphk	ifp->if_softc = sc;
385131455Smlaier	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
386131455Smlaier	ifp->if_snd.ifq_drv_maxlen = 0;
387131455Smlaier	IFQ_SET_READY(&ifp->if_snd);
388213028Sjhb	knlist_init_mtx(&sc->tun_rsel.si_note, &sc->tun_mtx);
389205222Sqingli	ifp->if_capabilities |= IFCAP_LINKSTATE;
390205222Sqingli	ifp->if_capenable |= IFCAP_LINKSTATE;
391131455Smlaier
39249829Sphk	if_attach(ifp);
393147611Sdwmalone	bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
39449829Sphk	dev->si_drv1 = sc;
395161103Srwatson	TUNDEBUG(ifp, "interface %s is created, minor = %#x\n",
396183397Sed	    ifp->if_xname, dev2unit(dev));
3976053Samurai}
3986053Samurai
39977589Sbrianstatic int
400130585Sphktunopen(struct cdev *dev, int flag, int mode, struct thread *td)
4016053Samurai{
4026053Samurai	struct ifnet	*ifp;
4036053Samurai	struct tun_softc *tp;
4046053Samurai
405127591Srwatson	/*
406127591Srwatson	 * XXXRW: Non-atomic test and set of dev->si_drv1 requires
407127591Srwatson	 * synchronization.
408127591Srwatson	 */
40949829Sphk	tp = dev->si_drv1;
41049829Sphk	if (!tp) {
411241610Sglebius		tuncreate(tunname, dev);
41249829Sphk		tp = dev->si_drv1;
41349829Sphk	}
414126077Sphk
415127591Srwatson	/*
416127591Srwatson	 * XXXRW: This use of tun_pid is subject to error due to the
417127591Srwatson	 * fact that a reference to the tunnel can live beyond the
418127591Srwatson	 * death of the process that created it.  Can we replace this
419127591Srwatson	 * with a simple busy flag?
420127591Srwatson	 */
421127591Srwatson	mtx_lock(&tp->tun_mtx);
422127591Srwatson	if (tp->tun_pid != 0 && tp->tun_pid != td->td_proc->p_pid) {
423127591Srwatson		mtx_unlock(&tp->tun_mtx);
424126077Sphk		return (EBUSY);
425127591Srwatson	}
426127099Srwatson	tp->tun_pid = td->td_proc->p_pid;
427126077Sphk
428126077Sphk	tp->tun_flags |= TUN_OPEN;
429147256Sbrooks	ifp = TUN2IFP(tp);
430185963Scsjp	if_link_state_change(ifp, LINK_STATE_UP);
431121778Sbrooks	TUNDEBUG(ifp, "open\n");
432213028Sjhb	mtx_unlock(&tp->tun_mtx);
43377589Sbrian
4346053Samurai	return (0);
4356053Samurai}
4366053Samurai
4376053Samurai/*
4386053Samurai * tunclose - close the device - mark i/f down & delete
4396053Samurai * routing info
4406053Samurai */
44112675Sjulianstatic	int
442130585Sphktunclose(struct cdev *dev, int foo, int bar, struct thread *td)
4436053Samurai{
44449829Sphk	struct tun_softc *tp;
44577589Sbrian	struct ifnet *ifp;
4466053Samurai
44749829Sphk	tp = dev->si_drv1;
448147256Sbrooks	ifp = TUN2IFP(tp);
44949829Sphk
450127591Srwatson	mtx_lock(&tp->tun_mtx);
4516053Samurai	tp->tun_flags &= ~TUN_OPEN;
452127099Srwatson	tp->tun_pid = 0;
4536053Samurai
4546053Samurai	/*
4556053Samurai	 * junk all pending output
4566053Samurai	 */
457183550Szec	CURVNET_SET(ifp->if_vnet);
458131455Smlaier	IFQ_PURGE(&ifp->if_snd);
4596053Samurai
4606053Samurai	if (ifp->if_flags & IFF_UP) {
461213028Sjhb		mtx_unlock(&tp->tun_mtx);
4626053Samurai		if_down(ifp);
463213028Sjhb		mtx_lock(&tp->tun_mtx);
4646053Samurai	}
46547550Sbrian
466166512Sbms	/* Delete all addresses and routes which reference this interface. */
467148887Srwatson	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
468111742Sdes		struct ifaddr *ifa;
46947550Sbrian
470213028Sjhb		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
471213028Sjhb		mtx_unlock(&tp->tun_mtx);
472166512Sbms		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
473166512Sbms			/* deal w/IPv4 PtP destination; unlocked read */
474166512Sbms			if (ifa->ifa_addr->sa_family == AF_INET) {
47547550Sbrian				rtinit(ifa, (int)RTM_DELETE,
47647550Sbrian				    tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
477166512Sbms			} else {
478166512Sbms				rtinit(ifa, (int)RTM_DELETE, 0);
479166512Sbms			}
480166512Sbms		}
481166512Sbms		if_purgeaddrs(ifp);
482213028Sjhb		mtx_lock(&tp->tun_mtx);
48347550Sbrian	}
484185963Scsjp	if_link_state_change(ifp, LINK_STATE_DOWN);
485183550Szec	CURVNET_RESTORE();
48647550Sbrian
48796122Salfred	funsetown(&tp->tun_sigio);
488122352Stanimura	selwakeuppri(&tp->tun_rsel, PZERO + 1);
489213028Sjhb	KNOTE_LOCKED(&tp->tun_rsel.si_note, 0);
490121778Sbrooks	TUNDEBUG (ifp, "closed\n");
491186391Sqingli
492186391Sqingli	cv_broadcast(&tp->tun_cv);
493186391Sqingli	mtx_unlock(&tp->tun_mtx);
4946053Samurai	return (0);
4956053Samurai}
4966053Samurai
497222651Sjhbstatic void
49877589Sbriantuninit(struct ifnet *ifp)
4996053Samurai{
500213328Sbz	struct tun_softc *tp = ifp->if_softc;
501184679Sbz#ifdef INET
502111742Sdes	struct ifaddr *ifa;
503184679Sbz#endif
5046053Samurai
505121778Sbrooks	TUNDEBUG(ifp, "tuninit\n");
5066053Samurai
507213028Sjhb	mtx_lock(&tp->tun_mtx);
508148887Srwatson	ifp->if_flags |= IFF_UP;
509148887Srwatson	ifp->if_drv_flags |= IFF_DRV_RUNNING;
51035067Sphk	getmicrotime(&ifp->if_lastchange);
5116053Samurai
512160038Syar#ifdef INET
513195022Srwatson	if_addr_rlock(ifp);
514160033Syar	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
515160038Syar		if (ifa->ifa_addr->sa_family == AF_INET) {
516160038Syar			struct sockaddr_in *si;
5176053Samurai
518160038Syar			si = (struct sockaddr_in *)ifa->ifa_addr;
519160038Syar			if (si->sin_addr.s_addr)
520160038Syar				tp->tun_flags |= TUN_IASET;
5216053Samurai
522160038Syar			si = (struct sockaddr_in *)ifa->ifa_dstaddr;
523160038Syar			if (si && si->sin_addr.s_addr)
524160038Syar				tp->tun_flags |= TUN_DSTADDR;
5256735Samurai		}
52632350Seivind	}
527195022Srwatson	if_addr_runlock(ifp);
528160038Syar#endif
529213028Sjhb	mtx_unlock(&tp->tun_mtx);
5306053Samurai}
5316053Samurai
5326053Samurai/*
5336053Samurai * Process an ioctl request.
5346053Samurai */
535105556Sphkstatic int
53677589Sbriantunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
5376053Samurai{
53848021Sphk	struct ifreq *ifr = (struct ifreq *)data;
53949829Sphk	struct tun_softc *tp = ifp->if_softc;
54048021Sphk	struct ifstat *ifs;
541213028Sjhb	int		error = 0;
5426053Samurai
5436053Samurai	switch(cmd) {
54448021Sphk	case SIOCGIFSTATUS:
54548021Sphk		ifs = (struct ifstat *)data;
546127591Srwatson		mtx_lock(&tp->tun_mtx);
547127099Srwatson		if (tp->tun_pid)
54848021Sphk			sprintf(ifs->ascii + strlen(ifs->ascii),
549127099Srwatson			    "\tOpened by PID %d\n", tp->tun_pid);
550127591Srwatson		mtx_unlock(&tp->tun_mtx);
55168250Sjlemon		break;
5526053Samurai	case SIOCSIFADDR:
553222651Sjhb		tuninit(ifp);
554222651Sjhb		TUNDEBUG(ifp, "address set\n");
5556053Samurai		break;
55620559Sfenner	case SIOCSIFMTU:
55749469Sbrian		ifp->if_mtu = ifr->ifr_mtu;
558121778Sbrooks		TUNDEBUG(ifp, "mtu set\n");
55920559Sfenner		break;
56075095Sbrian	case SIOCSIFFLAGS:
56111004Swollman	case SIOCADDMULTI:
56211004Swollman	case SIOCDELMULTI:
56311004Swollman		break;
5646053Samurai	default:
5656053Samurai		error = EINVAL;
5666053Samurai	}
5676053Samurai	return (error);
5686053Samurai}
5696053Samurai
5706053Samurai/*
5716053Samurai * tunoutput - queue packets from higher level ready to put out.
5726053Samurai */
573105556Sphkstatic int
574249925Sglebiustunoutput(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,
575221552Syongari    struct route *ro)
5766053Samurai{
57749829Sphk	struct tun_softc *tp = ifp->if_softc;
578127591Srwatson	u_short cached_tun_flags;
579101083Srwatson	int error;
580147611Sdwmalone	u_int32_t af;
5816053Samurai
582121778Sbrooks	TUNDEBUG (ifp, "tunoutput\n");
5836053Samurai
584101083Srwatson#ifdef MAC
585172930Srwatson	error = mac_ifnet_check_transmit(ifp, m0);
586101083Srwatson	if (error) {
587101083Srwatson		m_freem(m0);
588101083Srwatson		return (error);
589101083Srwatson	}
590101083Srwatson#endif
591101083Srwatson
592127591Srwatson	/* Could be unlocked read? */
593127591Srwatson	mtx_lock(&tp->tun_mtx);
594127591Srwatson	cached_tun_flags = tp->tun_flags;
595127591Srwatson	mtx_unlock(&tp->tun_mtx);
596127591Srwatson	if ((cached_tun_flags & TUN_READY) != TUN_READY) {
597121778Sbrooks		TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
5986053Samurai		m_freem (m0);
59991275Simp		return (EHOSTDOWN);
6006053Samurai	}
6016053Samurai
602105944Ssimokawa	if ((ifp->if_flags & IFF_UP) != IFF_UP) {
603105804Ssimokawa		m_freem (m0);
604105804Ssimokawa		return (EHOSTDOWN);
605105804Ssimokawa	}
606105804Ssimokawa
607147611Sdwmalone	/* BPF writes need to be handled specially. */
608249925Sglebius	if (dst->sa_family == AF_UNSPEC)
609147611Sdwmalone		bcopy(dst->sa_data, &af, sizeof(af));
610249925Sglebius	else
611249925Sglebius		af = dst->sa_family;
61211004Swollman
613249925Sglebius	if (bpf_peers_present(ifp->if_bpf))
614123922Ssam		bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m0);
6156053Samurai
61645014Sdes	/* prepend sockaddr? this may abort if the mbuf allocation fails */
617127591Srwatson	if (cached_tun_flags & TUN_LMODE) {
61845014Sdes		/* allocate space for sockaddr */
619243882Sglebius		M_PREPEND(m0, dst->sa_len, M_NOWAIT);
62045014Sdes
62145014Sdes		/* if allocation failed drop packet */
62269152Sjlemon		if (m0 == NULL) {
62369152Sjlemon			ifp->if_iqdrops++;
62445014Sdes			ifp->if_oerrors++;
62545014Sdes			return (ENOBUFS);
62645014Sdes		} else {
62745014Sdes			bcopy(dst, m0->m_data, dst->sa_len);
62845014Sdes		}
62945014Sdes	}
63045014Sdes
631127591Srwatson	if (cached_tun_flags & TUN_IFHEAD) {
63256410Sbrian		/* Prepend the address family */
633243882Sglebius		M_PREPEND(m0, 4, M_NOWAIT);
63456410Sbrian
63556410Sbrian		/* if allocation failed drop packet */
63669152Sjlemon		if (m0 == NULL) {
63769152Sjlemon			ifp->if_iqdrops++;
63856410Sbrian			ifp->if_oerrors++;
63991275Simp			return (ENOBUFS);
64056410Sbrian		} else
641249925Sglebius			*(u_int32_t *)m0->m_data = htonl(af);
64256410Sbrian	} else {
6436053Samurai#ifdef INET
644249925Sglebius		if (af != AF_INET)
64556410Sbrian#endif
64656410Sbrian		{
6476053Samurai			m_freem(m0);
64891275Simp			return (EAFNOSUPPORT);
6496053Samurai		}
65056410Sbrian	}
65156410Sbrian
652185164Skmacy	error = (ifp->if_transmit)(ifp, m0);
653221548Syongari	if (error)
65491275Simp		return (ENOBUFS);
65556410Sbrian	ifp->if_opackets++;
65691275Simp	return (0);
6576053Samurai}
6586053Samurai
6596053Samurai/*
6606053Samurai * the cdevsw interface is now pretty minimal.
6616053Samurai */
66212675Sjulianstatic	int
663221552Syongaritunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
664221552Syongari    struct thread *td)
6656053Samurai{
66671946Sbrian	int		error;
66749829Sphk	struct tun_softc *tp = dev->si_drv1;
668111742Sdes	struct tuninfo *tunp;
6696053Samurai
6706053Samurai	switch (cmd) {
671111742Sdes	case TUNSIFINFO:
672111742Sdes		tunp = (struct tuninfo *)data;
67349469Sbrian		if (tunp->mtu < IF_MINMTU)
67449459Sbrian			return (EINVAL);
675164033Srwatson		if (TUN2IFP(tp)->if_mtu != tunp->mtu) {
676164033Srwatson			error = priv_check(td, PRIV_NET_SETIFMTU);
677164033Srwatson			if (error)
678164033Srwatson				return (error);
679164033Srwatson		}
680213028Sjhb		mtx_lock(&tp->tun_mtx);
681147256Sbrooks		TUN2IFP(tp)->if_mtu = tunp->mtu;
682147256Sbrooks		TUN2IFP(tp)->if_type = tunp->type;
683147256Sbrooks		TUN2IFP(tp)->if_baudrate = tunp->baudrate;
684213028Sjhb		mtx_unlock(&tp->tun_mtx);
685111742Sdes		break;
686111742Sdes	case TUNGIFINFO:
687111742Sdes		tunp = (struct tuninfo *)data;
688213028Sjhb		mtx_lock(&tp->tun_mtx);
689147256Sbrooks		tunp->mtu = TUN2IFP(tp)->if_mtu;
690147256Sbrooks		tunp->type = TUN2IFP(tp)->if_type;
691147256Sbrooks		tunp->baudrate = TUN2IFP(tp)->if_baudrate;
692213028Sjhb		mtx_unlock(&tp->tun_mtx);
693111742Sdes		break;
6946053Samurai	case TUNSDEBUG:
6956053Samurai		tundebug = *(int *)data;
6966053Samurai		break;
6976053Samurai	case TUNGDEBUG:
6986053Samurai		*(int *)data = tundebug;
6996053Samurai		break;
70045014Sdes	case TUNSLMODE:
701127591Srwatson		mtx_lock(&tp->tun_mtx);
70256410Sbrian		if (*(int *)data) {
70345014Sdes			tp->tun_flags |= TUN_LMODE;
70456410Sbrian			tp->tun_flags &= ~TUN_IFHEAD;
70556410Sbrian		} else
70645014Sdes			tp->tun_flags &= ~TUN_LMODE;
707127591Srwatson		mtx_unlock(&tp->tun_mtx);
70845014Sdes		break;
70956410Sbrian	case TUNSIFHEAD:
710127591Srwatson		mtx_lock(&tp->tun_mtx);
71156410Sbrian		if (*(int *)data) {
71256410Sbrian			tp->tun_flags |= TUN_IFHEAD;
71356410Sbrian			tp->tun_flags &= ~TUN_LMODE;
714111742Sdes		} else
71556410Sbrian			tp->tun_flags &= ~TUN_IFHEAD;
716127591Srwatson		mtx_unlock(&tp->tun_mtx);
71756410Sbrian		break;
71856410Sbrian	case TUNGIFHEAD:
719127591Srwatson		mtx_lock(&tp->tun_mtx);
72056410Sbrian		*(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
721127591Srwatson		mtx_unlock(&tp->tun_mtx);
72256410Sbrian		break;
72345014Sdes	case TUNSIFMODE:
72445014Sdes		/* deny this if UP */
725147256Sbrooks		if (TUN2IFP(tp)->if_flags & IFF_UP)
72645014Sdes			return(EBUSY);
72745014Sdes
72882319Sbrian		switch (*(int *)data & ~IFF_MULTICAST) {
72945014Sdes		case IFF_POINTOPOINT:
73045014Sdes		case IFF_BROADCAST:
731213028Sjhb			mtx_lock(&tp->tun_mtx);
732147256Sbrooks			TUN2IFP(tp)->if_flags &=
73382319Sbrian			    ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
734147256Sbrooks			TUN2IFP(tp)->if_flags |= *(int *)data;
735213028Sjhb			mtx_unlock(&tp->tun_mtx);
73645014Sdes			break;
73745014Sdes		default:
73845014Sdes			return(EINVAL);
73945014Sdes		}
74045014Sdes		break;
74156349Sbrian	case TUNSIFPID:
742127591Srwatson		mtx_lock(&tp->tun_mtx);
743127099Srwatson		tp->tun_pid = curthread->td_proc->p_pid;
744127591Srwatson		mtx_unlock(&tp->tun_mtx);
74556349Sbrian		break;
7466053Samurai	case FIONBIO:
7476053Samurai		break;
7486053Samurai	case FIOASYNC:
749127591Srwatson		mtx_lock(&tp->tun_mtx);
7506053Samurai		if (*(int *)data)
7516053Samurai			tp->tun_flags |= TUN_ASYNC;
7526053Samurai		else
7536053Samurai			tp->tun_flags &= ~TUN_ASYNC;
754127591Srwatson		mtx_unlock(&tp->tun_mtx);
7556053Samurai		break;
7566053Samurai	case FIONREAD:
757147256Sbrooks		if (!IFQ_IS_EMPTY(&TUN2IFP(tp)->if_snd)) {
758131455Smlaier			struct mbuf *mb;
759147256Sbrooks			IFQ_LOCK(&TUN2IFP(tp)->if_snd);
760147256Sbrooks			IFQ_POLL_NOLOCK(&TUN2IFP(tp)->if_snd, mb);
761213028Sjhb			for (*(int *)data = 0; mb != NULL; mb = mb->m_next)
76212773Speter				*(int *)data += mb->m_len;
763147256Sbrooks			IFQ_UNLOCK(&TUN2IFP(tp)->if_snd);
76412773Speter		} else
7656053Samurai			*(int *)data = 0;
7666053Samurai		break;
76741086Struckman	case FIOSETOWN:
76841086Struckman		return (fsetown(*(int *)data, &tp->tun_sigio));
76941086Struckman
77041086Struckman	case FIOGETOWN:
771104393Struckman		*(int *)data = fgetown(&tp->tun_sigio);
77241086Struckman		return (0);
77341086Struckman
77441086Struckman	/* This is deprecated, FIOSETOWN should be used instead. */
7756053Samurai	case TIOCSPGRP:
77641086Struckman		return (fsetown(-(*(int *)data), &tp->tun_sigio));
77741086Struckman
77841086Struckman	/* This is deprecated, FIOGETOWN should be used instead. */
7796053Samurai	case TIOCGPGRP:
780104393Struckman		*(int *)data = -fgetown(&tp->tun_sigio);
78141086Struckman		return (0);
78241086Struckman
7836053Samurai	default:
7846053Samurai		return (ENOTTY);
7856053Samurai	}
7866053Samurai	return (0);
7876053Samurai}
7886053Samurai
7896053Samurai/*
7906053Samurai * The cdevsw read interface - reads a packet at a time, or at
7916053Samurai * least as much of a packet as can be read.
7926053Samurai */
79312675Sjulianstatic	int
794130585Sphktunread(struct cdev *dev, struct uio *uio, int flag)
7956053Samurai{
79649829Sphk	struct tun_softc *tp = dev->si_drv1;
797147256Sbrooks	struct ifnet	*ifp = TUN2IFP(tp);
79890227Sdillon	struct mbuf	*m;
799213028Sjhb	int		error=0, len;
8006053Samurai
801121778Sbrooks	TUNDEBUG (ifp, "read\n");
802127591Srwatson	mtx_lock(&tp->tun_mtx);
8036053Samurai	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
804127591Srwatson		mtx_unlock(&tp->tun_mtx);
805121778Sbrooks		TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
80691275Simp		return (EHOSTDOWN);
8076053Samurai	}
8086053Samurai
8096053Samurai	tp->tun_flags &= ~TUN_RWAIT;
8106053Samurai
8116053Samurai	do {
812131455Smlaier		IFQ_DEQUEUE(&ifp->if_snd, m);
81390227Sdillon		if (m == NULL) {
814139208Sphk			if (flag & O_NONBLOCK) {
815213028Sjhb				mtx_unlock(&tp->tun_mtx);
81691275Simp				return (EWOULDBLOCK);
8176053Samurai			}
8186053Samurai			tp->tun_flags |= TUN_RWAIT;
819213028Sjhb			error = mtx_sleep(tp, &tp->tun_mtx, PCATCH | (PZERO + 1),
820213028Sjhb			    "tunread", 0);
821213028Sjhb			if (error != 0) {
822213028Sjhb				mtx_unlock(&tp->tun_mtx);
82391275Simp				return (error);
82420098Sjulian			}
8256053Samurai		}
82690227Sdillon	} while (m == NULL);
827213028Sjhb	mtx_unlock(&tp->tun_mtx);
8286053Samurai
82990227Sdillon	while (m && uio->uio_resid > 0 && error == 0) {
83090227Sdillon		len = min(uio->uio_resid, m->m_len);
83181106Sfenner		if (len != 0)
832111741Sdes			error = uiomove(mtod(m, void *), len, uio);
83390227Sdillon		m = m_free(m);
8346053Samurai	}
8356053Samurai
83690227Sdillon	if (m) {
837121778Sbrooks		TUNDEBUG(ifp, "Dropping mbuf\n");
83890227Sdillon		m_freem(m);
8396053Samurai	}
84091275Simp	return (error);
8416053Samurai}
8426053Samurai
8436053Samurai/*
8446053Samurai * the cdevsw write interface - an atomic write is a packet - or else!
8456053Samurai */
84612675Sjulianstatic	int
847130585Sphktunwrite(struct cdev *dev, struct uio *uio, int flag)
8486053Samurai{
84949829Sphk	struct tun_softc *tp = dev->si_drv1;
850147256Sbrooks	struct ifnet	*ifp = TUN2IFP(tp);
851137101Sglebius	struct mbuf	*m;
85267169Sbrian	uint32_t	family;
853111888Sjlemon	int 		isr;
8546053Samurai
855121778Sbrooks	TUNDEBUG(ifp, "tunwrite\n");
8566053Samurai
857105944Ssimokawa	if ((ifp->if_flags & IFF_UP) != IFF_UP)
858105804Ssimokawa		/* ignore silently */
859105804Ssimokawa		return (0);
860105804Ssimokawa
86149116Sbrian	if (uio->uio_resid == 0)
86291275Simp		return (0);
86349116Sbrian
86449116Sbrian	if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) {
865194990Skib		TUNDEBUG(ifp, "len=%zd!\n", uio->uio_resid);
86691275Simp		return (EIO);
8676053Samurai	}
8686053Samurai
869243882Sglebius	if ((m = m_uiotombuf(uio, M_NOWAIT, 0, 0, M_PKTHDR)) == NULL) {
87057250Smdodd		ifp->if_ierrors++;
871222651Sjhb		return (ENOBUFS);
8726053Samurai	}
8736053Samurai
874137101Sglebius	m->m_pkthdr.rcvif = ifp;
875101083Srwatson#ifdef MAC
876172930Srwatson	mac_ifnet_create_mbuf(ifp, m);
877101083Srwatson#endif
8786053Samurai
879127591Srwatson	/* Could be unlocked read? */
880127591Srwatson	mtx_lock(&tp->tun_mtx);
88156410Sbrian	if (tp->tun_flags & TUN_IFHEAD) {
882127591Srwatson		mtx_unlock(&tp->tun_mtx);
883137101Sglebius		if (m->m_len < sizeof(family) &&
884137101Sglebius		    (m = m_pullup(m, sizeof(family))) == NULL)
88591275Simp			return (ENOBUFS);
886137101Sglebius		family = ntohl(*mtod(m, u_int32_t *));
887137101Sglebius		m_adj(m, sizeof(family));
888127591Srwatson	} else {
889127591Srwatson		mtx_unlock(&tp->tun_mtx);
89056410Sbrian		family = AF_INET;
891127591Srwatson	}
89256410Sbrian
893137101Sglebius	BPF_MTAP2(ifp, &family, sizeof(family), m);
894123922Ssam
895111888Sjlemon	switch (family) {
896111888Sjlemon#ifdef INET
897111888Sjlemon	case AF_INET:
898111888Sjlemon		isr = NETISR_IP;
899111888Sjlemon		break;
900111888Sjlemon#endif
901111999Sjlemon#ifdef INET6
902111999Sjlemon	case AF_INET6:
903111999Sjlemon		isr = NETISR_IPV6;
904111999Sjlemon		break;
905111999Sjlemon#endif
906111999Sjlemon#ifdef IPX
907111999Sjlemon	case AF_IPX:
908111999Sjlemon		isr = NETISR_IPX;
909111999Sjlemon		break;
910111999Sjlemon#endif
911111999Sjlemon#ifdef NETATALK
912111999Sjlemon	case AF_APPLETALK:
913111999Sjlemon		isr = NETISR_ATALK2;
914111999Sjlemon		break;
915111999Sjlemon#endif
916111888Sjlemon	default:
917111888Sjlemon		m_freem(m);
918111888Sjlemon		return (EAFNOSUPPORT);
919111888Sjlemon	}
920111888Sjlemon	if (harvest.point_to_point)
921256381Smarkm		random_harvest(&(m->m_data), 12, 2, RANDOM_NET_TUN);
922137101Sglebius	ifp->if_ibytes += m->m_pkthdr.len;
92357250Smdodd	ifp->if_ipackets++;
924183550Szec	CURVNET_SET(ifp->if_vnet);
925223741Sbz	M_SETFIB(m, ifp->if_fib);
926137101Sglebius	netisr_dispatch(isr, m);
927183550Szec	CURVNET_RESTORE();
928111888Sjlemon	return (0);
9296053Samurai}
9306053Samurai
9316053Samurai/*
93229365Speter * tunpoll - the poll interface, this is only useful on reads
9336053Samurai * really. The write detect always returns true, write never blocks
9346053Samurai * anyway, it either accepts the packet or drops it.
9356053Samurai */
93612675Sjulianstatic	int
937130585Sphktunpoll(struct cdev *dev, int events, struct thread *td)
9386053Samurai{
93949829Sphk	struct tun_softc *tp = dev->si_drv1;
940147256Sbrooks	struct ifnet	*ifp = TUN2IFP(tp);
94129365Speter	int		revents = 0;
942131455Smlaier	struct mbuf	*m;
9436053Samurai
944121778Sbrooks	TUNDEBUG(ifp, "tunpoll\n");
9456735Samurai
94646568Speter	if (events & (POLLIN | POLLRDNORM)) {
947131455Smlaier		IFQ_LOCK(&ifp->if_snd);
948131455Smlaier		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
949131455Smlaier		if (m != NULL) {
950121778Sbrooks			TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len);
95129365Speter			revents |= events & (POLLIN | POLLRDNORM);
95229365Speter		} else {
953121778Sbrooks			TUNDEBUG(ifp, "tunpoll waiting\n");
95483805Sjhb			selrecord(td, &tp->tun_rsel);
9556053Samurai		}
956131455Smlaier		IFQ_UNLOCK(&ifp->if_snd);
95746568Speter	}
95829365Speter	if (events & (POLLOUT | POLLWRNORM))
95929365Speter		revents |= events & (POLLOUT | POLLWRNORM);
96029365Speter
96129365Speter	return (revents);
9626053Samurai}
963161103Srwatson
964161103Srwatson/*
965161103Srwatson * tunkqfilter - support for the kevent() system call.
966161103Srwatson */
967161103Srwatsonstatic int
968161103Srwatsontunkqfilter(struct cdev *dev, struct knote *kn)
969161103Srwatson{
970161103Srwatson	struct tun_softc	*tp = dev->si_drv1;
971161103Srwatson	struct ifnet	*ifp = TUN2IFP(tp);
972161103Srwatson
973161103Srwatson	switch(kn->kn_filter) {
974161103Srwatson	case EVFILT_READ:
975161103Srwatson		TUNDEBUG(ifp, "%s kqfilter: EVFILT_READ, minor = %#x\n",
976183397Sed		    ifp->if_xname, dev2unit(dev));
977161103Srwatson		kn->kn_fop = &tun_read_filterops;
978161103Srwatson		break;
979161103Srwatson
980161103Srwatson	case EVFILT_WRITE:
981161103Srwatson		TUNDEBUG(ifp, "%s kqfilter: EVFILT_WRITE, minor = %#x\n",
982183397Sed		    ifp->if_xname, dev2unit(dev));
983161103Srwatson		kn->kn_fop = &tun_write_filterops;
984161103Srwatson		break;
985221552Syongari
986161103Srwatson	default:
987161103Srwatson		TUNDEBUG(ifp, "%s kqfilter: invalid filter, minor = %#x\n",
988183397Sed		    ifp->if_xname, dev2unit(dev));
989161103Srwatson		return(EINVAL);
990161103Srwatson	}
991161103Srwatson
992213028Sjhb	kn->kn_hook = tp;
993161103Srwatson	knlist_add(&tp->tun_rsel.si_note, kn, 0);
994161103Srwatson
995161103Srwatson	return (0);
996161103Srwatson}
997161103Srwatson
998161103Srwatson/*
999161103Srwatson * Return true of there is data in the interface queue.
1000161103Srwatson */
1001161103Srwatsonstatic int
1002161103Srwatsontunkqread(struct knote *kn, long hint)
1003161103Srwatson{
1004213028Sjhb	int			ret;
1005213028Sjhb	struct tun_softc	*tp = kn->kn_hook;
1006213028Sjhb	struct cdev		*dev = tp->tun_dev;
1007161103Srwatson	struct ifnet	*ifp = TUN2IFP(tp);
1008161103Srwatson
1009161103Srwatson	if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) {
1010161103Srwatson		TUNDEBUG(ifp,
1011161103Srwatson		    "%s have data in the queue.  Len = %d, minor = %#x\n",
1012183397Sed		    ifp->if_xname, ifp->if_snd.ifq_len, dev2unit(dev));
1013161103Srwatson		ret = 1;
1014161103Srwatson	} else {
1015161103Srwatson		TUNDEBUG(ifp,
1016161103Srwatson		    "%s waiting for data, minor = %#x\n", ifp->if_xname,
1017183397Sed		    dev2unit(dev));
1018161103Srwatson		ret = 0;
1019161103Srwatson	}
1020161103Srwatson
1021161103Srwatson	return (ret);
1022161103Srwatson}
1023161103Srwatson
1024161103Srwatson/*
1025161103Srwatson * Always can write, always return MTU in kn->data.
1026161103Srwatson */
1027161103Srwatsonstatic int
1028161103Srwatsontunkqwrite(struct knote *kn, long hint)
1029161103Srwatson{
1030213028Sjhb	struct tun_softc	*tp = kn->kn_hook;
1031161103Srwatson	struct ifnet	*ifp = TUN2IFP(tp);
1032161103Srwatson
1033161103Srwatson	kn->kn_data = ifp->if_mtu;
1034161103Srwatson
1035161103Srwatson	return (1);
1036161103Srwatson}
1037161103Srwatson
1038161103Srwatsonstatic void
1039161103Srwatsontunkqdetach(struct knote *kn)
1040161103Srwatson{
1041213028Sjhb	struct tun_softc	*tp = kn->kn_hook;
1042161103Srwatson
1043161103Srwatson	knlist_remove(&tp->tun_rsel.si_note, kn, 0);
1044161103Srwatson}
1045