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