xref: /dragonfly/sys/net/tap/if_tap.c (revision 2b3f93ea)
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 	if (m == NULL)
950 		return (ENOBUFS);
951 	mlen = MHLEN;
952 
953 	top = NULL;
954 	mp = &top;
955 	error = 0;
956 
957 	while (error == 0 && uio->uio_resid > 0) {
958 		m->m_len = (int)szmin(mlen, uio->uio_resid);
959 		error = uiomove(mtod(m, caddr_t), (size_t)m->m_len, uio);
960 		*mp = m;
961 		mp = &m->m_next;
962 		if (uio->uio_resid > 0) {
963 			MGET(m, M_WAITOK, MT_DATA);
964 			if (m == NULL) {
965 				error = ENOBUFS;
966 				break;
967 			}
968 			mlen = MLEN;
969 		}
970 	}
971 	if (error) {
972 		IFNET_STAT_INC(ifp, ierrors, 1);
973 		if (top)
974 			m_freem(top);
975 		return (error);
976 	}
977 
978 	top->m_pkthdr.len = (int)tlen;
979 	top->m_pkthdr.rcvif = ifp;
980 
981 	/*
982 	 * Ethernet bridge and bpf are handled in ether_input
983 	 *
984 	 * adjust mbuf and give packet to the ether_input
985 	 */
986 	ifnet_serialize_all(ifp);
987 	ifp->if_input(ifp, top, NULL, -1);
988 	IFNET_STAT_INC(ifp, ipackets, 1); /* ibytes are counted in ether_input */
989 	ifnet_deserialize_all(ifp);
990 
991 	return (0);
992 }
993 
994 
995 /*
996  * tapkqfilter - called from the fileops interface with nothing held
997  *
998  * MPSAFE
999  */
1000 static int
1001 tapkqfilter(struct dev_kqfilter_args *ap)
1002 {
1003 	cdev_t dev = ap->a_head.a_dev;
1004 	struct knote *kn = ap->a_kn;
1005 	struct tap_softc *sc = dev->si_drv1;
1006 	struct klist *list;
1007 
1008 	list = &sc->tap_rkq.ki_note;
1009 	ap->a_result =0;
1010 
1011 	switch (kn->kn_filter) {
1012 	case EVFILT_READ:
1013 		kn->kn_fop = &tapread_filtops;
1014 		kn->kn_hook = (void *)sc;
1015 		break;
1016 	case EVFILT_WRITE:
1017 		kn->kn_fop = &tapwrite_filtops;
1018 		kn->kn_hook = (void *)sc;
1019 		break;
1020 	default:
1021 		ap->a_result = EOPNOTSUPP;
1022 		return (0);
1023 	}
1024 
1025 	knote_insert(list, kn);
1026 	return (0);
1027 }
1028 
1029 static int
1030 tap_filter_read(struct knote *kn, long hint)
1031 {
1032 	struct tap_softc *sc = (struct tap_softc *)kn->kn_hook;
1033 
1034 	if (IF_QEMPTY(&sc->tap_devq) == 0)	/* XXX serializer */
1035 		return (1);
1036 	else
1037 		return (0);
1038 }
1039 
1040 static int
1041 tap_filter_write(struct knote *kn, long hint)
1042 {
1043 	/* Always ready for a write */
1044 	return (1);
1045 }
1046 
1047 static void
1048 tap_filter_detach(struct knote *kn)
1049 {
1050 	struct tap_softc *sc = (struct tap_softc *)kn->kn_hook;
1051 
1052 	knote_remove(&sc->tap_rkq.ki_note, kn);
1053 }
1054