This source file includes following definitions.
- tunattach
- tun_clone_create
- tun_create
- tun_clone_destroy
- tun_lookup
- tun_switch
- tunopen
- tunclose
- tuninit
- tun_ioctl
- tun_output
- tun_wakeup
- tunioctl
- tunread
- tunwrite
- tunpoll
- tunkqfilter
- filt_tunrdetach
- filt_tunread
- filt_tunwdetach
- filt_tunwrite
- tunstart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <sys/param.h>
41 #include <sys/kernel.h>
42 #include <sys/proc.h>
43 #include <sys/systm.h>
44 #include <sys/mbuf.h>
45 #include <sys/protosw.h>
46 #include <sys/socket.h>
47 #include <sys/ioctl.h>
48 #include <sys/errno.h>
49 #include <sys/syslog.h>
50 #include <sys/selinfo.h>
51 #include <sys/file.h>
52 #include <sys/time.h>
53 #include <sys/device.h>
54 #include <sys/vnode.h>
55 #include <sys/signalvar.h>
56 #include <sys/poll.h>
57 #include <sys/conf.h>
58
59 #include <machine/cpu.h>
60
61 #include <net/if.h>
62 #include <net/if_types.h>
63 #include <net/netisr.h>
64 #include <net/route.h>
65
66 #ifdef INET
67 #include <netinet/in.h>
68 #include <netinet/in_systm.h>
69 #include <netinet/in_var.h>
70 #include <netinet/ip.h>
71 #include <netinet/if_ether.h>
72 #endif
73
74 #ifdef NETATALK
75 #include <netatalk/at.h>
76 #include <netatalk/at_var.h>
77 #endif
78
79 #include "bpfilter.h"
80 #if NBPFILTER > 0
81 #include <net/bpf.h>
82 #endif
83
84
85 #include <dev/rndvar.h>
86
87 #include <net/if_tun.h>
88
89 struct tun_softc {
90 struct arpcom arpcom;
91 u_short tun_flags;
92 pid_t tun_pgid;
93 uid_t tun_siguid;
94 uid_t tun_sigeuid;
95 struct selinfo tun_rsel;
96 struct selinfo tun_wsel;
97 int tun_unit;
98 LIST_ENTRY(tun_softc) tun_list;
99 #define tun_if arpcom.ac_if
100 };
101
102 #ifdef TUN_DEBUG
103 int tundebug = TUN_DEBUG;
104 #define TUNDEBUG(a) (tundebug? printf a : 0)
105 #else
106 #define TUNDEBUG(a)
107 #endif
108
109
110 #define TUN_IFF_FLAGS (IFF_UP|IFF_POINTOPOINT|IFF_MULTICAST|IFF_BROADCAST)
111
112 void tunattach(int);
113 int tunopen(dev_t, int, int, struct proc *);
114 int tunclose(dev_t, int, int, struct proc *);
115 int tun_ioctl(struct ifnet *, u_long, caddr_t);
116 int tun_output(struct ifnet *, struct mbuf *, struct sockaddr *,
117 struct rtentry *);
118 int tunioctl(dev_t, u_long, caddr_t, int, struct proc *);
119 int tunread(dev_t, struct uio *, int);
120 int tunwrite(dev_t, struct uio *, int);
121 int tunpoll(dev_t, int, struct proc *);
122 int tunkqfilter(dev_t, struct knote *);
123 int tun_clone_create(struct if_clone *, int);
124 int tun_create(struct if_clone *, int, int);
125 int tun_clone_destroy(struct ifnet *);
126 struct tun_softc *tun_lookup(int);
127 void tun_wakeup(struct tun_softc *);
128 int tun_switch(struct tun_softc *, int);
129
130 static int tuninit(struct tun_softc *);
131 static void tunstart(struct ifnet *);
132 int filt_tunread(struct knote *, long);
133 int filt_tunwrite(struct knote *, long);
134 void filt_tunrdetach(struct knote *);
135 void filt_tunwdetach(struct knote *);
136
137 struct filterops tunread_filtops =
138 { 1, NULL, filt_tunrdetach, filt_tunread};
139
140 struct filterops tunwrite_filtops =
141 { 1, NULL, filt_tunwdetach, filt_tunwrite};
142
143 LIST_HEAD(, tun_softc) tun_softc_list;
144
145 struct if_clone tun_cloner =
146 IF_CLONE_INITIALIZER("tun", tun_clone_create, tun_clone_destroy);
147
148 void
149 tunattach(int n)
150 {
151 LIST_INIT(&tun_softc_list);
152 if_clone_attach(&tun_cloner);
153 }
154
155 int
156 tun_clone_create(struct if_clone *ifc, int unit)
157 {
158 return (tun_create(ifc, unit, 0));
159 }
160
161 int
162 tun_create(struct if_clone *ifc, int unit, int flags)
163 {
164 struct tun_softc *tp;
165 struct ifnet *ifp;
166 u_int32_t macaddr_rnd;
167 int s;
168
169 tp = malloc(sizeof(*tp), M_DEVBUF, M_NOWAIT);
170 if (!tp)
171 return (ENOMEM);
172 bzero(tp, sizeof(*tp));
173
174 tp->tun_unit = unit;
175 tp->tun_flags = TUN_INITED|TUN_STAYUP;
176
177
178 tp->arpcom.ac_enaddr[0] = 0x00;
179 tp->arpcom.ac_enaddr[1] = 0xbd;
180
181
182
183
184 macaddr_rnd = arc4random();
185 bcopy(&macaddr_rnd, &tp->arpcom.ac_enaddr[2], sizeof(u_int32_t));
186 tp->arpcom.ac_enaddr[5] = (u_char)unit + 1;
187
188 ifp = &tp->tun_if;
189 snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name,
190 unit);
191 ifp->if_softc = tp;
192 ifp->if_ioctl = tun_ioctl;
193 ifp->if_output = tun_output;
194 ifp->if_start = tunstart;
195 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
196 IFQ_SET_READY(&ifp->if_snd);
197 if ((flags & TUN_LAYER2) == 0) {
198 tp->tun_flags &= ~TUN_LAYER2;
199 ifp->if_mtu = ETHERMTU;
200 ifp->if_flags = IFF_POINTOPOINT;
201 ifp->if_type = IFT_TUNNEL;
202 ifp->if_hdrlen = sizeof(u_int32_t);
203 if_attach(ifp);
204 if_alloc_sadl(ifp);
205 #if NBPFILTER > 0
206 bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t));
207 #endif
208 } else {
209 tp->tun_flags |= TUN_LAYER2;
210 ifp->if_flags =
211 (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST|IFF_LINK0);
212 if_attach(ifp);
213 ether_ifattach(ifp);
214 }
215
216 ifp->if_output = tun_output;
217
218 s = splnet();
219 LIST_INSERT_HEAD(&tun_softc_list, tp, tun_list);
220 splx(s);
221
222 return (0);
223 }
224
225 int
226 tun_clone_destroy(struct ifnet *ifp)
227 {
228 struct tun_softc *tp = ifp->if_softc;
229 int s;
230
231 tun_wakeup(tp);
232
233 s = splhigh();
234 klist_invalidate(&tp->tun_rsel.si_note);
235 klist_invalidate(&tp->tun_wsel.si_note);
236 splx(s);
237
238 s = splnet();
239 LIST_REMOVE(tp, tun_list);
240 splx(s);
241
242 if (tp->tun_flags & TUN_LAYER2)
243 ether_ifdetach(ifp);
244
245 if_detach(ifp);
246
247 free(tp, M_DEVBUF);
248 return (0);
249 }
250
251 struct tun_softc *
252 tun_lookup(int unit)
253 {
254 struct tun_softc *tp;
255
256 LIST_FOREACH(tp, &tun_softc_list, tun_list)
257 if (tp->tun_unit == unit)
258 return (tp);
259 return (NULL);
260 }
261
262 int
263 tun_switch(struct tun_softc *tp, int flags)
264 {
265 struct ifnet *ifp = &tp->tun_if;
266 int unit, open, r;
267
268 if ((tp->tun_flags & TUN_LAYER2) == (flags & TUN_LAYER2))
269 return (0);
270
271
272 unit = tp->tun_unit;
273 open = tp->tun_flags & (TUN_OPEN|TUN_NBIO|TUN_ASYNC);
274 TUNDEBUG(("%s: switching to layer %d\n", ifp->if_xname,
275 flags & TUN_LAYER2 ? 2 : 3));
276
277
278 tun_clone_destroy(ifp);
279
280 r = tun_create(&tun_cloner, unit, flags);
281
282 if (open && r == 0) {
283
284 if ((tp = tun_lookup(unit)) == NULL)
285
286 return (ENXIO);
287 tp->tun_flags |= open;
288 TUNDEBUG(("%s: already open\n", tp->tun_if.if_xname));
289 }
290 return (r);
291 }
292
293
294
295
296
297 int
298 tunopen(dev_t dev, int flag, int mode, struct proc *p)
299 {
300 struct tun_softc *tp;
301 struct ifnet *ifp;
302 int error, s;
303
304 if ((error = suser(p, 0)) != 0)
305 return (error);
306
307 if ((tp = tun_lookup(minor(dev))) == NULL) {
308 char xname[IFNAMSIZ];
309
310 snprintf(xname, sizeof(xname), "%s%d", "tun", minor(dev));
311 if ((error = if_clone_create(xname)) != 0)
312 return (error);
313
314 if ((tp = tun_lookup(minor(dev))) == NULL)
315 return (ENXIO);
316 tp->tun_flags &= ~TUN_STAYUP;
317 }
318
319 if (tp->tun_flags & TUN_OPEN)
320 return (EBUSY);
321
322 ifp = &tp->tun_if;
323 tp->tun_flags |= TUN_OPEN;
324
325
326 s = splnet();
327 if_up(ifp);
328 ifp->if_flags |= IFF_RUNNING;
329 splx(s);
330
331 TUNDEBUG(("%s: open\n", ifp->if_xname));
332 return (0);
333 }
334
335
336
337
338
339 int
340 tunclose(dev_t dev, int flag, int mode, struct proc *p)
341 {
342 int s;
343 struct tun_softc *tp;
344 struct ifnet *ifp;
345
346 if ((tp = tun_lookup(minor(dev))) == NULL)
347 return (ENXIO);
348
349 ifp = &tp->tun_if;
350 tp->tun_flags &= ~(TUN_OPEN|TUN_NBIO|TUN_ASYNC);
351 ifp->if_flags &= ~IFF_RUNNING;
352
353
354
355
356 s = splnet();
357 IFQ_PURGE(&ifp->if_snd);
358 splx(s);
359
360 TUNDEBUG(("%s: closed\n", ifp->if_xname));
361
362 if (!(tp->tun_flags & TUN_STAYUP))
363 return (if_clone_destroy(ifp->if_xname));
364 else {
365 tp->tun_pgid = 0;
366 selwakeup(&tp->tun_rsel);
367 KNOTE(&tp->tun_rsel.si_note, 0);
368 }
369
370 return (0);
371 }
372
373 static int
374 tuninit(struct tun_softc *tp)
375 {
376 struct ifnet *ifp = &tp->tun_if;
377 struct ifaddr *ifa;
378
379 TUNDEBUG(("%s: tuninit\n", ifp->if_xname));
380
381 ifp->if_flags |= IFF_UP | IFF_RUNNING;
382 ifp->if_flags &= ~IFF_OACTIVE;
383
384 tp->tun_flags &= ~(TUN_IASET|TUN_DSTADDR|TUN_BRDADDR);
385 TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_list) {
386 #ifdef INET
387 if (ifa->ifa_addr->sa_family == AF_INET) {
388 struct sockaddr_in *sin;
389
390 sin = satosin(ifa->ifa_addr);
391 if (sin && sin->sin_addr.s_addr)
392 tp->tun_flags |= TUN_IASET;
393
394 if (ifp->if_flags & IFF_POINTOPOINT) {
395 sin = satosin(ifa->ifa_dstaddr);
396 if (sin && sin->sin_addr.s_addr)
397 tp->tun_flags |= TUN_DSTADDR;
398 } else
399 tp->tun_flags &= ~TUN_DSTADDR;
400
401 if (ifp->if_flags & IFF_BROADCAST) {
402 sin = satosin(ifa->ifa_broadaddr);
403 if (sin && sin->sin_addr.s_addr)
404 tp->tun_flags |= TUN_BRDADDR;
405 } else
406 tp->tun_flags &= ~TUN_BRDADDR;
407 }
408 #endif
409 #ifdef INET6
410 if (ifa->ifa_addr->sa_family == AF_INET6) {
411 struct sockaddr_in6 *sin;
412
413 sin = (struct sockaddr_in6 *)ifa->ifa_addr;
414 if (!IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr))
415 tp->tun_flags |= TUN_IASET;
416
417 if (ifp->if_flags & IFF_POINTOPOINT) {
418 sin = (struct sockaddr_in6 *)ifa->ifa_dstaddr;
419 if (sin &&
420 !IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr))
421 tp->tun_flags |= TUN_DSTADDR;
422 } else
423 tp->tun_flags &= ~TUN_DSTADDR;
424 }
425 #endif
426 }
427
428 return (0);
429 }
430
431
432
433
434 int
435 tun_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
436 {
437 struct tun_softc *tp = (struct tun_softc *)(ifp->if_softc);
438 struct ifreq *ifr = (struct ifreq *)data;
439 int error = 0, s;
440
441 s = splnet();
442 if (tp->tun_flags & TUN_LAYER2)
443 if ((error = ether_ioctl(ifp, &tp->arpcom, cmd, data)) > 0) {
444 splx(s);
445 return (error);
446 }
447 switch (cmd) {
448 case SIOCSIFADDR:
449 tuninit(tp);
450 TUNDEBUG(("%s: address set\n", ifp->if_xname));
451 if (tp->tun_flags & TUN_LAYER2)
452 switch (((struct ifaddr *)data)->ifa_addr->sa_family) {
453 #ifdef INET
454 case AF_INET:
455 arp_ifinit(&tp->arpcom, (struct ifaddr *)data);
456 break;
457 #endif
458 default:
459 break;
460 }
461 break;
462 case SIOCSIFDSTADDR:
463 tuninit(tp);
464 TUNDEBUG(("%s: destination address set\n", ifp->if_xname));
465 break;
466 case SIOCSIFBRDADDR:
467 tuninit(tp);
468 TUNDEBUG(("%s: broadcast address set\n", ifp->if_xname));
469 break;
470 case SIOCSIFMTU:
471 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > TUNMRU)
472 error = EINVAL;
473 else
474 ifp->if_mtu = ifr->ifr_mtu;
475 break;
476 case SIOCADDMULTI:
477 case SIOCDELMULTI: {
478 if (ifr == 0) {
479 error = EAFNOSUPPORT;
480 break;
481 }
482
483 if (tp->tun_flags & TUN_LAYER2) {
484 error = (cmd == SIOCADDMULTI) ?
485 ether_addmulti(ifr, &tp->arpcom) :
486 ether_delmulti(ifr, &tp->arpcom);
487 if (error == ENETRESET) {
488
489
490
491
492
493 error = 0;
494 }
495 break;
496 }
497
498 switch (ifr->ifr_addr.sa_family) {
499 #ifdef INET
500 case AF_INET:
501 break;
502 #endif
503 #ifdef INET6
504 case AF_INET6:
505 break;
506 #endif
507 default:
508 error = EAFNOSUPPORT;
509 break;
510 }
511 break;
512 }
513
514 case SIOCSIFFLAGS:
515 error = tun_switch(tp,
516 ifp->if_flags & IFF_LINK0 ? TUN_LAYER2 : 0);
517 break;
518 default:
519 error = EINVAL;
520 }
521 splx(s);
522 return (error);
523 }
524
525
526
527
528 int
529 tun_output(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
530 struct rtentry *rt)
531 {
532 struct tun_softc *tp = ifp->if_softc;
533 int s, len, error;
534 u_int32_t *af;
535
536 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) {
537 m_freem(m0);
538 return (EHOSTDOWN);
539 }
540
541 TUNDEBUG(("%s: tun_output\n", ifp->if_xname));
542
543 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
544 TUNDEBUG(("%s: not ready %#x\n", ifp->if_xname,
545 tp->tun_flags));
546 m_freem(m0);
547 return (EHOSTDOWN);
548 }
549
550 if (tp->tun_flags & TUN_LAYER2)
551
552 return (ether_output(ifp, m0, dst, rt));
553
554 M_PREPEND(m0, sizeof(*af), M_DONTWAIT);
555 af = mtod(m0, u_int32_t *);
556 *af = htonl(dst->sa_family);
557
558 #if NBPFILTER > 0
559 if (ifp->if_bpf)
560 bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_OUT);
561 #endif
562
563 len = m0->m_pkthdr.len + sizeof(*af);
564 s = splnet();
565 IFQ_ENQUEUE(&ifp->if_snd, m0, NULL, error);
566 if (error) {
567 splx(s);
568 ifp->if_collisions++;
569 return (error);
570 }
571 splx(s);
572 ifp->if_opackets++;
573 ifp->if_obytes += len;
574
575 tun_wakeup(tp);
576 return (0);
577 }
578
579 void
580 tun_wakeup(struct tun_softc *tp)
581 {
582 if (tp->tun_flags & TUN_RWAIT) {
583 tp->tun_flags &= ~TUN_RWAIT;
584 wakeup((caddr_t)tp);
585 }
586 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
587 csignal(tp->tun_pgid, SIGIO,
588 tp->tun_siguid, tp->tun_sigeuid);
589 selwakeup(&tp->tun_rsel);
590 KNOTE(&tp->tun_rsel.si_note, 0);
591 }
592
593
594
595
596 int
597 tunioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
598 {
599 int s;
600 struct tun_softc *tp;
601 struct tuninfo *tunp;
602 struct mbuf *m;
603
604 if ((tp = tun_lookup(minor(dev))) == NULL)
605 return (ENXIO);
606
607 s = splnet();
608 switch (cmd) {
609 case TUNSIFINFO:
610 tunp = (struct tuninfo *)data;
611 if (tunp->mtu < ETHERMIN || tunp->mtu > TUNMRU) {
612 splx(s);
613 return (EINVAL);
614 }
615 tp->tun_if.if_mtu = tunp->mtu;
616 tp->tun_if.if_type = tunp->type;
617 tp->tun_if.if_flags =
618 (tunp->flags & TUN_IFF_FLAGS) |
619 (tp->tun_if.if_flags & ~TUN_IFF_FLAGS);
620 tp->tun_if.if_baudrate = tunp->baudrate;
621 break;
622 case TUNGIFINFO:
623 tunp = (struct tuninfo *)data;
624 tunp->mtu = tp->tun_if.if_mtu;
625 tunp->type = tp->tun_if.if_type;
626 tunp->flags = tp->tun_if.if_flags;
627 tunp->baudrate = tp->tun_if.if_baudrate;
628 break;
629 #ifdef TUN_DEBUG
630 case TUNSDEBUG:
631 tundebug = *(int *)data;
632 break;
633 case TUNGDEBUG:
634 *(int *)data = tundebug;
635 break;
636 #endif
637 case TUNSIFMODE:
638 switch (*(int *)data & (IFF_POINTOPOINT|IFF_BROADCAST)) {
639 case IFF_POINTOPOINT:
640 case IFF_BROADCAST:
641 tp->tun_if.if_flags &= ~TUN_IFF_FLAGS;
642 tp->tun_if.if_flags |= *(int *)data & TUN_IFF_FLAGS;
643 break;
644 default:
645 splx(s);
646 return (EINVAL);
647 }
648 break;
649
650 case FIONBIO:
651 if (*(int *)data)
652 tp->tun_flags |= TUN_NBIO;
653 else
654 tp->tun_flags &= ~TUN_NBIO;
655 break;
656 case FIOASYNC:
657 if (*(int *)data)
658 tp->tun_flags |= TUN_ASYNC;
659 else
660 tp->tun_flags &= ~TUN_ASYNC;
661 break;
662 case FIONREAD:
663 IFQ_POLL(&tp->tun_if.if_snd, m);
664 if (m != NULL)
665 *(int *)data = m->m_pkthdr.len;
666 else
667 *(int *)data = 0;
668 break;
669 case TIOCSPGRP:
670 tp->tun_pgid = *(int *)data;
671 tp->tun_siguid = p->p_cred->p_ruid;
672 tp->tun_sigeuid = p->p_ucred->cr_uid;
673 break;
674 case TIOCGPGRP:
675 *(int *)data = tp->tun_pgid;
676 break;
677 case OSIOCGIFADDR:
678 case SIOCGIFADDR:
679 if (!(tp->tun_flags & TUN_LAYER2)) {
680 splx(s);
681 return (EINVAL);
682 }
683 bcopy(tp->arpcom.ac_enaddr, data,
684 sizeof(tp->arpcom.ac_enaddr));
685 break;
686
687 case SIOCSIFADDR:
688 if (!(tp->tun_flags & TUN_LAYER2)) {
689 splx(s);
690 return (EINVAL);
691 }
692 bcopy(data, tp->arpcom.ac_enaddr,
693 sizeof(tp->arpcom.ac_enaddr));
694 break;
695 default:
696 splx(s);
697 return (ENOTTY);
698 }
699 splx(s);
700 return (0);
701 }
702
703
704
705
706
707 int
708 tunread(dev_t dev, struct uio *uio, int ioflag)
709 {
710 struct tun_softc *tp;
711 struct ifnet *ifp;
712 struct mbuf *m, *m0;
713 int error = 0, len, s;
714
715 if ((tp = tun_lookup(minor(dev))) == NULL)
716 return (ENXIO);
717
718 ifp = &tp->tun_if;
719 TUNDEBUG(("%s: read\n", ifp->if_xname));
720 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
721 TUNDEBUG(("%s: not ready %#x\n", ifp->if_xname, tp->tun_flags));
722 return (EHOSTDOWN);
723 }
724
725 tp->tun_flags &= ~TUN_RWAIT;
726
727 s = splnet();
728 do {
729 while ((tp->tun_flags & TUN_READY) != TUN_READY)
730 if ((error = tsleep((caddr_t)tp,
731 (PZERO + 1)|PCATCH, "tunread", 0)) != 0) {
732 splx(s);
733 return (error);
734 }
735 IFQ_DEQUEUE(&ifp->if_snd, m0);
736 if (m0 == NULL) {
737 if (tp->tun_flags & TUN_NBIO && ioflag & IO_NDELAY) {
738 splx(s);
739 return (EWOULDBLOCK);
740 }
741 tp->tun_flags |= TUN_RWAIT;
742 if ((error = tsleep((caddr_t)tp,
743 (PZERO + 1)|PCATCH, "tunread", 0)) != 0) {
744 splx(s);
745 return (error);
746 }
747 }
748 } while (m0 == NULL);
749 splx(s);
750
751 while (m0 != NULL && uio->uio_resid > 0 && error == 0) {
752 len = min(uio->uio_resid, m0->m_len);
753 if (len != 0)
754 error = uiomove(mtod(m0, caddr_t), len, uio);
755 MFREE(m0, m);
756 m0 = m;
757 }
758
759 if (m0 != NULL) {
760 TUNDEBUG(("Dropping mbuf\n"));
761 m_freem(m0);
762 }
763 if (error)
764 ifp->if_ierrors++;
765
766 return (error);
767 }
768
769
770
771
772 int
773 tunwrite(dev_t dev, struct uio *uio, int ioflag)
774 {
775 struct tun_softc *tp;
776 struct ifnet *ifp;
777 struct ifqueue *ifq;
778 u_int32_t *th;
779 struct mbuf *top, **mp, *m;
780 int isr;
781 int error=0, s, tlen, mlen;
782
783 if ((tp = tun_lookup(minor(dev))) == NULL)
784 return (ENXIO);
785
786 ifp = &tp->tun_if;
787 TUNDEBUG(("%s: tunwrite\n", ifp->if_xname));
788
789 if (uio->uio_resid == 0 || uio->uio_resid > ifp->if_mtu +
790 (tp->tun_flags & TUN_LAYER2 ? ETHER_HDR_LEN : sizeof(*th))) {
791 TUNDEBUG(("%s: len=%d!\n", ifp->if_xname, uio->uio_resid));
792 return (EMSGSIZE);
793 }
794 tlen = uio->uio_resid;
795
796
797 MGETHDR(m, M_DONTWAIT, MT_DATA);
798 if (m == NULL)
799 return (ENOBUFS);
800 mlen = MHLEN;
801 if (uio->uio_resid >= MINCLSIZE) {
802 MCLGET(m, M_DONTWAIT);
803 if (!(m->m_flags & M_EXT)) {
804 m_free(m);
805 return (ENOBUFS);
806 }
807 mlen = MCLBYTES;
808 }
809
810 top = NULL;
811 mp = ⊤
812 if (tp->tun_flags & TUN_LAYER2) {
813
814
815
816
817 mlen -= ETHER_ALIGN;
818 m->m_data += ETHER_ALIGN;
819 }
820 while (error == 0 && uio->uio_resid > 0) {
821 m->m_len = min(mlen, uio->uio_resid);
822 error = uiomove(mtod (m, caddr_t), m->m_len, uio);
823 *mp = m;
824 mp = &m->m_next;
825 if (error == 0 && uio->uio_resid > 0) {
826 MGET(m, M_DONTWAIT, MT_DATA);
827 if (m == NULL) {
828 error = ENOBUFS;
829 break;
830 }
831 mlen = MLEN;
832 if (uio->uio_resid >= MINCLSIZE) {
833 MCLGET(m, M_DONTWAIT);
834 if (!(m->m_flags & M_EXT)) {
835 error = ENOBUFS;
836 m_free(m);
837 break;
838 }
839 mlen = MCLBYTES;
840 }
841 }
842 }
843 if (error) {
844 if (top != NULL)
845 m_freem(top);
846 ifp->if_ierrors++;
847 return (error);
848 }
849
850 top->m_pkthdr.len = tlen;
851 top->m_pkthdr.rcvif = ifp;
852
853 #if NBPFILTER > 0
854 if (ifp->if_bpf)
855 bpf_mtap(ifp->if_bpf, top, BPF_DIRECTION_IN);
856 #endif
857
858 if (tp->tun_flags & TUN_LAYER2) {
859 ether_input_mbuf(ifp, top);
860 ifp->if_ipackets++;
861 return (0);
862 }
863
864 th = mtod(top, u_int32_t *);
865
866 top->m_data += sizeof(*th);
867 top->m_len -= sizeof(*th);
868 top->m_pkthdr.len -= sizeof(*th);
869
870 switch (ntohl(*th)) {
871 #ifdef INET
872 case AF_INET:
873 ifq = &ipintrq;
874 isr = NETISR_IP;
875 break;
876 #endif
877 #ifdef INET6
878 case AF_INET6:
879 ifq = &ip6intrq;
880 isr = NETISR_IPV6;
881 break;
882 #endif
883 #ifdef NETATALK
884 case AF_APPLETALK:
885 ifq = &atintrq2;
886 isr = NETISR_ATALK;
887 break;
888 #endif
889 default:
890 m_freem(top);
891 return (EAFNOSUPPORT);
892 }
893
894 s = splnet();
895 if (IF_QFULL(ifq)) {
896 IF_DROP(ifq);
897 splx(s);
898 ifp->if_collisions++;
899 m_freem(top);
900 if (!ifq->ifq_congestion)
901 if_congestion(ifq);
902 return (ENOBUFS);
903 }
904 IF_ENQUEUE(ifq, top);
905 schednetisr(isr);
906 ifp->if_ipackets++;
907 ifp->if_ibytes += top->m_pkthdr.len;
908 splx(s);
909 return (error);
910 }
911
912
913
914
915
916
917 int
918 tunpoll(dev_t dev, int events, struct proc *p)
919 {
920 int revents, s;
921 struct tun_softc *tp;
922 struct ifnet *ifp;
923 struct mbuf *m;
924
925 if ((tp = tun_lookup(minor(dev))) == NULL)
926 return (POLLERR);
927
928 ifp = &tp->tun_if;
929 revents = 0;
930 s = splnet();
931 TUNDEBUG(("%s: tunpoll\n", ifp->if_xname));
932
933 if (events & (POLLIN | POLLRDNORM)) {
934 IFQ_POLL(&ifp->if_snd, m);
935 if (m != NULL) {
936 TUNDEBUG(("%s: tunselect q=%d\n", ifp->if_xname,
937 ifp->if_snd.ifq_len));
938 revents |= events & (POLLIN | POLLRDNORM);
939 } else {
940 TUNDEBUG(("%s: tunpoll waiting\n", ifp->if_xname));
941 selrecord(p, &tp->tun_rsel);
942 }
943 }
944 if (events & (POLLOUT | POLLWRNORM))
945 revents |= events & (POLLOUT | POLLWRNORM);
946 splx(s);
947 return (revents);
948 }
949
950
951
952
953
954
955
956
957
958
959 int
960 tunkqfilter(dev_t dev, struct knote *kn)
961 {
962 int s;
963 struct klist *klist;
964 struct tun_softc *tp;
965 struct ifnet *ifp;
966
967 if ((tp = tun_lookup(minor(dev))) == NULL)
968 return (ENXIO);
969
970 ifp = &tp->tun_if;
971
972 s = splnet();
973 TUNDEBUG(("%s: tunkqfilter\n", ifp->if_xname));
974 splx(s);
975
976 switch (kn->kn_filter) {
977 case EVFILT_READ:
978 klist = &tp->tun_rsel.si_note;
979 kn->kn_fop = &tunread_filtops;
980 break;
981 case EVFILT_WRITE:
982 klist = &tp->tun_wsel.si_note;
983 kn->kn_fop = &tunwrite_filtops;
984 break;
985 default:
986 return (EPERM);
987 }
988
989 kn->kn_hook = (caddr_t)tp;
990
991 s = splhigh();
992 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
993 splx(s);
994
995 return (0);
996 }
997
998 void
999 filt_tunrdetach(struct knote *kn)
1000 {
1001 int s;
1002 struct tun_softc *tp;
1003
1004 tp = (struct tun_softc *)kn->kn_hook;
1005 s = splhigh();
1006 if (!(kn->kn_status & KN_DETACHED))
1007 SLIST_REMOVE(&tp->tun_rsel.si_note, kn, knote, kn_selnext);
1008 splx(s);
1009 }
1010
1011 int
1012 filt_tunread(struct knote *kn, long hint)
1013 {
1014 int s;
1015 struct tun_softc *tp;
1016 struct ifnet *ifp;
1017 struct mbuf *m;
1018
1019 if (kn->kn_status & KN_DETACHED) {
1020 kn->kn_data = 0;
1021 return (1);
1022 }
1023
1024 tp = (struct tun_softc *)kn->kn_hook;
1025 ifp = &tp->tun_if;
1026
1027 s = splnet();
1028 IFQ_POLL(&ifp->if_snd, m);
1029 if (m != NULL) {
1030 splx(s);
1031 kn->kn_data = ifp->if_snd.ifq_len;
1032
1033 TUNDEBUG(("%s: tunkqread q=%d\n", ifp->if_xname,
1034 ifp->if_snd.ifq_len));
1035 return (1);
1036 }
1037 splx(s);
1038 TUNDEBUG(("%s: tunkqread waiting\n", ifp->if_xname));
1039 return (0);
1040 }
1041
1042 void
1043 filt_tunwdetach(struct knote *kn)
1044 {
1045 int s;
1046 struct tun_softc *tp;
1047
1048 tp = (struct tun_softc *)kn->kn_hook;
1049 s = splhigh();
1050 if (!(kn->kn_status & KN_DETACHED))
1051 SLIST_REMOVE(&tp->tun_wsel.si_note, kn, knote, kn_selnext);
1052 splx(s);
1053 }
1054
1055 int
1056 filt_tunwrite(struct knote *kn, long hint)
1057 {
1058 struct tun_softc *tp;
1059 struct ifnet *ifp;
1060
1061 if (kn->kn_status & KN_DETACHED) {
1062 kn->kn_data = 0;
1063 return (1);
1064 }
1065
1066 tp = (struct tun_softc *)kn->kn_hook;
1067 ifp = &tp->tun_if;
1068
1069 kn->kn_data = ifp->if_mtu;
1070
1071 return (1);
1072 }
1073
1074
1075
1076
1077
1078
1079
1080
1081 static void
1082 tunstart(struct ifnet *ifp)
1083 {
1084 struct tun_softc *tp = ifp->if_softc;
1085 struct mbuf *m;
1086
1087 if (!(tp->tun_flags & TUN_LAYER2) &&
1088 !ALTQ_IS_ENABLED(&ifp->if_snd) &&
1089 !TBR_IS_ENABLED(&ifp->if_snd))
1090 return;
1091
1092 IFQ_POLL(&ifp->if_snd, m);
1093 if (m != NULL) {
1094 if (tp->tun_flags & TUN_LAYER2) {
1095 #if NBPFILTER > 0
1096 if (ifp->if_bpf)
1097 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
1098 #endif
1099 ifp->if_opackets++;
1100 }
1101 tun_wakeup(tp);
1102 }
1103 }