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