Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107000045
D38714.id117718.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D38714.id117718.diff
View Options
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -111,6 +111,7 @@
#endif /* __i386__ || __amd64__ */
#include <compat/linux/linux.h>
+#include <compat/linux/linux_common.h>
#include <compat/linux/linux_emul.h>
#include <compat/linux/linux_mib.h>
#include <compat/linux/linux_misc.h>
@@ -1474,30 +1475,6 @@
return (error);
}
-static int
-linux_ifname(struct ifnet *ifp, char *buffer, size_t buflen)
-{
- struct ifnet *ifscan;
- int ethno;
-
- IFNET_RLOCK_ASSERT();
-
- /* Short-circuit non ethernet interfaces */
- if (linux_use_real_ifname(ifp))
- return (strlcpy(buffer, ifp->if_xname, buflen));
-
- /* Determine the (relative) unit number for ethernet interfaces */
- ethno = 0;
- CK_STAILQ_FOREACH(ifscan, &V_ifnet, if_link) {
- if (ifscan == ifp)
- return (snprintf(buffer, buflen, "eth%d", ethno));
- if (!linux_use_real_ifname(ifscan))
- ethno++;
- }
-
- return (0);
-}
-
/*
* Filler function for proc/net/dev
*/
@@ -1517,7 +1494,7 @@
CURVNET_SET(TD_TO_VNET(curthread));
IFNET_RLOCK();
CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
- linux_ifname(ifp, ifname, sizeof ifname);
+ ifname_bsd_to_linux_ifp(ifp, ifname, sizeof(ifname));
sbuf_printf(sb, "%6.6s: ", ifname);
sbuf_printf(sb, "%7ju %7ju %4ju %4ju %4lu %5lu %10lu %9ju ",
(uintmax_t )ifp->if_get_counter(ifp, IFCOUNTER_IBYTES),
@@ -1576,7 +1553,7 @@
/* select only first route in case of multipath */
nh = nhop_select_func(rnd.rnd_nhop, 0);
- linux_ifname(nh->nh_ifp, ifname, sizeof(ifname));
+ ifname_bsd_to_linux_ifp(nh->nh_ifp, ifname, sizeof(ifname));
gw = (nh->nh_flags & NHF_GATEWAY)
? nh->gw4_sa.sin_addr.s_addr : 0;
diff --git a/sys/compat/linux/linux.c b/sys/compat/linux/linux.c
--- a/sys/compat/linux/linux.c
+++ b/sys/compat/linux/linux.c
@@ -241,6 +241,85 @@
}
}
+/*
+ * Translate a FreeBSD interface name to a Linux interface name
+ * by interface name, and return the number of bytes copied to lxname.
+ */
+int
+ifname_bsd_to_linux_name(char *bsdname, char *lxname, size_t len)
+{
+ struct ifnet *ifscan;
+ int ret;
+
+ CURVNET_SET(TD_TO_VNET(curthread));
+ IFNET_RLOCK();
+ CK_STAILQ_FOREACH(ifscan, &V_ifnet, if_link) {
+ if (strncmp(ifscan->if_xname, bsdname, IFNAMSIZ) == 0) {
+ ret = ifname_bsd_to_linux_ifp(ifscan, lxname, len);
+ break;
+ }
+ }
+ IFNET_RUNLOCK();
+ CURVNET_RESTORE();
+ return (ret);
+}
+
+/*
+ * Translate a FreeBSD interface name to a Linux interface name
+ * by interface index, and return the number of bytes copied to lxname.
+ */
+int
+ifname_bsd_to_linux_idx(int index, char *lxname, size_t len)
+{
+ struct ifnet *ifscan;
+ int ret, idx;
+
+ /* index starts from 1. */
+ idx = 1;
+ CURVNET_SET(TD_TO_VNET(curthread));
+ IFNET_RLOCK();
+ CK_STAILQ_FOREACH(ifscan, &V_ifnet, if_link) {
+ if (index == idx++) {
+ ret = ifname_bsd_to_linux_ifp(ifscan, lxname, len);
+ break;
+ }
+ }
+ IFNET_RUNLOCK();
+ CURVNET_RESTORE();
+ return (ret);
+}
+
+/*
+ * Translate a FreeBSD interface name to a Linux interface name,
+ * and return the number of bytes copied to lxname.
+ */
+int
+ifname_bsd_to_linux_ifp(struct ifnet *ifp, char *lxname, size_t len)
+{
+ struct ifnet *ifscan;
+ int ethno;
+
+ IFNET_RLOCK_ASSERT();
+
+ /* Linux loopback interface name is lo (not lo0). */
+ if (IFP_IS_LOOP(ifp) && !linux_use_real_ifname(ifp))
+ return (strlcpy(lxname, "lo", len));
+
+ /* Short-circuit non ethernet interfaces. */
+ if (!IFP_IS_ETH(ifp) || linux_use_real_ifname(ifp))
+ return (strlcpy(lxname, ifp->if_xname, len));
+
+ /* Determine the (relative) unit number for ethernet interfaces. */
+ ethno = 0;
+ CK_STAILQ_FOREACH(ifscan, &V_ifnet, if_link) {
+ if (ifscan == ifp)
+ return (snprintf(lxname, len, "eth%d", ethno));
+ if (IFP_IS_ETH(ifscan))
+ ethno++;
+ }
+ return (0);
+}
+
/*
* Translate a Linux interface name to a FreeBSD interface name,
* and return the associated ifnet structure
@@ -732,5 +811,5 @@
linux_use_real_ifname(const struct ifnet *ifp)
{
- return (use_real_ifnames || !IFP_IS_ETH(ifp));
+ return (use_real_ifnames);
}
diff --git a/sys/compat/linux/linux_common.h b/sys/compat/linux/linux_common.h
--- a/sys/compat/linux/linux_common.h
+++ b/sys/compat/linux/linux_common.h
@@ -30,6 +30,10 @@
#ifndef _LINUX_COMMON_H_
#define _LINUX_COMMON_H_
+int ifname_bsd_to_linux_ifp(struct ifnet *, char *, size_t);
+int ifname_bsd_to_linux_idx(int, char *, size_t);
+int ifname_bsd_to_linux_name(char *, char *, size_t);
+
struct ifnet *ifname_linux_to_bsd(struct thread *td,
const char *lxname, char *bsdname);
void linux_ifflags(struct ifnet *ifp, short *flags);
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -2092,39 +2092,17 @@
linux_ioctl_ifname(struct thread *td, struct l_ifreq *uifr)
{
struct l_ifreq ifr;
- struct ifnet *ifp;
- int error, ethno, index;
+ int error, ret;
error = copyin(uifr, &ifr, sizeof(ifr));
if (error != 0)
return (error);
-
- CURVNET_SET(TD_TO_VNET(curthread));
- IFNET_RLOCK();
- index = 1; /* ifr.ifr_ifindex starts from 1 */
- ethno = 0;
- error = ENODEV;
- CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
- if (ifr.ifr_ifindex == index) {
- if (!linux_use_real_ifname(ifp))
- snprintf(ifr.ifr_name, LINUX_IFNAMSIZ,
- "eth%d", ethno);
- else
- strlcpy(ifr.ifr_name, ifp->if_xname,
- LINUX_IFNAMSIZ);
- error = 0;
- break;
- }
- if (!linux_use_real_ifname(ifp))
- ethno++;
- index++;
- }
- IFNET_RUNLOCK();
- if (error == 0)
- error = copyout(&ifr, uifr, sizeof(ifr));
- CURVNET_RESTORE();
-
- return (error);
+ ret = ifname_bsd_to_linux_idx(ifr.ifr_ifindex, ifr.ifr_name,
+ LINUX_IFNAMSIZ);
+ if (ret > 0)
+ return (copyout(&ifr, uifr, sizeof(ifr)));
+ else
+ return (ENODEV);
}
/*
@@ -2143,7 +2121,7 @@
struct ifnet *ifp;
struct ifaddr *ifa;
struct sbuf *sb;
- int error, ethno, full = 0, valid_len, max_len;
+ int error, full = 0, valid_len, max_len;
error = copyin(uifc, &ifc, sizeof(ifc));
if (error != 0)
@@ -2175,8 +2153,6 @@
}
again:
- /* Keep track of eth interfaces */
- ethno = 0;
if (ifc.ifc_len <= max_len) {
max_len = ifc.ifc_len;
full = 1;
@@ -2191,11 +2167,7 @@
int addrs = 0;
bzero(&ifr, sizeof(ifr));
- if (IFP_IS_ETH(ifp))
- snprintf(ifr.ifr_name, LINUX_IFNAMSIZ, "eth%d",
- ethno++);
- else
- strlcpy(ifr.ifr_name, ifp->if_xname, LINUX_IFNAMSIZ);
+ ifname_bsd_to_linux_ifp(ifp, ifr.ifr_name, LINUX_IFNAMSIZ);
/* Walk the address list */
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 9, 6:49 PM (15 m, 57 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15734740
Default Alt Text
D38714.id117718.diff (6 KB)
Attached To
Mode
D38714: linux(4): Consolidate a FreeBSD interface names translation code
Attached
Detach File
Event Timeline
Log In to Comment