if_tun.c revision 49829
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 its 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 19#include "opt_inet.h" 20 21#include <sys/param.h> 22#include <sys/proc.h> 23#include <sys/systm.h> 24#include <sys/mbuf.h> 25#include <sys/socket.h> 26#include <sys/filio.h> 27#include <sys/sockio.h> 28#include <sys/ttycom.h> 29#include <sys/poll.h> 30#include <sys/signalvar.h> 31#include <sys/filedesc.h> 32#include <sys/kernel.h> 33#include <sys/sysctl.h> 34#include <sys/conf.h> 35#include <sys/uio.h> 36#include <sys/vnode.h> 37#include <sys/malloc.h> 38 39#include <net/if.h> 40#include <net/netisr.h> 41#include <net/route.h> 42 43#ifdef INET 44#include <netinet/in.h> 45#include <netinet/in_var.h> 46#endif 47 48#ifdef NS 49#include <netns/ns.h> 50#include <netns/ns_if.h> 51#endif 52 53#include "bpf.h" 54#if NBPF > 0 55#include <net/bpf.h> 56#endif 57 58#include <net/if_tunvar.h> 59#include <net/if_tun.h> 60 61static MALLOC_DEFINE(M_TUN, "tun", "Tunnel Interface"); 62 63static void tunattach __P((void *)); 64PSEUDO_SET(tunattach, if_tun); 65 66static void tuncreate __P((dev_t dev)); 67 68#define TUNDEBUG if (tundebug) printf 69static int tundebug = 0; 70SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, ""); 71 72static int tunoutput __P((struct ifnet *, struct mbuf *, struct sockaddr *, 73 struct rtentry *rt)); 74static int tunifioctl __P((struct ifnet *, u_long, caddr_t)); 75static int tuninit __P((struct ifnet *)); 76 77static d_open_t tunopen; 78static d_close_t tunclose; 79static d_read_t tunread; 80static d_write_t tunwrite; 81static d_ioctl_t tunioctl; 82static d_poll_t tunpoll; 83 84#define CDEV_MAJOR 52 85static struct cdevsw tun_cdevsw = { 86 /* open */ tunopen, 87 /* close */ tunclose, 88 /* read */ tunread, 89 /* write */ tunwrite, 90 /* ioctl */ tunioctl, 91 /* stop */ nostop, 92 /* reset */ noreset, 93 /* devtotty */ nodevtotty, 94 /* poll */ tunpoll, 95 /* mmap */ nommap, 96 /* strategy */ nostrategy, 97 /* name */ "tun", 98 /* parms */ noparms, 99 /* maj */ CDEV_MAJOR, 100 /* dump */ nodump, 101 /* psize */ nopsize, 102 /* flags */ 0, 103 /* maxio */ 0, 104 /* bmaj */ -1 105}; 106 107static void 108tunattach(dummy) 109 void *dummy; 110{ 111 112 cdevsw_add(&tun_cdevsw); 113} 114 115static void 116tuncreate(dev) 117 dev_t dev; 118{ 119 struct tun_softc *sc; 120 struct ifnet *ifp; 121 122 dev = make_dev(&tun_cdevsw, minor(dev), 123 UID_UUCP, GID_DIALER, 0600, "tun%d", lminor(dev)); 124 125 MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK); 126 bzero(sc, sizeof *sc); 127 sc->tun_flags = TUN_INITED; 128 129 ifp = &sc->tun_if; 130 ifp->if_unit = lminor(dev); 131 ifp->if_name = "tun"; 132 ifp->if_mtu = TUNMTU; 133 ifp->if_ioctl = tunifioctl; 134 ifp->if_output = tunoutput; 135 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 136 ifp->if_snd.ifq_maxlen = ifqmaxlen; 137 ifp->if_softc = sc; 138 if_attach(ifp); 139#if NBPF > 0 140 bpfattach(ifp, DLT_NULL, sizeof(u_int)); 141#endif 142 dev->si_drv1 = sc; 143} 144 145/* 146 * tunnel open - must be superuser & the device must be 147 * configured in 148 */ 149static int 150tunopen(dev, flag, mode, p) 151 dev_t dev; 152 int flag, mode; 153 struct proc *p; 154{ 155 struct ifnet *ifp; 156 struct tun_softc *tp; 157 register int error; 158 159 error = suser(p); 160 if (error) 161 return (error); 162 163 tp = dev->si_drv1; 164 if (!tp) { 165 tuncreate(dev); 166 tp = dev->si_drv1; 167 } 168 if (tp->tun_flags & TUN_OPEN) 169 return EBUSY; 170 tp->tun_pid = p->p_pid; 171 ifp = &tp->tun_if; 172 tp->tun_flags |= TUN_OPEN; 173 TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit); 174 return (0); 175} 176 177/* 178 * tunclose - close the device - mark i/f down & delete 179 * routing info 180 */ 181static int 182tunclose(dev, foo, bar, p) 183 dev_t dev; 184 int foo; 185 int bar; 186 struct proc *p; 187{ 188 register int s; 189 struct tun_softc *tp; 190 struct ifnet *ifp; 191 struct mbuf *m; 192 193 tp = dev->si_drv1; 194 ifp = &tp->tun_if; 195 196 tp->tun_flags &= ~TUN_OPEN; 197 tp->tun_pid = 0; 198 199 /* 200 * junk all pending output 201 */ 202 do { 203 s = splimp(); 204 IF_DEQUEUE(&ifp->if_snd, m); 205 splx(s); 206 if (m) 207 m_freem(m); 208 } while (m); 209 210 if (ifp->if_flags & IFF_UP) { 211 s = splimp(); 212 if_down(ifp); 213 splx(s); 214 } 215 216 if (ifp->if_flags & IFF_RUNNING) { 217 register struct ifaddr *ifa; 218 219 s = splimp(); 220 /* find internet addresses and delete routes */ 221 for (ifa = ifp->if_addrhead.tqh_first; ifa; 222 ifa = ifa->ifa_link.tqe_next) 223 if (ifa->ifa_addr->sa_family == AF_INET) 224 rtinit(ifa, (int)RTM_DELETE, 225 tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); 226 ifp->if_flags &= ~IFF_RUNNING; 227 splx(s); 228 } 229 230 funsetown(tp->tun_sigio); 231 selwakeup(&tp->tun_rsel); 232 233 TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit); 234 return (0); 235} 236 237static int 238tuninit(ifp) 239 struct ifnet *ifp; 240{ 241 struct tun_softc *tp = ifp->if_softc; 242 register struct ifaddr *ifa; 243 244 TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit); 245 246 ifp->if_flags |= IFF_UP | IFF_RUNNING; 247 getmicrotime(&ifp->if_lastchange); 248 249 for (ifa = ifp->if_addrhead.tqh_first; ifa; 250 ifa = ifa->ifa_link.tqe_next) { 251#ifdef INET 252 if (ifa->ifa_addr->sa_family == AF_INET) { 253 struct sockaddr_in *si; 254 255 si = (struct sockaddr_in *)ifa->ifa_addr; 256 if (si && si->sin_addr.s_addr) 257 tp->tun_flags |= TUN_IASET; 258 259 si = (struct sockaddr_in *)ifa->ifa_dstaddr; 260 if (si && si->sin_addr.s_addr) 261 tp->tun_flags |= TUN_DSTADDR; 262 } 263#endif 264 } 265 return 0; 266} 267 268/* 269 * Process an ioctl request. 270 */ 271int 272tunifioctl(ifp, cmd, data) 273 struct ifnet *ifp; 274 u_long cmd; 275 caddr_t data; 276{ 277 struct ifreq *ifr = (struct ifreq *)data; 278 struct tun_softc *tp = ifp->if_softc; 279 struct ifstat *ifs; 280 int error = 0, s; 281 282 s = splimp(); 283 switch(cmd) { 284 case SIOCGIFSTATUS: 285 ifs = (struct ifstat *)data; 286 if (tp->tun_pid) 287 sprintf(ifs->ascii + strlen(ifs->ascii), 288 "\tOpened by PID %d\n", tp->tun_pid); 289 return(0); 290 case SIOCSIFADDR: 291 tuninit(ifp); 292 TUNDEBUG("%s%d: address set\n", 293 ifp->if_name, ifp->if_unit); 294 break; 295 case SIOCSIFDSTADDR: 296 tuninit(ifp); 297 TUNDEBUG("%s%d: destination address set\n", 298 ifp->if_name, ifp->if_unit); 299 break; 300 case SIOCSIFMTU: 301 ifp->if_mtu = ifr->ifr_mtu; 302 TUNDEBUG("%s%d: mtu set\n", 303 ifp->if_name, ifp->if_unit); 304 break; 305 case SIOCADDMULTI: 306 case SIOCDELMULTI: 307 break; 308 309 310 default: 311 error = EINVAL; 312 } 313 splx(s); 314 return (error); 315} 316 317/* 318 * tunoutput - queue packets from higher level ready to put out. 319 */ 320int 321tunoutput(ifp, m0, dst, rt) 322 struct ifnet *ifp; 323 struct mbuf *m0; 324 struct sockaddr *dst; 325 struct rtentry *rt; 326{ 327 struct tun_softc *tp = ifp->if_softc; 328 int s; 329 330 TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit); 331 332 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 333 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 334 ifp->if_unit, tp->tun_flags); 335 m_freem (m0); 336 return EHOSTDOWN; 337 } 338 339#if NBPF > 0 340 /* BPF write needs to be handled specially */ 341 if (dst->sa_family == AF_UNSPEC) { 342 dst->sa_family = *(mtod(m0, int *)); 343 m0->m_len -= sizeof(int); 344 m0->m_pkthdr.len -= sizeof(int); 345 m0->m_data += sizeof(int); 346 } 347 348 if (ifp->if_bpf) { 349 /* 350 * We need to prepend the address family as 351 * a four byte field. Cons up a dummy header 352 * to pacify bpf. This is safe because bpf 353 * will only read from the mbuf (i.e., it won't 354 * try to free it or keep a pointer to it). 355 */ 356 struct mbuf m; 357 u_int af = dst->sa_family; 358 359 m.m_next = m0; 360 m.m_len = 4; 361 m.m_data = (char *)⁡ 362 363 bpf_mtap(ifp, &m); 364 } 365#endif /* NBPF > 0 */ 366 367 /* prepend sockaddr? this may abort if the mbuf allocation fails */ 368 if (tp->tun_flags & TUN_LMODE) { 369 /* allocate space for sockaddr */ 370 M_PREPEND(m0, dst->sa_len, M_DONTWAIT); 371 372 /* if allocation failed drop packet */ 373 if (m0 == NULL){ 374 s = splimp(); /* spl on queue manipulation */ 375 IF_DROP(&ifp->if_snd); 376 splx(s); 377 ifp->if_oerrors++; 378 return (ENOBUFS); 379 } else { 380 bcopy(dst, m0->m_data, dst->sa_len); 381 } 382 } 383 384 switch(dst->sa_family) { 385#ifdef INET 386 case AF_INET: 387 s = splimp(); 388 if (IF_QFULL(&ifp->if_snd)) { 389 IF_DROP(&ifp->if_snd); 390 m_freem(m0); 391 splx(s); 392 ifp->if_collisions++; 393 return (ENOBUFS); 394 } 395 ifp->if_obytes += m0->m_pkthdr.len; 396 IF_ENQUEUE(&ifp->if_snd, m0); 397 splx(s); 398 ifp->if_opackets++; 399 break; 400#endif 401 default: 402 m_freem(m0); 403 return EAFNOSUPPORT; 404 } 405 406 if (tp->tun_flags & TUN_RWAIT) { 407 tp->tun_flags &= ~TUN_RWAIT; 408 wakeup((caddr_t)tp); 409 } 410 if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) 411 pgsigio(tp->tun_sigio, SIGIO, 0); 412 selwakeup(&tp->tun_rsel); 413 return 0; 414} 415 416/* 417 * the cdevsw interface is now pretty minimal. 418 */ 419static int 420tunioctl(dev, cmd, data, flag, p) 421 dev_t dev; 422 u_long cmd; 423 caddr_t data; 424 int flag; 425 struct proc *p; 426{ 427 int s; 428 struct tun_softc *tp = dev->si_drv1; 429 struct tuninfo *tunp; 430 431 switch (cmd) { 432 case TUNSIFINFO: 433 tunp = (struct tuninfo *)data; 434 if (tunp->mtu < IF_MINMTU) 435 return (EINVAL); 436 tp->tun_if.if_mtu = tunp->mtu; 437 tp->tun_if.if_type = tunp->type; 438 tp->tun_if.if_baudrate = tunp->baudrate; 439 break; 440 case TUNGIFINFO: 441 tunp = (struct tuninfo *)data; 442 tunp->mtu = tp->tun_if.if_mtu; 443 tunp->type = tp->tun_if.if_type; 444 tunp->baudrate = tp->tun_if.if_baudrate; 445 break; 446 case TUNSDEBUG: 447 tundebug = *(int *)data; 448 break; 449 case TUNGDEBUG: 450 *(int *)data = tundebug; 451 break; 452 case TUNSLMODE: 453 if (*(int *)data) 454 tp->tun_flags |= TUN_LMODE; 455 else 456 tp->tun_flags &= ~TUN_LMODE; 457 break; 458 case TUNSIFMODE: 459 /* deny this if UP */ 460 if (tp->tun_if.if_flags & IFF_UP) 461 return(EBUSY); 462 463 switch (*(int *)data) { 464 case IFF_POINTOPOINT: 465 tp->tun_if.if_flags |= IFF_POINTOPOINT; 466 tp->tun_if.if_flags &= ~IFF_BROADCAST; 467 break; 468 case IFF_BROADCAST: 469 tp->tun_if.if_flags &= ~IFF_POINTOPOINT; 470 tp->tun_if.if_flags |= IFF_BROADCAST; 471 break; 472 default: 473 return(EINVAL); 474 } 475 break; 476 case FIONBIO: 477 break; 478 case FIOASYNC: 479 if (*(int *)data) 480 tp->tun_flags |= TUN_ASYNC; 481 else 482 tp->tun_flags &= ~TUN_ASYNC; 483 break; 484 case FIONREAD: 485 s = splimp(); 486 if (tp->tun_if.if_snd.ifq_head) { 487 struct mbuf *mb = tp->tun_if.if_snd.ifq_head; 488 for( *(int *)data = 0; mb != 0; mb = mb->m_next) 489 *(int *)data += mb->m_len; 490 } else 491 *(int *)data = 0; 492 splx(s); 493 break; 494 case FIOSETOWN: 495 return (fsetown(*(int *)data, &tp->tun_sigio)); 496 497 case FIOGETOWN: 498 *(int *)data = fgetown(tp->tun_sigio); 499 return (0); 500 501 /* This is deprecated, FIOSETOWN should be used instead. */ 502 case TIOCSPGRP: 503 return (fsetown(-(*(int *)data), &tp->tun_sigio)); 504 505 /* This is deprecated, FIOGETOWN should be used instead. */ 506 case TIOCGPGRP: 507 *(int *)data = -fgetown(tp->tun_sigio); 508 return (0); 509 510 default: 511 return (ENOTTY); 512 } 513 return (0); 514} 515 516/* 517 * The cdevsw read interface - reads a packet at a time, or at 518 * least as much of a packet as can be read. 519 */ 520static int 521tunread(dev, uio, flag) 522 dev_t dev; 523 struct uio *uio; 524 int flag; 525{ 526 struct tun_softc *tp = dev->si_drv1; 527 struct ifnet *ifp = &tp->tun_if; 528 struct mbuf *m, *m0; 529 int error=0, len, s; 530 531 TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit); 532 if ((tp->tun_flags & TUN_READY) != TUN_READY) { 533 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name, 534 ifp->if_unit, tp->tun_flags); 535 return EHOSTDOWN; 536 } 537 538 tp->tun_flags &= ~TUN_RWAIT; 539 540 s = splimp(); 541 do { 542 IF_DEQUEUE(&ifp->if_snd, m0); 543 if (m0 == 0) { 544 if (flag & IO_NDELAY) { 545 splx(s); 546 return EWOULDBLOCK; 547 } 548 tp->tun_flags |= TUN_RWAIT; 549 if((error = tsleep((caddr_t)tp, PCATCH | (PZERO + 1), 550 "tunread", 0)) != 0) { 551 splx(s); 552 return error; 553 } 554 } 555 } while (m0 == 0); 556 splx(s); 557 558 while (m0 && uio->uio_resid > 0 && error == 0) { 559 len = min(uio->uio_resid, m0->m_len); 560 if (len == 0) 561 break; 562 error = uiomove(mtod(m0, caddr_t), len, uio); 563 MFREE(m0, m); 564 m0 = m; 565 } 566 567 if (m0) { 568 TUNDEBUG("Dropping mbuf\n"); 569 m_freem(m0); 570 } 571 return error; 572} 573 574/* 575 * the cdevsw write interface - an atomic write is a packet - or else! 576 */ 577static int 578tunwrite(dev, uio, flag) 579 dev_t dev; 580 struct uio *uio; 581 int flag; 582{ 583 struct tun_softc *tp = dev->si_drv1; 584 struct ifnet *ifp = &tp->tun_if; 585 struct mbuf *top, **mp, *m; 586 int error=0, s, tlen, mlen; 587 588 TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit); 589 590 if (uio->uio_resid == 0) 591 return 0; 592 593 if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) { 594 TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit, 595 uio->uio_resid); 596 return EIO; 597 } 598 tlen = uio->uio_resid; 599 600 /* get a header mbuf */ 601 MGETHDR(m, M_DONTWAIT, MT_DATA); 602 if (m == NULL) 603 return ENOBUFS; 604 mlen = MHLEN; 605 606 top = 0; 607 mp = ⊤ 608 while (error == 0 && uio->uio_resid > 0) { 609 m->m_len = min(mlen, uio->uio_resid); 610 error = uiomove(mtod (m, caddr_t), m->m_len, uio); 611 *mp = m; 612 mp = &m->m_next; 613 if (uio->uio_resid > 0) { 614 MGET (m, M_DONTWAIT, MT_DATA); 615 if (m == 0) { 616 error = ENOBUFS; 617 break; 618 } 619 mlen = MLEN; 620 } 621 } 622 if (error) { 623 if (top) 624 m_freem (top); 625 return error; 626 } 627 628 top->m_pkthdr.len = tlen; 629 top->m_pkthdr.rcvif = ifp; 630 631#if NBPF > 0 632 if (ifp->if_bpf) { 633 /* 634 * We need to prepend the address family as 635 * a four byte field. Cons up a dummy header 636 * to pacify bpf. This is safe because bpf 637 * will only read from the mbuf (i.e., it won't 638 * try to free it or keep a pointer to it). 639 */ 640 struct mbuf m; 641 u_int af = AF_INET; 642 643 m.m_next = top; 644 m.m_len = 4; 645 m.m_data = (char *)⁡ 646 647 bpf_mtap(ifp, &m); 648 } 649#endif 650 651#ifdef INET 652 s = splimp(); 653 if (IF_QFULL (&ipintrq)) { 654 IF_DROP(&ipintrq); 655 splx(s); 656 ifp->if_collisions++; 657 m_freem(top); 658 return ENOBUFS; 659 } 660 IF_ENQUEUE(&ipintrq, top); 661 splx(s); 662 ifp->if_ibytes += tlen; 663 ifp->if_ipackets++; 664 schednetisr(NETISR_IP); 665#endif 666 return error; 667} 668 669/* 670 * tunpoll - the poll interface, this is only useful on reads 671 * really. The write detect always returns true, write never blocks 672 * anyway, it either accepts the packet or drops it. 673 */ 674static int 675tunpoll(dev, events, p) 676 dev_t dev; 677 int events; 678 struct proc *p; 679{ 680 int s; 681 struct tun_softc *tp = dev->si_drv1; 682 struct ifnet *ifp = &tp->tun_if; 683 int revents = 0; 684 685 s = splimp(); 686 TUNDEBUG("%s%d: tunpoll\n", ifp->if_name, ifp->if_unit); 687 688 if (events & (POLLIN | POLLRDNORM)) { 689 if (ifp->if_snd.ifq_len > 0) { 690 TUNDEBUG("%s%d: tunpoll q=%d\n", ifp->if_name, 691 ifp->if_unit, ifp->if_snd.ifq_len); 692 revents |= events & (POLLIN | POLLRDNORM); 693 } else { 694 TUNDEBUG("%s%d: tunpoll waiting\n", ifp->if_name, 695 ifp->if_unit); 696 selrecord(p, &tp->tun_rsel); 697 } 698 } 699 if (events & (POLLOUT | POLLWRNORM)) 700 revents |= events & (POLLOUT | POLLWRNORM); 701 702 splx(s); 703 return (revents); 704} 705