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