if_tap: Disallow to destroy an opened device
[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 #include "use_tap.h"
40
41 #include <sys/param.h>
42 #include <sys/conf.h>
43 #include <sys/device.h>
44 #include <sys/filedesc.h>
45 #include <sys/filio.h>
46 #include <sys/kernel.h>
47 #include <sys/malloc.h>
48 #include <sys/mbuf.h>
49 #include <sys/proc.h>
50 #include <sys/priv.h>
51 #include <sys/signalvar.h>
52 #include <sys/socket.h>
53 #include <sys/sockio.h>
54 #include <sys/sysctl.h>
55 #include <sys/systm.h>
56 #include <sys/ttycom.h>
57 #include <sys/uio.h>
58 #include <sys/vnode.h>
59 #include <sys/serialize.h>
60 #include <sys/thread2.h>
61 #include <sys/mplock2.h>
62 #include <sys/devfs.h>
63 #include <sys/queue.h>
64
65 #include <net/bpf.h>
66 #include <net/ethernet.h>
67 #include <net/if.h>
68 #include <net/if_types.h>
69 #include <net/if_arp.h>
70 #include <net/if_clone.h>
71 #include <net/if_media.h>
72 #include <net/ifq_var.h>
73 #include <net/route.h>
74
75 #include <netinet/in.h>
76
77 #include "if_tapvar.h"
78 #include "if_tap.h"
79
80 #define TAP_IFFLAGS     (IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST)
81
82 #if NTAP <= 1
83 #define TAP_PREALLOCATED_UNITS  4
84 #else
85 #define TAP_PREALLOCATED_UNITS  NTAP
86 #endif
87
88 #define TAP             "tap"
89 #define TAPDEBUG        if (tapdebug) if_printf
90
91 /* module */
92 static int              tapmodevent(module_t, int, void *);
93
94 /* device */
95 static struct tap_softc *tapcreate(cdev_t, int);
96 static void             tapdestroy(struct tap_softc *);
97
98 /* clone */
99 static int              tap_clone_create(struct if_clone *, int, caddr_t);
100 static int              tap_clone_destroy(struct ifnet *);
101
102 /* network interface */
103 static void             tapifinit(void *);
104 static void             tapifstart(struct ifnet *, struct ifaltq_subque *);
105 static int              tapifioctl(struct ifnet *, u_long, caddr_t,
106                                    struct ucred *);
107 static void             tapifstop(struct tap_softc *, int);
108 static void             tapifflags(struct tap_softc *);
109
110 /* character device */
111 static d_open_t         tapopen;
112 static d_clone_t        tapclone;
113 static d_close_t        tapclose;
114 static d_read_t         tapread;
115 static d_write_t        tapwrite;
116 static d_ioctl_t        tapioctl;
117 static d_kqfilter_t     tapkqfilter;
118
119 static struct dev_ops   tap_ops = {
120         { TAP, 0, 0 },
121         .d_open =       tapopen,
122         .d_close =      tapclose,
123         .d_read =       tapread,
124         .d_write =      tapwrite,
125         .d_ioctl =      tapioctl,
126         .d_kqfilter =   tapkqfilter
127 };
128
129 /* kqueue support */
130 static void             tap_filter_detach(struct knote *);
131 static int              tap_filter_read(struct knote *, long);
132 static int              tap_filter_write(struct knote *, long);
133
134 static struct filterops tapread_filtops = {
135         FILTEROP_ISFD,
136         NULL,
137         tap_filter_detach,
138         tap_filter_read
139 };
140 static struct filterops tapwrite_filtops = {
141         FILTEROP_ISFD,
142         NULL,
143         tap_filter_detach,
144         tap_filter_write
145 };
146
147 static int              tapdebug = 0;           /* debug flag */
148 static int              taprefcnt = 0;          /* module ref. counter */
149 static int              tapuopen = 0;           /* allow user open() */
150 static int              tapuponopen = 0;        /* IFF_UP when opened */
151
152 static MALLOC_DEFINE(M_TAP, TAP, "Ethernet tunnel interface");
153
154 static DEVFS_DEFINE_CLONE_BITMAP(tap);
155
156 struct if_clone tap_cloner = IF_CLONE_INITIALIZER(
157         TAP, tap_clone_create, tap_clone_destroy, 0, IF_MAXUNIT);
158
159 static SLIST_HEAD(,tap_softc) tap_listhead =
160         SLIST_HEAD_INITIALIZER(&tap_listhead);
161
162 SYSCTL_INT(_debug, OID_AUTO, if_tap_debug, CTLFLAG_RW, &tapdebug, 0, "");
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, debug, CTLFLAG_RW, &tapdebug, 0, "");
171 SYSCTL_INT(_net_link_tap, OID_AUTO, refcnt, CTLFLAG_RD, &taprefcnt, 0,
172            "Number of opened devices");
173
174 DEV_MODULE(if_tap, tapmodevent, NULL);
175
176 /*
177  * tapmodevent
178  *
179  * module event handler
180  */
181 static int
182 tapmodevent(module_t mod, int type, void *data)
183 {
184         static cdev_t dev = NULL;
185         struct tap_softc *sc, *sc_tmp;
186         int i;
187
188         switch (type) {
189         case MOD_LOAD:
190                 dev = make_autoclone_dev(&tap_ops, &DEVFS_CLONE_BITMAP(tap),
191                                          tapclone, UID_ROOT, GID_WHEEL,
192                                          0600, TAP);
193                 SLIST_INIT(&tap_listhead);
194                 if_clone_attach(&tap_cloner);
195
196                 for (i = 0; i < TAP_PREALLOCATED_UNITS; ++i) {
197                         make_dev(&tap_ops, i, UID_ROOT, GID_WHEEL,
198                                  0600, "%s%d", TAP, i);
199                         devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(tap), i);
200                 }
201                 break;
202
203         case MOD_UNLOAD:
204                 if (taprefcnt > 0)
205                         return (EBUSY);
206
207                 if_clone_detach(&tap_cloner);
208
209                 SLIST_FOREACH_MUTABLE(sc, &tap_listhead, tap_link, sc_tmp)
210                         tapdestroy(sc);
211
212                 dev_ops_remove_all(&tap_ops);
213                 destroy_autoclone_dev(dev, &DEVFS_CLONE_BITMAP(tap));
214                 break;
215
216         default:
217                 return (EOPNOTSUPP);
218         }
219
220         return (0);
221 }
222
223
224 /*
225  * Create or clone an interface
226  */
227 static struct tap_softc *
228 tapcreate(cdev_t dev, int flags)
229 {
230         struct tap_softc *sc;
231         struct ifnet *ifp;
232         uint8_t ether_addr[ETHER_ADDR_LEN];
233         int unit = minor(dev);
234
235         sc = kmalloc(sizeof(*sc), M_TAP, M_WAITOK | M_ZERO);
236         dev->si_drv1 = sc;
237         sc->tap_dev = dev;
238         sc->tap_flags |= flags;
239
240         reference_dev(dev); /* device association */
241
242         /* generate fake MAC address: 00 bd xx xx xx unit_no */
243         ether_addr[0] = 0x00;
244         ether_addr[1] = 0xbd;
245         bcopy(&ticks, &ether_addr[2], 3);
246         ether_addr[5] = (u_char)unit;
247
248         /* fill the rest and attach interface */
249         ifp = &sc->tap_if;
250         if_initname(ifp, TAP, unit);
251         ifp->if_type = IFT_ETHER;
252         ifp->if_init = tapifinit;
253         ifp->if_start = tapifstart;
254         ifp->if_ioctl = tapifioctl;
255         ifp->if_mtu = ETHERMTU;
256         ifp->if_flags = TAP_IFFLAGS;
257         ifp->if_softc = sc;
258         ifq_set_maxlen(&ifp->if_snd, ifqmaxlen);
259         ifq_set_ready(&ifp->if_snd);
260
261         ether_ifattach(ifp, ether_addr, NULL);
262
263         sc->tap_flags |= TAP_INITED;
264         sc->tap_devq.ifq_maxlen = ifqmaxlen;
265
266         SLIST_INSERT_HEAD(&tap_listhead, sc, tap_link);
267
268         TAPDEBUG(ifp, "created, minor = %#x, flags = 0x%x\n",
269                  unit, sc->tap_flags);
270         return (sc);
271 }
272
273 static struct tap_softc *
274 tapfind(int unit)
275 {
276         struct tap_softc *sc;
277
278         SLIST_FOREACH(sc, &tap_listhead, tap_link) {
279                 if (minor(sc->tap_dev) == unit)
280                         return (sc);
281         }
282         return (NULL);
283 }
284
285 /*
286  * Create a new tap instance via ifconfig.
287  */
288 static int
289 tap_clone_create(struct if_clone *ifc __unused, int unit,
290                  caddr_t param __unused)
291 {
292         struct tap_softc *sc;
293         cdev_t dev;
294
295         sc = tapfind(unit);
296         if (sc == NULL) {
297                 if (!devfs_clone_bitmap_chk(&DEVFS_CLONE_BITMAP(tap), unit)) {
298                         devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(tap), unit);
299                         dev = make_dev(&tap_ops, unit, UID_ROOT, GID_WHEEL,
300                                        0600, "%s%d", TAP, unit);
301                 } else {
302                         dev = devfs_find_device_by_name("%s%d", TAP, unit);
303                 }
304
305                 if (dev == NULL)
306                         return (ENODEV);
307                 if ((sc = tapcreate(dev, TAP_MANUALMAKE)) == NULL)
308                         return (ENOMEM);
309         } else {
310                 dev = sc->tap_dev;
311         }
312
313         sc->tap_flags |= TAP_CLONE;
314         TAPDEBUG(&sc->tap_if, "clone created, minor = %#x, flags = 0x%x\n",
315                  minor(dev), sc->tap_flags);
316
317         return (0);
318 }
319
320 /*
321  * Open the tap device.
322  */
323 static int
324 tapopen(struct dev_open_args *ap)
325 {
326         cdev_t dev = NULL;
327         struct tap_softc *sc = NULL;
328         struct ifnet *ifp = NULL;
329         int error;
330
331         if (tapuopen == 0 &&
332             (error = priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) != 0)
333                 return (error);
334
335         get_mplock();
336         dev = ap->a_head.a_dev;
337         sc = dev->si_drv1;
338         if (sc == NULL && (sc = tapcreate(dev, TAP_MANUALMAKE)) == NULL) {
339                 rel_mplock();
340                 return (ENOMEM);
341         }
342         if (sc->tap_flags & TAP_OPEN) {
343                 rel_mplock();
344                 return (EBUSY);
345         }
346         ifp = &sc->tap_if;
347
348         if ((sc->tap_flags & TAP_CLONE) == 0) {
349                 EVENTHANDLER_INVOKE(ifnet_attach_event, ifp);
350
351                 /* Announce the return of the interface. */
352                 rt_ifannouncemsg(ifp, IFAN_ARRIVAL);
353         }
354
355         bcopy(sc->arpcom.ac_enaddr, sc->ether_addr, sizeof(sc->ether_addr));
356
357         if (curthread->td_proc)
358                 fsetown(curthread->td_proc->p_pid, &sc->tap_sigtd);
359         sc->tap_flags |= TAP_OPEN;
360         taprefcnt++;
361
362         if (tapuponopen && (ifp->if_flags & IFF_UP) == 0) {
363                 crit_enter();
364                 if_up(ifp);
365                 crit_exit();
366
367                 ifnet_serialize_all(ifp);
368                 tapifflags(sc);
369                 ifnet_deserialize_all(ifp);
370
371                 sc->tap_flags |= TAP_CLOSEDOWN;
372         }
373
374         TAPDEBUG(ifp, "opened, minor = %#x. Module refcnt = %d\n",
375                  minor(dev), taprefcnt);
376
377         rel_mplock();
378         return (0);
379 }
380
381 static int
382 tapclone(struct dev_clone_args *ap)
383 {
384         int unit;
385
386         unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(tap), 0);
387         ap->a_dev = make_only_dev(&tap_ops, unit, UID_ROOT, GID_WHEEL,
388                                   0600, "%s%d", TAP, unit);
389         if (tapcreate(ap->a_dev, 0) == NULL)
390                 return (ENOMEM);
391         else
392                 return (0);
393 }
394
395 /*
396  * Close the tap device: bring the interface down & delete routing info.
397  */
398 static int
399 tapclose(struct dev_close_args *ap)
400 {
401         cdev_t dev = ap->a_head.a_dev;
402         struct tap_softc *sc = dev->si_drv1;
403         struct ifnet *ifp;
404         int unit = minor(dev);
405         int clear_flags = 0;
406
407         KASSERT(sc != NULL,
408                 ("try closing the already destroyed %s%d", TAP, unit));
409         ifp = &sc->tap_if;
410
411         get_mplock();
412
413         /* Junk all pending output */
414         ifq_purge_all(&ifp->if_snd);
415
416         /*
417          * If the interface is not cloned, we always bring it down.
418          *
419          * If the interface is cloned, then we bring it down during
420          * closing only if it was brought up during opening.
421          */
422         if ((sc->tap_flags & TAP_CLONE) == 0 ||
423             (sc->tap_flags & TAP_CLOSEDOWN)) {
424                 if (ifp->if_flags & IFF_UP)
425                         if_down(ifp);
426                 clear_flags = 1;
427         }
428         ifnet_serialize_all(ifp);
429         tapifstop(sc, clear_flags);
430         ifnet_deserialize_all(ifp);
431
432         if ((sc->tap_flags & TAP_CLONE) == 0) {
433                 if_purgeaddrs_nolink(ifp);
434
435                 EVENTHANDLER_INVOKE(ifnet_detach_event, ifp);
436
437                 /* Announce the departure of the interface. */
438                 rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
439         }
440
441         funsetown(&sc->tap_sigio);
442         sc->tap_sigio = NULL;
443         KNOTE(&sc->tap_rkq.ki_note, 0);
444
445         sc->tap_flags &= ~TAP_OPEN;
446         funsetown(&sc->tap_sigtd);
447         sc->tap_sigtd = NULL;
448
449         taprefcnt--;
450         if (taprefcnt < 0) {
451                 taprefcnt = 0;
452                 if_printf(ifp, ". Module refcnt = %d is out of sync! "
453                           "Force refcnt to be 0.\n", taprefcnt);
454         }
455
456         TAPDEBUG(ifp, "closed, minor = %#x. Module refcnt = %d\n",
457                  unit, taprefcnt);
458
459         /* Only auto-destroy if the interface was not manually created. */
460         if ((sc->tap_flags & TAP_MANUALMAKE) == 0 &&
461             unit >= TAP_PREALLOCATED_UNITS) {
462                 tapdestroy(sc);
463                 dev->si_drv1 = NULL;
464         }
465
466         rel_mplock();
467         return (0);
468 }
469
470
471 /*
472  * Destroy a tap instance: the interface and the associated device.
473  */
474 static void
475 tapdestroy(struct tap_softc *sc)
476 {
477         struct ifnet *ifp = &sc->tap_if;
478         cdev_t dev = sc->tap_dev;
479         int unit = minor(dev);
480
481         TAPDEBUG(ifp, "destroyed, minor = %#x. Module refcnt = %d\n",
482                  unit, taprefcnt);
483
484         ifnet_serialize_all(ifp);
485         tapifstop(sc, 1);
486         ifnet_deserialize_all(ifp);
487
488         ether_ifdetach(ifp);
489
490         sc->tap_dev = NULL;
491         dev->si_drv1 = NULL;
492         release_dev(dev); /* device disassociation */
493
494         /* Also destroy the cloned device */
495         if (unit >= TAP_PREALLOCATED_UNITS) {
496                 destroy_dev(dev);
497                 devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(tap), unit);
498         }
499
500         SLIST_REMOVE(&tap_listhead, sc, tap_softc, tap_link);
501         kfree(sc, M_TAP);
502 }
503
504
505 /*
506  * Destroy a tap instance that is created via ifconfig.
507  */
508 static int
509 tap_clone_destroy(struct ifnet *ifp)
510 {
511         struct tap_softc *sc = ifp->if_softc;
512
513         if (sc->tap_flags & TAP_OPEN)
514                 return (EBUSY);
515         if ((sc->tap_flags & TAP_CLONE) == 0)
516                 return (EINVAL);
517
518         TAPDEBUG(ifp, "clone destroyed, minor = %#x, flags = 0x%x\n",
519                  minor(sc->tap_dev), sc->tap_flags);
520         tapdestroy(sc);
521
522         return (0);
523 }
524
525
526 /*
527  * tapifinit
528  *
529  * Network interface initialization function (called with if serializer held)
530  *
531  * MPSAFE
532  */
533 static void
534 tapifinit(void *xtp)
535 {
536         struct tap_softc *sc = xtp;
537         struct ifnet *ifp = &sc->tap_if;
538         struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
539
540         TAPDEBUG(ifp, "initializing, minor = %#x, flags = 0x%x\n",
541                  minor(sc->tap_dev), sc->tap_flags);
542
543         ASSERT_IFNET_SERIALIZED_ALL(ifp);
544
545         tapifstop(sc, 1);
546
547         ifp->if_flags |= IFF_RUNNING;
548         ifsq_clr_oactive(ifsq);
549
550         /* attempt to start output */
551         tapifstart(ifp, ifsq);
552 }
553
554 static void
555 tapifflags(struct tap_softc *sc)
556 {
557         struct ifnet *ifp = &sc->tap_if;
558
559         ASSERT_IFNET_SERIALIZED_ALL(ifp);
560
561         if (ifp->if_flags & IFF_UP) {
562                 if ((ifp->if_flags & IFF_RUNNING) == 0)
563                         tapifinit(sc);
564         } else {
565                 tapifstop(sc, 1);
566         }
567 }
568
569 /*
570  * tapifioctl
571  *
572  * Process an ioctl request on network interface (called with if serializer
573  * held).
574  *
575  * MPSAFE
576  */
577 static int
578 tapifioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
579 {
580         struct tap_softc *sc = ifp->if_softc;
581         struct ifstat *ifs = NULL;
582         struct ifmediareq *ifmr = NULL;
583         int error = 0;
584         int dummy;
585
586         switch (cmd) {
587         case SIOCADDMULTI:
588         case SIOCDELMULTI:
589                 break;
590
591         case SIOCSIFADDR:
592         case SIOCGIFADDR:
593         case SIOCSIFMTU:
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                 break;
793
794         case FIOGETOWN:
795                 *(int *)data = fgetown(&sc->tap_sigio);
796                 break;
797
798         /* this is deprecated, FIOSETOWN should be used instead */
799         case TIOCSPGRP:
800                 error = fsetown(-(*(int *)data), &sc->tap_sigio);
801                 break;
802
803         /* this is deprecated, FIOGETOWN should be used instead */
804         case TIOCGPGRP:
805                 *(int *)data = -fgetown(&sc->tap_sigio);
806                 break;
807
808         /*
809          * Support basic control of the network interface via the device file.
810          * e.g., vke(4) currently uses the 'SIOCGIFADDR' ioctl.
811          */
812
813         case SIOCGIFFLAGS:
814                 bcopy(&ifp->if_flags, data, sizeof(ifp->if_flags));
815                 break;
816
817         case SIOCGIFADDR:
818                 bcopy(sc->ether_addr, data, sizeof(sc->ether_addr));
819                 break;
820
821         case SIOCSIFADDR:
822                 bcopy(data, sc->ether_addr, sizeof(sc->ether_addr));
823                 break;
824
825         default:
826                 error = ENOTTY;
827                 break;
828         }
829
830         ifnet_deserialize_all(ifp);
831         return (error);
832 }
833
834
835 /*
836  * tapread
837  *
838  * The ops read interface - reads a packet at a time, or at
839  * least as much of a packet as can be read.
840  *
841  * Called from the fileops interface with nothing held.
842  *
843  * MPSAFE
844  */
845 static int
846 tapread(struct dev_read_args *ap)
847 {
848         cdev_t dev = ap->a_head.a_dev;
849         struct uio *uio = ap->a_uio;
850         struct tap_softc *sc = dev->si_drv1;
851         struct ifnet *ifp = &sc->tap_if;
852         struct mbuf *m0 = NULL;
853         int error = 0, len;
854
855         TAPDEBUG(ifp, "reading, minor = %#x\n", minor(dev));
856
857         if ((sc->tap_flags & TAP_READY) != TAP_READY) {
858                 TAPDEBUG(ifp, "not ready, minor = %#x, flags = 0x%x\n",
859                          minor(dev), sc->tap_flags);
860
861                 return (EHOSTDOWN);
862         }
863
864         sc->tap_flags &= ~TAP_RWAIT;
865
866         /* sleep until we get a packet */
867         do {
868                 ifnet_serialize_all(ifp);
869                 IF_DEQUEUE(&sc->tap_devq, m0);
870                 if (m0 == NULL) {
871                         if (ap->a_ioflag & IO_NDELAY) {
872                                 ifnet_deserialize_all(ifp);
873                                 return (EWOULDBLOCK);
874                         }
875                         sc->tap_flags |= TAP_RWAIT;
876                         tsleep_interlock(sc, PCATCH);
877                         ifnet_deserialize_all(ifp);
878                         error = tsleep(sc, PCATCH | PINTERLOCKED, "taprd", 0);
879                         if (error)
880                                 return (error);
881                 } else {
882                         ifnet_deserialize_all(ifp);
883                 }
884         } while (m0 == NULL);
885
886         BPF_MTAP(ifp, m0);
887
888         /* xfer packet to user space */
889         while ((m0 != NULL) && (uio->uio_resid > 0) && (error == 0)) {
890                 len = (int)szmin(uio->uio_resid, m0->m_len);
891                 if (len == 0)
892                         break;
893
894                 error = uiomove(mtod(m0, caddr_t), (size_t)len, uio);
895                 m0 = m_free(m0);
896         }
897
898         if (m0 != NULL) {
899                 TAPDEBUG(ifp, "dropping mbuf, minor = %#x\n", minor(dev));
900                 m_freem(m0);
901         }
902
903         return (error);
904 }
905
906 /*
907  * tapwrite
908  *
909  * The ops write interface - an atomic write is a packet - or else!
910  *
911  * Called from the fileops interface with nothing held.
912  *
913  * MPSAFE
914  */
915 static int
916 tapwrite(struct dev_write_args *ap)
917 {
918         cdev_t dev = ap->a_head.a_dev;
919         struct uio *uio = ap->a_uio;
920         struct tap_softc *sc = dev->si_drv1;
921         struct ifnet *ifp = &sc->tap_if;
922         struct mbuf *top = NULL, **mp = NULL, *m = NULL;
923         int error;
924         size_t tlen, mlen;
925
926         TAPDEBUG(ifp, "writing, minor = %#x\n", minor(dev));
927
928         if ((sc->tap_flags & TAP_READY) != TAP_READY) {
929                 TAPDEBUG(ifp, "not ready, minor = %#x, flags = 0x%x\n",
930                          minor(dev), sc->tap_flags);
931                 return (EHOSTDOWN);
932         }
933
934         if (uio->uio_resid == 0)
935                 return (0);
936
937         if (uio->uio_resid > TAPMRU) {
938                 TAPDEBUG(ifp, "invalid packet len = %zu, minor = %#x\n",
939                          uio->uio_resid, minor(dev));
940
941                 return (EIO);
942         }
943         tlen = uio->uio_resid;
944
945         /* get a header mbuf */
946         MGETHDR(m, M_WAITOK, MT_DATA);
947         if (m == NULL)
948                 return (ENOBUFS);
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                         if (m == NULL) {
963                                 error = ENOBUFS;
964                                 break;
965                         }
966                         mlen = MLEN;
967                 }
968         }
969         if (error) {
970                 IFNET_STAT_INC(ifp, ierrors, 1);
971                 if (top)
972                         m_freem(top);
973                 return (error);
974         }
975
976         top->m_pkthdr.len = (int)tlen;
977         top->m_pkthdr.rcvif = ifp;
978
979         /*
980          * Ethernet bridge and bpf are handled in ether_input
981          *
982          * adjust mbuf and give packet to the ether_input
983          */
984         ifnet_serialize_all(ifp);
985         ifp->if_input(ifp, top, NULL, -1);
986         IFNET_STAT_INC(ifp, ipackets, 1); /* ibytes are counted in ether_input */
987         ifnet_deserialize_all(ifp);
988
989         return (0);
990 }
991
992
993 /*
994  * tapkqfilter - called from the fileops interface with nothing held
995  *
996  * MPSAFE
997  */
998 static int
999 tapkqfilter(struct dev_kqfilter_args *ap)
1000 {
1001         cdev_t dev = ap->a_head.a_dev;
1002         struct knote *kn = ap->a_kn;
1003         struct tap_softc *sc = dev->si_drv1;
1004         struct klist *list;
1005
1006         list = &sc->tap_rkq.ki_note;
1007         ap->a_result =0;
1008
1009         switch (kn->kn_filter) {
1010         case EVFILT_READ:
1011                 kn->kn_fop = &tapread_filtops;
1012                 kn->kn_hook = (void *)sc;
1013                 break;
1014         case EVFILT_WRITE:
1015                 kn->kn_fop = &tapwrite_filtops;
1016                 kn->kn_hook = (void *)sc;
1017                 break;
1018         default:
1019                 ap->a_result = EOPNOTSUPP;
1020                 return (0);
1021         }
1022
1023         knote_insert(list, kn);
1024         return (0);
1025 }
1026
1027 static int
1028 tap_filter_read(struct knote *kn, long hint)
1029 {
1030         struct tap_softc *sc = (struct tap_softc *)kn->kn_hook;
1031
1032         if (IF_QEMPTY(&sc->tap_devq) == 0)      /* XXX serializer */
1033                 return (1);
1034         else
1035                 return (0);
1036 }
1037
1038 static int
1039 tap_filter_write(struct knote *kn, long hint)
1040 {
1041         /* Always ready for a write */
1042         return (1);
1043 }
1044
1045 static void
1046 tap_filter_detach(struct knote *kn)
1047 {
1048         struct tap_softc *sc = (struct tap_softc *)kn->kn_hook;
1049
1050         knote_remove(&sc->tap_rkq.ki_note, kn);
1051 }