]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/net/if_tap.c
This commit was generated by cvs2svn to compensate for changes in r167617,
[FreeBSD/FreeBSD.git] / sys / net / if_tap.c
1 /*-
2  * Copyright (C) 1999-2000 by Maksim Yevmenkin <m_evmenkin@yahoo.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * BASED ON:
27  * -------------------------------------------------------------------------
28  *
29  * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
30  * Nottingham University 1987.
31  */
32
33 /*
34  * $FreeBSD$
35  * $Id: if_tap.c,v 0.21 2000/07/23 21:46:02 max Exp $
36  */
37
38 #include "opt_compat.h"
39 #include "opt_inet.h"
40
41 #include <sys/param.h>
42 #include <sys/conf.h>
43 #include <sys/fcntl.h>
44 #include <sys/filio.h>
45 #include <sys/kernel.h>
46 #include <sys/malloc.h>
47 #include <sys/mbuf.h>
48 #include <sys/module.h>
49 #include <sys/poll.h>
50 #include <sys/priv.h>
51 #include <sys/proc.h>
52 #include <sys/selinfo.h>
53 #include <sys/signalvar.h>
54 #include <sys/socket.h>
55 #include <sys/sockio.h>
56 #include <sys/sysctl.h>
57 #include <sys/systm.h>
58 #include <sys/ttycom.h>
59 #include <sys/uio.h>
60 #include <sys/queue.h>
61
62 #include <net/bpf.h>
63 #include <net/ethernet.h>
64 #include <net/if.h>
65 #include <net/if_clone.h>
66 #include <net/if_dl.h>
67 #include <net/route.h>
68 #include <net/if_types.h>
69
70 #include <netinet/in.h>
71
72 #include <net/if_tapvar.h>
73 #include <net/if_tap.h>
74
75
76 #define CDEV_NAME       "tap"
77 #define TAPDEBUG        if (tapdebug) printf
78
79 #define TAP             "tap"
80 #define VMNET           "vmnet"
81 #define TAPMAXUNIT      0x7fff
82 #define VMNET_DEV_MASK  CLONE_FLAG0
83
84 /* module */
85 static int              tapmodevent(module_t, int, void *);
86
87 /* device */
88 static void             tapclone(void *, struct ucred *, char *, int,
89                             struct cdev **);
90 static void             tapcreate(struct cdev *);
91
92 /* network interface */
93 static void             tapifstart(struct ifnet *);
94 static int              tapifioctl(struct ifnet *, u_long, caddr_t);
95 static void             tapifinit(void *);
96
97 static int              tap_clone_create(struct if_clone *, int, caddr_t);
98 static void             tap_clone_destroy(struct ifnet *);
99 static int              vmnet_clone_create(struct if_clone *, int, caddr_t);
100 static void             vmnet_clone_destroy(struct ifnet *);
101
102 IFC_SIMPLE_DECLARE(tap, 0);
103 IFC_SIMPLE_DECLARE(vmnet, 0);
104
105 /* character device */
106 static d_open_t         tapopen;
107 static d_close_t        tapclose;
108 static d_read_t         tapread;
109 static d_write_t        tapwrite;
110 static d_ioctl_t        tapioctl;
111 static d_poll_t         tappoll;
112 static d_kqfilter_t     tapkqfilter;
113
114 /* kqueue(2) */
115 static int              tapkqread(struct knote *, long);
116 static int              tapkqwrite(struct knote *, long);
117 static void             tapkqdetach(struct knote *);
118
119 static struct filterops tap_read_filterops = {
120         .f_isfd =       1,
121         .f_attach =     NULL,
122         .f_detach =     tapkqdetach,
123         .f_event =      tapkqread,
124 };
125
126 static struct filterops tap_write_filterops = {
127         .f_isfd =       1,
128         .f_attach =     NULL,
129         .f_detach =     tapkqdetach,
130         .f_event =      tapkqwrite,
131 };
132
133 static struct cdevsw    tap_cdevsw = {
134         .d_version =    D_VERSION,
135         .d_flags =      D_PSEUDO | D_NEEDGIANT,
136         .d_open =       tapopen,
137         .d_close =      tapclose,
138         .d_read =       tapread,
139         .d_write =      tapwrite,
140         .d_ioctl =      tapioctl,
141         .d_poll =       tappoll,
142         .d_name =       CDEV_NAME,
143         .d_kqfilter =   tapkqfilter,
144 };
145
146 /*
147  * All global variables in if_tap.c are locked with tapmtx, with the
148  * exception of tapdebug, which is accessed unlocked; tapclones is
149  * static at runtime.
150  */
151 static struct mtx               tapmtx;
152 static int                      tapdebug = 0;        /* debug flag   */
153 static int                      tapuopen = 0;        /* allow user open() */         
154 static int                      tapdclone = 1;  /* enable devfs cloning */
155 static SLIST_HEAD(, tap_softc)  taphead;             /* first device */
156 static struct clonedevs         *tapclones;
157
158 MALLOC_DECLARE(M_TAP);
159 MALLOC_DEFINE(M_TAP, CDEV_NAME, "Ethernet tunnel interface");
160 SYSCTL_INT(_debug, OID_AUTO, if_tap_debug, CTLFLAG_RW, &tapdebug, 0, "");
161
162 SYSCTL_DECL(_net_link);
163 SYSCTL_NODE(_net_link, OID_AUTO, tap, CTLFLAG_RW, 0,
164     "Ethernet tunnel software network interface");
165 SYSCTL_INT(_net_link_tap, OID_AUTO, user_open, CTLFLAG_RW, &tapuopen, 0,
166         "Allow user to open /dev/tap (based on node permissions)");
167 SYSCTL_INT(_net_link_tap, OID_AUTO, devfs_cloning, CTLFLAG_RW, &tapdclone, 0,
168         "Enably legacy devfs interface creation");
169 SYSCTL_INT(_net_link_tap, OID_AUTO, debug, CTLFLAG_RW, &tapdebug, 0, "");
170
171 TUNABLE_INT("net.link.tap.devfs_cloning", &tapdclone);
172
173 DEV_MODULE(if_tap, tapmodevent, NULL);
174
175 static int
176 tap_clone_create(struct if_clone *ifc, int unit, caddr_t params)
177 {
178         struct cdev *dev;
179         int i;
180         int extra;
181
182         if (strcmp(ifc->ifc_name, VMNET) == 0)
183                 extra = VMNET_DEV_MASK;
184         else
185                 extra = 0;
186
187         /* find any existing device, or allocate new unit number */
188         i = clone_create(&tapclones, &tap_cdevsw, &unit, &dev, extra);
189         if (i) {
190                 dev = make_dev(&tap_cdevsw, unit2minor(unit | extra),
191                      UID_ROOT, GID_WHEEL, 0600, "%s%d", ifc->ifc_name, unit);
192                 if (dev != NULL) {
193                         dev_ref(dev);
194                         dev->si_flags |= SI_CHEAPCLONE;
195                 }
196         }
197
198         tapcreate(dev);
199         return (0);
200 }
201
202 /* vmnet devices are tap devices in disguise */
203 static int
204 vmnet_clone_create(struct if_clone *ifc, int unit, caddr_t params)
205 {
206         return tap_clone_create(ifc, unit, params);
207 }
208
209 static void
210 tap_destroy(struct tap_softc *tp)
211 {
212         struct ifnet *ifp = tp->tap_ifp;
213         int s;
214
215         /* Unlocked read. */
216         KASSERT(!(tp->tap_flags & TAP_OPEN),
217                 ("%s flags is out of sync", ifp->if_xname));
218
219         knlist_destroy(&tp->tap_rsel.si_note);
220         destroy_dev(tp->tap_dev);
221         s = splimp();
222         ether_ifdetach(ifp);
223         if_free_type(ifp, IFT_ETHER);
224         splx(s);
225
226         mtx_destroy(&tp->tap_mtx);
227         free(tp, M_TAP);
228 }
229
230 static void
231 tap_clone_destroy(struct ifnet *ifp)
232 {
233         struct tap_softc *tp = ifp->if_softc;
234
235         mtx_lock(&tapmtx);
236         SLIST_REMOVE(&taphead, tp, tap_softc, tap_next);
237         mtx_unlock(&tapmtx);
238         tap_destroy(tp);
239 }
240
241 /* vmnet devices are tap devices in disguise */
242 static void
243 vmnet_clone_destroy(struct ifnet *ifp)
244 {
245         tap_clone_destroy(ifp);
246 }
247
248 /*
249  * tapmodevent
250  *
251  * module event handler
252  */
253 static int
254 tapmodevent(module_t mod, int type, void *data)
255 {
256         static eventhandler_tag  eh_tag = NULL;
257         struct tap_softc        *tp = NULL;
258         struct ifnet            *ifp = NULL;
259
260         switch (type) {
261         case MOD_LOAD:
262
263                 /* intitialize device */
264
265                 mtx_init(&tapmtx, "tapmtx", NULL, MTX_DEF);
266                 SLIST_INIT(&taphead);
267
268                 clone_setup(&tapclones);
269                 eh_tag = EVENTHANDLER_REGISTER(dev_clone, tapclone, 0, 1000);
270                 if (eh_tag == NULL) {
271                         clone_cleanup(&tapclones);
272                         mtx_destroy(&tapmtx);
273                         return (ENOMEM);
274                 }
275                 if_clone_attach(&tap_cloner);
276                 if_clone_attach(&vmnet_cloner);
277                 return (0);
278
279         case MOD_UNLOAD:
280                 /*
281                  * The EBUSY algorithm here can't quite atomically
282                  * guarantee that this is race-free since we have to
283                  * release the tap mtx to deregister the clone handler.
284                  */
285                 mtx_lock(&tapmtx);
286                 SLIST_FOREACH(tp, &taphead, tap_next) {
287                         mtx_lock(&tp->tap_mtx);
288                         if (tp->tap_flags & TAP_OPEN) {
289                                 mtx_unlock(&tp->tap_mtx);
290                                 mtx_unlock(&tapmtx);
291                                 return (EBUSY);
292                         }
293                         mtx_unlock(&tp->tap_mtx);
294                 }
295                 mtx_unlock(&tapmtx);
296
297                 EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
298                 if_clone_detach(&tap_cloner);
299                 if_clone_detach(&vmnet_cloner);
300
301                 mtx_lock(&tapmtx);
302                 while ((tp = SLIST_FIRST(&taphead)) != NULL) {
303                         SLIST_REMOVE_HEAD(&taphead, tap_next);
304                         mtx_unlock(&tapmtx);
305
306                         ifp = tp->tap_ifp;
307
308                         TAPDEBUG("detaching %s\n", ifp->if_xname);
309
310                         tap_destroy(tp);
311                         mtx_lock(&tapmtx);
312                 }
313                 mtx_unlock(&tapmtx);
314                 clone_cleanup(&tapclones);
315
316                 mtx_destroy(&tapmtx);
317
318                 break;
319
320         default:
321                 return (EOPNOTSUPP);
322         }
323
324         return (0);
325 } /* tapmodevent */
326
327
328 /*
329  * DEVFS handler
330  *
331  * We need to support two kind of devices - tap and vmnet
332  */
333 static void
334 tapclone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **dev)
335 {
336         char            devname[SPECNAMELEN + 1];
337         int             i, unit, append_unit;
338         int             extra;
339
340         if (*dev != NULL)
341                 return;
342
343         if (!tapdclone ||
344             (!tapuopen && priv_check_cred(cred, PRIV_NET_IFCREATE, 0) != 0))
345                 return;
346
347         unit = 0;
348         append_unit = 0;
349         extra = 0;
350
351         /* We're interested in only tap/vmnet devices. */
352         if (strcmp(name, TAP) == 0) {
353                 unit = -1;
354         } else if (strcmp(name, VMNET) == 0) {
355                 unit = -1;
356                 extra = VMNET_DEV_MASK;
357         } else if (dev_stdclone(name, NULL, TAP, &unit) != 1) {
358                 if (dev_stdclone(name, NULL, VMNET, &unit) != 1) {
359                         return;
360                 } else {
361                         extra = VMNET_DEV_MASK;
362                 }
363         }
364
365         if (unit == -1)
366                 append_unit = 1;
367
368         /* find any existing device, or allocate new unit number */
369         i = clone_create(&tapclones, &tap_cdevsw, &unit, dev, extra);
370         if (i) {
371                 if (append_unit) {
372                         /*
373                          * We were passed 'tun' or 'tap', with no unit specified
374                          * so we'll need to append it now.
375                          */
376                         namelen = snprintf(devname, sizeof(devname), "%s%d", name,
377                             unit);
378                         name = devname;
379                 }
380
381                 *dev = make_dev(&tap_cdevsw, unit2minor(unit | extra),
382                      UID_ROOT, GID_WHEEL, 0600, "%s", name);
383                 if (*dev != NULL) {
384                         dev_ref(*dev);
385                         (*dev)->si_flags |= SI_CHEAPCLONE;
386                 }
387         }
388
389         if_clone_create(name, namelen, NULL);
390 } /* tapclone */
391
392
393 /*
394  * tapcreate
395  *
396  * to create interface
397  */
398 static void
399 tapcreate(struct cdev *dev)
400 {
401         struct ifnet            *ifp = NULL;
402         struct tap_softc        *tp = NULL;
403         unsigned short           macaddr_hi;
404         int                      unit, s;
405         char                    *name = NULL;
406         u_char                  eaddr[6];
407
408         dev->si_flags &= ~SI_CHEAPCLONE;
409
410         /* allocate driver storage and create device */
411         MALLOC(tp, struct tap_softc *, sizeof(*tp), M_TAP, M_WAITOK | M_ZERO);
412         mtx_init(&tp->tap_mtx, "tap_mtx", NULL, MTX_DEF);
413         mtx_lock(&tapmtx);
414         SLIST_INSERT_HEAD(&taphead, tp, tap_next);
415         mtx_unlock(&tapmtx);
416
417         unit = dev2unit(dev);
418
419         /* select device: tap or vmnet */
420         if (unit & VMNET_DEV_MASK) {
421                 name = VMNET;
422                 tp->tap_flags |= TAP_VMNET;
423         } else
424                 name = TAP;
425
426         unit &= TAPMAXUNIT;
427
428         TAPDEBUG("tapcreate(%s%d). minor = %#x\n", name, unit, minor(dev));
429
430         /* generate fake MAC address: 00 bd xx xx xx unit_no */
431         macaddr_hi = htons(0x00bd);
432         bcopy(&macaddr_hi, eaddr, sizeof(short));
433         bcopy(&ticks, &eaddr[2], sizeof(long));
434         eaddr[5] = (u_char)unit;
435
436         /* fill the rest and attach interface */
437         ifp = tp->tap_ifp = if_alloc(IFT_ETHER);
438         if (ifp == NULL)
439                 panic("%s%d: can not if_alloc()", name, unit);
440         ifp->if_softc = tp;
441         if_initname(ifp, name, unit);
442         ifp->if_init = tapifinit;
443         ifp->if_start = tapifstart;
444         ifp->if_ioctl = tapifioctl;
445         ifp->if_mtu = ETHERMTU;
446         ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
447         ifp->if_snd.ifq_maxlen = ifqmaxlen;
448
449         dev->si_drv1 = tp;
450         tp->tap_dev = dev;
451
452         s = splimp();
453         ether_ifattach(ifp, eaddr);
454         splx(s);
455
456         mtx_lock(&tp->tap_mtx);
457         tp->tap_flags |= TAP_INITED;
458         mtx_unlock(&tp->tap_mtx);
459
460         knlist_init(&tp->tap_rsel.si_note, NULL, NULL, NULL, NULL);
461
462         TAPDEBUG("interface %s is created. minor = %#x\n", 
463                 ifp->if_xname, minor(dev));
464 } /* tapcreate */
465
466
467 /*
468  * tapopen
469  *
470  * to open tunnel. must be superuser
471  */
472 static int
473 tapopen(struct cdev *dev, int flag, int mode, struct thread *td)
474 {
475         struct tap_softc        *tp = NULL;
476         struct ifnet            *ifp = NULL;
477         int                      error, s;
478
479         if (tapuopen == 0) {
480                 error = priv_check(td, PRIV_NET_TAP);
481                 if (error)
482                         return (error);
483         }
484
485         if ((dev2unit(dev) & CLONE_UNITMASK) > TAPMAXUNIT)
486                 return (ENXIO);
487
488         tp = dev->si_drv1;
489
490         mtx_lock(&tp->tap_mtx);
491         if (tp->tap_flags & TAP_OPEN) {
492                 mtx_unlock(&tp->tap_mtx);
493                 return (EBUSY);
494         }
495
496         bcopy(IF_LLADDR(tp->tap_ifp), tp->ether_addr, sizeof(tp->ether_addr));
497         tp->tap_pid = td->td_proc->p_pid;
498         tp->tap_flags |= TAP_OPEN;
499         ifp = tp->tap_ifp;
500         mtx_unlock(&tp->tap_mtx);
501
502         s = splimp();
503         ifp->if_drv_flags |= IFF_DRV_RUNNING;
504         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
505         splx(s);
506
507         TAPDEBUG("%s is open. minor = %#x\n", ifp->if_xname, minor(dev));
508
509         return (0);
510 } /* tapopen */
511
512
513 /*
514  * tapclose
515  *
516  * close the device - mark i/f down & delete routing info
517  */
518 static int
519 tapclose(struct cdev *dev, int foo, int bar, struct thread *td)
520 {
521         struct ifaddr           *ifa;
522         struct tap_softc        *tp = dev->si_drv1;
523         struct ifnet            *ifp = tp->tap_ifp;
524         int                     s;
525
526         /* junk all pending output */
527         IF_DRAIN(&ifp->if_snd);
528
529         /*
530          * do not bring the interface down, and do not anything with
531          * interface, if we are in VMnet mode. just close the device.
532          */
533
534         mtx_lock(&tp->tap_mtx);
535         if (((tp->tap_flags & TAP_VMNET) == 0) && (ifp->if_flags & IFF_UP)) {
536                 mtx_unlock(&tp->tap_mtx);
537                 s = splimp();
538                 if_down(ifp);
539                 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
540                         TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
541                                 rtinit(ifa, (int)RTM_DELETE, 0);
542                         }
543                         if_purgeaddrs(ifp);
544                         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
545                 }
546                 splx(s);
547         } else
548                 mtx_unlock(&tp->tap_mtx);
549
550         funsetown(&tp->tap_sigio);
551         selwakeuppri(&tp->tap_rsel, PZERO+1);
552         KNOTE_UNLOCKED(&tp->tap_rsel.si_note, 0);
553
554         mtx_lock(&tp->tap_mtx);
555         tp->tap_flags &= ~TAP_OPEN;
556         tp->tap_pid = 0;
557         mtx_unlock(&tp->tap_mtx);
558
559         TAPDEBUG("%s is closed. minor = %#x\n", 
560                 ifp->if_xname, minor(dev));
561
562         return (0);
563 } /* tapclose */
564
565
566 /*
567  * tapifinit
568  *
569  * network interface initialization function
570  */
571 static void
572 tapifinit(void *xtp)
573 {
574         struct tap_softc        *tp = (struct tap_softc *)xtp;
575         struct ifnet            *ifp = tp->tap_ifp;
576
577         TAPDEBUG("initializing %s\n", ifp->if_xname);
578
579         ifp->if_drv_flags |= IFF_DRV_RUNNING;
580         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
581
582         /* attempt to start output */
583         tapifstart(ifp);
584 } /* tapifinit */
585
586
587 /*
588  * tapifioctl
589  *
590  * Process an ioctl request on network interface
591  */
592 static int
593 tapifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
594 {
595         struct tap_softc        *tp = ifp->if_softc;
596         struct ifstat           *ifs = NULL;
597         int                      s, dummy;
598
599         switch (cmd) {
600                 case SIOCSIFFLAGS: /* XXX -- just like vmnet does */
601                 case SIOCADDMULTI:
602                 case SIOCDELMULTI:
603                         break;
604
605                 case SIOCGIFSTATUS:
606                         s = splimp();
607                         ifs = (struct ifstat *)data;
608                         dummy = strlen(ifs->ascii);
609                         mtx_lock(&tp->tap_mtx);
610                         if (tp->tap_pid != 0 && dummy < sizeof(ifs->ascii))
611                                 snprintf(ifs->ascii + dummy,
612                                         sizeof(ifs->ascii) - dummy,
613                                         "\tOpened by PID %d\n", tp->tap_pid);
614                         mtx_unlock(&tp->tap_mtx);
615                         splx(s);
616                         break;
617
618                 default:
619                         s = splimp();
620                         dummy = ether_ioctl(ifp, cmd, data);
621                         splx(s);
622                         return (dummy);
623                         /* NOT REACHED */
624         }
625
626         return (0);
627 } /* tapifioctl */
628
629
630 /*
631  * tapifstart
632  *
633  * queue packets from higher level ready to put out
634  */
635 static void
636 tapifstart(struct ifnet *ifp)
637 {
638         struct tap_softc        *tp = ifp->if_softc;
639         int                      s;
640
641         TAPDEBUG("%s starting\n", ifp->if_xname);
642
643         /*
644          * do not junk pending output if we are in VMnet mode.
645          * XXX: can this do any harm because of queue overflow?
646          */
647
648         mtx_lock(&tp->tap_mtx);
649         if (((tp->tap_flags & TAP_VMNET) == 0) &&
650             ((tp->tap_flags & TAP_READY) != TAP_READY)) {
651                 struct mbuf     *m = NULL;
652
653                 mtx_unlock(&tp->tap_mtx);
654
655                 /* Unlocked read. */
656                 TAPDEBUG("%s not ready, tap_flags = 0x%x\n", ifp->if_xname, 
657                     tp->tap_flags);
658
659                 s = splimp();
660                 do {
661                         IF_DEQUEUE(&ifp->if_snd, m);
662                         if (m != NULL)
663                                 m_freem(m);
664                         ifp->if_oerrors ++;
665                 } while (m != NULL);
666                 splx(s);
667
668                 return;
669         }
670         mtx_unlock(&tp->tap_mtx);
671
672         s = splimp();
673         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
674
675         if (ifp->if_snd.ifq_len != 0) {
676                 mtx_lock(&tp->tap_mtx);
677                 if (tp->tap_flags & TAP_RWAIT) {
678                         tp->tap_flags &= ~TAP_RWAIT;
679                         wakeup(tp);
680                 }
681
682                 if ((tp->tap_flags & TAP_ASYNC) && (tp->tap_sigio != NULL)) {
683                         mtx_unlock(&tp->tap_mtx);
684                         pgsigio(&tp->tap_sigio, SIGIO, 0);
685                 } else
686                         mtx_unlock(&tp->tap_mtx);
687
688                 selwakeuppri(&tp->tap_rsel, PZERO+1);
689                 KNOTE_UNLOCKED(&tp->tap_rsel.si_note, 0);
690                 ifp->if_opackets ++; /* obytes are counted in ether_output */
691         }
692
693         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
694         splx(s);
695 } /* tapifstart */
696
697
698 /*
699  * tapioctl
700  *
701  * the cdevsw interface is now pretty minimal
702  */
703 static int
704 tapioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
705 {
706         struct tap_softc        *tp = dev->si_drv1;
707         struct ifnet            *ifp = tp->tap_ifp;
708         struct tapinfo          *tapp = NULL;
709         int                      s;
710         int                      f;
711 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
712     defined(COMPAT_FREEBSD4)
713         int                      ival;
714 #endif
715
716         switch (cmd) {
717                 case TAPSIFINFO:
718                         s = splimp();
719                         tapp = (struct tapinfo *)data;
720                         ifp->if_mtu = tapp->mtu;
721                         ifp->if_type = tapp->type;
722                         ifp->if_baudrate = tapp->baudrate;
723                         splx(s);
724                         break;
725
726                 case TAPGIFINFO:
727                         tapp = (struct tapinfo *)data;
728                         tapp->mtu = ifp->if_mtu;
729                         tapp->type = ifp->if_type;
730                         tapp->baudrate = ifp->if_baudrate;
731                         break;
732
733                 case TAPSDEBUG:
734                         tapdebug = *(int *)data;
735                         break;
736
737                 case TAPGDEBUG:
738                         *(int *)data = tapdebug;
739                         break;
740
741                 case FIONBIO:
742                         break;
743
744                 case FIOASYNC:
745                         s = splimp();
746                         mtx_lock(&tp->tap_mtx);
747                         if (*(int *)data)
748                                 tp->tap_flags |= TAP_ASYNC;
749                         else
750                                 tp->tap_flags &= ~TAP_ASYNC;
751                         mtx_unlock(&tp->tap_mtx);
752                         splx(s);
753                         break;
754
755                 case FIONREAD:
756                         s = splimp();
757                         if (ifp->if_snd.ifq_head) {
758                                 struct mbuf     *mb = ifp->if_snd.ifq_head;
759
760                                 for(*(int *)data = 0;mb != NULL;mb = mb->m_next)
761                                         *(int *)data += mb->m_len;
762                         } else
763                                 *(int *)data = 0;
764                         splx(s);
765                         break;
766
767                 case FIOSETOWN:
768                         return (fsetown(*(int *)data, &tp->tap_sigio));
769
770                 case FIOGETOWN:
771                         *(int *)data = fgetown(&tp->tap_sigio);
772                         return (0);
773
774                 /* this is deprecated, FIOSETOWN should be used instead */
775                 case TIOCSPGRP:
776                         return (fsetown(-(*(int *)data), &tp->tap_sigio));
777
778                 /* this is deprecated, FIOGETOWN should be used instead */
779                 case TIOCGPGRP:
780                         *(int *)data = -fgetown(&tp->tap_sigio);
781                         return (0);
782
783                 /* VMware/VMnet port ioctl's */
784
785                 case SIOCGIFFLAGS:      /* get ifnet flags */
786                         bcopy(&ifp->if_flags, data, sizeof(ifp->if_flags));
787                         break;
788
789 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
790     defined(COMPAT_FREEBSD4)
791                 case _IO('V', 0):
792                         ival = IOCPARM_IVAL(data);
793                         data = (caddr_t)&ival;
794                         /* FALLTHROUGH */
795 #endif
796                 case VMIO_SIOCSIFFLAGS: /* VMware/VMnet SIOCSIFFLAGS */
797                         f = *(int *)data;
798                         f &= 0x0fff;
799                         f &= ~IFF_CANTCHANGE;
800                         f |= IFF_UP;
801
802                         s = splimp();
803                         ifp->if_flags = f | (ifp->if_flags & IFF_CANTCHANGE);
804                         splx(s);
805                         break;
806
807                 case OSIOCGIFADDR:      /* get MAC address of the remote side */
808                 case SIOCGIFADDR:
809                         mtx_lock(&tp->tap_mtx);
810                         bcopy(tp->ether_addr, data, sizeof(tp->ether_addr));
811                         mtx_unlock(&tp->tap_mtx);
812                         break;
813
814                 case SIOCSIFADDR:       /* set MAC address of the remote side */
815                         mtx_lock(&tp->tap_mtx);
816                         bcopy(data, tp->ether_addr, sizeof(tp->ether_addr));
817                         mtx_unlock(&tp->tap_mtx);
818                         break;
819
820                 default:
821                         return (ENOTTY);
822         }
823         return (0);
824 } /* tapioctl */
825
826
827 /*
828  * tapread
829  *
830  * the cdevsw read interface - reads a packet at a time, or at
831  * least as much of a packet as can be read
832  */
833 static int
834 tapread(struct cdev *dev, struct uio *uio, int flag)
835 {
836         struct tap_softc        *tp = dev->si_drv1;
837         struct ifnet            *ifp = tp->tap_ifp;
838         struct mbuf             *m = NULL;
839         int                      error = 0, len, s;
840
841         TAPDEBUG("%s reading, minor = %#x\n", ifp->if_xname, minor(dev));
842
843         mtx_lock(&tp->tap_mtx);
844         if ((tp->tap_flags & TAP_READY) != TAP_READY) {
845                 mtx_unlock(&tp->tap_mtx);
846
847                 /* Unlocked read. */
848                 TAPDEBUG("%s not ready. minor = %#x, tap_flags = 0x%x\n",
849                         ifp->if_xname, minor(dev), tp->tap_flags);
850
851                 return (EHOSTDOWN);
852         }
853
854         tp->tap_flags &= ~TAP_RWAIT;
855         mtx_unlock(&tp->tap_mtx);
856
857         /* sleep until we get a packet */
858         do {
859                 s = splimp();
860                 IF_DEQUEUE(&ifp->if_snd, m);
861                 splx(s);
862
863                 if (m == NULL) {
864                         if (flag & O_NONBLOCK)
865                                 return (EWOULDBLOCK);
866
867                         mtx_lock(&tp->tap_mtx);
868                         tp->tap_flags |= TAP_RWAIT;
869                         mtx_unlock(&tp->tap_mtx);
870                         error = tsleep(tp,PCATCH|(PZERO+1),"taprd",0);
871                         if (error)
872                                 return (error);
873                 }
874         } while (m == NULL);
875
876         /* feed packet to bpf */
877         BPF_MTAP(ifp, m);
878
879         /* xfer packet to user space */
880         while ((m != NULL) && (uio->uio_resid > 0) && (error == 0)) {
881                 len = min(uio->uio_resid, m->m_len);
882                 if (len == 0)
883                         break;
884
885                 error = uiomove(mtod(m, void *), len, uio);
886                 m = m_free(m);
887         }
888
889         if (m != NULL) {
890                 TAPDEBUG("%s dropping mbuf, minor = %#x\n", ifp->if_xname, 
891                         minor(dev));
892                 m_freem(m);
893         }
894
895         return (error);
896 } /* tapread */
897
898
899 /*
900  * tapwrite
901  *
902  * the cdevsw write interface - an atomic write is a packet - or else!
903  */
904 static int
905 tapwrite(struct cdev *dev, struct uio *uio, int flag)
906 {
907         struct ether_header     *eh;
908         struct tap_softc        *tp = dev->si_drv1;
909         struct ifnet            *ifp = tp->tap_ifp;
910         struct mbuf             *m;
911
912         TAPDEBUG("%s writting, minor = %#x\n", 
913                 ifp->if_xname, minor(dev));
914
915         if (uio->uio_resid == 0)
916                 return (0);
917
918         if ((uio->uio_resid < 0) || (uio->uio_resid > TAPMRU)) {
919                 TAPDEBUG("%s invalid packet len = %d, minor = %#x\n",
920                         ifp->if_xname, uio->uio_resid, minor(dev));
921
922                 return (EIO);
923         }
924
925         if ((m = m_uiotombuf(uio, M_DONTWAIT, 0, ETHER_ALIGN,
926             M_PKTHDR)) == NULL) {
927                 ifp->if_ierrors ++;
928                 return (ENOBUFS);
929         }
930
931         m->m_pkthdr.rcvif = ifp;
932
933         /*
934          * Only pass a unicast frame to ether_input(), if it would actually
935          * have been received by non-virtual hardware.
936          */
937         if (m->m_len < sizeof(struct ether_header)) {
938                 m_freem(m);
939                 return (0);
940         }
941         eh = mtod(m, struct ether_header *);
942
943         if (eh && (ifp->if_flags & IFF_PROMISC) == 0 &&
944             !ETHER_IS_MULTICAST(eh->ether_dhost) &&
945             bcmp(eh->ether_dhost, IF_LLADDR(ifp), ETHER_ADDR_LEN) != 0) {
946                 m_freem(m);
947                 return (0);
948         }
949
950         /* Pass packet up to parent. */
951         (*ifp->if_input)(ifp, m);
952         ifp->if_ipackets ++; /* ibytes are counted in parent */
953
954         return (0);
955 } /* tapwrite */
956
957
958 /*
959  * tappoll
960  *
961  * the poll interface, this is only useful on reads
962  * really. the write detect always returns true, write never blocks
963  * anyway, it either accepts the packet or drops it
964  */
965 static int
966 tappoll(struct cdev *dev, int events, struct thread *td)
967 {
968         struct tap_softc        *tp = dev->si_drv1;
969         struct ifnet            *ifp = tp->tap_ifp;
970         int                      s, revents = 0;
971
972         TAPDEBUG("%s polling, minor = %#x\n", 
973                 ifp->if_xname, minor(dev));
974
975         s = splimp();
976         if (events & (POLLIN | POLLRDNORM)) {
977                 if (ifp->if_snd.ifq_len > 0) {
978                         TAPDEBUG("%s have data in queue. len = %d, " \
979                                 "minor = %#x\n", ifp->if_xname,
980                                 ifp->if_snd.ifq_len, minor(dev));
981
982                         revents |= (events & (POLLIN | POLLRDNORM));
983                 } else {
984                         TAPDEBUG("%s waiting for data, minor = %#x\n",
985                                 ifp->if_xname, minor(dev));
986
987                         selrecord(td, &tp->tap_rsel);
988                 }
989         }
990
991         if (events & (POLLOUT | POLLWRNORM))
992                 revents |= (events & (POLLOUT | POLLWRNORM));
993
994         splx(s);
995         return (revents);
996 } /* tappoll */
997
998
999 /*
1000  * tap_kqfilter
1001  *
1002  * support for kevent() system call
1003  */
1004 static int
1005 tapkqfilter(struct cdev *dev, struct knote *kn)
1006 {
1007         int                      s;
1008         struct tap_softc        *tp = dev->si_drv1;
1009         struct ifnet            *ifp = tp->tap_ifp;
1010
1011         s = splimp();
1012         switch (kn->kn_filter) {
1013         case EVFILT_READ:
1014                 TAPDEBUG("%s kqfilter: EVFILT_READ, minor = %#x\n",
1015                         ifp->if_xname, minor(dev));
1016                 kn->kn_fop = &tap_read_filterops;
1017                 break;
1018
1019         case EVFILT_WRITE:
1020                 TAPDEBUG("%s kqfilter: EVFILT_WRITE, minor = %#x\n",
1021                         ifp->if_xname, minor(dev));
1022                 kn->kn_fop = &tap_write_filterops;
1023                 break;
1024
1025         default:
1026                 TAPDEBUG("%s kqfilter: invalid filter, minor = %#x\n",
1027                         ifp->if_xname, minor(dev));
1028                 splx(s);
1029                 return (EINVAL);
1030                 /* NOT REACHED */
1031         }
1032         splx(s);
1033
1034         kn->kn_hook = (caddr_t) dev;
1035         knlist_add(&tp->tap_rsel.si_note, kn, 0);
1036
1037         return (0);
1038 } /* tapkqfilter */
1039
1040
1041 /*
1042  * tap_kqread
1043  * 
1044  * Return true if there is data in the interface queue
1045  */
1046 static int
1047 tapkqread(struct knote *kn, long hint)
1048 {
1049         int                      ret, s;
1050         struct cdev             *dev = (struct cdev *)(kn->kn_hook);
1051         struct tap_softc        *tp = dev->si_drv1;
1052         struct ifnet            *ifp = tp->tap_ifp;
1053
1054         s = splimp();
1055         if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) {
1056                 TAPDEBUG("%s have data in queue. len = %d, minor = %#x\n",
1057                         ifp->if_xname, ifp->if_snd.ifq_len, minor(dev));
1058                 ret = 1;
1059         } else {
1060                 TAPDEBUG("%s waiting for data, minor = %#x\n",
1061                         ifp->if_xname, minor(dev));
1062                 ret = 0;
1063         }
1064         splx(s);
1065
1066         return (ret);
1067 } /* tapkqread */
1068
1069
1070 /*
1071  * tap_kqwrite
1072  *
1073  * Always can write. Return the MTU in kn->data
1074  */
1075 static int
1076 tapkqwrite(struct knote *kn, long hint)
1077 {
1078         int                      s;
1079         struct tap_softc        *tp = ((struct cdev *) kn->kn_hook)->si_drv1;
1080         struct ifnet            *ifp = tp->tap_ifp;
1081
1082         s = splimp();
1083         kn->kn_data = ifp->if_mtu;
1084         splx(s);
1085
1086         return (1);
1087 } /* tapkqwrite */
1088
1089
1090 static void
1091 tapkqdetach(struct knote *kn)
1092 {
1093         struct tap_softc        *tp = ((struct cdev *) kn->kn_hook)->si_drv1;
1094
1095         knlist_remove(&tp->tap_rsel.si_note, kn, 0);
1096 } /* tapkqdetach */
1097