xref: /dragonfly/sys/net/tap/if_tap.c (revision 9317c2d0)
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/priv.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 
282 	if (tapfind(unit) != NULL)
283 		return (EEXIST);
284 
285 	if (dev == NULL) {
286 		if (!devfs_clone_bitmap_chk(&DEVFS_CLONE_BITMAP(tap), unit)) {
287 			devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(tap), unit);
288 			dev = make_dev(&tap_ops, unit, UID_ROOT, GID_WHEEL,
289 				       0600, "%s%d", TAP, unit);
290 		} else {
291 			dev = devfs_find_device_by_name("%s%d", TAP, unit);
292 			if (dev == NULL)
293 				return (ENOENT);
294 		}
295 	}
296 
297 	if ((sc = tapcreate(dev, 0)) == NULL)
298 		return (ENOMEM);
299 
300 	sc->tap_flags |= TAP_CLONE;
301 	TAPDEBUG(&sc->tap_if, "clone created, minor = %#x, flags = 0x%x\n",
302 		 minor(sc->tap_dev), sc->tap_flags);
303 
304 	return (0);
305 }
306 
307 /*
308  * Open the tap device.
309  */
310 static int
311 tapopen(struct dev_open_args *ap)
312 {
313 	cdev_t dev = NULL;
314 	struct tap_softc *sc = NULL;
315 	struct ifnet *ifp = NULL;
316 	int error;
317 
318 	if (tapuopen == 0 &&
319 	    (error = priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) != 0)
320 		return (error);
321 
322 	get_mplock();
323 
324 	dev = ap->a_head.a_dev;
325 	sc = dev->si_drv1;
326 	if (sc == NULL && (sc = tapcreate(dev, TAP_MANUALMAKE)) == NULL) {
327 		rel_mplock();
328 		return (ENOMEM);
329 	}
330 	if (sc->tap_flags & TAP_OPEN) {
331 		rel_mplock();
332 		return (EBUSY);
333 	}
334 
335 	ifp = &sc->tap_if;
336 	bcopy(sc->arpcom.ac_enaddr, sc->ether_addr, sizeof(sc->ether_addr));
337 
338 	if (curthread->td_proc)
339 		fsetown(curthread->td_proc->p_pid, &sc->tap_sigtd);
340 	sc->tap_flags |= TAP_OPEN;
341 	taprefcnt++;
342 
343 	if (tapuponopen && (ifp->if_flags & IFF_UP) == 0) {
344 		crit_enter();
345 		if_up(ifp);
346 		crit_exit();
347 
348 		ifnet_serialize_all(ifp);
349 		tapifflags(sc);
350 		ifnet_deserialize_all(ifp);
351 
352 		sc->tap_flags |= TAP_CLOSEDOWN;
353 	}
354 
355 	TAPDEBUG(ifp, "opened, minor = %#x. Module refcnt = %d\n",
356 		 minor(dev), taprefcnt);
357 
358 	rel_mplock();
359 	return (0);
360 }
361 
362 static int
363 tapclone(struct dev_clone_args *ap)
364 {
365 	char ifname[IFNAMSIZ];
366 	int unit;
367 
368 	unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(tap), 0);
369 	ksnprintf(ifname, IFNAMSIZ, "%s%d", TAP, unit);
370 	ap->a_dev = make_only_dev(&tap_ops, unit, UID_ROOT, GID_WHEEL,
371 				  0600, "%s", ifname);
372 
373 	/*
374 	 * Use the if_clone framework to create cloned device/interface,
375 	 * so the two clone methods (autoclone device /dev/tap; ifconfig
376 	 * clone) are consistent and can be mix used.
377 	 *
378 	 * Need to pass the cdev_t because the device created by
379 	 * 'make_only_dev()' doesn't appear in '/dev' yet so that it can't
380 	 * be found by 'devfs_find_device_by_name()' in 'tap_clone_create()'.
381 	 */
382 	return (if_clone_create(ifname, IFNAMSIZ, NULL, (caddr_t)ap->a_dev));
383 }
384 
385 /*
386  * Close the tap device: bring the interface down & delete routing info.
387  */
388 static int
389 tapclose(struct dev_close_args *ap)
390 {
391 	cdev_t dev = ap->a_head.a_dev;
392 	struct tap_softc *sc = dev->si_drv1;
393 	struct ifnet *ifp;
394 	int unit = minor(dev);
395 	int clear_flags = 0;
396 
397 	KASSERT(sc != NULL,
398 		("try closing the already destroyed %s%d", TAP, unit));
399 	ifp = &sc->tap_if;
400 
401 	get_mplock();
402 
403 	/* Junk all pending output */
404 	ifq_purge_all(&ifp->if_snd);
405 
406 	/*
407 	 * If the interface is not cloned, we always bring it down.
408 	 *
409 	 * If the interface is cloned, then we bring it down during
410 	 * closing only if it was brought up during opening.
411 	 */
412 	if ((sc->tap_flags & TAP_CLONE) == 0 ||
413 	    (sc->tap_flags & TAP_CLOSEDOWN)) {
414 		if (ifp->if_flags & IFF_UP)
415 			if_down(ifp);
416 		clear_flags = 1;
417 	}
418 	ifnet_serialize_all(ifp);
419 	tapifstop(sc, clear_flags);
420 	ifnet_deserialize_all(ifp);
421 
422 	if ((sc->tap_flags & TAP_CLONE) == 0) {
423 		if_purgeaddrs_nolink(ifp);
424 
425 		EVENTHANDLER_INVOKE(ifnet_detach_event, ifp);
426 
427 		/* Announce the departure of the interface. */
428 		rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
429 	}
430 
431 	funsetown(&sc->tap_sigio);
432 	sc->tap_sigio = NULL;
433 	KNOTE(&sc->tap_rkq.ki_note, 0);
434 
435 	sc->tap_flags &= ~TAP_OPEN;
436 	funsetown(&sc->tap_sigtd);
437 	sc->tap_sigtd = NULL;
438 
439 	taprefcnt--;
440 	if (taprefcnt < 0) {
441 		taprefcnt = 0;
442 		if_printf(ifp, ". Module refcnt = %d is out of sync! "
443 			  "Force refcnt to be 0.\n", taprefcnt);
444 	}
445 
446 	TAPDEBUG(ifp, "closed, minor = %#x. Module refcnt = %d\n",
447 		 unit, taprefcnt);
448 
449 	/* Only auto-destroy if the interface was not manually created. */
450 	if ((sc->tap_flags & TAP_MANUALMAKE) == 0) {
451 		tapdestroy(sc);
452 		dev->si_drv1 = NULL;
453 	}
454 
455 	rel_mplock();
456 	return (0);
457 }
458 
459 
460 /*
461  * Destroy a tap instance: the interface and the associated device.
462  */
463 static void
464 tapdestroy(struct tap_softc *sc)
465 {
466 	struct ifnet *ifp = &sc->tap_if;
467 	cdev_t dev = sc->tap_dev;
468 	int unit = minor(dev);
469 
470 	TAPDEBUG(ifp, "destroyed, minor = %#x. Module refcnt = %d\n",
471 		 unit, taprefcnt);
472 
473 	ifnet_serialize_all(ifp);
474 	tapifstop(sc, 1);
475 	ifnet_deserialize_all(ifp);
476 	ether_ifdetach(ifp);
477 
478 	sc->tap_dev = NULL;
479 	dev->si_drv1 = NULL;
480 	release_dev(dev); /* device disassociation */
481 
482 	/* Also destroy the cloned device */
483 	destroy_dev(dev);
484 	devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(tap), unit);
485 
486 	SLIST_REMOVE(&tap_listhead, sc, tap_softc, tap_link);
487 	kfree(sc, M_TAP);
488 }
489 
490 
491 /*
492  * Destroy a tap instance that is created via ifconfig.
493  */
494 static int
495 tap_clone_destroy(struct ifnet *ifp)
496 {
497 	struct tap_softc *sc = ifp->if_softc;
498 
499 	if (sc->tap_flags & TAP_OPEN)
500 		return (EBUSY);
501 	if ((sc->tap_flags & TAP_CLONE) == 0)
502 		return (EINVAL);
503 
504 	TAPDEBUG(ifp, "clone destroyed, minor = %#x, flags = 0x%x\n",
505 		 minor(sc->tap_dev), sc->tap_flags);
506 	tapdestroy(sc);
507 
508 	return (0);
509 }
510 
511 
512 /*
513  * tapifinit
514  *
515  * Network interface initialization function (called with if serializer held)
516  *
517  * MPSAFE
518  */
519 static void
520 tapifinit(void *xtp)
521 {
522 	struct tap_softc *sc = xtp;
523 	struct ifnet *ifp = &sc->tap_if;
524 	struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
525 
526 	TAPDEBUG(ifp, "initializing, minor = %#x, flags = 0x%x\n",
527 		 minor(sc->tap_dev), sc->tap_flags);
528 
529 	ASSERT_IFNET_SERIALIZED_ALL(ifp);
530 
531 	tapifstop(sc, 1);
532 
533 	ifp->if_flags |= IFF_RUNNING;
534 	ifsq_clr_oactive(ifsq);
535 
536 	/* attempt to start output */
537 	tapifstart(ifp, ifsq);
538 }
539 
540 static void
541 tapifflags(struct tap_softc *sc)
542 {
543 	struct ifnet *ifp = &sc->tap_if;
544 
545 	ASSERT_IFNET_SERIALIZED_ALL(ifp);
546 
547 	if (ifp->if_flags & IFF_UP) {
548 		if ((ifp->if_flags & IFF_RUNNING) == 0)
549 			tapifinit(sc);
550 	} else {
551 		tapifstop(sc, 1);
552 	}
553 }
554 
555 /*
556  * tapifioctl
557  *
558  * Process an ioctl request on network interface (called with if serializer
559  * held).
560  *
561  * MPSAFE
562  */
563 static int
564 tapifioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr)
565 {
566 	struct tap_softc *sc = ifp->if_softc;
567 	struct ifreq *ifr = NULL;
568 	struct ifstat *ifs = NULL;
569 	struct ifmediareq *ifmr = NULL;
570 	int error = 0;
571 	int dummy;
572 
573 	switch (cmd) {
574 	case SIOCADDMULTI:
575 	case SIOCDELMULTI:
576 		break;
577 
578 	case SIOCSIFMTU:
579 		ifr = (struct ifreq *)data;
580 		ifp->if_mtu = ifr->ifr_mtu;
581 		TAPDEBUG(ifp, "mtu set\n");
582 		break;
583 
584 	case SIOCSIFADDR:
585 	case SIOCGIFADDR:
586 		error = ether_ioctl(ifp, cmd, data);
587 		break;
588 
589 	case SIOCSIFFLAGS:
590 		tapifflags(sc);
591 		break;
592 
593 	case SIOCGIFMEDIA:
594 		/*
595 		 * The bridge code needs this when running the
596 		 * spanning tree protocol.
597 		 */
598 		ifmr = (struct ifmediareq *)data;
599 		dummy = ifmr->ifm_count;
600 		ifmr->ifm_count = 1;
601 		ifmr->ifm_status = IFM_AVALID;
602 		ifmr->ifm_active = IFM_ETHER;
603 		if (sc->tap_flags & TAP_OPEN)
604 			ifmr->ifm_status |= IFM_ACTIVE;
605 		ifmr->ifm_current = ifmr->ifm_active;
606 		if (dummy >= 1) {
607 			int media = IFM_ETHER;
608 			error = copyout(&media, ifmr->ifm_ulist, sizeof(int));
609 		}
610 		break;
611 
612 	case SIOCGIFSTATUS:
613 		ifs = (struct ifstat *)data;
614 		dummy = strlen(ifs->ascii);
615 		if ((sc->tap_flags & TAP_OPEN) && dummy < sizeof(ifs->ascii)) {
616 			if (sc->tap_sigtd && sc->tap_sigtd->sio_proc) {
617 				ksnprintf(ifs->ascii + dummy,
618 				    sizeof(ifs->ascii) - dummy,
619 				    "\tOpened by pid %d\n",
620 				    (int)sc->tap_sigtd->sio_proc->p_pid);
621 			} else {
622 				ksnprintf(ifs->ascii + dummy,
623 				    sizeof(ifs->ascii) - dummy,
624 				    "\tOpened by <unknown>\n");
625 			}
626 		}
627 		break;
628 
629 	default:
630 		error = EINVAL;
631 		break;
632 	}
633 
634 	return (error);
635 }
636 
637 /*
638  * tapifstart
639  *
640  * Queue packets from higher level ready to put out (called with if serializer
641  * held)
642  *
643  * MPSAFE
644  */
645 static void
646 tapifstart(struct ifnet *ifp, struct ifaltq_subque *ifsq)
647 {
648 	struct tap_softc *sc = ifp->if_softc;
649 	struct ifqueue *ifq;
650 	struct mbuf *m;
651 	int has_data = 0;
652 
653 	ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq);
654 	TAPDEBUG(ifp, "starting, minor = %#x\n", minor(sc->tap_dev));
655 
656 	if ((sc->tap_flags & TAP_READY) != TAP_READY) {
657 		TAPDEBUG(ifp, "not ready, minor = %#x, flags = 0x%x\n",
658 			 minor(sc->tap_dev), sc->tap_flags);
659 		ifsq_purge(ifsq);
660 		return;
661 	}
662 
663 	ifsq_set_oactive(ifsq);
664 
665 	ifq = &sc->tap_devq;
666 	while ((m = ifsq_dequeue(ifsq)) != NULL) {
667 		if (IF_QFULL(ifq)) {
668 			IF_DROP(ifq);
669 			IFNET_STAT_INC(ifp, oerrors, 1);
670 			m_freem(m);
671 		} else {
672 			IF_ENQUEUE(ifq, m);
673 			IFNET_STAT_INC(ifp, opackets, 1);
674 			has_data = 1;
675 		}
676 	}
677 
678 	if (has_data) {
679 		if (sc->tap_flags & TAP_RWAIT) {
680 			sc->tap_flags &= ~TAP_RWAIT;
681 			wakeup((caddr_t)sc);
682 		}
683 
684 		KNOTE(&sc->tap_rkq.ki_note, 0);
685 
686 		if ((sc->tap_flags & TAP_ASYNC) && (sc->tap_sigio != NULL)) {
687 			get_mplock();
688 			pgsigio(sc->tap_sigio, SIGIO, 0);
689 			rel_mplock();
690 		}
691 	}
692 
693 	ifsq_clr_oactive(ifsq);
694 }
695 
696 static void
697 tapifstop(struct tap_softc *sc, int clear_flags)
698 {
699 	struct ifnet *ifp = &sc->tap_if;
700 
701 	ASSERT_IFNET_SERIALIZED_ALL(ifp);
702 	IF_DRAIN(&sc->tap_devq);
703 	sc->tap_flags &= ~TAP_CLOSEDOWN;
704 	if (clear_flags) {
705 		ifp->if_flags &= ~IFF_RUNNING;
706 		ifsq_clr_oactive(ifq_get_subq_default(&ifp->if_snd));
707 	}
708 }
709 
710 /*
711  * tapioctl
712  *
713  * The ops interface is now pretty minimal.  Called via fileops with nothing
714  * held.
715  *
716  * MPSAFE
717  */
718 static int
719 tapioctl(struct dev_ioctl_args *ap)
720 {
721 	cdev_t dev = ap->a_head.a_dev;
722 	caddr_t data = ap->a_data;
723 	struct tap_softc *sc = dev->si_drv1;
724 	struct ifnet *ifp = &sc->tap_if;
725 	struct ifreq *ifr;
726 	struct tapinfo *tapp = NULL;
727 	struct mbuf *mb;
728 	int error;
729 
730 	ifnet_serialize_all(ifp);
731 	error = 0;
732 
733 	switch (ap->a_cmd) {
734 	case TAPSIFINFO:
735 		tapp = (struct tapinfo *)data;
736 		if (ifp->if_type != tapp->type)
737 			return (EPROTOTYPE);
738 		ifp->if_mtu = tapp->mtu;
739 		ifp->if_baudrate = tapp->baudrate;
740 		break;
741 
742 	case TAPGIFINFO:
743 		tapp = (struct tapinfo *)data;
744 		tapp->mtu = ifp->if_mtu;
745 		tapp->type = ifp->if_type;
746 		tapp->baudrate = ifp->if_baudrate;
747 		break;
748 
749 	case TAPGIFNAME:
750 		ifr = (struct ifreq *)data;
751 		strlcpy(ifr->ifr_name, ifp->if_xname, IFNAMSIZ);
752 		break;
753 
754 	case TAPSDEBUG:
755 		tapdebug = *(int *)data;
756 		break;
757 
758 	case TAPGDEBUG:
759 		*(int *)data = tapdebug;
760 		break;
761 
762 	case FIOASYNC:
763 		if (*(int *)data)
764 			sc->tap_flags |= TAP_ASYNC;
765 		else
766 			sc->tap_flags &= ~TAP_ASYNC;
767 		break;
768 
769 	case FIONREAD:
770 		/* Take a look at devq first */
771 		IF_POLL(&sc->tap_devq, mb);
772 		if (mb != NULL) {
773 			*(int *)data = 0;
774 			for(; mb != NULL; mb = mb->m_next)
775 				*(int *)data += mb->m_len;
776 		} else {
777 			*(int *)data = ifsq_poll_pktlen(
778 			    ifq_get_subq_default(&ifp->if_snd));
779 		}
780 		break;
781 
782 	case FIOSETOWN:
783 		error = fsetown(*(int *)data, &sc->tap_sigio);
784 		if (error == 0)
785 			error = fsetown(*(int *)data, &sc->tap_sigtd);
786 		break;
787 
788 	case FIOGETOWN:
789 		*(int *)data = fgetown(&sc->tap_sigio);
790 		break;
791 
792 	/* this is deprecated, FIOSETOWN should be used instead */
793 	case TIOCSPGRP:
794 		error = fsetown(-(*(int *)data), &sc->tap_sigio);
795 		break;
796 
797 	/* this is deprecated, FIOGETOWN should be used instead */
798 	case TIOCGPGRP:
799 		*(int *)data = -fgetown(&sc->tap_sigio);
800 		break;
801 
802 	/*
803 	 * Support basic control of the network interface via the device file.
804 	 * e.g., vke(4) currently uses the 'SIOCGIFADDR' ioctl.
805 	 */
806 
807 	case SIOCGIFFLAGS:
808 		bcopy(&ifp->if_flags, data, sizeof(ifp->if_flags));
809 		break;
810 
811 	case SIOCGIFADDR:
812 		bcopy(sc->ether_addr, data, sizeof(sc->ether_addr));
813 		break;
814 
815 	case SIOCSIFADDR:
816 		bcopy(data, sc->ether_addr, sizeof(sc->ether_addr));
817 		break;
818 
819 	default:
820 		error = ENOTTY;
821 		break;
822 	}
823 
824 	ifnet_deserialize_all(ifp);
825 	return (error);
826 }
827 
828 
829 /*
830  * tapread
831  *
832  * The ops read interface - reads a packet at a time, or at
833  * least as much of a packet as can be read.
834  *
835  * Called from the fileops interface with nothing held.
836  *
837  * MPSAFE
838  */
839 static int
840 tapread(struct dev_read_args *ap)
841 {
842 	cdev_t dev = ap->a_head.a_dev;
843 	struct uio *uio = ap->a_uio;
844 	struct tap_softc *sc = dev->si_drv1;
845 	struct ifnet *ifp = &sc->tap_if;
846 	struct mbuf *m0 = NULL;
847 	int error = 0, len;
848 
849 	TAPDEBUG(ifp, "reading, minor = %#x\n", minor(dev));
850 
851 	if ((sc->tap_flags & TAP_READY) != TAP_READY) {
852 		TAPDEBUG(ifp, "not ready, minor = %#x, flags = 0x%x\n",
853 			 minor(dev), sc->tap_flags);
854 
855 		return (EHOSTDOWN);
856 	}
857 
858 	sc->tap_flags &= ~TAP_RWAIT;
859 
860 	/* sleep until we get a packet */
861 	do {
862 		ifnet_serialize_all(ifp);
863 		IF_DEQUEUE(&sc->tap_devq, m0);
864 		if (m0 == NULL) {
865 			if (ap->a_ioflag & IO_NDELAY) {
866 				ifnet_deserialize_all(ifp);
867 				return (EWOULDBLOCK);
868 			}
869 			sc->tap_flags |= TAP_RWAIT;
870 			tsleep_interlock(sc, PCATCH);
871 			ifnet_deserialize_all(ifp);
872 			error = tsleep(sc, PCATCH | PINTERLOCKED, "taprd", 0);
873 			if (error)
874 				return (error);
875 		} else {
876 			ifnet_deserialize_all(ifp);
877 		}
878 	} while (m0 == NULL);
879 
880 	BPF_MTAP(ifp, m0);
881 
882 	/* xfer packet to user space */
883 	while ((m0 != NULL) && (uio->uio_resid > 0) && (error == 0)) {
884 		len = (int)szmin(uio->uio_resid, m0->m_len);
885 		if (len == 0)
886 			break;
887 
888 		error = uiomove(mtod(m0, caddr_t), (size_t)len, uio);
889 		m0 = m_free(m0);
890 	}
891 
892 	if (m0 != NULL) {
893 		TAPDEBUG(ifp, "dropping mbuf, minor = %#x\n", minor(dev));
894 		m_freem(m0);
895 	}
896 
897 	return (error);
898 }
899 
900 /*
901  * tapwrite
902  *
903  * The ops write interface - an atomic write is a packet - or else!
904  *
905  * Called from the fileops interface with nothing held.
906  *
907  * MPSAFE
908  */
909 static int
910 tapwrite(struct dev_write_args *ap)
911 {
912 	cdev_t dev = ap->a_head.a_dev;
913 	struct uio *uio = ap->a_uio;
914 	struct tap_softc *sc = dev->si_drv1;
915 	struct ifnet *ifp = &sc->tap_if;
916 	struct mbuf *top = NULL, **mp = NULL, *m = NULL;
917 	int error;
918 	size_t tlen, mlen;
919 
920 	TAPDEBUG(ifp, "writing, minor = %#x\n", minor(dev));
921 
922 	if ((sc->tap_flags & TAP_READY) != TAP_READY) {
923 		TAPDEBUG(ifp, "not ready, minor = %#x, flags = 0x%x\n",
924 			 minor(dev), sc->tap_flags);
925 		return (EHOSTDOWN);
926 	}
927 
928 	if (uio->uio_resid == 0)
929 		return (0);
930 
931 	if (uio->uio_resid > TAPMRU) {
932 		TAPDEBUG(ifp, "invalid packet len = %zu, minor = %#x\n",
933 			 uio->uio_resid, minor(dev));
934 
935 		return (EIO);
936 	}
937 	tlen = uio->uio_resid;
938 
939 	/* get a header mbuf */
940 	MGETHDR(m, M_WAITOK, MT_DATA);
941 	if (m == NULL)
942 		return (ENOBUFS);
943 	mlen = MHLEN;
944 
945 	top = NULL;
946 	mp = &top;
947 	error = 0;
948 
949 	while (error == 0 && uio->uio_resid > 0) {
950 		m->m_len = (int)szmin(mlen, uio->uio_resid);
951 		error = uiomove(mtod(m, caddr_t), (size_t)m->m_len, uio);
952 		*mp = m;
953 		mp = &m->m_next;
954 		if (uio->uio_resid > 0) {
955 			MGET(m, M_WAITOK, MT_DATA);
956 			if (m == NULL) {
957 				error = ENOBUFS;
958 				break;
959 			}
960 			mlen = MLEN;
961 		}
962 	}
963 	if (error) {
964 		IFNET_STAT_INC(ifp, ierrors, 1);
965 		if (top)
966 			m_freem(top);
967 		return (error);
968 	}
969 
970 	top->m_pkthdr.len = (int)tlen;
971 	top->m_pkthdr.rcvif = ifp;
972 
973 	/*
974 	 * Ethernet bridge and bpf are handled in ether_input
975 	 *
976 	 * adjust mbuf and give packet to the ether_input
977 	 */
978 	ifnet_serialize_all(ifp);
979 	ifp->if_input(ifp, top, NULL, -1);
980 	IFNET_STAT_INC(ifp, ipackets, 1); /* ibytes are counted in ether_input */
981 	ifnet_deserialize_all(ifp);
982 
983 	return (0);
984 }
985 
986 
987 /*
988  * tapkqfilter - called from the fileops interface with nothing held
989  *
990  * MPSAFE
991  */
992 static int
993 tapkqfilter(struct dev_kqfilter_args *ap)
994 {
995 	cdev_t dev = ap->a_head.a_dev;
996 	struct knote *kn = ap->a_kn;
997 	struct tap_softc *sc = dev->si_drv1;
998 	struct klist *list;
999 
1000 	list = &sc->tap_rkq.ki_note;
1001 	ap->a_result =0;
1002 
1003 	switch (kn->kn_filter) {
1004 	case EVFILT_READ:
1005 		kn->kn_fop = &tapread_filtops;
1006 		kn->kn_hook = (void *)sc;
1007 		break;
1008 	case EVFILT_WRITE:
1009 		kn->kn_fop = &tapwrite_filtops;
1010 		kn->kn_hook = (void *)sc;
1011 		break;
1012 	default:
1013 		ap->a_result = EOPNOTSUPP;
1014 		return (0);
1015 	}
1016 
1017 	knote_insert(list, kn);
1018 	return (0);
1019 }
1020 
1021 static int
1022 tap_filter_read(struct knote *kn, long hint)
1023 {
1024 	struct tap_softc *sc = (struct tap_softc *)kn->kn_hook;
1025 
1026 	if (IF_QEMPTY(&sc->tap_devq) == 0)	/* XXX serializer */
1027 		return (1);
1028 	else
1029 		return (0);
1030 }
1031 
1032 static int
1033 tap_filter_write(struct knote *kn, long hint)
1034 {
1035 	/* Always ready for a write */
1036 	return (1);
1037 }
1038 
1039 static void
1040 tap_filter_detach(struct knote *kn)
1041 {
1042 	struct tap_softc *sc = (struct tap_softc *)kn->kn_hook;
1043 
1044 	knote_remove(&sc->tap_rkq.ki_note, kn);
1045 }
1046