Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 Mar 2023 09:12:43 GMT
From:      Dmitry Chagin <dchagin@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 5d5b633dde2a - main - linsysfs(4): Refactor to avoid referencing an unstable interfaces
Message-ID:  <202303040912.3249ChQo078833@gitrepo.freebsd.org>

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

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

commit 5d5b633dde2a12548daa3188fca27c04b51586bf
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2023-03-04 09:11:38 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2023-03-04 09:11:38 +0000

    linsysfs(4): Refactor to avoid referencing an unstable interfaces
    
    Enter the net epoch when traversing a list of interfaces. For that
    split the ifname_linux_to_bsd() function on two counterparts, where
    the ifname_linux_to_ifp() intended to use in epoch, while the
    ifname_linux_to_bsd() intended to be a self-contained.
    Until the linux_ioctl_coket() function is refactored, the
    ifname_linux_to_bsd() temporarily returns interface outside
    of the net epoch.
    
    Reviewed by:            melifaro
    Differential Revision:  https://reviews.freebsd.org/D38790
---
 sys/compat/linsysfs/linsysfs.c  | 103 ++++++++++++++++++++++++++--------------
 sys/compat/linux/linux.c        |  33 ++++++++-----
 sys/compat/linux/linux_common.h |   1 +
 3 files changed, 90 insertions(+), 47 deletions(-)

diff --git a/sys/compat/linsysfs/linsysfs.c b/sys/compat/linsysfs/linsysfs.c
index 0c0744a054a0..3b1bdfc280fc 100644
--- a/sys/compat/linsysfs/linsysfs.c
+++ b/sys/compat/linsysfs/linsysfs.c
@@ -72,18 +72,23 @@ atoi(const char *str)
 static int
 linsysfs_ifnet_addr(PFS_FILL_ARGS)
 {
+	struct epoch_tracker et;
 	struct l_sockaddr lsa;
 	struct ifnet *ifp;
-
-	ifp = ifname_linux_to_bsd(td, pn->pn_parent->pn_name, NULL);
-	if (ifp == NULL)
-		return (ENOENT);
-	if (linux_ifhwaddr(ifp, &lsa) != 0)
-		return (ENOENT);
-	sbuf_printf(sb, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
-	    lsa.sa_data[0], lsa.sa_data[1], lsa.sa_data[2],
-	    lsa.sa_data[3], lsa.sa_data[4], lsa.sa_data[5]);
-	return (0);
+	int error;
+
+	CURVNET_SET(TD_TO_VNET(td));
+	NET_EPOCH_ENTER(et);
+	ifp = ifname_linux_to_ifp(td, pn->pn_parent->pn_name);
+	if (ifp != NULL && (error = linux_ifhwaddr(ifp, &lsa)) == 0)
+		error = sbuf_printf(sb, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
+		    lsa.sa_data[0], lsa.sa_data[1], lsa.sa_data[2],
+		    lsa.sa_data[3], lsa.sa_data[4], lsa.sa_data[5]);
+	else
+		error = ENOENT;
+	NET_EPOCH_EXIT(et);
+	CURVNET_RESTORE();
+	return (error == -1 ? ERANGE : error);
 }
 
 static int
@@ -97,37 +102,58 @@ linsysfs_ifnet_addrlen(PFS_FILL_ARGS)
 static int
 linsysfs_ifnet_flags(PFS_FILL_ARGS)
 {
+	struct epoch_tracker et;
 	struct ifnet *ifp;
-
-	ifp = ifname_linux_to_bsd(td, pn->pn_parent->pn_name, NULL);
-	if (ifp == NULL)
-		return (ENOENT);
-	sbuf_printf(sb, "0x%x\n", linux_ifflags(ifp));
-	return (0);
+	int error;
+
+	CURVNET_SET(TD_TO_VNET(td));
+	NET_EPOCH_ENTER(et);
+	ifp = ifname_linux_to_ifp(td, pn->pn_parent->pn_name);
+	if (ifp != NULL)
+		error = sbuf_printf(sb, "0x%x\n", linux_ifflags(ifp));
+	else
+		error = ENOENT;
+	NET_EPOCH_EXIT(et);
+	CURVNET_RESTORE();
+	return (error == -1 ? ERANGE : error);
 }
 
 static int
 linsysfs_ifnet_ifindex(PFS_FILL_ARGS)
 {
+	struct epoch_tracker et;
 	struct ifnet *ifp;
-
-	ifp = ifname_linux_to_bsd(td, pn->pn_parent->pn_name, NULL);
-	if (ifp == NULL)
-		return (ENOENT);
-	sbuf_printf(sb, "%u\n", if_getindex(ifp));
-	return (0);
+	int error;
+
+	CURVNET_SET(TD_TO_VNET(td));
+	NET_EPOCH_ENTER(et);
+	ifp = ifname_linux_to_ifp(td, pn->pn_parent->pn_name);
+	if (ifp != NULL)
+		error = sbuf_printf(sb, "%u\n", if_getindex(ifp));
+	else
+		error = ENOENT;
+	NET_EPOCH_EXIT(et);
+	CURVNET_RESTORE();
+	return (error == -1 ? ERANGE : error);
 }
 
 static int
 linsysfs_ifnet_mtu(PFS_FILL_ARGS)
 {
+	struct epoch_tracker et;
 	struct ifnet *ifp;
-
-	ifp = ifname_linux_to_bsd(td, pn->pn_parent->pn_name, NULL);
-	if (ifp == NULL)
-		return (ENOENT);
-	sbuf_printf(sb, "%u\n", if_getmtu(ifp));
-	return (0);
+	int error;
+
+	CURVNET_SET(TD_TO_VNET(td));
+	NET_EPOCH_ENTER(et);
+	ifp = ifname_linux_to_ifp(td, pn->pn_parent->pn_name);
+	if (ifp != NULL)
+		error = sbuf_printf(sb, "%u\n", if_getmtu(ifp));
+	else
+		error = ENOENT;
+	NET_EPOCH_EXIT(et);
+	CURVNET_RESTORE();
+	return (error == -1 ? ERANGE : error);
 }
 
 static int
