Author: dchagin
Date: Fri May  3 08:42:49 2019
New Revision: 347052
URL: https://svnweb.freebsd.org/changeset/base/347052

Log:
  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.
  
  Reviewed by:  emaste
  MFC after:    2 weeks
  Differential Revision:        https://reviews.freebsd.org/D20137

Added:
  head/sys/compat/linux/linux_common.h   (contents, props changed)
Modified:
  head/sys/amd64/linux/linux.h
  head/sys/amd64/linux32/linux.h
  head/sys/arm64/linux/linux.h
  head/sys/compat/linux/linux.c
  head/sys/compat/linux/linux.h
  head/sys/compat/linux/linux_ioctl.c
  head/sys/i386/linux/linux.h

Modified: head/sys/amd64/linux/linux.h
==============================================================================
--- head/sys/amd64/linux/linux.h        Fri May  3 08:27:03 2019        
(r347051)
+++ head/sys/amd64/linux/linux.h        Fri May  3 08:42:49 2019        
(r347052)
@@ -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: head/sys/amd64/linux32/linux.h
==============================================================================
--- head/sys/amd64/linux32/linux.h      Fri May  3 08:27:03 2019        
(r347051)
+++ head/sys/amd64/linux32/linux.h      Fri May  3 08:42:49 2019        
(r347052)
@@ -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: head/sys/arm64/linux/linux.h
==============================================================================
--- head/sys/arm64/linux/linux.h        Fri May  3 08:27:03 2019        
(r347051)
+++ head/sys/arm64/linux/linux.h        Fri May  3 08:42:49 2019        
(r347052)
@@ -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: head/sys/compat/linux/linux.c
==============================================================================
--- head/sys/compat/linux/linux.c       Fri May  3 08:27:03 2019        
(r347051)
+++ head/sys/compat/linux/linux.c       Fri May  3 08:42:49 2019        
(r347052)
@@ -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: head/sys/compat/linux/linux.h
==============================================================================
--- head/sys/compat/linux/linux.h       Fri May  3 08:27:03 2019        
(r347051)
+++ head/sys/compat/linux/linux.h       Fri May  3 08:42:49 2019        
(r347052)
@@ -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

Added: head/sys/compat/linux/linux_common.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/compat/linux/linux_common.h        Fri May  3 08:42:49 2019        
(r347052)
@@ -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: head/sys/compat/linux/linux_ioctl.c
==============================================================================
--- head/sys/compat/linux/linux_ioctl.c Fri May  3 08:27:03 2019        
(r347051)
+++ head/sys/compat/linux/linux_ioctl.c Fri May  3 08:42:49 2019        
(r347052)
@@ -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: head/sys/i386/linux/linux.h
==============================================================================
--- head/sys/i386/linux/linux.h Fri May  3 08:27:03 2019        (r347051)
+++ head/sys/i386/linux/linux.h Fri May  3 08:42:49 2019        (r347052)
@@ -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 {
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to