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