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