From 60bad3a41e9d66bb46f6cd76bff2e8e718519652 Mon Sep 17 00:00:00 2001 From: Wen Liang Date: Sat, 14 Aug 2021 15:13:18 -0400 Subject: [PATCH] platform: obtain `l_perm_address` via netlink or lookup via ethtool Add and call the new `nm_platform_link_get_permanent_address()` to obtain `l_perm_address` via netlink or lookup via ethtool if kernel does not expose the `IFLA_PERM_ADDRESS`. And call the new `nm_platform_link_get_permanent_address()` in the unit tests. https://bugzilla.redhat.com/show_bug.cgi?id=1987286 Signed-off-by: Wen Liang --- src/core/devices/nm-device.c | 6 +++--- src/core/platform/tests/test-link.c | 16 ++++++++++++++++ src/libnm-platform/nm-platform.c | 17 +++++++++++++++++ src/libnm-platform/nm-platform.h | 3 +++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 4ee5dc9a28..0a2cf101d1 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -17132,9 +17132,9 @@ nm_device_update_permanent_hw_address(NMDevice *self, gboolean force_freeze) return; } - success_read = nm_platform_link_get_permanent_address_ethtool(nm_device_get_platform(self), - ifindex, - &cached_hw_addr_perm); + success_read = nm_platform_link_get_permanent_address(nm_device_get_platform(self), + pllink, + &cached_hw_addr_perm); if (success_read && priv->hw_addr_len == cached_hw_addr_perm.len) { priv->hw_addr_perm_fake = FALSE; priv->hw_addr_perm = diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c index f6c3841ed8..69e4846d6f 100644 --- a/src/core/platform/tests/test-link.c +++ b/src/core/platform/tests/test-link.c @@ -580,6 +580,7 @@ test_bridge_addr(void) char addr[ETH_ALEN]; NMPlatformLink link; const NMPlatformLink *plink = NULL; + NMPLinkAddress hw_perm_addr; nm_utils_hwaddr_aton("de:ad:be:ef:00:11", addr, sizeof(addr)); @@ -599,6 +600,7 @@ test_bridge_addr(void) plink = nm_platform_link_get(NM_PLATFORM_GET, link.ifindex); g_assert(plink); + g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, plink, &hw_perm_addr)); if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) { g_assert(!nm_platform_link_get_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex)); @@ -611,6 +613,7 @@ test_bridge_addr(void) g_assert(nm_platform_link_get_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex)); plink = nm_platform_link_get(NM_PLATFORM_GET, link.ifindex); g_assert(plink); + g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, plink, &hw_perm_addr)); g_assert_cmpint(_nm_platform_uint8_inv(plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_NONE); @@ -620,6 +623,7 @@ test_bridge_addr(void) g_assert(!nm_platform_link_get_user_ipv6ll_enabled(NM_PLATFORM_GET, link.ifindex)); plink = nm_platform_link_get(NM_PLATFORM_GET, link.ifindex); g_assert(plink); + g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, plink, &hw_perm_addr)); g_assert_cmpint(_nm_platform_uint8_inv(plink->inet6_addr_gen_mode_inv), ==, NM_IN6_ADDR_GEN_MODE_EUI64); @@ -730,6 +734,7 @@ static void test_external(void) { const NMPlatformLink *pllink; + NMPLinkAddress hw_perm_addr; SignalData * link_added, *link_changed, *link_removed; int ifindex; @@ -758,6 +763,7 @@ test_external(void) pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex); g_assert(pllink); + g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, pllink, &hw_perm_addr)); if (!pllink->initialized) { /* we still lack the notification via UDEV. Expect another link changed signal. */ wait_signal(link_changed); @@ -2522,6 +2528,7 @@ test_nl_bugs_veth(void) const NMPlatformLink *pllink_veth0, *pllink_veth1; gs_free_error GError * error = NULL; NMTstpNamespaceHandle *ns_handle = NULL; + NMPLinkAddress hw_perm_addr; /* create veth pair. */ ifindex_veth0 = nmtstp_link_veth_add(NM_PLATFORM_GET, -1, IFACE_VETH0, IFACE_VETH1)->ifindex; @@ -2538,6 +2545,7 @@ test_nl_bugs_veth(void) /* assert that NMPlatformLink.parent is the peer-ifindex. */ pllink_veth0 = nm_platform_link_get(NM_PLATFORM_GET, ifindex_veth0); g_assert(pllink_veth0); + g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, pllink_veth0, &hw_perm_addr)); if (pllink_veth0->parent == 0) { /* Kernels prior to 4.1 dated 21 June, 2015 don't support exposing the veth peer * as IFA_LINK. skip the remainder of the test. */ @@ -2549,6 +2557,7 @@ test_nl_bugs_veth(void) * https://bugzilla.redhat.com/show_bug.cgi?id=1285827 in place. */ pllink_veth1 = nm_platform_link_get(NM_PLATFORM_GET, ifindex_veth1); g_assert(pllink_veth1); + g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, pllink_veth1, &hw_perm_addr)); g_assert_cmpint(pllink_veth1->parent, ==, ifindex_veth0); /* move one veth peer to another namespace and check that the @@ -2588,6 +2597,7 @@ test_nl_bugs_spuroius_newlink(void) const char * IFACE_DUMMY0 = "nm-test-dummy0"; int ifindex_bond0, ifindex_dummy0; const NMPlatformLink *pllink; + NMPLinkAddress hw_perm_addr; gboolean wait_for_settle; /* see https://bugzilla.redhat.com/show_bug.cgi?id=1285719 */ @@ -2609,6 +2619,7 @@ test_nl_bugs_spuroius_newlink(void) pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex_dummy0); g_assert(pllink); + g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, pllink, &hw_perm_addr)); if (pllink->master == ifindex_bond0) break; }); @@ -2621,6 +2632,7 @@ again: nm_platform_process_events(NM_PLATFORM_GET); pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex_bond0); g_assert(!pllink); + g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, pllink, &hw_perm_addr)); if (wait_for_settle) { wait_for_settle = FALSE; @@ -2641,6 +2653,7 @@ test_nl_bugs_spuroius_dellink(void) const char * IFACE_DUMMY0 = "nm-test-dummy0"; int ifindex_bridge0, ifindex_dummy0; const NMPlatformLink *pllink; + NMPLinkAddress hw_perm_addr; gboolean wait_for_settle; /* see https://bugzilla.redhat.com/show_bug.cgi?id=1285719 */ @@ -2663,6 +2676,7 @@ test_nl_bugs_spuroius_dellink(void) pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex_dummy0); g_assert(pllink); + g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, pllink, &hw_perm_addr)); if (pllink->master == ifindex_bridge0) break; }); @@ -2677,8 +2691,10 @@ again: nm_platform_process_events(NM_PLATFORM_GET); pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex_bridge0); g_assert(pllink); + g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, pllink, &hw_perm_addr)); pllink = nm_platform_link_get(NM_PLATFORM_GET, ifindex_dummy0); g_assert(pllink); + g_assert(!nm_platform_link_get_permanent_address(NM_PLATFORM_GET, pllink, &hw_perm_addr)); g_assert_cmpint(pllink->parent, ==, 0); if (wait_for_settle) { diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index af93533efc..0e0dc348b7 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -1765,6 +1765,23 @@ nm_platform_link_get_permanent_address_ethtool(NMPlatform * self, return FALSE; } +gboolean +nm_platform_link_get_permanent_address(NMPlatform * self, + const NMPlatformLink *plink, + NMPLinkAddress * out_address) +{ + _CHECK_SELF(self, klass, FALSE); + nm_assert(out_address); + + if (!plink) + return FALSE; + if (plink->l_perm_address.len > 0) { + *out_address = plink->l_perm_address; + return TRUE; + } + return nm_platform_link_get_permanent_address_ethtool(self, plink->ifindex, out_address); +} + gboolean nm_platform_link_supports_carrier_detect(NMPlatform *self, int ifindex) { diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index 170d8ae37d..8965700082 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -1866,6 +1866,9 @@ gboolean nm_platform_link_set_ipv6_token(NMPlatform *self, int ifindex, NMUtilsI gboolean nm_platform_link_get_permanent_address_ethtool(NMPlatform * self, int ifindex, NMPLinkAddress *out_address); +gboolean nm_platform_link_get_permanent_address(NMPlatform * self, + const NMPlatformLink *plink, + NMPLinkAddress * out_address); int nm_platform_link_set_address(NMPlatform *self, int ifindex, const void *address, size_t length); int nm_platform_link_set_mtu(NMPlatform *self, int ifindex, guint32 mtu); gboolean nm_platform_link_set_name(NMPlatform *self, int ifindex, const char *name);