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