From owner-freebsd-bugs Fri Apr 13 15:20:18 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 5051437B446 for ; Fri, 13 Apr 2001 15:20:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id f3DMK1K16413; Fri, 13 Apr 2001 15:20:01 -0700 (PDT) (envelope-from gnats) Received: from ambrisko.com (adsl-216-103-208-74.dsl.snfc21.pacbell.net [216.103.208.74]) by hub.freebsd.org (Postfix) with ESMTP id 2133D37B43F for ; Fri, 13 Apr 2001 15:12:55 -0700 (PDT) (envelope-from ambrisko@ambrisko.com) Received: (from ambrisko@localhost) by ambrisko.com (8.11.3/8.11.2) id f3DMCrS41923; Fri, 13 Apr 2001 15:12:53 -0700 (PDT) (envelope-from ambrisko) Message-Id: <200104132212.f3DMCrS41923@ambrisko.com> Date: Fri, 13 Apr 2001 15:12:53 -0700 (PDT) From: Doug Ambrisko Reply-To: ambrisko@ambrisko.com To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.113 Subject: kern/26546: Add ioctl support to linux emulation and permit ethX syntax Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 26546 >Category: kern >Synopsis: Add ioctl support to linux emulation and permit ethX syntax >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Fri Apr 13 15:20:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Doug Ambrisko >Release: FreeBSD 4.3-RC i386 >Organization: Whistle/IBM >Environment: System: FreeBSD server2.ambrisko.com 4.3-RC FreeBSD 4.3-RC #3: Sat Apr 7 14:18:35 PDT 2001 ambrisko@server2.ambrisko.com:/usr/src/sys/compile/SERVER i386 >Description: Running the Cisco binary only Aironet configuration tool only talks to "eth" devices. Since this is in the binary we can't change it. So I added a mapping function in the emulation that iterates through the hardware ethernet devices and use the number in "eth" to count the iteration. Interesting side effect is that if you have a Linux version of ifconfig on your machine you can do ifconfig eth0 and it will work. I put this in a funtion to isolate the interface scan if it saw an interface argument of "eth" type. The substition is then done for the real FreeBSD interface and then the FreeBSD ioctl is called. When the FreeBSD ioctl returns it restores the original interface name and returns the result. I also implement to "Device Private" ioctls that the Cisco utility uses to talk to the Aironet driver. With this and my Aironet changes you can run the configuration binaries from Cisco for Linux and do things like upgrade the firmware on the card and things like that. >How-To-Repeat: >Fix: Index: compat/linux/linux_ioctl.c =================================================================== RCS file: /cvs/freebsd/src/sys/compat/linux/linux_ioctl.c,v retrieving revision 1.55.2.4 diff -c -r1.55.2.4 linux_ioctl.c *** linux_ioctl.c 2000/11/03 13:11:18 1.55.2.4 --- linux_ioctl.c 2001/04/13 21:58:45 *************** *** 71,76 **** --- 71,77 ---- 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 }; *************** *** 84,89 **** --- 85,92 ---- { 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); *************** *** 91,96 **** --- 94,100 ---- 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 { *************** *** 1315,1321 **** --- 1319,1374 ---- * Socket related ioctls */ + /* + * Map "eth" into valid FreeBSD name of hardware ethernet devices + * via present devices + */ + static int + linux_eth_to_bsd_ioctl(struct proc *p, struct linux_ioctl_args *args) + { + struct ifnet *ifp; + int count; + int i; + int remapped = 0; + char temp[IFNAMSIZ]; + char *ptr; + + ptr = (char *)(args->arg); + + if ((strncmp(ptr,"eth",3)) == 0){ + bcopy(ptr, temp, sizeof(temp)); + count = ptr[3] - '0'; + + for (i=0, ifp = TAILQ_FIRST(&ifnet); + ifp != NULL; + ifp = TAILQ_NEXT(ifp, if_link)) { + + if ((ifp->if_flags & + (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_BROADCAST) + ) != IFF_BROADCAST) + continue; + + if(i==count){ + snprintf(ptr, IFNAMSIZ, + "%s%d", ifp->if_name, ifp->if_unit); + + remapped = 1; + break; + } + i++; + } + } + + i = ioctl(p, (struct ioctl_args *)args); + + if (remapped) + bcopy(temp, ptr, sizeof(temp)); + + return i; + } + + static int linux_ioctl_socket(struct proc *p, struct linux_ioctl_args *args) { *************** *** 1323,1371 **** case LINUX_FIOSETOWN: args->cmd = FIOSETOWN; ! return (ioctl(p, (struct ioctl_args *)args)); case LINUX_SIOCSPGRP: args->cmd = SIOCSPGRP; ! return (ioctl(p, (struct ioctl_args *)args)); case LINUX_FIOGETOWN: args->cmd = FIOGETOWN; ! return (ioctl(p, (struct ioctl_args *)args)); case LINUX_SIOCGPGRP: args->cmd = SIOCGPGRP; ! return (ioctl(p, (struct ioctl_args *)args)); case LINUX_SIOCATMARK: args->cmd = SIOCATMARK; ! return (ioctl(p, (struct ioctl_args *)args)); /* LINUX_SIOCGSTAMP */ case LINUX_SIOCGIFCONF: args->cmd = OSIOCGIFCONF; ! return (ioctl(p, (struct ioctl_args *)args)); case LINUX_SIOCGIFFLAGS: args->cmd = SIOCGIFFLAGS; ! return (ioctl(p, (struct ioctl_args *)args)); case LINUX_SIOCGIFADDR: args->cmd = OSIOCGIFADDR; ! return (ioctl(p, (struct ioctl_args *)args)); case LINUX_SIOCGIFDSTADDR: args->cmd = OSIOCGIFDSTADDR; ! return (ioctl(p, (struct ioctl_args *)args)); case LINUX_SIOCGIFBRDADDR: args->cmd = OSIOCGIFBRDADDR; ! return (ioctl(p, (struct ioctl_args *)args)); case LINUX_SIOCGIFNETMASK: args->cmd = OSIOCGIFNETMASK; ! return (ioctl(p, (struct ioctl_args *)args)); case LINUX_SIOCGIFHWADDR: { int ifn; --- 1376,1424 ---- case LINUX_FIOSETOWN: args->cmd = FIOSETOWN; ! return linux_eth_to_bsd_ioctl(p, args); case LINUX_SIOCSPGRP: args->cmd = SIOCSPGRP; ! return linux_eth_to_bsd_ioctl(p, args); case LINUX_FIOGETOWN: args->cmd = FIOGETOWN; ! return linux_eth_to_bsd_ioctl(p, args); case LINUX_SIOCGPGRP: args->cmd = SIOCGPGRP; ! return linux_eth_to_bsd_ioctl(p, args); case LINUX_SIOCATMARK: args->cmd = SIOCATMARK; ! return linux_eth_to_bsd_ioctl(p, args); /* LINUX_SIOCGSTAMP */ case LINUX_SIOCGIFCONF: args->cmd = OSIOCGIFCONF; ! return linux_eth_to_bsd_ioctl(p, args); case LINUX_SIOCGIFFLAGS: args->cmd = SIOCGIFFLAGS; ! return linux_eth_to_bsd_ioctl(p, args); case LINUX_SIOCGIFADDR: args->cmd = OSIOCGIFADDR; ! return linux_eth_to_bsd_ioctl(p, args); case LINUX_SIOCGIFDSTADDR: args->cmd = OSIOCGIFDSTADDR; ! return linux_eth_to_bsd_ioctl(p, args); case LINUX_SIOCGIFBRDADDR: args->cmd = OSIOCGIFBRDADDR; ! return linux_eth_to_bsd_ioctl(p, args); case LINUX_SIOCGIFNETMASK: args->cmd = OSIOCGIFNETMASK; ! return linux_eth_to_bsd_ioctl(p, args); case LINUX_SIOCGIFHWADDR: { int ifn; *************** *** 1399,1410 **** case LINUX_SIOCADDMULTI: args->cmd = SIOCADDMULTI; ! return (ioctl(p, (struct ioctl_args *)args)); case LINUX_SIOCDELMULTI: args->cmd = SIOCDELMULTI; ! return (ioctl(p, (struct ioctl_args *)args)); } return (ENOIOCTL); --- 1452,1484 ---- case LINUX_SIOCADDMULTI: args->cmd = SIOCADDMULTI; ! return linux_eth_to_bsd_ioctl(p, args); case LINUX_SIOCDELMULTI: args->cmd = SIOCDELMULTI; ! return linux_eth_to_bsd_ioctl(p, args); ! } + return (ENOIOCTL); + } + + /* + * Device Private ioctl + */ + + static int + linux_ioctl_private(struct proc *p, struct linux_ioctl_args *args) + { + + switch (args->cmd & 0xffff) { + + case SIOCDEVPRIVATE: + args->cmd = SIOCGPRIVATE_0; + return linux_eth_to_bsd_ioctl(p, args); + + case SIOCDEVPRIVATE+1: + args->cmd = SIOCGPRIVATE_1; + return linux_eth_to_bsd_ioctl(p, args); } return (ENOIOCTL); Index: compat/linux/linux_ioctl.h =================================================================== RCS file: /cvs/freebsd/src/sys/compat/linux/linux_ioctl.h,v retrieving revision 1.4.2.1 diff -c -r1.4.2.1 linux_ioctl.h *** linux_ioctl.h 2000/10/30 10:51:37 1.4.2.1 --- linux_ioctl.h 2001/04/13 21:58:45 *************** *** 143,148 **** --- 143,162 ---- #define LINUX_IOCTL_SOCKET_MIN LINUX_FIOSETOWN #define LINUX_IOCTL_SOCKET_MAX LINUX_SIOCDELMULTI + /* Device private ioctl calls */ + + /* + * These 16 ioctls are available to devices via the do_ioctl() device + * vector. Each device should include this file and redefine these names + * as their own. Because these are device dependent it is a good idea + * _NOT_ to issue them to random objects and hope. + */ + + #define SIOCDEVPRIVATE 0x89F0 /* to 89FF */ + + #define LINUX_IOCTL_PRIVATE_MIN SIOCDEVPRIVATE + #define LINUX_IOCTL_PRIVATE_MAX SIOCDEVPRIVATE+0xf + /* * sound */ Index: sys/sockio.h =================================================================== RCS file: /cvs/freebsd/src/sys/sys/sockio.h,v retrieving revision 1.14.2.2 diff -c -r1.14.2.2 sockio.h *** sockio.h 2000/08/22 18:06:21 1.14.2.2 --- sockio.h 2001/04/13 21:58:45 *************** *** 98,101 **** --- 98,104 ---- #define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */ #define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) /* set link level addr */ + #define SIOCGPRIVATE_0 _IOWR('i', 80, struct ifreq) /* Linux Private + 0 */ + #define SIOCGPRIVATE_1 _IOWR('i', 81, struct ifreq) /* Linux Private + 1 */ + #endif /* !_SYS_SOCKIO_H_ */ >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message