version 1.10.2.7, 2008/02/27 08:37:01 |
version 1.10.2.8, 2008/03/17 09:15:41 |
Line 97 SYSCTL_SETUP_PROTO(sysctl_tap_setup); |
|
Line 97 SYSCTL_SETUP_PROTO(sysctl_tap_setup); |
|
*/ |
*/ |
|
|
struct tap_softc { |
struct tap_softc { |
struct device sc_dev; |
device_t sc_dev; |
struct ifmedia sc_im; |
struct ifmedia sc_im; |
struct ethercom sc_ec; |
struct ethercom sc_ec; |
int sc_flags; |
int sc_flags; |
Line 115 struct tap_softc { |
|
Line 115 struct tap_softc { |
|
|
|
void tapattach(int); |
void tapattach(int); |
|
|
static int tap_match(struct device *, struct cfdata *, void *); |
static int tap_match(device_t, cfdata_t, void *); |
static void tap_attach(struct device *, struct device *, void *); |
static void tap_attach(device_t, device_t, void *); |
static int tap_detach(struct device*, int); |
static int tap_detach(device_t, int); |
|
|
CFATTACH_DECL(tap, sizeof(struct tap_softc), |
CFATTACH_DECL_NEW(tap, sizeof(struct tap_softc), |
tap_match, tap_attach, tap_detach, NULL); |
tap_match, tap_attach, tap_detach, NULL); |
extern struct cfdriver tap_cd; |
extern struct cfdriver tap_cd; |
|
|
Line 216 struct if_clone tap_cloners = IF_CLONE_I |
|
Line 216 struct if_clone tap_cloners = IF_CLONE_I |
|
|
|
/* Helper functionis shared by the two cloning code paths */ |
/* Helper functionis shared by the two cloning code paths */ |
static struct tap_softc * tap_clone_creator(int); |
static struct tap_softc * tap_clone_creator(int); |
int tap_clone_destroyer(struct device *); |
int tap_clone_destroyer(device_t); |
|
|
void |
void |
tapattach(int n) |
tapattach(int n) |
Line 236 tapattach(int n) |
|
Line 236 tapattach(int n) |
|
|
|
/* Pretty much useless for a pseudo-device */ |
/* Pretty much useless for a pseudo-device */ |
static int |
static int |
tap_match(struct device *self, struct cfdata *cfdata, |
tap_match(device_t parent, cfdata_t cfdata, void *arg) |
void *arg) |
|
{ |
{ |
|
|
return (1); |
return (1); |
} |
} |
|
|
void |
void |
tap_attach(struct device *parent, struct device *self, |
tap_attach(device_t parent, device_t self, void *aux) |
void *aux) |
|
{ |
{ |
struct tap_softc *sc = (struct tap_softc *)self; |
struct tap_softc *sc = device_private(self); |
struct ifnet *ifp; |
struct ifnet *ifp; |
const struct sysctlnode *node; |
const struct sysctlnode *node; |
uint8_t enaddr[ETHER_ADDR_LEN] = |
uint8_t enaddr[ETHER_ADDR_LEN] = |
Line 256 tap_attach(struct device *parent, struct |
|
Line 255 tap_attach(struct device *parent, struct |
|
uint32_t ui; |
uint32_t ui; |
int error; |
int error; |
|
|
|
sc->sc_dev = self; |
|
|
/* |
/* |
* In order to obtain unique initial Ethernet address on a host, |
* In order to obtain unique initial Ethernet address on a host, |
* do some randomisation using the current uptime. It's not meant |
* do some randomisation using the current uptime. It's not meant |
Line 265 tap_attach(struct device *parent, struct |
|
Line 266 tap_attach(struct device *parent, struct |
|
ui = (tv.tv_sec ^ tv.tv_usec) & 0xffffff; |
ui = (tv.tv_sec ^ tv.tv_usec) & 0xffffff; |
memcpy(enaddr+3, (uint8_t *)&ui, 3); |
memcpy(enaddr+3, (uint8_t *)&ui, 3); |
|
|
aprint_verbose("%s: Ethernet address %s\n", device_xname(&sc->sc_dev), |
aprint_verbose_dev(self, "Ethernet address %s\n", |
ether_snprintf(enaddrstr, sizeof(enaddrstr), enaddr)); |
ether_snprintf(enaddrstr, sizeof(enaddrstr), enaddr)); |
|
|
/* |
/* |
Line 290 tap_attach(struct device *parent, struct |
|
Line 291 tap_attach(struct device *parent, struct |
|
* to support IPv6. |
* to support IPv6. |
*/ |
*/ |
ifp = &sc->sc_ec.ec_if; |
ifp = &sc->sc_ec.ec_if; |
strcpy(ifp->if_xname, sc->sc_dev.dv_xname); |
strcpy(ifp->if_xname, device_xname(self)); |
ifp->if_softc = sc; |
ifp->if_softc = sc; |
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; |
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; |
ifp->if_ioctl = tap_ioctl; |
ifp->if_ioctl = tap_ioctl; |
Line 324 tap_attach(struct device *parent, struct |
|
Line 325 tap_attach(struct device *parent, struct |
|
*/ |
*/ |
if ((error = sysctl_createv(NULL, 0, NULL, |
if ((error = sysctl_createv(NULL, 0, NULL, |
&node, CTLFLAG_READWRITE, |
&node, CTLFLAG_READWRITE, |
CTLTYPE_STRING, sc->sc_dev.dv_xname, NULL, |
CTLTYPE_STRING, device_xname(self), NULL, |
tap_sysctl_handler, 0, sc, 18, |
tap_sysctl_handler, 0, sc, 18, |
CTL_NET, AF_LINK, tap_node, device_unit(&sc->sc_dev), |
CTL_NET, AF_LINK, tap_node, device_unit(sc->sc_dev), |
CTL_EOL)) != 0) |
CTL_EOL)) != 0) |
aprint_error("%s: sysctl_createv returned %d, ignoring\n", |
aprint_error_dev(self, "sysctl_createv returned %d, ignoring\n", |
sc->sc_dev.dv_xname, error); |
error); |
|
|
/* |
/* |
* Initialize the two locks for the device. |
* Initialize the two locks for the device. |
Line 355 tap_attach(struct device *parent, struct |
|
Line 356 tap_attach(struct device *parent, struct |
|
* routine, in reversed order. |
* routine, in reversed order. |
*/ |
*/ |
static int |
static int |
tap_detach(struct device* self, int flags) |
tap_detach(device_t self, int flags) |
{ |
{ |
struct tap_softc *sc = (struct tap_softc *)self; |
struct tap_softc *sc = device_private(self); |
struct ifnet *ifp = &sc->sc_ec.ec_if; |
struct ifnet *ifp = &sc->sc_ec.ec_if; |
int error, s; |
int error, s; |
|
|
Line 373 tap_detach(struct device* self, int flag |
|
Line 374 tap_detach(struct device* self, int flag |
|
* CTL_EOL. |
* CTL_EOL. |
*/ |
*/ |
if ((error = sysctl_destroyv(NULL, CTL_NET, AF_LINK, tap_node, |
if ((error = sysctl_destroyv(NULL, CTL_NET, AF_LINK, tap_node, |
device_unit(&sc->sc_dev), CTL_EOL)) != 0) |
device_unit(sc->sc_dev), CTL_EOL)) != 0) |
aprint_error("%s: sysctl_destroyv returned %d, ignoring\n", |
aprint_error_dev(self, |
sc->sc_dev.dv_xname, error); |
"sysctl_destroyv returned %d, ignoring\n", error); |
ether_ifdetach(ifp); |
ether_ifdetach(ifp); |
if_detach(ifp); |
if_detach(ifp); |
ifmedia_delete_instance(&sc->sc_im, IFM_INST_ANY); |
ifmedia_delete_instance(&sc->sc_im, IFM_INST_ANY); |
Line 456 tap_start(struct ifnet *ifp) |
|
Line 457 tap_start(struct ifnet *ifp) |
|
} else if (!IFQ_IS_EMPTY(&ifp->if_snd)) { |
} else if (!IFQ_IS_EMPTY(&ifp->if_snd)) { |
ifp->if_flags |= IFF_OACTIVE; |
ifp->if_flags |= IFF_OACTIVE; |
wakeup(sc); |
wakeup(sc); |
selnotify(&sc->sc_rsel, 1); |
selnotify(&sc->sc_rsel, 0, 1); |
if (sc->sc_flags & TAP_ASYNCIO) |
if (sc->sc_flags & TAP_ASYNCIO) |
fownsignal(sc->sc_pgid, SIGIO, POLL_IN, |
fownsignal(sc->sc_pgid, SIGIO, POLL_IN, |
POLLIN|POLLRDNORM, NULL); |
POLLIN|POLLRDNORM, NULL); |
Line 551 tap_stop(struct ifnet *ifp, int disable) |
|
Line 552 tap_stop(struct ifnet *ifp, int disable) |
|
|
|
ifp->if_flags &= ~IFF_RUNNING; |
ifp->if_flags &= ~IFF_RUNNING; |
wakeup(sc); |
wakeup(sc); |
selnotify(&sc->sc_rsel, 1); |
selnotify(&sc->sc_rsel, 0, 1); |
if (sc->sc_flags & TAP_ASYNCIO) |
if (sc->sc_flags & TAP_ASYNCIO) |
fownsignal(sc->sc_pgid, SIGIO, POLL_HUP, 0, NULL); |
fownsignal(sc->sc_pgid, SIGIO, POLL_HUP, 0, NULL); |
} |
} |
Line 599 tap_clone_creator(int unit) |
|
Line 600 tap_clone_creator(int unit) |
|
cf->cf_fstate = FSTATE_NOTFOUND; |
cf->cf_fstate = FSTATE_NOTFOUND; |
} |
} |
|
|
return (struct tap_softc *)config_attach_pseudo(cf); |
return device_private(config_attach_pseudo(cf)); |
} |
} |
|
|
/* |
/* |
Line 610 tap_clone_creator(int unit) |
|
Line 611 tap_clone_creator(int unit) |
|
static int |
static int |
tap_clone_destroy(struct ifnet *ifp) |
tap_clone_destroy(struct ifnet *ifp) |
{ |
{ |
return tap_clone_destroyer((struct device *)ifp->if_softc); |
return tap_clone_destroyer(device_private(ifp->if_softc)); |
} |
} |
|
|
int |
int |
tap_clone_destroyer(struct device *dev) |
tap_clone_destroyer(device_t dev) |
{ |
{ |
struct cfdata *cf = device_cfdata(dev); |
cfdata_t cf = device_cfdata(dev); |
int error; |
int error; |
|
|
if ((error = config_detach(dev, 0)) != 0) |
if ((error = config_detach(dev, 0)) != 0) |
aprint_error("%s: unable to detach instance\n", |
aprint_error_dev(dev, "unable to detach instance\n"); |
dev->dv_xname); |
|
free(cf, M_DEVBUF); |
free(cf, M_DEVBUF); |
|
|
return (error); |
return (error); |
Line 657 tap_cdev_open(dev_t dev, int flags, int |
|
Line 657 tap_cdev_open(dev_t dev, int flags, int |
|
if (minor(dev) == TAP_CLONER) |
if (minor(dev) == TAP_CLONER) |
return tap_dev_cloner(l); |
return tap_dev_cloner(l); |
|
|
sc = (struct tap_softc *)device_lookup(&tap_cd, minor(dev)); |
sc = device_private(device_lookup(&tap_cd, minor(dev))); |
if (sc == NULL) |
if (sc == NULL) |
return (ENXIO); |
return (ENXIO); |
|
|
Line 709 tap_dev_cloner(struct lwp *l) |
|
Line 709 tap_dev_cloner(struct lwp *l) |
|
sc->sc_flags |= TAP_INUSE; |
sc->sc_flags |= TAP_INUSE; |
|
|
return fdclone(l, fp, fd, FREAD|FWRITE, &tap_fileops, |
return fdclone(l, fp, fd, FREAD|FWRITE, &tap_fileops, |
(void *)(intptr_t)device_unit(&sc->sc_dev)); |
(void *)(intptr_t)device_unit(sc->sc_dev)); |
} |
} |
|
|
/* |
/* |
Line 727 tap_cdev_close(dev_t dev, int flags, int |
|
Line 727 tap_cdev_close(dev_t dev, int flags, int |
|
struct lwp *l) |
struct lwp *l) |
{ |
{ |
struct tap_softc *sc = |
struct tap_softc *sc = |
(struct tap_softc *)device_lookup(&tap_cd, minor(dev)); |
device_private(device_lookup(&tap_cd, minor(dev))); |
|
|
if (sc == NULL) |
if (sc == NULL) |
return (ENXIO); |
return (ENXIO); |
Line 748 tap_fops_close(struct file *fp, struct l |
|
Line 748 tap_fops_close(struct file *fp, struct l |
|
struct tap_softc *sc; |
struct tap_softc *sc; |
int error; |
int error; |
|
|
sc = (struct tap_softc *)device_lookup(&tap_cd, unit); |
sc = device_private(device_lookup(&tap_cd, unit)); |
if (sc == NULL) |
if (sc == NULL) |
return (ENXIO); |
return (ENXIO); |
|
|
Line 762 tap_fops_close(struct file *fp, struct l |
|
Line 762 tap_fops_close(struct file *fp, struct l |
|
if ((sc->sc_flags & TAP_GOING) != 0) |
if ((sc->sc_flags & TAP_GOING) != 0) |
return (0); |
return (0); |
|
|
return tap_clone_destroyer((struct device *)sc); |
return tap_clone_destroyer(sc->sc_dev); |
} |
} |
|
|
static int |
static int |
|
|
tap_dev_read(int unit, struct uio *uio, int flags) |
tap_dev_read(int unit, struct uio *uio, int flags) |
{ |
{ |
struct tap_softc *sc = |
struct tap_softc *sc = |
(struct tap_softc *)device_lookup(&tap_cd, unit); |
device_private(device_lookup(&tap_cd, unit)); |
struct ifnet *ifp; |
struct ifnet *ifp; |
struct mbuf *m, *n; |
struct mbuf *m, *n; |
int error = 0, s; |
int error = 0, s; |
|
|
tap_dev_write(int unit, struct uio *uio, int flags) |
tap_dev_write(int unit, struct uio *uio, int flags) |
{ |
{ |
struct tap_softc *sc = |
struct tap_softc *sc = |
(struct tap_softc *)device_lookup(&tap_cd, unit); |
device_private(device_lookup(&tap_cd, unit)); |
struct ifnet *ifp; |
struct ifnet *ifp; |
struct mbuf *m, **mp; |
struct mbuf *m, **mp; |
int error = 0; |
int error = 0; |
|
|
tap_dev_ioctl(int unit, u_long cmd, void *data, struct lwp *l) |
tap_dev_ioctl(int unit, u_long cmd, void *data, struct lwp *l) |
{ |
{ |
struct tap_softc *sc = |
struct tap_softc *sc = |
(struct tap_softc *)device_lookup(&tap_cd, unit); |
device_private(device_lookup(&tap_cd, unit)); |
int error = 0; |
int error = 0; |
|
|
if (sc == NULL) |
if (sc == NULL) |
|
|
tap_dev_poll(int unit, int events, struct lwp *l) |
tap_dev_poll(int unit, int events, struct lwp *l) |
{ |
{ |
struct tap_softc *sc = |
struct tap_softc *sc = |
(struct tap_softc *)device_lookup(&tap_cd, unit); |
device_private(device_lookup(&tap_cd, unit)); |
int revents = 0; |
int revents = 0; |
|
|
if (sc == NULL) |
if (sc == NULL) |
|
|
tap_dev_kqfilter(int unit, struct knote *kn) |
tap_dev_kqfilter(int unit, struct knote *kn) |
{ |
{ |
struct tap_softc *sc = |
struct tap_softc *sc = |
(struct tap_softc *)device_lookup(&tap_cd, unit); |
device_private(device_lookup(&tap_cd, unit)); |
|
|
if (sc == NULL) |
if (sc == NULL) |
return (ENXIO); |
return (ENXIO); |