Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Feb 2023 17:20:30 GMT
From:      Justin Hibbits <jhibbits@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: e9e637bf243c - main - Revert "Port Linuxulator to IfAPI"
Message-ID:  <202302211720.31LHKU9U003104@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by jhibbits:

URL: https://cgit.FreeBSD.org/src/commit/?id=e9e637bf243c35180936574e761b2fa164a97144

commit e9e637bf243c35180936574e761b2fa164a97144
Author:     Justin Hibbits <jhibbits@FreeBSD.org>
AuthorDate: 2023-02-21 17:18:36 +0000
Commit:     Justin Hibbits <jhibbits@FreeBSD.org>
CommitDate: 2023-02-21 17:20:24 +0000

    Revert "Port Linuxulator to IfAPI"
    
    Revert pending netlink fixes, and further fixes to this.
    
    This reverts commit 52d984831d82d97dc132d0d57fca6ee89572799b.
    
    Requested by:   dchagin
---
 sys/compat/linux/linux.c       | 104 ++++++++-------------
 sys/compat/linux/linux.h       |   4 +-
 sys/compat/linux/linux_ioctl.c | 205 ++++++++++++++++-------------------------
 3 files changed, 118 insertions(+), 195 deletions(-)

diff --git a/sys/compat/linux/linux.c b/sys/compat/linux/linux.c
index 16aa731b20ff..4e435081b3b6 100644
--- a/sys/compat/linux/linux.c
+++ b/sys/compat/linux/linux.c
@@ -241,36 +241,6 @@ bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss)
 	}
 }
 
-struct ifname_linux_to_bsd_cb_s {
-	if_t ifp;
-	const char *lxname;
-	int unit;
-	int index;
-	bool is_lo;
-	bool is_eth;
-};
-
-static int
-ifname_linux_to_bsd_cb(if_t ifp, void *arg)
-{
-	struct ifname_linux_to_bsd_cb_s *cbs = arg;
-
-	/*
-	 * 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.
-	 */
-	cbs->ifp = ifp;
-	if (strncmp(if_name(ifp), cbs->lxname, LINUX_IFNAMSIZ) == 0)
-		return (-1);
-	if (cbs->is_eth && IFP_IS_ETH(ifp) && cbs->unit == cbs->index++)
-		return (-1);
-	if (cbs->is_lo && IFP_IS_LOOP(ifp))
-		return (-1);
-	cbs->ifp = NULL;
-
-	return (0);
-}
 /*
  * Translate a Linux interface name to a FreeBSD interface name,
  * and return the associated ifnet structure
@@ -280,33 +250,46 @@ ifname_linux_to_bsd_cb(if_t ifp, void *arg)
 struct ifnet *
 ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname)
 {
-	struct ifname_linux_to_bsd_cb_s cbs = {};
-	int len;
+	struct ifnet *ifp;
+	int len, unit;
 	char *ep;
+	int index;
+	bool is_eth, is_lo;
 
-	cbs.lxname = lxname;
 	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) */
-	cbs.is_lo = (len == 2 && strncmp(lxname, "lo", len) == 0);
-	cbs.unit = (int)strtoul(lxname + len, &ep, 10);
+	is_lo = (len == 2 && strncmp(lxname, "lo", len) == 0);
+	unit = (int)strtoul(lxname + len, &ep, 10);
 	if ((ep == NULL || ep == lxname + len || ep >= lxname + LINUX_IFNAMSIZ) &&
-	    cbs.is_lo == 0)
+	    is_lo == 0)
 		return (NULL);
-	cbs.index = 0;
-	cbs.is_eth = (len == 3 && strncmp(lxname, "eth", len) == 0);
+	index = 0;
+	is_eth = (len == 3 && strncmp(lxname, "eth", len) == 0);
 
 	CURVNET_SET(TD_TO_VNET(td));
 	IFNET_RLOCK();
-	if_foreach(ifname_linux_to_bsd_cb, &cbs);
+	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 (cbs.ifp != NULL && bsdname != NULL)
-		strlcpy(bsdname, if_name(cbs.ifp), IFNAMSIZ);
-	return (cbs.ifp);
+	if (ifp != NULL && bsdname != NULL)
+		strlcpy(bsdname, ifp->if_xname, IFNAMSIZ);
+	return (ifp);
 }
 
 void
