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