Page MenuHomeFreeBSD

D20137.id56960.diff
No OneTemporary

D20137.id56960.diff

Index: sys/amd64/linux/linux.h
===================================================================
--- sys/amd64/linux/linux.h
+++ sys/amd64/linux/linux.h
@@ -377,11 +377,6 @@
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;
@@ -391,9 +386,6 @@
u_char port;
} __packed;
-#define LINUX_IFHWADDRLEN 6
-#define LINUX_IFNAMSIZ 16
-
struct l_ifreq {
union {
char ifrn_name[LINUX_IFNAMSIZ];
Index: sys/amd64/linux32/linux.h
===================================================================
--- sys/amd64/linux32/linux.h
+++ sys/amd64/linux32/linux.h
@@ -478,11 +478,6 @@
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;
@@ -492,9 +487,6 @@
u_char port;
} __packed;
-#define LINUX_IFHWADDRLEN 6
-#define LINUX_IFNAMSIZ 16
-
struct l_ifreq {
union {
char ifrn_name[LINUX_IFNAMSIZ];
Index: sys/arm64/linux/linux.h
===================================================================
--- sys/arm64/linux/linux.h
+++ sys/arm64/linux/linux.h
@@ -264,11 +264,6 @@
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;
@@ -278,9 +273,6 @@
u_char port;
} __packed;
-#define LINUX_IFHWADDRLEN 6
-#define LINUX_IFNAMSIZ 16
-
struct l_ifreq {
union {
char ifrn_name[LINUX_IFNAMSIZ];
Index: sys/compat/linux/linux.h
===================================================================
--- sys/compat/linux/linux.h
+++ sys/compat/linux/linux.h
@@ -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
Index: sys/compat/linux/linux.c
===================================================================
--- sys/compat/linux/linux.c
+++ sys/compat/linux/linux.c
@@ -29,10 +29,21 @@
#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 */
@@ -203,3 +214,94 @@
}
}
}
+
+/*
+ * 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, 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);
+}
+
+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);
+}
+
+
+
Index: sys/compat/linux/linux_common.h
===================================================================
--- /dev/null
+++ 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_ */
Index: sys/compat/linux/linux_ioctl.c
===================================================================
--- sys/compat/linux/linux_ioctl.c
+++ sys/compat/linux/linux_ioctl.c
@@ -81,6 +81,7 @@
#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>
@@ -2121,56 +2122,6 @@
return (error);
}
-/*
- * 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 @@
{
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)));
}
Index: sys/i386/linux/linux.h
===================================================================
--- sys/i386/linux/linux.h
+++ sys/i386/linux/linux.h
@@ -454,11 +454,6 @@
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;
@@ -468,9 +463,6 @@
u_char port;
};
-#define LINUX_IFHWADDRLEN 6
-#define LINUX_IFNAMSIZ 16
-
struct l_ifreq {
union {
char ifrn_name[LINUX_IFNAMSIZ];

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 28, 1:53 AM (2 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24329858
Default Alt Text
D20137.id56960.diff (10 KB)

Event Timeline