@@ -314,7 +297,7 @@ linux_ifflags(struct ifnet *ifp, short *flags)
 {
 	unsigned short fl;
 
-	fl = (if_getflags(ifp) | if_getdrvflags(ifp)) & 0xffff;
+	fl = (ifp->if_flags | ifp->if_drv_flags) & 0xffff;
 	*flags = 0;
 	if (fl & IFF_UP)
 		*flags |= LINUX_IFF_UP;
@@ -338,28 +321,11 @@ linux_ifflags(struct ifnet *ifp, short *flags)
 		*flags |= LINUX_IFF_MULTICAST;
 }
 
-static u_int
-linux_ifhwaddr_cb(void *arg, struct ifaddr *ifa, u_int count)
-{
-	struct sockaddr_dl *sdl = (struct sockaddr_dl *)ifa->ifa_addr;
-	struct l_sockaddr *lsa = arg;
-
-	if (count > 0)
-		return (0);
-
-	if (sdl->sdl_type != IFT_ETHER)
-		return (0);
-
-	bzero(lsa, sizeof(*lsa));
-	lsa->sa_family = LINUX_ARPHRD_ETHER;
-	bcopy(LLADDR(sdl), lsa->sa_data, LINUX_IFHWADDRLEN);
-
-	return (1);
-}
-
 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));
@@ -370,8 +336,16 @@ linux_ifhwaddr(struct ifnet *ifp, struct l_sockaddr *lsa)
 	if (!IFP_IS_ETH(ifp))
 		return (ENOENT);
 
-	if (if_foreach_addr_type(ifp, AF_LINK, linux_ifhwaddr_cb, lsa) > 0)
-		return (0);
+	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);
 }
@@ -758,5 +732,5 @@ bool
 linux_use_real_ifname(const struct ifnet *ifp)
 {
 
-	return (use_real_ifnames || !IFP_IS_ETH(__DECONST(if_t, ifp)));
+	return (use_real_ifnames || !IFP_IS_ETH(ifp));
 }
diff --git a/sys/compat/linux/linux.h b/sys/compat/linux/linux.h
index e133c35010cf..055d8e3b9cf6 100644
--- a/sys/compat/linux/linux.h
+++ b/sys/compat/linux/linux.h
@@ -287,8 +287,8 @@ struct l_statx {
 /*
  * Criteria for interface name translation
  */
-#define	IFP_IS_ETH(ifp)		(if_gettype(ifp) == IFT_ETHER)
-#define	IFP_IS_LOOP(ifp)	(if_gettype(ifp) == IFT_LOOP)
+#define	IFP_IS_ETH(ifp)		((ifp)->if_type == IFT_ETHER)
+#define	IFP_IS_LOOP(ifp)	((ifp)->if_type == IFT_LOOP)
 
 struct ifnet;
 
diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index c70060b8bf5d..2cb0e9ead23f 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -2087,138 +2087,46 @@ linux_ioctl_console(struct thread *td, struct linux_ioctl_args *args)
 /*
  * Implement the SIOCGIFNAME ioctl
  */
-struct linux_ioctl_ifname_cb_s {
-	struct l_ifreq ifr;
-	int index;
-	int ethno;
-};
-
-static int
-linux_ioctl_ifname_cb(if_t ifp, void *arg)
-{
-	struct linux_ioctl_ifname_cb_s *cbs = arg;
-	
-	if (cbs->ifr.ifr_ifindex == cbs->index) {
-		if (!linux_use_real_ifname(ifp))
-			snprintf(cbs->ifr.ifr_name, LINUX_IFNAMSIZ,
-			    "eth%d", cbs->ethno);
-		else
-			strlcpy(cbs->ifr.ifr_name, if_name(ifp),
-			    LINUX_IFNAMSIZ);
-		return (-1);
-	}
-	if (!linux_use_real_ifname(ifp))
-		cbs->ethno++;
-	cbs->index++;
-
-	return (0);
-}
 
 static int
 linux_ioctl_ifname(struct thread *td, struct l_ifreq *uifr)
 {
-	struct linux_ioctl_ifname_cb_s cbs;
 	struct l_ifreq ifr;
-	int error;
+	struct ifnet *ifp;
+	int error, ethno, index;
 
-	error = copyin(uifr, &cbs.ifr, sizeof(cbs.ifr));
+	error = copyin(uifr, &ifr, sizeof(ifr));
 	if (error != 0)
 		return (error);
 
 	CURVNET_SET(TD_TO_VNET(curthread));
 	IFNET_RLOCK();
-	cbs.index = 1;	/* ifr.ifr_ifindex starts from 1 */
-	cbs.ethno = 0;
-	error = if_foreach(linux_ioctl_ifname_cb, &cbs);
-
-	if (error == 0)
-		error = ENODEV;
+	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 == -1)
+	if (error == 0)
 		error = copyout(&ifr, uifr, sizeof(ifr));
 	CURVNET_RESTORE();
 
 	return (error);
 }
 
