Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146593982
D52130.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D52130.diff
View Options
diff --git a/lib/libifconfig/Makefile b/lib/libifconfig/Makefile
--- a/lib/libifconfig/Makefile
+++ b/lib/libifconfig/Makefile
@@ -18,6 +18,7 @@
libifconfig_internal.c \
libifconfig_lagg.c \
libifconfig_media.c \
+ libifconfig_nl.c \
libifconfig_sfp.c
GEN= libifconfig_sfp_tables.h \
diff --git a/lib/libifconfig/libifconfig.h b/lib/libifconfig/libifconfig.h
--- a/lib/libifconfig/libifconfig.h
+++ b/lib/libifconfig/libifconfig.h
@@ -382,3 +382,23 @@
* length of *lenp * IFNAMSIZ bytes.
*/
int ifconfig_list_cloners(ifconfig_handle_t *h, char **bufp, size_t *lenp);
+
+/** Get MAC address of an interface
+ * @param h An open ifconfig state object
+ * @param ifname The interface name
+ * @param addr Return argument. It will be filled with the MAC address
+ * @return 0 on success, nonzero on failure.
+ * On failure, the error info on the handle is set.
+ */
+int ifconfig_get_mac(ifconfig_handle_t *h, const char *ifname,
+ struct ether_addr *addr);
+
+/** Set MAC address on an interface
+ * @param h An open ifconfig state object
+ * @param ifname The interface name
+ * @param addr The MAC address
+ * @return 0 on success, nonzero on failure.
+ * On failure, the error info on the handle is set.
+ */
+int ifconfig_set_mac(ifconfig_handle_t *h, const char *ifname,
+ const struct ether_addr *addr);
diff --git a/lib/libifconfig/libifconfig_nl.c b/lib/libifconfig/libifconfig_nl.c
new file mode 100644
--- /dev/null
+++ b/lib/libifconfig/libifconfig_nl.c
@@ -0,0 +1,186 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025, Muhammad Saheed <saheed@FreeBSD.org>
+ */
+
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netlink/netlink.h>
+#include <netlink/netlink_snl.h>
+#include <netlink/netlink_snl_route_parsers.h>
+#include <netlink/route/common.h>
+#include <netlink/route/interface.h>
+
+#include <errno.h>
+
+#include "libifconfig.h"
+#include "libifconfig_internal.h"
+
+static int ifconfig_get_link(ifconfig_handle_t *h, struct snl_state *ss,
+ const char *ifname, struct snl_parsed_link_simple *link);
+
+int
+ifconfig_get_mac(ifconfig_handle_t *h, const char *ifname,
+ struct ether_addr *addr)
+{
+ int ret = 0;
+ uint32_t nlmsg_seq = 0;
+ struct snl_state ss;
+ struct snl_writer nw = { 0 };
+ struct nlmsghdr *hdr;
+ struct snl_parsed_link link = { 0 };
+ struct snl_errmsg_data e = { 0 };
+
+ assert(addr != NULL);
+
+ if (!snl_init(&ss, NETLINK_ROUTE)) {
+ ifconfig_error(h, NETLINK, ENOTSUP);
+ return (-1);
+ }
+
+ snl_init_writer(&ss, &nw);
+ hdr = snl_create_msg_request(&nw, RTM_GETLINK);
+ (void)snl_reserve_msg_object(&nw, struct ifinfomsg);
+
+ snl_add_msg_attr_string(&nw, IFLA_IFNAME, ifname);
+
+ if ((hdr = snl_finalize_msg(&nw)) == NULL) {
+ ifconfig_error(h, NETLINK, ENOMEM);
+ ret = -1;
+ goto out;
+ }
+
+ if (!snl_send_message(&ss, hdr)) {
+ ifconfig_error(h, NETLINK, EIO);
+ ret = -1;
+ goto out;
+ }
+
+ nlmsg_seq = hdr->nlmsg_seq;
+ while ((hdr = snl_read_reply_multi(&ss, nlmsg_seq, &e)) != NULL) {
+ if (!snl_parse_nlmsg(&ss, hdr, &snl_rtm_link_parser, &link))
+ continue;
+
+ if (link.ifla_address != NULL &&
+ NLA_DATA_LEN(link.ifla_address) == ETHER_ADDR_LEN) {
+ memcpy(addr, NLA_DATA(link.ifla_address),
+ ETHER_ADDR_LEN);
+ goto out;
+ }
+ }
+ ifconfig_error(h, NETLINK, ENOENT);
+ ret = -1;
+
+out:
+ snl_free(&ss);
+ return (ret);
+}
+
+static int
+ifconfig_get_link(ifconfig_handle_t *h, struct snl_state *ss,
+ const char *ifname, struct snl_parsed_link_simple *link)
+{
+ struct snl_writer nw = { 0 };
+ struct nlmsghdr *hdr;
+ struct snl_errmsg_data e = { 0 };
+
+ snl_init_writer(ss, &nw);
+ hdr = snl_create_msg_request(&nw, RTM_GETLINK);
+ (void)snl_reserve_msg_object(&nw, struct ifinfomsg);
+ snl_add_msg_attr_string(&nw, IFLA_IFNAME, ifname);
+
+ if ((hdr = snl_finalize_msg(&nw)) == NULL) {
+ ifconfig_error(h, NETLINK, ENOMEM);
+ return (-1);
+ }
+
+ if (!snl_send_message(ss, hdr)) {
+ ifconfig_error(h, NETLINK, EIO);
+ return (-1);
+ }
+
+ hdr = snl_read_reply(ss, hdr->nlmsg_seq);
+ if (hdr->nlmsg_type == NLMSG_ERROR) {
+ int error = snl_parse_errmsg(ss, hdr, &e) ? e.error : EINVAL;
+
+ ifconfig_error(h, NETLINK, error);
+ return (-1);
+ }
+
+ if (hdr->nlmsg_type != RTM_NEWLINK) {
+ ifconfig_error(h, NETLINK, EINVAL);
+ return (1);
+ }
+
+ if (!snl_parse_nlmsg(ss, hdr, &snl_rtm_link_parser_simple, link)) {
+ ifconfig_error(h, NETLINK, EINVAL);
+ return (1);
+ }
+
+ return (0);
+}
+
+int
+ifconfig_set_mac(ifconfig_handle_t *h, const char *ifname,
+ const struct ether_addr *addr)
+{
+ int ret = 0;
+ struct snl_state ss;
+ struct snl_writer nw = { 0 };
+ struct nlmsghdr *hdr;
+ struct ifinfomsg *ifi;
+ struct snl_errmsg_data e = { 0 };
+ struct snl_parsed_link_simple link = { 0 };
+
+ assert(addr != NULL);
+
+ if (!snl_init(&ss, NETLINK_ROUTE)) {
+ ifconfig_error(h, NETLINK, ENOTSUP);
+ return (-1);
+ }
+
+ snl_init_writer(&ss, &nw);
+ hdr = snl_create_msg_request(&nw, RTM_NEWLINK);
+ ifi = snl_reserve_msg_object(&nw, struct ifinfomsg);
+
+ if (ifconfig_get_link(h, &ss, ifname, &link) != 0) {
+ ret = -1;
+ goto out;
+ }
+
+ ifi->ifi_family = AF_UNSPEC;
+ ifi->ifi_type = link.ifi_type;
+ ifi->ifi_index = link.ifi_index;
+
+ /*
+ * Preserve interface flags
+ */
+ ifi->ifi_flags = link.ifi_flags;
+ ifi->ifi_change = 0xFFFFFFFF;
+
+ snl_add_msg_attr_string(&nw, IFLA_IFNAME, ifname);
+ snl_add_msg_attr(&nw, IFLA_ADDRESS, ETHER_ADDR_LEN, addr);
+
+ if ((hdr = snl_finalize_msg(&nw)) == NULL) {
+ ifconfig_error(h, NETLINK, ENOMEM);
+ ret = -1;
+ goto out;
+ }
+
+ if (!snl_send_message(&ss, hdr)) {
+ ifconfig_error(h, NETLINK, EIO);
+ ret = -1;
+ goto out;
+ }
+
+ if (!snl_read_reply_code(&ss, hdr->nlmsg_seq, &e)) {
+ ifconfig_error(h, NETLINK, e.error);
+ ret = -1;
+ goto out;
+ }
+
+out:
+ snl_free(&ss);
+ return (ret);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 4, 10:51 PM (9 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29259408
Default Alt Text
D52130.diff (5 KB)
Attached To
Mode
D52130: libifconfig: Add netlink based helpers to retrieve and set MAC address
Attached
Detach File
Event Timeline
Log In to Comment