From nobody Sun Feb 26 08:11:26 2023 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4PPbtk6zg9z3s3ZW; Sun, 26 Feb 2023 08:11:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4PPbtk5zBWz4FRX; Sun, 26 Feb 2023 08:11:26 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1677399086; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=418k3Olwv4J9t9daylnmjKPWrhhUxCE5isvsgZ2eRpI=; b=CQLCbgPLMK5mPtL0l8UzxENdYakXVy2bizztDUjmZ5bQQeLEXCvvID/k6UzTRZoza6FP1c YY4L7GaQeVCOQ+jBerLh4P+82QzNJywkLJFgafF0x2HIqu24dS7v5X/qeLLzhYJQiFYbb0 dvh2aqAdBUoODHeRHa8czUgEHf8YfU8f0ALkkJeYXTQbz9kFodOLzH2L1Y5wNx+msI4cSx 3nsuERLPgoz3WVpIwvf15+D4P9ASo1uFKtgXzFd3WmmkqpL7VoWN/6LuzRhPG+I2QzZsLS 2sFoSgugPpjx8XN5w4ShNAOIKWXMiR4kgpYKj6LKSBcHspASV88QfAWSiAMupg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1677399086; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=418k3Olwv4J9t9daylnmjKPWrhhUxCE5isvsgZ2eRpI=; b=MhUqI1b2G2rN/+lyYgJ5qQ+oGaq5z8K6PypYjMwF59Wnpt0X1/rrdGqnFfSyZ6s4QAl3pr IEBrUAljA1vIltaAzTgJMTxm/telDuPwoPIzCEgs83XLNquu5/WzZsqR6rPG9bnFeyWKut crfKz5Rc+Zos9aSf+O+Fjt3H/pBDgBdwVMp/4jDKXpLBy1SnV4AOWKbUwwU23JlQZYbAgE fT6FCIzZYQ4qm8UXiqgXSIb5k5rIqGRi42OCFTXyPL1FZEscqlKv+3wxt/2xGjdZnVF8KV A2bErw5NtLOJlrFugc4+lIbnJQ4o8/WMXcWyWWQkvHlu190S5RuBAYps35GLiA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1677399086; a=rsa-sha256; cv=none; b=tTxIBtXYDddG0A7KiTpQ7IJ1DUL5GpGhSUUQGDi0Oh1hjRvifDteZOxrnTCl3U9OazaO15 WUJKHo3BjGN0vvOICXwZpneQVK4s930oT40lDk2JLZKChWOuo4+GJ5whcj/WjFEuUFIGnz v2xrTW98bMzSCPFRt/n2oNGVw+X9QK9Gu46QlXkfl6DekyZJRr8ai370desWX7kNLDFT5T 9vNZjMJyQU6GILs0m9uEZmbc8VySPWyVUxfgzVXmVn/Ht2Jr7pL+zEOF7SwdYxVc3yFYq8 hDyEzBr4cv+5zJw8pRayfyFJ/+vnidgB0kh9KaWMkIau/IrEIO2XO44O9TcP7Q== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4PPbtk4t1mzdXw; Sun, 26 Feb 2023 08:11:26 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 31Q8BQDV082510; Sun, 26 Feb 2023 08:11:26 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 31Q8BQFf082509; Sun, 26 Feb 2023 08:11:26 GMT (envelope-from git) Date: Sun, 26 Feb 2023 08:11:26 GMT Message-Id: <202302260811.31Q8BQFf082509@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dmitry Chagin Subject: git: a83551a52d1c - stable/13 - linux(4): Consolidate a FreeBSD interface names translation code List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: dchagin X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: a83551a52d1cfa8a756ef8dd298cab8042e27437 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by dchagin: URL: https://cgit.FreeBSD.org/src/commit/?id=a83551a52d1cfa8a756ef8dd298cab8042e27437 commit a83551a52d1cfa8a756ef8dd298cab8042e27437 Author: Dmitry Chagin AuthorDate: 2023-02-23 08:00:29 +0000 Commit: Dmitry Chagin CommitDate: 2023-02-26 08:10:44 +0000 linux(4): Consolidate a FreeBSD interface names translation code We have some amount of interface names translation functions which are differs by bugs implementation. Consolidates it in a one place. Fixup loopback interface names translation and use ifnet methods and accessors, where possible. Reviewed by: melifaro Differential Revision: https://reviews.freebsd.org/D38714 MFC after: 3 days X-MFC with: 32fdc75fe7 (cherry picked from commit 3ab3c9c29cf0e5df8dbbaaf2003456445534bad8) --- sys/compat/linprocfs/linprocfs.c | 40 +++++------------- sys/compat/linux/linux.c | 87 ++++++++++++++++++++++++++++++++++++++-- sys/compat/linux/linux_common.h | 4 ++ sys/compat/linux/linux_ioctl.c | 56 +++++++------------------- 4 files changed, 113 insertions(+), 74 deletions(-) diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index a93f8a1dbb8b..3aa01de9ce65 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -111,6 +111,7 @@ __FBSDID("$FreeBSD$"); #endif /* __i386__ || __amd64__ */ #include +#include #include #include #include @@ -1474,36 +1475,13 @@ linprocfs_doprocmem(PFS_FILL_ARGS) 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 */ static int linprocfs_donetdev(PFS_FILL_ARGS) { + struct epoch_tracker et; char ifname[16]; /* XXX LINUX_IFNAMSIZ */ struct ifnet *ifp; @@ -1515,9 +1493,9 @@ linprocfs_donetdev(PFS_FILL_ARGS) "bytes packets errs drop fifo colls carrier compressed"); CURVNET_SET(TD_TO_VNET(curthread)); - IFNET_RLOCK(); + NET_EPOCH_ENTER(et); 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), @@ -1546,7 +1524,7 @@ linprocfs_donetdev(PFS_FILL_ARGS) * tx_heartbeat_errors*/ 0UL); /* tx_compressed */ } - IFNET_RUNLOCK(); + NET_EPOCH_EXIT(et); CURVNET_RESTORE(); return (0); @@ -1576,7 +1554,8 @@ linux_route_print(struct rtentry *rt, void *vw) /* select only first route in case of multipath */ nh = nhop_select_func(rnd.rnd_nhop, 0); - linux_ifname(nh->nh_ifp, ifname, sizeof(ifname)); + if (ifname_bsd_to_linux_ifp(nh->nh_ifp, ifname, sizeof(ifname)) <= 0) + return (ENODEV); gw = (nh->nh_flags & NHF_GATEWAY) ? nh->gw4_sa.sin_addr.s_addr : 0; @@ -1605,6 +1584,7 @@ linux_route_print(struct rtentry *rt, void *vw) static int linprocfs_donetroute(PFS_FILL_ARGS) { + struct epoch_tracker et; struct walkarg w = { .sb = sb }; @@ -1615,9 +1595,9 @@ linprocfs_donetroute(PFS_FILL_ARGS) "\tWindow\tIRTT"); CURVNET_SET(TD_TO_VNET(curthread)); - IFNET_RLOCK(); + NET_EPOCH_ENTER(et); rib_walk(fibnum, AF_INET, false, linux_route_print, &w); - IFNET_RUNLOCK(); + NET_EPOCH_EXIT(et); CURVNET_RESTORE(); return (0); diff --git a/sys/compat/linux/linux.c b/sys/compat/linux/linux.c index bf0479b89588..41297d549c26 100644 --- a/sys/compat/linux/linux.c +++ b/sys/compat/linux/linux.c @@ -242,6 +242,84 @@ bsd_to_linux_sigset(sigset_t *bss, l_sigset_t *lss) } } +/* + * 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(const char *bsdname, char *lxname, size_t len) +{ + struct epoch_tracker et; + struct ifnet *ifp; + int ret; + + ret = 0; + CURVNET_SET(TD_TO_VNET(curthread)); + NET_EPOCH_ENTER(et); + ifp = ifunit(bsdname); + if (ifp != NULL) + ret = ifname_bsd_to_linux_ifp(ifp, lxname, len); + NET_EPOCH_EXIT(et); + 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(u_int idx, char *lxname, size_t len) +{ + struct epoch_tracker et; + struct ifnet *ifp; + int ret; + + ret = 0; + CURVNET_SET(TD_TO_VNET(curthread)); + NET_EPOCH_ENTER(et); + ifp = ifnet_byindex(idx); + if (ifp != NULL) + ret = ifname_bsd_to_linux_ifp(ifp, lxname, len); + NET_EPOCH_EXIT(et); + 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 unit; + + NET_EPOCH_ASSERT(); + + /* + * Linux loopback interface name is lo (not lo0), + * we translate lo to lo0, loX to loX. + */ + if (IFP_IS_LOOP(ifp) && strncmp(ifp->if_xname, "lo0", IFNAMSIZ) == 0) + 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. */ + unit = 0; + CK_STAILQ_FOREACH(ifscan, &V_ifnet, if_link) { + if (ifscan == ifp) + return (snprintf(lxname, len, "eth%d", unit)); + if (IFP_IS_ETH(ifscan)) + unit++; + } + return (0); +} + /* * Translate a Linux interface name to a FreeBSD interface name, * and return the associated ifnet structure @@ -262,8 +340,11 @@ ifname_linux_to_bsd(struct thread *td, const char *lxname, char *bsdname) 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) == 0); + /* + * Linux loopback interface name is lo (not lo0), + * we translate lo to lo0, loX to loX. + */ + is_lo = (len == 2 && strncmp(lxname, "lo", LINUX_IFNAMSIZ) == 0); unit = (int)strtoul(lxname + len, &ep, 10); if ((ep == NULL || ep == lxname + len || ep >= lxname + LINUX_IFNAMSIZ) && is_lo == 0) @@ -736,5 +817,5 @@ bool 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 index 0eb302bfcd17..9ebaff26b9ff 100644 --- 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(u_int, char *, size_t); +int ifname_bsd_to_linux_name(const 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 index 29edea547725..cd739522c496 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -2105,39 +2105,17 @@ static int 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); } /* @@ -2147,6 +2125,7 @@ linux_ioctl_ifname(struct thread *td, struct l_ifreq *uifr) static int linux_ifconf(struct thread *td, struct ifconf *uifc) { + struct epoch_tracker et; #ifdef COMPAT_LINUX32 struct l_ifconf ifc; #else @@ -2156,7 +2135,7 @@ linux_ifconf(struct thread *td, struct ifconf *uifc) 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) @@ -2168,7 +2147,7 @@ linux_ifconf(struct thread *td, struct ifconf *uifc) /* handle the 'request buffer size' case */ if ((l_uintptr_t)ifc.ifc_buf == PTROUT(NULL)) { ifc.ifc_len = 0; - IFNET_RLOCK(); + NET_EPOCH_ENTER(et); CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { struct sockaddr *sa = ifa->ifa_addr; @@ -2176,7 +2155,7 @@ linux_ifconf(struct thread *td, struct ifconf *uifc) ifc.ifc_len += sizeof(ifr); } } - IFNET_RUNLOCK(); + NET_EPOCH_EXIT(et); error = copyout(&ifc, uifc, sizeof(ifc)); CURVNET_RESTORE(); return (error); @@ -2188,8 +2167,6 @@ linux_ifconf(struct thread *td, struct ifconf *uifc) } again: - /* Keep track of eth interfaces */ - ethno = 0; if (ifc.ifc_len <= max_len) { max_len = ifc.ifc_len; full = 1; @@ -2199,16 +2176,13 @@ again: valid_len = 0; /* Return all AF_INET addresses of all interfaces */ - IFNET_RLOCK(); + NET_EPOCH_ENTER(et); 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); + ifname_bsd_to_linux_ifp(ifp, ifr.ifr_name, + sizeof(ifr.ifr_name)); /* Walk the address list */ CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { @@ -2235,7 +2209,7 @@ again: valid_len = sbuf_len(sb); } } - IFNET_RUNLOCK(); + NET_EPOCH_EXIT(et); if (valid_len != max_len && !full) { sbuf_delete(sb);