-static u_int
-linux_ifconf_ifaddr_cb(void *arg, struct ifaddr *ifa, u_int count)
-{
-#ifdef COMPAT_LINUX32
-	struct l_ifconf *ifc;
-#else
-	struct ifconf *ifc;
-#endif
-	ifc = arg;
-	ifc->ifc_len += sizeof(struct l_ifreq);
-
-	return (1);
-}
-
-static int
-linux_ifconf_ifnet_cb(if_t ifp, void *arg)
-{
-	if_foreach_addr_type(ifp, AF_INET, linux_ifconf_ifaddr_cb, arg);
-
-	return (0);
-}
-
-struct linux_ifconfig_ifaddr_cb2_s {
-	struct l_ifreq ifr;
-	struct sbuf *sb;
-	size_t max_len;
-	size_t valid_len;
-	int ethno;
-};
-
-static u_int
-linux_ifconf_ifaddr_cb2(void *arg, struct ifaddr *ifa, u_int len)
-{
-	struct linux_ifconfig_ifaddr_cb2_s *cbs = arg;
-	struct sockaddr *sa = ifa->ifa_addr;
-
-	cbs->ifr.ifr_addr.sa_family = LINUX_AF_INET;
-	memcpy(cbs->ifr.ifr_addr.sa_data, sa->sa_data,
-	    sizeof(cbs->ifr.ifr_addr.sa_data));
-	sbuf_bcat(cbs->sb, &cbs->ifr, sizeof(cbs->ifr));
-	cbs->max_len += sizeof(cbs->ifr);
-
-	if (sbuf_error(cbs->sb) == 0)
-		cbs->valid_len = sbuf_len(cbs->sb);
-
-	return (len);
-}
-
-static int
-linux_ifconf_ifnet_cb2(if_t ifp, void *arg)
-{
-	struct linux_ifconfig_ifaddr_cb2_s *cbs = arg;
-	int addrs = 0;
-
-	bzero(&cbs->ifr, sizeof(cbs->ifr));
-	if (IFP_IS_ETH(ifp))
-		snprintf(cbs->ifr.ifr_name, LINUX_IFNAMSIZ, "eth%d",
-		    cbs->ethno++);
-	else
-		strlcpy(cbs->ifr.ifr_name, if_name(ifp), LINUX_IFNAMSIZ);
-
-	/* Walk the address list */
-	addrs = if_foreach_addr_type(ifp, AF_INET,
-	    linux_ifconf_ifaddr_cb2, cbs);
-	if (sbuf_error(cbs->sb) == 0)
-		cbs->valid_len = sbuf_len(cbs->sb);
-	if (addrs == 0) {
-		bzero((caddr_t)&cbs->ifr.ifr_addr, sizeof(cbs->ifr.ifr_addr));
-		sbuf_bcat(cbs->sb, &cbs->ifr, sizeof(cbs->ifr));
-		cbs->max_len += sizeof(cbs->ifr);
-
-		if (sbuf_error(cbs->sb) == 0)
-			cbs->valid_len = sbuf_len(cbs->sb);
-	}
-
-	return (0);
-}
-
 /*
  * Implement the SIOCGIFCONF ioctl
  */
