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