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