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: stable/10/sys/net/if_tun.c 326692 2017-12-08 15:26:57Z hselasky $ 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 } 680326692Shselasky if (TUN2IFP(tp)->if_type != tunp->type) 681326692Shselasky return (EPROTOTYPE); 682213028Sjhb mtx_lock(&tp->tun_mtx); 683147256Sbrooks TUN2IFP(tp)->if_mtu = tunp->mtu; 684147256Sbrooks TUN2IFP(tp)->if_baudrate = tunp->baudrate; 685213028Sjhb mtx_unlock(&tp->tun_mtx); 686111742Sdes break; 687111742Sdes case TUNGIFINFO: 688111742Sdes tunp = (struct tuninfo *)data; 689213028Sjhb mtx_lock(&tp->tun_mtx); 690147256Sbrooks tunp->mtu = TUN2IFP(tp)->if_mtu; 691147256Sbrooks tunp->type = TUN2IFP(tp)->if_type; 692147256Sbrooks tunp->baudrate = TUN2IFP(tp)->if_baudrate; 693213028Sjhb mtx_unlock(&tp->tun_mtx); 694111742Sdes break; 6956053Samurai case TUNSDEBUG: 6966053Samurai tundebug = *(int *)data; 6976053Samurai break; 6986053Samurai case TUNGDEBUG: 6996053Samurai *(int *)data = tundebug; 7006053Samurai break; 70145014Sdes case TUNSLMODE: 702127591Srwatson mtx_lock(&tp->tun_mtx); 70356410Sbrian if (*(int *)data) { 70445014Sdes tp->tun_flags |= TUN_LMODE; 70556410Sbrian tp->tun_flags &= ~TUN_IFHEAD; 70656410Sbrian } else 70745014Sdes tp->tun_flags &= ~TUN_LMODE; 708127591Srwatson mtx_unlock(&tp->tun_mtx); 70945014Sdes break; 71056410Sbrian case TUNSIFHEAD: 711127591Srwatson mtx_lock(&tp->tun_mtx); 71256410Sbrian if (*(int *)data) { 71356410Sbrian tp->tun_flags |= TUN_IFHEAD; 71456410Sbrian tp->tun_flags &= ~TUN_LMODE; 715111742Sdes } else 71656410Sbrian tp->tun_flags &= ~TUN_IFHEAD; 717127591Srwatson mtx_unlock(&tp->tun_mtx); 71856410Sbrian break; 71956410Sbrian case TUNGIFHEAD: 720127591Srwatson mtx_lock(&tp->tun_mtx); 72156410Sbrian *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0; 722127591Srwatson mtx_unlock(&tp->tun_mtx); 72356410Sbrian break; 72445014Sdes case TUNSIFMODE: 72545014Sdes /* deny this if UP */ 726147256Sbrooks if (TUN2IFP(tp)->if_flags & IFF_UP) 72745014Sdes return(EBUSY); 72845014Sdes 72982319Sbrian switch (*(int *)data & ~IFF_MULTICAST) { 73045014Sdes case IFF_POINTOPOINT: 73145014Sdes case IFF_BROADCAST: 732213028Sjhb mtx_lock(&tp->tun_mtx); 733147256Sbrooks TUN2IFP(tp)->if_flags &= 73482319Sbrian ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST); 735147256Sbrooks TUN2IFP(tp)->if_flags |= *(int *)data; 736213028Sjhb mtx_unlock(&tp->tun_mtx); 73745014Sdes break; 73845014Sdes default: 73945014Sdes return(EINVAL); 74045014Sdes } 74145014Sdes break; 74256349Sbrian case TUNSIFPID: 743127591Srwatson mtx_lock(&tp->tun_mtx); 744127099Srwatson tp->tun_pid = curthread->td_proc->p_pid; 745127591Srwatson mtx_unlock(&tp->tun_mtx); 74656349Sbrian break; 7476053Samurai case FIONBIO: 7486053Samurai break; 7496053Samurai case FIOASYNC: 750127591Srwatson mtx_lock(&tp->tun_mtx); 7516053Samurai if (*(int *)data) 7526053Samurai tp->tun_flags |= TUN_ASYNC; 7536053Samurai else 7546053Samurai tp->tun_flags &= ~TUN_ASYNC; 755127591Srwatson mtx_unlock(&tp->tun_mtx); 7566053Samurai break; 7576053Samurai case FIONREAD: 758147256Sbrooks if (!IFQ_IS_EMPTY(&TUN2IFP(tp)->if_snd)) { 759131455Smlaier struct mbuf *mb; 760147256Sbrooks IFQ_LOCK(&TUN2IFP(tp)->if_snd); 761147256Sbrooks IFQ_POLL_NOLOCK(&TUN2IFP(tp)->if_snd, mb); 762213028Sjhb for (*(int *)data = 0; mb != NULL; mb = mb->m_next) 76312773Speter *(int *)data += mb->m_len; 764147256Sbrooks IFQ_UNLOCK(&TUN2IFP(tp)->if_snd); 76512773Speter } else 7666053Samurai *(int *)data = 0; 7676053Samurai break; 76841086Struckman case FIOSETOWN: 76941086Struckman return (fsetown(*(int *)data, &tp->tun_sigio)); 77041086Struckman 77141086Struckman case FIOGETOWN: 772104393Struckman *(int *)data = fgetown(&tp->tun_sigio); 77341086Struckman return (0); 77441086Struckman 77541086Struckman /* This is deprecated, FIOSETOWN should be used instead. */ 7766053Samurai case TIOCSPGRP: 77741086Struckman return (fsetown(-(*(int *)data), &tp->tun_sigio)); 77841086Struckman 77941086Struckman /* This is deprecated, FIOGETOWN should be used instead. */ 7806053Samurai case TIOCGPGRP: 781104393Struckman *(int *)data = -fgetown(&tp->tun_sigio); 78241086Struckman return (0); 78341086Struckman 7846053Samurai default: 7856053Samurai return (ENOTTY); 7866053Samurai } 7876053Samurai return (0); 7886053Samurai} 7896053Samurai 7906053Samurai/* 7916053Samurai * The cdevsw read interface - reads a packet at a time, or at 7926053Samurai * least as much of a packet as can be read. 7936053Samurai */ 79412675Sjulianstatic int 795130585Sphktunread(struct cdev *dev, struct uio *uio, int flag) 7966053Samurai{ 79749829Sphk struct tun_softc *tp = dev->si_drv1; 798147256Sbrooks struct ifnet *ifp = TUN2IFP(tp); 79990227Sdillon struct mbuf *m; 800213028Sjhb int error=0, len; 8016053Samurai 802121778Sbrooks TUNDEBUG (ifp, "read\n"); 803127591Srwatson mtx_lock(&tp->tun_mtx); 8046053Samurai if ((tp->tun_flags & TUN_READY) != TUN_READY) { 805127591Srwatson mtx_unlock(&tp->tun_mtx); 806121778Sbrooks TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags); 80791275Simp return (EHOSTDOWN); 8086053Samurai } 8096053Samurai 8106053Samurai tp->tun_flags &= ~TUN_RWAIT; 8116053Samurai 8126053Samurai do { 813131455Smlaier IFQ_DEQUEUE(&ifp->if_snd, m); 81490227Sdillon if (m == NULL) { 815139208Sphk if (flag & O_NONBLOCK) { 816213028Sjhb mtx_unlock(&tp->tun_mtx); 81791275Simp return (EWOULDBLOCK); 8186053Samurai } 8196053Samurai tp->tun_flags |= TUN_RWAIT; 820213028Sjhb error = mtx_sleep(tp, &tp->tun_mtx, PCATCH | (PZERO + 1), 821213028Sjhb "tunread", 0); 822213028Sjhb if (error != 0) { 823213028Sjhb mtx_unlock(&tp->tun_mtx); 82491275Simp return (error); 82520098Sjulian } 8266053Samurai } 82790227Sdillon } while (m == NULL); 828213028Sjhb mtx_unlock(&tp->tun_mtx); 8296053Samurai 83090227Sdillon while (m && uio->uio_resid > 0 && error == 0) { 83190227Sdillon len = min(uio->uio_resid, m->m_len); 83281106Sfenner if (len != 0) 833111741Sdes error = uiomove(mtod(m, void *), len, uio); 83490227Sdillon m = m_free(m); 8356053Samurai } 8366053Samurai 83790227Sdillon if (m) { 838121778Sbrooks TUNDEBUG(ifp, "Dropping mbuf\n"); 83990227Sdillon m_freem(m); 8406053Samurai } 84191275Simp return (error); 8426053Samurai} 8436053Samurai 8446053Samurai/* 8456053Samurai * the cdevsw write interface - an atomic write is a packet - or else! 8466053Samurai */ 84712675Sjulianstatic int 848130585Sphktunwrite(struct cdev *dev, struct uio *uio, int flag) 8496053Samurai{ 85049829Sphk struct tun_softc *tp = dev->si_drv1; 851147256Sbrooks struct ifnet *ifp = TUN2IFP(tp); 852137101Sglebius struct mbuf *m; 85367169Sbrian uint32_t family; 854111888Sjlemon int isr; 8556053Samurai 856121778Sbrooks TUNDEBUG(ifp, "tunwrite\n"); 8576053Samurai 858105944Ssimokawa if ((ifp->if_flags & IFF_UP) != IFF_UP) 859105804Ssimokawa /* ignore silently */ 860105804Ssimokawa return (0); 861105804Ssimokawa 86249116Sbrian if (uio->uio_resid == 0) 86391275Simp return (0); 86449116Sbrian 86549116Sbrian if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) { 866194990Skib TUNDEBUG(ifp, "len=%zd!\n", uio->uio_resid); 86791275Simp return (EIO); 8686053Samurai } 8696053Samurai 870243882Sglebius if ((m = m_uiotombuf(uio, M_NOWAIT, 0, 0, M_PKTHDR)) == NULL) { 87157250Smdodd ifp->if_ierrors++; 872222651Sjhb return (ENOBUFS); 8736053Samurai } 8746053Samurai 875137101Sglebius m->m_pkthdr.rcvif = ifp; 876101083Srwatson#ifdef MAC 877172930Srwatson mac_ifnet_create_mbuf(ifp, m); 878101083Srwatson#endif 8796053Samurai 880127591Srwatson /* Could be unlocked read? */ 881127591Srwatson mtx_lock(&tp->tun_mtx); 88256410Sbrian if (tp->tun_flags & TUN_IFHEAD) { 883127591Srwatson mtx_unlock(&tp->tun_mtx); 884137101Sglebius if (m->m_len < sizeof(family) && 885137101Sglebius (m = m_pullup(m, sizeof(family))) == NULL) 88691275Simp return (ENOBUFS); 887137101Sglebius family = ntohl(*mtod(m, u_int32_t *)); 888137101Sglebius m_adj(m, sizeof(family)); 889127591Srwatson } else { 890127591Srwatson mtx_unlock(&tp->tun_mtx); 89156410Sbrian family = AF_INET; 892127591Srwatson } 89356410Sbrian 894137101Sglebius BPF_MTAP2(ifp, &family, sizeof(family), m); 895123922Ssam 896111888Sjlemon switch (family) { 897111888Sjlemon#ifdef INET 898111888Sjlemon case AF_INET: 899111888Sjlemon isr = NETISR_IP; 900111888Sjlemon break; 901111888Sjlemon#endif 902111999Sjlemon#ifdef INET6 903111999Sjlemon case AF_INET6: 904111999Sjlemon isr = NETISR_IPV6; 905111999Sjlemon break; 906111999Sjlemon#endif 907111999Sjlemon#ifdef IPX 908111999Sjlemon case AF_IPX: 909111999Sjlemon isr = NETISR_IPX; 910111999Sjlemon break; 911111999Sjlemon#endif 912111999Sjlemon#ifdef NETATALK 913111999Sjlemon case AF_APPLETALK: 914111999Sjlemon isr = NETISR_ATALK2; 915111999Sjlemon break; 916111999Sjlemon#endif 917111888Sjlemon default: 918111888Sjlemon m_freem(m); 919111888Sjlemon return (EAFNOSUPPORT); 920111888Sjlemon } 921111888Sjlemon if (harvest.point_to_point) 922256381Smarkm random_harvest(&(m->m_data), 12, 2, RANDOM_NET_TUN); 923137101Sglebius ifp->if_ibytes += m->m_pkthdr.len; 92457250Smdodd ifp->if_ipackets++; 925183550Szec CURVNET_SET(ifp->if_vnet); 926223741Sbz M_SETFIB(m, ifp->if_fib); 927137101Sglebius netisr_dispatch(isr, m); 928183550Szec CURVNET_RESTORE(); 929111888Sjlemon return (0); 9306053Samurai} 9316053Samurai 9326053Samurai/* 93329365Speter * tunpoll - the poll interface, this is only useful on reads 9346053Samurai * really. The write detect always returns true, write never blocks 9356053Samurai * anyway, it either accepts the packet or drops it. 9366053Samurai */ 93712675Sjulianstatic int 938130585Sphktunpoll(struct cdev *dev, int events, struct thread *td) 9396053Samurai{ 94049829Sphk struct tun_softc *tp = dev->si_drv1; 941147256Sbrooks struct ifnet *ifp = TUN2IFP(tp); 94229365Speter int revents = 0; 943131455Smlaier struct mbuf *m; 9446053Samurai 945121778Sbrooks TUNDEBUG(ifp, "tunpoll\n"); 9466735Samurai 94746568Speter if (events & (POLLIN | POLLRDNORM)) { 948131455Smlaier IFQ_LOCK(&ifp->if_snd); 949131455Smlaier IFQ_POLL_NOLOCK(&ifp->if_snd, m); 950131455Smlaier if (m != NULL) { 951121778Sbrooks TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len); 95229365Speter revents |= events & (POLLIN | POLLRDNORM); 95329365Speter } else { 954121778Sbrooks TUNDEBUG(ifp, "tunpoll waiting\n"); 95583805Sjhb selrecord(td, &tp->tun_rsel); 9566053Samurai } 957131455Smlaier IFQ_UNLOCK(&ifp->if_snd); 95846568Speter } 95929365Speter if (events & (POLLOUT | POLLWRNORM)) 96029365Speter revents |= events & (POLLOUT | POLLWRNORM); 96129365Speter 96229365Speter return (revents); 9636053Samurai} 964161103Srwatson 965161103Srwatson/* 966161103Srwatson * tunkqfilter - support for the kevent() system call. 967161103Srwatson */ 968161103Srwatsonstatic int 969161103Srwatsontunkqfilter(struct cdev *dev, struct knote *kn) 970161103Srwatson{ 971161103Srwatson struct tun_softc *tp = dev->si_drv1; 972161103Srwatson struct ifnet *ifp = TUN2IFP(tp); 973161103Srwatson 974161103Srwatson switch(kn->kn_filter) { 975161103Srwatson case EVFILT_READ: 976161103Srwatson TUNDEBUG(ifp, "%s kqfilter: EVFILT_READ, minor = %#x\n", 977183397Sed ifp->if_xname, dev2unit(dev)); 978161103Srwatson kn->kn_fop = &tun_read_filterops; 979161103Srwatson break; 980161103Srwatson 981161103Srwatson case EVFILT_WRITE: 982161103Srwatson TUNDEBUG(ifp, "%s kqfilter: EVFILT_WRITE, minor = %#x\n", 983183397Sed ifp->if_xname, dev2unit(dev)); 984161103Srwatson kn->kn_fop = &tun_write_filterops; 985161103Srwatson break; 986221552Syongari 987161103Srwatson default: 988161103Srwatson TUNDEBUG(ifp, "%s kqfilter: invalid filter, minor = %#x\n", 989183397Sed ifp->if_xname, dev2unit(dev)); 990161103Srwatson return(EINVAL); 991161103Srwatson } 992161103Srwatson 993213028Sjhb kn->kn_hook = tp; 994161103Srwatson knlist_add(&tp->tun_rsel.si_note, kn, 0); 995161103Srwatson 996161103Srwatson return (0); 997161103Srwatson} 998161103Srwatson 999161103Srwatson/* 1000161103Srwatson * Return true of there is data in the interface queue. 1001161103Srwatson */ 1002161103Srwatsonstatic int 1003161103Srwatsontunkqread(struct knote *kn, long hint) 1004161103Srwatson{ 1005213028Sjhb int ret; 1006213028Sjhb struct tun_softc *tp = kn->kn_hook; 1007213028Sjhb struct cdev *dev = tp->tun_dev; 1008161103Srwatson struct ifnet *ifp = TUN2IFP(tp); 1009161103Srwatson 1010161103Srwatson if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) { 1011161103Srwatson TUNDEBUG(ifp, 1012161103Srwatson "%s have data in the queue. Len = %d, minor = %#x\n", 1013183397Sed ifp->if_xname, ifp->if_snd.ifq_len, dev2unit(dev)); 1014161103Srwatson ret = 1; 1015161103Srwatson } else { 1016161103Srwatson TUNDEBUG(ifp, 1017161103Srwatson "%s waiting for data, minor = %#x\n", ifp->if_xname, 1018183397Sed dev2unit(dev)); 1019161103Srwatson ret = 0; 1020161103Srwatson } 1021161103Srwatson 1022161103Srwatson return (ret); 1023161103Srwatson} 1024161103Srwatson 1025161103Srwatson/* 1026161103Srwatson * Always can write, always return MTU in kn->data. 1027161103Srwatson */ 1028161103Srwatsonstatic int 1029161103Srwatsontunkqwrite(struct knote *kn, long hint) 1030161103Srwatson{ 1031213028Sjhb struct tun_softc *tp = kn->kn_hook; 1032161103Srwatson struct ifnet *ifp = TUN2IFP(tp); 1033161103Srwatson 1034161103Srwatson kn->kn_data = ifp->if_mtu; 1035161103Srwatson 1036161103Srwatson return (1); 1037161103Srwatson} 1038161103Srwatson 1039161103Srwatsonstatic void 1040161103Srwatsontunkqdetach(struct knote *kn) 1041161103Srwatson{ 1042213028Sjhb struct tun_softc *tp = kn->kn_hook; 1043161103Srwatson 1044161103Srwatson knlist_remove(&tp->tun_rsel.si_note, kn, 0); 1045161103Srwatson} 1046