@@ -2231,22 +2139,30 @@ linux_ifconf(struct thread *td, struct ifconf *uifc)
 #else
 	struct ifconf ifc;
 #endif
-	struct linux_ifconfig_ifaddr_cb2_s cbs;
+	struct l_ifreq ifr;
+	struct ifnet *ifp;
+	struct ifaddr *ifa;
 	struct sbuf *sb;
-	int error, full = 0;
+	int error, ethno, full = 0, valid_len, max_len;
 
 	error = copyin(uifc, &ifc, sizeof(ifc));
 	if (error != 0)
 		return (error);
 
-	cbs.max_len = maxphys - 1;
+	max_len = maxphys - 1;
 
 	CURVNET_SET(TD_TO_VNET(td));
 	/* handle the 'request buffer size' case */
 	if ((l_uintptr_t)ifc.ifc_buf == PTROUT(NULL)) {
 		ifc.ifc_len = 0;
 		IFNET_RLOCK();
-		if_foreach(linux_ifconf_ifnet_cb, &ifc);
+		CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
+			CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+				struct sockaddr *sa = ifa->ifa_addr;
+				if (sa->sa_family == AF_INET)
+					ifc.ifc_len += sizeof(ifr);
+			}
+		}
 		IFNET_RUNLOCK();
 		error = copyout(&ifc, uifc, sizeof(ifc));
 		CURVNET_RESTORE();
@@ -2259,28 +2175,61 @@ linux_ifconf(struct thread *td, struct ifconf *uifc)
 	}
 
 again:
-	cbs.ethno = 0;
 	/* Keep track of eth interfaces */
-	if (ifc.ifc_len <= cbs.max_len) {
-		cbs.max_len = ifc.ifc_len;
+	ethno = 0;
+	if (ifc.ifc_len <= max_len) {
+		max_len = ifc.ifc_len;
 		full = 1;
 	}
-	sb = sbuf_new(NULL, NULL, cbs.max_len + 1, SBUF_FIXEDLEN);
-	cbs.max_len = 0;
-	cbs.valid_len = 0;
-	cbs.sb = sb;
+	sb = sbuf_new(NULL, NULL, max_len + 1, SBUF_FIXEDLEN);
+	max_len = 0;
+	valid_len = 0;
 
 	/* Return all AF_INET addresses of all interfaces */
 	IFNET_RLOCK();
-	if_foreach(linux_ifconf_ifnet_cb2, &cbs);
+	CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
+		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);
+
+		/* Walk the address list */
+		CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+			struct sockaddr *sa = ifa->ifa_addr;
+
+			if (sa->sa_family == AF_INET) {
+				ifr.ifr_addr.sa_family = LINUX_AF_INET;
+				memcpy(ifr.ifr_addr.sa_data, sa->sa_data,
+				    sizeof(ifr.ifr_addr.sa_data));
+				sbuf_bcat(sb, &ifr, sizeof(ifr));
+				max_len += sizeof(ifr);
+				addrs++;
+			}
+
+			if (sbuf_error(sb) == 0)
+				valid_len = sbuf_len(sb);
+		}
+		if (addrs == 0) {
+			bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
+			sbuf_bcat(sb, &ifr, sizeof(ifr));
+			max_len += sizeof(ifr);
+
+			if (sbuf_error(sb) == 0)
+				valid_len = sbuf_len(sb);
+		}
+	}
 	IFNET_RUNLOCK();
 
-	if (cbs.valid_len != cbs.max_len && !full) {
+	if (valid_len != max_len && !full) {
 		sbuf_delete(sb);
 		goto again;
 	}
 
-	ifc.ifc_len = cbs.valid_len;
+	ifc.ifc_len = valid_len;
 	sbuf_finish(sb);
 	error = copyout(sbuf_data(sb), PTRIN(ifc.ifc_buf), ifc.ifc_len);
 	if (error == 0)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202302211720.31LHKU9U003104>