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 10277589Sbrian#define TUNNAME "tun" 10349829Sphk 104127580Srwatson/* 105127580Srwatson * All mutable global variables in if_tun are locked using tunmtx, with 106127580Srwatson * the exception of tundebug, which is used unlocked, and tunclones, 107127580Srwatson * which is static after setup. 108127580Srwatson */ 109127580Srwatsonstatic struct mtx tunmtx; 11077589Sbrianstatic 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); 118248085Smariusstatic 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 *); 13177589Sbrianstatic int tunoutput(struct ifnet *, struct mbuf *, struct sockaddr *, 132191148Skmacy 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 *); 137166497Sbms 138166497SbmsIFC_SIMPLE_DECLARE(tun, 0); 139166497Sbms 14077589Sbrianstatic d_open_t tunopen; 14177589Sbrianstatic d_close_t tunclose; 14277589Sbrianstatic d_read_t tunread; 14377589Sbrianstatic d_write_t tunwrite; 14477589Sbrianstatic d_ioctl_t tunioctl; 14577589Sbrianstatic d_poll_t tunpoll; 146161103Srwatsonstatic d_kqfilter_t tunkqfilter; 14712675Sjulian 148161103Srwatsonstatic int tunkqread(struct knote *, long); 149161103Srwatsonstatic int tunkqwrite(struct knote *, long); 150161103Srwatsonstatic void tunkqdetach(struct knote *); 151161103Srwatson 152161103Srwatsonstatic struct filterops tun_read_filterops = { 153161103Srwatson .f_isfd = 1, 154161103Srwatson .f_attach = NULL, 155161103Srwatson .f_detach = tunkqdetach, 156161103Srwatson .f_event = tunkqread, 157161103Srwatson}; 158161103Srwatson 159161103Srwatsonstatic struct filterops tun_write_filterops = { 160161103Srwatson .f_isfd = 1, 161161103Srwatson .f_attach = NULL, 162161103Srwatson .f_detach = tunkqdetach, 163161103Srwatson .f_event = tunkqwrite, 164161103Srwatson}; 165161103Srwatson 16612675Sjulianstatic struct cdevsw tun_cdevsw = { 167126080Sphk .d_version = D_VERSION, 168213028Sjhb .d_flags = D_PSEUDO | D_NEEDMINOR, 169111815Sphk .d_open = tunopen, 170111815Sphk .d_close = tunclose, 171111815Sphk .d_read = tunread, 172111815Sphk .d_write = tunwrite, 173111815Sphk .d_ioctl = tunioctl, 174111815Sphk .d_poll = tunpoll, 175161103Srwatson .d_kqfilter = tunkqfilter, 176111815Sphk .d_name = TUNNAME, 17712118Sbde}; 1787747Swollman 179166497Sbmsstatic int 180166497Sbmstun_clone_create(struct if_clone *ifc, int unit, caddr_t params) 181166497Sbms{ 182166497Sbms struct cdev *dev; 183166497Sbms int i; 184166497Sbms 185166497Sbms /* find any existing device, or allocate new unit number */ 186166497Sbms i = clone_create(&tunclones, &tun_cdevsw, &unit, &dev, 0); 187166497Sbms if (i) { 188166497Sbms /* No preexisting struct cdev *, create one */ 189183381Sed dev = make_dev(&tun_cdevsw, unit, 190166497Sbms UID_UUCP, GID_DIALER, 0600, "%s%d", ifc->ifc_name, unit); 191166497Sbms } 192166497Sbms tuncreate(ifc->ifc_name, dev); 193166497Sbms 194166497Sbms return (0); 195166497Sbms} 196166497Sbms 19710429Sbdestatic void 198148868Srwatsontunclone(void *arg, struct ucred *cred, char *name, int namelen, 199148868Srwatson struct cdev **dev) 20064880Sphk{ 201166497Sbms char devname[SPECNAMELEN + 1]; 202166497Sbms int u, i, append_unit; 20364880Sphk 204130640Sphk if (*dev != NULL) 20564880Sphk return; 20677589Sbrian 207166497Sbms /* 208166497Sbms * If tun cloning is enabled, only the superuser can create an 209166497Sbms * interface. 210166497Sbms */ 211166497Sbms if (!tundclone || priv_check_cred(cred, PRIV_NET_IFCREATE, 0) != 0) 212166497Sbms return; 213166497Sbms 21477589Sbrian if (strcmp(name, TUNNAME) == 0) { 215126077Sphk u = -1; 21677589Sbrian } else if (dev_stdclone(name, NULL, TUNNAME, &u) != 1) 21777589Sbrian return; /* Don't recognise the name */ 218126077Sphk if (u != -1 && u > IF_MAXUNIT) 219126077Sphk return; /* Unit number too high */ 22077589Sbrian 221166497Sbms if (u == -1) 222166497Sbms append_unit = 1; 223166497Sbms else 224166497Sbms append_unit = 0; 225166497Sbms 226194252Sjamie CURVNET_SET(CRED_TO_VNET(cred)); 227126077Sphk /* find any existing device, or allocate new unit number */ 228126077Sphk i = clone_create(&tunclones, &tun_cdevsw, &u, dev, 0); 229126077Sphk if (i) { 230166497Sbms if (append_unit) { 231221552Syongari namelen = snprintf(devname, sizeof(devname), "%s%d", 232221552Syongari name, u); 233166497Sbms name = devname; 234166497Sbms } 235130585Sphk /* No preexisting struct cdev *, create one */ 236204464Skib *dev = make_dev_credf(MAKEDEV_REF, &tun_cdevsw, u, cred, 237166497Sbms UID_UUCP, GID_DIALER, 0600, "%s", name); 23877589Sbrian } 239166497Sbms 240166497Sbms if_clone_create(name, namelen, NULL); 241183550Szec CURVNET_RESTORE(); 24264880Sphk} 24364880Sphk 244127580Srwatsonstatic void 245127580Srwatsontun_destroy(struct tun_softc *tp) 246127580Srwatson{ 247130585Sphk struct cdev *dev; 248127580Srwatson 249127591Srwatson /* Unlocked read. */ 250186391Sqingli mtx_lock(&tp->tun_mtx); 251186497Sqingli if ((tp->tun_flags & TUN_OPEN) != 0) 252186391Sqingli cv_wait_unlock(&tp->tun_cv, &tp->tun_mtx); 253186483Skmacy else 254186483Skmacy mtx_unlock(&tp->tun_mtx); 255186497Sqingli 256183550Szec CURVNET_SET(TUN2IFP(tp)->if_vnet); 257127580Srwatson dev = tp->tun_dev; 258147256Sbrooks bpfdetach(TUN2IFP(tp)); 259147256Sbrooks if_detach(TUN2IFP(tp)); 260147256Sbrooks if_free(TUN2IFP(tp)); 261127580Srwatson destroy_dev(dev); 262225177Sattilio seldrain(&tp->tun_rsel); 263161103Srwatson knlist_destroy(&tp->tun_rsel.si_note); 264127591Srwatson mtx_destroy(&tp->tun_mtx); 265186391Sqingli cv_destroy(&tp->tun_cv); 266127580Srwatson free(tp, M_TUN); 267183550Szec CURVNET_RESTORE(); 268127580Srwatson} 269127580Srwatson 270166497Sbmsstatic void 271166497Sbmstun_clone_destroy(struct ifnet *ifp) 272166497Sbms{ 273166497Sbms struct tun_softc *tp = ifp->if_softc; 274166497Sbms 275166497Sbms mtx_lock(&tunmtx); 276166497Sbms TAILQ_REMOVE(&tunhead, tp, tun_list); 277166497Sbms mtx_unlock(&tunmtx); 278166497Sbms tun_destroy(tp); 279166497Sbms} 280166497Sbms 28171862Speterstatic int 282111742Sdestunmodevent(module_t mod, int type, void *data) 28375103Sbrian{ 28475103Sbrian static eventhandler_tag tag; 28575103Sbrian struct tun_softc *tp; 28675103Sbrian 287111742Sdes switch (type) { 288111742Sdes case MOD_LOAD: 289127580Srwatson mtx_init(&tunmtx, "tunmtx", NULL, MTX_DEF); 290126845Sphk clone_setup(&tunclones); 29177589Sbrian tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000); 29275103Sbrian if (tag == NULL) 29375103Sbrian return (ENOMEM); 294166497Sbms if_clone_attach(&tun_cloner); 295111742Sdes break; 296111742Sdes case MOD_UNLOAD: 297166497Sbms 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, 32171862Speter 0 322111742Sdes}; 3236053Samurai 32471862SpeterDECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 325254310SmarkjMODULE_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 365126077Sphk dev->si_flags &= ~SI_CHEAPCLONE; 36649829Sphk 367184205Sdes sc = malloc(sizeof(*sc), M_TUN, M_WAITOK | M_ZERO); 368127591Srwatson mtx_init(&sc->tun_mtx, "tun_mtx", NULL, MTX_DEF); 369186391Sqingli cv_init(&sc->tun_cv, "tun_condvar"); 37049829Sphk sc->tun_flags = TUN_INITED; 371126077Sphk sc->tun_dev = dev; 372127580Srwatson mtx_lock(&tunmtx); 373126077Sphk TAILQ_INSERT_TAIL(&tunhead, sc, tun_list); 374127580Srwatson mtx_unlock(&tunmtx); 37549829Sphk 376147256Sbrooks ifp = sc->tun_ifp = if_alloc(IFT_PPP); 377147256Sbrooks if (ifp == NULL) 378147256Sbrooks panic("%s%d: failed to if_alloc() interface.\n", 379166497Sbms name, dev2unit(dev)); 380166497Sbms if_initname(ifp, name, dev2unit(dev)); 38149829Sphk ifp->if_mtu = TUNMTU; 38249829Sphk ifp->if_ioctl = tunifioctl; 38349829Sphk ifp->if_output = tunoutput; 38469621Sjlemon ifp->if_start = tunstart; 38549829Sphk ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 38649829Sphk ifp->if_softc = sc; 387131455Smlaier IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); 388131455Smlaier ifp->if_snd.ifq_drv_maxlen = 0; 389131455Smlaier IFQ_SET_READY(&ifp->if_snd); 390213028Sjhb knlist_init_mtx(&sc->tun_rsel.si_note, &sc->tun_mtx); 391205222Sqingli ifp->if_capabilities |= IFCAP_LINKSTATE; 392205222Sqingli ifp->if_capenable |= IFCAP_LINKSTATE; 393131455Smlaier 39449829Sphk if_attach(ifp); 395147611Sdwmalone bpfattach(ifp, DLT_NULL, sizeof(u_int32_t)); 39649829Sphk dev->si_drv1 = sc; 397161103Srwatson TUNDEBUG(ifp, "interface %s is created, minor = %#x\n", 398183397Sed ifp->if_xname, dev2unit(dev)); 3996053Samurai} 4006053Samurai 40177589Sbrianstatic int 402130585Sphktunopen(struct cdev *dev, int flag, int mode, struct thread *td) 4036053Samurai{ 4046053Samurai struct ifnet *ifp; 4056053Samurai struct tun_softc *tp; 4066053Samurai 407127591Srwatson /* 408127591Srwatson * XXXRW: Non-atomic test and set of dev->si_drv1 requires 409127591Srwatson * synchronization. 410127591Srwatson */ 41149829Sphk tp = dev->si_drv1; 41249829Sphk if (!tp) { 413166497Sbms tuncreate(TUNNAME, dev); 41449829Sphk tp = dev->si_drv1; 41549829Sphk } 416126077Sphk 417127591Srwatson /* 418127591Srwatson * XXXRW: This use of tun_pid is subject to error due to the 419127591Srwatson * fact that a reference to the tunnel can live beyond the 420127591Srwatson * death of the process that created it. Can we replace this 421127591Srwatson * with a simple busy flag? 422127591Srwatson */ 423127591Srwatson mtx_lock(&tp->tun_mtx); 424127591Srwatson if (tp->tun_pid != 0 && tp->tun_pid != td->td_proc->p_pid) { 425127591Srwatson mtx_unlock(&tp->tun_mtx); 426126077Sphk return (EBUSY); 427127591Srwatson } 428127099Srwatson tp->tun_pid = td->td_proc->p_pid; 429126077Sphk 430126077Sphk tp->tun_flags |= TUN_OPEN; 431147256Sbrooks ifp = TUN2IFP(tp); 432185963Scsjp if_link_state_change(ifp, LINK_STATE_UP); 433121778Sbrooks TUNDEBUG(ifp, "open\n"); 434213028Sjhb mtx_unlock(&tp->tun_mtx); 43577589Sbrian 4366053Samurai return (0); 4376053Samurai} 4386053Samurai 4396053Samurai/* 4406053Samurai * tunclose - close the device - mark i/f down & delete 4416053Samurai * routing info 4426053Samurai */ 44312675Sjulianstatic int 444130585Sphktunclose(struct cdev *dev, int foo, int bar, struct thread *td) 4456053Samurai{ 44649829Sphk struct tun_softc *tp; 44777589Sbrian struct ifnet *ifp; 4486053Samurai 44949829Sphk tp = dev->si_drv1; 450147256Sbrooks ifp = TUN2IFP(tp); 45149829Sphk 452127591Srwatson mtx_lock(&tp->tun_mtx); 4536053Samurai tp->tun_flags &= ~TUN_OPEN; 454127099Srwatson tp->tun_pid = 0; 4556053Samurai 4566053Samurai /* 4576053Samurai * junk all pending output 4586053Samurai */ 459183550Szec CURVNET_SET(ifp->if_vnet); 460131455Smlaier IFQ_PURGE(&ifp->if_snd); 4616053Samurai 4626053Samurai if (ifp->if_flags & IFF_UP) { 463213028Sjhb mtx_unlock(&tp->tun_mtx); 4646053Samurai if_down(ifp); 465213028Sjhb mtx_lock(&tp->tun_mtx); 4666053Samurai } 46747550Sbrian 468166512Sbms /* Delete all addresses and routes which reference this interface. */ 469148887Srwatson if (ifp->if_drv_flags & IFF_DRV_RUNNING) { 470111742Sdes struct ifaddr *ifa; 47147550Sbrian 472213028Sjhb ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 473213028Sjhb mtx_unlock(&tp->tun_mtx); 474166512Sbms TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 475166512Sbms /* deal w/IPv4 PtP destination; unlocked read */ 476166512Sbms if (ifa->ifa_addr->sa_family == AF_INET) { 47747550Sbrian rtinit(ifa, (int)RTM_DELETE, 47847550Sbrian tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); 479166512Sbms } else { 480166512Sbms rtinit(ifa, (int)RTM_DELETE, 0); 481166512Sbms } 482166512Sbms } 483166512Sbms if_purgeaddrs(ifp); 484213028Sjhb mtx_lock(&tp->tun_mtx); 48547550Sbrian } 486185963Scsjp if_link_state_change(ifp, LINK_STATE_DOWN); 487183550Szec CURVNET_RESTORE(); 48847550Sbrian 48996122Salfred funsetown(&tp->tun_sigio); 490122352Stanimura selwakeuppri(&tp->tun_rsel, PZERO + 1); 491213028Sjhb KNOTE_LOCKED(&tp->tun_rsel.si_note, 0); 492121778Sbrooks TUNDEBUG (ifp, "closed\n"); 493186391Sqingli 494186391Sqingli cv_broadcast(&tp->tun_cv); 495186391Sqingli mtx_unlock(&tp->tun_mtx); 4966053Samurai return (0); 4976053Samurai} 4986053Samurai 499222651Sjhbstatic void 50077589Sbriantuninit(struct ifnet *ifp) 5016053Samurai{ 502213328Sbz struct tun_softc *tp = ifp->if_softc; 503184679Sbz#ifdef INET 504111742Sdes struct ifaddr *ifa; 505184679Sbz#endif 5066053Samurai 507121778Sbrooks TUNDEBUG(ifp, "tuninit\n"); 5086053Samurai 509213028Sjhb mtx_lock(&tp->tun_mtx); 510148887Srwatson ifp->if_flags |= IFF_UP; 511148887Srwatson ifp->if_drv_flags |= IFF_DRV_RUNNING; 51235067Sphk getmicrotime(&ifp->if_lastchange); 5136053Samurai 514160038Syar#ifdef INET 515195022Srwatson if_addr_rlock(ifp); 516160033Syar TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 517160038Syar if (ifa->ifa_addr->sa_family == AF_INET) { 518160038Syar struct sockaddr_in *si; 5196053Samurai 520160038Syar si = (struct sockaddr_in *)ifa->ifa_addr; 521160038Syar if (si->sin_addr.s_addr) 522160038Syar tp->tun_flags |= TUN_IASET; 5236053Samurai 524160038Syar si = (struct sockaddr_in *)ifa->ifa_dstaddr; 525160038Syar if (si && si->sin_addr.s_addr) 526160038Syar tp->tun_flags |= TUN_DSTADDR; 5276735Samurai } 52832350Seivind } 529195022Srwatson if_addr_runlock(ifp); 530160038Syar#endif 531213028Sjhb mtx_unlock(&tp->tun_mtx); 5326053Samurai} 5336053Samurai 5346053Samurai/* 5356053Samurai * Process an ioctl request. 5366053Samurai */ 537105556Sphkstatic int 53877589Sbriantunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 5396053Samurai{ 54048021Sphk struct ifreq *ifr = (struct ifreq *)data; 54149829Sphk struct tun_softc *tp = ifp->if_softc; 54248021Sphk struct ifstat *ifs; 543213028Sjhb int error = 0; 5446053Samurai 5456053Samurai switch(cmd) { 54648021Sphk case SIOCGIFSTATUS: 54748021Sphk ifs = (struct ifstat *)data; 548127591Srwatson mtx_lock(&tp->tun_mtx); 549127099Srwatson if (tp->tun_pid) 55048021Sphk sprintf(ifs->ascii + strlen(ifs->ascii), 551127099Srwatson "\tOpened by PID %d\n", tp->tun_pid); 552127591Srwatson mtx_unlock(&tp->tun_mtx); 55368250Sjlemon break; 5546053Samurai case SIOCSIFADDR: 555222651Sjhb tuninit(ifp); 556222651Sjhb TUNDEBUG(ifp, "address set\n"); 5576053Samurai break; 5586053Samurai case SIOCSIFDSTADDR: 559222651Sjhb tuninit(ifp); 560222651Sjhb TUNDEBUG(ifp, "destination address set\n"); 5616053Samurai break; 56220559Sfenner case SIOCSIFMTU: 56349469Sbrian ifp->if_mtu = ifr->ifr_mtu; 564121778Sbrooks TUNDEBUG(ifp, "mtu set\n"); 56520559Sfenner break; 56675095Sbrian case SIOCSIFFLAGS: 56711004Swollman case SIOCADDMULTI: 56811004Swollman case SIOCDELMULTI: 56911004Swollman break; 5706053Samurai default: 5716053Samurai error = EINVAL; 5726053Samurai } 5736053Samurai return (error); 5746053Samurai} 5756053Samurai 5766053Samurai/* 5776053Samurai * tunoutput - queue packets from higher level ready to put out. 5786053Samurai */ 579105556Sphkstatic int 580221552Syongaritunoutput(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst, 581221552Syongari struct route *ro) 5826053Samurai{ 58349829Sphk struct tun_softc *tp = ifp->if_softc; 584127591Srwatson u_short cached_tun_flags; 585101083Srwatson int error; 586147611Sdwmalone u_int32_t af; 5876053Samurai 588121778Sbrooks TUNDEBUG (ifp, "tunoutput\n"); 5896053Samurai 590101083Srwatson#ifdef MAC 591172930Srwatson error = mac_ifnet_check_transmit(ifp, m0); 592101083Srwatson if (error) { 593101083Srwatson m_freem(m0); 594101083Srwatson return (error); 595101083Srwatson } 596101083Srwatson#endif 597101083Srwatson 598127591Srwatson /* Could be unlocked read? */ 599127591Srwatson mtx_lock(&tp->tun_mtx); 600127591Srwatson cached_tun_flags = tp->tun_flags; 601127591Srwatson mtx_unlock(&tp->tun_mtx); 602127591Srwatson if ((cached_tun_flags & TUN_READY) != TUN_READY) { 603121778Sbrooks TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags); 6046053Samurai m_freem (m0); 60591275Simp return (EHOSTDOWN); 6066053Samurai } 6076053Samurai 608105944Ssimokawa if ((ifp->if_flags & IFF_UP) != IFF_UP) { 609105804Ssimokawa m_freem (m0); 610105804Ssimokawa return (EHOSTDOWN); 611105804Ssimokawa } 612105804Ssimokawa 613147611Sdwmalone /* BPF writes need to be handled specially. */ 61411004Swollman if (dst->sa_family == AF_UNSPEC) { 615147611Sdwmalone bcopy(dst->sa_data, &af, sizeof(af)); 616147611Sdwmalone dst->sa_family = af; 61711004Swollman } 61811004Swollman 619159180Scsjp if (bpf_peers_present(ifp->if_bpf)) { 620147611Sdwmalone af = dst->sa_family; 621123922Ssam bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m0); 6226053Samurai } 6236053Samurai 62445014Sdes /* prepend sockaddr? this may abort if the mbuf allocation fails */ 625127591Srwatson if (cached_tun_flags & TUN_LMODE) { 62645014Sdes /* allocate space for sockaddr */ 627111119Simp M_PREPEND(m0, dst->sa_len, M_DONTWAIT); 62845014Sdes 62945014Sdes /* if allocation failed drop packet */ 63069152Sjlemon if (m0 == NULL) { 63169152Sjlemon ifp->if_iqdrops++; 63245014Sdes ifp->if_oerrors++; 63345014Sdes return (ENOBUFS); 63445014Sdes } else { 63545014Sdes bcopy(dst, m0->m_data, dst->sa_len); 63645014Sdes } 63745014Sdes } 63845014Sdes 639127591Srwatson if (cached_tun_flags & TUN_IFHEAD) { 64056410Sbrian /* Prepend the address family */ 641111119Simp M_PREPEND(m0, 4, M_DONTWAIT); 64256410Sbrian 64356410Sbrian /* if allocation failed drop packet */ 64469152Sjlemon if (m0 == NULL) { 64569152Sjlemon ifp->if_iqdrops++; 64656410Sbrian ifp->if_oerrors++; 64791275Simp return (ENOBUFS); 64856410Sbrian } else 64956410Sbrian *(u_int32_t *)m0->m_data = htonl(dst->sa_family); 65056410Sbrian } else { 6516053Samurai#ifdef INET 65256410Sbrian if (dst->sa_family != AF_INET) 65356410Sbrian#endif 65456410Sbrian { 6556053Samurai m_freem(m0); 65691275Simp return (EAFNOSUPPORT); 6576053Samurai } 65856410Sbrian } 65956410Sbrian 660185164Skmacy error = (ifp->if_transmit)(ifp, m0); 661221548Syongari if (error) 66291275Simp return (ENOBUFS); 66356410Sbrian ifp->if_opackets++; 66491275Simp return (0); 6656053Samurai} 6666053Samurai 6676053Samurai/* 6686053Samurai * the cdevsw interface is now pretty minimal. 6696053Samurai */ 67012675Sjulianstatic int 671221552Syongaritunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, 672221552Syongari struct thread *td) 6736053Samurai{ 67471946Sbrian int error; 67549829Sphk struct tun_softc *tp = dev->si_drv1; 676111742Sdes struct tuninfo *tunp; 6776053Samurai 6786053Samurai switch (cmd) { 679111742Sdes case TUNSIFINFO: 680111742Sdes tunp = (struct tuninfo *)data; 68149469Sbrian if (tunp->mtu < IF_MINMTU) 68249459Sbrian return (EINVAL); 683164033Srwatson if (TUN2IFP(tp)->if_mtu != tunp->mtu) { 684164033Srwatson error = priv_check(td, PRIV_NET_SETIFMTU); 685164033Srwatson if (error) 686164033Srwatson return (error); 687164033Srwatson } 688213028Sjhb mtx_lock(&tp->tun_mtx); 689147256Sbrooks TUN2IFP(tp)->if_mtu = tunp->mtu; 690147256Sbrooks TUN2IFP(tp)->if_type = tunp->type; 691147256Sbrooks TUN2IFP(tp)->if_baudrate = tunp->baudrate; 692213028Sjhb mtx_unlock(&tp->tun_mtx); 693111742Sdes break; 694111742Sdes case TUNGIFINFO: 695111742Sdes tunp = (struct tuninfo *)data; 696213028Sjhb mtx_lock(&tp->tun_mtx); 697147256Sbrooks tunp->mtu = TUN2IFP(tp)->if_mtu; 698147256Sbrooks tunp->type = TUN2IFP(tp)->if_type; 699147256Sbrooks tunp->baudrate = TUN2IFP(tp)->if_baudrate; 700213028Sjhb mtx_unlock(&tp->tun_mtx); 701111742Sdes break; 7026053Samurai case TUNSDEBUG: 7036053Samurai tundebug = *(int *)data; 7046053Samurai break; 7056053Samurai case TUNGDEBUG: 7066053Samurai *(int *)data = tundebug; 7076053Samurai break; 70845014Sdes case TUNSLMODE: 709127591Srwatson mtx_lock(&tp->tun_mtx); 71056410Sbrian if (*(int *)data) { 71145014Sdes tp->tun_flags |= TUN_LMODE; 71256410Sbrian tp->tun_flags &= ~TUN_IFHEAD; 71356410Sbrian } else 71445014Sdes tp->tun_flags &= ~TUN_LMODE; 715127591Srwatson mtx_unlock(&tp->tun_mtx); 71645014Sdes break; 71756410Sbrian case TUNSIFHEAD: 718127591Srwatson mtx_lock(&tp->tun_mtx); 71956410Sbrian if (*(int *)data) { 72056410Sbrian tp->tun_flags |= TUN_IFHEAD; 72156410Sbrian tp->tun_flags &= ~TUN_LMODE; 722111742Sdes } else 72356410Sbrian tp->tun_flags &= ~TUN_IFHEAD; 724127591Srwatson mtx_unlock(&tp->tun_mtx); 72556410Sbrian break; 72656410Sbrian case TUNGIFHEAD: 727127591Srwatson mtx_lock(&tp->tun_mtx); 72856410Sbrian *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0; 729127591Srwatson mtx_unlock(&tp->tun_mtx); 73056410Sbrian break; 73145014Sdes case TUNSIFMODE: 73245014Sdes /* deny this if UP */ 733147256Sbrooks if (TUN2IFP(tp)->if_flags & IFF_UP) 73445014Sdes return(EBUSY); 73545014Sdes 73682319Sbrian switch (*(int *)data & ~IFF_MULTICAST) { 73745014Sdes case IFF_POINTOPOINT: 73845014Sdes case IFF_BROADCAST: 739213028Sjhb mtx_lock(&tp->tun_mtx); 740147256Sbrooks TUN2IFP(tp)->if_flags &= 74182319Sbrian ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST); 742147256Sbrooks TUN2IFP(tp)->if_flags |= *(int *)data; 743213028Sjhb mtx_unlock(&tp->tun_mtx); 74445014Sdes break; 74545014Sdes default: 74645014Sdes return(EINVAL); 74745014Sdes } 74845014Sdes break; 74956349Sbrian case TUNSIFPID: 750127591Srwatson mtx_lock(&tp->tun_mtx); 751127099Srwatson tp->tun_pid = curthread->td_proc->p_pid; 752127591Srwatson mtx_unlock(&tp->tun_mtx); 75356349Sbrian break; 7546053Samurai case FIONBIO: 7556053Samurai break; 7566053Samurai case FIOASYNC: 757127591Srwatson mtx_lock(&tp->tun_mtx); 7586053Samurai if (*(int *)data) 7596053Samurai tp->tun_flags |= TUN_ASYNC; 7606053Samurai else 7616053Samurai tp->tun_flags &= ~TUN_ASYNC; 762127591Srwatson mtx_unlock(&tp->tun_mtx); 7636053Samurai break; 7646053Samurai case FIONREAD: 765147256Sbrooks if (!IFQ_IS_EMPTY(&TUN2IFP(tp)->if_snd)) { 766131455Smlaier struct mbuf *mb; 767147256Sbrooks IFQ_LOCK(&TUN2IFP(tp)->if_snd); 768147256Sbrooks IFQ_POLL_NOLOCK(&TUN2IFP(tp)->if_snd, mb); 769213028Sjhb for (*(int *)data = 0; mb != NULL; mb = mb->m_next) 77012773Speter *(int *)data += mb->m_len; 771147256Sbrooks IFQ_UNLOCK(&TUN2IFP(tp)->if_snd); 77212773Speter } else 7736053Samurai *(int *)data = 0; 7746053Samurai break; 77541086Struckman case FIOSETOWN: 77641086Struckman return (fsetown(*(int *)data, &tp->tun_sigio)); 77741086Struckman 77841086Struckman case FIOGETOWN: 779104393Struckman *(int *)data = fgetown(&tp->tun_sigio); 78041086Struckman return (0); 78141086Struckman 78241086Struckman /* This is deprecated, FIOSETOWN should be used instead. */ 7836053Samurai case TIOCSPGRP: 78441086Struckman return (fsetown(-(*(int *)data), &tp->tun_sigio)); 78541086Struckman 78641086Struckman /* This is deprecated, FIOGETOWN should be used instead. */ 7876053Samurai case TIOCGPGRP: 788104393Struckman *(int *)data = -fgetown(&tp->tun_sigio); 78941086Struckman return (0); 79041086Struckman 7916053Samurai default: 7926053Samurai return (ENOTTY); 7936053Samurai } 7946053Samurai return (0); 7956053Samurai} 7966053Samurai 7976053Samurai/* 7986053Samurai * The cdevsw read interface - reads a packet at a time, or at 7996053Samurai * least as much of a packet as can be read. 8006053Samurai */ 80112675Sjulianstatic int 802130585Sphktunread(struct cdev *dev, struct uio *uio, int flag) 8036053Samurai{ 80449829Sphk struct tun_softc *tp = dev->si_drv1; 805147256Sbrooks struct ifnet *ifp = TUN2IFP(tp); 80690227Sdillon struct mbuf *m; 807213028Sjhb int error=0, len; 8086053Samurai 809121778Sbrooks TUNDEBUG (ifp, "read\n"); 810127591Srwatson mtx_lock(&tp->tun_mtx); 8116053Samurai if ((tp->tun_flags & TUN_READY) != TUN_READY) { 812127591Srwatson mtx_unlock(&tp->tun_mtx); 813121778Sbrooks TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags); 81491275Simp return (EHOSTDOWN); 8156053Samurai } 8166053Samurai 8176053Samurai tp->tun_flags &= ~TUN_RWAIT; 8186053Samurai 8196053Samurai do { 820131455Smlaier IFQ_DEQUEUE(&ifp->if_snd, m); 82190227Sdillon if (m == NULL) { 822139208Sphk if (flag & O_NONBLOCK) { 823213028Sjhb mtx_unlock(&tp->tun_mtx); 82491275Simp return (EWOULDBLOCK); 8256053Samurai } 8266053Samurai tp->tun_flags |= TUN_RWAIT; 827213028Sjhb error = mtx_sleep(tp, &tp->tun_mtx, PCATCH | (PZERO + 1), 828213028Sjhb "tunread", 0); 829213028Sjhb if (error != 0) { 830213028Sjhb mtx_unlock(&tp->tun_mtx); 83191275Simp return (error); 83220098Sjulian } 8336053Samurai } 83490227Sdillon } while (m == NULL); 835213028Sjhb mtx_unlock(&tp->tun_mtx); 8366053Samurai 83790227Sdillon while (m && uio->uio_resid > 0 && error == 0) { 83890227Sdillon len = min(uio->uio_resid, m->m_len); 83981106Sfenner if (len != 0) 840111741Sdes error = uiomove(mtod(m, void *), len, uio); 84190227Sdillon m = m_free(m); 8426053Samurai } 8436053Samurai 84490227Sdillon if (m) { 845121778Sbrooks TUNDEBUG(ifp, "Dropping mbuf\n"); 84690227Sdillon m_freem(m); 8476053Samurai } 84891275Simp return (error); 8496053Samurai} 8506053Samurai 8516053Samurai/* 8526053Samurai * the cdevsw write interface - an atomic write is a packet - or else! 8536053Samurai */ 85412675Sjulianstatic int 855130585Sphktunwrite(struct cdev *dev, struct uio *uio, int flag) 8566053Samurai{ 85749829Sphk struct tun_softc *tp = dev->si_drv1; 858147256Sbrooks struct ifnet *ifp = TUN2IFP(tp); 859137101Sglebius struct mbuf *m; 86067169Sbrian uint32_t family; 861111888Sjlemon int isr; 8626053Samurai 863121778Sbrooks TUNDEBUG(ifp, "tunwrite\n"); 8646053Samurai 865105944Ssimokawa if ((ifp->if_flags & IFF_UP) != IFF_UP) 866105804Ssimokawa /* ignore silently */ 867105804Ssimokawa return (0); 868105804Ssimokawa 86949116Sbrian if (uio->uio_resid == 0) 87091275Simp return (0); 87149116Sbrian 87249116Sbrian if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) { 873194990Skib TUNDEBUG(ifp, "len=%zd!\n", uio->uio_resid); 87491275Simp return (EIO); 8756053Samurai } 8766053Samurai 877163915Sandre if ((m = m_uiotombuf(uio, M_DONTWAIT, 0, 0, M_PKTHDR)) == NULL) { 87857250Smdodd ifp->if_ierrors++; 879222651Sjhb return (ENOBUFS); 8806053Samurai } 8816053Samurai 882137101Sglebius m->m_pkthdr.rcvif = ifp; 883101083Srwatson#ifdef MAC 884172930Srwatson mac_ifnet_create_mbuf(ifp, m); 885101083Srwatson#endif 8866053Samurai 887127591Srwatson /* Could be unlocked read? */ 888127591Srwatson mtx_lock(&tp->tun_mtx); 88956410Sbrian if (tp->tun_flags & TUN_IFHEAD) { 890127591Srwatson mtx_unlock(&tp->tun_mtx); 891137101Sglebius if (m->m_len < sizeof(family) && 892137101Sglebius (m = m_pullup(m, sizeof(family))) == NULL) 89391275Simp return (ENOBUFS); 894137101Sglebius family = ntohl(*mtod(m, u_int32_t *)); 895137101Sglebius m_adj(m, sizeof(family)); 896127591Srwatson } else { 897127591Srwatson mtx_unlock(&tp->tun_mtx); 89856410Sbrian family = AF_INET; 899127591Srwatson } 90056410Sbrian 901137101Sglebius BPF_MTAP2(ifp, &family, sizeof(family), m); 902123922Ssam 903111888Sjlemon switch (family) { 904111888Sjlemon#ifdef INET 905111888Sjlemon case AF_INET: 906111888Sjlemon isr = NETISR_IP; 907111888Sjlemon break; 908111888Sjlemon#endif 909111999Sjlemon#ifdef INET6 910111999Sjlemon case AF_INET6: 911111999Sjlemon isr = NETISR_IPV6; 912111999Sjlemon break; 913111999Sjlemon#endif 914111999Sjlemon#ifdef IPX 915111999Sjlemon case AF_IPX: 916111999Sjlemon isr = NETISR_IPX; 917111999Sjlemon break; 918111999Sjlemon#endif 919111999Sjlemon#ifdef NETATALK 920111999Sjlemon case AF_APPLETALK: 921111999Sjlemon isr = NETISR_ATALK2; 922111999Sjlemon break; 923111999Sjlemon#endif 924111888Sjlemon default: 925111888Sjlemon m_freem(m); 926111888Sjlemon return (EAFNOSUPPORT); 927111888Sjlemon } 928111888Sjlemon /* First chunk of an mbuf contains good junk */ 929111888Sjlemon if (harvest.point_to_point) 930111888Sjlemon random_harvest(m, 16, 3, 0, RANDOM_NET); 931137101Sglebius ifp->if_ibytes += m->m_pkthdr.len; 93257250Smdodd ifp->if_ipackets++; 933183550Szec CURVNET_SET(ifp->if_vnet); 934223741Sbz M_SETFIB(m, ifp->if_fib); 935137101Sglebius netisr_dispatch(isr, m); 936183550Szec CURVNET_RESTORE(); 937111888Sjlemon return (0); 9386053Samurai} 9396053Samurai 9406053Samurai/* 94129365Speter * tunpoll - the poll interface, this is only useful on reads 9426053Samurai * really. The write detect always returns true, write never blocks 9436053Samurai * anyway, it either accepts the packet or drops it. 9446053Samurai */ 94512675Sjulianstatic int 946130585Sphktunpoll(struct cdev *dev, int events, struct thread *td) 9476053Samurai{ 94849829Sphk struct tun_softc *tp = dev->si_drv1; 949147256Sbrooks struct ifnet *ifp = TUN2IFP(tp); 95029365Speter int revents = 0; 951131455Smlaier struct mbuf *m; 9526053Samurai 953121778Sbrooks TUNDEBUG(ifp, "tunpoll\n"); 9546735Samurai 95546568Speter if (events & (POLLIN | POLLRDNORM)) { 956131455Smlaier IFQ_LOCK(&ifp->if_snd); 957131455Smlaier IFQ_POLL_NOLOCK(&ifp->if_snd, m); 958131455Smlaier if (m != NULL) { 959121778Sbrooks TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len); 96029365Speter revents |= events & (POLLIN | POLLRDNORM); 96129365Speter } else { 962121778Sbrooks TUNDEBUG(ifp, "tunpoll waiting\n"); 96383805Sjhb selrecord(td, &tp->tun_rsel); 9646053Samurai } 965131455Smlaier IFQ_UNLOCK(&ifp->if_snd); 96646568Speter } 96729365Speter if (events & (POLLOUT | POLLWRNORM)) 96829365Speter revents |= events & (POLLOUT | POLLWRNORM); 96929365Speter 97029365Speter return (revents); 9716053Samurai} 972161103Srwatson 973161103Srwatson/* 974161103Srwatson * tunkqfilter - support for the kevent() system call. 975161103Srwatson */ 976161103Srwatsonstatic int 977161103Srwatsontunkqfilter(struct cdev *dev, struct knote *kn) 978161103Srwatson{ 979161103Srwatson struct tun_softc *tp = dev->si_drv1; 980161103Srwatson struct ifnet *ifp = TUN2IFP(tp); 981161103Srwatson 982161103Srwatson switch(kn->kn_filter) { 983161103Srwatson case EVFILT_READ: 984161103Srwatson TUNDEBUG(ifp, "%s kqfilter: EVFILT_READ, minor = %#x\n", 985183397Sed ifp->if_xname, dev2unit(dev)); 986161103Srwatson kn->kn_fop = &tun_read_filterops; 987161103Srwatson break; 988161103Srwatson 989161103Srwatson case EVFILT_WRITE: 990161103Srwatson TUNDEBUG(ifp, "%s kqfilter: EVFILT_WRITE, minor = %#x\n", 991183397Sed ifp->if_xname, dev2unit(dev)); 992161103Srwatson kn->kn_fop = &tun_write_filterops; 993161103Srwatson break; 994221552Syongari 995161103Srwatson default: 996161103Srwatson TUNDEBUG(ifp, "%s kqfilter: invalid filter, minor = %#x\n", 997183397Sed ifp->if_xname, dev2unit(dev)); 998161103Srwatson return(EINVAL); 999161103Srwatson } 1000161103Srwatson 1001213028Sjhb kn->kn_hook = tp; 1002161103Srwatson knlist_add(&tp->tun_rsel.si_note, kn, 0); 1003161103Srwatson 1004161103Srwatson return (0); 1005161103Srwatson} 1006161103Srwatson 1007161103Srwatson/* 1008161103Srwatson * Return true of there is data in the interface queue. 1009161103Srwatson */ 1010161103Srwatsonstatic int 1011161103Srwatsontunkqread(struct knote *kn, long hint) 1012161103Srwatson{ 1013213028Sjhb int ret; 1014213028Sjhb struct tun_softc *tp = kn->kn_hook; 1015213028Sjhb struct cdev *dev = tp->tun_dev; 1016161103Srwatson struct ifnet *ifp = TUN2IFP(tp); 1017161103Srwatson 1018161103Srwatson if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) { 1019161103Srwatson TUNDEBUG(ifp, 1020161103Srwatson "%s have data in the queue. Len = %d, minor = %#x\n", 1021183397Sed ifp->if_xname, ifp->if_snd.ifq_len, dev2unit(dev)); 1022161103Srwatson ret = 1; 1023161103Srwatson } else { 1024161103Srwatson TUNDEBUG(ifp, 1025161103Srwatson "%s waiting for data, minor = %#x\n", ifp->if_xname, 1026183397Sed dev2unit(dev)); 1027161103Srwatson ret = 0; 1028161103Srwatson } 1029161103Srwatson 1030161103Srwatson return (ret); 1031161103Srwatson} 1032161103Srwatson 1033161103Srwatson/* 1034161103Srwatson * Always can write, always return MTU in kn->data. 1035161103Srwatson */ 1036161103Srwatsonstatic int 1037161103Srwatsontunkqwrite(struct knote *kn, long hint) 1038161103Srwatson{ 1039213028Sjhb struct tun_softc *tp = kn->kn_hook; 1040161103Srwatson struct ifnet *ifp = TUN2IFP(tp); 1041161103Srwatson 1042161103Srwatson kn->kn_data = ifp->if_mtu; 1043161103Srwatson 1044161103Srwatson return (1); 1045161103Srwatson} 1046161103Srwatson 1047161103Srwatsonstatic void 1048161103Srwatsontunkqdetach(struct knote *kn) 1049161103Srwatson{ 1050213028Sjhb struct tun_softc *tp = kn->kn_hook; 1051161103Srwatson 1052161103Srwatson knlist_remove(&tp->tun_rsel.si_note, kn, 0); 1053161103Srwatson} 1054