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