if_tun.c revision 1.122 1 /* $NetBSD: if_tun.c,v 1.122 2015/08/20 14:40:19 christos Exp $ */
2
3 /*
4 * Copyright (c) 1988, Julian Onions <jpo (at) 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 its wicked way with. This driver has its
12 * roots in a similar driver written by Phil Cockcroft (formerly) at
13 * UCL. This driver is based much more on read/write/poll mode of
14 * operation though.
15 */
16
17 #include <sys/cdefs.h>
18 __KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1.122 2015/08/20 14:40:19 christos Exp $");
19
20 #include "opt_inet.h"
21
22 #include <sys/param.h>
23 #include <sys/proc.h>
24 #include <sys/systm.h>
25 #include <sys/mbuf.h>
26 #include <sys/buf.h>
27 #include <sys/protosw.h>
28 #include <sys/socket.h>
29 #include <sys/ioctl.h>
30 #include <sys/errno.h>
31 #include <sys/syslog.h>
32 #include <sys/select.h>
33 #include <sys/poll.h>
34 #include <sys/file.h>
35 #include <sys/signalvar.h>
36 #include <sys/conf.h>
37 #include <sys/kauth.h>
38 #include <sys/mutex.h>
39 #include <sys/cpu.h>
40
41 #include <net/if.h>
42 #include <net/if_types.h>
43 #include <net/netisr.h>
44 #include <net/route.h>
45
46
47 #ifdef INET
48 #include <netinet/in.h>
49 #include <netinet/in_systm.h>
50 #include <netinet/in_var.h>
51 #include <netinet/ip.h>
52 #include <netinet/if_inarp.h>
53 #endif
54
55
56 #include <sys/time.h>
57 #include <net/bpf.h>
58
59 #include <net/if_tun.h>
60
61 #include "ioconf.h"
62
63 #define TUNDEBUG if (tundebug) printf
64 int tundebug = 0;
65
66 extern int ifqmaxlen;
67
68 static LIST_HEAD(, tun_softc) tun_softc_list;
69 static LIST_HEAD(, tun_softc) tunz_softc_list;
70 static kmutex_t tun_softc_lock;
71
72 static int tun_ioctl(struct ifnet *, u_long, void *);
73 static int tun_output(struct ifnet *, struct mbuf *,
74 const struct sockaddr *, struct rtentry *rt);
75 static int tun_clone_create(struct if_clone *, int);
76 static int tun_clone_destroy(struct ifnet *);
77
78 static struct if_clone tun_cloner =
79 IF_CLONE_INITIALIZER("tun", tun_clone_create, tun_clone_destroy);
80
81 static void tunattach0(struct tun_softc *);
82 static void tuninit(struct tun_softc *);
83 static void tun_i_softintr(void *);
84 static void tun_o_softintr(void *);
85 #ifdef ALTQ
86 static void tunstart(struct ifnet *);
87 #endif
88 static struct tun_softc *tun_find_unit(dev_t);
89 static struct tun_softc *tun_find_zunit(int);
90
91 static dev_type_open(tunopen);
92 static dev_type_close(tunclose);
93 static dev_type_read(tunread);
94 static dev_type_write(tunwrite);
95 static dev_type_ioctl(tunioctl);
96 static dev_type_poll(tunpoll);
97 static dev_type_kqfilter(tunkqfilter);
98
99 const struct cdevsw tun_cdevsw = {
100 .d_open = tunopen,
101 .d_close = tunclose,
102 .d_read = tunread,
103 .d_write = tunwrite,
104 .d_ioctl = tunioctl,
105 .d_stop = nostop,
106 .d_tty = notty,
107 .d_poll = tunpoll,
108 .d_mmap = nommap,
109 .d_kqfilter = tunkqfilter,
110 .d_discard = nodiscard,
111 .d_flag = D_OTHER
112 };
113
114 void
115 tunattach(int unused)
116 {
117
118 mutex_init(&tun_softc_lock, MUTEX_DEFAULT, IPL_NET);
119 LIST_INIT(&tun_softc_list);
120 LIST_INIT(&tunz_softc_list);
121 if_clone_attach(&tun_cloner);
122 }
123
124 /*
125 * Find driver instance from dev_t.
126 * Returns with tp locked (if found).
127 */
128 static struct tun_softc *
129 tun_find_unit(dev_t dev)
130 {
131 struct tun_softc *tp;
132 int unit = minor(dev);
133
134 mutex_enter(&tun_softc_lock);
135 LIST_FOREACH(tp, &tun_softc_list, tun_list)
136 if (unit == tp->tun_unit)
137 break;
138 if (tp)
139 mutex_enter(&tp->tun_lock);
140 mutex_exit(&tun_softc_lock);
141
142 return (tp);
143 }
144
145 /*
146 * Find zombie driver instance by unit number.
147 * Remove tp from list and return it unlocked (if found).
148 */
149 static struct tun_softc *
150 tun_find_zunit(int unit)
151 {
152 struct tun_softc *tp;
153
154 mutex_enter(&tun_softc_lock);
155 LIST_FOREACH(tp, &tunz_softc_list, tun_list)
156 if (unit == tp->tun_unit)
157 break;
158 if (tp)
159 LIST_REMOVE(tp, tun_list);
160 mutex_exit(&tun_softc_lock);
161 #ifdef DIAGNOSTIC
162 if (tp != NULL && (tp->tun_flags & (TUN_INITED|TUN_OPEN)) != TUN_OPEN)
163 printf("tun%d: inconsistent flags: %x\n", unit, tp->tun_flags);
164 #endif
165
166 return (tp);
167 }
168
169 static int
170 tun_clone_create(struct if_clone *ifc, int unit)
171 {
172 struct tun_softc *tp;
173
174 if ((tp = tun_find_zunit(unit)) == NULL) {
175 /* Allocate a new instance */
176 tp = malloc(sizeof(*tp), M_DEVBUF, M_WAITOK|M_ZERO);
177
178 tp->tun_unit = unit;
179 mutex_init(&tp->tun_lock, MUTEX_DEFAULT, IPL_NET);
180 selinit(&tp->tun_rsel);
181 selinit(&tp->tun_wsel);
182 } else {
183 /* Revive tunnel instance; clear ifp part */
184 (void)memset(&tp->tun_if, 0, sizeof(struct ifnet));
185 }
186
187 if_initname(&tp->tun_if, ifc->ifc_name, unit);
188 tunattach0(tp);
189 tp->tun_flags |= TUN_INITED;
190 tp->tun_osih = softint_establish(SOFTINT_CLOCK, tun_o_softintr, tp);
191 tp->tun_isih = softint_establish(SOFTINT_CLOCK, tun_i_softintr, tp);
192
193 mutex_enter(&tun_softc_lock);
194 LIST_INSERT_HEAD(&tun_softc_list, tp, tun_list);
195 mutex_exit(&tun_softc_lock);
196
197 return (0);
198 }
199
200 static void
201 tunattach0(struct tun_softc *tp)
202 {
203 struct ifnet *ifp;
204
205 ifp = &tp->tun_if;
206 ifp->if_softc = tp;
207 ifp->if_mtu = TUNMTU;
208 ifp->if_ioctl = tun_ioctl;
209 ifp->if_output = tun_output;
210 #ifdef ALTQ
211 ifp->if_start = tunstart;
212 #endif
213 ifp->if_flags = IFF_POINTOPOINT;
214 ifp->if_type = IFT_TUNNEL;
215 ifp->if_snd.ifq_maxlen = ifqmaxlen;
216 ifp->if_collisions = 0;
217 ifp->if_ierrors = 0;
218 ifp->if_oerrors = 0;
219 ifp->if_ipackets = 0;
220 ifp->if_opackets = 0;
221 ifp->if_ibytes = 0;
222 ifp->if_obytes = 0;
223 ifp->if_dlt = DLT_NULL;
224 IFQ_SET_READY(&ifp->if_snd);
225 if_attach(ifp);
226 if_alloc_sadl(ifp);
227 bpf_attach(ifp, DLT_NULL, sizeof(uint32_t));
228 }
229
230 static int
231 tun_clone_destroy(struct ifnet *ifp)
232 {
233 struct tun_softc *tp = (void *)ifp;
234 int zombie = 0;
235
236 IF_PURGE(&ifp->if_snd);
237 ifp->if_flags &= ~IFF_RUNNING;
238
239 mutex_enter(&tun_softc_lock);
240 mutex_enter(&tp->tun_lock);
241 LIST_REMOVE(tp, tun_list);
242 if (tp->tun_flags & TUN_OPEN) {
243 /* Hang on to storage until last close */
244 zombie = 1;
245 tp->tun_flags &= ~TUN_INITED;
246 LIST_INSERT_HEAD(&tunz_softc_list, tp, tun_list);
247 }
248 mutex_exit(&tun_softc_lock);
249
250 if (tp->tun_flags & TUN_RWAIT) {
251 tp->tun_flags &= ~TUN_RWAIT;
252 wakeup((void *)tp);
253 }
254 selnotify(&tp->tun_rsel, 0, 0);
255
256 mutex_exit(&tp->tun_lock);
257
258 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
259 fownsignal(tp->tun_pgid, SIGIO, POLL_HUP, 0, NULL);
260
261 bpf_detach(ifp);
262 if_detach(ifp);
263
264 if (!zombie) {
265 seldestroy(&tp->tun_rsel);
266 seldestroy(&tp->tun_wsel);
267 softint_disestablish(tp->tun_osih);
268 softint_disestablish(tp->tun_isih);
269 mutex_destroy(&tp->tun_lock);
270 free(tp, M_DEVBUF);
271 }
272
273 return (0);
274 }
275
276 /*
277 * tunnel open - must be superuser & the device must be
278 * configured in
279 */
280 static int
281 tunopen(dev_t dev, int flag, int mode, struct lwp *l)
282 {
283 struct ifnet *ifp;
284 struct tun_softc *tp;
285 int error;
286
287 error = kauth_authorize_network(l->l_cred, KAUTH_NETWORK_INTERFACE_TUN,
288 KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD, NULL, NULL, NULL);
289 if (error)
290 return (error);
291
292 tp = tun_find_unit(dev);
293
294 if (tp == NULL) {
295 (void)tun_clone_create(&tun_cloner, minor(dev));
296 tp = tun_find_unit(dev);
297 if (tp == NULL) {
298 error = ENXIO;
299 goto out_nolock;
300 }
301 }
302
303 if (tp->tun_flags & TUN_OPEN) {
304 error = EBUSY;
305 goto out;
306 }
307
308 ifp = &tp->tun_if;
309 tp->tun_flags |= TUN_OPEN;
310 TUNDEBUG("%s: open\n", ifp->if_xname);
311 out:
312 mutex_exit(&tp->tun_lock);
313 out_nolock:
314 return (error);
315 }
316
317 /*
318 * tunclose - close the device - mark i/f down & delete
319 * routing info
320 */
321 int
322 tunclose(dev_t dev, int flag, int mode,
323 struct lwp *l)
324 {
325 struct tun_softc *tp;
326 struct ifnet *ifp;
327
328 if ((tp = tun_find_zunit(minor(dev))) != NULL) {
329 /* interface was "destroyed" before the close */
330 seldestroy(&tp->tun_rsel);
331 seldestroy(&tp->tun_wsel);
332 softint_disestablish(tp->tun_osih);
333 softint_disestablish(tp->tun_isih);
334 mutex_destroy(&tp->tun_lock);
335 free(tp, M_DEVBUF);
336 goto out_nolock;
337 }
338
339 if ((tp = tun_find_unit(dev)) == NULL)
340 goto out_nolock;
341
342 ifp = &tp->tun_if;
343
344 tp->tun_flags &= ~TUN_OPEN;
345
346 tp->tun_pgid = 0;
347 selnotify(&tp->tun_rsel, 0, 0);
348
349 TUNDEBUG ("%s: closed\n", ifp->if_xname);
350 mutex_exit(&tp->tun_lock);
351
352 /*
353 * junk all pending output
354 */
355 IFQ_PURGE(&ifp->if_snd);
356
357 if (ifp->if_flags & IFF_UP) {
358 if_down(ifp);
359 if (ifp->if_flags & IFF_RUNNING) {
360 /* find internet addresses and delete routes */
361 struct ifaddr *ifa;
362 IFADDR_FOREACH(ifa, ifp) {
363 #if defined(INET) || defined(INET6)
364 if (ifa->ifa_addr->sa_family == AF_INET ||
365 ifa->ifa_addr->sa_family == AF_INET6) {
366 rtinit(ifa, (int)RTM_DELETE,
367 tp->tun_flags & TUN_DSTADDR
368 ? RTF_HOST
369 : 0);
370 }
371 #endif
372 }
373 }
374 }
375 out_nolock:
376 return (0);
377 }
378
379 /*
380 * Call at splnet().
381 */
382 static void
383 tuninit(struct tun_softc *tp)
384 {
385 struct ifnet *ifp = &tp->tun_if;
386 struct ifaddr *ifa;
387
388 TUNDEBUG("%s: tuninit\n", ifp->if_xname);
389
390 mutex_enter(&tp->tun_lock);
391 ifp->if_flags |= IFF_UP | IFF_RUNNING;
392
393 tp->tun_flags &= ~(TUN_IASET|TUN_DSTADDR);
394 IFADDR_FOREACH(ifa, ifp) {
395 #ifdef INET
396 if (ifa->ifa_addr->sa_family == AF_INET) {
397 struct sockaddr_in *sin;
398
399 sin = satosin(ifa->ifa_addr);
400 if (sin && sin->sin_addr.s_addr)
401 tp->tun_flags |= TUN_IASET;
402
403 if (ifp->if_flags & IFF_POINTOPOINT) {
404 sin = satosin(ifa->ifa_dstaddr);
405 if (sin && sin->sin_addr.s_addr)
406 tp->tun_flags |= TUN_DSTADDR;
407 }
408 }
409 #endif
410 #ifdef INET6
411 if (ifa->ifa_addr->sa_family == AF_INET6) {
412 struct sockaddr_in6 *sin;
413
414 sin = (struct sockaddr_in6 *)ifa->ifa_addr;
415 if (!IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr))
416 tp->tun_flags |= TUN_IASET;
417
418 if (ifp->if_flags & IFF_POINTOPOINT) {
419 sin = (struct sockaddr_in6 *)ifa->ifa_dstaddr;
420 if (sin &&
421 !IN6_IS_ADDR_UNSPECIFIED(&sin->sin6_addr))
422 tp->tun_flags |= TUN_DSTADDR;
423 } else
424 tp->tun_flags &= ~TUN_DSTADDR;
425 }
426 #endif /* INET6 */
427 }
428 mutex_exit(&tp->tun_lock);
429 }
430
431 /*
432 * Process an ioctl request.
433 */
434 static int
435 tun_ioctl(struct ifnet *ifp, u_long cmd, void *data)
436 {
437 int error = 0, s;
438 struct tun_softc *tp = (struct tun_softc *)(ifp->if_softc);
439 struct ifreq *ifr = (struct ifreq *)data;
440 struct ifaddr *ifa = (struct ifaddr *)data;
441
442 s = splnet();
443
444 switch (cmd) {
445 case SIOCINITIFADDR:
446 tuninit(tp);
447 ifa->ifa_rtrequest = p2p_rtrequest;
448 TUNDEBUG("%s: address set\n", ifp->if_xname);
449 break;
450 case SIOCSIFBRDADDR:
451 TUNDEBUG("%s: broadcast address set\n", ifp->if_xname);
452 break;
453 case SIOCSIFMTU:
454 if (ifr->ifr_mtu > TUNMTU || ifr->ifr_mtu < 576) {
455 error = EINVAL;
456 break;
457 }
458 TUNDEBUG("%s: interface mtu set\n", ifp->if_xname);
459 if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
460 error = 0;
461 break;
462 case SIOCADDMULTI:
463 case SIOCDELMULTI:
464 if (ifr == NULL) {
465 error = EAFNOSUPPORT; /* XXX */
466 break;
467 }
468 switch (ifreq_getaddr(cmd, ifr)->sa_family) {
469 #ifdef INET
470 case AF_INET:
471 break;
472 #endif
473 #ifdef INET6
474 case AF_INET6:
475 break;
476 #endif
477 default:
478 error = EAFNOSUPPORT;
479 break;
480 }
481 break;
482 default:
483 error = ifioctl_common(ifp, cmd, data);
484 }
485
486 splx(s);
487 return (error);
488 }
489
490 /*
491 * tun_output - queue packets from higher level ready to put out.
492 */
493 static int
494 tun_output(struct ifnet *ifp, struct mbuf *m0, const struct sockaddr *dst,
495 struct rtentry *rt)
496 {
497 struct tun_softc *tp = ifp->if_softc;
498 int s;
499 int error;
500 #if defined(INET) || defined(INET6)
501 int mlen;
502 uint32_t *af;
503 #endif
504 ALTQ_DECL(struct altq_pktattr pktattr;)
505
506 s = splnet();
507 mutex_enter(&tp->tun_lock);
508 TUNDEBUG ("%s: tun_output\n", ifp->if_xname);
509
510 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
511 TUNDEBUG ("%s: not ready 0%o\n", ifp->if_xname,
512 tp->tun_flags);
513 error = EHOSTDOWN;
514 goto out;
515 }
516
517 /*
518 * if the queueing discipline needs packet classification,
519 * do it before prepending link headers.
520 */
521 IFQ_CLASSIFY(&ifp->if_snd, m0, dst->sa_family, &pktattr);
522
523 bpf_mtap_af(ifp, dst->sa_family, m0);
524
525 switch(dst->sa_family) {
526 #ifdef INET6
527 case AF_INET6:
528 #endif
529 #ifdef INET
530 case AF_INET:
531 #endif
532 #if defined(INET) || defined(INET6)
533 if (tp->tun_flags & TUN_PREPADDR) {
534 /* Simple link-layer header */
535 M_PREPEND(m0, dst->sa_len, M_DONTWAIT);
536 if (m0 == NULL) {
537 IF_DROP(&ifp->if_snd);
538 error = ENOBUFS;
539 goto out;
540 }
541 bcopy(dst, mtod(m0, char *), dst->sa_len);
542 }
543
544 if (tp->tun_flags & TUN_IFHEAD) {
545 /* Prepend the address family */
546 M_PREPEND(m0, sizeof(*af), M_DONTWAIT);
547 if (m0 == NULL) {
548 IF_DROP(&ifp->if_snd);
549 error = ENOBUFS;
550 goto out;
551 }
552 af = mtod(m0,uint32_t *);
553 *af = htonl(dst->sa_family);
554 } else {
555 #ifdef INET
556 if (dst->sa_family != AF_INET)
557 #endif
558 {
559 error = EAFNOSUPPORT;
560 goto out;
561 }
562 }
563 /* FALLTHROUGH */
564 case AF_UNSPEC:
565 IFQ_ENQUEUE(&ifp->if_snd, m0, &pktattr, error);
566 if (error) {
567 ifp->if_collisions++;
568 error = EAFNOSUPPORT;
569 m0 = NULL;
570 goto out;
571 }
572 mlen = m0->m_pkthdr.len;
573 ifp->if_opackets++;
574 ifp->if_obytes += mlen;
575 break;
576 #endif
577 default:
578 error = EAFNOSUPPORT;
579 goto out;
580 }
581
582 if (tp->tun_flags & TUN_RWAIT) {
583 tp->tun_flags &= ~TUN_RWAIT;
584 wakeup((void *)tp);
585 }
586 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
587 softint_schedule(tp->tun_isih);
588
589 selnotify(&tp->tun_rsel, 0, 0);
590 out:
591 mutex_exit(&tp->tun_lock);
592 splx(s);
593
594 if (error && m0) {
595 m_freem(m0);
596 }
597 return 0;
598 }
599
600 static void
601 tun_i_softintr(void *cookie)
602 {
603 struct tun_softc *tp = cookie;
604
605 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
606 fownsignal(tp->tun_pgid, SIGIO, POLL_IN, POLLIN|POLLRDNORM,
607 NULL);
608 }
609
610 static void
611 tun_o_softintr(void *cookie)
612 {
613 struct tun_softc *tp = cookie;
614
615 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
616 fownsignal(tp->tun_pgid, SIGIO, POLL_OUT, POLLOUT|POLLWRNORM,
617 NULL);
618 }
619
620 /*
621 * the cdevsw interface is now pretty minimal.
622 */
623 int
624 tunioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
625 {
626 struct tun_softc *tp;
627 int s, error = 0;
628
629 s = splnet();
630 tp = tun_find_unit(dev);
631
632 /* interface was "destroyed" already */
633 if (tp == NULL) {
634 error = ENXIO;
635 goto out_nolock;
636 }
637
638 switch (cmd) {
639 case TUNSDEBUG:
640 tundebug = *(int *)data;
641 break;
642
643 case TUNGDEBUG:
644 *(int *)data = tundebug;
645 break;
646
647 case TUNSIFMODE:
648 switch (*(int *)data & (IFF_POINTOPOINT|IFF_BROADCAST)) {
649 case IFF_POINTOPOINT:
650 case IFF_BROADCAST:
651 if (tp->tun_if.if_flags & IFF_UP) {
652 error = EBUSY;
653 goto out;
654 }
655 tp->tun_if.if_flags &=
656 ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
657 tp->tun_if.if_flags |= *(int *)data;
658 break;
659 default:
660 error = EINVAL;
661 goto out;
662 }
663 break;
664
665 case TUNSLMODE:
666 if (*(int *)data) {
667 tp->tun_flags |= TUN_PREPADDR;
668 tp->tun_flags &= ~TUN_IFHEAD;
669 } else
670 tp->tun_flags &= ~TUN_PREPADDR;
671 break;
672
673 case TUNSIFHEAD:
674 if (*(int *)data) {
675 tp->tun_flags |= TUN_IFHEAD;
676 tp->tun_flags &= ~TUN_PREPADDR;
677 } else
678 tp->tun_flags &= ~TUN_IFHEAD;
679 break;
680
681 case TUNGIFHEAD:
682 *(int *)data = (tp->tun_flags & TUN_IFHEAD);
683 break;
684
685 case FIONBIO:
686 if (*(int *)data)
687 tp->tun_flags |= TUN_NBIO;
688 else
689 tp->tun_flags &= ~TUN_NBIO;
690 break;
691
692 case FIOASYNC:
693 if (*(int *)data)
694 tp->tun_flags |= TUN_ASYNC;
695 else
696 tp->tun_flags &= ~TUN_ASYNC;
697 break;
698
699 case FIONREAD:
700 if (tp->tun_if.if_snd.ifq_head)
701 *(int *)data = tp->tun_if.if_snd.ifq_head->m_pkthdr.len;
702 else
703 *(int *)data = 0;
704 break;
705
706 case TIOCSPGRP:
707 case FIOSETOWN:
708 error = fsetown(&tp->tun_pgid, cmd, data);
709 break;
710
711 case TIOCGPGRP:
712 case FIOGETOWN:
713 error = fgetown(tp->tun_pgid, cmd, data);
714 break;
715
716 default:
717 error = ENOTTY;
718 }
719
720 out:
721 mutex_exit(&tp->tun_lock);
722 out_nolock:
723 splx(s);
724 return (error);
725 }
726
727 /*
728 * The cdevsw read interface - reads a packet at a time, or at
729 * least as much of a packet as can be read.
730 */
731 int
732 tunread(dev_t dev, struct uio *uio, int ioflag)
733 {
734 struct tun_softc *tp;
735 struct ifnet *ifp;
736 struct mbuf *m, *m0;
737 int error = 0, len, s, index;
738
739 s = splnet();
740 tp = tun_find_unit(dev);
741
742 /* interface was "destroyed" already */
743 if (tp == NULL) {
744 error = ENXIO;
745 goto out_nolock;
746 }
747
748 index = tp->tun_if.if_index;
749 ifp = &tp->tun_if;
750
751 TUNDEBUG ("%s: read\n", ifp->if_xname);
752 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
753 TUNDEBUG ("%s: not ready 0%o\n", ifp->if_xname, tp->tun_flags);
754 error = EHOSTDOWN;
755 goto out;
756 }
757
758 tp->tun_flags &= ~TUN_RWAIT;
759
760 do {
761 IFQ_DEQUEUE(&ifp->if_snd, m0);
762 if (m0 == 0) {
763 if (tp->tun_flags & TUN_NBIO) {
764 error = EWOULDBLOCK;
765 goto out;
766 }
767 tp->tun_flags |= TUN_RWAIT;
768 if (mtsleep((void *)tp, PZERO|PCATCH|PNORELOCK,
769 "tunread", 0, &tp->tun_lock) != 0) {
770 error = EINTR;
771 goto out_nolock;
772 } else {
773 /*
774 * Maybe the interface was destroyed while
775 * we were sleeping, so let's ensure that
776 * we're looking at the same (valid) tun
777 * interface before looping.
778 */
779 tp = tun_find_unit(dev);
780 if (tp == NULL) {
781 error = ENXIO;
782 goto out_nolock;
783 }
784 if (tp->tun_if.if_index != index) {
785 error = ENXIO;
786 goto out;
787 }
788 }
789 }
790 } while (m0 == 0);
791
792 mutex_exit(&tp->tun_lock);
793 splx(s);
794
795 /* Copy the mbuf chain */
796 while (m0 && uio->uio_resid > 0 && error == 0) {
797 len = min(uio->uio_resid, m0->m_len);
798 if (len != 0)
799 error = uiomove(mtod(m0, void *), len, uio);
800 MFREE(m0, m);
801 m0 = m;
802 }
803
804 if (m0) {
805 TUNDEBUG("Dropping mbuf\n");
806 m_freem(m0);
807 }
808 if (error)
809 ifp->if_ierrors++;
810
811 return (error);
812
813 out:
814 mutex_exit(&tp->tun_lock);
815 out_nolock:
816 splx(s);
817 return (error);
818 }
819
820 /*
821 * the cdevsw write interface - an atomic write is a packet - or else!
822 */
823 int
824 tunwrite(dev_t dev, struct uio *uio, int ioflag)
825 {
826 struct tun_softc *tp;
827 struct ifnet *ifp;
828 struct mbuf *top, **mp, *m;
829 pktqueue_t *pktq;
830 struct sockaddr dst;
831 int error = 0, s, tlen, mlen;
832 uint32_t family;
833
834 s = splnet();
835 tp = tun_find_unit(dev);
836
837 /* interface was "destroyed" already */
838 if (tp == NULL) {
839 error = ENXIO;
840 goto out_nolock;
841 }
842
843 /* Unlock until we've got the data */
844 mutex_exit(&tp->tun_lock);
845 splx(s);
846
847 ifp = &tp->tun_if;
848
849 TUNDEBUG("%s: tunwrite\n", ifp->if_xname);
850
851 if (tp->tun_flags & TUN_PREPADDR) {
852 if (uio->uio_resid < sizeof(dst)) {
853 error = EIO;
854 goto out0;
855 }
856 error = uiomove((void *)&dst, sizeof(dst), uio);
857 if (dst.sa_len > sizeof(dst)) {
858 /* Duh.. */
859 char discard;
860 int n = dst.sa_len - sizeof(dst);
861 while (n--)
862 if ((error = uiomove(&discard, 1, uio)) != 0) {
863 goto out0;
864 }
865 }
866 } else if (tp->tun_flags & TUN_IFHEAD) {
867 if (uio->uio_resid < sizeof(family)){
868 error = EIO;
869 goto out0;
870 }
871 error = uiomove((void *)&family, sizeof(family), uio);
872 dst.sa_family = ntohl(family);
873 } else {
874 #ifdef INET
875 dst.sa_family = AF_INET;
876 #endif
877 }
878
879 if (uio->uio_resid > TUNMTU) {
880 TUNDEBUG("%s: len=%lu!\n", ifp->if_xname,
881 (unsigned long)uio->uio_resid);
882 error = EIO;
883 goto out0;
884 }
885
886 switch (dst.sa_family) {
887 #ifdef INET
888 case AF_INET:
889 pktq = ip_pktq;
890 break;
891 #endif
892 #ifdef INET6
893 case AF_INET6:
894 pktq = ip6_pktq;
895 break;
896 #endif
897 default:
898 error = EAFNOSUPPORT;
899 goto out0;
900 }
901
902 tlen = uio->uio_resid;
903
904 /* get a header mbuf */
905 MGETHDR(m, M_DONTWAIT, MT_DATA);
906 if (m == NULL) {
907 error = ENOBUFS;
908 goto out0;
909 }
910 mlen = MHLEN;
911
912 top = NULL;
913 mp = ⊤
914 while (error == 0 && uio->uio_resid > 0) {
915 m->m_len = min(mlen, uio->uio_resid);
916 error = uiomove(mtod(m, void *), m->m_len, uio);
917 *mp = m;
918 mp = &m->m_next;
919 if (error == 0 && uio->uio_resid > 0) {
920 MGET(m, M_DONTWAIT, MT_DATA);
921 if (m == NULL) {
922 error = ENOBUFS;
923 break;
924 }
925 mlen = MLEN;
926 }
927 }
928 if (error) {
929 if (top != NULL)
930 m_freem (top);
931 ifp->if_ierrors++;
932 goto out0;
933 }
934
935 top->m_pkthdr.len = tlen;
936 top->m_pkthdr.rcvif = ifp;
937
938 bpf_mtap_af(ifp, dst.sa_family, top);
939
940 s = splnet();
941 mutex_enter(&tp->tun_lock);
942 if ((tp->tun_flags & TUN_INITED) == 0) {
943 /* Interface was destroyed */
944 error = ENXIO;
945 goto out;
946 }
947 if (__predict_false(!pktq_enqueue(pktq, top, 0))) {
948 ifp->if_collisions++;
949 mutex_exit(&tp->tun_lock);
950 error = ENOBUFS;
951 m_freem(top);
952 goto out_nolock;
953 }
954 ifp->if_ipackets++;
955 ifp->if_ibytes += tlen;
956 out:
957 mutex_exit(&tp->tun_lock);
958 out_nolock:
959 splx(s);
960 out0:
961 return (error);
962 }
963
964 #ifdef ALTQ
965 /*
966 * Start packet transmission on the interface.
967 * when the interface queue is rate-limited by ALTQ or TBR,
968 * if_start is needed to drain packets from the queue in order
969 * to notify readers when outgoing packets become ready.
970 *
971 * Should be called at splnet.
972 */
973 static void
974 tunstart(struct ifnet *ifp)
975 {
976 struct tun_softc *tp = ifp->if_softc;
977
978 if (!ALTQ_IS_ENABLED(&ifp->if_snd) && !TBR_IS_ENABLED(&ifp->if_snd))
979 return;
980
981 mutex_enter(&tp->tun_lock);
982 if (!IF_IS_EMPTY(&ifp->if_snd)) {
983 if (tp->tun_flags & TUN_RWAIT) {
984 tp->tun_flags &= ~TUN_RWAIT;
985 wakeup((void *)tp);
986 }
987 if (tp->tun_flags & TUN_ASYNC && tp->tun_pgid)
988 softint_schedule(tp->tun_osih);
989
990 selnotify(&tp->tun_rsel, 0, 0);
991 }
992 mutex_exit(&tp->tun_lock);
993 }
994 #endif /* ALTQ */
995 /*
996 * tunpoll - the poll interface, this is only useful on reads
997 * really. The write detect always returns true, write never blocks
998 * anyway, it either accepts the packet or drops it.
999 */
1000 int
1001 tunpoll(dev_t dev, int events, struct lwp *l)
1002 {
1003 struct tun_softc *tp;
1004 struct ifnet *ifp;
1005 int s, revents = 0;
1006
1007 s = splnet();
1008 tp = tun_find_unit(dev);
1009
1010 /* interface was "destroyed" already */
1011 if (tp == NULL)
1012 goto out_nolock;
1013
1014 ifp = &tp->tun_if;
1015
1016 TUNDEBUG("%s: tunpoll\n", ifp->if_xname);
1017
1018 if (events & (POLLIN | POLLRDNORM)) {
1019 if (!IFQ_IS_EMPTY(&ifp->if_snd)) {
1020 TUNDEBUG("%s: tunpoll q=%d\n", ifp->if_xname,
1021 ifp->if_snd.ifq_len);
1022 revents |= events & (POLLIN | POLLRDNORM);
1023 } else {
1024 TUNDEBUG("%s: tunpoll waiting\n", ifp->if_xname);
1025 selrecord(l, &tp->tun_rsel);
1026 }
1027 }
1028
1029 if (events & (POLLOUT | POLLWRNORM))
1030 revents |= events & (POLLOUT | POLLWRNORM);
1031
1032 mutex_exit(&tp->tun_lock);
1033 out_nolock:
1034 splx(s);
1035 return (revents);
1036 }
1037
1038 static void
1039 filt_tunrdetach(struct knote *kn)
1040 {
1041 struct tun_softc *tp = kn->kn_hook;
1042 int s;
1043
1044 s = splnet();
1045 SLIST_REMOVE(&tp->tun_rsel.sel_klist, kn, knote, kn_selnext);
1046 splx(s);
1047 }
1048
1049 static int
1050 filt_tunread(struct knote *kn, long hint)
1051 {
1052 struct tun_softc *tp = kn->kn_hook;
1053 struct ifnet *ifp = &tp->tun_if;
1054 struct mbuf *m;
1055 int s;
1056
1057 s = splnet();
1058 IF_POLL(&ifp->if_snd, m);
1059 if (m == NULL) {
1060 splx(s);
1061 return (0);
1062 }
1063
1064 for (kn->kn_data = 0; m != NULL; m = m->m_next)
1065 kn->kn_data += m->m_len;
1066
1067 splx(s);
1068 return (1);
1069 }
1070
1071 static const struct filterops tunread_filtops =
1072 { 1, NULL, filt_tunrdetach, filt_tunread };
1073
1074 static const struct filterops tun_seltrue_filtops =
1075 { 1, NULL, filt_tunrdetach, filt_seltrue };
1076
1077 int
1078 tunkqfilter(dev_t dev, struct knote *kn)
1079 {
1080 struct tun_softc *tp;
1081 struct klist *klist;
1082 int rv = 0, s;
1083
1084 s = splnet();
1085 tp = tun_find_unit(dev);
1086 if (tp == NULL)
1087 goto out_nolock;
1088
1089 switch (kn->kn_filter) {
1090 case EVFILT_READ:
1091 klist = &tp->tun_rsel.sel_klist;
1092 kn->kn_fop = &tunread_filtops;
1093 break;
1094
1095 case EVFILT_WRITE:
1096 klist = &tp->tun_rsel.sel_klist;
1097 kn->kn_fop = &tun_seltrue_filtops;
1098 break;
1099
1100 default:
1101 rv = EINVAL;
1102 goto out;
1103 }
1104
1105 kn->kn_hook = tp;
1106
1107 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1108
1109 out:
1110 mutex_exit(&tp->tun_lock);
1111 out_nolock:
1112 splx(s);
1113 return (rv);
1114 }
1115