]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/net/if_tap.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.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 | D_NEEDMINOR,
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                      tapuponopen = 0;    /* IFF_UP on open() */
155 static int                      tapdclone = 1;  /* enable devfs cloning */
156 static SLIST_HEAD(, tap_softc)  taphead;             /* first device */
157 static struct clonedevs         *tapclones;
158
159 MALLOC_DECLARE(M_TAP);
160 MALLOC_DEFINE(M_TAP, CDEV_NAME, "Ethernet tunnel interface");
161 SYSCTL_INT(_debug, OID_AUTO, if_tap_debug, CTLFLAG_RW, &tapdebug, 0, "");
162
163 SYSCTL_DECL(_net_link);
164 SYSCTL_NODE(_net_link, OID_AUTO, tap, CTLFLAG_RW, 0,
165     "Ethernet tunnel software network interface");
166 SYSCTL_INT(_net_link_tap, OID_AUTO, user_open, CTLFLAG_RW, &tapuopen, 0,
167         "Allow user to open /dev/tap (based on node permissions)");
168 SYSCTL_INT(_net_link_tap, OID_AUTO, up_on_open, CTLFLAG_RW, &tapuponopen, 0,
169         "Bring interface up when /dev/tap is opened");
170 SYSCTL_INT(_net_link_tap, OID_AUTO, devfs_cloning, CTLFLAG_RW, &tapdclone, 0,
171         "Enably legacy devfs interface creation");
172 SYSCTL_INT(_net_link_tap, OID_AUTO, debug, CTLFLAG_RW, &tapdebug, 0, "");
173
174 TUNABLE_INT("net.link.tap.devfs_cloning", &tapdclone);
175
176 DEV_MODULE(if_tap, tapmodevent, NULL);
177
178 static int
179 tap_clone_create(struct if_clone *ifc, int unit, caddr_t params)
180 {
181         struct cdev *dev;
182         int i;
183         int extra;
184
185         if (strcmp(ifc->ifc_name, VMNET) == 0)
186                 extra = VMNET_DEV_MASK;
187         else
188                 extra = 0;
189
190         /* find any existing device, or allocate new unit number */
191         i = clone_create(&tapclones, &tap_cdevsw, &unit, &dev, extra);
192         if (i) {
193                 dev = make_dev(&tap_cdevsw, unit | extra,
194                      UID_ROOT, GID_WHEEL, 0600, "%s%d", ifc->ifc_name, unit);
195         }
196
197         tapcreate(dev);
198         return (0);
199 }
200
201 /* vmnet devices are tap devices in disguise */
202 static int
203 vmnet_clone_create(struct if_clone *ifc, int unit, caddr_t params)
204 {
205         return tap_clone_create(ifc, unit, params);
206 }
207
208 static void
209 tap_destroy(struct tap_softc *tp)
210 {
211         struct ifnet *ifp = tp->tap_ifp;
212         int s;
213
214         /* Unlocked read. */
215         KASSERT(!(tp->tap_flags & TAP_OPEN),
216                 ("%s flags is out of sync", ifp->if_xname));
217
218         knlist_destroy(&tp->tap_rsel.si_note);
219         destroy_dev(tp->tap_dev);
220         s = splimp();
221         ether_ifdetach(ifp);
222         if_free_type(ifp, IFT_ETHER);
223         splx(s);
224
225         mtx_destroy(&tp->tap_mtx);
226         free(tp, M_TAP);
227 }
228
229 static void
230 tap_clone_destroy(struct ifnet *ifp)
231 {
232         struct tap_softc *tp = ifp->if_softc;
233
234         mtx_lock(&tapmtx);
235         SLIST_REMOVE(&taphead, tp, tap_softc, tap_next);
236         mtx_unlock(&tapmtx);
237         tap_destroy(tp);
238 }
239
240 /* vmnet devices are tap devices in disguise */
241 static void
242 vmnet_clone_destroy(struct ifnet *ifp)
243 {
244         tap_clone_destroy(ifp);
245 }
246
247 /*
248  * tapmodevent
249  *
250  * module event handler
251  */
252 static int
253 tapmodevent(module_t mod, int type, void *data)
254 {
255         static eventhandler_tag  eh_tag = NULL;
256         struct tap_softc        *tp = NULL;
257         struct ifnet            *ifp = NULL;
258
259         switch (type) {
260         case MOD_LOAD:
261
262                 /* intitialize device */
263
264                 mtx_init(&tapmtx, "tapmtx", NULL, MTX_DEF);
265                 SLIST_INIT(&taphead);
266
267                 clone_setup(&tapclones);
268                 eh_tag = EVENTHANDLER_REGISTER(dev_clone, tapclone, 0, 1000);
269                 if (eh_tag == NULL) {
270                         clone_cleanup(&tapclones);
271                         mtx_destroy(&tapmtx);
272                         return (ENOMEM);
273                 }
274                 if_clone_attach(&tap_cloner);
275                 if_clone_attach(&vmnet_cloner);
276                 return (0);
277
278         case MOD_UNLOAD:
279                 /*
280                  * The EBUSY algorithm here can't quite atomically
281                  * guarantee that this is race-free since we have to
282                  * release the tap mtx to deregister the clone handler.
283                  */
284                 mtx_lock(&tapmtx);
285                 SLIST_FOREACH(tp, &taphead, tap_next) {
286                         mtx_lock(&tp->tap_mtx);
287                         if (tp->tap_flags & TAP_OPEN) {
288                                 mtx_unlock(&tp->tap_mtx);
289                                 mtx_unlock(&tapmtx);
290                                 return (EBUSY);
291                         }
292                         mtx_unlock(&tp->tap_mtx);
293                 }
294                 mtx_unlock(&tapmtx);
295
296                 EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
297                 if_clone_detach(&tap_cloner);
298                 if_clone_detach(&vmnet_cloner);
299                 drain_dev_clone_events();
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_credf(MAKEDEV_REF, &tap_cdevsw, unit | extra,
382                      cred, UID_ROOT, GID_WHEEL, 0600, "%s", name);
383         }
384
385         if_clone_create(name, namelen, NULL);
386 } /* tapclone */
387
388
389 /*
390  * tapcreate
391  *
392  * to create interface
393  */
394 static void
395 tapcreate(struct cdev *dev)
396 {
397         struct ifnet            *ifp = NULL;
398         struct tap_softc        *tp = NULL;
399         unsigned short           macaddr_hi;
400         uint32_t                 macaddr_mid;
401         int                      unit, s;
402         char                    *name = NULL;
403         u_char                  eaddr[6];
404
405         dev->si_flags &= ~SI_CHEAPCLONE;
406
407         /* allocate driver storage and create device */
408         tp = malloc(sizeof(*tp), M_TAP, M_WAITOK | M_ZERO);
409         mtx_init(&tp->tap_mtx, "tap_mtx", NULL, MTX_DEF);
410         mtx_lock(&tapmtx);
411         SLIST_INSERT_HEAD(&taphead, tp, tap_next);
412         mtx_unlock(&tapmtx);
413
414         unit = dev2unit(dev);
415
416         /* select device: tap or vmnet */
417         if (unit & VMNET_DEV_MASK) {
418                 name = VMNET;
419                 tp->tap_flags |= TAP_VMNET;
420         } else
421                 name = TAP;
422
423         unit &= TAPMAXUNIT;
424
425         TAPDEBUG("tapcreate(%s%d). minor = %#x\n", name, unit, dev2unit(dev));
426
427         /* generate fake MAC address: 00 bd xx xx xx unit_no */
428         macaddr_hi = htons(0x00bd);
429         macaddr_mid = (uint32_t) ticks;
430         bcopy(&macaddr_hi, eaddr, sizeof(short));
431         bcopy(&macaddr_mid, &eaddr[2], sizeof(uint32_t));
432         eaddr[5] = (u_char)unit;
433
434         /* fill the rest and attach interface */
435         ifp = tp->tap_ifp = if_alloc(IFT_ETHER);
436         if (ifp == NULL)
437                 panic("%s%d: can not if_alloc()", name, unit);
438         ifp->if_softc = tp;
439         if_initname(ifp, name, unit);
440         ifp->if_init = tapifinit;
441         ifp->if_start = tapifstart;
442         ifp->if_ioctl = tapifioctl;
443         ifp->if_mtu = ETHERMTU;
444         ifp->if_flags = (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST);
445         ifp->if_snd.ifq_maxlen = ifqmaxlen;
446         ifp->if_capabilities |= IFCAP_LINKSTATE;
447         ifp->if_capenable |= IFCAP_LINKSTATE;
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_mtx(&tp->tap_rsel.si_note, NULL);
461
462         TAPDEBUG("interface %s is created. minor = %#x\n", 
463                 ifp->if_xname, dev2unit(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         if (tapuponopen)
506                 ifp->if_flags |= IFF_UP;
507         if_link_state_change(ifp, LINK_STATE_UP);
508         splx(s);
509
510         TAPDEBUG("%s is open. minor = %#x\n", ifp->if_xname, dev2unit(dev));
511
512         return (0);
513 } /* tapopen */
514
515
516 /*
517  * tapclose
518  *
519  * close the device - mark i/f down & delete routing info
520  */
521 static int
522 tapclose(struct cdev *dev, int foo, int bar, struct thread *td)
523 {
524         struct ifaddr           *ifa;
525         struct tap_softc        *tp = dev->si_drv1;
526         struct ifnet            *ifp = tp->tap_ifp;
527         int                     s;
528
529         /* junk all pending output */
530         IF_DRAIN(&ifp->if_snd);
531
532         /*
533          * do not bring the interface down, and do not anything with
534          * interface, if we are in VMnet mode. just close the device.
535          */
536
537         mtx_lock(&tp->tap_mtx);
538         if (((tp->tap_flags & TAP_VMNET) == 0) && (ifp->if_flags & IFF_UP)) {
539                 mtx_unlock(&tp->tap_mtx);
540                 s = splimp();
541                 if_down(ifp);
542                 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
543                         TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
544                                 rtinit(ifa, (int)RTM_DELETE, 0);
545                         }
546                         if_purgeaddrs(ifp);
547                         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
548                 }
549                 splx(s);
550         } else
551                 mtx_unlock(&tp->tap_mtx);
552
553         if_link_state_change(ifp, LINK_STATE_DOWN);
554         funsetown(&tp->tap_sigio);
555         selwakeuppri(&tp->tap_rsel, PZERO+1);
556         KNOTE_UNLOCKED(&tp->tap_rsel.si_note, 0);
557
558         mtx_lock(&tp->tap_mtx);
559         tp->tap_flags &= ~TAP_OPEN;
560         tp->tap_pid = 0;
561         mtx_unlock(&tp->tap_mtx);
562
563         TAPDEBUG("%s is closed. minor = %#x\n", 
564                 ifp->if_xname, dev2unit(dev));
565
566         return (0);
567 } /* tapclose */
568
569
570 /*
571  * tapifinit
572  *
573  * network interface initialization function
574  */
575 static void
576 tapifinit(void *xtp)
577 {
578         struct tap_softc        *tp = (struct tap_softc *)xtp;
579         struct ifnet            *ifp = tp->tap_ifp;
580
581         TAPDEBUG("initializing %s\n", ifp->if_xname);
582
583         ifp->if_drv_flags |= IFF_DRV_RUNNING;
584         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
585
586         /* attempt to start output */
587         tapifstart(ifp);
588 } /* tapifinit */
589
590
591 /*
592  * tapifioctl
593  *
594  * Process an ioctl request on network interface
595  */
596 static int
597 tapifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
598 {
599         struct tap_softc        *tp = ifp->if_softc;
600         struct ifreq            *ifr = (struct ifreq *)data;
601         struct ifstat           *ifs = NULL;
602         int                      s, dummy;
603
604         switch (cmd) {
605                 case SIOCSIFFLAGS: /* XXX -- just like vmnet does */
606                 case SIOCADDMULTI:
607                 case SIOCDELMULTI:
608                         break;
609
610                 case SIOCSIFMTU:
611                         ifp->if_mtu = ifr->ifr_mtu;
612                         break;
613
614                 case SIOCGIFSTATUS:
615                         s = splimp();
616                         ifs = (struct ifstat *)data;
617                         dummy = strlen(ifs->ascii);
618                         mtx_lock(&tp->tap_mtx);
619                         if (tp->tap_pid != 0 && dummy < sizeof(ifs->ascii))
620                                 snprintf(ifs->ascii + dummy,
621                                         sizeof(ifs->ascii) - dummy,
622                                         "\tOpened by PID %d\n", tp->tap_pid);
623                         mtx_unlock(&tp->tap_mtx);
624                         splx(s);
625                         break;
626
627                 default:
628                         s = splimp();
629                         dummy = ether_ioctl(ifp, cmd, data);
630                         splx(s);
631                         return (dummy);
632                         /* NOT REACHED */
633         }
634
635         return (0);
636 } /* tapifioctl */
637
638
639 /*
640  * tapifstart
641  *
642  * queue packets from higher level ready to put out
643  */
644 static void
645 tapifstart(struct ifnet *ifp)
646 {
647         struct tap_softc        *tp = ifp->if_softc;
648         int                      s;
649
650         TAPDEBUG("%s starting\n", ifp->if_xname);
651
652         /*
653          * do not junk pending output if we are in VMnet mode.
654          * XXX: can this do any harm because of queue overflow?
655          */
656
657         mtx_lock(&tp->tap_mtx);
658         if (((tp->tap_flags & TAP_VMNET) == 0) &&
659             ((tp->tap_flags & TAP_READY) != TAP_READY)) {
660                 struct mbuf     *m = NULL;
661
662                 mtx_unlock(&tp->tap_mtx);
663
664                 /* Unlocked read. */
665                 TAPDEBUG("%s not ready, tap_flags = 0x%x\n", ifp->if_xname, 
666                     tp->tap_flags);
667
668                 s = splimp();
669                 do {
670                         IF_DEQUEUE(&ifp->if_snd, m);
671                         if (m != NULL)
672                                 m_freem(m);
673                         ifp->if_oerrors ++;
674                 } while (m != NULL);
675                 splx(s);
676
677                 return;
678         }
679         mtx_unlock(&tp->tap_mtx);
680
681         s = splimp();
682         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
683
684         if (ifp->if_snd.ifq_len != 0) {
685                 mtx_lock(&tp->tap_mtx);
686                 if (tp->tap_flags & TAP_RWAIT) {
687                         tp->tap_flags &= ~TAP_RWAIT;
688                         wakeup(tp);
689                 }
690
691                 if ((tp->tap_flags & TAP_ASYNC) && (tp->tap_sigio != NULL)) {
692                         mtx_unlock(&tp->tap_mtx);
693                         pgsigio(&tp->tap_sigio, SIGIO, 0);
694                 } else
695                         mtx_unlock(&tp->tap_mtx);
696
697                 selwakeuppri(&tp->tap_rsel, PZERO+1);
698                 KNOTE_UNLOCKED(&tp->tap_rsel.si_note, 0);
699                 ifp->if_opackets ++; /* obytes are counted in ether_output */
700         }
701
702         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
703         splx(s);
704 } /* tapifstart */
705
706
707 /*
708  * tapioctl
709  *
710  * the cdevsw interface is now pretty minimal
711  */
712 static int
713 tapioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
714 {
715         struct tap_softc        *tp = dev->si_drv1;
716         struct ifnet            *ifp = tp->tap_ifp;
717         struct tapinfo          *tapp = NULL;
718         int                      s;
719         int                      f;
720 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
721     defined(COMPAT_FREEBSD4)
722         int                      ival;
723 #endif
724
725         switch (cmd) {
726                 case TAPSIFINFO:
727                         s = splimp();
728                         tapp = (struct tapinfo *)data;
729                         ifp->if_mtu = tapp->mtu;
730                         ifp->if_type = tapp->type;
731                         ifp->if_baudrate = tapp->baudrate;
732                         splx(s);
733                         break;
734
735                 case TAPGIFINFO:
736                         tapp = (struct tapinfo *)data;
737                         tapp->mtu = ifp->if_mtu;
738                         tapp->type = ifp->if_type;
739                         tapp->baudrate = ifp->if_baudrate;
740                         break;
741
742                 case TAPSDEBUG:
743                         tapdebug = *(int *)data;
744                         break;
745
746                 case TAPGDEBUG:
747                         *(int *)data = tapdebug;
748                         break;
749
750                 case TAPGIFNAME: {
751                         struct ifreq    *ifr = (struct ifreq *) data;
752
753                         strlcpy(ifr->ifr_name, ifp->if_xname, IFNAMSIZ);
754                         } break;
755
756                 case FIONBIO:
757                         break;
758
759                 case FIOASYNC:
760                         s = splimp();
761                         mtx_lock(&tp->tap_mtx);
762                         if (*(int *)data)
763                                 tp->tap_flags |= TAP_ASYNC;
764                         else
765                                 tp->tap_flags &= ~TAP_ASYNC;
766                         mtx_unlock(&tp->tap_mtx);
767                         splx(s);
768                         break;
769
770                 case FIONREAD:
771                         s = splimp();
772                         if (ifp->if_snd.ifq_head) {
773                                 struct mbuf     *mb = ifp->if_snd.ifq_head;
774
775                                 for(*(int *)data = 0;mb != NULL;mb = mb->m_next)
776                                         *(int *)data += mb->m_len;
777                         } else
778                                 *(int *)data = 0;
779                         splx(s);
780                         break;
781
782                 case FIOSETOWN:
783                         return (fsetown(*(int *)data, &tp->tap_sigio));
784
785                 case FIOGETOWN:
786                         *(int *)data = fgetown(&tp->tap_sigio);
787                         return (0);
788
789                 /* this is deprecated, FIOSETOWN should be used instead */
790                 case TIOCSPGRP:
791                         return (fsetown(-(*(int *)data), &tp->tap_sigio));
792
793                 /* this is deprecated, FIOGETOWN should be used instead */
794                 case TIOCGPGRP:
795                         *(int *)data = -fgetown(&tp->tap_sigio);
796                         return (0);
797
798                 /* VMware/VMnet port ioctl's */
799
800                 case SIOCGIFFLAGS:      /* get ifnet flags */
801                         bcopy(&ifp->if_flags, data, sizeof(ifp->if_flags));
802                         break;
803
804 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
805     defined(COMPAT_FREEBSD4)
806                 case _IO('V', 0):
807                         ival = IOCPARM_IVAL(data);
808                         data = (caddr_t)&ival;
809                         /* FALLTHROUGH */
810 #endif
811                 case VMIO_SIOCSIFFLAGS: /* VMware/VMnet SIOCSIFFLAGS */
812                         f = *(int *)data;
813                         f &= 0x0fff;
814                         f &= ~IFF_CANTCHANGE;
815                         f |= IFF_UP;
816
817                         s = splimp();
818                         ifp->if_flags = f | (ifp->if_flags & IFF_CANTCHANGE);
819                         splx(s);
820                         break;
821
822                 case OSIOCGIFADDR:      /* get MAC address of the remote side */
823                 case SIOCGIFADDR:
824                         mtx_lock(&tp->tap_mtx);
825                         bcopy(tp->ether_addr, data, sizeof(tp->ether_addr));
826                         mtx_unlock(&tp->tap_mtx);
827                         break;
828
829                 case SIOCSIFADDR:       /* set MAC address of the remote side */
830                         mtx_lock(&tp->tap_mtx);
831                         bcopy(data, tp->ether_addr, sizeof(tp->ether_addr));
832                         mtx_unlock(&tp->tap_mtx);
833                         break;
834
835                 default:
836                         return (ENOTTY);
837         }
838         return (0);
839 } /* tapioctl */
840
841
842 /*
843  * tapread
844  *
845  * the cdevsw read interface - reads a packet at a time, or at
846  * least as much of a packet as can be read
847  */
848 static int
849 tapread(struct cdev *dev, struct uio *uio, int flag)
850 {
851         struct tap_softc        *tp = dev->si_drv1;
852         struct ifnet            *ifp = tp->tap_ifp;
853         struct mbuf             *m = NULL;
854         int                      error = 0, len, s;
855
856         TAPDEBUG("%s reading, minor = %#x\n", ifp->if_xname, dev2unit(dev));
857
858         mtx_lock(&tp->tap_mtx);
859         if ((tp->tap_flags & TAP_READY) != TAP_READY) {
860                 mtx_unlock(&tp->tap_mtx);
861
862                 /* Unlocked read. */
863                 TAPDEBUG("%s not ready. minor = %#x, tap_flags = 0x%x\n",
864                         ifp->if_xname, dev2unit(dev), tp->tap_flags);
865
866                 return (EHOSTDOWN);
867         }
868
869         tp->tap_flags &= ~TAP_RWAIT;
870         mtx_unlock(&tp->tap_mtx);
871
872         /* sleep until we get a packet */
873         do {
874                 s = splimp();
875                 IF_DEQUEUE(&ifp->if_snd, m);
876                 splx(s);
877
878                 if (m == NULL) {
879                         if (flag & O_NONBLOCK)
880                                 return (EWOULDBLOCK);
881
882                         mtx_lock(&tp->tap_mtx);
883                         tp->tap_flags |= TAP_RWAIT;
884                         mtx_unlock(&tp->tap_mtx);
885                         error = tsleep(tp,PCATCH|(PZERO+1),"taprd",0);
886                         if (error)
887                                 return (error);
888                 }
889         } while (m == NULL);
890
891         /* feed packet to bpf */
892         BPF_MTAP(ifp, m);
893
894         /* xfer packet to user space */
895         while ((m != NULL) && (uio->uio_resid > 0) && (error == 0)) {
896                 len = min(uio->uio_resid, m->m_len);
897                 if (len == 0)
898                         break;
899
900                 error = uiomove(mtod(m, void *), len, uio);
901                 m = m_free(m);
902         }
903
904         if (m != NULL) {
905                 TAPDEBUG("%s dropping mbuf, minor = %#x\n", ifp->if_xname, 
906                         dev2unit(dev));
907                 m_freem(m);
908         }
909
910         return (error);
911 } /* tapread */
912
913
914 /*
915  * tapwrite
916  *
917  * the cdevsw write interface - an atomic write is a packet - or else!
918  */
919 static int
920 tapwrite(struct cdev *dev, struct uio *uio, int flag)
921 {
922         struct ether_header     *eh;
923         struct tap_softc        *tp = dev->si_drv1;
924         struct ifnet            *ifp = tp->tap_ifp;
925         struct mbuf             *m;
926
927         TAPDEBUG("%s writting, minor = %#x\n", 
928                 ifp->if_xname, dev2unit(dev));
929
930         if (uio->uio_resid == 0)
931                 return (0);
932
933         if ((uio->uio_resid < 0) || (uio->uio_resid > TAPMRU)) {
934                 TAPDEBUG("%s invalid packet len = %zd, minor = %#x\n",
935                         ifp->if_xname, uio->uio_resid, dev2unit(dev));
936
937                 return (EIO);
938         }
939
940         if ((m = m_uiotombuf(uio, M_DONTWAIT, 0, ETHER_ALIGN,
941             M_PKTHDR)) == NULL) {
942                 ifp->if_ierrors ++;
943                 return (ENOBUFS);
944         }
945
946         m->m_pkthdr.rcvif = ifp;
947
948         /*
949          * Only pass a unicast frame to ether_input(), if it would actually
950          * have been received by non-virtual hardware.
951          */
952         if (m->m_len < sizeof(struct ether_header)) {
953                 m_freem(m);
954                 return (0);
955         }
956         eh = mtod(m, struct ether_header *);
957
958         if (eh && (ifp->if_flags & IFF_PROMISC) == 0 &&
959             !ETHER_IS_MULTICAST(eh->ether_dhost) &&
960             bcmp(eh->ether_dhost, IF_LLADDR(ifp), ETHER_ADDR_LEN) != 0) {
961                 m_freem(m);
962                 return (0);
963         }
964
965         /* Pass packet up to parent. */
966         (*ifp->if_input)(ifp, m);
967         ifp->if_ipackets ++; /* ibytes are counted in parent */
968
969         return (0);
970 } /* tapwrite */
971
972
973 /*
974  * tappoll
975  *
976  * the poll interface, this is only useful on reads
977  * really. the write detect always returns true, write never blocks
978  * anyway, it either accepts the packet or drops it
979  */
980 static int
981 tappoll(struct cdev *dev, int events, struct thread *td)
982 {
983         struct tap_softc        *tp = dev->si_drv1;
984         struct ifnet            *ifp = tp->tap_ifp;
985         int                      s, revents = 0;
986
987         TAPDEBUG("%s polling, minor = %#x\n", 
988                 ifp->if_xname, dev2unit(dev));
989
990         s = splimp();
991         if (events & (POLLIN | POLLRDNORM)) {
992                 if (ifp->if_snd.ifq_len > 0) {
993                         TAPDEBUG("%s have data in queue. len = %d, " \
994                                 "minor = %#x\n", ifp->if_xname,
995                                 ifp->if_snd.ifq_len, dev2unit(dev));
996
997                         revents |= (events & (POLLIN | POLLRDNORM));
998                 } else {
999                         TAPDEBUG("%s waiting for data, minor = %#x\n",
1000                                 ifp->if_xname, dev2unit(dev));
1001
1002                         selrecord(td, &tp->tap_rsel);
1003                 }
1004         }
1005
1006         if (events & (POLLOUT | POLLWRNORM))
1007                 revents |= (events & (POLLOUT | POLLWRNORM));
1008
1009         splx(s);
1010         return (revents);
1011 } /* tappoll */
1012
1013
1014 /*
1015  * tap_kqfilter
1016  *
1017  * support for kevent() system call
1018  */
1019 static int
1020 tapkqfilter(struct cdev *dev, struct knote *kn)
1021 {
1022         int                      s;
1023         struct tap_softc        *tp = dev->si_drv1;
1024         struct ifnet            *ifp = tp->tap_ifp;
1025
1026         s = splimp();
1027         switch (kn->kn_filter) {
1028         case EVFILT_READ:
1029                 TAPDEBUG("%s kqfilter: EVFILT_READ, minor = %#x\n",
1030                         ifp->if_xname, dev2unit(dev));
1031                 kn->kn_fop = &tap_read_filterops;
1032                 break;
1033
1034         case EVFILT_WRITE:
1035                 TAPDEBUG("%s kqfilter: EVFILT_WRITE, minor = %#x\n",
1036                         ifp->if_xname, dev2unit(dev));
1037                 kn->kn_fop = &tap_write_filterops;
1038                 break;
1039
1040         default:
1041                 TAPDEBUG("%s kqfilter: invalid filter, minor = %#x\n",
1042                         ifp->if_xname, dev2unit(dev));
1043                 splx(s);
1044                 return (EINVAL);
1045                 /* NOT REACHED */
1046         }
1047         splx(s);
1048
1049         kn->kn_hook = (caddr_t) dev;
1050         knlist_add(&tp->tap_rsel.si_note, kn, 0);
1051
1052         return (0);
1053 } /* tapkqfilter */
1054
1055
1056 /*
1057  * tap_kqread
1058  * 
1059  * Return true if there is data in the interface queue
1060  */
1061 static int
1062 tapkqread(struct knote *kn, long hint)
1063 {
1064         int                      ret, s;
1065         struct cdev             *dev = (struct cdev *)(kn->kn_hook);
1066         struct tap_softc        *tp = dev->si_drv1;
1067         struct ifnet            *ifp = tp->tap_ifp;
1068
1069         s = splimp();
1070         if ((kn->kn_data = ifp->if_snd.ifq_len) > 0) {
1071                 TAPDEBUG("%s have data in queue. len = %d, minor = %#x\n",
1072                         ifp->if_xname, ifp->if_snd.ifq_len, dev2unit(dev));
1073                 ret = 1;
1074         } else {
1075                 TAPDEBUG("%s waiting for data, minor = %#x\n",
1076                         ifp->if_xname, dev2unit(dev));
1077                 ret = 0;
1078         }
1079         splx(s);
1080
1081         return (ret);
1082 } /* tapkqread */
1083
1084
1085 /*
1086  * tap_kqwrite
1087  *
1088  * Always can write. Return the MTU in kn->data
1089  */
1090 static int
1091 tapkqwrite(struct knote *kn, long hint)
1092 {
1093         int                      s;
1094         struct tap_softc        *tp = ((struct cdev *) kn->kn_hook)->si_drv1;
1095         struct ifnet            *ifp = tp->tap_ifp;
1096
1097         s = splimp();
1098         kn->kn_data = ifp->if_mtu;
1099         splx(s);
1100
1101         return (1);
1102 } /* tapkqwrite */
1103
1104
1105 static void
1106 tapkqdetach(struct knote *kn)
1107 {
1108         struct tap_softc        *tp = ((struct cdev *) kn->kn_hook)->si_drv1;
1109
1110         knlist_remove(&tp->tap_rsel.si_note, kn, 0);
1111 } /* tapkqdetach */
1112