2 * Copyright (C) 1999-2000 by Maksim Yevmenkin <m_evmenkin@yahoo.com>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 * -------------------------------------------------------------------------
29 * Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
30 * Nottingham University 1987.
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 $
40 #include <sys/param.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>
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>
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>
65 #include <net/ethernet.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>
74 #include <netinet/in.h>
76 #include "if_tapvar.h"
79 #define TAP_IFFLAGS (IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST)
82 #define TAPDEBUG if (tapdebug) if_printf
85 static int tapmodevent(module_t
, int, void *);
88 static struct tap_softc
*tapcreate(cdev_t
, int);
89 static void tapdestroy(struct tap_softc
*);
92 static int tap_clone_create(struct if_clone
*, int,
94 static int tap_clone_destroy(struct ifnet
*);
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
,
101 static void tapifstop(struct tap_softc
*, int);
102 static void tapifflags(struct tap_softc
*);
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
;
113 static struct dev_ops tap_ops
= {
120 .d_kqfilter
= tapkqfilter
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);
128 static struct filterops tapread_filtops
= {
134 static struct filterops tapwrite_filtops
= {
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 */
146 static MALLOC_DEFINE(M_TAP
, TAP
, "Ethernet tunnel interface");
148 static DEVFS_DEFINE_CLONE_BITMAP(tap
);
150 struct if_clone tap_cloner
= IF_CLONE_INITIALIZER(
151 TAP
, tap_clone_create
, tap_clone_destroy
, 0, IF_MAXUNIT
);
153 static SLIST_HEAD(,tap_softc
) tap_listhead
=
154 SLIST_HEAD_INITIALIZER(&tap_listhead
);
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");
168 DEV_MODULE(if_tap
, tapmodevent
, NULL
);
173 * module event handler
176 tapmodevent(module_t mod
, int type
, void *data
)
178 static cdev_t dev
= NULL
;
179 struct tap_softc
*sc
, *sc_tmp
;
183 dev
= make_autoclone_dev(&tap_ops
, &DEVFS_CLONE_BITMAP(tap
),
184 tapclone
, UID_ROOT
, GID_WHEEL
,
186 SLIST_INIT(&tap_listhead
);
187 if_clone_attach(&tap_cloner
);
194 if_clone_detach(&tap_cloner
);
196 SLIST_FOREACH_MUTABLE(sc
, &tap_listhead
, tap_link
, sc_tmp
)
199 dev_ops_remove_all(&tap_ops
);
200 destroy_autoclone_dev(dev
, &DEVFS_CLONE_BITMAP(tap
));
212 * Create or clone an interface
214 static struct tap_softc
*
215 tapcreate(cdev_t dev
, int flags
)
217 struct tap_softc
*sc
;
219 uint8_t ether_addr
[ETHER_ADDR_LEN
];
220 int unit
= minor(dev
);
222 sc
= kmalloc(sizeof(*sc
), M_TAP
, M_WAITOK
| M_ZERO
);
225 sc
->tap_flags
|= flags
;
227 reference_dev(dev
); /* device association */
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
, ðer_addr
[2], 3);
233 ether_addr
[5] = (u_char
)unit
;
235 /* fill the rest and attach interface */
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
;
245 ifq_set_maxlen(&ifp
->if_snd
, ifqmaxlen
);
246 ifq_set_ready(&ifp
->if_snd
);
248 ether_ifattach(ifp
, ether_addr
, NULL
);
250 sc
->tap_flags
|= TAP_INITED
;
251 sc
->tap_devq
.ifq_maxlen
= ifqmaxlen
;
253 SLIST_INSERT_HEAD(&tap_listhead
, sc
, tap_link
);
255 TAPDEBUG(ifp
, "created, minor = %#x, flags = 0x%x\n",
256 unit
, sc
->tap_flags
);
260 static struct tap_softc
*
263 struct tap_softc
*sc
;
265 SLIST_FOREACH(sc
, &tap_listhead
, tap_link
) {
266 if (minor(sc
->tap_dev
) == unit
)
273 * Create a new tap instance via ifconfig.
276 tap_clone_create(struct if_clone
*ifc __unused
, int unit
,
277 caddr_t params __unused
, caddr_t data
)
279 struct tap_softc
*sc
;
280 cdev_t dev
= (cdev_t
)data
;
283 if (tapfind(unit
) != 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
);
292 dev
= devfs_find_device_by_name("%s%d", TAP
, unit
);
296 flags
= TAP_MANUALMAKE
;
301 if ((sc
= tapcreate(dev
, flags
)) == NULL
)
304 sc
->tap_flags
|= TAP_CLONE
;
306 TAPDEBUG(&sc
->tap_if
, "clone created, minor = %#x, flags = 0x%x\n",
307 minor(sc
->tap_dev
), sc
->tap_flags
);
313 * Open the tap device.
316 tapopen(struct dev_open_args
*ap
)
319 struct tap_softc
*sc
= NULL
;
320 struct ifnet
*ifp
= NULL
;
324 (error
= caps_priv_check(ap
->a_cred
, SYSCAP_RESTRICTEDROOT
)) != 0)
331 dev
= ap
->a_head
.a_dev
;
333 if (sc
== NULL
&& (sc
= tapcreate(dev
, 0)) == NULL
) {
337 if (sc
->tap_flags
& TAP_OPEN
) {
343 bcopy(sc
->arpcom
.ac_enaddr
, sc
->ether_addr
, sizeof(sc
->ether_addr
));
345 if (curthread
->td_proc
)
346 fsetown(curthread
->td_proc
->p_pid
, &sc
->tap_sigtd
);
347 sc
->tap_flags
|= TAP_OPEN
;
350 if (tapuponopen
&& (ifp
->if_flags
& IFF_UP
) == 0) {
355 ifnet_serialize_all(ifp
);
357 ifnet_deserialize_all(ifp
);
359 sc
->tap_flags
|= TAP_CLOSEDOWN
;
362 TAPDEBUG(ifp
, "opened, minor = %#x. Module refcnt = %d\n",
363 minor(dev
), taprefcnt
);
370 tapclone(struct dev_clone_args
*ap
)
372 char ifname
[IFNAMSIZ
];
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
,
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.
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()'.
389 return (if_clone_create(ifname
, IFNAMSIZ
, NULL
, (caddr_t
)ap
->a_dev
));
393 * Close the tap device: bring the interface down & delete routing info.
396 tapclose(struct dev_close_args
*ap
)
398 cdev_t dev
= ap
->a_head
.a_dev
;
399 struct tap_softc
*sc
= dev
->si_drv1
;
401 int unit
= minor(dev
);
403 char ifname
[IFNAMSIZ
];
406 ("try closing the already destroyed %s%d", TAP
, unit
));
411 /* Junk all pending output */
412 ifq_purge_all(&ifp
->if_snd
);
415 * If the interface is not cloned, we always bring it down.
417 * If the interface is cloned, then we bring it down during
418 * closing only if it was brought up during opening.
420 if ((sc
->tap_flags
& TAP_CLONE
) == 0 ||
421 (sc
->tap_flags
& TAP_CLOSEDOWN
)) {
422 if (ifp
->if_flags
& IFF_UP
)
426 ifnet_serialize_all(ifp
);
427 tapifstop(sc
, clear_flags
);
428 ifnet_deserialize_all(ifp
);
430 if ((sc
->tap_flags
& TAP_MANUALMAKE
) == 0) {
431 if_purgeaddrs_nolink(ifp
);
433 EVENTHANDLER_INVOKE(ifnet_detach_event
, ifp
);
435 /* Announce the departure of the interface. */
436 rt_ifannouncemsg(ifp
, IFAN_DEPARTURE
);
439 funsetown(&sc
->tap_sigio
);
440 sc
->tap_sigio
= NULL
;
441 KNOTE(&sc
->tap_rkq
.ki_note
, 0);
443 sc
->tap_flags
&= ~TAP_OPEN
;
444 funsetown(&sc
->tap_sigtd
);
445 sc
->tap_sigtd
= NULL
;
450 if_printf(ifp
, ". Module refcnt = %d is out of sync! "
451 "Force refcnt to be 0.\n", taprefcnt
);
454 TAPDEBUG(ifp
, "closed, minor = %#x. Module refcnt = %d\n",
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
);
469 * Destroy a tap instance: the interface and the associated device.
472 tapdestroy(struct tap_softc
*sc
)
474 struct ifnet
*ifp
= &sc
->tap_if
;
475 cdev_t dev
= sc
->tap_dev
;
476 int unit
= minor(dev
);
478 TAPDEBUG(ifp
, "destroyed, minor = %#x. Module refcnt = %d\n",
481 ifnet_serialize_all(ifp
);
483 ifnet_deserialize_all(ifp
);
488 release_dev(dev
); /* device disassociation */
490 /* Also destroy the cloned device */
492 devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(tap
), unit
);
494 SLIST_REMOVE(&tap_listhead
, sc
, tap_softc
, tap_link
);
500 * Destroy a tap instance that is created via ifconfig.
503 tap_clone_destroy(struct ifnet
*ifp
)
505 struct tap_softc
*sc
= ifp
->if_softc
;
507 if (sc
->tap_flags
& TAP_OPEN
)
509 if ((sc
->tap_flags
& TAP_CLONE
) == 0)
512 TAPDEBUG(ifp
, "clone destroyed, minor = %#x, flags = 0x%x\n",
513 minor(sc
->tap_dev
), sc
->tap_flags
);
523 * Network interface initialization function (called with if serializer held)
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
);
534 TAPDEBUG(ifp
, "initializing, minor = %#x, flags = 0x%x\n",
535 minor(sc
->tap_dev
), sc
->tap_flags
);
537 ASSERT_IFNET_SERIALIZED_ALL(ifp
);
541 ifp
->if_flags
|= IFF_RUNNING
;
542 ifsq_clr_oactive(ifsq
);
544 /* attempt to start output */
545 tapifstart(ifp
, ifsq
);
549 tapifflags(struct tap_softc
*sc
)
551 struct ifnet
*ifp
= &sc
->tap_if
;
553 ASSERT_IFNET_SERIALIZED_ALL(ifp
);
555 if (ifp
->if_flags
& IFF_UP
) {
556 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
566 * Process an ioctl request on network interface (called with if serializer
572 tapifioctl(struct ifnet
*ifp
, u_long cmd
, caddr_t data
, struct ucred
*cr
)
574 struct tap_softc
*sc
= ifp
->if_softc
;
575 struct ifreq
*ifr
= NULL
;
576 struct ifstat
*ifs
= NULL
;
577 struct ifmediareq
*ifmr
= NULL
;
587 ifr
= (struct ifreq
*)data
;
588 ifp
->if_mtu
= ifr
->ifr_mtu
;
589 TAPDEBUG(ifp
, "mtu set\n");
594 error
= ether_ioctl(ifp
, cmd
, data
);
603 * The bridge code needs this when running the
604 * spanning tree protocol.
606 ifmr
= (struct ifmediareq
*)data
;
607 dummy
= ifmr
->ifm_count
;
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
;
615 int media
= IFM_ETHER
;
616 error
= copyout(&media
, ifmr
->ifm_ulist
, sizeof(int));
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
);
630 ksnprintf(ifs
->ascii
+ dummy
,
631 sizeof(ifs
->ascii
) - dummy
,
632 "\tOpened by <unknown>\n");
648 * Queue packets from higher level ready to put out (called with if serializer
654 tapifstart(struct ifnet
*ifp
, struct ifaltq_subque
*ifsq
)
656 struct tap_softc
*sc
= ifp
->if_softc
;
661 ASSERT_ALTQ_SQ_DEFAULT(ifp
, ifsq
);
662 TAPDEBUG(ifp
, "starting, minor = %#x\n", minor(sc
->tap_dev
));
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
);
671 ifsq_set_oactive(ifsq
);
674 while ((m
= ifsq_dequeue(ifsq
)) != NULL
) {
677 IFNET_STAT_INC(ifp
, oerrors
, 1);
681 IFNET_STAT_INC(ifp
, opackets
, 1);
687 if (sc
->tap_flags
& TAP_RWAIT
) {
688 sc
->tap_flags
&= ~TAP_RWAIT
;
692 KNOTE(&sc
->tap_rkq
.ki_note
, 0);
694 if ((sc
->tap_flags
& TAP_ASYNC
) && (sc
->tap_sigio
!= NULL
)) {
696 pgsigio(sc
->tap_sigio
, SIGIO
, 0);
701 ifsq_clr_oactive(ifsq
);
705 tapifstop(struct tap_softc
*sc
, int clear_flags
)
707 struct ifnet
*ifp
= &sc
->tap_if
;
709 ASSERT_IFNET_SERIALIZED_ALL(ifp
);
710 IF_DRAIN(&sc
->tap_devq
);
711 sc
->tap_flags
&= ~TAP_CLOSEDOWN
;
713 ifp
->if_flags
&= ~IFF_RUNNING
;
714 ifsq_clr_oactive(ifq_get_subq_default(&ifp
->if_snd
));
721 * The ops interface is now pretty minimal. Called via fileops with nothing
727 tapioctl(struct dev_ioctl_args
*ap
)
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
;
734 struct tapinfo
*tapp
= NULL
;
738 ifnet_serialize_all(ifp
);
743 tapp
= (struct tapinfo
*)data
;
744 if (ifp
->if_type
!= tapp
->type
)
746 ifp
->if_mtu
= tapp
->mtu
;
747 ifp
->if_baudrate
= tapp
->baudrate
;
751 tapp
= (struct tapinfo
*)data
;
752 tapp
->mtu
= ifp
->if_mtu
;
753 tapp
->type
= ifp
->if_type
;
754 tapp
->baudrate
= ifp
->if_baudrate
;
758 ifr
= (struct ifreq
*)data
;
759 strlcpy(ifr
->ifr_name
, ifp
->if_xname
, IFNAMSIZ
);
763 tapdebug
= *(int *)data
;
767 *(int *)data
= tapdebug
;
772 sc
->tap_flags
|= TAP_ASYNC
;
774 sc
->tap_flags
&= ~TAP_ASYNC
;
778 /* Take a look at devq first */
779 IF_POLL(&sc
->tap_devq
, mb
);
782 for(; mb
!= NULL
; mb
= mb
->m_next
)
783 *(int *)data
+= mb
->m_len
;
785 *(int *)data
= ifsq_poll_pktlen(
786 ifq_get_subq_default(&ifp
->if_snd
));
791 error
= fsetown(*(int *)data
, &sc
->tap_sigio
);
793 error
= fsetown(*(int *)data
, &sc
->tap_sigtd
);
797 *(int *)data
= fgetown(&sc
->tap_sigio
);
800 /* this is deprecated, FIOSETOWN should be used instead */
802 error
= fsetown(-(*(int *)data
), &sc
->tap_sigio
);
805 /* this is deprecated, FIOGETOWN should be used instead */
807 *(int *)data
= -fgetown(&sc
->tap_sigio
);
811 * Support basic control of the network interface via the device file.
812 * e.g., vke(4) currently uses the 'SIOCGIFADDR' ioctl.
816 bcopy(&ifp
->if_flags
, data
, sizeof(ifp
->if_flags
));
820 bcopy(sc
->ether_addr
, data
, sizeof(sc
->ether_addr
));
824 bcopy(data
, sc
->ether_addr
, sizeof(sc
->ether_addr
));
832 ifnet_deserialize_all(ifp
);
840 * The ops read interface - reads a packet at a time, or at
841 * least as much of a packet as can be read.
843 * Called from the fileops interface with nothing held.
848 tapread(struct dev_read_args
*ap
)
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
;
857 TAPDEBUG(ifp
, "reading, minor = %#x\n", minor(dev
));
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
);
866 sc
->tap_flags
&= ~TAP_RWAIT
;
868 /* sleep until we get a packet */
870 ifnet_serialize_all(ifp
);
871 IF_DEQUEUE(&sc
->tap_devq
, m0
);
873 if (ap
->a_ioflag
& IO_NDELAY
) {
874 ifnet_deserialize_all(ifp
);
875 return (EWOULDBLOCK
);
877 sc
->tap_flags
|= TAP_RWAIT
;
878 tsleep_interlock(sc
, PCATCH
);
879 ifnet_deserialize_all(ifp
);
880 error
= tsleep(sc
, PCATCH
| PINTERLOCKED
, "taprd", 0);
884 ifnet_deserialize_all(ifp
);
886 } while (m0
== NULL
);
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
);
896 error
= uiomove(mtod(m0
, caddr_t
), (size_t)len
, uio
);
901 TAPDEBUG(ifp
, "dropping mbuf, minor = %#x\n", minor(dev
));
911 * The ops write interface - an atomic write is a packet - or else!
913 * Called from the fileops interface with nothing held.
918 tapwrite(struct dev_write_args
*ap
)
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
;
928 TAPDEBUG(ifp
, "writing, minor = %#x\n", minor(dev
));
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
);
936 if (uio
->uio_resid
== 0)
939 if (uio
->uio_resid
> TAPMRU
) {
940 TAPDEBUG(ifp
, "invalid packet len = %zu, minor = %#x\n",
941 uio
->uio_resid
, minor(dev
));
945 tlen
= uio
->uio_resid
;
947 /* get a header mbuf */
948 MGETHDR(m
, M_WAITOK
, MT_DATA
);
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
);
960 if (uio
->uio_resid
> 0) {
961 MGET(m
, M_WAITOK
, MT_DATA
);
966 IFNET_STAT_INC(ifp
, ierrors
, 1);
972 top
->m_pkthdr
.len
= (int)tlen
;
973 top
->m_pkthdr
.rcvif
= ifp
;
976 * Ethernet bridge and bpf are handled in ether_input
978 * adjust mbuf and give packet to the ether_input
980 ifnet_serialize_all(ifp
);
981 ifp
->if_input(ifp
, top
, NULL
, -1);
982 IFNET_STAT_INC(ifp
, ipackets
, 1); /* ibytes are counted in ether_input */
983 ifnet_deserialize_all(ifp
);
990 * tapkqfilter - called from the fileops interface with nothing held
995 tapkqfilter(struct dev_kqfilter_args
*ap
)
997 cdev_t dev
= ap
->a_head
.a_dev
;
998 struct knote
*kn
= ap
->a_kn
;
999 struct tap_softc
*sc
= dev
->si_drv1
;
1002 list
= &sc
->tap_rkq
.ki_note
;
1005 switch (kn
->kn_filter
) {
1007 kn
->kn_fop
= &tapread_filtops
;
1008 kn
->kn_hook
= (void *)sc
;
1011 kn
->kn_fop
= &tapwrite_filtops
;
1012 kn
->kn_hook
= (void *)sc
;
1015 ap
->a_result
= EOPNOTSUPP
;
1019 knote_insert(list
, kn
);
1024 tap_filter_read(struct knote
*kn
, long hint
)
1026 struct tap_softc
*sc
= (struct tap_softc
*)kn
->kn_hook
;
1028 if (IF_QEMPTY(&sc
->tap_devq
) == 0) /* XXX serializer */
1035 tap_filter_write(struct knote
*kn
, long hint
)
1037 /* Always ready for a write */
1042 tap_filter_detach(struct knote
*kn
)
1044 struct tap_softc
*sc
= (struct tap_softc
*)kn
->kn_hook
;
1046 knote_remove(&sc
->tap_rkq
.ki_note
, kn
);