FreeBSD/Linux Kernel Cross Reference
sys/net/if_tun.c
1 /* $NetBSD: if_tun.c,v 1.14 1994/06/29 06:36:25 cgd 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 it's
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 * $FreeBSD: releng/6.2/sys/net/if_tun.c 161441 2006-08-18 14:05:17Z rwatson $
17 */
18
19 #include "opt_atalk.h"
20 #include "opt_inet.h"
21 #include "opt_inet6.h"
22 #include "opt_ipx.h"
23 #include "opt_mac.h"
24
25 #include <sys/param.h>
26 #include <sys/proc.h>
27 #include <sys/systm.h>
28 #include <sys/mac.h>
29 #include <sys/mbuf.h>
30 #include <sys/module.h>
31 #include <sys/socket.h>
32 #include <sys/fcntl.h>
33 #include <sys/filio.h>
34 #include <sys/sockio.h>
35 #include <sys/ttycom.h>
36 #include <sys/poll.h>
37 #include <sys/selinfo.h>
38 #include <sys/signalvar.h>
39 #include <sys/filedesc.h>
40 #include <sys/kernel.h>
41 #include <sys/sysctl.h>
42 #include <sys/conf.h>
43 #include <sys/uio.h>
44 #include <sys/malloc.h>
45 #include <sys/random.h>
46
47 #include <net/if.h>
48 #include <net/if_types.h>
49 #include <net/netisr.h>
50 #include <net/route.h>
51 #ifdef INET
52 #include <netinet/in.h>
53 #endif
54 #include <net/bpf.h>
55 #include <net/if_tun.h>
56
57 #include <sys/queue.h>
58
59 /*
60 * tun_list is protected by global tunmtx. Other mutable fields are
61 * protected by tun->tun_mtx, or by their owning subsystem. tun_dev is
62 * static for the duration of a tunnel interface.
63 */
64 struct tun_softc {
65 TAILQ_ENTRY(tun_softc) tun_list;
66 struct cdev *tun_dev;
67 u_short tun_flags; /* misc flags */
68 #define TUN_OPEN 0x0001
69 #define TUN_INITED 0x0002
70 #define TUN_RCOLL 0x0004
71 #define TUN_IASET 0x0008
72 #define TUN_DSTADDR 0x0010
73 #define TUN_LMODE 0x0020
74 #define TUN_RWAIT 0x0040
75 #define TUN_ASYNC 0x0080
76 #define TUN_IFHEAD 0x0100
77
78 #define TUN_READY (TUN_OPEN | TUN_INITED)
79
80 /*
81 * XXXRW: tun_pid is used to exclusively lock /dev/tun. Is this
82 * actually needed? Can we just return EBUSY if already open?
83 * Problem is that this involved inherent races when a tun device
84 * is handed off from one process to another, as opposed to just
85 * being slightly stale informationally.
86 */
87 pid_t tun_pid; /* owning pid */
88 struct ifnet *tun_ifp; /* the interface */
89 struct sigio *tun_sigio; /* information for async I/O */
90 struct selinfo tun_rsel; /* read select */
91 struct mtx tun_mtx; /* protect mutable softc fields */
92 };
93 #define TUN2IFP(sc) ((sc)->tun_ifp)
94
95 #define TUNDEBUG if (tundebug) if_printf
96 #define TUNNAME "tun"
97
98 /*
99 * All mutable global variables in if_tun are locked using tunmtx, with
100 * the exception of tundebug, which is used unlocked, and tunclones,
101 * which is static after setup.
102 */
103 static struct mtx tunmtx;
104 static MALLOC_DEFINE(M_TUN, TUNNAME, "Tunnel Interface");
105 static int tundebug = 0;
106 static struct clonedevs *tunclones;
107 static TAILQ_HEAD(,tun_softc) tunhead = TAILQ_HEAD_INITIALIZER(tunhead);
108 SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
109
110 static void tunclone(void *arg, struct ucred *cred, char *name,
111 int namelen, struct cdev **dev);
112 static void tuncreate(struct cdev *dev);
113 static int tunifioctl(struct ifnet *, u_long, caddr_t);
114 static int tuninit(struct ifnet *);
115 static int tunmodevent(module_t, int, void *);
116 static int tunoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
117 struct rtentry *rt);
118 static void tunstart(struct ifnet *);
119
120 static d_open_t tunopen;
121 static d_close_t tunclose;
122 static d_read_t tunread;
123 static d_write_t tunwrite;
124 static d_ioctl_t tunioctl;
125 static d_poll_t tunpoll;
126 static d_kqfilter_t tunkqfilter;
127
128 static int tunkqread(struct knote *, long);
129 static int tunkqwrite(struct knote *, long);
130 static void tunkqdetach(struct knote *);
131
132 static struct filterops tun_read_filterops = {
133 .f_isfd = 1,
134 .f_attach = NULL,
135 .f_detach = tunkqdetach,
136 .f_event = tunkqread,
137 };
138
139 static struct filterops tun_write_filterops = {
140 .f_isfd = 1,
141 .f_attach = NULL,
142 .f_detach = tunkqdetach,
143 .f_event = tunkqwrite,
144 };
145
146 static struct cdevsw tun_cdevsw = {
147 .d_version = D_VERSION,
148 .d_flags = D_PSEUDO | D_NEEDGIANT,
149 .d_open = tunopen,
150 .d_close = tunclose,
151 .d_read = tunread,
152 .d_write = tunwrite,
153 .d_ioctl = tunioctl,
154 .d_poll = tunpoll,
155 .d_kqfilter = tunkqfilter,
156 .d_name = TUNNAME,
157 };
158
159 static void
160 tunclone(void *arg, struct ucred *cred, char *name, int namelen,
161 struct cdev **dev)
162 {
163 int u, i;
164
165 if (*dev != NULL)
166 return;
167
168 if (strcmp(name, TUNNAME) == 0) {
169 u = -1;
170 } else if (dev_stdclone(name, NULL, TUNNAME, &u) != 1)
171 return; /* Don't recognise the name */
172 if (u != -1 && u > IF_MAXUNIT)
173 return; /* Unit number too high */
174
175 /* find any existing device, or allocate new unit number */
176 i = clone_create(&tunclones, &tun_cdevsw, &u, dev, 0);
177 if (i) {
178 /* No preexisting struct cdev *, create one */
179 *dev = make_dev(&tun_cdevsw, unit2minor(u),
180 UID_UUCP, GID_DIALER, 0600, "tun%d", u);
181 if (*dev != NULL) {
182 dev_ref(*dev);
183 (*dev)->si_flags |= SI_CHEAPCLONE;
184 }
185 }
186 }
187
188 static void
189 tun_destroy(struct tun_softc *tp)
190 {
191 struct cdev *dev;
192
193 /* Unlocked read. */
194 KASSERT((tp->tun_flags & TUN_OPEN) == 0,
195 ("tununits is out of sync - unit %d", TUN2IFP(tp)->if_dunit));
196
197 dev = tp->tun_dev;
198 bpfdetach(TUN2IFP(tp));
199 if_detach(TUN2IFP(tp));
200 if_free(TUN2IFP(tp));
201 destroy_dev(dev);
202 knlist_destroy(&tp->tun_rsel.si_note);
203 mtx_destroy(&tp->tun_mtx);
204 free(tp, M_TUN);
205 }
206
207 static int
208 tunmodevent(module_t mod, int type, void *data)
209 {
210 static eventhandler_tag tag;
211 struct tun_softc *tp;
212
213 switch (type) {
214 case MOD_LOAD:
215 mtx_init(&tunmtx, "tunmtx", NULL, MTX_DEF);
216 clone_setup(&tunclones);
217 tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000);
218 if (tag == NULL)
219 return (ENOMEM);
220 break;
221 case MOD_UNLOAD:
222 EVENTHANDLER_DEREGISTER(dev_clone, tag);
223
224 mtx_lock(&tunmtx);
225 while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
226 TAILQ_REMOVE(&tunhead, tp, tun_list);
227 mtx_unlock(&tunmtx);
228 tun_destroy(tp);
229 mtx_lock(&tunmtx);
230 }
231 mtx_unlock(&tunmtx);
232 clone_cleanup(&tunclones);
233 mtx_destroy(&tunmtx);
234 break;
235 default:
236 return EOPNOTSUPP;
237 }
238 return 0;
239 }
240
241 static moduledata_t tun_mod = {
242 "if_tun",
243 tunmodevent,
244 0
245 };
246
247 DECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
248
249 static void
250 tunstart(struct ifnet *ifp)
251 {
252 struct tun_softc *tp = ifp->if_softc;
253 struct mbuf *m;
254
255 TUNDEBUG(ifp,"%s starting\n", ifp->if_xname);
256 if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
257 IFQ_LOCK(&ifp->if_snd);
258 IFQ_POLL_NOLOCK(&ifp->if_snd, m);
259 if (m == NULL) {
260 IFQ_UNLOCK(&ifp->if_snd);
261 return;
262 }
263 IFQ_UNLOCK(&ifp->if_snd);
264 }
265
266 mtx_lock(&tp->tun_mtx);
267 if (tp->tun_flags & TUN_RWAIT) {
268 tp->tun_flags &= ~TUN_RWAIT;
269 wakeup(tp);
270 }
271 if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio) {
272 mtx_unlock(&tp->tun_mtx);
273 pgsigio(&tp->tun_sigio, SIGIO, 0);
274 } else
275 mtx_unlock(&tp->tun_mtx);
276 selwakeuppri(&tp->tun_rsel, PZERO + 1);
277 KNOTE_UNLOCKED(&tp->tun_rsel.si_note, 0);
278 }
279
280 /* XXX: should return an error code so it can fail. */
281 static void
282 tuncreate(struct cdev *dev)
283 {
284 struct tun_softc *sc;
285 struct ifnet *ifp;
286
287 dev->si_flags &= ~SI_CHEAPCLONE;
288
289 MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO);
290 mtx_init(&sc->tun_mtx, "tun_mtx", NULL, MTX_DEF);
291 sc->tun_flags = TUN_INITED;
292 sc->tun_dev = dev;
293 mtx_lock(&tunmtx);
294 TAILQ_INSERT_TAIL(&tunhead, sc, tun_list);
295 mtx_unlock(&tunmtx);
296
297 ifp = sc->tun_ifp = if_alloc(IFT_PPP);
298 if (ifp == NULL)
299 panic("%s%d: failed to if_alloc() interface.\n",
300 TUNNAME, dev2unit(dev));
301 if_initname(ifp, TUNNAME, dev2unit(dev));
302 ifp->if_mtu = TUNMTU;
303 ifp->if_ioctl = tunifioctl;
304 ifp->if_output = tunoutput;
305 ifp->if_start = tunstart;
306 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
307 ifp->if_softc = sc;
308 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen);
309 ifp->if_snd.ifq_drv_maxlen = 0;
310 IFQ_SET_READY(&ifp->if_snd);
311 knlist_init(&sc->tun_rsel.si_note, NULL, NULL, NULL, NULL);
312
313 if_attach(ifp);
314 bpfattach(ifp, DLT_NULL, sizeof(u_int32_t));
315 dev->si_drv1 = sc;
316 TUNDEBUG(ifp, "interface %s is created, minor = %#x\n",
317 ifp->if_xname, minor(dev));
318 }
319
320 static int
321 tunopen(struct cdev *dev, int flag, int mode, struct thread *td)
322 {
323 struct ifnet *ifp;
324 struct tun_softc *tp;
325
326 /*
327 * XXXRW: Non-atomic test and set of dev->si_drv1 requires
328 * synchronization.
329 */
330 tp = dev->si_drv1;
331 if (!tp) {
332 tuncreate(dev);
333 tp = dev->si_drv1;
334 }
335
336 /*
337 * XXXRW: This use of tun_pid is subject to error due to the
338 * fact that a reference to the tunnel can live beyond the
339 * death of the process that created it. Can we replace this
340 * with a simple busy flag?
341 */
342 mtx_lock(&tp->tun_mtx);
343 if (tp->tun_pid != 0 && tp->tun_pid != td->td_proc->p_pid) {
344 mtx_unlock(&tp->tun_mtx);
345 return (EBUSY);
346 }
347 tp->tun_pid = td->td_proc->p_pid;
348
349 tp->tun_flags |= TUN_OPEN;
350 mtx_unlock(&tp->tun_mtx);
351 ifp = TUN2IFP(tp);
352 TUNDEBUG(ifp, "open\n");
353
354 return (0);
355 }
356
357 /*
358 * tunclose - close the device - mark i/f down & delete
359 * routing info
360 */
361 static int
362 tunclose(struct cdev *dev, int foo, int bar, struct thread *td)
363 {
364 struct tun_softc *tp;
365 struct ifnet *ifp;
366 int s;
367
368 tp = dev->si_drv1;
369 ifp = TUN2IFP(tp);
370
371 mtx_lock(&tp->tun_mtx);
372 tp->tun_flags &= ~TUN_OPEN;
373 tp->tun_pid = 0;
374
375 /*
376 * junk all pending output
377 */
378 s = splimp();
379 IFQ_PURGE(&ifp->if_snd);
380 splx(s);
381 mtx_unlock(&tp->tun_mtx);
382
383 if (ifp->if_flags & IFF_UP) {
384 s = splimp();
385 if_down(ifp);
386 splx(s);
387 }
388
389 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
390 struct ifaddr *ifa;
391
392 s = splimp();
393 /* find internet addresses and delete routes */
394 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
395 if (ifa->ifa_addr->sa_family == AF_INET)
396 /* Unlocked read. */
397 rtinit(ifa, (int)RTM_DELETE,
398 tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
399 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
400 splx(s);
401 }
402
403 funsetown(&tp->tun_sigio);
404 selwakeuppri(&tp->tun_rsel, PZERO + 1);
405 KNOTE_UNLOCKED(&tp->tun_rsel.si_note, 0);
406 TUNDEBUG (ifp, "closed\n");
407 return (0);
408 }
409
410 static int
411 tuninit(struct ifnet *ifp)
412 {
413 struct tun_softc *tp = ifp->if_softc;
414 struct ifaddr *ifa;
415 int error = 0;
416
417 TUNDEBUG(ifp, "tuninit\n");
418
419 ifp->if_flags |= IFF_UP;
420 ifp->if_drv_flags |= IFF_DRV_RUNNING;
421 getmicrotime(&ifp->if_lastchange);
422
423 for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa;
424 ifa = TAILQ_NEXT(ifa, ifa_link)) {
425 if (ifa->ifa_addr == NULL)
426 error = EFAULT;
427 /* XXX: Should maybe return straight off? */
428 else {
429 #ifdef INET
430 if (ifa->ifa_addr->sa_family == AF_INET) {
431 struct sockaddr_in *si;
432
433 si = (struct sockaddr_in *)ifa->ifa_addr;
434 mtx_lock(&tp->tun_mtx);
435 if (si->sin_addr.s_addr)
436 tp->tun_flags |= TUN_IASET;
437
438 si = (struct sockaddr_in *)ifa->ifa_dstaddr;
439 if (si && si->sin_addr.s_addr)
440 tp->tun_flags |= TUN_DSTADDR;
441 mtx_unlock(&tp->tun_mtx);
442 }
443 #endif
444 }
445 }
446 return (error);
447 }
448
449 /*
450 * Process an ioctl request.
451 */
452 static int
453 tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
454 {
455 struct ifreq *ifr = (struct ifreq *)data;
456 struct tun_softc *tp = ifp->if_softc;
457 struct ifstat *ifs;
458 int error = 0, s;
459
460 s = splimp();
461 switch(cmd) {
462 case SIOCGIFSTATUS:
463 ifs = (struct ifstat *)data;
464 mtx_lock(&tp->tun_mtx);
465 if (tp->tun_pid)
466 sprintf(ifs->ascii + strlen(ifs->ascii),
467 "\tOpened by PID %d\n", tp->tun_pid);
468 mtx_unlock(&tp->tun_mtx);
469 break;
470 case SIOCSIFADDR:
471 error = tuninit(ifp);
472 TUNDEBUG(ifp, "address set, error=%d\n", error);
473 break;
474 case SIOCSIFDSTADDR:
475 error = tuninit(ifp);
476 TUNDEBUG(ifp, "destination address set, error=%d\n", error);
477 break;
478 case SIOCSIFMTU:
479 ifp->if_mtu = ifr->ifr_mtu;
480 TUNDEBUG(ifp, "mtu set\n");
481 break;
482 case SIOCSIFFLAGS:
483 case SIOCADDMULTI:
484 case SIOCDELMULTI:
485 break;
486 default:
487 error = EINVAL;
488 }
489 splx(s);
490 return (error);
491 }
492
493 /*
494 * tunoutput - queue packets from higher level ready to put out.
495 */
496 static int
497 tunoutput(
498 struct ifnet *ifp,
499 struct mbuf *m0,
500 struct sockaddr *dst,
501 struct rtentry *rt)
502 {
503 struct tun_softc *tp = ifp->if_softc;
504 u_short cached_tun_flags;
505 int error;
506 u_int32_t af;
507
508 TUNDEBUG (ifp, "tunoutput\n");
509
510 #ifdef MAC
511 error = mac_check_ifnet_transmit(ifp, m0);
512 if (error) {
513 m_freem(m0);
514 return (error);
515 }
516 #endif
517
518 /* Could be unlocked read? */
519 mtx_lock(&tp->tun_mtx);
520 cached_tun_flags = tp->tun_flags;
521 mtx_unlock(&tp->tun_mtx);
522 if ((cached_tun_flags & TUN_READY) != TUN_READY) {
523 TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
524 m_freem (m0);
525 return (EHOSTDOWN);
526 }
527
528 if ((ifp->if_flags & IFF_UP) != IFF_UP) {
529 m_freem (m0);
530 return (EHOSTDOWN);
531 }
532
533 /* BPF writes need to be handled specially. */
534 if (dst->sa_family == AF_UNSPEC) {
535 bcopy(dst->sa_data, &af, sizeof(af));
536 dst->sa_family = af;
537 }
538
539 if (ifp->if_bpf) {
540 af = dst->sa_family;
541 bpf_mtap2(ifp->if_bpf, &af, sizeof(af), m0);
542 }
543
544 /* prepend sockaddr? this may abort if the mbuf allocation fails */
545 if (cached_tun_flags & TUN_LMODE) {
546 /* allocate space for sockaddr */
547 M_PREPEND(m0, dst->sa_len, M_DONTWAIT);
548
549 /* if allocation failed drop packet */
550 if (m0 == NULL) {
551 ifp->if_iqdrops++;
552 ifp->if_oerrors++;
553 return (ENOBUFS);
554 } else {
555 bcopy(dst, m0->m_data, dst->sa_len);
556 }
557 }
558
559 if (cached_tun_flags & TUN_IFHEAD) {
560 /* Prepend the address family */
561 M_PREPEND(m0, 4, M_DONTWAIT);
562
563 /* if allocation failed drop packet */
564 if (m0 == NULL) {
565 ifp->if_iqdrops++;
566 ifp->if_oerrors++;
567 return (ENOBUFS);
568 } else
569 *(u_int32_t *)m0->m_data = htonl(dst->sa_family);
570 } else {
571 #ifdef INET
572 if (dst->sa_family != AF_INET)
573 #endif
574 {
575 m_freem(m0);
576 return (EAFNOSUPPORT);
577 }
578 }
579
580 IFQ_HANDOFF(ifp, m0, error);
581 if (error) {
582 ifp->if_collisions++;
583 return (ENOBUFS);
584 }
585 ifp->if_opackets++;
586 return (0);
587 }
588
589 /*
590 * the cdevsw interface is now pretty minimal.
591 */
592 static int
593 tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
594 {
595 int s;
596 int error;
597 struct tun_softc *tp = dev->si_drv1;
598 struct tuninfo *tunp;
599
600 switch (cmd) {
601 case TUNSIFINFO:
602 tunp = (struct tuninfo *)data;
603 if (tunp->mtu < IF_MINMTU)
604 return (EINVAL);
605 if (TUN2IFP(tp)->if_mtu != tunp->mtu
606 && (error = suser(td)) != 0)
607 return (error);
608 TUN2IFP(tp)->if_mtu = tunp->mtu;
609 TUN2IFP(tp)->if_type = tunp->type;
610 TUN2IFP(tp)->if_baudrate = tunp->baudrate;
611 break;
612 case TUNGIFINFO:
613 tunp = (struct tuninfo *)data;
614 tunp->mtu = TUN2IFP(tp)->if_mtu;
615 tunp->type = TUN2IFP(tp)->if_type;
616 tunp->baudrate = TUN2IFP(tp)->if_baudrate;
617 break;
618 case TUNSDEBUG:
619 tundebug = *(int *)data;
620 break;
621 case TUNGDEBUG:
622 *(int *)data = tundebug;
623 break;
624 case TUNSLMODE:
625 mtx_lock(&tp->tun_mtx);
626 if (*(int *)data) {
627 tp->tun_flags |= TUN_LMODE;
628 tp->tun_flags &= ~TUN_IFHEAD;
629 } else
630 tp->tun_flags &= ~TUN_LMODE;
631 mtx_unlock(&tp->tun_mtx);
632 break;
633 case TUNSIFHEAD:
634 mtx_lock(&tp->tun_mtx);
635 if (*(int *)data) {
636 tp->tun_flags |= TUN_IFHEAD;
637 tp->tun_flags &= ~TUN_LMODE;
638 } else
639 tp->tun_flags &= ~TUN_IFHEAD;
640 mtx_unlock(&tp->tun_mtx);
641 break;
642 case TUNGIFHEAD:
643 /* Could be unlocked read? */
644 mtx_lock(&tp->tun_mtx);
645 *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
646 mtx_unlock(&tp->tun_mtx);
647 break;
648 case TUNSIFMODE:
649 /* deny this if UP */
650 if (TUN2IFP(tp)->if_flags & IFF_UP)
651 return(EBUSY);
652
653 switch (*(int *)data & ~IFF_MULTICAST) {
654 case IFF_POINTOPOINT:
655 case IFF_BROADCAST:
656 TUN2IFP(tp)->if_flags &=
657 ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
658 TUN2IFP(tp)->if_flags |= *(int *)data;
659 break;
660 default:
661 return(EINVAL);
662 }
663 break;
664 case TUNSIFPID:
665 mtx_lock(&tp->tun_mtx);
666 tp->tun_pid = curthread->td_proc->p_pid;
667 mtx_unlock(&tp->tun_mtx);
668 break;
669 case FIONBIO:
670 break;
671 case FIOASYNC:
672 mtx_lock(&tp->tun_mtx);
673 if (*(int *)data)
674 tp->tun_flags |= TUN_ASYNC;
675 else
676 tp->tun_flags &= ~TUN_ASYNC;
677 mtx_unlock(&tp->tun_mtx);
678 break;
679 case FIONREAD:
680 s = splimp();
681 if (!IFQ_IS_EMPTY(&TUN2IFP(tp)->if_snd)) {
682 struct mbuf *mb;
683 IFQ_LOCK(&TUN2IFP(tp)->if_snd);
684 IFQ_POLL_NOLOCK(&TUN2IFP(tp)->if_snd, mb);
685 for( *(int *)data = 0; mb != 0; mb = mb->m_next)
686 *(int *)data += mb->m_len;
687 IFQ_UNLOCK(&TUN2IFP(tp)->if_snd);
688 } else
689 *(int *)data = 0;
690 splx(s);
691 break;
692 case FIOSETOWN:
693 return (fsetown(*(int *)data, &tp->tun_sigio));
694
695 case FIOGETOWN:
696 *(int *)data = fgetown(&tp->tun_sigio);
697 return (0);
698
699 /* This is deprecated, FIOSETOWN should be used instead. */
700 case TIOCSPGRP:
701 return (fsetown(-(*(int *)data), &tp->tun_sigio));
702
703 /* This is deprecated, FIOGETOWN should be used instead. */
704 case TIOCGPGRP:
705 *(int *)data = -fgetown(&tp->tun_sigio);
706 return (0);
707
708 default:
709 return (ENOTTY);
710 }
711 return (0);
712 }
713
714 /*
715 * The cdevsw read interface - reads a packet at a time, or at
716 * least as much of a packet as can be read.
717 */
718 static int
719 tunread(struct cdev *dev, struct uio *uio, int flag)
720 {
721 struct tun_softc *tp = dev->si_drv1;
722 struct ifnet *ifp = TUN2IFP(tp);
723 struct mbuf *m;
724 int error=0, len, s;
725
726 TUNDEBUG (ifp, "read\n");
727 mtx_lock(&tp->tun_mtx);
728 if ((tp->tun_flags & TUN_READY) != TUN_READY) {
729 mtx_unlock(&tp->tun_mtx);
730 TUNDEBUG (ifp, "not ready 0%o\n", tp->tun_flags);
731 return (EHOSTDOWN);
732 }
733
734 tp->tun_flags &= ~TUN_RWAIT;
735 mtx_unlock(&tp->tun_mtx);
736
737 s = splimp();
738 do {
739 IFQ_DEQUEUE(&ifp->if_snd, m);
740 if (m == NULL) {
741 if (flag & O_NONBLOCK) {
742 splx(s);
743 return (EWOULDBLOCK);
744 }
745 mtx_lock(&tp->tun_mtx);
746 tp->tun_flags |= TUN_RWAIT;
747 mtx_unlock(&tp->tun_mtx);
748 if ((error = tsleep(tp, PCATCH | (PZERO + 1),
749 "tunread", 0)) != 0) {
750 splx(s);
751 return (error);
752 }
753 }
754 } while (m == NULL);
755 splx(s);
756
757 while (m && uio->uio_resid > 0 && error == 0) {
758 len = min(uio->uio_resid, m->m_len);
759 if (len != 0)
760 error = uiomove(mtod(m, void *), len, uio);
761 m = m_free(m);
762 }
763
764 if (m) {
765 TUNDEBUG(ifp, "Dropping mbuf\n");
766 m_freem(m);
767 }
768 return (error);
769 }
770
771 /*
772 * the cdevsw write interface - an atomic write is a packet - or else!
773 */
774 static int
775 tunwrite(struct cdev *dev, struct uio *uio, int flag)
776 {
777 struct tun_softc *tp = dev->si_drv1;
778 struct ifnet *ifp = TUN2IFP(tp);
779 struct mbuf *m;
780 int error = 0;
781 uint32_t family;
782 int isr;
783
784 TUNDEBUG(ifp, "tunwrite\n");
785
786 if ((ifp->if_flags & IFF_UP) != IFF_UP)
787 /* ignore silently */
788 return (0);
789
790 if (uio->uio_resid == 0)
791 return (0);
792
793 if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) {
794 TUNDEBUG(ifp, "len=%d!\n", uio->uio_resid);
795 return (EIO);
796 }
797
798 if ((m = m_uiotombuf(uio, M_DONTWAIT, 0, 0)) == NULL) {
799 ifp->if_ierrors++;
800 return (error);
801 }
802
803 m->m_pkthdr.rcvif = ifp;
804 #ifdef MAC
805 mac_create_mbuf_from_ifnet(ifp, m);
806 #endif
807
808 /* Could be unlocked read? */
809 mtx_lock(&tp->tun_mtx);
810 if (tp->tun_flags & TUN_IFHEAD) {
811 mtx_unlock(&tp->tun_mtx);
812 if (m->m_len < sizeof(family) &&
813 (m = m_pullup(m, sizeof(family))) == NULL)
814 return (ENOBUFS);
815 family = ntohl(*mtod(m, u_int32_t *));
816 m_adj(m, sizeof(family));
817 } else {
818 mtx_unlock(&tp->tun_mtx);
819 family = AF_INET;
820 }
821
822 BPF_MTAP2(ifp, &family, sizeof(family), m);
823
824 switch (family) {
825 #ifdef INET
826 case AF_INET:
827 isr = NETISR_IP;
828 break;
829 #endif
830 #ifdef INET6
831 case AF_INET6:
832 isr = NETISR_IPV6;
833 break;
834 #endif
835 #ifdef IPX
836 case AF_IPX:
837 isr = NETISR_IPX;
838 break;
839 #endif
840 #ifdef NETATALK
841 case AF_APPLETALK:
842 isr = NETISR_ATALK2;
843 break;
844 #endif
845 default:
846 m_freem(m);
847 return (EAFNOSUPPORT);
848 }
849 /* First chunk of an mbuf contains good junk */
850 if (harvest.point_to_point)
851 random_harvest(m, 16, 3, 0, RANDOM_NET);
852 ifp->if_ibytes += m->m_pkthdr.len;
853 ifp->if_ipackets++;
854 netisr_dispatch(isr, m);
855 return (0);
856 }
857
858 /*
859 * tunpoll - the poll interface, this is only useful on reads
860 * really. The write detect always returns true, write never blocks
861 * anyway, it either accepts the packet or drops it.
862 */
863 static int
864 tunpoll(struct cdev *dev, int events, struct thread *td)
865 {
866 int s;
867 struct tun_softc *tp = dev->si_drv1;
868 struct ifnet *ifp = TUN2IFP(tp);
869 int revents = 0;
870 struct mbuf *m;
871
872 s = splimp();
873 TUNDEBUG(ifp, "tunpoll\n");
874
875 if (events & (POLLIN | POLLRDNORM)) {
876 IFQ_LOCK(&ifp->if_snd);
877 IFQ_POLL_NOLOCK(&ifp->if_snd, m);
878 if (m != NULL) {
879 TUNDEBUG(ifp, "tunpoll q=%d\n", ifp->if_snd.ifq_len);
880 revents |= events & (POLLIN | POLLRDNORM);
881 } else {
882 TUNDEBUG(ifp, "tunpoll waiting\n");
883 selrecord(td, &tp->tun_rsel);
884 }
885 IFQ_UNLOCK(&ifp->if_snd);
886 }
887 if (events & (POLLOUT | POLLWRNORM))
888 revents |= events & (POLLOUT | POLLWRNORM);
889
890 splx(s);
891 return (revents);
892 }
893
894 /*
895 * tunkqfilter - support for the kevent() system call.
896 */
897 static int
898 tunkqfilter(struct cdev *dev, struct knote *kn)
899 {
900 int s;
901 struct tun_softc *tp = dev->si_drv1;
902 struct ifnet *ifp = TUN2IFP(tp);
903
904 s = splimp();
905 switch(kn->kn_filter) {
906 case EVFILT_READ:
907 TUNDEBUG(ifp, "%s kqfilter: EVFILT_READ, minor = %#x\n",
908 ifp->if_xname, minor(dev));
909 kn->kn_fop = &tun_read_filterops;
910 break;
911
912 case EVFILT_WRITE:
913 TUNDEBUG(ifp, "%s kqfilter: EVFILT_WRITE, minor = %#x\n",
914 ifp->if_xname, minor(dev));
915 kn->kn_fop = &tun_write_filterops;
916 break;
917
918 default:
919 TUNDEBUG(ifp, "%s kqfilter: invalid filter, minor = %#x\n",
920 ifp->if_xname, minor(dev));
921 splx(s);
922 return(EINVAL);
923 }
924 splx(s);
925
926 kn->kn_hook = (caddr_t) dev;
927 knlist_add(&tp->tun_rsel.si_note, kn, 0);
928
929 return (0);
930 }
931
932 /*
933 * Return true of there is data in the interface queue.
934 */
935 static int
936 tunkqread(struct knote *kn, long hint)
937 {
938 int ret, s;
939 struct cdev *dev = (struct cdev *)(kn->kn_hook);
940 struct tun_softc *tp = dev->si_drv1;
941 struct ifnet *ifp = TUN2IFP(tp);
942
943 s = splimp();
944 if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) {
945 TUNDEBUG(ifp,
946 "%s have data in the queue. Len = %d, minor = %#x\n",
947 ifp->if_xname, ifp->if_snd.ifq_len, minor(dev));
948 ret = 1;
949 } else {
950 TUNDEBUG(ifp,
951 "%s waiting for data, minor = %#x\n", ifp->if_xname,
952 minor(dev));
953 ret = 0;
954 }
955 splx(s);
956
957 return (ret);
958 }
959
960 /*
961 * Always can write, always return MTU in kn->data.
962 */
963 static int
964 tunkqwrite(struct knote *kn, long hint)
965 {
966 int s;
967 struct tun_softc *tp = ((struct cdev *)kn->kn_hook)->si_drv1;
968 struct ifnet *ifp = TUN2IFP(tp);
969
970 s = splimp();
971 kn->kn_data = ifp->if_mtu;
972 splx(s);
973
974 return (1);
975 }
976
977 static void
978 tunkqdetach(struct knote *kn)
979 {
980 struct tun_softc *tp = ((struct cdev *)kn->kn_hook)->si_drv1;
981
982 knlist_remove(&tp->tun_rsel.si_note, kn, 0);
983 }
Cache object: a9aaeb5fa88ea3f2e0e49cde3311a187
|