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