[LTP] [PATCH v3 19/31] tst_netdevice: Add two more helper macros
Cyril Hrubis
chrubis@suse.cz
Tue Aug 25 13:36:13 CEST 2026
- NETDEV_SET_HWADDR() helper to change MAC address
- NETDEV_SET_MASTER() helper to connect two devices as master-slave
Signed-off-by: Cyril Hrubis <chrubis@suse.cz>
---
include/tst_netdevice.h | 20 +++++++++
lib/tst_netdevice.c | 90 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 110 insertions(+)
diff --git a/include/tst_netdevice.h b/include/tst_netdevice.h
index 2617bb149..934ee5fb4 100644
--- a/include/tst_netdevice.h
+++ b/include/tst_netdevice.h
@@ -61,6 +61,26 @@ int tst_netdev_remove_address_inet(const char *file, const int lineno,
#define NETDEV_REMOVE_ADDRESS_INET(ifname, address) \
tst_netdev_remove_address_inet(__FILE__, __LINE__, 1, (ifname), \
(address))
+/*
+ * Change the link-layer (MAC) address of an existing network device. Most
+ * drivers require the device to be administratively down for this to
+ * succeed.
+ */
+int tst_netdev_set_hwaddr(const char *file, const int lineno, int strict,
+ const char *ifname, const void *addr, size_t addrlen);
+#define NETDEV_SET_HWADDR(ifname, addr, addrlen) \
+ tst_netdev_set_hwaddr(__FILE__, __LINE__, 1, (ifname), (addr), \
+ (addrlen))
+
+/*
+ * Enslave ifname to the master_ifname device, e.g. add it as a bridge or bond
+ * port. Pass NULL as master_ifname to release the device from its current
+ * master.
+ */
+int tst_netdev_set_master(const char *file, const int lineno, int strict,
+ const char *ifname, const char *master_ifname);
+#define NETDEV_SET_MASTER(ifname, master_ifname) \
+ tst_netdev_set_master(__FILE__, __LINE__, 1, (ifname), (master_ifname))
int tst_netdev_change_ns_fd(const char *file, const int lineno, int strict,
const char *ifname, int nsfd);
diff --git a/lib/tst_netdevice.c b/lib/tst_netdevice.c
index 1042466bf..0861d39fc 100644
--- a/lib/tst_netdevice.c
+++ b/lib/tst_netdevice.c
@@ -287,6 +287,96 @@ static int modify_address(const char *file, const int lineno, int strict,
return ret;
}
+int tst_netdev_set_hwaddr(const char *file, const int lineno, int strict,
+ const char *ifname, const void *addr, size_t addrlen)
+{
+ struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
+ struct tst_netlink_context *ctx;
+ int ret;
+
+ if (strlen(ifname) >= IFNAMSIZ) {
+ tst_brk_(file, lineno, TBROK,
+ "Network device name \"%s\" too long", ifname);
+ return 0;
+ }
+
+ ctx = create_request(file, lineno, RTM_NEWLINK, 0, &info, sizeof(info));
+
+ if (!ctx)
+ return 0;
+
+ if (!tst_rtnl_add_attr_string(file, lineno, ctx, IFLA_IFNAME, ifname)) {
+ tst_netlink_destroy_context(file, lineno, ctx);
+ return 0;
+ }
+
+ if (!tst_rtnl_add_attr(file, lineno, ctx, IFLA_ADDRESS, addr, addrlen)) {
+ tst_netlink_destroy_context(file, lineno, ctx);
+ return 0;
+ }
+
+ ret = tst_netlink_send_validate(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
+
+ if (strict && !ret) {
+ tst_brk_(file, lineno, TBROK,
+ "Failed to set hwaddr for %s: %s", ifname,
+ tst_strerrno(tst_netlink_errno));
+ }
+
+ return ret;
+}
+
+int tst_netdev_set_master(const char *file, const int lineno, int strict,
+ const char *ifname, const char *master_ifname)
+{
+ struct ifinfomsg info = { .ifi_family = AF_UNSPEC };
+ struct tst_netlink_context *ctx;
+ int32_t master_index = 0;
+ int ret;
+
+ if (strlen(ifname) >= IFNAMSIZ) {
+ tst_brk_(file, lineno, TBROK,
+ "Network device name \"%s\" too long", ifname);
+ return 0;
+ }
+
+ if (master_ifname) {
+ master_index = tst_netdev_index_by_name(file, lineno,
+ master_ifname);
+
+ if (master_index < 0)
+ return 0;
+ }
+
+ ctx = create_request(file, lineno, RTM_NEWLINK, 0, &info, sizeof(info));
+
+ if (!ctx)
+ return 0;
+
+ if (!tst_rtnl_add_attr_string(file, lineno, ctx, IFLA_IFNAME, ifname)) {
+ tst_netlink_destroy_context(file, lineno, ctx);
+ return 0;
+ }
+
+ if (!tst_rtnl_add_attr(file, lineno, ctx, IFLA_MASTER, &master_index,
+ sizeof(master_index))) {
+ tst_netlink_destroy_context(file, lineno, ctx);
+ return 0;
+ }
+
+ ret = tst_netlink_send_validate(file, lineno, ctx);
+ tst_netlink_destroy_context(file, lineno, ctx);
+
+ if (strict && !ret) {
+ tst_brk_(file, lineno, TBROK,
+ "Failed to set master for %s: %s", ifname,
+ tst_strerrno(tst_netlink_errno));
+ }
+
+ return ret;
+}
+
int tst_netdev_add_address(const char *file, const int lineno, int strict,
const char *ifname, unsigned int family, const void *address,
unsigned int prefix, size_t addrlen, unsigned int flags)
--
2.51.0
More information about the ltp
mailing list