nrelease - fix/improve livecd
[dragonfly.git] / sys / net / tap / 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: src/sys/net/if_tap.c,v 1.3.2.3 2002/04/14 21:41:48 luigi Exp $
35  * $Id: if_tap.c,v 0.21 2000/07/23 21:46:02 max Exp $
36  */
37
38 #include "opt_inet.h"
39
40 #include <sys/param.h>
41 #include <sys/conf.h>
42 #include <sys/device.h>
43 #include <sys/filedesc.h>
44 #include <sys/filio.h>
45 #include <sys/kernel.h>
46 #include <sys/malloc.h>
47 #include <sys/mbuf.h>
48 #include <sys/proc.h>
49 #include <sys/caps.h>
50 #include <sys/signalvar.h>
51 #include <sys/socket.h>
52 #include <sys/sockio.h>
53 #include <sys/sysctl.h>
54 #include <sys/systm.h>
55 #include <sys/ttycom.h>
56 #include <sys/uio.h>
57 #include <sys/vnode.h>
58 #include <sys/serialize.h>
59 #include <sys/thread2.h>
60 #include <sys/mplock2.h>
61 #include <sys/devfs.h>
62 #include <sys/queue.h>
63
64 #include <net/bpf.h>
65 #include <net/ethernet.h>
66 #include <net/if.h>
67 #include <net/if_types.h>
68 #include <net/if_arp.h>
69 #include <net/if_clone.h>
70 #include <net/if_media.h>
71 #include <net/ifq_var.h>
72 #include <net/route.h>
73
74 #include <netinet/in.h>
75
76 #include "if_tapvar.h"
77 #include "if_tap.h"
78
79 #define TAP_IFFLAGS     (IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST)
80
81 #define TAP             "tap"
82 #define TAPDEBUG        if (tapdebug) if_printf
83
84 /* module */
85 static int              tapmodevent(module_t, int, void *);
86
87 /* device */
88 static struct tap_softc *tapcreate(cdev_t, int);
89 static void             tapdestroy(struct tap_softc *);
90
91 /* clone */
92 static int              tap_clone_create(struct if_clone *, int,
93                                          caddr_t, caddr_t);
94 static int              tap_clone_destroy(struct ifnet *);
95
96 /* network interface */
97 static void             tapifinit(void *);
98 static void             tapifstart(struct ifnet *, struct ifaltq_subque *);
99 static int              tapifioctl(struct ifnet *, u_long, caddr_t,
100                                    struct ucred *);
101 static void             tapifstop(struct tap_softc *, int);
102 static void             tapifflags(struct tap_softc *);
103
104 /* character device */
105 static d_open_t         tapopen;
106 static d_clone_t        tapclone;
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_kqfilter_t     tapkqfilter;
112
113 static struct dev_ops   tap_ops = {
114         { TAP, 0, 0 },
115         .d_open =       tapopen,
116         .d_close =      tapclose,
117         .d_read =       tapread,
118         .d_write =      tapwrite,
119         .d_ioctl =      tapioctl,
120         .d_kqfilter =   tapkqfilter
121 };
122
123 /* kqueue support */
124 static void             tap_filter_detach(struct knote *);
125 static int              tap_filter_read(struct knote *, long);
126 static int              tap_filter_write(struct knote *, long);
127
128 static struct filterops tapread_filtops = {
129         FILTEROP_ISFD,
130         NULL,
131         tap_filter_detach,
132         tap_filter_read
133 };
134 static struct filterops tapwrite_filtops = {
135         FILTEROP_ISFD,
136         NULL,
137         tap_filter_detach,
138         tap_filter_write
139 };
140
141 static int              tapdebug = 0;           /* debug flag */
142 static int              taprefcnt = 0;          /* module ref. counter */
143 static int              tapuopen = 0;           /* allow user open() */
144 static int              tapuponopen = 0;        /* IFF_UP when opened */
145
146 static MALLOC_DEFINE(M_TAP, TAP, "Ethernet tunnel interface");
147
148 static DEVFS_DEFINE_CLONE_BITMAP(tap);
149
150 struct if_clone tap_cloner = IF_CLONE_INITIALIZER(
151         TAP, tap_clone_create, tap_clone_destroy, 0, IF_MAXUNIT);
152
153 static SLIST_HEAD(,tap_softc) tap_listhead =
154         SLIST_HEAD_INITIALIZER(&tap_listhead);
155
156 SYSCTL_INT(_debug, OID_AUTO, if_tap_debug, CTLFLAG_RW, &tapdebug, 0, "");
157 SYSCTL_DECL(_net_link);
158 SYSCTL_NODE(_net_link, OID_AUTO, tap, CTLFLAG_RW, 0,
159             "Ethernet tunnel software network interface");
160 SYSCTL_INT(_net_link_tap, OID_AUTO, user_open, CTLFLAG_RW, &tapuopen, 0,
161            "Allow user to open /dev/tap (based on node permissions)");
162 SYSCTL_INT(_net_link_tap, OID_AUTO, up_on_open, CTLFLAG_RW, &tapuponopen, 0,
163            "Bring interface up when /dev/tap is opened");
164 SYSCTL_INT(_net_link_tap, OID_AUTO, debug, CTLFLAG_RW, &tapdebug, 0, "");
165 SYSCTL_INT(_net_link_tap, OID_AUTO, refcnt, CTLFLAG_RD, &taprefcnt, 0,
166            "Number of opened devices");
167
168 DEV_MODULE(if_tap, tapmodevent, NULL);
169
170 /*
171  * tapmodevent
172  *
173  * module event handler
174  */
175 static int
176 tapmodevent(module_t mod, int type, void *data)
177 {
178         static cdev_t dev = NULL;
179         struct tap_softc *sc, *sc_tmp;
180
181         switch (type) {
182         case MOD_LOAD:
183                 dev = make_autoclone_dev(&tap_ops, &DEVFS_CLONE_BITMAP(tap),
184                                          tapclone, UID_ROOT, GID_WHEEL,
185                                          0600, TAP);
186                 SLIST_INIT(&tap_listhead);
187                 if_clone_attach(&tap_cloner);
188                 break;
189
190         case MOD_UNLOAD:
191                 if (taprefcnt > 0)
192                         return (EBUSY);
193
194                 if_clone_detach(&tap_cloner);
195
196                 SLIST_FOREACH_MUTABLE(sc, &tap_listhead, tap_link, sc_tmp)
197                         tapdestroy(sc);
198
199                 dev_ops_remove_all(&tap_ops);
200                 destroy_autoclone_dev(dev, &DEVFS_CLONE_BITMAP(tap));
201                 break;
202
203         default:
204                 return (EOPNOTSUPP);
205         }
206
207         return (0);
208 }
209
210
211 /*
212  * Create or clone an interface
213  */
214 static struct tap_softc *
215 tapcreate(cdev_t dev, int flags)
216 {
217         struct tap_softc *sc;
218         struct ifnet *ifp;
219         uint8_t ether_addr[ETHER_ADDR_LEN];
220         int unit = minor(dev);
221
222         sc = kmalloc(sizeof(*sc), M_TAP, M_WAITOK | M_ZERO);
223         dev->si_drv1 = sc;
224         sc->tap_dev = dev;
225         sc->tap_flags |= flags;
226
227         reference_dev(dev); /* device association */
228
229         /* generate fake MAC address: 00 bd xx xx xx unit_no */
230         ether_addr[0] = 0x00;
231         ether_addr[1] = 0xbd;
232         bcopy(&ticks, &ether_addr[2], 3);
233         ether_addr[5] = (u_char)unit;
234
235         /* fill the rest and attach interface */
236         ifp = &sc->tap_if;
237         if_initname(ifp, TAP, unit);
238         ifp->if_type = IFT_ETHER;
239         ifp->if_init = tapifinit;
240         ifp->if_start = tapifstart;
241         ifp->if_ioctl = tapifioctl;
242         ifp->if_mtu = ETHERMTU;
243         ifp->if_flags = TAP_IFFLAGS;
244         ifp->if_softc = sc;
245         ifq_set_maxlen(&ifp->if_snd, ifqmaxlen);
246         ifq_set_ready(&ifp->if_snd);
247
248         ether_ifattach(ifp, ether_addr, NULL);
249
250         sc->tap_flags |= TAP_INITED;
251         sc->tap_devq.ifq_maxlen = ifqmaxlen;
252
253         SLIST_INSERT_HEAD(&tap_listhead, sc, tap_link);
254
255         TAPDEBUG(ifp, "created, minor = %#x, flags = 0x%x\n",
256                  unit, sc->tap_flags);
257         return (sc);
258 }
259
260 static struct tap_softc *
261 tapfind(int unit)
262 {
263         struct tap_softc *sc;
264
265         SLIST_FOREACH(sc, &tap_listhead, tap_link) {
266                 if (minor(sc->tap_dev) == unit)
267                         return (sc);
268         }
269         return (NULL);
270 }
271
272 /*
273  * Create a new tap instance via ifconfig.
274  */
275 static int
276 tap_clone_create(struct if_clone *ifc __unused, int unit,
277                  caddr_t params __unused, caddr_t data)
278 {
279         struct tap_softc *sc;
280         cdev_t dev = (cdev_t)data;
281         int flags;
282
283         if (tapfind(unit) != NULL)
284                 return (EEXIST);
285
286         if (dev == NULL) {
287                 if (!devfs_clone_bitmap_chk(&DEVFS_CLONE_BITMAP(tap), unit)) {
288                         devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(tap), unit);
289                         dev = make_dev(&tap_ops, unit, UID_ROOT, GID_WHEEL,
290                                        0600, "%s%d", TAP, unit);
291                 } else {
292                         dev = devfs_find_device_by_name("%s%d", TAP, unit);
293                         if (dev == NULL)
294                                 return (ENOENT);
295                 }
296                 flags = TAP_MANUALMAKE;
297         } else {
298                 flags = 0;
299         }
300
301         if ((sc = tapcreate(dev, flags)) == NULL)
302                 return (ENOMEM);
303
304         sc->tap_flags |= TAP_CLONE;
305
306         TAPDEBUG(&sc->tap_if, "clone created, minor = %#x, flags = 0x%x\n",
307                  minor(sc->tap_dev), sc->tap_flags);
308
309         return (0);
310 }
311
312 /*
313  * Open the tap device.
314  */
315 static int
316 tapopen(struct dev_open_args *ap)
317 {
318         cdev_t dev = NULL;
319         struct tap_softc *sc = NULL;
320         struct ifnet *ifp = NULL;
321         int error;
322
323         if (tapuopen == 0 &&
324             (error = caps_priv_check(ap->a_cred, SYSCAP_RESTRICTEDROOT)) != 0)
325         {
326                 return (error);
327         }
328
329         get_mplock();
330
331         dev = ap->a_head.a_dev;
332         sc = dev->si_drv1;
333         if (sc == NULL && (sc = tapcreate(dev, 0)) == NULL) {
334                 rel_mplock();
335                 return (ENOMEM);
336         }
337         if (sc->tap_flags & TAP_OPEN) {
338                 rel_mplock();
339                 return (EBUSY);
340         }
341
342         ifp = &sc->tap_if;
343         bcopy(sc->arpcom.ac_enaddr, sc->ether_addr, sizeof(sc->ether_addr));
344
345         if (curthread->td_proc)
346                 fsetown(curthread->td_proc->p_pid, &sc->tap_sigtd);
347         sc->tap_flags |= TAP_OPEN;
348         taprefcnt++;
349
350         if (tapuponopen && (ifp->if_flags & IFF_UP) == 0) {
351                 crit_enter();
352                 if_up(ifp);
353                 crit_exit();
354
355                 ifnet_serialize_all(ifp);
356                 tapifflags(sc);
357                 ifnet_deserialize_all(ifp);
358
359                 sc->tap_flags |= TAP_CLOSEDOWN;
360         }
361
362         TAPDEBUG(ifp, "opened, minor = %#x. Module refcnt = %d\n",
363                  minor(dev), taprefcnt);
364
365         rel_mplock();
366         return (0);
367 }
368
369 static int
370 tapclone(struct dev_clone_args *ap)
371 {
372         char ifname[IFNAMSIZ];
373         int unit;
374
375         unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(tap), 0);
376         ksnprintf(ifname, IFNAMSIZ, "%s%d", TAP, unit);
377         ap->a_dev = make_only_dev(&tap_ops, unit, UID_ROOT, GID_WHEEL,
378                                   0600, "%s", ifname);
379
380         /*
381          * Use the if_clone framework to create cloned device/interface,
382          * so the two clone methods (autoclone device /dev/tap; ifconfig
383          * clone) are consistent and can be mix used.
384          *
385          * Need to pass the cdev_t because the device created by
386          * 'make_only_dev()' doesn't appear in '/dev' yet so that it can't
387          * be found by 'devfs_find_device_by_name()' in 'tap_clone_create()'.
388          */
389         return (if_clone_create(ifname, IFNAMSIZ, NULL, (caddr_t)ap->a_dev));
390 }
391
392 /*
393  * Close the tap device: bring the interface down & delete routing info.
394  */
395 static int
396 tapclose(struct dev_close_args *ap)
397 {
398         cdev_t dev = ap->a_head.a_dev;
399         struct tap_softc *sc = dev->si_drv1;
400         struct ifnet *ifp;
401         int unit = minor(dev);
402         int clear_flags = 0;
403         char ifname[IFNAMSIZ];
404
405         KASSERT(sc != NULL,
406                 ("try closing the already destroyed %s%d", TAP, unit));
407         ifp = &sc->tap_if;
408
409         get_mplock();
410
411         /* Junk all pending output */
412         ifq_purge_all(&ifp->if_snd);
413
414         /*
415          * If the interface is not cloned, we always bring it down.
416          *
417          * If the interface is cloned, then we bring it down during
418          * closing only if it was brought up during opening.
419          */
420         if ((sc->tap_flags & TAP_CLONE) == 0 ||
421             (sc->tap_flags & TAP_CLOSEDOWN)) {
422                 if (ifp->if_flags & IFF_UP)
423                         if_down(ifp);
424                 clear_flags = 1;
425         }
426         ifnet_serialize_all(ifp);
427         tapifstop(sc, clear_flags);
428         ifnet_deserialize_all(ifp);
429
430         if ((sc->tap_flags & TAP_MANUALMAKE) == 0) {
431                 if_purgeaddrs_nolink(ifp);
432
433                 EVENTHANDLER_INVOKE(ifnet_detach_event, ifp);
434
435                 /* Announce the departure of the interface. */
436                 rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
437         }
438
439         funsetown(&sc->tap_sigio);
440         sc->tap_sigio = NULL;
441         KNOTE(&sc->tap_rkq.ki_note, 0);
442
443         sc->tap_flags &= ~TAP_OPEN;
444         funsetown(&sc->tap_sigtd);
445         sc->tap_sigtd = NULL;
446
447         taprefcnt--;
448         if (taprefcnt < 0) {
449                 taprefcnt = 0;
450                 if_printf(ifp, ". Module refcnt = %d is out of sync! "
451                           "Force refcnt to be 0.\n", taprefcnt);
452         }
453
454         TAPDEBUG(ifp, "closed, minor = %#x. Module refcnt = %d\n",
455                  unit, taprefcnt);
456
457         /* Only auto-destroy if the interface was not manually created. */
458         if ((sc->tap_flags & TAP_MANUALMAKE) == 0) {
459                 ksnprintf(ifname, IFNAMSIZ, "%s%d", TAP, unit);
460                 if_clone_destroy(ifname);
461         }
462
463         rel_mplock();
464         return (0);
465 }
466
467
468 /*
469  * Destroy a tap instance: the interface and the associated device.
470  */
471 static void
472 tapdestroy(struct tap_softc *sc)
473 {
474         struct ifnet *ifp = &sc->tap_if;
475         cdev_t dev = sc->tap_dev;
476         int unit = minor(dev);
477
478         TAPDEBUG(ifp, "destroyed, minor = %#x. Module refcnt = %d\n",
479                  unit, taprefcnt);
480
481         ifnet_serialize_all(ifp);
482         tapifstop(sc, 1);
483         ifnet_deserialize_all(ifp);
484         ether_ifdetach(ifp);
485
486         sc->tap_dev = NULL;
487         dev->si_drv1 = NULL;
488         release_dev(dev); /* device disassociation */
489
490         /* Also destroy the cloned device */
491         destroy_dev(dev);
492         devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(tap), unit);
493
494         SLIST_REMOVE(&tap_listhead, sc, tap_softc, tap_link);
495         kfree(sc, M_TAP);
496 }
497
498
499 /*
500  * Destroy a tap instance that is created via ifconfig.
501  */
502 static int
503 tap_clone_destroy(struct ifnet *ifp)
504 {
505         struct tap_softc *sc = ifp->if_softc;
506
507         if (sc->tap_flags & TAP_OPEN)
508                 return (EBUSY);
509         if ((sc->tap_flags & TAP_CLONE) == 0)
510                 return (EINVAL);
511
512         TAPDEBUG(ifp, "clone destroyed, minor = %#x, flags = 0x%x\n",
513                  minor(sc->tap_dev), sc->tap_flags);
514         tapdestroy(sc);
515
516         return (0);
517 }
518
519
520 /*
521  * tapifinit
522  *
523  * Network interface initialization function (called with if serializer held)
524  *
525  * MPSAFE
526  */
527 static void
528 tapifinit(void *xtp)
529 {
530         struct tap_softc *sc = xtp;
531         struct ifnet *ifp = &sc->tap_if;
532         struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
533
534         TAPDEBUG(ifp, "initializing, minor = %#x, flags = 0x%x\n",
535                  minor(sc->tap_dev), sc->tap_flags);
536
537         ASSERT_IFNET_SERIALIZED_ALL(ifp);
538
539         tapifstop(sc, 1);
540
541         ifp->if_flags |= IFF_RUNNING;
542         ifsq_clr_oactive(ifsq);
543
544         /* attempt to start output */
545         tapifstart(ifp, ifsq);
546 }
547
548 static void
549 tapifflags(struct tap_softc *sc)
550 {
551         struct ifnet *ifp = &sc->tap_if;
552
553         ASSERT_IFNET_SERIALIZED_ALL(ifp);
554
555         if (ifp->if_flags & IFF_UP) {
556                 if ((ifp->if_flags & IFF_RUNNING) == 0)
557                         tapifinit(sc);
558         } else {
559                 tapifstop(sc, 1);
560         }
561 }
562
563 /*
564  * tapifioctl
565  *
566  * Process an ioctl request on network interface (called with if serializer
567  * held).
568  *
569  * MPSAFE
570  */
571 static int
572 tapifioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
573 {
574         struct tap_softc *sc = ifp->if_softc;
575         struct ifreq *ifr = NULL;
576         struct ifstat *ifs = NULL;
577         struct ifmediareq *ifmr = NULL;
578         int error = 0;
579         int dummy;
580
581         switch (cmd) {
582         case SIOCADDMULTI:
583         case SIOCDELMULTI:
584                 break;
585
586         case SIOCSIFMTU:
587                 ifr = (struct ifreq *)data;
588                 ifp->if_mtu = ifr->ifr_mtu;
589                 TAPDEBUG(ifp, "mtu set\n");
590                 break;
591
592         case SIOCSIFADDR:
593         case SIOCGIFADDR:
594                 error = ether_ioctl(ifp, cmd, data);
595                 break;
596
597         case SIOCSIFFLAGS:
598                 tapifflags(sc);
599                 break;
600
601         case SIOCGIFMEDIA:
602                 /*
603                  * The bridge code needs this when running the
604                  * spanning tree protocol.
605                  */
606                 ifmr = (struct ifmediareq *)data;
607                 dummy = ifmr->ifm_count;
608                 ifmr->ifm_count = 1;
609                 ifmr->ifm_status = IFM_AVALID;
610                 ifmr->ifm_active = IFM_ETHER;
611                 if (sc->tap_flags & TAP_OPEN)
612                         ifmr->ifm_status |= IFM_ACTIVE;
613                 ifmr->ifm_current = ifmr->ifm_active;
614                 if (dummy >= 1) {
615                         int media = IFM_ETHER;
616                         error = copyout(&media, ifmr->ifm_ulist, sizeof(int));
617                 }
618                 break;
619
620         case SIOCGIFSTATUS:
621                 ifs = (struct ifstat *)data;
622                 dummy = strlen(ifs->ascii);
623                 if ((sc->tap_flags & TAP_OPEN) && dummy < sizeof(ifs->ascii)) {
624                         if (sc->tap_sigtd && sc->tap_sigtd->sio_proc) {
625                                 ksnprintf(ifs->ascii + dummy,
626                                     sizeof(ifs->ascii) - dummy,
627                                     "\tOpened by pid %d\n",
628                                     (int)sc->tap_sigtd->sio_proc->p_pid);
629                         } else {
630                                 ksnprintf(ifs->ascii + dummy,
631                                     sizeof(ifs->ascii) - dummy,
632                                     "\tOpened by <unknown>\n");
633                         }
634                 }
635                 break;
636
637         default:
638                 error = EINVAL;
639                 break;
640         }
641
642         return (error);
643 }
644
645 /*
646  * tapifstart
647  *
648  * Queue packets from higher level ready to put out (called with if serializer
649  * held)
650  *
651  * MPSAFE
652  */
653 static void
654 tapifstart(struct ifnet *ifp, struct ifaltq_subque *ifsq)
655 {
656         struct tap_softc *sc = ifp->if_softc;
657         struct ifqueue *ifq;
658         struct mbuf *m;
659         int has_data = 0;
660
661         ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
662         TAPDEBUG(ifp, "starting, minor = %#x\n", minor(sc->tap_dev));
663
664         if ((sc->tap_flags & TAP_READY) != TAP_READY) {
665                 TAPDEBUG(ifp, "not ready, minor = %#x, flags = 0x%x\n",
666                          minor(sc->tap_dev), sc->tap_flags);
667                 ifsq_purge(ifsq);
668                 return;
669         }
670
671         ifsq_set_oactive(ifsq);
672
673         ifq = &sc->tap_devq;
674         while ((m = ifsq_dequeue(ifsq)) != NULL) {
675                 if (IF_QFULL(ifq)) {
676                         IF_DROP(ifq);
677                         IFNET_STAT_INC(ifp, oerrors, 1);
678                         m_freem(m);
679                 } else {
680                         IF_ENQUEUE(ifq, m);
681                         IFNET_STAT_INC(ifp, opackets, 1);
682                         has_data = 1;
683                 }
684         }
685
686         if (has_data) {
687                 if (sc->tap_flags & TAP_RWAIT) {
688                         sc->tap_flags &= ~TAP_RWAIT;
689                         wakeup((caddr_t)sc);
690                 }
691
692                 KNOTE(&sc->tap_rkq.ki_note, 0);
693
694                 if ((sc->tap_flags & TAP_ASYNC) && (sc->tap_sigio != NULL)) {
695                         get_mplock();
696                         pgsigio(sc->tap_sigio, SIGIO, 0);
697                         rel_mplock();
698                 }
699         }
700
701         ifsq_clr_oactive(ifsq);
702 }
703
704 static void
705 tapifstop(struct tap_softc *sc, int clear_flags)
706 {
707         struct ifnet *ifp = &sc->tap_if;
708
709         ASSERT_IFNET_SERIALIZED_ALL(ifp);
710         IF_DRAIN(&sc->tap_devq);
711         sc->tap_flags &= ~TAP_CLOSEDOWN;
712         if (clear_flags) {
713                 ifp->if_flags &= ~IFF_RUNNING;
714                 ifsq_clr_oactive(ifq_get_subq_default(&ifp->if_snd));
715         }
716 }
717
718 /*
719  * tapioctl
720  *
721  * The ops interface is now pretty minimal.  Called via fileops with nothing
722  * held.
723  *
724  * MPSAFE
725  */
726 static int
727 tapioctl(struct dev_ioctl_args *ap)
728 {
729         cdev_t dev = ap->a_head.a_dev;
730         caddr_t data = ap->a_data;
731         struct tap_softc *sc = dev->si_drv1;
732         struct ifnet *ifp = &sc->tap_if;
733         struct ifreq *ifr;
734         struct tapinfo *tapp = NULL;
735         struct mbuf *mb;
736         int error;
737
738         ifnet_serialize_all(ifp);
739         error = 0;
740
741         switch (ap->a_cmd) {
742         case TAPSIFINFO:
743                 tapp = (struct tapinfo *)data;
744                 if (ifp->if_type != tapp->type)
745                         return (EPROTOTYPE);
746                 ifp->if_mtu = tapp->mtu;
747                 ifp->if_baudrate = tapp->baudrate;
748                 break;
749
750         case TAPGIFINFO:
751                 tapp = (struct tapinfo *)data;
752                 tapp->mtu = ifp->if_mtu;
753                 tapp->type = ifp->if_type;
754                 tapp->baudrate = ifp->if_baudrate;
755                 break;
756
757         case TAPGIFNAME:
758                 ifr = (struct ifreq *)data;
759                 strlcpy(ifr->ifr_name, ifp->if_xname, IFNAMSIZ);
760                 break;
761
762         case TAPSDEBUG:
763                 tapdebug = *(int *)data;
764                 break;
765
766         case TAPGDEBUG:
767                 *(int *)data = tapdebug;
768                 break;
769
770         case FIOASYNC:
771                 if (*(int *)data)
772                         sc->tap_flags |= TAP_ASYNC;
773                 else
774                         sc->tap_flags &= ~TAP_ASYNC;
775                 break;
776
777         case FIONREAD:
778                 /* Take a look at devq first */
779                 IF_POLL(&sc->tap_devq, mb);
780                 if (mb != NULL) {
781                         *(int *)data = 0;
782                         for(; mb != NULL; mb = mb->m_next)
783                                 *(int *)data += mb->m_len;
784                 } else {
785                         *(int *)data = ifsq_poll_pktlen(
786                             ifq_get_subq_default(&ifp->if_snd));
787                 }
788                 break;
789
790         case FIOSETOWN:
791                 error = fsetown(*(int *)data, &sc->tap_sigio);
792                 if (error == 0)
793                         error = fsetown(*(int *)data, &sc->tap_sigtd);
794                 break;
795
796         case FIOGETOWN:
797                 *(int *)data = fgetown(&sc->tap_sigio);
798                 break;
799
800         /* this is deprecated, FIOSETOWN should be used instead */
801         case TIOCSPGRP:
802                 error = fsetown(-(*(int *)data), &sc->tap_sigio);
803                 break;
804
805         /* this is deprecated, FIOGETOWN should be used instead */
806         case TIOCGPGRP:
807                 *(int *)data = -fgetown(&sc->tap_sigio);
808                 break;
809
810         /*
811          * Support basic control of the network interface via the device file.
812          * e.g., vke(4) currently uses the 'SIOCGIFADDR' ioctl.
813          */
814
815         case SIOCGIFFLAGS:
816                 bcopy(&ifp->if_flags, data, sizeof(ifp->if_flags));
817                 break;
818
819         case SIOCGIFADDR:
820                 bcopy(sc->ether_addr, data, sizeof(sc->ether_addr));
821                 break;
822
823         case SIOCSIFADDR:
824                 bcopy(data, sc->ether_addr, sizeof(sc->ether_addr));
825                 break;
826
827         default:
828                 error = ENOTTY;
829                 break;
830         }
831
832         ifnet_deserialize_all(ifp);
833         return (error);
834 }
835
836
837 /*
838  * tapread
839  *
840  * The ops read interface - reads a packet at a time, or at
841  * least as much of a packet as can be read.
842  *
843  * Called from the fileops interface with nothing held.
844  *
845  * MPSAFE
846  */
847 static int
848 tapread(struct dev_read_args *ap)
849 {
850         cdev_t dev = ap->a_head.a_dev;
851         struct uio *uio = ap->a_uio;
852         struct tap_softc *sc = dev->si_drv1;
853         struct ifnet *ifp = &sc->tap_if;
854         struct mbuf *m0 = NULL;
855         int error = 0, len;
856
857         TAPDEBUG(ifp, "reading, minor = %#x\n", minor(dev));
858
859         if ((sc->tap_flags & TAP_READY) != TAP_READY) {
860                 TAPDEBUG(ifp, "not ready, minor = %#x, flags = 0x%x\n",
861                          minor(dev), sc->tap_flags);
862
863                 return (EHOSTDOWN);
864         }
865
866         sc->tap_flags &= ~TAP_RWAIT;
867
868         /* sleep until we get a packet */
869         do {
870                 ifnet_serialize_all(ifp);
871                 IF_DEQUEUE(&sc->tap_devq, m0);
872                 if (m0 == NULL) {
873                         if (ap->a_ioflag & IO_NDELAY) {
874                                 ifnet_deserialize_all(ifp);
875                                 return (EWOULDBLOCK);
876                         }
877                         sc->tap_flags |= TAP_RWAIT;
878                         tsleep_interlock(sc, PCATCH);
879                         ifnet_deserialize_all(ifp);
880                         error = tsleep(sc, PCATCH | PINTERLOCKED, "taprd", 0);
881                         if (error)
882                                 return (error);
883                 } else {
884                         ifnet_deserialize_all(ifp);
885                 }
886         } while (m0 == NULL);
887
888         BPF_MTAP(ifp, m0);
889
890         /* xfer packet to user space */
891         while ((m0 != NULL) && (uio->uio_resid > 0) && (error == 0)) {
892                 len = (int)szmin(uio->uio_resid, m0->m_len);
893                 if (len == 0)
894                         break;
895
896                 error = uiomove(mtod(m0, caddr_t), (size_t)len, uio);
897                 m0 = m_free(m0);
898         }
899
900         if (m0 != NULL) {
901                 TAPDEBUG(ifp, "dropping mbuf, minor = %#x\n", minor(dev));
902                 m_freem(m0);
903         }
904
905         return (error);
906 }
907
908 /*
909  * tapwrite
910  *
911  * The ops write interface - an atomic write is a packet - or else!
912  *
913  * Called from the fileops interface with nothing held.
914  *
915  * MPSAFE
916  */
917 static int
918 tapwrite(struct dev_write_args *ap)
919 {
920         cdev_t dev = ap->a_head.a_dev;
921         struct uio *uio = ap->a_uio;
922         struct tap_softc *sc = dev->si_drv1;
923         struct ifnet *ifp = &sc->tap_if;
924         struct mbuf *top = NULL, **mp = NULL, *m = NULL;
925         int error;
926         size_t tlen, mlen;
927
928         TAPDEBUG(ifp, "writing, minor = %#x\n", minor(dev));
929
930         if ((sc->tap_flags & TAP_READY) != TAP_READY) {
931                 TAPDEBUG(ifp, "not ready, minor = %#x, flags = 0x%x\n",
932                          minor(dev), sc->tap_flags);
933                 return (EHOSTDOWN);
934         }
935
936         if (uio->uio_resid == 0)
937                 return (0);
938
939         if (uio->uio_resid > TAPMRU) {
940                 TAPDEBUG(ifp, "invalid packet len = %zu, minor = %#x\n",
941                          uio->uio_resid, minor(dev));
942
943                 return (EIO);
944         }
945         tlen = uio->uio_resid;
946
947         /* get a header mbuf */
948         MGETHDR(m, M_WAITOK, MT_DATA);
949         mlen = MHLEN;
950
951         top = NULL;
952         mp = &top;
953         error = 0;
954
955         while (error == 0 && uio->uio_resid > 0) {
956                 m->m_len = (int)szmin(mlen, uio->uio_resid);
957                 error = uiomove(mtod(m, caddr_t), (size_t)m->m_len, uio);
958                 *mp = m;
959                 mp = &m->m_next;
960                 if (uio->uio_resid > 0) {
961                         MGET(m, M_WAITOK, MT_DATA);
962                         mlen = MLEN;
963                 }
964         }
965         if (error) {
966                 IFNET_STAT_INC(ifp, ierrors, 1);
967                 if (top)
968                         m_freem(top);
969                 return (error);
970         }
971
972         top->m_pkthdr.len = (int)tlen;
973         top->m_pkthdr.rcvif = ifp;
974
975         /*
976          * Ethernet bridge and bpf are handled in ether_input
977          *
978          * adjust mbuf and give packet to the ether_input
979          */
980         ifnet_serialize_all(ifp);
981         ifp->if_input(ifp, top, NULL, -1);
982         IFNET_STAT_INC(ifp, ipackets, 1); /* ibytes are counted in ether_input */
983         ifnet_deserialize_all(ifp);
984
985         return (0);
986 }
987
988
989 /*
990  * tapkqfilter - called from the fileops interface with nothing held
991  *
992  * MPSAFE
993  */
994 static int
995 tapkqfilter(struct dev_kqfilter_args *ap)
996 {
997         cdev_t dev = ap->a_head.a_dev;
998         struct knote *kn = ap->a_kn;
999         struct tap_softc *sc = dev->si_drv1;
1000         struct klist *list;
1001
1002         list = &sc->tap_rkq.ki_note;
1003         ap->a_result =0;
1004
1005         switch (kn->kn_filter) {
1006         case EVFILT_READ:
1007                 kn->kn_fop = &tapread_filtops;
1008                 kn->kn_hook = (void *)sc;
1009                 break;
1010         case EVFILT_WRITE:
1011                 kn->kn_fop = &tapwrite_filtops;
1012                 kn->kn_hook = (void *)sc;
1013                 break;
1014         default:
1015                 ap->a_result = EOPNOTSUPP;
1016                 return (0);
1017         }
1018
1019         knote_insert(list, kn);
1020         return (0);
1021 }
1022
1023 static int
1024 tap_filter_read(struct knote *kn, long hint)
1025 {
1026         struct tap_softc *sc = (struct tap_softc *)kn->kn_hook;
1027
1028         if (IF_QEMPTY(&sc->tap_devq) == 0)      /* XXX serializer */
1029                 return (1);
1030         else
1031                 return (0);
1032 }
1033
1034 static int
1035 tap_filter_write(struct knote *kn, long hint)
1036 {
1037         /* Always ready for a write */
1038         return (1);
1039 }
1040
1041 static void
1042 tap_filter_detach(struct knote *kn)
1043 {
1044         struct tap_softc *sc = (struct tap_softc *)kn->kn_hook;
1045
1046         knote_remove(&sc->tap_rkq.ki_note, kn);
1047 }