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