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