svn commit: r348092 - in stable/12/sys: amd64/linux amd64/linux32 arm64/linux compat/linux i386/linux
Dmitry Chagin
dchagin at FreeBSD.org
Wed May 22 05:32:42 UTC 2019
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 {
More information about the svn-src-all
mailing list