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