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