]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/if_tun.c
Modify the cache handling code to assume 2 virtual colours, which is much
[FreeBSD/FreeBSD.git] / 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$
17  */
18
19 #include "opt_inet.h"
20 #include "opt_mac.h"
21
22 #include <sys/param.h>
23 #include <sys/proc.h>
24 #include <sys/systm.h>
25 #include <sys/mac.h>
26 #include <sys/mbuf.h>
27 #include <sys/module.h>
28 #include <sys/socket.h>
29 #include <sys/filio.h>
30 #include <sys/sockio.h>
31 #include <sys/ttycom.h>
32 #include <sys/poll.h>
33 #include <sys/signalvar.h>
34 #include <sys/filedesc.h>
35 #include <sys/kernel.h>
36 #include <sys/sysctl.h>
37 #include <sys/conf.h>
38 #include <sys/uio.h>
39 #include <sys/vnode.h>
40 #include <sys/malloc.h>
41 #include <machine/bus.h>        /* XXX Shouldn't really be required ! */
42 #include <sys/rman.h>
43
44 #include <net/if.h>
45 #include <net/if_types.h>
46 #include <net/route.h>
47 #include <net/intrq.h>
48 #ifdef INET
49 #include <netinet/in.h>
50 #endif
51 #include <net/bpf.h>
52 #include <net/if_tunvar.h>
53 #include <net/if_tun.h>
54
55 #define TUNDEBUG        if (tundebug) printf
56 #define TUNNAME         "tun"
57 #define TUN_MAXUNIT     0x7fff  /* ifp->if_unit is only 15 bits */
58
59 static MALLOC_DEFINE(M_TUN, TUNNAME, "Tunnel Interface");
60 static int tundebug = 0;
61 static struct tun_softc *tunhead = NULL;
62 static struct rman tununits[1];
63 static udev_t tunbasedev = NOUDEV;
64 SYSCTL_INT(_debug, OID_AUTO, if_tun_debug, CTLFLAG_RW, &tundebug, 0, "");
65
66 static void     tunclone(void *arg, char *name, int namelen, dev_t *dev);
67 static void     tuncreate(dev_t dev);
68 static int      tunifioctl(struct ifnet *, u_long, caddr_t);
69 static int      tuninit(struct ifnet *);
70 static int      tunmodevent(module_t, int, void *);
71 static int      tunoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
72                     struct rtentry *rt);
73 static void     tunstart(struct ifnet *);
74
75 static d_open_t         tunopen;
76 static d_close_t        tunclose;
77 static d_read_t         tunread;
78 static d_write_t        tunwrite;
79 static d_ioctl_t        tunioctl;
80 static d_poll_t         tunpoll;
81
82 #define CDEV_MAJOR 52
83 static struct cdevsw tun_cdevsw = {
84         /* open */      tunopen,
85         /* close */     tunclose,
86         /* read */      tunread,
87         /* write */     tunwrite,
88         /* ioctl */     tunioctl,
89         /* poll */      tunpoll,
90         /* mmap */      nommap,
91         /* strategy */  nostrategy,
92         /* name */      TUNNAME,
93         /* maj */       CDEV_MAJOR,
94         /* dump */      nodump,
95         /* psize */     nopsize,
96         /* flags */     0,
97 };
98
99 static void
100 tunclone(void *arg, char *name, int namelen, dev_t *dev)
101 {
102         struct resource *r;
103         int err;
104         int u;
105
106         if (*dev != NODEV)
107                 return;
108
109         if (strcmp(name, TUNNAME) == 0) {
110                 r = rman_reserve_resource(tununits, 0, TUN_MAXUNIT, 1,
111                     RF_ALLOCATED | RF_ACTIVE, NULL);
112                 u = rman_get_start(r);
113                 err = rman_release_resource(r);
114                 KASSERT(err == 0, ("Unexpected failure releasing resource"));
115                 *dev = makedev(CDEV_MAJOR, unit2minor(u));
116                 if ((*dev)->si_flags & SI_NAMED)
117                         return; /* Already make_dev()d */
118         } else if (dev_stdclone(name, NULL, TUNNAME, &u) != 1)
119                 return; /* Don't recognise the name */
120
121         *dev = make_dev(&tun_cdevsw, unit2minor(u),
122             UID_ROOT, GID_WHEEL, 0600, "tun%d", u);
123
124         /*
125          * All devices depend on tunbasedev so that we can simply
126          * destroy_dev() this device at module unload time to get
127          * rid of all our make_dev()d resources.
128          */
129         if (tunbasedev == NOUDEV)
130                 tunbasedev = (*dev)->si_udev;
131         else {
132                 (*dev)->si_flags |= SI_CHEAPCLONE;
133                 dev_depends(udev2dev(tunbasedev, 0), *dev);
134         }
135 }
136
137 static int
138 tunmodevent(module_t mod, int type, void *data) 
139 {
140         static eventhandler_tag tag;
141         struct tun_softc *tp;
142         dev_t dev;
143         int err;
144
145         switch (type) { 
146         case MOD_LOAD: 
147                 tag = EVENTHANDLER_REGISTER(dev_clone, tunclone, 0, 1000);
148                 if (tag == NULL)
149                         return (ENOMEM);
150                 if (!devfs_present) {
151                         err = cdevsw_add(&tun_cdevsw);
152                         if (err != 0) {
153                                 EVENTHANDLER_DEREGISTER(dev_clone, tag);
154                                 return (err);
155                         }
156                 }
157                 tununits->rm_type = RMAN_ARRAY;
158                 tununits->rm_descr = "open if_tun units";
159                 err = rman_init(tununits);
160                 if (err != 0) {
161                         cdevsw_remove(&tun_cdevsw);
162                         EVENTHANDLER_DEREGISTER(dev_clone, tag);
163                         return (err);
164                 }
165                 err = rman_manage_region(tununits, 0, TUN_MAXUNIT);
166                 if (err != 0) {
167                         printf("%s: tununits: rman_manage_region: Failed %d\n",
168                             TUNNAME, err);
169                         rman_fini(tununits);
170                         cdevsw_remove(&tun_cdevsw);
171                         EVENTHANDLER_DEREGISTER(dev_clone, tag);
172                         return (err);
173                 }
174                 break; 
175         case MOD_UNLOAD: 
176                 err = rman_fini(tununits);
177                 if (err != 0)
178                         return (err);
179                 EVENTHANDLER_DEREGISTER(dev_clone, tag);
180
181                 while (tunhead != NULL) {
182                         KASSERT((tunhead->tun_flags & TUN_OPEN) == 0,
183                             ("tununits is out of sync - unit %d",
184                             tunhead->tun_if.if_unit));
185                         tp = tunhead;
186                         dev = makedev(tun_cdevsw.d_maj,
187                             unit2minor(tp->tun_if.if_unit));
188                         KASSERT(dev->si_drv1 == tp, ("Bad makedev result"));
189                         tunhead = tp->next;
190                         bpfdetach(&tp->tun_if);
191                         if_detach(&tp->tun_if);
192                         KASSERT(dev->si_flags & SI_NAMED, ("Missing make_dev"));
193                         free(tp, M_TUN);
194                 }
195
196                 /*
197                  * Destroying tunbasedev results in all of our make_dev()s
198                  * conveniently going away.
199                  */
200                 if (tunbasedev != NOUDEV)
201                         destroy_dev(udev2dev(tunbasedev, 0));
202
203                 if (!devfs_present)
204                         cdevsw_remove(&tun_cdevsw);
205                 break;
206         } 
207         return 0; 
208
209
210 static moduledata_t tun_mod = { 
211         "if_tun", 
212         tunmodevent, 
213         0
214 }; 
215
216 DECLARE_MODULE(if_tun, tun_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
217
218 static void
219 tunstart(struct ifnet *ifp)
220 {
221         struct tun_softc *tp = ifp->if_softc;
222
223         if (tp->tun_flags & TUN_RWAIT) {
224                 tp->tun_flags &= ~TUN_RWAIT;
225                 wakeup((caddr_t)tp);
226         }
227         if (tp->tun_flags & TUN_ASYNC && tp->tun_sigio)
228                 pgsigio(&tp->tun_sigio, SIGIO, 0);
229         selwakeup(&tp->tun_rsel);
230 }
231
232 static void
233 tuncreate(dev_t dev)
234 {
235         struct tun_softc *sc;
236         struct ifnet *ifp;
237
238         if (!(dev->si_flags & SI_NAMED))
239                 dev = make_dev(&tun_cdevsw, minor(dev),
240                     UID_UUCP, GID_DIALER, 0600, "tun%d", dev2unit(dev));
241
242         MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO);
243         sc->tun_flags = TUN_INITED;
244         sc->next = tunhead;
245         tunhead = sc;
246
247         ifp = &sc->tun_if;
248         ifp->if_unit = dev2unit(dev);
249         ifp->if_name = TUNNAME;
250         ifp->if_mtu = TUNMTU;
251         ifp->if_ioctl = tunifioctl;
252         ifp->if_output = tunoutput;
253         ifp->if_start = tunstart;
254         ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
255         ifp->if_type = IFT_PPP;
256         ifp->if_snd.ifq_maxlen = ifqmaxlen;
257         ifp->if_softc = sc;
258         if_attach(ifp);
259         bpfattach(ifp, DLT_NULL, sizeof(u_int));
260         dev->si_drv1 = sc;
261 }
262
263 static int
264 tunopen(dev_t dev, int flag, int mode, struct thread *td)
265 {
266         struct resource *r;
267         struct ifnet    *ifp;
268         struct tun_softc *tp;
269         int unit;
270
271         unit = dev2unit(dev);
272         if (unit > TUN_MAXUNIT)
273                 return (ENXIO);
274
275         r = rman_reserve_resource(tununits, unit, unit, 1,
276             RF_ALLOCATED | RF_ACTIVE, NULL);
277         if (r == NULL)
278                 return (EBUSY);
279
280         dev->si_flags &= ~SI_CHEAPCLONE;
281
282         tp = dev->si_drv1;
283         if (!tp) {
284                 tuncreate(dev);
285                 tp = dev->si_drv1;
286         }
287         KASSERT(!(tp->tun_flags & TUN_OPEN), ("Resource & flags out-of-sync"));
288         tp->r_unit = r;
289         tp->tun_pid = td->td_proc->p_pid;
290         ifp = &tp->tun_if;
291         tp->tun_flags |= TUN_OPEN;
292         TUNDEBUG("%s%d: open\n", ifp->if_name, ifp->if_unit);
293
294         return (0);
295 }
296
297 /*
298  * tunclose - close the device - mark i/f down & delete
299  * routing info
300  */
301 static  int
302 tunclose(dev_t dev, int foo, int bar, struct thread *td)
303 {
304         struct tun_softc *tp;
305         struct ifnet *ifp;
306         int s;
307         int err;
308
309         tp = dev->si_drv1;
310         ifp = &tp->tun_if;
311
312         KASSERT(tp->r_unit, ("Unit %d not marked open", ifp->if_unit));
313         tp->tun_flags &= ~TUN_OPEN;
314         tp->tun_pid = 0;
315
316         /*
317          * junk all pending output
318          */
319         IF_DRAIN(&ifp->if_snd);
320
321         if (ifp->if_flags & IFF_UP) {
322                 s = splimp();
323                 if_down(ifp);
324                 splx(s);
325         }
326
327         if (ifp->if_flags & IFF_RUNNING) {
328                 register struct ifaddr *ifa;
329
330                 s = splimp();
331                 /* find internet addresses and delete routes */
332                 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link)
333                         if (ifa->ifa_addr->sa_family == AF_INET)
334                                 rtinit(ifa, (int)RTM_DELETE,
335                                     tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0);
336                 ifp->if_flags &= ~IFF_RUNNING;
337                 splx(s);
338         }
339
340         funsetown(&tp->tun_sigio);
341         selwakeup(&tp->tun_rsel);
342
343         TUNDEBUG ("%s%d: closed\n", ifp->if_name, ifp->if_unit);
344         err = rman_release_resource(tp->r_unit);
345         KASSERT(err == 0, ("Unit %d failed to release", ifp->if_unit));
346
347         return (0);
348 }
349
350 static int
351 tuninit(struct ifnet *ifp)
352 {
353         struct tun_softc *tp = ifp->if_softc;
354         register struct ifaddr *ifa;
355         int error = 0;
356
357         TUNDEBUG("%s%d: tuninit\n", ifp->if_name, ifp->if_unit);
358
359         ifp->if_flags |= IFF_UP | IFF_RUNNING;
360         getmicrotime(&ifp->if_lastchange);
361
362         for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; 
363              ifa = TAILQ_NEXT(ifa, ifa_link)) {
364                 if (ifa->ifa_addr == NULL)
365                         error = EFAULT;
366                         /* XXX: Should maybe return straight off? */
367                 else {
368 #ifdef INET
369                         if (ifa->ifa_addr->sa_family == AF_INET) {
370                             struct sockaddr_in *si;
371
372                             si = (struct sockaddr_in *)ifa->ifa_addr;
373                             if (si->sin_addr.s_addr)
374                                     tp->tun_flags |= TUN_IASET;
375
376                             si = (struct sockaddr_in *)ifa->ifa_dstaddr;
377                             if (si && si->sin_addr.s_addr)
378                                     tp->tun_flags |= TUN_DSTADDR;
379                         }
380 #endif
381                 }
382         }
383         return (error);
384 }
385
386 /*
387  * Process an ioctl request.
388  */
389 int
390 tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
391 {
392         struct ifreq *ifr = (struct ifreq *)data;
393         struct tun_softc *tp = ifp->if_softc;
394         struct ifstat *ifs;
395         int             error = 0, s;
396
397         s = splimp();
398         switch(cmd) {
399         case SIOCGIFSTATUS:
400                 ifs = (struct ifstat *)data;
401                 if (tp->tun_pid)
402                         sprintf(ifs->ascii + strlen(ifs->ascii),
403                             "\tOpened by PID %d\n", tp->tun_pid);
404                 break;
405         case SIOCSIFADDR:
406                 error = tuninit(ifp);
407                 TUNDEBUG("%s%d: address set, error=%d\n",
408                          ifp->if_name, ifp->if_unit, error);
409                 break;
410         case SIOCSIFDSTADDR:
411                 error = tuninit(ifp);
412                 TUNDEBUG("%s%d: destination address set, error=%d\n",
413                          ifp->if_name, ifp->if_unit, error);
414                 break;
415         case SIOCSIFMTU:
416                 ifp->if_mtu = ifr->ifr_mtu;
417                 TUNDEBUG("%s%d: mtu set\n", ifp->if_name, ifp->if_unit);
418                 break;
419         case SIOCSIFFLAGS:
420         case SIOCADDMULTI:
421         case SIOCDELMULTI:
422                 break;
423         default:
424                 error = EINVAL;
425         }
426         splx(s);
427         return (error);
428 }
429
430 /*
431  * tunoutput - queue packets from higher level ready to put out.
432  */
433 int
434 tunoutput(
435         struct ifnet *ifp,
436         struct mbuf *m0,
437         struct sockaddr *dst,
438         struct rtentry *rt)
439 {
440         struct tun_softc *tp = ifp->if_softc;
441 #ifdef MAC
442         int error;
443 #endif
444
445         TUNDEBUG ("%s%d: tunoutput\n", ifp->if_name, ifp->if_unit);
446
447 #ifdef MAC
448         error = mac_check_ifnet_transmit(ifp, m0);
449         if (error) {
450                 m_freem(m0);
451                 return (error);
452         }
453 #endif
454
455         if ((tp->tun_flags & TUN_READY) != TUN_READY) {
456                 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
457                           ifp->if_unit, tp->tun_flags);
458                 m_freem (m0);
459                 return (EHOSTDOWN);
460         }
461
462         /* BPF write needs to be handled specially */
463         if (dst->sa_family == AF_UNSPEC) {
464                 dst->sa_family = *(mtod(m0, int *));
465                 m0->m_len -= sizeof(int);
466                 m0->m_pkthdr.len -= sizeof(int);
467                 m0->m_data += sizeof(int);
468         }
469
470         if (ifp->if_bpf) {
471                 /*
472                  * We need to prepend the address family as
473                  * a four byte field.  Cons up a dummy header
474                  * to pacify bpf.  This is safe because bpf
475                  * will only read from the mbuf (i.e., it won't
476                  * try to free it or keep a pointer to it).
477                  */
478                 struct mbuf m;
479                 uint32_t af = dst->sa_family;
480
481                 m.m_next = m0;
482                 m.m_len = 4;
483                 m.m_data = (char *)&af;
484
485                 bpf_mtap(ifp, &m);
486         }
487
488         /* prepend sockaddr? this may abort if the mbuf allocation fails */
489         if (tp->tun_flags & TUN_LMODE) {
490                 /* allocate space for sockaddr */
491                 M_PREPEND(m0, dst->sa_len, M_DONTWAIT);
492
493                 /* if allocation failed drop packet */
494                 if (m0 == NULL) {
495                         ifp->if_iqdrops++;
496                         ifp->if_oerrors++;
497                         return (ENOBUFS);
498                 } else {
499                         bcopy(dst, m0->m_data, dst->sa_len);
500                 }
501         }
502
503         if (tp->tun_flags & TUN_IFHEAD) {
504                 /* Prepend the address family */
505                 M_PREPEND(m0, 4, M_DONTWAIT);
506
507                 /* if allocation failed drop packet */
508                 if (m0 == NULL) {
509                         ifp->if_iqdrops++;
510                         ifp->if_oerrors++;
511                         return (ENOBUFS);
512                 } else
513                         *(u_int32_t *)m0->m_data = htonl(dst->sa_family);
514         } else {
515 #ifdef INET
516                 if (dst->sa_family != AF_INET)
517 #endif
518                 {
519                         m_freem(m0);
520                         return (EAFNOSUPPORT);
521                 }
522         }
523
524         if (! IF_HANDOFF(&ifp->if_snd, m0, ifp)) {
525                 ifp->if_collisions++;
526                 return (ENOBUFS);
527         }
528         ifp->if_opackets++;
529         return (0);
530 }
531
532 /*
533  * the cdevsw interface is now pretty minimal.
534  */
535 static  int
536 tunioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td)
537 {
538         int             s;
539         int             error;
540         struct tun_softc *tp = dev->si_drv1;
541         struct tuninfo *tunp;
542
543         switch (cmd) {
544         case TUNSIFINFO:
545                 tunp = (struct tuninfo *)data;
546                 if (tunp->mtu < IF_MINMTU)
547                         return (EINVAL);
548                 if (tp->tun_if.if_mtu != tunp->mtu
549                 && (error = suser(td)) != 0)
550                         return (error);
551                 tp->tun_if.if_mtu = tunp->mtu;
552                 tp->tun_if.if_type = tunp->type;
553                 tp->tun_if.if_baudrate = tunp->baudrate;
554                 break;
555         case TUNGIFINFO:
556                 tunp = (struct tuninfo *)data;
557                 tunp->mtu = tp->tun_if.if_mtu;
558                 tunp->type = tp->tun_if.if_type;
559                 tunp->baudrate = tp->tun_if.if_baudrate;
560                 break;
561         case TUNSDEBUG:
562                 tundebug = *(int *)data;
563                 break;
564         case TUNGDEBUG:
565                 *(int *)data = tundebug;
566                 break;
567         case TUNSLMODE:
568                 if (*(int *)data) {
569                         tp->tun_flags |= TUN_LMODE;
570                         tp->tun_flags &= ~TUN_IFHEAD;
571                 } else
572                         tp->tun_flags &= ~TUN_LMODE;
573                 break;
574         case TUNSIFHEAD:
575                 if (*(int *)data) {
576                         tp->tun_flags |= TUN_IFHEAD;
577                         tp->tun_flags &= ~TUN_LMODE;
578                 } else 
579                         tp->tun_flags &= ~TUN_IFHEAD;
580                 break;
581         case TUNGIFHEAD:
582                 *(int *)data = (tp->tun_flags & TUN_IFHEAD) ? 1 : 0;
583                 break;
584         case TUNSIFMODE:
585                 /* deny this if UP */
586                 if (tp->tun_if.if_flags & IFF_UP)
587                         return(EBUSY);
588
589                 switch (*(int *)data & ~IFF_MULTICAST) {
590                 case IFF_POINTOPOINT:
591                 case IFF_BROADCAST:
592                         tp->tun_if.if_flags &=
593                             ~(IFF_BROADCAST|IFF_POINTOPOINT|IFF_MULTICAST);
594                         tp->tun_if.if_flags |= *(int *)data;
595                         break;
596                 default:
597                         return(EINVAL);
598                 }
599                 break;
600         case TUNSIFPID:
601                 tp->tun_pid = curthread->td_proc->p_pid;
602                 break;
603         case FIONBIO:
604                 break;
605         case FIOASYNC:
606                 if (*(int *)data)
607                         tp->tun_flags |= TUN_ASYNC;
608                 else
609                         tp->tun_flags &= ~TUN_ASYNC;
610                 break;
611         case FIONREAD:
612                 s = splimp();
613                 if (tp->tun_if.if_snd.ifq_head) {
614                         struct mbuf *mb = tp->tun_if.if_snd.ifq_head;
615                         for( *(int *)data = 0; mb != 0; mb = mb->m_next) 
616                                 *(int *)data += mb->m_len;
617                 } else
618                         *(int *)data = 0;
619                 splx(s);
620                 break;
621         case FIOSETOWN:
622                 return (fsetown(*(int *)data, &tp->tun_sigio));
623
624         case FIOGETOWN:
625                 *(int *)data = fgetown(tp->tun_sigio);
626                 return (0);
627
628         /* This is deprecated, FIOSETOWN should be used instead. */
629         case TIOCSPGRP:
630                 return (fsetown(-(*(int *)data), &tp->tun_sigio));
631
632         /* This is deprecated, FIOGETOWN should be used instead. */
633         case TIOCGPGRP:
634                 *(int *)data = -fgetown(tp->tun_sigio);
635                 return (0);
636
637         default:
638                 return (ENOTTY);
639         }
640         return (0);
641 }
642
643 /*
644  * The cdevsw read interface - reads a packet at a time, or at
645  * least as much of a packet as can be read.
646  */
647 static  int
648 tunread(dev_t dev, struct uio *uio, int flag)
649 {
650         struct tun_softc *tp = dev->si_drv1;
651         struct ifnet    *ifp = &tp->tun_if;
652         struct mbuf     *m;
653         int             error=0, len, s;
654
655         TUNDEBUG ("%s%d: read\n", ifp->if_name, ifp->if_unit);
656         if ((tp->tun_flags & TUN_READY) != TUN_READY) {
657                 TUNDEBUG ("%s%d: not ready 0%o\n", ifp->if_name,
658                           ifp->if_unit, tp->tun_flags);
659                 return (EHOSTDOWN);
660         }
661
662         tp->tun_flags &= ~TUN_RWAIT;
663
664         s = splimp();
665         do {
666                 IF_DEQUEUE(&ifp->if_snd, m);
667                 if (m == NULL) {
668                         if (flag & IO_NDELAY) {
669                                 splx(s);
670                                 return (EWOULDBLOCK);
671                         }
672                         tp->tun_flags |= TUN_RWAIT;
673                         if((error = tsleep((caddr_t)tp, PCATCH | (PZERO + 1),
674                                         "tunread", 0)) != 0) {
675                                 splx(s);
676                                 return (error);
677                         }
678                 }
679         } while (m == NULL);
680         splx(s);
681
682         while (m && uio->uio_resid > 0 && error == 0) {
683                 len = min(uio->uio_resid, m->m_len);
684                 if (len != 0)
685                         error = uiomove(mtod(m, caddr_t), len, uio);
686                 m = m_free(m);
687         }
688
689         if (m) {
690                 TUNDEBUG("%s%d: Dropping mbuf\n", ifp->if_name, ifp->if_unit);
691                 m_freem(m);
692         }
693         return (error);
694 }
695
696 /*
697  * the cdevsw write interface - an atomic write is a packet - or else!
698  */
699 static  int
700 tunwrite(dev_t dev, struct uio *uio, int flag)
701 {
702         struct tun_softc *tp = dev->si_drv1;
703         struct ifnet    *ifp = &tp->tun_if;
704         struct mbuf     *top, **mp, *m;
705         int             error=0, tlen, mlen;
706         uint32_t        family;
707
708         TUNDEBUG("%s%d: tunwrite\n", ifp->if_name, ifp->if_unit);
709
710         if (uio->uio_resid == 0)
711                 return (0);
712
713         if (uio->uio_resid < 0 || uio->uio_resid > TUNMRU) {
714                 TUNDEBUG("%s%d: len=%d!\n", ifp->if_name, ifp->if_unit,
715                     uio->uio_resid);
716                 return (EIO);
717         }
718         tlen = uio->uio_resid;
719
720         /* get a header mbuf */
721         MGETHDR(m, M_DONTWAIT, MT_DATA);
722         if (m == NULL)
723                 return (ENOBUFS);
724         mlen = MHLEN;
725
726         top = 0;
727         mp = &top;
728         while (error == 0 && uio->uio_resid > 0) {
729                 m->m_len = min(mlen, uio->uio_resid);
730                 error = uiomove(mtod (m, caddr_t), m->m_len, uio);
731                 *mp = m;
732                 mp = &m->m_next;
733                 if (uio->uio_resid > 0) {
734                         MGET (m, M_DONTWAIT, MT_DATA);
735                         if (m == 0) {
736                                 error = ENOBUFS;
737                                 break;
738                         }
739                         mlen = MLEN;
740                 }
741         }
742         if (error) {
743                 if (top)
744                         m_freem (top);
745                 ifp->if_ierrors++;
746                 return (error);
747         }
748
749         top->m_pkthdr.len = tlen;
750         top->m_pkthdr.rcvif = ifp;
751 #ifdef MAC
752         mac_create_mbuf_from_ifnet(ifp, top);
753 #endif
754
755         if (ifp->if_bpf) {
756                 if (tp->tun_flags & TUN_IFHEAD) {
757                         /*
758                          * Conveniently, we already have a 4-byte address
759                          * family prepended to our packet !
760                          * Inconveniently, it's in the wrong byte order !
761                          */
762                         if ((top = m_pullup(top, sizeof(family))) == NULL)
763                                 return (ENOBUFS);
764                         *mtod(top, u_int32_t *) =
765                             ntohl(*mtod(top, u_int32_t *));
766                         bpf_mtap(ifp, top);
767                         *mtod(top, u_int32_t *) =
768                             htonl(*mtod(top, u_int32_t *));
769                 } else {
770                         /*
771                          * We need to prepend the address family as
772                          * a four byte field.  Cons up a dummy header
773                          * to pacify bpf.  This is safe because bpf
774                          * will only read from the mbuf (i.e., it won't
775                          * try to free it or keep a pointer to it).
776                          */
777                         struct mbuf m;
778                         uint32_t af = AF_INET;
779
780                         m.m_next = top;
781                         m.m_len = 4;
782                         m.m_data = (char *)&af;
783
784                         bpf_mtap(ifp, &m);
785                 }
786         }
787
788         if (tp->tun_flags & TUN_IFHEAD) {
789                 if (top->m_len < sizeof(family) &&
790                     (top = m_pullup(top, sizeof(family))) == NULL)
791                         return (ENOBUFS);
792                 family = ntohl(*mtod(top, u_int32_t *));
793                 m_adj(top, sizeof(family));
794         } else
795                 family = AF_INET;
796
797         ifp->if_ibytes += top->m_pkthdr.len;
798         ifp->if_ipackets++;
799
800         return (family_enqueue(family, top));
801 }
802
803 /*
804  * tunpoll - the poll interface, this is only useful on reads
805  * really. The write detect always returns true, write never blocks
806  * anyway, it either accepts the packet or drops it.
807  */
808 static  int
809 tunpoll(dev_t dev, int events, struct thread *td)
810 {
811         int             s;
812         struct tun_softc *tp = dev->si_drv1;
813         struct ifnet    *ifp = &tp->tun_if;
814         int             revents = 0;
815
816         s = splimp();
817         TUNDEBUG("%s%d: tunpoll\n", ifp->if_name, ifp->if_unit);
818
819         if (events & (POLLIN | POLLRDNORM)) {
820                 if (ifp->if_snd.ifq_len > 0) {
821                         TUNDEBUG("%s%d: tunpoll q=%d\n", ifp->if_name,
822                             ifp->if_unit, ifp->if_snd.ifq_len);
823                         revents |= events & (POLLIN | POLLRDNORM);
824                 } else {
825                         TUNDEBUG("%s%d: tunpoll waiting\n", ifp->if_name,
826                             ifp->if_unit);
827                         selrecord(td, &tp->tun_rsel);
828                 }
829         }
830         if (events & (POLLOUT | POLLWRNORM))
831                 revents |= events & (POLLOUT | POLLWRNORM);
832
833         splx(s);
834         return (revents);
835 }