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