if_tun.c revision 31283
1/* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd Exp $ */ 2 3/* 4 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk> 5 * Nottingham University 1987. 6 * 7 * This source may be freely distributed, however I would be interested 8 * in any changes that are made. 9 * 10 * This driver takes packets off the IP i/f and hands them up to a 11 * user process to have it's wicked way with. This driver has it's 12 * roots in a similar driver written by Phil Cockcroft (formerly) at 13 * UCL. This driver is based much more on read/write/poll mode of 14 * operation though. 15 */ 16 17#include "tun.h" 18#if NTUN > 0 19 20#include <sys/param.h> 21#include <sys/proc.h> 22#include <sys/systm.h> 23#include <sys/mbuf.h> 24#include <sys/socket.h> 25#include <sys/filio.h> 26#include <sys/sockio.h> 27#include <sys/ttycom.h> 28#include <sys/poll.h> 29#include <sys/signalvar.h> 30#include <sys/kernel.h> 31#include <sys/sysctl.h> 32#ifdef DEVFS 33#include <sys/devfsext.h> 34#endif /*DEVFS*/ 35#include <sys/conf.h> 36#include <sys/uio.h> 37/* 38 * XXX stop <sys/vnode.h> from including <vnode_if.h>. <vnode_if.h> doesn't 39 * exist if we are an LKM. 40 */ 41#undef KERNEL 42#include <sys/vnode.h> 43#define KERNEL 44 45#include <net/if.h> 46#include <net/netisr.h> 47#include <net/route.h> 48 49#ifdef INET 50#include <netinet/in.h> 51#include <netinet/in_var.h> 52#endif 53 54#ifdef NS 55#include <netns/ns.h> 56#include <netns/ns_if.h> 57#endif 58 59#include "bpfilter.h" 60#if NBPFILTER > 0 61#include <net/bpf.h> 62#endif 63 64#include <net/if_tun.h> 65 66static void tunattach __P((void *)); 67PSEUDO_SET(tunattach, if_tun); 68 69#define TUNDEBUG if (tundebug) printf 70static int tundebug = 0; 71SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, ""); 72 73static struct tun_softc tunctl[NTUN]; 74 75static int tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, 76 struct rtentry *rt)); 77static int tunifioctl __P((struct ifnet *, int, caddr_t)); 78static int tuninit __P((int)); 79 80static d_open_t tunopen; 81static d_close_t tunclose; 82static d_read_t tunread; 83static d_write_t tunwrite; 84static d_ioctl_t tunioctl; 85static d_poll_t tunpoll; 86 87#define CDEV_MAJOR 52 88static struct cdevsw tun_cdevsw = { 89 tunopen, tunclose, tunread, tunwrite, 90 tunioctl, nullstop, noreset, nodevtotty, 91 tunpoll, nommap, nostrategy, "tun", NULL, -1 92}; 93 94 95static tun_devsw_installed = 0; 96#ifdef DEVFS 97static void *tun_devfs_token[NTUN]; 98#endif 99 100static void 101tunattach(dummy) 102 void *dummy; 103{ 104 register int i; 105 struct ifnet *ifp; 106 dev_t dev; 107 108 if ( tun_devsw_installed ) 109 return; 110 dev = makedev(CDEV_MAJOR, 0); 111 cdevsw_add(&dev, &tun_cdevsw, NULL); 112 tun_devsw_installed = 1; 113 for ( i = 0; i < NTUN; i++ ) { 114#ifdef DEVFS 115 tun_devfs_token[i] = devfs_add_devswf(&tun_cdevsw, i, DV_CHR, 116 UID_UUCP, GID_DIALER, 117 0600, "tun%d", i); 118#endif 119 tunctl[i].tun_flags = TUN_INITED; 120 121 ifp = &tunctl[i].tun_if; 122 ifp->if_unit = i; 123 ifp->if_name = "tun"; 124 ifp->if_mtu = TUNMTU; 125 ifp->if_ioctl = tunifioctl; 126 ifp->if_output = tunoutput; 127 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 128 ifp->if_snd.ifq_maxlen = ifqmaxlen; 129 ifp->if_collisions = 0; 130 ifp->if_ierrors = 0; 131 ifp->if_oerrors = 0; 132 ifp->if_ipackets = 0; 133 ifp->if_opackets = 0; 134 if_attach(ifp); 135#if NBPFILTER > 0 136 bpfattach(ifp, DLT_NULL, sizeof(u_int)); 137#endif 138 } 139} 140 141/* 142 * tunnel open - must be superuser & the device must be 143 * configured in 144 */ 145static int 146tunopen(dev, flag, mode, p) 147 dev_t dev; 148 int flag, mode; 149 struct proc *p; 150{ 151 struct ifnet *ifp; 152 struct tun_softc *tp; 153 register int unit, error; 154 155 error = suser(p->p_ucred, &p->p_acflag); 156 if (error) 157 return (error); 158 159 if ((unit = minor(dev)) >= NTUN) 160 return (ENXIO); 161 tp = &tunctl[unit]; 162 if (tp->tun_flags & TUN_OPEN) 163 return EBUSY; 164 ifp = &tp->tun_if; 165 tp->tun_flags |= TUN_OPEN; 166 TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit); 167 return (0); 168} 169 170/* 171 * tunclose - close the device - mark i/f down & delete 172 * routing info 173 */ 174static int 175tunclose(dev, foo, bar, p) 176 dev_t dev; 177 int foo; 178 int bar; 179 struct proc *p; 180{ 181 register int unit = minor(dev), s; 182 struct tun_softc *tp = &tunctl[unit]; 183 struct ifnet *ifp = &tp->tun_if; 184 struct mbuf *m; 185 186 tp->tun_flags &= ~TUN_OPEN; 187 188 /* 189 * junk all pending output 190 */ 191 do { 192 s = splimp(); 193 IF_DEQUEUE(&ifp->if_snd, m); 194 splx(s); 195 if (m) 196 m_freem(m); 197 } while (m); 198 199 if (ifp->if_flags & IFF_UP) { 200 s = splimp(); 201 if_down(ifp); 202 if (ifp->if_flags & IFF_RUNNING) { 203 /* find internet addresses and delete routes */ 204 register struct ifaddr *ifa; 205 for (ifa = ifp->if_addrhead.tqh_first; ifa; 206 ifa = ifa->ifa_link.tqe_next) { 207 if (ifa->ifa_addr->sa_family == AF_INET) { 208 rtinit(ifa, (int)RTM_DELETE, 209 tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); 210 } 211 } 212 } 213 splx(s); 214 } 215 tp->tun_pgrp = 0; 216 selwakeup(&tp->tun_rsel); 217 218 TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit); 219 return (0); 220} 221 222static int 223tuninit(unit) 224 int unit; 225{ 226 struct tun_softc *tp = &tunctl[unit]; 227 struct ifnet *ifp = &tp->tun_if; 228 register struct ifaddr *ifa; 229 230 TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit); 231 232 ifp->if_flags |= IFF_UP | IFF_RUNNING; 233 microtime(&ifp->if_lastchange); 234 235 for (ifa = ifp->if_addrhead.tqh_first; ifa; 236 ifa = ifa->ifa_link.tqe_next) 237 if (ifa->ifa_addr->sa_family == AF_INET) { 238 struct sockaddr_in *si; 239 240 si = (struct sockaddr_in *)ifa->ifa_addr; 241 if (si && si->sin_addr.s_addr) 242 tp->tun_flags |= TUN_IASET; 243 244 si = (struct sockaddr_in *)ifa->ifa_dstaddr; 245 if (si && si->sin_addr.s_addr) 246 tp->tun_flags |= TUN_DSTADDR; 247 } 248 249 return 0; 250} 251 252/* 253 * Process an ioctl request. 254 */ 255int 256tunifioctl(ifp, cmd, data) 257 struct ifnet *ifp; 258 int cmd; 259 caddr_t data; 260{ 261 register struct ifreq *ifr = (struct ifreq *)data; 262 int error = 0, s; 263 264 s = splimp(); 265 switch(cmd) { 266 case SIOCSIFADDR: 267 tuninit(ifp->if_unit); 268 TUNDEBUG("%s%d: address set\n", 269 ifp->if_name, ifp->if_unit); 270 break; 271 case SIOCSIFDSTADDR: 272 tuninit(ifp->if_unit); 273 TUNDEBUG("%s%d: destination address set\n", 274 ifp->if_name, ifp->if_unit); 275 break; 276 case SIOCSIFMTU: 277 ifp->if_mtu = ifr->ifr_mtu; 278 TUNDEBUG("%s%d: mtu set\n", 279 ifp->if_name, ifp->if_unit); 280 break; 281 case SIOCADDMULTI: 282 case SIOCDELMULTI: 283 break; 284 285 286 default: 287 error = EINVAL; 288 } 289 splx(s); 290 return (error); 291} 292 293/* 294 * tunoutput - queue packets from higher level ready to put out. 295 */ 296int 297tunoutput(ifp, m0, dst, rt) 298 struct ifnet *ifp; 299 struct mbuf *m0; 300 struct sockaddr *dst; 301 struct rtentry *rt; 302{ 303 struct tun_softc *tp = &tunctl[ifp->if_unit]; 304 struct proc *p; 305 int s; 306 307 TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit); 308 309 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 310 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 311 ifp->if_unit, tp->tun_flags); 312 m_freem (m0); 313 return EHOSTDOWN; 314 } 315 316#if NBPFILTER > 0 317 /* BPF write needs to be handled specially */ 318 if (dst->sa_family == AF_UNSPEC) { 319 dst->sa_family = *(mtod(m0, int *)); 320 m0->m_len -= sizeof(int); 321 m0->m_pkthdr.len -= sizeof(int); 322 m0->m_data += sizeof(int); 323 } 324 325 if (ifp->if_bpf) { 326 /* 327 * We need to prepend the address family as 328 * a four byte field. Cons up a dummy header 329 * to pacify bpf. This is safe because bpf 330 * will only read from the mbuf (i.e., it won't 331 * try to free it or keep a pointer to it). 332 */ 333 struct mbuf m; 334 u_int af = dst->sa_family; 335 336 m.m_next = m0; 337 m.m_len = 4; 338 m.m_data = (char *)⁡ 339 340 bpf_mtap(ifp, &m); 341 } 342#endif 343 344 switch(dst->sa_family) { 345#ifdef INET 346 case AF_INET: 347 s = splimp(); 348 if (IF_QFULL(&ifp->if_snd)) { 349 IF_DROP(&ifp->if_snd); 350 m_freem(m0); 351 splx(s); 352 ifp->if_collisions++; 353 return (ENOBUFS); 354 } 355 ifp->if_obytes += m0->m_pkthdr.len; 356 IF_ENQUEUE(&ifp->if_snd, m0); 357 splx(s); 358 ifp->if_opackets++; 359 break; 360#endif 361 default: 362 m_freem(m0); 363 return EAFNOSUPPORT; 364 } 365 366 if (tp->tun_flags & TUN_RWAIT) { 367 tp->tun_flags &= ~TUN_RWAIT; 368 wakeup((caddr_t)tp); 369 } 370 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) { 371 if (tp->tun_pgrp > 0) 372 gsignal(tp->tun_pgrp, SIGIO); 373 else if ((p = pfind(-tp->tun_pgrp)) != 0) 374 psignal(p, SIGIO); 375 } 376 selwakeup(&tp->tun_rsel); 377 return 0; 378} 379 380/* 381 * the cdevsw interface is now pretty minimal. 382 */ 383static int 384tunioctl(dev, cmd, data, flag, p) 385 dev_t dev; 386 int cmd; 387 caddr_t data; 388 int flag; 389 struct proc *p; 390{ 391 int unit = minor(dev), s; 392 struct tun_softc *tp = &tunctl[unit]; 393 struct tuninfo *tunp; 394 395 switch (cmd) { 396 case TUNSIFINFO: 397 tunp = (struct tuninfo *)data; 398 tp->tun_if.if_mtu = tunp->mtu; 399 tp->tun_if.if_type = tunp->type; 400 tp->tun_if.if_baudrate = tunp->baudrate; 401 break; 402 case TUNGIFINFO: 403 tunp = (struct tuninfo *)data; 404 tunp->mtu = tp->tun_if.if_mtu; 405 tunp->type = tp->tun_if.if_type; 406 tunp->baudrate = tp->tun_if.if_baudrate; 407 break; 408 case TUNSDEBUG: 409 tundebug = *(int *)data; 410 break; 411 case TUNGDEBUG: 412 *(int *)data = tundebug; 413 break; 414 case FIONBIO: 415 break; 416 case FIOASYNC: 417 if (*(int *)data) 418 tp->tun_flags |= TUN_ASYNC; 419 else 420 tp->tun_flags &= ~TUN_ASYNC; 421 break; 422 case FIONREAD: 423 s = splimp(); 424 if (tp->tun_if.if_snd.ifq_head) { 425 struct mbuf *mb = tp->tun_if.if_snd.ifq_head; 426 for( *(int *)data = 0; mb != 0; mb = mb->m_next) 427 *(int *)data += mb->m_len; 428 } else 429 *(int *)data = 0; 430 splx(s); 431 break; 432 case TIOCSPGRP: 433 tp->tun_pgrp = *(int *)data; 434 break; 435 case TIOCGPGRP: 436 *(int *)data = tp->tun_pgrp; 437 break; 438 default: 439 return (ENOTTY); 440 } 441 return (0); 442} 443 444/* 445 * The cdevsw read interface - reads a packet at a time, or at 446 * least as much of a packet as can be read. 447 */ 448static int 449tunread(dev, uio, flag) 450 dev_t dev; 451 struct uio *uio; 452 int flag; 453{ 454 int unit = minor(dev); 455 struct tun_softc *tp = &tunctl[unit]; 456 struct ifnet *ifp = &tp->tun_if; 457 struct mbuf *m, *m0; 458 int error=0, len, s; 459 460 TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit); 461 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 462 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 463 ifp->if_unit, tp->tun_flags); 464 return EHOSTDOWN; 465 } 466 467 tp->tun_flags &= ~TUN_RWAIT; 468 469 s = splimp(); 470 do { 471 IF_DEQUEUE(&ifp->if_snd, m0); 472 if (m0 == 0) { 473 if (flag & IO_NDELAY) { 474 splx(s); 475 return EWOULDBLOCK; 476 } 477 tp->tun_flags |= TUN_RWAIT; 478 if( error = tsleep((caddr_t)tp, PCATCH | (PZERO + 1), 479 "tunread", 0)) { 480 splx(s); 481 return error; 482 } 483 } 484 } while (m0 == 0); 485 splx(s); 486 487 while (m0 && uio->uio_resid > 0 && error == 0) { 488 len = min(uio->uio_resid, m0->m_len); 489 if (len == 0) 490 break; 491 error = uiomove(mtod(m0, caddr_t), len, uio); 492 MFREE(m0, m); 493 m0 = m; 494 } 495 496 if (m0) { 497 TUNDEBUG("Dropping mbuf\n"); 498 m_freem(m0); 499 } 500 return error; 501} 502 503/* 504 * the cdevsw write interface - an atomic write is a packet - or else! 505 */ 506static int 507tunwrite(dev, uio, flag) 508 dev_t dev; 509 struct uio *uio; 510 int flag; 511{ 512 int unit = minor (dev); 513 struct ifnet *ifp = &tunctl[unit].tun_if; 514 struct mbuf *top, **mp, *m; 515 int error=0, s, tlen, mlen; 516 517 TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit); 518 519 if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) { 520 TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit, 521 uio->uio_resid); 522 return EIO; 523 } 524 tlen = uio->uio_resid; 525 526 /* get a header mbuf */ 527 MGETHDR(m, M_DONTWAIT, MT_DATA); 528 if (m == NULL) 529 return ENOBUFS; 530 mlen = MHLEN; 531 532 top = 0; 533 mp = ⊤ 534 while (error == 0 && uio->uio_resid > 0) { 535 m->m_len = min(mlen, uio->uio_resid); 536 error = uiomove(mtod (m, caddr_t), m->m_len, uio); 537 *mp = m; 538 mp = &m->m_next; 539 if (uio->uio_resid > 0) { 540 MGET (m, M_DONTWAIT, MT_DATA); 541 if (m == 0) { 542 error = ENOBUFS; 543 break; 544 } 545 mlen = MLEN; 546 } 547 } 548 if (error) { 549 if (top) 550 m_freem (top); 551 return error; 552 } 553 554 top->m_pkthdr.len = tlen; 555 top->m_pkthdr.rcvif = ifp; 556 557#if NBPFILTER > 0 558 if (ifp->if_bpf) { 559 /* 560 * We need to prepend the address family as 561 * a four byte field. Cons up a dummy header 562 * to pacify bpf. This is safe because bpf 563 * will only read from the mbuf (i.e., it won't 564 * try to free it or keep a pointer to it). 565 */ 566 struct mbuf m; 567 u_int af = AF_INET; 568 569 m.m_next = top; 570 m.m_len = 4; 571 m.m_data = (char *)⁡ 572 573 bpf_mtap(ifp, &m); 574 } 575#endif 576 577 s = splimp(); 578 if (IF_QFULL (&ipintrq)) { 579 IF_DROP(&ipintrq); 580 splx(s); 581 ifp->if_collisions++; 582 m_freem(top); 583 return ENOBUFS; 584 } 585 IF_ENQUEUE(&ipintrq, top); 586 splx(s); 587 ifp->if_ibytes += tlen; 588 ifp->if_ipackets++; 589 schednetisr(NETISR_IP); 590 return error; 591} 592 593/* 594 * tunpoll - the poll interface, this is only useful on reads 595 * really. The write detect always returns true, write never blocks 596 * anyway, it either accepts the packet or drops it. 597 */ 598static int 599tunpoll(dev, events, p) 600 dev_t dev; 601 int events; 602 struct proc *p; 603{ 604 int unit = minor(dev), s; 605 struct tun_softc *tp = &tunctl[unit]; 606 struct ifnet *ifp = &tp->tun_if; 607 int revents = 0; 608 609 s = splimp(); 610 TUNDEBUG("%s%d: tunpoll\n", ifp->if_name, ifp->if_unit); 611 612 if (events & (POLLIN | POLLRDNORM)) 613 if (ifp->if_snd.ifq_len > 0) { 614 TUNDEBUG("%s%d: tunpoll q=%d\n", ifp->if_name, 615 ifp->if_unit, ifp->if_snd.ifq_len); 616 revents |= events & (POLLIN | POLLRDNORM); 617 } else { 618 TUNDEBUG("%s%d: tunpoll waiting\n", ifp->if_name, 619 ifp->if_unit); 620 selrecord(p, &tp->tun_rsel); 621 } 622 623 if (events & (POLLOUT | POLLWRNORM)) 624 revents |= events & (POLLOUT | POLLWRNORM); 625 626 splx(s); 627 return (revents); 628} 629 630 631#endif /* NTUN */ 632