if_tun.c revision 163915
1193323Sed/*	$NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $	*/
2193323Sed
3193323Sed/*-
4193323Sed * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
5193323Sed * Nottingham University 1987.
6193323Sed *
7193323Sed * This source may be freely distributed, however I would be interested
8193323Sed * in any changes that are made.
9193323Sed *
10193323Sed * This driver takes packets off the IP i/f and hands them up to a
11193323Sed * user process to have its wicked way with. This driver has it's
12193323Sed * roots in a similar driver written by Phil Cockcroft (formerly) at
13193323Sed * UCL. This driver is based much more on read/write/poll mode of
14193323Sed * operation though.
15193323Sed *
16193323Sed * $FreeBSD: head/sys/net/if_tun.c 163915 2006-11-02 17:37:22Z andre $
17193323Sed */
18193323Sed
19193323Sed#include "opt_atalk.h"
20193323Sed#include "opt_inet.h"
21193323Sed#include "opt_inet6.h"
22193323Sed#include "opt_ipx.h"
23193323Sed#include "opt_mac.h"
24193323Sed
25193323Sed#include <sys/param.h>
26193323Sed#include <sys/proc.h>
27193323Sed#include <sys/systm.h>
28193323Sed#include <sys/mbuf.h>
29193323Sed#include <sys/module.h>
30193323Sed#include <sys/socket.h>
31193323Sed#include <sys/fcntl.h>
32193323Sed#include <sys/filio.h>
33193323Sed#include <sys/sockio.h>
34193323Sed#include <sys/ttycom.h>
35193323Sed#include <sys/poll.h>
36193323Sed#include <sys/selinfo.h>
37193323Sed#include <sys/signalvar.h>
38193323Sed#include <sys/filedesc.h>
39193323Sed#include <sys/kernel.h>
40193323Sed#include <sys/sysctl.h>
41193323Sed#include <sys/conf.h>
42193323Sed#include <sys/uio.h>
43193323Sed#include <sys/malloc.h>
44193323Sed#include <sys/random.h>
45193323Sed
46193323Sed#include <net/if.h>
47193323Sed#include <net/if_types.h>
48193323Sed#include <net/netisr.h>
49193323Sed#include <net/route.h>
50193323Sed#ifdef INET
51193323Sed#include <netinet/in.h>
52193323Sed#endif
53193323Sed#include <net/bpf.h>
54193323Sed#include <net/if_tun.h>
55193323Sed
56193323Sed#include <sys/queue.h>
57193323Sed
58193323Sed#include <security/mac/mac_framework.h>
59193323Sed
60193323Sed/*
61193323Sed * tun_list is protected by global tunmtx.  Other mutable fields are
62193323Sed * protected by tun->tun_mtx, or by their owning subsystem.  tun_dev is
63193323Sed * static for the duration of a tunnel interface.
64193323Sed */
65193323Sedstruct tun_softc {
66193323Sed	TAILQ_ENTRY(tun_softc)	tun_list;
67193323Sed	struct cdev *tun_dev;
68193323Sed	u_short	tun_flags;		/* misc flags */
69193323Sed#define	TUN_OPEN	0x0001
70193323Sed#define	TUN_INITED	0x0002
71194612Sed#define	TUN_RCOLL	0x0004
72193323Sed#define	TUN_IASET	0x0008
73193323Sed#define	TUN_DSTADDR	0x0010
74193323Sed#define	TUN_LMODE	0x0020
75193323Sed#define	TUN_RWAIT	0x0040
76193323Sed#define	TUN_ASYNC	0x0080
77193323Sed#define	TUN_IFHEAD	0x0100
78193323Sed
79193323Sed#define TUN_READY       (TUN_OPEN | TUN_INITED)
80193323Sed
81193323Sed	/*
82193323Sed	 * XXXRW: tun_pid is used to exclusively lock /dev/tun.  Is this
83193323Sed	 * actually needed?  Can we just return EBUSY if already open?
84193323Sed	 * Problem is that this involved inherent races when a tun device
85193323Sed	 * is handed off from one process to another, as opposed to just
86193323Sed	 * being slightly stale informationally.
87193323Sed	 */
88193323Sed	pid_t	tun_pid;		/* owning pid */
89193323Sed	struct	ifnet *tun_ifp;		/* the interface */
90193323Sed	struct  sigio *tun_sigio;	/* information for async I/O */
91193323Sed	struct	selinfo	tun_rsel;	/* read select */
92193323Sed	struct mtx	tun_mtx;	/* protect mutable softc fields */
93193323Sed};
94193323Sed#define TUN2IFP(sc)	((sc)->tun_ifp)
95193323Sed
96193323Sed#define TUNDEBUG	if (tundebug) if_printf
97193323Sed#define	TUNNAME		"tun"
98193323Sed
99193323Sed/*
100193323Sed * All mutable global variables in if_tun are locked using tunmtx, with
101193323Sed * the exception of tundebug, which is used unlocked, and tunclones,
102193323Sed * which is static after setup.
103193323Sed */
104193323Sedstatic struct mtx tunmtx;
105193323Sedstatic MALLOC_DEFINE(M_TUN, TUNNAME, "Tunnel Interface");
106193323Sedstatic int tundebug = 0;
107193323Sedstatic struct clonedevs *tunclones;
108193323Sedstatic TAILQ_HEAD(,tun_softc)	tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
109193323SedSYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
110193323Sed
111193323Sedstatic void	tunclone(void *arg, struct ucred *cred, char *name,
112193323Sed		    int namelen, struct cdev **dev);
113193323Sedstatic void	tuncreate(struct cdev *dev);
114193323Sedstatic int	tunifioctl(struct ifnet *, u_long, caddr_t);
115193323Sedstatic int	tuninit(struct ifnet *);
116193323Sedstatic int	tunmodevent(module_t, int, void *);
117193323Sedstatic int	tunoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
118193323Sed		    struct rtentry *rt);
119193323Sedstatic void	tunstart(struct ifnet *);
120193323Sed
121193323Sedstatic d_open_t		tunopen;
122193323Sedstatic d_close_t	tunclose;
123193323Sedstatic d_read_t		tunread;
124193323Sedstatic d_write_t	tunwrite;
125193323Sedstatic d_ioctl_t	tunioctl;
126193323Sedstatic d_poll_t		tunpoll;
127193323Sedstatic d_kqfilter_t	tunkqfilter;
128193323Sed
129193323Sedstatic int		tunkqread(struct knote *, long);
130193323Sedstatic int		tunkqwrite(struct knote *, long);
131193323Sedstatic void		tunkqdetach(struct knote *);
132193323Sed
133193323Sedstatic struct filterops tun_read_filterops = {
134193323Sed	.f_isfd =	1,
135193323Sed	.f_attach =	NULL,
136194612Sed	.f_detach =	tunkqdetach,
137194612Sed	.f_event =	tunkqread,
138193323Sed};
139193323Sed
140193323Sedstatic struct filterops tun_write_filterops = {
141193323Sed	.f_isfd =	1,
142193323Sed	.f_attach =	NULL,
143193323Sed	.f_detach =	tunkqdetach,
144193323Sed	.f_event =	tunkqwrite,
145193323Sed};
146193323Sed
147193323Sedstatic struct cdevsw tun_cdevsw = {
148193323Sed	.d_version =	D_VERSION,
149193323Sed	.d_flags =	D_PSEUDO | D_NEEDGIANT,
150193323Sed	.d_open =	tunopen,
151193323Sed	.d_close =	tunclose,
152193323Sed	.d_read =	tunread,
153193323Sed	.d_write =	tunwrite,
154193323Sed	.d_ioctl =	tunioctl,
155193323Sed	.d_poll =	tunpoll,
156193323Sed	.d_kqfilter =	tunkqfilter,
157193323Sed	.d_name =	TUNNAME,
158193323Sed};
159193323Sed
160193323Sedstatic void
161193323Sedtunclone(void *arg, struct ucred *cred, char *name, int namelen,
162193323Sed    struct cdev **dev)
163193323Sed{
164193323Sed	int u, i;
165193323Sed
166193323Sed	if (*dev != NULL)
167193323Sed		return;
168193323Sed
169193323Sed	if (strcmp(name, TUNNAME) == 0) {
170193323Sed		u = -1;
171193323Sed	} else if (dev_stdclone(name, NULL, TUNNAME, &u) != 1)
172193323Sed		return;	/* Don't recognise the name */
173193323Sed	if (u != -1 && u > IF_MAXUNIT)
174193323Sed		return;	/* Unit number too high */
175193323Sed
176193323Sed	/* find any existing device, or allocate new unit number */
177193323Sed	i = clone_create(&tunclones, &tun_cdevsw, &u, dev, 0);
178193323Sed	if (i) {
179193323Sed		/* No preexisting struct cdev *, create one */
180193323Sed		*dev = make_dev(&tun_cdevsw, unit2minor(u),
181193323Sed		    UID_UUCP, GID_DIALER, 0600, "tun%d", u);
182193323Sed		if (*dev != NULL) {
183194612Sed			dev_ref(*dev);
184193323Sed			(*dev)->si_flags |= SI_CHEAPCLONE;
185193323Sed		}
186193323Sed	}
187193323Sed}
188193323Sed
189193323Sedstatic void
190193323Sedtun_destroy(struct tun_softc *tp)
191194612Sed{
192194612Sed	struct cdev *dev;
193194612Sed
194194612Sed	/* Unlocked read. */
195194612Sed	KASSERT((tp->tun_flags & TUN_OPEN) == 0,
196193323Sed	    ("tununits is out of sync - unit %d", TUN2IFP(tp)->if_dunit));
197193323Sed
198193323Sed	dev = tp->tun_dev;
199193323Sed	bpfdetach(TUN2IFP(tp));
200193323Sed	if_detach(TUN2IFP(tp));
201193323Sed	if_free(TUN2IFP(tp));
202193323Sed	destroy_dev(dev);
203194612Sed	knlist_destroy(&tp->tun_rsel.si_note);
204194612Sed	mtx_destroy(&tp->tun_mtx);
205194612Sed	free(tp, M_TUN);
206193323Sed}
207193323Sed
208193323Sedstatic int
209193323Sedtunmodevent(module_t mod, int type, void *data)
210193323Sed{
211193323Sed	static eventhandler_tag tag;
212193323Sed	struct tun_softc *tp;
213193323Sed
214193323Sed	switch (type) {
215193323Sed	case MOD_LOAD:
216193323Sed		mtx_init(&tunmtx, "tunmtx", NULL, MTX_DEF);
217193323Sed		clone_setup(&tunclones);
218193323Sed		tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000);
219194612Sed		if (tag == NULL)
220194612Sed			return (ENOMEM);
221194612Sed		break;
222193323Sed	case MOD_UNLOAD:
223193323Sed		EVENTHANDLER_DEREGISTER(dev_clone, tag);
224193323Sed
225193323Sed		mtx_lock(&tunmtx);
226193323Sed		while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
227193323Sed			TAILQ_REMOVE(&tunhead, tp, tun_list);
228193323Sed			mtx_unlock(&tunmtx);
229193323Sed			tun_destroy(tp);
230193323Sed			mtx_lock(&tunmtx);
231193323Sed		}
232193323Sed		mtx_unlock(&tunmtx);
233193323Sed		clone_cleanup(&tunclones);
234193323Sed		mtx_destroy(&tunmtx);
235193323Sed		break;
236193323Sed	default:
237193323Sed		return EOPNOTSUPP;
238193323Sed	}
239193323Sed	return 0;
240193323Sed}
241194612Sed
242194612Sedstatic moduledata_t tun_mod = {
243194612Sed	"if_tun",
244193323Sed	tunmodevent,
245193323Sed	0
246193323Sed};
247193323Sed
248193323SedDECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
249193323Sed
250193323Sedstatic void
251193323Sedtunstart(struct ifnet *ifp)
252193323Sed{
253193323Sed	struct tun_softc *tp = ifp->if_softc;
254193323Sed	struct mbuf *m;
255193323Sed
256193323Sed	TUNDEBUG(ifp,"%s starting\n", ifp->if_xname);
257193323Sed	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
258193323Sed		IFQ_LOCK(&ifp->if_snd);
259193323Sed		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
260193323Sed		if (m == NULL) {
261193323Sed			IFQ_UNLOCK(&ifp->if_snd);
262193323Sed			return;
263194612Sed		}
264194612Sed		IFQ_UNLOCK(&ifp->if_snd);
265194612Sed	}
266193323Sed
267193323Sed	mtx_lock(&tp->tun_mtx);
268193323Sed	if (tp->tun_flags & TUN_RWAIT) {
269193323Sed		tp->tun_flags &= ~TUN_RWAIT;
270193323Sed		wakeup(tp);
271193323Sed	}
272193323Sed	if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) {
273193323Sed		mtx_unlock(&tp->tun_mtx);
274193323Sed		pgsigio(&tp->tun_sigio, SIGIO, 0);
275193323Sed	} else
276193323Sed		mtx_unlock(&tp->tun_mtx);
277193323Sed	selwakeuppri(&tp->tun_rsel, PZERO + 1);
278193323Sed	KNOTE_UNLOCKED(&tp->tun_rsel.si_note, 0);
279193323Sed}
280193323Sed
281193323Sed/* XXX: should return an error code so it can fail. */
282193323Sedstatic void
283193323Sedtuncreate(struct cdev *dev)
284193323Sed{
285193323Sed	struct tun_softc *sc;
286193323Sed	struct ifnet *ifp;
287193323Sed
288193323Sed	dev->si_flags &= ~SI_CHEAPCLONE;
289193323Sed
290193323Sed	MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO);
291193323Sed	mtx_init(&sc->tun_mtx, "tun_mtx", NULL, MTX_DEF);
292193323Sed	sc->tun_flags = TUN_INITED;
293193323Sed	sc->tun_dev = dev;
294193323Sed	mtx_lock(&tunmtx);
295193323Sed	TAILQ_INSERT_TAIL(&tunhead, sc, tun_list);
296193323Sed	mtx_unlock(&tunmtx);
297193323Sed
298193323Sed	ifp = sc->tun_ifp = if_alloc(IFT_PPP);
299193323Sed	if (ifp == NULL)
300193323Sed		panic("%s%d: failed to if_alloc() interface.\n",
301193323Sed		    TUNNAME, dev2unit(dev));
302193323Sed	if_initname(ifp, TUNNAME, dev2unit(dev));
303193323Sed	ifp->if_mtu = TUNMTU;
304193323Sed	ifp->if_ioctl = tunifioctl;
305193323Sed	ifp->if_output = tunoutput;
306193323Sed	ifp->if_start = tunstart;
307194612Sed	ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
308193323Sed	ifp->if_softc = sc;
309193323Sed	IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
310193323Sed	ifp->if_snd.ifq_drv_maxlen = 0;
311193323Sed	IFQ_SET_READY(&ifp->if_snd);
312193323Sed	knlist_init(&sc->tun_rsel.si_note, NULL, NULL, NULL, NULL);
313193323Sed
314193323Sed	if_attach(ifp);
315193323Sed	bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
316193323Sed	dev->si_drv1 = sc;
317193323Sed	TUNDEBUG(ifp, "interface %s is created, minor = %#x\n",
318193323Sed	    ifp->if_xname, minor(dev));
319193323Sed}
320193323Sed
321193323Sedstatic int
322193323Sedtunopen(struct cdev *dev, int flag, int mode, struct thread *td)
323193323Sed{
324193323Sed	struct ifnet	*ifp;
325193323Sed	struct tun_softc *tp;
326193323Sed
327193323Sed	/*
328193323Sed	 * XXXRW: Non-atomic test and set of dev->si_drv1 requires
329193323Sed	 * synchronization.
330193323Sed	 */
331193323Sed	tp = dev->si_drv1;
332193323Sed	if (!tp) {
333193323Sed		tuncreate(dev);
334193323Sed		tp = dev->si_drv1;
335193323Sed	}
336193323Sed
337193323Sed	/*
338193323Sed	 * XXXRW: This use of tun_pid is subject to error due to the
339193323Sed	 * fact that a reference to the tunnel can live beyond the
340193323Sed	 * death of the process that created it.  Can we replace this
341193323Sed	 * with a simple busy flag?
342193323Sed	 */
343193323Sed	mtx_lock(&tp->tun_mtx);
344193323Sed	if (tp->tun_pid != 0 && tp->tun_pid != td->td_proc->p_pid) {
345193323Sed		mtx_unlock(&tp->tun_mtx);
346193323Sed		return (EBUSY);
347193323Sed	}
348193323Sed	tp->tun_pid = td->td_proc->p_pid;
349193323Sed
350193323Sed	tp->tun_flags |= TUN_OPEN;
351193323Sed	mtx_unlock(&tp->tun_mtx);
352193323Sed	ifp = TUN2IFP(tp);
353193323Sed	TUNDEBUG(ifp, "open\n");
354193323Sed
355193323Sed	return (0);
356193323Sed}
357193323Sed
358193323Sed/*
359193323Sed * tunclose - close the device - mark i/f down & delete
360193323Sed * routing info
361193323Sed */
362193323Sedstatic	int
363193323Sedtunclose(struct cdev *dev, int foo, int bar, struct thread *td)
364193323Sed{
365193323Sed	struct tun_softc *tp;
366193323Sed	struct ifnet *ifp;
367193323Sed	int s;
368193323Sed
369193323Sed	tp = dev->si_drv1;
370193323Sed	ifp = TUN2IFP(tp);
371193323Sed
372193323Sed	mtx_lock(&tp->tun_mtx);
373193323Sed	tp->tun_flags &= ~TUN_OPEN;
374193323Sed	tp->tun_pid = 0;
375193323Sed
376193323Sed	/*
377193323Sed	 * junk all pending output
378193323Sed	 */
379193323Sed	s = splimp();
380193323Sed	IFQ_PURGE(&ifp->if_snd);
381193323Sed	splx(s);
382193323Sed	mtx_unlock(&tp->tun_mtx);
383193323Sed
384193323Sed	if (ifp->if_flags & IFF_UP) {
385193323Sed		s = splimp();
386193323Sed		if_down(ifp);
387194612Sed		splx(s);
388193323Sed	}
389193323Sed
390193323Sed	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
391193323Sed		struct ifaddr *ifa;
392193323Sed
393193323Sed		s = splimp();
394193323Sed		/* find internet addresses and delete routes */
395193323Sed		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
396193323Sed			if (ifa->ifa_addr->sa_family == AF_INET)
397193323Sed				/* Unlocked read. */
398193323Sed				rtinit(ifa, (int)RTM_DELETE,
399193323Sed				    tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
400193323Sed		ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
401193323Sed		splx(s);
402193323Sed	}
403193323Sed
404193323Sed	funsetown(&tp->tun_sigio);
405193323Sed	selwakeuppri(&tp->tun_rsel, PZERO + 1);
406193323Sed	KNOTE_UNLOCKED(&tp->tun_rsel.si_note, 0);
407193323Sed	TUNDEBUG (ifp, "closed\n");
408193323Sed	return (0);
409193323Sed}
410193323Sed
411193323Sedstatic int
412193323Sedtuninit(struct ifnet *ifp)
413193323Sed{
414193323Sed	struct tun_softc *tp = ifp->if_softc;
415193323Sed	struct ifaddr *ifa;
416193323Sed	int error = 0;
417193323Sed
418193323Sed	TUNDEBUG(ifp, "tuninit\n");
419193323Sed
420193323Sed	ifp->if_flags |= IFF_UP;
421193323Sed	ifp->if_drv_flags |= IFF_DRV_RUNNING;
422193323Sed	getmicrotime(&ifp->if_lastchange);
423193323Sed
424193323Sed#ifdef INET
425193323Sed	TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
426193323Sed		if (ifa->ifa_addr->sa_family == AF_INET) {
427193323Sed			struct sockaddr_in *si;
428193323Sed
429193323Sed			si = (struct sockaddr_in *)ifa->ifa_addr;
430193323Sed			mtx_lock(&tp->tun_mtx);
431193323Sed			if (si->sin_addr.s_addr)
432193323Sed				tp->tun_flags |= TUN_IASET;
433193323Sed
434193323Sed			si = (struct sockaddr_in *)ifa->ifa_dstaddr;
435193323Sed			if (si && si->sin_addr.s_addr)
436193323Sed				tp->tun_flags |= TUN_DSTADDR;
437193323Sed			mtx_unlock(&tp->tun_mtx);
438193323Sed		}
439193323Sed	}
440193323Sed#endif
441193323Sed	return (error);
442193323Sed}
443193323Sed
444193323Sed/*
445193323Sed * Process an ioctl request.
446193323Sed */
447193323Sedstatic int
448193323Sedtunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
449193323Sed{
450193323Sed	struct ifreq *ifr = (struct ifreq *)data;
451193323Sed	struct tun_softc *tp = ifp->if_softc;
452193323Sed	struct ifstat *ifs;
453193323Sed	int		error = 0, s;
454193323Sed
455193323Sed	s = splimp();
456193323Sed	switch(cmd) {
457193323Sed	case SIOCGIFSTATUS:
458193323Sed		ifs = (struct ifstat *)data;
459193323Sed		mtx_lock(&tp->tun_mtx);
460193323Sed		if (tp->tun_pid)
461193323Sed			sprintf(ifs->ascii + strlen(ifs->ascii),
462193323Sed			    "\tOpened by PID %d\n", tp->tun_pid);
463193323Sed		mtx_unlock(&tp->tun_mtx);
464193323Sed		break;
465193323Sed	case SIOCSIFADDR:
466193323Sed		error = tuninit(ifp);
467193323Sed		TUNDEBUG(ifp, "address set, error=%d\n", error);
468193323Sed		break;
469193323Sed	case SIOCSIFDSTADDR:
470193323Sed		error = tuninit(ifp);
471193323Sed		TUNDEBUG(ifp, "destination address set, error=%d\n", error);
472193323Sed		break;
473193323Sed	case SIOCSIFMTU:
474193323Sed		ifp->if_mtu = ifr->ifr_mtu;
475193323Sed		TUNDEBUG(ifp, "mtu set\n");
476193323Sed		break;
477193323Sed	case SIOCSIFFLAGS:
478193323Sed	case SIOCADDMULTI:
479193323Sed	case SIOCDELMULTI:
480193323Sed		break;
481193323Sed	default:
482193323Sed		error = EINVAL;
483193323Sed	}
484193323Sed	splx(s);
485193323Sed	return (error);
486193323Sed}
487193323Sed
488193323Sed/*
489193323Sed * tunoutput - queue packets from higher level ready to put out.
490193323Sed */
491193323Sedstatic int
492193323Sedtunoutput(
493193323Sed	struct ifnet *ifp,
494193323Sed	struct mbuf *m0,
495193323Sed	struct sockaddr *dst,
496193323Sed	struct rtentry *rt)
497193323Sed{
498193323Sed	struct tun_softc *tp = ifp->if_softc;
499193323Sed	u_short cached_tun_flags;
500193323Sed	int error;
501193323Sed	u_int32_t af;
502193323Sed
503193323Sed	TUNDEBUG (ifp, "tunoutput\n");
504193323Sed
505193323Sed#ifdef MAC
506193323Sed	error = mac_check_ifnet_transmit(ifp, m0);
507193323Sed	if (error) {
508193323Sed		m_freem(m0);
509193323Sed		return (error);
510193323Sed	}
511193323Sed#endif
512193323Sed
513193323Sed	/* Could be unlocked read? */
514193323Sed	mtx_lock(&tp->tun_mtx);
515193323Sed	cached_tun_flags = tp->tun_flags;
516193323Sed	mtx_unlock(&tp->tun_mtx);
517193323Sed	if ((cached_tun_flags & TUN_READY) != TUN_READY) {
518194612Sed		TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
519194612Sed		m_freem (m0);
520194612Sed		return (EHOSTDOWN);
521194612Sed	}
522194612Sed
523193323Sed	if ((ifp->if_flags & IFF_UP) != IFF_UP) {
524194612Sed		m_freem (m0);
525194612Sed		return (EHOSTDOWN);
526194612Sed	}
527194612Sed
528194612Sed	/* BPF writes need to be handled specially. */
529194612Sed	if (dst->sa_family == AF_UNSPEC) {
530194612Sed		bcopy(dst->sa_data, &af, sizeof(af));
531193323Sed		dst->sa_family = af;
532193323Sed	}
533193323Sed
534193323Sed	if (bpf_peers_present(ifp->if_bpf)) {
535193323Sed		af = dst->sa_family;
536193323Sed		bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m0);
537193323Sed	}
538193323Sed
539193323Sed	/* prepend sockaddr? this may abort if the mbuf allocation fails */
540193323Sed	if (cached_tun_flags & TUN_LMODE) {
541193323Sed		/* allocate space for sockaddr */
542193323Sed		M_PREPEND(m0, dst->sa_len, M_DONTWAIT);
543193323Sed
544193323Sed		/* if allocation failed drop packet */
545193323Sed		if (m0 == NULL) {
546193323Sed			ifp->if_iqdrops++;
547193323Sed			ifp->if_oerrors++;
548193323Sed			return (ENOBUFS);
549193323Sed		} else {
550193323Sed			bcopy(dst, m0->m_data, dst->sa_len);
551193323Sed		}
552193323Sed	}
553193323Sed
554193323Sed	if (cached_tun_flags & TUN_IFHEAD) {
555193323Sed		/* Prepend the address family */
556193323Sed		M_PREPEND(m0, 4, M_DONTWAIT);
557193323Sed
558193323Sed		/* if allocation failed drop packet */
559193323Sed		if (m0 == NULL) {
560193323Sed			ifp->if_iqdrops++;
561193323Sed			ifp->if_oerrors++;
562193323Sed			return (ENOBUFS);
563193323Sed		} else
564193323Sed			*(u_int32_t *)m0->m_data = htonl(dst->sa_family);
565193323Sed	} else {
566193323Sed#ifdef INET
567193323Sed		if (dst->sa_family != AF_INET)
568193323Sed#endif
569193323Sed		{
570193323Sed			m_freem(m0);
571193323Sed			return (EAFNOSUPPORT);
572193323Sed		}
573193323Sed	}
574193323Sed
575193323Sed	IFQ_HANDOFF(ifp, m0, error);
576193323Sed	if (error) {
577193323Sed		ifp->if_collisions++;
578193323Sed		return (ENOBUFS);
579193323Sed	}
580193323Sed	ifp->if_opackets++;
581194612Sed	return (0);
582193323Sed}
583193323Sed
584193323Sed/*
585193323Sed * the cdevsw interface is now pretty minimal.
586193323Sed */
587193323Sedstatic	int
588193323Sedtunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
589193323Sed{
590193323Sed	int		s;
591193323Sed	int		error;
592193323Sed	struct tun_softc *tp = dev->si_drv1;
593193323Sed	struct tuninfo *tunp;
594193323Sed
595193323Sed	switch (cmd) {
596193323Sed	case TUNSIFINFO:
597193323Sed		tunp = (struct tuninfo *)data;
598193323Sed		if (tunp->mtu < IF_MINMTU)
599193323Sed			return (EINVAL);
600193323Sed		if (TUN2IFP(tp)->if_mtu != tunp->mtu
601193323Sed		&& (error = suser(td)) != 0)
602193323Sed			return (error);
603193323Sed		TUN2IFP(tp)->if_mtu = tunp->mtu;
604193323Sed		TUN2IFP(tp)->if_type = tunp->type;
605193323Sed		TUN2IFP(tp)->if_baudrate = tunp->baudrate;
606193323Sed		break;
607193323Sed	case TUNGIFINFO:
608193323Sed		tunp = (struct tuninfo *)data;
609193323Sed		tunp->mtu = TUN2IFP(tp)->if_mtu;
610193323Sed		tunp->type = TUN2IFP(tp)->if_type;
611193323Sed		tunp->baudrate = TUN2IFP(tp)->if_baudrate;
612193323Sed		break;
613193323Sed	case TUNSDEBUG:
614193323Sed		tundebug = *(int *)data;
615193323Sed		break;
616193323Sed	case TUNGDEBUG:
617193323Sed		*(int *)data = tundebug;
618193323Sed		break;
619193323Sed	case TUNSLMODE:
620193323Sed		mtx_lock(&tp->tun_mtx);
621193323Sed		if (*(int *)data) {
622193323Sed			tp->tun_flags |= TUN_LMODE;
623193323Sed			tp->tun_flags &= ~TUN_IFHEAD;
624193323Sed		} else
625193323Sed			tp->tun_flags &= ~TUN_LMODE;
626193323Sed		mtx_unlock(&tp->tun_mtx);
627193323Sed		break;
628193323Sed	case TUNSIFHEAD:
629193323Sed		mtx_lock(&tp->tun_mtx);
630193323Sed		if (*(int *)data) {
631193323Sed			tp->tun_flags |= TUN_IFHEAD;
632193323Sed			tp->tun_flags &= ~TUN_LMODE;
633193323Sed		} else
634193323Sed			tp->tun_flags &= ~TUN_IFHEAD;
635193323Sed		mtx_unlock(&tp->tun_mtx);
636193323Sed		break;
637193323Sed	case TUNGIFHEAD:
638193323Sed		/* Could be unlocked read? */
639193323Sed		mtx_lock(&tp->tun_mtx);
640193323Sed		*(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
641193323Sed		mtx_unlock(&tp->tun_mtx);
642193323Sed		break;
643193323Sed	case TUNSIFMODE:
644193323Sed		/* deny this if UP */
645193323Sed		if (TUN2IFP(tp)->if_flags & IFF_UP)
646193323Sed			return(EBUSY);
647193323Sed
648193323Sed		switch (*(int *)data & ~IFF_MULTICAST) {
649193323Sed		case IFF_POINTOPOINT:
650193323Sed		case IFF_BROADCAST:
651193323Sed			TUN2IFP(tp)->if_flags &=
652193323Sed			    ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
653193323Sed			TUN2IFP(tp)->if_flags |= *(int *)data;
654193323Sed			break;
655193323Sed		default:
656193323Sed			return(EINVAL);
657193323Sed		}
658193323Sed		break;
659193323Sed	case TUNSIFPID:
660193323Sed		mtx_lock(&tp->tun_mtx);
661193323Sed		tp->tun_pid = curthread->td_proc->p_pid;
662193323Sed		mtx_unlock(&tp->tun_mtx);
663193323Sed		break;
664193323Sed	case FIONBIO:
665193323Sed		break;
666193323Sed	case FIOASYNC:
667193323Sed		mtx_lock(&tp->tun_mtx);
668193323Sed		if (*(int *)data)
669193323Sed			tp->tun_flags |= TUN_ASYNC;
670193323Sed		else
671193323Sed			tp->tun_flags &= ~TUN_ASYNC;
672193323Sed		mtx_unlock(&tp->tun_mtx);
673193323Sed		break;
674193323Sed	case FIONREAD:
675193323Sed		s = splimp();
676193323Sed		if (!IFQ_IS_EMPTY(&TUN2IFP(tp)->if_snd)) {
677193323Sed			struct mbuf *mb;
678193323Sed			IFQ_LOCK(&TUN2IFP(tp)->if_snd);
679193323Sed			IFQ_POLL_NOLOCK(&TUN2IFP(tp)->if_snd, mb);
680193323Sed			for( *(int *)data = 0; mb != 0; mb = mb->m_next)
681193323Sed				*(int *)data += mb->m_len;
682193323Sed			IFQ_UNLOCK(&TUN2IFP(tp)->if_snd);
683193323Sed		} else
684193323Sed			*(int *)data = 0;
685193323Sed		splx(s);
686193323Sed		break;
687193323Sed	case FIOSETOWN:
688193323Sed		return (fsetown(*(int *)data, &tp->tun_sigio));
689193323Sed
690193323Sed	case FIOGETOWN:
691193323Sed		*(int *)data = fgetown(&tp->tun_sigio);
692193323Sed		return (0);
693193323Sed
694193323Sed	/* This is deprecated, FIOSETOWN should be used instead. */
695193323Sed	case TIOCSPGRP:
696193323Sed		return (fsetown(-(*(int *)data), &tp->tun_sigio));
697193323Sed
698193323Sed	/* This is deprecated, FIOGETOWN should be used instead. */
699193323Sed	case TIOCGPGRP:
700193323Sed		*(int *)data = -fgetown(&tp->tun_sigio);
701193323Sed		return (0);
702193323Sed
703193323Sed	default:
704193323Sed		return (ENOTTY);
705193323Sed	}
706193323Sed	return (0);
707193323Sed}
708193323Sed
709193323Sed/*
710193323Sed * The cdevsw read interface - reads a packet at a time, or at
711193323Sed * least as much of a packet as can be read.
712193323Sed */
713193323Sedstatic	int
714193323Sedtunread(struct cdev *dev, struct uio *uio, int flag)
715193323Sed{
716193323Sed	struct tun_softc *tp = dev->si_drv1;
717193323Sed	struct ifnet	*ifp = TUN2IFP(tp);
718193323Sed	struct mbuf	*m;
719193323Sed	int		error=0, len, s;
720193323Sed
721193323Sed	TUNDEBUG (ifp, "read\n");
722193323Sed	mtx_lock(&tp->tun_mtx);
723193323Sed	if ((tp->tun_flags & TUN_READY) != TUN_READY) {
724193323Sed		mtx_unlock(&tp->tun_mtx);
725193323Sed		TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
726193323Sed		return (EHOSTDOWN);
727193323Sed	}
728193323Sed
729193323Sed	tp->tun_flags &= ~TUN_RWAIT;
730193323Sed	mtx_unlock(&tp->tun_mtx);
731193323Sed
732193323Sed	s = splimp();
733193323Sed	do {
734193323Sed		IFQ_DEQUEUE(&ifp->if_snd, m);
735193323Sed		if (m == NULL) {
736193323Sed			if (flag & O_NONBLOCK) {
737193323Sed				splx(s);
738193323Sed				return (EWOULDBLOCK);
739193323Sed			}
740193323Sed			mtx_lock(&tp->tun_mtx);
741193323Sed			tp->tun_flags |= TUN_RWAIT;
742193323Sed			mtx_unlock(&tp->tun_mtx);
743193323Sed			if ((error = tsleep(tp, PCATCH | (PZERO + 1),
744193323Sed					"tunread", 0)) != 0) {
745193323Sed				splx(s);
746193323Sed				return (error);
747193323Sed			}
748193323Sed		}
749193323Sed	} while (m == NULL);
750193323Sed	splx(s);
751193323Sed
752193323Sed	while (m && uio->uio_resid > 0 && error == 0) {
753193323Sed		len = min(uio->uio_resid, m->m_len);
754193323Sed		if (len != 0)
755193323Sed			error = uiomove(mtod(m, void *), len, uio);
756193323Sed		m = m_free(m);
757193323Sed	}
758193323Sed
759193323Sed	if (m) {
760193323Sed		TUNDEBUG(ifp, "Dropping mbuf\n");
761193323Sed		m_freem(m);
762193323Sed	}
763193323Sed	return (error);
764193323Sed}
765193323Sed
766193323Sed/*
767193323Sed * the cdevsw write interface - an atomic write is a packet - or else!
768193323Sed */
769193323Sedstatic	int
770193323Sedtunwrite(struct cdev *dev, struct uio *uio, int flag)
771193323Sed{
772193323Sed	struct tun_softc *tp = dev->si_drv1;
773193323Sed	struct ifnet	*ifp = TUN2IFP(tp);
774193323Sed	struct mbuf	*m;
775193323Sed	int		error = 0;
776193323Sed	uint32_t	family;
777193323Sed	int 		isr;
778193323Sed
779193323Sed	TUNDEBUG(ifp, "tunwrite\n");
780193323Sed
781193323Sed	if ((ifp->if_flags & IFF_UP) != IFF_UP)
782193323Sed		/* ignore silently */
783193323Sed		return (0);
784193323Sed
785193323Sed	if (uio->uio_resid == 0)
786194612Sed		return (0);
787193323Sed
788194612Sed	if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) {
789193323Sed		TUNDEBUG(ifp, "len=%d!\n", uio->uio_resid);
790193323Sed		return (EIO);
791193323Sed	}
792193323Sed
793193323Sed	if ((m = m_uiotombuf(uio, M_DONTWAIT, 0, 0, M_PKTHDR)) == NULL) {
794193323Sed		ifp->if_ierrors++;
795194612Sed		return (error);
796193323Sed	}
797193323Sed
798193323Sed	m->m_pkthdr.rcvif = ifp;
799193323Sed#ifdef MAC
800193323Sed	mac_create_mbuf_from_ifnet(ifp, m);
801193323Sed#endif
802193323Sed
803193323Sed	/* Could be unlocked read? */
804193323Sed	mtx_lock(&tp->tun_mtx);
805193323Sed	if (tp->tun_flags & TUN_IFHEAD) {
806193323Sed		mtx_unlock(&tp->tun_mtx);
807193323Sed		if (m->m_len < sizeof(family) &&
808193323Sed		    (m = m_pullup(m, sizeof(family))) == NULL)
809193323Sed			return (ENOBUFS);
810193323Sed		family = ntohl(*mtod(m, u_int32_t *));
811193323Sed		m_adj(m, sizeof(family));
812193323Sed	} else {
813193323Sed		mtx_unlock(&tp->tun_mtx);
814193323Sed		family = AF_INET;
815193323Sed	}
816193323Sed
817193323Sed	BPF_MTAP2(ifp, &family, sizeof(family), m);
818193323Sed
819193323Sed	switch (family) {
820193323Sed#ifdef INET
821193323Sed	case AF_INET:
822193323Sed		isr = NETISR_IP;
823193323Sed		break;
824193323Sed#endif
825193323Sed#ifdef INET6
826193323Sed	case AF_INET6:
827193323Sed		isr = NETISR_IPV6;
828193323Sed		break;
829193323Sed#endif
830193323Sed#ifdef IPX
831193323Sed	case AF_IPX:
832193323Sed		isr = NETISR_IPX;
833193323Sed		break;
834193323Sed#endif
835193323Sed#ifdef NETATALK
836193323Sed	case AF_APPLETALK:
837193323Sed		isr = NETISR_ATALK2;
838193323Sed		break;
839193323Sed#endif
840193323Sed	default:
841193323Sed		m_freem(m);
842193323Sed		return (EAFNOSUPPORT);
843193323Sed	}
844193323Sed	/* First chunk of an mbuf contains good junk */
845193323Sed	if (harvest.point_to_point)
846193323Sed		random_harvest(m, 16, 3, 0, RANDOM_NET);
847193323Sed	ifp->if_ibytes += m->m_pkthdr.len;
848193323Sed	ifp->if_ipackets++;
849193323Sed	netisr_dispatch(isr, m);
850193323Sed	return (0);
851193323Sed}
852193323Sed
853193323Sed/*
854193323Sed * tunpoll - the poll interface, this is only useful on reads
855193323Sed * really. The write detect always returns true, write never blocks
856193323Sed * anyway, it either accepts the packet or drops it.
857193323Sed */
858193323Sedstatic	int
859193323Sedtunpoll(struct cdev *dev, int events, struct thread *td)
860193323Sed{
861193323Sed	int		s;
862193323Sed	struct tun_softc *tp = dev->si_drv1;
863193323Sed	struct ifnet	*ifp = TUN2IFP(tp);
864193323Sed	int		revents = 0;
865193323Sed	struct mbuf	*m;
866193323Sed
867193323Sed	s = splimp();
868193323Sed	TUNDEBUG(ifp, "tunpoll\n");
869193323Sed
870193323Sed	if (events & (POLLIN | POLLRDNORM)) {
871193323Sed		IFQ_LOCK(&ifp->if_snd);
872193323Sed		IFQ_POLL_NOLOCK(&ifp->if_snd, m);
873193323Sed		if (m != NULL) {
874193323Sed			TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len);
875193323Sed			revents |= events & (POLLIN | POLLRDNORM);
876193323Sed		} else {
877193323Sed			TUNDEBUG(ifp, "tunpoll waiting\n");
878193323Sed			selrecord(td, &tp->tun_rsel);
879193323Sed		}
880193323Sed		IFQ_UNLOCK(&ifp->if_snd);
881193323Sed	}
882193323Sed	if (events & (POLLOUT | POLLWRNORM))
883194612Sed		revents |= events & (POLLOUT | POLLWRNORM);
884193323Sed
885193323Sed	splx(s);
886193323Sed	return (revents);
887193323Sed}
888193323Sed
889193323Sed/*
890193323Sed * tunkqfilter - support for the kevent() system call.
891193323Sed */
892193323Sedstatic int
893193323Sedtunkqfilter(struct cdev *dev, struct knote *kn)
894193323Sed{
895193323Sed	int			s;
896193323Sed	struct tun_softc	*tp = dev->si_drv1;
897193323Sed	struct ifnet	*ifp = TUN2IFP(tp);
898193323Sed
899193323Sed	s = splimp();
900193323Sed	switch(kn->kn_filter) {
901193323Sed	case EVFILT_READ:
902193323Sed		TUNDEBUG(ifp, "%s kqfilter: EVFILT_READ, minor = %#x\n",
903193323Sed		    ifp->if_xname, minor(dev));
904193323Sed		kn->kn_fop = &tun_read_filterops;
905193323Sed		break;
906193323Sed
907193323Sed	case EVFILT_WRITE:
908193323Sed		TUNDEBUG(ifp, "%s kqfilter: EVFILT_WRITE, minor = %#x\n",
909193323Sed		    ifp->if_xname, minor(dev));
910193323Sed		kn->kn_fop = &tun_write_filterops;
911193323Sed		break;
912193323Sed
913193323Sed	default:
914193323Sed		TUNDEBUG(ifp, "%s kqfilter: invalid filter, minor = %#x\n",
915193323Sed		    ifp->if_xname, minor(dev));
916193323Sed		splx(s);
917193323Sed		return(EINVAL);
918193323Sed	}
919193323Sed	splx(s);
920193323Sed
921193323Sed	kn->kn_hook = (caddr_t) dev;
922193323Sed	knlist_add(&tp->tun_rsel.si_note, kn, 0);
923193323Sed
924193323Sed	return (0);
925193323Sed}
926193323Sed
927193323Sed/*
928193323Sed * Return true of there is data in the interface queue.
929193323Sed */
930193323Sedstatic int
931193323Sedtunkqread(struct knote *kn, long hint)
932193323Sed{
933193323Sed	int			ret, s;
934193323Sed	struct cdev		*dev = (struct cdev *)(kn->kn_hook);
935193323Sed	struct tun_softc	*tp = dev->si_drv1;
936193323Sed	struct ifnet	*ifp = TUN2IFP(tp);
937193323Sed
938193323Sed	s = splimp();
939193323Sed	if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) {
940193323Sed		TUNDEBUG(ifp,
941193323Sed		    "%s have data in the queue.  Len = %d, minor = %#x\n",
942193323Sed		    ifp->if_xname, ifp->if_snd.ifq_len, minor(dev));
943193323Sed		ret = 1;
944193323Sed	} else {
945193323Sed		TUNDEBUG(ifp,
946193323Sed		    "%s waiting for data, minor = %#x\n", ifp->if_xname,
947193323Sed		    minor(dev));
948193323Sed		ret = 0;
949193323Sed	}
950193323Sed	splx(s);
951193323Sed
952193323Sed	return (ret);
953193323Sed}
954193323Sed
955194612Sed/*
956193323Sed * Always can write, always return MTU in kn->data.
957193323Sed */
958193323Sedstatic int
959194178Sedtunkqwrite(struct knote *kn, long hint)
960194178Sed{
961194178Sed	int			s;
962194178Sed	struct tun_softc	*tp = ((struct cdev *)kn->kn_hook)->si_drv1;
963194178Sed	struct ifnet	*ifp = TUN2IFP(tp);
964194178Sed
965194178Sed	s = splimp();
966194178Sed	kn->kn_data = ifp->if_mtu;
967194178Sed	splx(s);
968194178Sed
969194178Sed	return (1);
970194178Sed}
971194178Sed
972194178Sedstatic void
973194178Sedtunkqdetach(struct knote *kn)
974194178Sed{
975194178Sed	struct tun_softc	*tp = ((struct cdev *)kn->kn_hook)->si_drv1;
976194178Sed
977194178Sed	knlist_remove(&tp->tun_rsel.si_note, kn, 0);
978194178Sed}
979194178Sed