Skip site navigation (1)Skip section navigation (2)
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>