git: 287d60af1812 - main - compat/linux: Fix IFLA_IFNAME translation for multi-message netlink

From: Pouria Mousavizadeh Tehrani <pouria_at_FreeBSD.org>
Date: Fri, 25 Sep 2026 17:06:29 UTC
The branch main has been updated by pouria:

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

commit 287d60af18126ee0750fa2332896ede2b84a12dc
Author:     Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
AuthorDate: 2026-09-25 16:41:36 +0000
Commit:     Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
CommitDate: 2026-09-25 17:05:36 +0000

    compat/linux: Fix IFLA_IFNAME translation for multi-message netlink
    
    nlmsg_translate_ifname_nla() always used nw->ifp for the name,
    which is fine for a single-message ifnet event, but an RTM_GETLINK
    dump holds one RTM_NEWLINK per interface and is translated with
    the ifp the writer had when the buffer was flushed.
    
    The root of the problem is that msgs_to_linux() takes a single
    ifp for a buffer that may contain messages about many interfaces.
    
    Use ifi_index to resolve the name instead.
    
    Reviewed by:    glebius
    Differential Revision:  https://reviews.freebsd.org/D59595
---
 sys/compat/linux/linux_netlink.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/sys/compat/linux/linux_netlink.c b/sys/compat/linux/linux_netlink.c
index ef6c52c013f9..286cc72ef337 100644
--- a/sys/compat/linux/linux_netlink.c
+++ b/sys/compat/linux/linux_netlink.c
@@ -245,13 +245,16 @@ nlmsg_copy_nla(const struct nlattr *nla_orig, struct nl_writer *nw)
  * Translate a FreeBSD interface name to a Linux interface name.
  */
 static bool
-nlmsg_translate_ifname_nla(struct nlattr *nla, struct nl_writer *nw)
+nlmsg_translate_ifname_nla(struct nlmsghdr *hdr, struct nlattr *nla,
+    struct nl_writer *nw)
 {
+	struct ifinfomsg *ifinfo;
 	char ifname[LINUX_IFNAMSIZ];
 
-	if (nw->ifp == NULL)
-		return (false);
-	(void)ifname_bsd_to_linux_ifp(nw->ifp, ifname, sizeof(ifname));
+	ifinfo = (struct ifinfomsg *)(hdr + 1);
+	if (ifname_bsd_to_linux_idx(ifinfo->ifi_index, ifname,
+	    sizeof(ifname)) <= 0)
+		return (nlmsg_copy_nla(nla, nw));
 	return (nlattr_add_string(nw, IFLA_IFNAME, ifname));
 }
 
@@ -272,7 +275,7 @@ nlmsg_translate_all_nla(struct nlmsghdr *hdr, struct nlattr *nla,
 	case NL_RTM_GETLINK:
 		switch (nla->nla_type) {
 		case IFLA_IFNAME:
-			return (nlmsg_translate_ifname_nla(nla, nw));
+			return (nlmsg_translate_ifname_nla(hdr, nla, nw));
 		default:
 			break;
 		}