diff options
author | des <des@FreeBSD.org> | 2001-10-19 01:38:10 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2001-10-19 01:38:10 +0000 |
commit | 8bbeedf7ceda38632a2db527a2b525e5cb194c18 (patch) | |
tree | 86b34441d1ad9f7046ea553179f98344e8a771ec /sys/compat | |
parent | 30d25bb2aa6bd4dfb7db34a25a4e1c7312ed4e7d (diff) | |
download | FreeBSD-src-8bbeedf7ceda38632a2db527a2b525e5cb194c18.zip FreeBSD-src-8bbeedf7ceda38632a2db527a2b525e5cb194c18.tar.gz |
Add support for the "device private" ioctls soon to be used by the an driver.
Also slightly change the name translation policy - only rename interfaces
that have the IFF_BROADCAST flag set. This is not perfect, but is closer to
how Linux names network interfaces.
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/linux/linux_ioctl.c | 79 | ||||
-rw-r--r-- | sys/compat/linux/linux_ioctl.h | 13 |
2 files changed, 76 insertions, 16 deletions
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index ef9a3e4..e81448d 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -69,6 +69,7 @@ static linux_ioctl_function_t linux_ioctl_disk; static linux_ioctl_function_t linux_ioctl_socket; static linux_ioctl_function_t linux_ioctl_sound; static linux_ioctl_function_t linux_ioctl_termio; +static linux_ioctl_function_t linux_ioctl_private; static struct linux_ioctl_handler cdrom_handler = { linux_ioctl_cdrom, LINUX_IOCTL_CDROM_MIN, LINUX_IOCTL_CDROM_MAX }; @@ -82,6 +83,8 @@ static struct linux_ioctl_handler sound_handler = { linux_ioctl_sound, LINUX_IOCTL_SOUND_MIN, LINUX_IOCTL_SOUND_MAX }; static struct linux_ioctl_handler termio_handler = { linux_ioctl_termio, LINUX_IOCTL_TERMIO_MIN, LINUX_IOCTL_TERMIO_MAX }; +static struct linux_ioctl_handler private_handler = +{ linux_ioctl_private, LINUX_IOCTL_PRIVATE_MIN, LINUX_IOCTL_PRIVATE_MAX }; DATA_SET(linux_ioctl_handler_set, cdrom_handler); DATA_SET(linux_ioctl_handler_set, console_handler); @@ -89,6 +92,7 @@ DATA_SET(linux_ioctl_handler_set, disk_handler); DATA_SET(linux_ioctl_handler_set, socket_handler); DATA_SET(linux_ioctl_handler_set, sound_handler); DATA_SET(linux_ioctl_handler_set, termio_handler); +DATA_SET(linux_ioctl_handler_set, private_handler); struct handler_element { @@ -1320,7 +1324,20 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args) return (ENOIOCTL); } -#if 0 +/* + * Construct the Linux name for an interface + */ + +int +linux_ifname(struct ifnet *ifp, char *name, size_t size) +{ + if ((ifp->if_flags & IFF_BROADCAST) != 0) + return snprintf(name, LINUX_IFNAMSIZ, + "eth%d", ifp->if_index); + return snprintf(name, LINUX_IFNAMSIZ, + "%s%d", ifp->if_name, ifp->if_unit); +} + /* * Translate a FreeBSD interface name to a Linux interface name, * and return the associated ifnet structure. @@ -1348,17 +1365,11 @@ ifname_bsd_to_linux(const char *bsdname, char *lxname) strncmp(ifp->if_name, bsdname, len) == 0) break; } - if (ifp != NULL) { - if ((ifp->if_flags & IFF_LOOPBACK) != 0) - snprintf(lxname, LINUX_IFNAMSIZ, - "lo%d", ifp->if_unit); - else - snprintf(lxname, LINUX_IFNAMSIZ, - "eth%d", ifp->if_index); - } + if (ifp != NULL) + linux_ifname(ifp, lxname, LINUX_IFNAMSIZ); + return (ifp); } -#endif /* * Translate a Linux interface name to a FreeBSD interface name, @@ -1388,6 +1399,7 @@ ifname_linux_to_bsd(const char *lxname, char *bsdname) strncmp(ifp->if_name, lxname, len) == 0) break; if (ifp->if_index == unit && + (ifp->if_flags & IFF_BROADCAST) != 0 && strncmp(lxname, "eth", len) == 0) break; } @@ -1430,12 +1442,7 @@ linux_ifconf(struct thread *td, struct ifconf *uifc) if (uio.uio_resid <= 0) break; bzero(&ifr, sizeof ifr); - if ((ifp->if_flags & IFF_LOOPBACK) != 0) - snprintf(ifr.ifr_name, LINUX_IFNAMSIZ, - "lo%d", ifp->if_unit); - else - snprintf(ifr.ifr_name, LINUX_IFNAMSIZ, - "eth%d", ifp->if_index); + linux_ifname(ifp, ifr.ifr_name, LINUX_IFNAMSIZ); error = uiomove((caddr_t)&ifr, sizeof ifr, &uio); if (error != 0) return (error); @@ -1538,6 +1545,8 @@ linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args) case LINUX_SIOCGIFFLAGS: case LINUX_SIOCGIFHWADDR: case LINUX_SIOCGIFNETMASK: + case LINUX_SIOCDEVPRIVATE: + case LINUX_SIOCDEVPRIVATE+1: /* copy in the interface name and translate it. */ copyin((char *)(args->arg), lifname, LINUX_IFNAMSIZ); #ifdef DEBUG @@ -1636,6 +1645,18 @@ linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args) args->cmd = SIOCDELMULTI; error = ioctl(td, (struct ioctl_args *)args); break; + + /* + * XXX This is slightly bogus, but these ioctls are currently + * XXX only used by the aironet (if_an) network driver. + */ + case LINUX_SIOCDEVPRIVATE: + args->cmd = SIOCGPRIVATE_0; + error = ioctl(td, (struct ioctl_args *)args); + + case LINUX_SIOCDEVPRIVATE+1: + args->cmd = SIOCGPRIVATE_1; + error = ioctl(td, (struct ioctl_args *)args); } if (ifp != NULL) @@ -1649,6 +1670,32 @@ linux_ioctl_socket(struct thread *td, struct linux_ioctl_args *args) } /* + * Device private ioctl handler + */ +static int +linux_ioctl_private(struct thread *td, struct linux_ioctl_args *args) +{ + struct filedesc *fdp; + struct file *fp; + int type; + + /* XXX is it sufficient to PROC_LOCK td->td_proc? */ + mtx_lock(&Giant); + fdp = td->td_proc->p_fd; + if (args->fd >= fdp->fd_nfiles || + (fp = fdp->fd_ofiles[args->fd]) == NULL) { + mtx_unlock(&Giant); + return (EBADF); + } else { + type = fp->f_type; + } + mtx_unlock(&Giant); + if (type == DTYPE_SOCKET) + return (linux_ioctl_socket(td, args)); + return (ioctl(td, (struct ioctl_args *)args)); +} + +/* * main ioctl syscall function */ diff --git a/sys/compat/linux/linux_ioctl.h b/sys/compat/linux/linux_ioctl.h index d5508e6..2e3a06c 100644 --- a/sys/compat/linux/linux_ioctl.h +++ b/sys/compat/linux/linux_ioctl.h @@ -144,6 +144,13 @@ #define LINUX_IOCTL_SOCKET_MAX LINUX_SIOCDELMULTI /* + * Device private ioctl calls + */ +#define LINUX_SIOCDEVPRIVATE 0x89F0 /* to 89FF */ +#define LINUX_IOCTL_PRIVATE_MIN LINUX_SIOCDEVPRIVATE +#define LINUX_IOCTL_PRIVATE_MAX LINUX_SIOCDEVPRIVATE+0xf + +/* * sound */ #define LINUX_SOUND_MIXER_WRITE_VOLUME 0x4d00 @@ -434,4 +441,10 @@ #define LINUX_ASYNC_CALLOUT_NOHUP 0x0400 #define LINUX_ASYNC_FLAGS 0x0FFF +/* + * This doesn't really belong here, but I can't think of a better + * place to put it. + */ +int linux_ifname(struct ifnet *, char *, size_t); + #endif /* !_LINUX_IOCTL_H_ */ |