git: f13a042a5711 - main - netlink/route: Support modifying IFLA_ADDRESS with RTM_NEWLINK

From: Aymeric Wibo <obiwac_at_FreeBSD.org>
Date: Sat, 23 Aug 2025 19:12:33 UTC
The branch main has been updated by obiwac:

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

commit f13a042a5711310c0b240338c7bd8d6b58f05478
Author:     Muhammad Saheed <saheed@FreeBSD.org>
AuthorDate: 2025-08-23 19:09:35 +0000
Commit:     Aymeric Wibo <obiwac@FreeBSD.org>
CommitDate: 2025-08-23 19:11:42 +0000

    netlink/route: Support modifying IFLA_ADDRESS with RTM_NEWLINK
    
    Allows setting link-layer address (MAC) by specifying the IFLA_ADDRESS
    attribute on RTM_NEWLINK requests.
    
    Reviewed by:    melifaro, obiwac, mckusick (mentor)
    Approved by:    melifaro, obiwac, mckusick (mentor)
    Sponsored by:   Google LLC (GSoC)
    Differential Revision:  https://reviews.freebsd.org/D51922
---
 sys/netlink/route/iface.c         |  1 +
 sys/netlink/route/iface_drivers.c | 18 ++++++++++++++++++
 sys/netlink/route/route_var.h     |  1 +
 3 files changed, 20 insertions(+)

diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
index 8b871576d0b2..9beb80792af4 100644
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -403,6 +403,7 @@ static const struct nlattr_parser nla_p_linfo[] = {
 NL_DECLARE_ATTR_PARSER(linfo_parser, nla_p_linfo);
 
 static const struct nlattr_parser nla_p_if[] = {
+	{ .type = IFLA_ADDRESS, .off = _OUT(ifla_address), .cb = nlattr_get_nla },
 	{ .type = IFLA_IFNAME, .off = _OUT(ifla_ifname), .cb = nlattr_get_string },
 	{ .type = IFLA_MTU, .off = _OUT(ifla_mtu), .cb = nlattr_get_uint32 },
 	{ .type = IFLA_LINK, .off = _OUT(ifla_link), .cb = nlattr_get_uint32 },
diff --git a/sys/netlink/route/iface_drivers.c b/sys/netlink/route/iface_drivers.c
index 4bf913d9c978..21db3017df18 100644
--- a/sys/netlink/route/iface_drivers.c
+++ b/sys/netlink/route/iface_drivers.c
@@ -105,6 +105,24 @@ _nl_modify_ifp_generic(struct ifnet *ifp, struct nl_parsed_link *lattrs,
 		}
 	}
 
+	if (lattrs->ifla_address != NULL) {
+		if (nlp_has_priv(npt->nlp, PRIV_NET_SETIFMAC)) {
+			error = if_setlladdr(ifp,
+			    NLA_DATA(lattrs->ifla_address),
+			    NLA_DATA_LEN(lattrs->ifla_address));
+			if (error != 0) {
+				nlmsg_report_err_msg(npt,
+				    "setting IFLA_ADDRESS failed with error code: %d",
+				    error);
+				return (error);
+			}
+		} else {
+			nlmsg_report_err_msg(npt,
+			    "Not enough privileges to set IFLA_ADDRESS");
+			return (EPERM);
+		}
+	}
+
 	return (0);
 }
 
diff --git a/sys/netlink/route/route_var.h b/sys/netlink/route/route_var.h
index b84b34461e35..41f110038b54 100644
--- a/sys/netlink/route/route_var.h
+++ b/sys/netlink/route/route_var.h
@@ -69,6 +69,7 @@ struct nl_parsed_link {
 	char		*ifla_cloner;
 	char		*ifla_ifalias;
 	struct nlattr	*ifla_idata;
+	struct nlattr	*ifla_address;
 	unsigned short	ifi_type;
 	int		ifi_index;
 	uint32_t	ifla_link;