if_tun.c revision 20559
1263367Semaste/* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */ 2254721Semaste 3254721Semaste/* 4254721Semaste * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> 5254721Semaste * Nottingham University 1987. 6254721Semaste * 7254721Semaste * This source may be freely distributed, however I would be interested 8254721Semaste * in any changes that are made. 9254721Semaste * 10254721Semaste * This driver takes packets off the IP i/f and hands them up to a 11254721Semaste * user process to have it's wicked way with. This driver has it's 12254721Semaste * roots in a similar driver written by Phil Cockcroft (formerly) at 13254721Semaste * UCL. This driver is based much more on read/write/select mode of 14254721Semaste * operation though. 15254721Semaste */ 16269024Semaste 17254721Semaste#include "tun.h" 18254721Semaste#if NTUN > 0 19263363Semaste 20263363Semaste#include <sys/param.h> 21269024Semaste#include <sys/proc.h> 22269024Semaste#include <sys/systm.h> 23263363Semaste#include <sys/mbuf.h> 24263363Semaste#include <sys/buf.h> 25254721Semaste#include <sys/protosw.h> 26254721Semaste#include <sys/socket.h> 27254721Semaste#include <sys/ioctl.h> 28254721Semaste#include <sys/errno.h> 29254721Semaste#include <sys/syslog.h> 30254721Semaste#include <sys/select.h> 31254721Semaste#include <sys/file.h> 32254721Semaste#include <sys/signalvar.h> 33254721Semaste#include <sys/kernel.h> 34254721Semaste#include <sys/sysctl.h> 35254721Semaste#ifdef DEVFS 36254721Semaste#include <sys/devfsext.h> 37254721Semaste#endif /*DEVFS*/ 38254721Semaste#include <sys/conf.h> 39254721Semaste 40254721Semaste#include <net/if.h> 41254721Semaste#include <net/netisr.h> 42254721Semaste#include <net/route.h> 43254721Semaste 44254721Semaste#ifdef INET 45254721Semaste#include <netinet/in.h> 46254721Semaste#include <netinet/in_systm.h> 47254721Semaste#include <netinet/in_var.h> 48254721Semaste#include <netinet/ip.h> 49254721Semaste#include <netinet/if_ether.h> 50254721Semaste#endif 51254721Semaste 52254721Semaste#ifdef NS 53254721Semaste#include <netns/ns.h> 54254721Semaste#include <netns/ns_if.h> 55254721Semaste#endif 56254721Semaste 57254721Semaste#include "bpfilter.h" 58254721Semaste#if NBPFILTER > 0 59254721Semaste#include <sys/time.h> 60254721Semaste#include <net/bpf.h> 61254721Semaste#endif 62254721Semaste 63254721Semaste#include <net/if_tun.h> 64254721Semaste 65254721Semastestatic void tunattach __P((void *)); 66254721SemastePSEUDO_SET(tunattach, if_tun); 67254721Semaste 68254721Semaste#define TUNDEBUG if (tundebug) printf 69254721Semastestatic int tundebug = 0; 70254721SemasteSYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, ""); 71254721Semaste 72254721Semastestatic struct tun_softc tunctl[NTUN]; 73254721Semaste 74254721Semastestatic int tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, 75254721Semaste struct rtentry *rt)); 76254721Semastestatic int tunifioctl __P((struct ifnet *, int, caddr_t)); 77254721Semastestatic int tuninit __P((int)); 78254721Semaste 79254721Semastestatic d_open_t tunopen; 80254721Semastestatic d_close_t tunclose; 81254721Semastestatic d_read_t tunread; 82269024Semastestatic d_write_t tunwrite; 83269024Semastestatic d_ioctl_t tunioctl; 84269024Semastestatic d_select_t tunselect; 85269024Semaste 86269024Semaste#define CDEV_MAJOR 52 87254721Semastestatic struct cdevsw tun_cdevsw = { 88254721Semaste tunopen, tunclose, tunread, tunwrite, 89254721Semaste tunioctl, nullstop, noreset, nodevtotty, 90254721Semaste tunselect, nommap, nostrategy, "tun", NULL, -1 91263363Semaste}; 92263363Semaste 93263363Semaste 94263363Semastestatic tun_devsw_installed = 0; 95263363Semaste#ifdef DEVFS 96263363Semastestatic void *tun_devfs_token[NTUN]; 97269024Semaste#endif 98269024Semaste 99269024Semastestatic void 100269024Semastetunattach(dummy) 101269024Semaste void *dummy; 102263363Semaste{ 103263363Semaste register int i; 104263363Semaste struct ifnet *ifp; 105263363Semaste dev_t dev; 106263363Semaste 107263363Semaste if ( tun_devsw_installed ) 108263363Semaste return; 109254721Semaste dev = makedev(CDEV_MAJOR, 0); 110254721Semaste cdevsw_add(&dev, &tun_cdevsw, NULL); 111254721Semaste tun_devsw_installed = 1; 112254721Semaste for ( i = 0; i < NTUN; i++ ) { 113269024Semaste#ifdef DEVFS 114269024Semaste tun_devfs_token[i] = devfs_add_devswf(&tun_cdevsw, i, DV_CHR, 115269024Semaste UID_UUCP, GID_DIALER, 116269024Semaste 0600, "tun%d", i); 117254721Semaste#endif 118254721Semaste tunctl[i].tun_flags = TUN_INITED; 119254721Semaste 120254721Semaste ifp = &tunctl[i].tun_if; 121254721Semaste ifp->if_unit = i; 122254721Semaste ifp->if_name = "tun"; 123254721Semaste ifp->if_mtu = TUNMTU; 124254721Semaste ifp->if_ioctl = tunifioctl; 125254721Semaste ifp->if_output = tunoutput; 126254721Semaste ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 127254721Semaste ifp->if_snd.ifq_maxlen = ifqmaxlen; 128254721Semaste ifp->if_collisions = 0; 129254721Semaste ifp->if_ierrors = 0; 130254721Semaste ifp->if_oerrors = 0; 131254721Semaste ifp->if_ipackets = 0; 132254721Semaste ifp->if_opackets = 0; 133254721Semaste if_attach(ifp); 134254721Semaste#if NBPFILTER > 0 135254721Semaste bpfattach(ifp, DLT_NULL, sizeof(u_int)); 136254721Semaste#endif 137254721Semaste } 138254721Semaste} 139254721Semaste 140254721Semaste/* 141254721Semaste * tunnel open - must be superuser & the device must be 142254721Semaste * configured in 143254721Semaste */ 144254721Semastestatic int 145254721Semastetunopen(dev, flag, mode, p) 146254721Semaste dev_t dev; 147254721Semaste int flag, mode; 148254721Semaste struct proc *p; 149254721Semaste{ 150254721Semaste struct ifnet *ifp; 151254721Semaste struct tun_softc *tp; 152254721Semaste register int unit, error; 153254721Semaste 154254721Semaste error = suser(p->p_ucred, &p->p_acflag); 155254721Semaste if (error) 156254721Semaste return (error); 157269024Semaste 158254721Semaste if ((unit = minor(dev)) >= NTUN) 159254721Semaste return (ENXIO); 160254721Semaste tp = &tunctl[unit]; 161254721Semaste if (tp->tun_flags & TUN_OPEN) 162254721Semaste return EBUSY; 163254721Semaste ifp = &tp->tun_if; 164254721Semaste tp->tun_flags |= TUN_OPEN; 165254721Semaste TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit); 166254721Semaste return (0); 167254721Semaste} 168254721Semaste 169254721Semaste/* 170254721Semaste * tunclose - close the device - mark i/f down & delete 171269024Semaste * routing info 172269024Semaste */ 173269024Semastestatic int 174269024Semastetunclose(dev_t dev, int foo, int bar, struct proc *p) 175269024Semaste{ 176269024Semaste register int unit = minor(dev), s; 177269024Semaste struct tun_softc *tp = &tunctl[unit]; 178269024Semaste struct ifnet *ifp = &tp->tun_if; 179269024Semaste struct mbuf *m; 180269024Semaste 181269024Semaste tp->tun_flags &= ~TUN_OPEN; 182269024Semaste 183254721Semaste /* 184254721Semaste * junk all pending output 185254721Semaste */ 186254721Semaste do { 187269024Semaste s = splimp(); 188269024Semaste IF_DEQUEUE(&ifp->if_snd, m); 189269024Semaste splx(s); 190269024Semaste if (m) 191269024Semaste m_freem(m); 192269024Semaste } while (m); 193269024Semaste 194269024Semaste if (ifp->if_flags & IFF_UP) { 195269024Semaste s = splimp(); 196254721Semaste if_down(ifp); 197254721Semaste if (ifp->if_flags & IFF_RUNNING) { 198254721Semaste /* find internet addresses and delete routes */ 199254721Semaste register struct ifaddr *ifa; 200254721Semaste for (ifa = ifp->if_addrhead.tqh_first; ifa; 201254721Semaste ifa = ifa->ifa_link.tqe_next) { 202254721Semaste if (ifa->ifa_addr->sa_family == AF_INET) { 203254721Semaste rtinit(ifa, (int)RTM_DELETE, 204254721Semaste tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); 205254721Semaste } 206254721Semaste } 207254721Semaste } 208254721Semaste splx(s); 209269024Semaste } 210254721Semaste tp->tun_pgrp = 0; 211254721Semaste selwakeup(&tp->tun_rsel); 212254721Semaste 213254721Semaste TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit); 214254721Semaste return (0); 215254721Semaste} 216254721Semaste 217254721Semastestatic int 218254721Semastetuninit(unit) 219254721Semaste int unit; 220254721Semaste{ 221263363Semaste struct tun_softc *tp = &tunctl[unit]; 222263363Semaste struct ifnet *ifp = &tp->tun_if; 223263363Semaste register struct ifaddr *ifa; 224254721Semaste 225263363Semaste TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit); 226254721Semaste 227254721Semaste ifp->if_flags |= IFF_UP | IFF_RUNNING; 228254721Semaste microtime(&ifp->if_lastchange); 229254721Semaste 230254721Semaste for (ifa = ifp->if_addrhead.tqh_first; ifa; 231269024Semaste ifa = ifa->ifa_link.tqe_next) 232254721Semaste if (ifa->ifa_addr->sa_family == AF_INET) { 233254721Semaste struct sockaddr_in *si; 234254721Semaste 235254721Semaste si = (struct sockaddr_in *)ifa->ifa_addr; 236254721Semaste if (si && si->sin_addr.s_addr) 237254721Semaste tp->tun_flags |= TUN_IASET; 238254721Semaste 239254721Semaste si = (struct sockaddr_in *)ifa->ifa_dstaddr; 240254721Semaste if (si && si->sin_addr.s_addr) 241254721Semaste tp->tun_flags |= TUN_DSTADDR; 242254721Semaste } 243254721Semaste 244254721Semaste return 0; 245254721Semaste} 246254721Semaste 247254721Semaste/* 248254721Semaste * Process an ioctl request. 249254721Semaste */ 250254721Semasteint 251254721Semastetunifioctl(ifp, cmd, data) 252254721Semaste struct ifnet *ifp; 253254721Semaste int cmd; 254254721Semaste caddr_t data; 255254721Semaste{ 256254721Semaste register struct ifreq *ifr = (struct ifreq *)data; 257254721Semaste int error = 0, s; 258254721Semaste 259254721Semaste s = splimp(); 260254721Semaste switch(cmd) { 261254721Semaste case SIOCSIFADDR: 262254721Semaste tuninit(ifp->if_unit); 263254721Semaste TUNDEBUG("%s%d: address set\n", 264254721Semaste ifp->if_name, ifp->if_unit); 265254721Semaste break; 266254721Semaste case SIOCSIFDSTADDR: 267254721Semaste tuninit(ifp->if_unit); 268254721Semaste TUNDEBUG("%s%d: destination address set\n", 269254721Semaste ifp->if_name, ifp->if_unit); 270254721Semaste break; 271254721Semaste case SIOCSIFMTU: 272254721Semaste ifp->if_mtu = ifr->ifr_mtu; 273263367Semaste TUNDEBUG("%s%d: mtu set\n", 274263367Semaste ifp->if_name, ifp->if_unit); 275263367Semaste break; 276263367Semaste case SIOCADDMULTI: 277263367Semaste case SIOCDELMULTI: 278254721Semaste if (ifr == 0) { 279254721Semaste error = EAFNOSUPPORT; /* XXX */ 280263363Semaste break; 281254721Semaste } 282254721Semaste switch (ifr->ifr_addr.sa_family) { 283263363Semaste 284263363Semaste#ifdef INET 285263363Semaste case AF_INET: 286254721Semaste break; 287254721Semaste#endif 288254721Semaste 289254721Semaste default: 290263367Semaste error = EAFNOSUPPORT; 291263367Semaste break; 292263367Semaste } 293263367Semaste break; 294263367Semaste 295263367Semaste 296263367Semaste default: 297263367Semaste error = EINVAL; 298263367Semaste } 299254721Semaste splx(s); 300254721Semaste return (error); 301254721Semaste} 302254721Semaste 303254721Semaste/* 304254721Semaste * tunoutput - queue packets from higher level ready to put out. 305254721Semaste */ 306254721Semasteint 307254721Semastetunoutput(ifp, m0, dst, rt) 308254721Semaste struct ifnet *ifp; 309269024Semaste struct mbuf *m0; 310269024Semaste struct sockaddr *dst; 311269024Semaste struct rtentry *rt; 312269024Semaste{ 313254721Semaste struct tun_softc *tp = &tunctl[ifp->if_unit]; 314254721Semaste struct proc *p; 315254721Semaste int s; 316254721Semaste 317263363Semaste TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit); 318263363Semaste 319263363Semaste if ((tp->tun_flags & TUN_READY) != TUN_READY) { 320263363Semaste TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 321263363Semaste ifp->if_unit, tp->tun_flags); 322263363Semaste m_freem (m0); 323263363Semaste return EHOSTDOWN; 324263363Semaste } 325263363Semaste 326263363Semaste#if NBPFILTER > 0 327263363Semaste /* BPF write needs to be handled specially */ 328263367Semaste if (dst->sa_family == AF_UNSPEC) { 329263363Semaste dst->sa_family = *(mtod(m0, int *)); 330263363Semaste m0->m_len -= sizeof(int); 331263363Semaste m0->m_pkthdr.len -= sizeof(int); 332263363Semaste m0->m_data += sizeof(int); 333263363Semaste } 334263363Semaste 335263363Semaste if (ifp->if_bpf) { 336263363Semaste /* 337263363Semaste * We need to prepend the address family as 338263363Semaste * a four byte field. Cons up a dummy header 339263363Semaste * to pacify bpf. This is safe because bpf 340263363Semaste * will only read from the mbuf (i.e., it won't 341263363Semaste * try to free it or keep a pointer to it). 342263363Semaste */ 343263363Semaste struct mbuf m; 344263363Semaste u_int af = dst->sa_family; 345263363Semaste 346263363Semaste m.m_next = m0; 347263363Semaste m.m_len = 4; 348263363Semaste m.m_data = (char *)⁡ 349263363Semaste 350263363Semaste bpf_mtap(ifp, &m); 351263363Semaste } 352263363Semaste#endif 353263367Semaste 354263363Semaste switch(dst->sa_family) { 355263363Semaste#ifdef INET 356263363Semaste case AF_INET: 357263363Semaste s = splimp(); 358263363Semaste if (IF_QFULL(&ifp->if_snd)) { 359263363Semaste IF_DROP(&ifp->if_snd); 360263363Semaste m_freem(m0); 361263363Semaste splx(s); 362263363Semaste ifp->if_collisions++; 363263363Semaste return (ENOBUFS); 364254721Semaste } 365254721Semaste ifp->if_obytes += m0->m_pkthdr.len; 366254721Semaste IF_ENQUEUE(&ifp->if_snd, m0); 367254721Semaste splx(s); 368269024Semaste ifp->if_opackets++; 369254721Semaste break; 370269024Semaste#endif 371269024Semaste default: 372254721Semaste m_freem(m0); 373269024Semaste return EAFNOSUPPORT; 374269024Semaste } 375269024Semaste 376269024Semaste if (tp->tun_flags & TUN_RWAIT) { 377269024Semaste tp->tun_flags &= ~TUN_RWAIT; 378269024Semaste wakeup((caddr_t)tp); 379269024Semaste } 380269024Semaste if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) { 381269024Semaste if (tp->tun_pgrp > 0) 382269024Semaste gsignal(tp->tun_pgrp, SIGIO); 383269024Semaste else if ((p = pfind(-tp->tun_pgrp)) != 0) 384269024Semaste psignal(p, SIGIO); 385269024Semaste } 386254721Semaste selwakeup(&tp->tun_rsel); 387254721Semaste return 0; 388254721Semaste} 389254721Semaste 390254721Semaste/* 391254721Semaste * the cdevsw interface is now pretty minimal. 392254721Semaste */ 393254721Semastestatic int 394254721Semastetunioctl(dev, cmd, data, flag, p) 395254721Semaste dev_t dev; 396254721Semaste int cmd; 397254721Semaste caddr_t data; 398254721Semaste int flag; 399254721Semaste struct proc *p; 400254721Semaste{ 401254721Semaste int unit = minor(dev), s; 402254721Semaste struct tun_softc *tp = &tunctl[unit]; 403254721Semaste struct tuninfo *tunp; 404254721Semaste 405254721Semaste switch (cmd) { 406254721Semaste case TUNSIFINFO: 407254721Semaste tunp = (struct tuninfo *)data; 408254721Semaste tp->tun_if.if_mtu = tunp->mtu; 409254721Semaste tp->tun_if.if_type = tunp->type; 410254721Semaste tp->tun_if.if_baudrate = tunp->baudrate; 411254721Semaste break; 412254721Semaste case TUNGIFINFO: 413254721Semaste tunp = (struct tuninfo *)data; 414254721Semaste tunp->mtu = tp->tun_if.if_mtu; 415254721Semaste tunp->type = tp->tun_if.if_type; 416254721Semaste tunp->baudrate = tp->tun_if.if_baudrate; 417254721Semaste break; 418254721Semaste case TUNSDEBUG: 419254721Semaste tundebug = *(int *)data; 420254721Semaste break; 421254721Semaste case TUNGDEBUG: 422254721Semaste *(int *)data = tundebug; 423254721Semaste break; 424254721Semaste case FIONBIO: 425254721Semaste if (*(int *)data) 426254721Semaste tp->tun_flags |= TUN_NBIO; 427254721Semaste else 428254721Semaste tp->tun_flags &= ~TUN_NBIO; 429254721Semaste break; 430254721Semaste case FIOASYNC: 431254721Semaste if (*(int *)data) 432254721Semaste tp->tun_flags |= TUN_ASYNC; 433254721Semaste else 434254721Semaste tp->tun_flags &= ~TUN_ASYNC; 435254721Semaste break; 436254721Semaste case FIONREAD: 437254721Semaste s = splimp(); 438254721Semaste if (tp->tun_if.if_snd.ifq_head) { 439254721Semaste struct mbuf *mb = tp->tun_if.if_snd.ifq_head; 440254721Semaste for( *(int *)data = 0; mb != 0; mb = mb->m_next) 441254721Semaste *(int *)data += mb->m_len; 442254721Semaste } else 443254721Semaste *(int *)data = 0; 444254721Semaste splx(s); 445254721Semaste break; 446254721Semaste case TIOCSPGRP: 447254721Semaste tp->tun_pgrp = *(int *)data; 448254721Semaste break; 449254721Semaste case TIOCGPGRP: 450254721Semaste *(int *)data = tp->tun_pgrp; 451254721Semaste break; 452254721Semaste default: 453254721Semaste return (ENOTTY); 454254721Semaste } 455254721Semaste return (0); 456254721Semaste} 457254721Semaste 458254721Semaste/* 459254721Semaste * The cdevsw read interface - reads a packet at a time, or at 460254721Semaste * least as much of a packet as can be read. 461254721Semaste */ 462254721Semastestatic int 463254721Semastetunread(dev_t dev, struct uio *uio, int flag) 464254721Semaste{ 465254721Semaste int unit = minor(dev); 466254721Semaste struct tun_softc *tp = &tunctl[unit]; 467254721Semaste struct ifnet *ifp = &tp->tun_if; 468254721Semaste struct mbuf *m, *m0; 469254721Semaste int error=0, len, s; 470254721Semaste 471254721Semaste TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit); 472254721Semaste if ((tp->tun_flags & TUN_READY) != TUN_READY) { 473254721Semaste TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 474254721Semaste ifp->if_unit, tp->tun_flags); 475254721Semaste return EHOSTDOWN; 476254721Semaste } 477254721Semaste 478254721Semaste tp->tun_flags &= ~TUN_RWAIT; 479254721Semaste 480254721Semaste s = splimp(); 481254721Semaste do { 482254721Semaste IF_DEQUEUE(&ifp->if_snd, m0); 483254721Semaste if (m0 == 0) { 484254721Semaste if (tp->tun_flags & TUN_NBIO) { 485254721Semaste splx(s); 486254721Semaste return EWOULDBLOCK; 487254721Semaste } 488254721Semaste tp->tun_flags |= TUN_RWAIT; 489254721Semaste if( error = tsleep((caddr_t)tp, PCATCH | (PZERO + 1), 490254721Semaste "tunread", 0)) { 491254721Semaste splx(s); 492254721Semaste return error; 493254721Semaste } 494254721Semaste } 495254721Semaste } while (m0 == 0); 496254721Semaste splx(s); 497254721Semaste 498254721Semaste while (m0 && uio->uio_resid > 0 && error == 0) { 499254721Semaste len = min(uio->uio_resid, m0->m_len); 500254721Semaste if (len == 0) 501254721Semaste break; 502254721Semaste error = uiomove(mtod(m0, caddr_t), len, uio); 503254721Semaste MFREE(m0, m); 504254721Semaste m0 = m; 505254721Semaste } 506254721Semaste 507254721Semaste if (m0) { 508254721Semaste TUNDEBUG("Dropping mbuf\n"); 509254721Semaste m_freem(m0); 510254721Semaste } 511254721Semaste return error; 512254721Semaste} 513254721Semaste 514254721Semaste/* 515254721Semaste * the cdevsw write interface - an atomic write is a packet - or else! 516254721Semaste */ 517254721Semastestatic int 518254721Semastetunwrite(dev_t dev, struct uio *uio, int flag) 519254721Semaste{ 520254721Semaste int unit = minor (dev); 521254721Semaste struct ifnet *ifp = &tunctl[unit].tun_if; 522254721Semaste struct mbuf *top, **mp, *m; 523254721Semaste int error=0, s, tlen, mlen; 524254721Semaste 525254721Semaste TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit); 526254721Semaste 527254721Semaste if (uio->uio_resid < 0 || uio->uio_resid > ifp->if_mtu) { 528254721Semaste TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit, 529254721Semaste uio->uio_resid); 530254721Semaste return EIO; 531254721Semaste } 532254721Semaste tlen = uio->uio_resid; 533254721Semaste 534254721Semaste /* get a header mbuf */ 535254721Semaste MGETHDR(m, M_DONTWAIT, MT_DATA); 536254721Semaste if (m == NULL) 537254721Semaste return ENOBUFS; 538254721Semaste mlen = MHLEN; 539254721Semaste 540254721Semaste top = 0; 541254721Semaste mp = ⊤ 542254721Semaste while (error == 0 && uio->uio_resid > 0) { 543254721Semaste m->m_len = min(mlen, uio->uio_resid); 544254721Semaste error = uiomove(mtod (m, caddr_t), m->m_len, uio); 545254721Semaste *mp = m; 546254721Semaste mp = &m->m_next; 547254721Semaste if (uio->uio_resid > 0) { 548254721Semaste MGET (m, M_DONTWAIT, MT_DATA); 549254721Semaste if (m == 0) { 550254721Semaste error = ENOBUFS; 551254721Semaste break; 552254721Semaste } 553254721Semaste mlen = MLEN; 554254721Semaste } 555254721Semaste } 556254721Semaste if (error) { 557254721Semaste if (top) 558254721Semaste m_freem (top); 559254721Semaste return error; 560254721Semaste } 561254721Semaste 562254721Semaste top->m_pkthdr.len = tlen; 563254721Semaste top->m_pkthdr.rcvif = ifp; 564254721Semaste 565254721Semaste#if NBPFILTER > 0 566263363Semaste if (ifp->if_bpf) { 567263363Semaste /* 568263363Semaste * We need to prepend the address family as 569263363Semaste * a four byte field. Cons up a dummy header 570263363Semaste * to pacify bpf. This is safe because bpf 571254721Semaste * will only read from the mbuf (i.e., it won't 572254721Semaste * try to free it or keep a pointer to it). 573254721Semaste */ 574254721Semaste struct mbuf m; 575254721Semaste u_int af = AF_INET; 576254721Semaste 577254721Semaste m.m_next = top; 578254721Semaste m.m_len = 4; 579263363Semaste m.m_data = (char *)⁡ 580254721Semaste 581254721Semaste bpf_mtap(ifp, &m); 582254721Semaste } 583254721Semaste#endif 584254721Semaste 585254721Semaste s = splimp(); 586254721Semaste if (IF_QFULL (&ipintrq)) { 587254721Semaste IF_DROP(&ipintrq); 588254721Semaste splx(s); 589254721Semaste ifp->if_collisions++; 590254721Semaste m_freem(top); 591254721Semaste return ENOBUFS; 592254721Semaste } 593254721Semaste IF_ENQUEUE(&ipintrq, top); 594254721Semaste splx(s); 595254721Semaste ifp->if_ibytes += tlen; 596254721Semaste ifp->if_ipackets++; 597254721Semaste schednetisr(NETISR_IP); 598254721Semaste return error; 599254721Semaste} 600254721Semaste 601254721Semaste/* 602254721Semaste * tunselect - the select interface, this is only useful on reads 603254721Semaste * really. The write detect always returns true, write never blocks 604254721Semaste * anyway, it either accepts the packet or drops it. 605254721Semaste */ 606254721Semastestatic int 607254721Semastetunselect(dev_t dev, int rw, struct proc *p) 608254721Semaste{ 609254721Semaste int unit = minor(dev), s; 610254721Semaste struct tun_softc *tp = &tunctl[unit]; 611254721Semaste struct ifnet *ifp = &tp->tun_if; 612254721Semaste 613254721Semaste s = splimp(); 614254721Semaste TUNDEBUG("%s%d: tunselect\n", ifp->if_name, ifp->if_unit); 615254721Semaste 616254721Semaste switch (rw) { 617254721Semaste case FREAD: 618254721Semaste if (ifp->if_snd.ifq_len > 0) { 619254721Semaste splx(s); 620254721Semaste TUNDEBUG("%s%d: tunselect q=%d\n", ifp->if_name, 621254721Semaste ifp->if_unit, ifp->if_snd.ifq_len); 622254721Semaste return 1; 623254721Semaste } 624254721Semaste selrecord(p, &tp->tun_rsel); 625254721Semaste break; 626254721Semaste case FWRITE: 627254721Semaste splx(s); 628254721Semaste return 1; 629254721Semaste } 630254721Semaste splx(s); 631254721Semaste TUNDEBUG("%s%d: tunselect waiting\n", ifp->if_name, ifp->if_unit); 632254721Semaste return 0; 633254721Semaste} 634254721Semaste 635254721Semaste 636254721Semaste#endif /* NTUN */ 637254721Semaste