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