Date: Wed, 22 May 2019 05:32:39 +0000 (UTC) From: Dmitry Chagin <dchagin@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r348092 - in stable/12/sys: amd64/linux amd64/linux32 arm64/linux compat/linux i386/linux Message-ID: <201905220532.x4M5Wdne099695@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dchagin Date: Wed May 22 05:32:39 2019 New Revision: 348092 URL: https://svnweb.freebsd.org/changeset/base/348092 Log: MFC r347052: In order to reduce duplication between MD parts of the Linuxulator move bits that are MI out into the headers in compat/linux. For that remove bogus _packed attribute from struct l_sockaddr and use MI types for struct members. And continue to move into the linux_common module a code that is intended for both Linuxulator modules (both instruction set - 32 & 64 bit) or for external modules like linsysfs or linprocfs. To avoid header pollution introduce new sys/compat/linux_common.h header. Added: stable/12/sys/compat/linux/linux_common.h - copied unchanged from r347052, head/sys/compat/linux/linux_common.h Modified: stable/12/sys/amd64/linux/linux.h stable/12/sys/amd64/linux32/linux.h stable/12/sys/arm64/linux/linux.h stable/12/sys/compat/linux/linux.c stable/12/sys/compat/linux/linux.h stable/12/sys/compat/linux/linux_ioctl.c stable/12/sys/i386/linux/linux.h Directory Properties: stable/12/ (props changed) Modified: stable/12/sys/amd64/linux/linux.h ============================================================================== --- stable/12/sys/amd64/linux/linux.h Wed May 22 04:51:08 2019 (r348091) +++ stable/12/sys/amd64/linux/linux.h Wed May 22 05:32:39 2019 (r348092) @@ -377,11 +377,6 @@ union l_semun { l_uintptr_t __pad; }; -struct l_sockaddr { - l_ushort sa_family; - char sa_data[14]; -}; - struct l_ifmap { l_ulong mem_start; l_ulong mem_end; @@ -390,9 +385,6 @@ struct l_ifmap { u_char dma; u_char port; } __packed; - -#define LINUX_IFHWADDRLEN 6 -#define LINUX_IFNAMSIZ 16 struct l_ifreq { union { Modified: stable/12/sys/amd64/linux32/linux.h ============================================================================== --- stable/12/sys/amd64/linux32/linux.h Wed May 22 04:51:08 2019 (r348091) +++ stable/12/sys/amd64/linux32/linux.h Wed May 22 05:32:39 2019 (r348092) @@ -478,11 +478,6 @@ union l_semun { l_uintptr_t __pad; } __packed; -struct l_sockaddr { - l_ushort sa_family; - char sa_data[14]; -} __packed; - struct l_ifmap { l_ulong mem_start; l_ulong mem_end; @@ -491,9 +486,6 @@ struct l_ifmap { u_char dma; u_char port; } __packed; - -#define LINUX_IFHWADDRLEN 6 -#define LINUX_IFNAMSIZ 16 struct l_ifreq { union { Modified: stable/12/sys/arm64/linux/linux.h ============================================================================== --- stable/12/sys/arm64/linux/linux.h Wed May 22 04:51:08 2019 (r348091) +++ stable/12/sys/arm64/linux/linux.h Wed May 22 05:32:39 2019 (r348092) @@ -264,11 +264,6 @@ union l_semun { l_uintptr_t __pad; }; -struct l_sockaddr { - l_ushort sa_family; - char sa_data[14]; -}; - struct l_ifmap { l_ulong mem_start; l_ulong mem_end; @@ -277,9 +272,6 @@ struct l_ifmap { u_char dma; u_char port; } __packed; - -#define LINUX_IFHWADDRLEN 6 -#define LINUX_IFNAMSIZ 16 struct l_ifreq { union { Modified: stable/12/sys/compat/linux/linux.c ============================================================================== --- stable/12/sys/compat/linux/linux.c Wed May 22 04:51:08 2019 (r348091) +++ stable/12/sys/compat/linux/linux.c Wed May 22 05:32:39 2019 (r348092) @@ -29,10 +29,21 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> +#include <sys/ctype.h> +#include <sys/jail.h> +#include <sys/lock.h> #include <sys/signalvar.h> +#include <sys/socket.h> +#include <net/if.h> +#include <net/if_var.h> +#include <net/if_dl.h> +#include <net/if_types.h> + #include <compat/linux/linux.h> +#include <compat/linux/linux_common.h> +CTASSERT(LINUX_IFNAMSIZ == IFNAMSIZ); static int bsd_to_linux_sigtbl[LINUX_SIGTBLSZ] = { LINUX_SIGHUP, /* SIGHUP */ @@ -202,4 +213,98 @@ bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) LINUX_SIGADDSET(*lss, l); } } +} + +/* + * Translate a Linux interface name to a FreeBSD interface name, + * and return the associated ifnet structure + * bsdname and lxname need to be least IFNAMSIZ bytes long, but + * can point to the same buffer. + */ +struct ifnet * +ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname) +{ + struct ifnet *ifp; + int len, unit; + char *ep; + int is_eth, is_lo, index; + + for (len = 0; len < LINUX_IFNAMSIZ; ++len) + if (!isalpha(lxname[len]) || lxname[len] == 0) + break; + if (len == 0 || len == LINUX_IFNAMSIZ) + return (NULL); + /* Linux loopback interface name is lo (not lo0) */ + is_lo = (len == 2 && !strncmp(lxname, "lo", len)) ? 1 : 0; + unit = (int)strtoul(lxname + len, &ep, 10); + if ((ep == NULL || ep == lxname + len || ep >= lxname + LINUX_IFNAMSIZ) && + is_lo == 0) + return (NULL); + index = 0; + is_eth = (len == 3 && !strncmp(lxname, "eth", len)) ? 1 : 0; + + CURVNET_SET(TD_TO_VNET(td)); + IFNET_RLOCK(); + CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { + /* + * Allow Linux programs to use FreeBSD names. Don't presume + * we never have an interface named "eth", so don't make + * the test optional based on is_eth. + */ + if (strncmp(ifp->if_xname, lxname, LINUX_IFNAMSIZ) == 0) + break; + if (is_eth && IFP_IS_ETH(ifp) && unit == index++) + break; + if (is_lo && IFP_IS_LOOP(ifp)) + break; + } + IFNET_RUNLOCK(); + CURVNET_RESTORE(); + if (ifp != NULL && bsdname != NULL) + strlcpy(bsdname, ifp->if_xname, IFNAMSIZ); + return (ifp); +} + +void +linux_ifflags(struct ifnet *ifp, short *flags) +{ + + *flags = (ifp->if_flags | ifp->if_drv_flags) & 0xffff; + /* these flags have no Linux equivalent */ + *flags &= ~(IFF_DRV_OACTIVE|IFF_SIMPLEX| + IFF_LINK0|IFF_LINK1|IFF_LINK2); + /* Linux' multicast flag is in a different bit */ + if (*flags & IFF_MULTICAST) { + *flags &= ~IFF_MULTICAST; + *flags |= 0x1000; + } +} + +int +linux_ifhwaddr(struct ifnet *ifp, struct l_sockaddr *lsa) +{ + struct ifaddr *ifa; + struct sockaddr_dl *sdl; + + if (IFP_IS_LOOP(ifp)) { + bzero(lsa, sizeof(*lsa)); + lsa->sa_family = LINUX_ARPHRD_LOOPBACK; + return (0); + } + + if (!IFP_IS_ETH(ifp)) + return (ENOENT); + + CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { + sdl = (struct sockaddr_dl*)ifa->ifa_addr; + if (sdl != NULL && (sdl->sdl_family == AF_LINK) && + (sdl->sdl_type == IFT_ETHER)) { + bzero(lsa, sizeof(*lsa)); + lsa->sa_family = LINUX_ARPHRD_ETHER; + bcopy(LLADDR(sdl), lsa->sa_data, LINUX_IFHWADDRLEN); + return (0); + } + } + + return (ENOENT); } Modified: stable/12/sys/compat/linux/linux.h ============================================================================== --- stable/12/sys/compat/linux/linux.h Wed May 22 04:51:08 2019 (r348091) +++ stable/12/sys/compat/linux/linux.h Wed May 22 05:32:39 2019 (r348092) @@ -29,6 +29,23 @@ #ifndef _LINUX_MI_H_ #define _LINUX_MI_H_ +#define LINUX_IFHWADDRLEN 6 +#define LINUX_IFNAMSIZ 16 + +/* + * Criteria for interface name translation + */ +#define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER) +#define IFP_IS_LOOP(ifp) (ifp->if_type == IFT_LOOP) + +struct l_sockaddr { + unsigned short sa_family; + char sa_data[14]; +}; + +#define LINUX_ARPHRD_ETHER 1 +#define LINUX_ARPHRD_LOOPBACK 772 + /* sigaltstack */ #define LINUX_SS_ONSTACK 1 #define LINUX_SS_DISABLE 2 Copied: stable/12/sys/compat/linux/linux_common.h (from r347052, head/sys/compat/linux/linux_common.h) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/12/sys/compat/linux/linux_common.h Wed May 22 05:32:39 2019 (r348092, copy of r347052, head/sys/compat/linux/linux_common.h) @@ -0,0 +1,38 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2019 Dmitry Chagin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LINUX_COMMON_H_ +#define _LINUX_COMMON_H_ + +struct ifnet *ifname_linux_to_bsd(struct thread *td, + const char *lxname, char *bsdname); +void linux_ifflags(struct ifnet *ifp, short *flags); +int linux_ifhwaddr(struct ifnet *ifp, struct l_sockaddr *lsa); + +#endif /* _LINUX_COMMON_H_ */ Modified: stable/12/sys/compat/linux/linux_ioctl.c ============================================================================== --- stable/12/sys/compat/linux/linux_ioctl.c Wed May 22 04:51:08 2019 (r348091) +++ stable/12/sys/compat/linux/linux_ioctl.c Wed May 22 05:32:39 2019 (r348092) @@ -81,6 +81,7 @@ __FBSDID("$FreeBSD$"); #include <machine/../linux/linux_proto.h> #endif +#include <compat/linux/linux_common.h> #include <compat/linux/linux_ioctl.h> #include <compat/linux/linux_mib.h> #include <compat/linux/linux_socket.h> @@ -2122,56 +2123,6 @@ linux_ioctl_console(struct thread *td, struct linux_io } /* - * Criteria for interface name translation - */ -#define IFP_IS_ETH(ifp) (ifp->if_type == IFT_ETHER) - -/* - * Translate a Linux interface name to a FreeBSD interface name, - * and return the associated ifnet structure - * bsdname and lxname need to be least IFNAMSIZ bytes long, but - * can point to the same buffer. - */ - -static struct ifnet * -ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname) -{ - struct ifnet *ifp; - int len, unit; - char *ep; - int is_eth, index; - - for (len = 0; len < LINUX_IFNAMSIZ; ++len) - if (!isalpha(lxname[len])) - break; - if (len == 0 || len == LINUX_IFNAMSIZ) - return (NULL); - unit = (int)strtoul(lxname + len, &ep, 10); - if (ep == NULL || ep == lxname + len || ep >= lxname + LINUX_IFNAMSIZ) - return (NULL); - index = 0; - is_eth = (len == 3 && !strncmp(lxname, "eth", len)) ? 1 : 0; - CURVNET_SET(TD_TO_VNET(td)); - IFNET_RLOCK(); - CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { - /* - * Allow Linux programs to use FreeBSD names. Don't presume - * we never have an interface named "eth", so don't make - * the test optional based on is_eth. - */ - if (strncmp(ifp->if_xname, lxname, LINUX_IFNAMSIZ) == 0) - break; - if (is_eth && IFP_IS_ETH(ifp) && unit == index++) - break; - } - IFNET_RUNLOCK(); - CURVNET_RESTORE(); - if (ifp != NULL) - strlcpy(bsdname, ifp->if_xname, IFNAMSIZ); - return (ifp); -} - -/* * Implement the SIOCGIFNAME ioctl */ @@ -2332,50 +2283,20 @@ linux_gifflags(struct thread *td, struct ifnet *ifp, s { l_short flags; - flags = (ifp->if_flags | ifp->if_drv_flags) & 0xffff; - /* these flags have no Linux equivalent */ - flags &= ~(IFF_DRV_OACTIVE|IFF_SIMPLEX| - IFF_LINK0|IFF_LINK1|IFF_LINK2); - /* Linux' multicast flag is in a different bit */ - if (flags & IFF_MULTICAST) { - flags &= ~IFF_MULTICAST; - flags |= 0x1000; - } + linux_ifflags(ifp, &flags); return (copyout(&flags, &ifr->ifr_flags, sizeof(flags))); } -#define ARPHRD_ETHER 1 -#define ARPHRD_LOOPBACK 772 - static int linux_gifhwaddr(struct ifnet *ifp, struct l_ifreq *ifr) { - struct ifaddr *ifa; - struct sockaddr_dl *sdl; struct l_sockaddr lsa; - if (ifp->if_type == IFT_LOOP) { - bzero(&lsa, sizeof(lsa)); - lsa.sa_family = ARPHRD_LOOPBACK; - return (copyout(&lsa, &ifr->ifr_hwaddr, sizeof(lsa))); - } - - if (ifp->if_type != IFT_ETHER) + if (linux_ifhwaddr(ifp, &lsa) != 0) return (ENOENT); - CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - sdl = (struct sockaddr_dl*)ifa->ifa_addr; - if (sdl != NULL && (sdl->sdl_family == AF_LINK) && - (sdl->sdl_type == IFT_ETHER)) { - bzero(&lsa, sizeof(lsa)); - lsa.sa_family = ARPHRD_ETHER; - bcopy(LLADDR(sdl), lsa.sa_data, LINUX_IFHWADDRLEN); - return (copyout(&lsa, &ifr->ifr_hwaddr, sizeof(lsa))); - } - } - - return (ENOENT); + return (copyout(&lsa, &ifr->ifr_hwaddr, sizeof(lsa))); } Modified: stable/12/sys/i386/linux/linux.h ============================================================================== --- stable/12/sys/i386/linux/linux.h Wed May 22 04:51:08 2019 (r348091) +++ stable/12/sys/i386/linux/linux.h Wed May 22 05:32:39 2019 (r348092) @@ -454,11 +454,6 @@ union l_semun { l_uintptr_t __pad; }; -struct l_sockaddr { - l_ushort sa_family; - char sa_data[14]; -}; - struct l_ifmap { l_ulong mem_start; l_ulong mem_end; @@ -467,9 +462,6 @@ struct l_ifmap { u_char dma; u_char port; }; - -#define LINUX_IFHWADDRLEN 6 -#define LINUX_IFNAMSIZ 16 struct l_ifreq { union {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905220532.x4M5Wdne099695>