if_tun.c revision 15117
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 ) return; 108 dev = makedev(CDEV_MAJOR, 0); 109 cdevsw_add(&dev,&tun_cdevsw, NULL); 110 tun_devsw_installed = 1; 111 for ( i = 0; i < NTUN; i++ ) { 112#ifdef DEVFS 113 tun_devfs_token[i] = devfs_add_devswf(&tun_cdevsw, i, DV_CHR, 114 UID_UUCP, GID_DIALER, 115 0600, "tun%d", i); 116#endif 117 tunctl[i].tun_flags = TUN_INITED; 118 119 ifp = &tunctl[i].tun_if; 120 ifp->if_unit = i; 121 ifp->if_name = "tun"; 122 ifp->if_mtu = TUNMTU; 123 ifp->if_ioctl = tunifioctl; 124 ifp->if_output = tunoutput; 125 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 126 ifp->if_snd.ifq_maxlen = ifqmaxlen; 127 ifp->if_collisions = 0; 128 ifp->if_ierrors = 0; 129 ifp->if_oerrors = 0; 130 ifp->if_ipackets = 0; 131 ifp->if_opackets = 0; 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->p_ucred, &p->p_acflag); 154 if (error) 155 return (error); 156 157 if ((unit = minor(dev)) >= NTUN) 158 return (ENXIO); 159 tp = &tunctl[unit]; 160 if (tp->tun_flags & TUN_OPEN) 161 return ENXIO; 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_t dev, int foo, int bar, struct proc *p) 174{ 175 register int unit = minor(dev), s; 176 struct tun_softc *tp = &tunctl[unit]; 177 struct ifnet *ifp = &tp->tun_if; 178 struct mbuf *m; 179 180 tp->tun_flags &= ~TUN_OPEN; 181 182 /* 183 * junk all pending output 184 */ 185 do { 186 s = splimp(); 187 IF_DEQUEUE(&ifp->if_snd, m); 188 splx(s); 189 if (m) 190 m_freem(m); 191 } while (m); 192 193 if (ifp->if_flags & IFF_UP) { 194 s = splimp(); 195 if_down(ifp); 196 if (ifp->if_flags & IFF_RUNNING) { 197 /* find internet addresses and delete routes */ 198 register struct ifaddr *ifa; 199 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) { 200 if (ifa->ifa_addr->sa_family == AF_INET) { 201 rtinit(ifa, (int)RTM_DELETE, 202 tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); 203 } 204 } 205 } 206 splx(s); 207 } 208 tp->tun_pgrp = 0; 209 selwakeup(&tp->tun_rsel); 210 211 TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit); 212 return (0); 213} 214 215static int 216tuninit(unit) 217 int unit; 218{ 219 struct tun_softc *tp = &tunctl[unit]; 220 struct ifnet *ifp = &tp->tun_if; 221 register struct ifaddr *ifa; 222 223 TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit); 224 225 ifp->if_flags |= IFF_UP | IFF_RUNNING; 226 227 for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) 228 if (ifa->ifa_addr->sa_family == AF_INET) { 229 struct sockaddr_in *si; 230 231 si = (struct sockaddr_in *)ifa->ifa_addr; 232 if (si && si->sin_addr.s_addr) 233 tp->tun_flags |= TUN_IASET; 234 235 si = (struct sockaddr_in *)ifa->ifa_dstaddr; 236 if (si && si->sin_addr.s_addr) 237 tp->tun_flags |= TUN_DSTADDR; 238 } 239 240 return 0; 241} 242 243/* 244 * Process an ioctl request. 245 */ 246int 247tunifioctl(ifp, cmd, data) 248 struct ifnet *ifp; 249 int cmd; 250 caddr_t data; 251{ 252 register struct ifreq *ifr = (struct ifreq *)data; 253 int error = 0, s; 254 255 s = splimp(); 256 switch(cmd) { 257 case SIOCSIFADDR: 258 tuninit(ifp->if_unit); 259 TUNDEBUG("%s%d: address set\n", 260 ifp->if_name, ifp->if_unit); 261 break; 262 case SIOCSIFDSTADDR: 263 tuninit(ifp->if_unit); 264 TUNDEBUG("%s%d: destination address set\n", 265 ifp->if_name, ifp->if_unit); 266 break; 267 case SIOCADDMULTI: 268 case SIOCDELMULTI: 269 if (ifr == 0) { 270 error = EAFNOSUPPORT; /* XXX */ 271 break; 272 } 273 switch (ifr->ifr_addr.sa_family) { 274 275#ifdef INET 276 case AF_INET: 277 break; 278#endif 279 280 default: 281 error = EAFNOSUPPORT; 282 break; 283 } 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 IF_ENQUEUE(&ifp->if_snd, m0); 357 splx(s); 358 ifp->if_opackets++; 359 break; 360#endif 361 default: 362 m_freem(m0); 363 return EAFNOSUPPORT; 364 } 365 366 if (tp->tun_flags & TUN_RWAIT) { 367 tp->tun_flags &= ~TUN_RWAIT; 368 wakeup((caddr_t)tp); 369 } 370 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgrp) { 371 if (tp->tun_pgrp > 0) 372 gsignal(tp->tun_pgrp, SIGIO); 373 else if ((p = pfind(-tp->tun_pgrp)) != 0) 374 psignal(p, SIGIO); 375 } 376 selwakeup(&tp->tun_rsel); 377 return 0; 378} 379 380/* 381 * the cdevsw interface is now pretty minimal. 382 */ 383static int 384tunioctl(dev, cmd, data, flag, p) 385 dev_t dev; 386 int cmd; 387 caddr_t data; 388 int flag; 389 struct proc *p; 390{ 391 int unit = minor(dev), s; 392 struct tun_softc *tp = &tunctl[unit]; 393 struct tuninfo *tunp; 394 395 switch (cmd) { 396 case TUNSIFINFO: 397 tunp = (struct tuninfo *)data; 398 tp->tun_if.if_mtu = tunp->mtu; 399 tp->tun_if.if_type = tunp->type; 400 tp->tun_if.if_baudrate = tunp->baudrate; 401 break; 402 case TUNGIFINFO: 403 tunp = (struct tuninfo *)data; 404 tunp->mtu = tp->tun_if.if_mtu; 405 tunp->type = tp->tun_if.if_type; 406 tunp->baudrate = tp->tun_if.if_baudrate; 407 break; 408 case TUNSDEBUG: 409 tundebug = *(int *)data; 410 break; 411 case TUNGDEBUG: 412 *(int *)data = tundebug; 413 break; 414 case FIONBIO: 415 if (*(int *)data) 416 tp->tun_flags |= TUN_NBIO; 417 else 418 tp->tun_flags &= ~TUN_NBIO; 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_t dev, struct uio *uio, 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 (tp->tun_flags & TUN_NBIO) { 475 splx(s); 476 return EWOULDBLOCK; 477 } 478 tp->tun_flags |= TUN_RWAIT; 479 tsleep((caddr_t)tp, PZERO + 1, "tunread", 0); 480 } 481 } while (m0 == 0); 482 splx(s); 483 484 while (m0 && uio->uio_resid > 0 && error == 0) { 485 len = min(uio->uio_resid, m0->m_len); 486 if (len == 0) 487 break; 488 error = uiomove(mtod(m0, caddr_t), len, uio); 489 MFREE(m0, m); 490 m0 = m; 491 } 492 493 if (m0) { 494 TUNDEBUG("Dropping mbuf\n"); 495 m_freem(m0); 496 } 497 return error; 498} 499 500/* 501 * the cdevsw write interface - an atomic write is a packet - or else! 502 */ 503static int 504tunwrite(dev_t dev, struct uio *uio, int flag) 505{ 506 int unit = minor (dev); 507 struct ifnet *ifp = &tunctl[unit].tun_if; 508 struct mbuf *top, **mp, *m; 509 int error=0, s, tlen, mlen; 510 511 TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit); 512 513 if (uio->uio_resid < 0 || uio->uio_resid > TUNMTU) { 514 TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit, 515 uio->uio_resid); 516 return EIO; 517 } 518 tlen = uio->uio_resid; 519 520 /* get a header mbuf */ 521 MGETHDR(m, M_DONTWAIT, MT_DATA); 522 if (m == NULL) 523 return ENOBUFS; 524 mlen = MHLEN; 525 526 top = 0; 527 mp = ⊤ 528 while (error == 0 && uio->uio_resid > 0) { 529 m->m_len = min(mlen, uio->uio_resid); 530 error = uiomove(mtod (m, caddr_t), m->m_len, uio); 531 *mp = m; 532 mp = &m->m_next; 533 if (uio->uio_resid > 0) { 534 MGET (m, M_DONTWAIT, MT_DATA); 535 if (m == 0) { 536 error = ENOBUFS; 537 break; 538 } 539 mlen = MLEN; 540 } 541 } 542 if (error) { 543 if (top) 544 m_freem (top); 545 return error; 546 } 547 548 top->m_pkthdr.len = tlen; 549 top->m_pkthdr.rcvif = ifp; 550 551#if NBPFILTER > 0 552 if (ifp->if_bpf) { 553 /* 554 * We need to prepend the address family as 555 * a four byte field. Cons up a dummy header 556 * to pacify bpf. This is safe because bpf 557 * will only read from the mbuf (i.e., it won't 558 * try to free it or keep a pointer to it). 559 */ 560 struct mbuf m; 561 u_int af = AF_INET; 562 563 m.m_next = top; 564 m.m_len = 4; 565 m.m_data = (char *)⁡ 566 567 bpf_mtap(ifp, &m); 568 } 569#endif 570 571 s = splimp(); 572 if (IF_QFULL (&ipintrq)) { 573 IF_DROP(&ipintrq); 574 splx(s); 575 ifp->if_collisions++; 576 m_freem(top); 577 return ENOBUFS; 578 } 579 IF_ENQUEUE(&ipintrq, top); 580 splx(s); 581 ifp->if_ipackets++; 582 schednetisr(NETISR_IP); 583 return error; 584} 585 586/* 587 * tunselect - the select interface, this is only useful on reads 588 * really. The write detect always returns true, write never blocks 589 * anyway, it either accepts the packet or drops it. 590 */ 591static int 592tunselect(dev_t dev, int rw, struct proc *p) 593{ 594 int unit = minor(dev), s; 595 struct tun_softc *tp = &tunctl[unit]; 596 struct ifnet *ifp = &tp->tun_if; 597 598 s = splimp(); 599 TUNDEBUG("%s%d: tunselect\n", ifp->if_name, ifp->if_unit); 600 601 switch (rw) { 602 case FREAD: 603 if (ifp->if_snd.ifq_len > 0) { 604 splx(s); 605 TUNDEBUG("%s%d: tunselect q=%d\n", ifp->if_name, 606 ifp->if_unit, ifp->if_snd.ifq_len); 607 return 1; 608 } 609 selrecord(p, &tp->tun_rsel); 610 break; 611 case FWRITE: 612 splx(s); 613 return 1; 614 } 615 splx(s); 616 TUNDEBUG("%s%d: tunselect waiting\n", ifp->if_name, ifp->if_unit); 617 return 0; 618} 619 620 621#endif /* NTUN */ 622