From cd086e3c60be82d5effacbacf80dc20dd2584d33 Mon Sep 17 00:00:00 2001 From: Aaron LI Date: Sat, 7 Jul 2018 18:57:10 +0800 Subject: [PATCH] if_tap: Some small tweaks and cleanups * Consistently use the TAP define instead of "tap", also remove the CDEV_NAME define. * Consistently use "tap_if" instead of "arpcom.ac_if". * Better name the kqueue functions, and move the structs to the beginning. * Reorder to better group related functions. * Explicitly include the required header. * Use variable "sc" instead of "tp" to refer to "struct tap_softc". * Staticize the bitmap variable. * Use the variable unit = minor(dev) more. * Improve the debug messages. * Various minor style tweaks and cleanups. --- sys/net/tap/if_tap.c | 617 ++++++++++++++++++++-------------------- sys/net/tap/if_tap.h | 8 +- sys/net/tap/if_tapvar.h | 25 +- 3 files changed, 323 insertions(+), 327 deletions(-) diff --git a/sys/net/tap/if_tap.c b/sys/net/tap/if_tap.c index 00ce4e7d95..20cb975a8b 100644 --- a/sys/net/tap/if_tap.c +++ b/sys/net/tap/if_tap.c @@ -57,9 +57,10 @@ #include #include #include - #include #include +#include +#include #include #include @@ -69,14 +70,13 @@ #include #include #include -#include #include #include "if_tapvar.h" #include "if_tap.h" -#define TAP_IFFLAGS (IFF_BROADCAST|IFF_SIMPLEX|IFF_MULTICAST) +#define TAP_IFFLAGS (IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST) #if NTAP <= 1 #define TAP_PREALLOCATED_UNITS 4 @@ -84,17 +84,14 @@ #define TAP_PREALLOCATED_UNITS NTAP #endif -#define CDEV_NAME "tap" +#define TAP "tap" #define TAPDEBUG if (tapdebug) if_printf -#define TAP "tap" #define VMNET "vmnet" #define VMNET_DEV_MASK 0x00010000 -DEVFS_DEFINE_CLONE_BITMAP(tap); - /* module */ -static int tapmodevent (module_t, int, void *); +static int tapmodevent(module_t, int, void *); /* device */ static struct tap_softc *tapcreate(int, cdev_t, int); @@ -104,17 +101,14 @@ static void tapdestroy(struct tap_softc *); static int tap_clone_create(struct if_clone *, int, caddr_t); static int tap_clone_destroy(struct ifnet *); - /* network interface */ -static void tapifstart (struct ifnet *, - struct ifaltq_subque *); -static int tapifioctl (struct ifnet *, u_long, caddr_t, - struct ucred *); -static void tapifinit (void *); +static void tapifinit(void *); +static void tapifstart(struct ifnet *, struct ifaltq_subque *); +static int tapifioctl(struct ifnet *, u_long, caddr_t, + struct ucred *); static void tapifstop(struct tap_softc *, int); static void tapifflags(struct tap_softc *); - /* character device */ static d_open_t tapopen; static d_clone_t tapclone; @@ -125,7 +119,7 @@ static d_ioctl_t tapioctl; static d_kqfilter_t tapkqfilter; static struct dev_ops tap_ops = { - { CDEV_NAME, 0, 0 }, + { TAP, 0, 0 }, .d_open = tapopen, .d_close = tapclose, .d_read = tapread, @@ -134,17 +128,37 @@ static struct dev_ops tap_ops = { .d_kqfilter = tapkqfilter }; -static int taprefcnt = 0; /* module ref. counter */ +/* kqueue support */ +static void tap_filter_detach(struct knote *); +static int tap_filter_read(struct knote *, long); +static int tap_filter_write(struct knote *, long); + +static struct filterops tapread_filtops = { + FILTEROP_ISFD, + NULL, + tap_filter_detach, + tap_filter_read +}; +static struct filterops tapwrite_filtops = { + FILTEROP_ISFD, + NULL, + tap_filter_detach, + tap_filter_write +}; + +static int tapdebug = 0; /* debug flag */ +static int taprefcnt = 0; /* module ref. counter */ static int taplastunit = -1; /* max. open unit number */ -static int tapdebug = 0; /* debug flag */ -static int tapuopen = 0; /* all user open() */ -static int tapuponopen = 0; /* IFF_UP */ - -MALLOC_DECLARE(M_TAP); -MALLOC_DEFINE(M_TAP, CDEV_NAME, "Ethernet tunnel interface"); -struct if_clone tap_cloner = IF_CLONE_INITIALIZER("tap", - tap_clone_create, tap_clone_destroy, - 0, IF_MAXUNIT); +static int tapuopen = 0; /* allow user open() */ +static int tapuponopen = 0; /* IFF_UP when opened */ + +static MALLOC_DEFINE(M_TAP, TAP, "Ethernet tunnel interface"); + +static DEVFS_DEFINE_CLONE_BITMAP(tap); + +struct if_clone tap_cloner = IF_CLONE_INITIALIZER( + TAP, tap_clone_create, tap_clone_destroy, 0, IF_MAXUNIT); + static SLIST_HEAD(,tap_softc) tap_listhead = SLIST_HEAD_INITIALIZER(&tap_listhead); @@ -169,7 +183,7 @@ static int tapmodevent(module_t mod, int type, void *data) { static int attached = 0; - struct tap_softc *tp, *ntp; + struct tap_softc *sc, *sc_tmp; int i; switch (type) { @@ -177,14 +191,14 @@ tapmodevent(module_t mod, int type, void *data) if (attached) return (EEXIST); - make_autoclone_dev(&tap_ops, &DEVFS_CLONE_BITMAP(tap), tapclone, - UID_ROOT, GID_WHEEL, 0600, "tap"); + make_autoclone_dev(&tap_ops, &DEVFS_CLONE_BITMAP(tap), + tapclone, UID_ROOT, GID_WHEEL, 0600, TAP); SLIST_INIT(&tap_listhead); if_clone_attach(&tap_cloner); for (i = 0; i < TAP_PREALLOCATED_UNITS; ++i) { make_dev(&tap_ops, i, UID_ROOT, GID_WHEEL, - 0600, "tap%d", i); + 0600, "%s%d", TAP, i); devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(tap), i); } @@ -197,15 +211,14 @@ tapmodevent(module_t mod, int type, void *data) if_clone_detach(&tap_cloner); - /* Maintain tap ifs in a local list */ - SLIST_FOREACH_MUTABLE(tp, &tap_listhead, tap_link, ntp) - tapdestroy(tp); - - attached = 0; + SLIST_FOREACH_MUTABLE(sc, &tap_listhead, tap_link, sc_tmp) + tapdestroy(sc); - devfs_clone_handler_del("tap"); + devfs_clone_handler_del(TAP); dev_ops_remove_all(&tap_ops); devfs_clone_bitmap_uninit(&DEVFS_CLONE_BITMAP(tap)); + + attached = 0; break; default: @@ -213,7 +226,7 @@ tapmodevent(module_t mod, int type, void *data) } return (0); -} /* tapmodevent */ +} /* @@ -222,18 +235,17 @@ tapmodevent(module_t mod, int type, void *data) static struct tap_softc * tapcreate(int unit, cdev_t dev, int flags) { - const char *name = TAP; - struct ifnet *ifp; - struct tap_softc *tp; - uint8_t ether_addr[ETHER_ADDR_LEN]; + struct tap_softc *sc; + struct ifnet *ifp; + uint8_t ether_addr[ETHER_ADDR_LEN]; - tp = kmalloc(sizeof(*tp), M_TAP, M_WAITOK | M_ZERO); - dev->si_drv1 = tp; - tp->tap_dev = dev; - tp->tap_unit = unit; - tp->tap_flags |= flags; + sc = kmalloc(sizeof(*sc), M_TAP, M_WAITOK | M_ZERO); + dev->si_drv1 = sc; + sc->tap_dev = dev; + sc->tap_unit = unit; + sc->tap_flags |= flags; - reference_dev(dev); /* tp association */ + reference_dev(dev); /* device association */ /* generate fake MAC address: 00 bd xx xx xx unit_no */ ether_addr[0] = 0x00; @@ -241,11 +253,11 @@ tapcreate(int unit, cdev_t dev, int flags) bcopy(&ticks, ðer_addr[2], 3); ether_addr[5] = (u_char)unit; - /* fill the rest and attach interface */ - ifp = &tp->tap_if; - ifp->if_softc = tp; + /* fill the rest and attach interface */ + ifp = &sc->tap_if; + ifp->if_softc = sc; - if_initname(ifp, name, unit); + if_initname(ifp, TAP, unit); if (unit > taplastunit) taplastunit = unit; @@ -259,24 +271,24 @@ tapcreate(int unit, cdev_t dev, int flags) ether_ifattach(ifp, ether_addr, NULL); - tp->tap_flags |= TAP_INITED; - tp->tap_devq.ifq_maxlen = ifqmaxlen; + sc->tap_flags |= TAP_INITED; + sc->tap_devq.ifq_maxlen = ifqmaxlen; - SLIST_INSERT_HEAD(&tap_listhead, tp, tap_link); + SLIST_INSERT_HEAD(&tap_listhead, sc, tap_link); TAPDEBUG(ifp, "created. minor = %#x\n", minor(dev)); - return (tp); + return (sc); } static struct tap_softc * tapfind(int unit) { - struct tap_softc *tp; + struct tap_softc *sc; - SLIST_FOREACH(tp, &tap_listhead, tap_link) { - if (tp->tap_unit == unit) - return(tp); + SLIST_FOREACH(sc, &tap_listhead, tap_link) { + if (sc->tap_unit == unit) + return (sc); } return (NULL); } @@ -288,33 +300,35 @@ tapfind(int unit) */ static int tap_clone_create(struct if_clone *ifc __unused, int unit, - caddr_t param __unused) + caddr_t param __unused) { - struct tap_softc *tp; + struct tap_softc *sc; cdev_t dev; - tp = tapfind(unit); - if (tp == NULL) { + sc = tapfind(unit); + if (sc == NULL) { if (!devfs_clone_bitmap_chk(&DEVFS_CLONE_BITMAP(tap), unit)) { devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(tap), unit); dev = make_dev(&tap_ops, unit, UID_ROOT, GID_WHEEL, - 0600, "%s%d", TAP, unit); + 0600, "%s%d", TAP, unit); } else { dev = devfs_find_device_by_name("%s%d", TAP, unit); } KKASSERT(dev != NULL); - tp = tapcreate(unit, dev, TAP_MANUALMAKE); + sc = tapcreate(unit, dev, TAP_MANUALMAKE); + } else { + dev = sc->tap_dev; } - tp->tap_flags |= TAP_CLONE; - TAPDEBUG(&tp->tap_if, "clone created. minor = %#x tap_flags = 0x%x\n", - minor(tp->tap_dev), tp->tap_flags); + sc->tap_flags |= TAP_CLONE; + TAPDEBUG(&sc->tap_if, "clone created, minor = %#x, flags = 0x%x\n", + minor(dev), sc->tap_flags); return (0); } /* - * tapopen + * tapopen * * to open tunnel. must be superuser */ @@ -322,38 +336,38 @@ static int tapopen(struct dev_open_args *ap) { cdev_t dev = NULL; - struct tap_softc *tp = NULL; + struct tap_softc *sc = NULL; struct ifnet *ifp = NULL; int error; - if (tapuopen == 0 && + if (tapuopen == 0 && (error = priv_check_cred(ap->a_cred, PRIV_ROOT, 0)) != 0) return (error); get_mplock(); dev = ap->a_head.a_dev; - tp = dev->si_drv1; - if (tp == NULL) - tp = tapcreate(minor(dev), dev, TAP_MANUALMAKE); - if (tp->tap_flags & TAP_OPEN) { + sc = dev->si_drv1; + if (sc == NULL) + sc = tapcreate(minor(dev), dev, TAP_MANUALMAKE); + if (sc->tap_flags & TAP_OPEN) { rel_mplock(); return (EBUSY); } - ifp = &tp->arpcom.ac_if; + ifp = &sc->tap_if; - if ((tp->tap_flags & TAP_CLONE) == 0) { + if ((sc->tap_flags & TAP_CLONE) == 0) { EVENTHANDLER_INVOKE(ifnet_attach_event, ifp); /* Announce the return of the interface. */ rt_ifannouncemsg(ifp, IFAN_ARRIVAL); } - bcopy(tp->arpcom.ac_enaddr, tp->ether_addr, sizeof(tp->ether_addr)); + bcopy(sc->arpcom.ac_enaddr, sc->ether_addr, sizeof(sc->ether_addr)); if (curthread->td_proc) - fsetown(curthread->td_proc->p_pid, &tp->tap_sigtd); - tp->tap_flags |= TAP_OPEN; - taprefcnt ++; + fsetown(curthread->td_proc->p_pid, &sc->tap_sigtd); + sc->tap_flags |= TAP_OPEN; + taprefcnt++; if (tapuponopen && (ifp->if_flags & IFF_UP) == 0) { crit_enter(); @@ -361,14 +375,14 @@ tapopen(struct dev_open_args *ap) crit_exit(); ifnet_serialize_all(ifp); - tapifflags(tp); + tapifflags(sc); ifnet_deserialize_all(ifp); - tp->tap_flags |= TAP_CLOSEDOWN; + sc->tap_flags |= TAP_CLOSEDOWN; } - TAPDEBUG(ifp, "opened. minor = %#x, refcnt = %d, taplastunit = %d\n", - minor(tp->tap_dev), taprefcnt, taplastunit); + TAPDEBUG(ifp, "opened, minor = %#x, refcnt = %d, taplastunit = %d\n", + minor(dev), taprefcnt, taplastunit); rel_mplock(); return (0); @@ -395,8 +409,9 @@ static int tapclose(struct dev_close_args *ap) { cdev_t dev = ap->a_head.a_dev; - struct tap_softc *tp = dev->si_drv1; - struct ifnet *ifp = &tp->tap_if; + struct tap_softc *sc = dev->si_drv1; + struct ifnet *ifp = &sc->tap_if; + int unit = minor(dev); int clear_flags = 0; get_mplock(); @@ -413,18 +428,18 @@ tapclose(struct dev_close_args *ap) * If the interface is cloned, then we bring it down during * closing only if it was brought up during opening. */ - if ((tp->tap_flags & TAP_VMNET) == 0 && - ((tp->tap_flags & TAP_CLONE) == 0 || - (tp->tap_flags & TAP_CLOSEDOWN))) { + if ((sc->tap_flags & TAP_VMNET) == 0 && + ((sc->tap_flags & TAP_CLONE) == 0 || + (sc->tap_flags & TAP_CLOSEDOWN))) { if (ifp->if_flags & IFF_UP) if_down(ifp); clear_flags = 1; } ifnet_serialize_all(ifp); - tapifstop(tp, clear_flags); + tapifstop(sc, clear_flags); ifnet_deserialize_all(ifp); - if ((tp->tap_flags & TAP_CLONE) == 0) { + if ((sc->tap_flags & TAP_CLONE) == 0) { if_purgeaddrs_nolink(ifp); EVENTHANDLER_INVOKE(ifnet_detach_event, ifp); @@ -433,77 +448,74 @@ tapclose(struct dev_close_args *ap) rt_ifannouncemsg(ifp, IFAN_DEPARTURE); } - funsetown(&tp->tap_sigio); - tp->tap_sigio = NULL; - KNOTE(&tp->tap_rkq.ki_note, 0); + funsetown(&sc->tap_sigio); + sc->tap_sigio = NULL; + KNOTE(&sc->tap_rkq.ki_note, 0); - tp->tap_flags &= ~TAP_OPEN; - funsetown(&tp->tap_sigtd); - tp->tap_sigtd = NULL; + sc->tap_flags &= ~TAP_OPEN; + funsetown(&sc->tap_sigtd); + sc->tap_sigtd = NULL; - taprefcnt --; + taprefcnt--; if (taprefcnt < 0) { taprefcnt = 0; if_printf(ifp, "minor = %#x, refcnt = %d is out of sync. " - "set refcnt to 0\n", minor(tp->tap_dev), taprefcnt); + "set refcnt to 0\n", unit, taprefcnt); } - TAPDEBUG(ifp, "closed. minor = %#x, refcnt = %d, taplastunit = %d\n", - minor(tp->tap_dev), taprefcnt, taplastunit); + TAPDEBUG(ifp, "closed, minor = %#x, refcnt = %d, taplastunit = %d\n", + unit, taprefcnt, taplastunit); - /* - * Only auto-destroy if the interface was not manually - * created. - */ - if ((tp->tap_flags & TAP_MANUALMAKE) == 0 && - tp->tap_unit >= TAP_PREALLOCATED_UNITS) { - tapdestroy(tp); + /* Only auto-destroy if the interface was not manually created. */ + if ((sc->tap_flags & TAP_MANUALMAKE) == 0 && + unit >= TAP_PREALLOCATED_UNITS) { + tapdestroy(sc); } rel_mplock(); return (0); } + /* * tapdestroy: * * Destroy a tap instance. */ static void -tapdestroy(struct tap_softc *tp) +tapdestroy(struct tap_softc *sc) { - struct ifnet *ifp = &tp->arpcom.ac_if; - cdev_t dev; + struct ifnet *ifp = &sc->tap_if; + cdev_t dev = sc->tap_dev; + int unit = minor(dev); - TAPDEBUG(ifp, "destroyed. minor = %#x, refcnt = %d, taplastunit = %d\n", - minor(tp->tap_dev), taprefcnt, taplastunit); + TAPDEBUG(ifp, "destroyed, minor = %#x, refcnt = %d, taplastunit = %d\n", + unit, taprefcnt, taplastunit); ifnet_serialize_all(ifp); - tapifstop(tp, 1); + tapifstop(sc, 1); ifnet_deserialize_all(ifp); ether_ifdetach(ifp); - SLIST_REMOVE(&tap_listhead, tp, tap_softc, tap_link); + SLIST_REMOVE(&tap_listhead, sc, tap_softc, tap_link); - dev = tp->tap_dev; - tp->tap_dev = NULL; + sc->tap_dev = NULL; dev->si_drv1 = NULL; + release_dev(dev); /* device disassociation */ - release_dev(dev); /* tp association */ - - /* - * Also destroy the cloned device - */ - if (tp->tap_unit >= TAP_PREALLOCATED_UNITS) { + /* Also destroy the cloned device */ + if (unit >= TAP_PREALLOCATED_UNITS) { destroy_dev(dev); - devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(tap), tp->tap_unit); + devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(tap), + sc->tap_unit); } - kfree(tp, M_TAP); + kfree(sc, M_TAP); taplastunit--; } + /* * tap_clone_destroy: * @@ -512,18 +524,19 @@ tapdestroy(struct tap_softc *tp) static int tap_clone_destroy(struct ifnet *ifp) { - struct tap_softc *tp = ifp->if_softc; - - if ((tp->tap_flags & TAP_CLONE) == 0) - return ENXIO; + struct tap_softc *sc = ifp->if_softc; - TAPDEBUG(&tp->tap_if, "clone destroyed. minor = %#x tap_flags = 0x%x\n", - minor(tp->tap_dev), tp->tap_flags); - tapdestroy(tp); + if ((sc->tap_flags & TAP_CLONE) == 0) + return (ENXIO); - return 0; + TAPDEBUG(&sc->tap_if, "clone destroyed, minor = %#x, flags = 0x%x\n", + minor(sc->tap_dev), sc->tap_flags); + tapdestroy(sc); + + return (0); } + /* * tapifinit * @@ -534,16 +547,16 @@ tap_clone_destroy(struct ifnet *ifp) static void tapifinit(void *xtp) { - struct tap_softc *tp = xtp; - struct ifnet *ifp = &tp->tap_if; + struct tap_softc *sc = xtp; + struct ifnet *ifp = &sc->tap_if; struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd); - TAPDEBUG(ifp, "initializing, minor = %#x tap_flags = 0x%x\n", - minor(tp->tap_dev), tp->tap_flags); + TAPDEBUG(ifp, "initializing, minor = %#x, flags = 0x%x\n", + minor(sc->tap_dev), sc->tap_flags); ASSERT_IFNET_SERIALIZED_ALL(ifp); - tapifstop(tp, 1); + tapifstop(sc, 1); ifp->if_flags |= IFF_RUNNING; ifsq_clr_oactive(ifsq); @@ -552,6 +565,26 @@ tapifinit(void *xtp) tapifstart(ifp, ifsq); } +static void +tapifflags(struct tap_softc *sc) +{ + struct ifnet *ifp = &sc->tap_if; + + ASSERT_IFNET_SERIALIZED_ALL(ifp); + if ((sc->tap_flags & TAP_VMNET) == 0) { + /* + * Only for non-vmnet tap(4) + */ + if (ifp->if_flags & IFF_UP) { + if ((ifp->if_flags & IFF_RUNNING) == 0) + tapifinit(sc); + } else { + tapifstop(sc, 1); + } + } else { + /* XXX */ + } +} /* * tapifioctl @@ -564,78 +597,74 @@ tapifinit(void *xtp) static int tapifioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr) { - struct tap_softc *tp = (struct tap_softc *)(ifp->if_softc); - struct ifstat *ifs = NULL; - struct ifmediareq *ifmr = NULL; - int error = 0; - int dummy; + struct tap_softc *sc = ifp->if_softc; + struct ifstat *ifs = NULL; + struct ifmediareq *ifmr = NULL; + int error = 0; + int dummy; switch (cmd) { - case SIOCSIFADDR: - case SIOCGIFADDR: - case SIOCSIFMTU: - error = ether_ioctl(ifp, cmd, data); - break; + case SIOCADDMULTI: /* XXX - just like vmnet does */ + case SIOCDELMULTI: + break; - case SIOCSIFFLAGS: - tapifflags(tp); - break; + case SIOCSIFADDR: + case SIOCGIFADDR: + case SIOCSIFMTU: + error = ether_ioctl(ifp, cmd, data); + break; - case SIOCADDMULTI: /* XXX -- just like vmnet does */ - case SIOCDELMULTI: - break; + case SIOCSIFFLAGS: + tapifflags(sc); + break; - case SIOCGIFMEDIA: - /* - * The bridge code needs this when running the - * spanning tree protocol. - */ - ifmr = (struct ifmediareq *)data; - dummy = ifmr->ifm_count; - ifmr->ifm_count = 1; - ifmr->ifm_status = IFM_AVALID; - ifmr->ifm_active = IFM_ETHER; - if (tp->tap_flags & TAP_OPEN) - ifmr->ifm_status |= IFM_ACTIVE; - ifmr->ifm_current = ifmr->ifm_active; - if (dummy >= 1) { - int media = IFM_ETHER; - error = copyout(&media, - ifmr->ifm_ulist, - sizeof(int)); - } - break; + case SIOCGIFMEDIA: + /* + * The bridge code needs this when running the + * spanning tree protocol. + */ + ifmr = (struct ifmediareq *)data; + dummy = ifmr->ifm_count; + ifmr->ifm_count = 1; + ifmr->ifm_status = IFM_AVALID; + ifmr->ifm_active = IFM_ETHER; + if (sc->tap_flags & TAP_OPEN) + ifmr->ifm_status |= IFM_ACTIVE; + ifmr->ifm_current = ifmr->ifm_active; + if (dummy >= 1) { + int media = IFM_ETHER; + error = copyout(&media, ifmr->ifm_ulist, sizeof(int)); + } + break; - case SIOCGIFSTATUS: - ifs = (struct ifstat *)data; - dummy = strlen(ifs->ascii); - if ((tp->tap_flags & TAP_OPEN) && - dummy < sizeof(ifs->ascii)) { - if (tp->tap_sigtd && tp->tap_sigtd->sio_proc) { - ksnprintf(ifs->ascii + dummy, - sizeof(ifs->ascii) - dummy, - "\tOpened by pid %d\n", - (int)tp->tap_sigtd->sio_proc->p_pid); - } else { - ksnprintf(ifs->ascii + dummy, - sizeof(ifs->ascii) - dummy, - "\tOpened by \n"); - } + case SIOCGIFSTATUS: + ifs = (struct ifstat *)data; + dummy = strlen(ifs->ascii); + if ((sc->tap_flags & TAP_OPEN) && dummy < sizeof(ifs->ascii)) { + if (sc->tap_sigtd && sc->tap_sigtd->sio_proc) { + ksnprintf(ifs->ascii + dummy, + sizeof(ifs->ascii) - dummy, + "\tOpened by pid %d\n", + (int)sc->tap_sigtd->sio_proc->p_pid); + } else { + ksnprintf(ifs->ascii + dummy, + sizeof(ifs->ascii) - dummy, + "\tOpened by \n"); } - break; + } + break; - default: - error = EINVAL; - break; + default: + error = EINVAL; + break; } return (error); } - /* - * tapifstart - * + * tapifstart + * * Queue packets from higher level ready to put out (called with if serializer * held) * @@ -644,30 +673,30 @@ tapifioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr) static void tapifstart(struct ifnet *ifp, struct ifaltq_subque *ifsq) { - struct tap_softc *tp = ifp->if_softc; + struct tap_softc *sc = ifp->if_softc; struct ifqueue *ifq; struct mbuf *m; int has_data = 0; ASSERT_ALTQ_SQ_DEFAULT(ifp, ifsq); - TAPDEBUG(ifp, "starting, minor = %#x\n", minor(tp->tap_dev)); + TAPDEBUG(ifp, "starting, minor = %#x\n", minor(sc->tap_dev)); /* * do not junk pending output if we are in VMnet mode. * XXX: can this do any harm because of queue overflow? */ - if (((tp->tap_flags & TAP_VMNET) == 0) && - ((tp->tap_flags & TAP_READY) != TAP_READY)) { - TAPDEBUG(ifp, "not ready. minor = %#x, tap_flags = 0x%x\n", - minor(tp->tap_dev), tp->tap_flags); + if (((sc->tap_flags & TAP_VMNET) == 0) && + ((sc->tap_flags & TAP_READY) != TAP_READY)) { + TAPDEBUG(ifp, "not ready, minor = %#x, flags = 0x%x\n", + minor(sc->tap_dev), sc->tap_flags); ifsq_purge(ifsq); return; } ifsq_set_oactive(ifsq); - ifq = &tp->tap_devq; + ifq = &sc->tap_devq; while ((m = ifsq_dequeue(ifsq)) != NULL) { if (IF_QFULL(ifq)) { IF_DROP(ifq); @@ -681,16 +710,16 @@ tapifstart(struct ifnet *ifp, struct ifaltq_subque *ifsq) } if (has_data) { - if (tp->tap_flags & TAP_RWAIT) { - tp->tap_flags &= ~TAP_RWAIT; - wakeup((caddr_t)tp); + if (sc->tap_flags & TAP_RWAIT) { + sc->tap_flags &= ~TAP_RWAIT; + wakeup((caddr_t)sc); } - KNOTE(&tp->tap_rkq.ki_note, 0); + KNOTE(&sc->tap_rkq.ki_note, 0); - if ((tp->tap_flags & TAP_ASYNC) && (tp->tap_sigio != NULL)) { + if ((sc->tap_flags & TAP_ASYNC) && (sc->tap_sigio != NULL)) { get_mplock(); - pgsigio(tp->tap_sigio, SIGIO, 0); + pgsigio(sc->tap_sigio, SIGIO, 0); rel_mplock(); } } @@ -698,6 +727,19 @@ tapifstart(struct ifnet *ifp, struct ifaltq_subque *ifsq) ifsq_clr_oactive(ifsq); } +static void +tapifstop(struct tap_softc *sc, int clear_flags) +{ + struct ifnet *ifp = &sc->tap_if; + + ASSERT_IFNET_SERIALIZED_ALL(ifp); + IF_DRAIN(&sc->tap_devq); + sc->tap_flags &= ~TAP_CLOSEDOWN; + if (clear_flags) { + ifp->if_flags &= ~IFF_RUNNING; + ifsq_clr_oactive(ifq_get_subq_default(&ifp->if_snd)); + } +} /* * tapioctl @@ -712,9 +754,9 @@ tapioctl(struct dev_ioctl_args *ap) { cdev_t dev = ap->a_head.a_dev; caddr_t data = ap->a_data; - struct tap_softc *tp = dev->si_drv1; - struct ifnet *ifp = &tp->tap_if; - struct tapinfo *tapp = NULL; + struct tap_softc *sc = dev->si_drv1; + struct ifnet *ifp = &sc->tap_if; + struct tapinfo *tapp = NULL; struct mbuf *mb; short f; int error; @@ -747,14 +789,14 @@ tapioctl(struct dev_ioctl_args *ap) case FIOASYNC: if (*(int *)data) - tp->tap_flags |= TAP_ASYNC; + sc->tap_flags |= TAP_ASYNC; else - tp->tap_flags &= ~TAP_ASYNC; + sc->tap_flags &= ~TAP_ASYNC; break; case FIONREAD: /* Take a look at devq first */ - IF_POLL(&tp->tap_devq, mb); + IF_POLL(&sc->tap_devq, mb); if (mb != NULL) { *(int *)data = 0; for(; mb != NULL; mb = mb->m_next) @@ -766,21 +808,21 @@ tapioctl(struct dev_ioctl_args *ap) break; case FIOSETOWN: - error = fsetown(*(int *)data, &tp->tap_sigio); + error = fsetown(*(int *)data, &sc->tap_sigio); break; case FIOGETOWN: - *(int *)data = fgetown(&tp->tap_sigio); + *(int *)data = fgetown(&sc->tap_sigio); break; /* this is deprecated, FIOSETOWN should be used instead */ case TIOCSPGRP: - error = fsetown(-(*(int *)data), &tp->tap_sigio); + error = fsetown(-(*(int *)data), &sc->tap_sigio); break; /* this is deprecated, FIOGETOWN should be used instead */ case TIOCGPGRP: - *(int *)data = -fgetown(&tp->tap_sigio); + *(int *)data = -fgetown(&sc->tap_sigio); break; /* VMware/VMnet port ioctl's */ @@ -798,17 +840,18 @@ tapioctl(struct dev_ioctl_args *ap) break; case SIOCGIFADDR: /* get MAC address of the remote side */ - bcopy(tp->ether_addr, data, sizeof(tp->ether_addr)); + bcopy(sc->ether_addr, data, sizeof(sc->ether_addr)); break; case SIOCSIFADDR: /* set MAC address of the remote side */ - bcopy(data, tp->ether_addr, sizeof(tp->ether_addr)); + bcopy(data, sc->ether_addr, sizeof(sc->ether_addr)); break; default: error = ENOTTY; break; } + ifnet_deserialize_all(ifp); return (error); } @@ -829,35 +872,35 @@ tapread(struct dev_read_args *ap) { cdev_t dev = ap->a_head.a_dev; struct uio *uio = ap->a_uio; - struct tap_softc *tp = dev->si_drv1; - struct ifnet *ifp = &tp->tap_if; - struct mbuf *m0 = NULL; - int error = 0, len; + struct tap_softc *sc = dev->si_drv1; + struct ifnet *ifp = &sc->tap_if; + struct mbuf *m0 = NULL; + int error = 0, len; - TAPDEBUG(ifp, "reading, minor = %#x\n", minor(tp->tap_dev)); + TAPDEBUG(ifp, "reading, minor = %#x\n", minor(dev)); - if ((tp->tap_flags & TAP_READY) != TAP_READY) { - TAPDEBUG(ifp, "not ready. minor = %#x, tap_flags = 0x%x\n", - minor(tp->tap_dev), tp->tap_flags); + if ((sc->tap_flags & TAP_READY) != TAP_READY) { + TAPDEBUG(ifp, "not ready, minor = %#x, flags = 0x%x\n", + minor(dev), sc->tap_flags); return (EHOSTDOWN); } - tp->tap_flags &= ~TAP_RWAIT; + sc->tap_flags &= ~TAP_RWAIT; /* sleep until we get a packet */ do { ifnet_serialize_all(ifp); - IF_DEQUEUE(&tp->tap_devq, m0); + IF_DEQUEUE(&sc->tap_devq, m0); if (m0 == NULL) { if (ap->a_ioflag & IO_NDELAY) { ifnet_deserialize_all(ifp); return (EWOULDBLOCK); } - tp->tap_flags |= TAP_RWAIT; - tsleep_interlock(tp, PCATCH); + sc->tap_flags |= TAP_RWAIT; + tsleep_interlock(sc, PCATCH); ifnet_deserialize_all(ifp); - error = tsleep(tp, PCATCH | PINTERLOCKED, "taprd", 0); + error = tsleep(sc, PCATCH | PINTERLOCKED, "taprd", 0); if (error) return (error); } else { @@ -878,8 +921,7 @@ tapread(struct dev_read_args *ap) } if (m0 != NULL) { - TAPDEBUG(ifp, "dropping mbuf, minor = %#x\n", - minor(tp->tap_dev)); + TAPDEBUG(ifp, "dropping mbuf, minor = %#x\n", minor(dev)); m_freem(m0); } @@ -900,17 +942,17 @@ tapwrite(struct dev_write_args *ap) { cdev_t dev = ap->a_head.a_dev; struct uio *uio = ap->a_uio; - struct tap_softc *tp = dev->si_drv1; - struct ifnet *ifp = &tp->tap_if; - struct mbuf *top = NULL, **mp = NULL, *m = NULL; - int error; - size_t tlen, mlen; + struct tap_softc *sc = dev->si_drv1; + struct ifnet *ifp = &sc->tap_if; + struct mbuf *top = NULL, **mp = NULL, *m = NULL; + int error; + size_t tlen, mlen; - TAPDEBUG(ifp, "writing, minor = %#x\n", minor(tp->tap_dev)); + TAPDEBUG(ifp, "writing, minor = %#x\n", minor(dev)); - if ((tp->tap_flags & TAP_READY) != TAP_READY) { - TAPDEBUG(ifp, "not ready. minor = %#x, tap_flags = 0x%x\n", - minor(tp->tap_dev), tp->tap_flags); + if ((sc->tap_flags & TAP_READY) != TAP_READY) { + TAPDEBUG(ifp, "not ready, minor = %#x, flags = 0x%x\n", + minor(dev), sc->tap_flags); return (EHOSTDOWN); } @@ -919,7 +961,7 @@ tapwrite(struct dev_write_args *ap) if (uio->uio_resid > TAPMRU) { TAPDEBUG(ifp, "invalid packet len = %zu, minor = %#x\n", - uio->uio_resid, minor(tp->tap_dev)); + uio->uio_resid, minor(dev)); return (EIO); } @@ -958,7 +1000,7 @@ tapwrite(struct dev_write_args *ap) top->m_pkthdr.len = (int)tlen; top->m_pkthdr.rcvif = ifp; - + /* * Ethernet bridge and bpf are handled in ether_input * @@ -966,112 +1008,69 @@ tapwrite(struct dev_write_args *ap) */ ifnet_serialize_all(ifp); ifp->if_input(ifp, top, NULL, -1); - IFNET_STAT_INC(ifp, ipackets, 1);/* ibytes are counted in ether_input */ + IFNET_STAT_INC(ifp, ipackets, 1); /* ibytes are counted in ether_input */ ifnet_deserialize_all(ifp); return (0); } + /* * tapkqfilter - called from the fileops interface with nothing held * * MPSAFE */ -static int filt_tapread(struct knote *kn, long hint); -static int filt_tapwrite(struct knote *kn, long hint); -static void filt_tapdetach(struct knote *kn); -static struct filterops tapread_filtops = - { FILTEROP_ISFD, NULL, filt_tapdetach, filt_tapread }; -static struct filterops tapwrite_filtops = - { FILTEROP_ISFD, NULL, filt_tapdetach, filt_tapwrite }; - static int tapkqfilter(struct dev_kqfilter_args *ap) { cdev_t dev = ap->a_head.a_dev; struct knote *kn = ap->a_kn; - struct tap_softc *tp; + struct tap_softc *sc = dev->si_drv1; struct klist *list; - tp = dev->si_drv1; - list = &tp->tap_rkq.ki_note; + list = &sc->tap_rkq.ki_note; ap->a_result =0; - switch(kn->kn_filter) { + switch (kn->kn_filter) { case EVFILT_READ: kn->kn_fop = &tapread_filtops; - kn->kn_hook = (void *)tp; + kn->kn_hook = (void *)sc; break; case EVFILT_WRITE: kn->kn_fop = &tapwrite_filtops; - kn->kn_hook = (void *)tp; + kn->kn_hook = (void *)sc; break; default: ap->a_result = EOPNOTSUPP; - return(0); + return (0); } knote_insert(list, kn); - return(0); + return (0); } static int -filt_tapread(struct knote *kn, long hint) +tap_filter_read(struct knote *kn, long hint) { - struct tap_softc *tp = (void *)kn->kn_hook; + struct tap_softc *sc = (struct tap_softc *)kn->kn_hook; - if (IF_QEMPTY(&tp->tap_devq) == 0) /* XXX serializer */ - return(1); + if (IF_QEMPTY(&sc->tap_devq) == 0) /* XXX serializer */ + return (1); else - return(0); + return (0); } static int -filt_tapwrite(struct knote *kn, long hint) +tap_filter_write(struct knote *kn, long hint) { /* Always ready for a write */ return (1); } static void -filt_tapdetach(struct knote *kn) +tap_filter_detach(struct knote *kn) { - struct tap_softc *tp = (void *)kn->kn_hook; - - knote_remove(&tp->tap_rkq.ki_note, kn); -} - -static void -tapifstop(struct tap_softc *tp, int clear_flags) -{ - struct ifnet *ifp = &tp->tap_if; - - ASSERT_IFNET_SERIALIZED_ALL(ifp); - IF_DRAIN(&tp->tap_devq); - tp->tap_flags &= ~TAP_CLOSEDOWN; - if (clear_flags) { - ifp->if_flags &= ~IFF_RUNNING; - ifsq_clr_oactive(ifq_get_subq_default(&ifp->if_snd)); - } -} + struct tap_softc *sc = (struct tap_softc *)kn->kn_hook; -static void -tapifflags(struct tap_softc *tp) -{ - struct ifnet *ifp = &tp->arpcom.ac_if; - - ASSERT_IFNET_SERIALIZED_ALL(ifp); - if ((tp->tap_flags & TAP_VMNET) == 0) { - /* - * Only for non-vmnet tap(4) - */ - if (ifp->if_flags & IFF_UP) { - if ((ifp->if_flags & IFF_RUNNING) == 0) - tapifinit(tp); - } else { - tapifstop(tp, 1); - } - } else { - /* XXX */ - } + knote_remove(&sc->tap_rkq.ki_note, kn); } diff --git a/sys/net/tap/if_tap.h b/sys/net/tap/if_tap.h index 745119b37c..6cec47e10b 100644 --- a/sys/net/tap/if_tap.h +++ b/sys/net/tap/if_tap.h @@ -32,7 +32,6 @@ /* * $FreeBSD: src/sys/net/if_tap.h,v 1.1.2.1 2000/07/27 13:57:05 nsayer Exp $ - * $DragonFly: src/sys/net/tap/if_tap.h,v 1.2 2003/06/17 04:28:48 dillon Exp $ * $Id: if_tap.h,v 0.7 2000/07/12 04:12:51 max Exp $ */ @@ -41,8 +40,6 @@ #include -/* refer to if_tapvar.h for the softc stuff */ - /* maximum receive packet size (hard limit) */ #define TAPMRU 16384 @@ -53,9 +50,10 @@ struct tapinfo { u_char dummy; /* place holder */ }; -/* ioctl's for get/set debug */ -#define TAPSDEBUG _IOW('t', 90, int) +/* get/set internal debug variable */ #define TAPGDEBUG _IOR('t', 89, int) +#define TAPSDEBUG _IOW('t', 90, int) +/* get/set network interface information */ #define TAPSIFINFO _IOW('t', 91, struct tapinfo) #define TAPGIFINFO _IOR('t', 92, struct tapinfo) diff --git a/sys/net/tap/if_tapvar.h b/sys/net/tap/if_tapvar.h index 4be19a44b4..0ce3ef4c48 100644 --- a/sys/net/tap/if_tapvar.h +++ b/sys/net/tap/if_tapvar.h @@ -35,7 +35,6 @@ /* * $FreeBSD: src/sys/net/if_tapvar.h,v 1.3.2.1 2000/07/27 13:57:05 nsayer Exp $ - * $DragonFly: src/sys/net/tap/if_tapvar.h,v 1.6 2008/09/05 17:03:15 dillon Exp $ * $Id: if_tapvar.h,v 0.6 2000/07/11 02:16:08 max Exp $ */ @@ -43,30 +42,30 @@ #define _NET_IF_TAPVAR_H_ struct tap_softc { - struct arpcom arpcom; /* ethernet common data */ + struct arpcom arpcom; /* ethernet common data */ #define tap_if arpcom.ac_if - cdev_t tap_dev; /* device */ + cdev_t tap_dev; /* device */ - u_short tap_flags; /* misc flags */ + u_short tap_flags; /* misc flags */ #define TAP_OPEN (1 << 0) #define TAP_INITED (1 << 1) #define TAP_RWAIT (1 << 2) #define TAP_ASYNC (1 << 3) -#define TAP_READY (TAP_OPEN|TAP_INITED) #define TAP_VMNET (1 << 4) #define TAP_CLONE (1 << 5) -#define TAP_CLOSEDOWN (1 << 6) -#define TAP_MANUALMAKE (1 << 7) +#define TAP_CLOSEDOWN (1 << 6) +#define TAP_MANUALMAKE (1 << 7) +#define TAP_READY (TAP_OPEN | TAP_INITED) - u_int8_t ether_addr[ETHER_ADDR_LEN]; /* ether addr of the remote side */ - - struct sigio *tap_sigtd; /* track process owning tap */ - struct sigio *tap_sigio; /* information for async I/O */ - struct kqinfo tap_rkq; /* read select/poll/kq */ + uint8_t ether_addr[ETHER_ADDR_LEN]; + /* ether addr of the remote side */ + struct sigio *tap_sigtd; /* track process owning tap */ + struct sigio *tap_sigio; /* information for async I/O */ + struct kqinfo tap_rkq; /* read select/poll/kq */ struct ifqueue tap_devq; int tap_unit; - SLIST_ENTRY(tap_softc) tap_link; /* Local tap list */ + SLIST_ENTRY(tap_softc) tap_link; /* local tap list */ }; #endif /* !_NET_IF_TAPVAR_H_ */ -- 2.41.0