@@ -142,16 +168,21 @@ linsysfs_ifnet_tx_queue_len(PFS_FILL_ARGS)
 static int
 linsysfs_ifnet_type(PFS_FILL_ARGS)
 {
+	struct epoch_tracker et;
 	struct l_sockaddr lsa;
 	struct ifnet *ifp;
-
-	ifp = ifname_linux_to_bsd(td, pn->pn_parent->pn_name, NULL);
-	if (ifp == NULL)
-		return (ENOENT);
-	if (linux_ifhwaddr(ifp, &lsa) != 0)
-		return (ENOENT);
-	sbuf_printf(sb, "%d\n", lsa.sa_family);
-	return (0);
+	int error;
+
+	CURVNET_SET(TD_TO_VNET(td));
+	NET_EPOCH_ENTER(et);
+	ifp = ifname_linux_to_ifp(td, pn->pn_parent->pn_name);
+	if (ifp != NULL && (error = linux_ifhwaddr(ifp, &lsa)) == 0)
+		error = sbuf_printf(sb, "%d\n", lsa.sa_family);
+	else
+		error = ENOENT;
+	NET_EPOCH_EXIT(et);
+	CURVNET_RESTORE();
+	return (error == -1 ? ERANGE : error);
 }
 
 static void
diff --git a/sys/compat/linux/linux.c b/sys/compat/linux/linux.c
index 135bc10e2dc1..f31a4b5e4f5c 100644
--- a/sys/compat/linux/linux.c
+++ b/sys/compat/linux/linux.c
@@ -342,7 +342,7 @@ ifname_bsd_to_linux_ifp(struct ifnet *ifp, char *lxname, size_t len)
  * bsdname and lxname need to be least IFNAMSIZ bytes long, but
  * can point to the same buffer.
  */
-struct ifname_linux_to_bsd_cb_s {
+struct ifname_linux_to_ifp_cb_s {
 	bool		is_lo;
 	bool		is_eth;
 	int		ethno;
@@ -352,9 +352,9 @@ struct ifname_linux_to_bsd_cb_s {
 };
 
 static int
-ifname_linux_to_bsd_cb(if_t ifp, void *arg)
+ifname_linux_to_ifp_cb(if_t ifp, void *arg)
 {
-	struct ifname_linux_to_bsd_cb_s *cbs = arg;
+	struct ifname_linux_to_ifp_cb_s *cbs = arg;
 
 	NET_EPOCH_ASSERT();
 
@@ -379,17 +379,18 @@ out:
 }
 
 struct ifnet *
-ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname)
+ifname_linux_to_ifp(struct thread *td, const char *lxname)
 {
-	struct ifname_linux_to_bsd_cb_s arg = {
+	struct ifname_linux_to_ifp_cb_s arg = {
 		.ethno = 0,
 		.lxname = lxname,
 		.ifp = NULL,
 	};
-	struct epoch_tracker et;
-	int len, ret;
+	int len;
 	char *ep;
 
+	NET_EPOCH_ASSERT();
+
 	for (len = 0; len < LINUX_IFNAMSIZ; ++len)
 		if (!isalpha(lxname[len]) || lxname[len] == '\0')
 			break;
@@ -406,14 +407,24 @@ ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname)
 		return (NULL);
 	arg.is_eth = (len == 3 && strncmp(lxname, "eth", len) == 0);
 
+	if_foreach(ifname_linux_to_ifp_cb, &arg);
+	return (arg.ifp);
+}
+
+struct ifnet *
+ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname)
+{
+	struct epoch_tracker et;
+	struct ifnet *ifp;
+
 	CURVNET_SET(TD_TO_VNET(td));
 	NET_EPOCH_ENTER(et);
-	ret = if_foreach(ifname_linux_to_bsd_cb, &arg);
+	ifp = ifname_linux_to_ifp(td, lxname);
+	if (ifp != NULL && bsdname != NULL)
+		strlcpy(bsdname, if_name(ifp), IFNAMSIZ);
 	NET_EPOCH_EXIT(et);
 	CURVNET_RESTORE();
-	if (ret > 0 && arg.ifp != NULL && bsdname != NULL)
-		strlcpy(bsdname, if_name(arg.ifp), IFNAMSIZ);
-	return (arg.ifp);
+	return (ifp);
 }
 
 unsigned short
diff --git a/sys/compat/linux/linux_common.h b/sys/compat/linux/linux_common.h
index c25c4abf18ae..4b693ccaf868 100644
--- a/sys/compat/linux/linux_common.h
+++ b/sys/compat/linux/linux_common.h
@@ -33,6 +33,7 @@
 int	ifname_bsd_to_linux_ifp(struct ifnet *, char *, size_t);
 int	ifname_bsd_to_linux_idx(u_int, char *, size_t);
 int	ifname_bsd_to_linux_name(const char *, char *, size_t);
+struct ifnet *ifname_linux_to_ifp(struct thread *, const char *);
 
 struct ifnet	*ifname_linux_to_bsd(struct thread *td,
 		    const char *lxname, char *bsdname);



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