From a67eb9d8d00b9c69f52879e5edf087932bf4d07d Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 6 Oct 2016 21:28:40 +0200 Subject: [PATCH 01/13] logging: remove LOGD_HW alias for LOGD_PLATFORM Since commit 1495853e01299d1eb33d4eb10b91e37dcf855cc8, LOGD_HW is renamed to LOGD_PLATFORM. Remove the internal usage of the deprecated name. Backport this patch to nm-1-4 because it avoids follow-up conflicts with future backports. Also, it is a really trivial change, meaning, we only replace the obsolte LOGD_HW name. (cherry picked from commit 64951f07fb39e1c88448ba2ad72a5e710712c89d) Conflicts: src/devices/nm-device.c src/devices/wwan/nm-modem.c --- src/devices/adsl/nm-atm-manager.c | 14 +++++------ src/devices/nm-device-bond.c | 2 +- src/devices/nm-device-ethernet.c | 14 +++++------ src/devices/nm-device-factory.c | 18 +++++++-------- src/devices/nm-device-ip-tunnel.c | 8 +++---- src/devices/nm-device-macvlan.c | 2 +- src/devices/nm-device-tun.c | 2 +- src/devices/nm-device-veth.c | 2 +- src/devices/nm-device-vxlan.c | 2 +- src/devices/nm-device.c | 30 ++++++++++++------------ src/devices/wifi/nm-device-wifi.c | 2 +- src/devices/wifi/nm-wifi-factory.c | 2 +- src/devices/wwan/nm-modem.c | 4 ++-- src/nm-logging.h | 1 - src/nm-manager.c | 6 ++--- src/nm-rfkill-manager.c | 2 +- src/platform/wifi/wifi-utils-nl80211.c | 16 ++++++------- src/platform/wifi/wifi-utils-wext.c | 32 +++++++++++++------------- 18 files changed, 79 insertions(+), 80 deletions(-) diff --git a/src/devices/adsl/nm-atm-manager.c b/src/devices/adsl/nm-atm-manager.c index 6708575215..40c782fd00 100644 --- a/src/devices/adsl/nm-atm-manager.c +++ b/src/devices/adsl/nm-atm-manager.c @@ -68,7 +68,7 @@ dev_get_attrs (GUdevDevice *udev_device, path = g_udev_device_get_sysfs_path (udev_device); if (!path) { - nm_log_warn (LOGD_HW, "couldn't determine device path; ignoring..."); + nm_log_warn (LOGD_PLATFORM, "couldn't determine device path; ignoring..."); return FALSE; } @@ -110,11 +110,11 @@ adsl_add (NMAtmManager *self, GUdevDevice *udev_device) ifname = g_udev_device_get_name (udev_device); if (!ifname) { - nm_log_warn (LOGD_HW, "failed to get device's interface name"); + nm_log_warn (LOGD_PLATFORM, "failed to get device's interface name"); return; } - nm_log_dbg (LOGD_HW, "(%s): found ATM device", ifname); + nm_log_dbg (LOGD_PLATFORM, "(%s): found ATM device", ifname); atm_index_path = g_strdup_printf ("/sys/class/atm/%s/atmindex", NM_ASSERT_VALID_PATH_COMPONENT (ifname)); @@ -123,12 +123,12 @@ adsl_add (NMAtmManager *self, GUdevDevice *udev_device) 10, 0, G_MAXINT, -1); if (atm_index < 0) { - nm_log_warn (LOGD_HW, "(%s): failed to get ATM index", ifname); + nm_log_warn (LOGD_PLATFORM, "(%s): failed to get ATM index", ifname); return; } if (!dev_get_attrs (udev_device, &sysfs_path, &driver)) { - nm_log_warn (LOGD_HW, "(%s): failed to get ATM attributes", ifname); + nm_log_warn (LOGD_PLATFORM, "(%s): failed to get ATM attributes", ifname); return; } @@ -153,7 +153,7 @@ adsl_remove (NMAtmManager *self, GUdevDevice *udev_device) const char *iface = g_udev_device_get_name (udev_device); GSList *iter; - nm_log_dbg (LOGD_HW, "(%s): removing ATM device", iface); + nm_log_dbg (LOGD_PLATFORM, "(%s): removing ATM device", iface); for (iter = priv->devices; iter; iter = iter->next) { NMDevice *device = iter->data; @@ -210,7 +210,7 @@ handle_uevent (GUdevClient *client, ifindex = g_udev_device_get_property (device, "IFINDEX"); seqnum = g_udev_device_get_seqnum (device); - nm_log_dbg (LOGD_HW, "UDEV event: action '%s' subsys '%s' device '%s' (%s); seqnum=%" G_GUINT64_FORMAT, + nm_log_dbg (LOGD_PLATFORM, "UDEV event: action '%s' subsys '%s' device '%s' (%s); seqnum=%" G_GUINT64_FORMAT, action, subsys, g_udev_device_get_name (device), ifindex ? ifindex : "unknown", seqnum); if (!strcmp (action, "add")) diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 3f17849b0a..75b2e31532 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -129,7 +129,7 @@ set_bond_attr (NMDevice *device, NMBondMode mode, const char *attr, const char * ret = nm_platform_sysctl_master_set_option (NM_PLATFORM_GET, ifindex, attr, value); if (!ret) - _LOGW (LOGD_HW, "failed to set bonding attribute '%s' to '%s'", attr, value); + _LOGW (LOGD_PLATFORM, "failed to set bonding attribute '%s' to '%s'", attr, value); return ret; } diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index aef464e778..d2e15725f4 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -188,7 +188,7 @@ _update_s390_subchannels (NMDeviceEthernet *self) parent_path = g_udev_device_get_sysfs_path (parent); dir = g_dir_open (parent_path, 0, &error); if (!dir) { - _LOGW (LOGD_DEVICE | LOGD_HW, "update-s390: failed to open directory '%s': %s", + _LOGW (LOGD_DEVICE | LOGD_PLATFORM, "update-s390: failed to open directory '%s': %s", parent_path, error->message); g_clear_error (&error); return; @@ -218,11 +218,11 @@ _update_s390_subchannels (NMDeviceEthernet *self) g_hash_table_insert (priv->s390_options, g_strdup (item), value); value = NULL; } else - _LOGW (LOGD_DEVICE | LOGD_HW, "update-s390: error reading %s", path); + _LOGW (LOGD_DEVICE | LOGD_PLATFORM, "update-s390: error reading %s", path); } if (error) { - _LOGW (LOGD_DEVICE | LOGD_HW, "update-s390: failed reading sysfs for %s (%s)", item, error->message); + _LOGW (LOGD_DEVICE | LOGD_PLATFORM, "update-s390: failed reading sysfs for %s (%s)", item, error->message); g_clear_error (&error); } } @@ -247,7 +247,7 @@ _update_s390_subchannels (NMDeviceEthernet *self) priv->subchannels_dbus[2] = g_strdup (priv->subchan3); priv->subchannels_dbus[3] = NULL; - _LOGI (LOGD_DEVICE | LOGD_HW, "update-s390: found s390 '%s' subchannels [%s]", + _LOGI (LOGD_DEVICE | LOGD_PLATFORM, "update-s390: found s390 '%s' subchannels [%s]", nm_device_get_driver ((NMDevice *) self) ?: "(unknown driver)", priv->subchannels); @@ -311,7 +311,7 @@ get_generic_capabilities (NMDevice *device) if (nm_platform_link_supports_carrier_detect (NM_PLATFORM_GET, nm_device_get_ifindex (device))) return NM_DEVICE_CAP_CARRIER_DETECT; else { - _LOGI (LOGD_HW, "driver '%s' does not support carrier detection.", + _LOGI (LOGD_PLATFORM, "driver '%s' does not support carrier detection.", nm_device_get_driver (device)); return NM_DEVICE_CAP_NONE; } @@ -1324,7 +1324,7 @@ deactivate (NMDevice *device) s_dcb = (NMSettingDcb *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_DCB); if (s_dcb) { if (!nm_dcb_cleanup (nm_device_get_iface (device), &error)) { - _LOGW (LOGD_DEVICE | LOGD_HW, "failed to disable DCB/FCoE: %s", + _LOGW (LOGD_DEVICE | LOGD_PLATFORM, "failed to disable DCB/FCoE: %s", error->message); g_clear_error (&error); } @@ -1529,7 +1529,7 @@ get_link_speed (NMDevice *device) priv->speed = speed; _notify (self, PROP_SPEED); - _LOGD (LOGD_HW | LOGD_ETHER, "speed is now %d Mb/s", speed); + _LOGD (LOGD_PLATFORM | LOGD_ETHER, "speed is now %d Mb/s", speed); } static void diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index 7873756f9e..a72c0bbb5e 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -369,7 +369,7 @@ read_device_factory_paths (void) dir = g_dir_open (NMPLUGINDIR, 0, &error); if (!dir) { - nm_log_warn (LOGD_HW, "device plugin: failed to open directory %s: %s", + nm_log_warn (LOGD_PLATFORM, "device plugin: failed to open directory %s: %s", NMPLUGINDIR, error->message); g_clear_error (&error); @@ -391,17 +391,17 @@ read_device_factory_paths (void) if (stat (data.path, &data.st) != 0) { errsv = errno; - nm_log_warn (LOGD_HW, "device plugin: skip invalid file %s (error during stat: %s)", data.path, strerror (errsv)); + nm_log_warn (LOGD_PLATFORM, "device plugin: skip invalid file %s (error during stat: %s)", data.path, strerror (errsv)); goto NEXT; } if (!S_ISREG (data.st.st_mode)) goto NEXT; if (data.st.st_uid != 0) { - nm_log_warn (LOGD_HW, "device plugin: skip invalid file %s (file must be owned by root)", data.path); + nm_log_warn (LOGD_PLATFORM, "device plugin: skip invalid file %s (file must be owned by root)", data.path); goto NEXT; } if (data.st.st_mode & (S_IWGRP | S_IWOTH | S_ISUID)) { - nm_log_warn (LOGD_HW, "device plugin: skip invalid file %s (invalid file permissions)", data.path); + nm_log_warn (LOGD_PLATFORM, "device plugin: skip invalid file %s (invalid file permissions)", data.path); goto NEXT; } @@ -443,7 +443,7 @@ _add_factory (NMDeviceFactory *factory, if (check_duplicates) { found = find_factory (link_types, setting_types); if (found) { - nm_log_warn (LOGD_HW, "Loading device plugin failed: multiple plugins " + nm_log_warn (LOGD_PLATFORM, "Loading device plugin failed: multiple plugins " "for same type (using '%s' instead of '%s')", (char *) g_object_get_data (G_OBJECT (found), PLUGIN_PATH_TAG), path); @@ -459,7 +459,7 @@ _add_factory (NMDeviceFactory *factory, callback (factory, user_data); - nm_log_info (LOGD_HW, "Loaded device plugin: %s (%s)", G_OBJECT_TYPE_NAME (factory), path); + nm_log_info (LOGD_PLATFORM, "Loaded device plugin: %s (%s)", G_OBJECT_TYPE_NAME (factory), path); return TRUE; } @@ -502,12 +502,12 @@ nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc call plugin = g_module_open (*path, G_MODULE_BIND_LOCAL); if (!plugin) { - nm_log_warn (LOGD_HW, "(%s): failed to load plugin: %s", item, g_module_error ()); + nm_log_warn (LOGD_PLATFORM, "(%s): failed to load plugin: %s", item, g_module_error ()); continue; } if (!g_module_symbol (plugin, "nm_device_factory_create", (gpointer) &create_func)) { - nm_log_warn (LOGD_HW, "(%s): failed to find device factory creator: %s", item, g_module_error ()); + nm_log_warn (LOGD_PLATFORM, "(%s): failed to find device factory creator: %s", item, g_module_error ()); g_module_close (plugin); continue; } @@ -518,7 +518,7 @@ nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc call factory = create_func (&error); if (!factory) { - nm_log_warn (LOGD_HW, "(%s): failed to initialize device factory: %s", + nm_log_warn (LOGD_PLATFORM, "(%s): failed to initialize device factory: %s", item, NM_G_ERROR_MSG (error)); g_clear_error (&error); continue; diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index 785010ebfa..72a13893dd 100644 --- a/src/devices/nm-device-ip-tunnel.c +++ b/src/devices/nm-device-ip-tunnel.c @@ -160,7 +160,7 @@ clear: lnk = nm_platform_link_get_lnk_gre (NM_PLATFORM_GET, ifindex, NULL); if (!lnk) { - _LOGW (LOGD_HW, "could not read %s properties", "gre"); + _LOGW (LOGD_PLATFORM, "could not read %s properties", "gre"); goto clear; } @@ -205,7 +205,7 @@ clear: lnk = nm_platform_link_get_lnk_sit (NM_PLATFORM_GET, ifindex, NULL); if (!lnk) { - _LOGW (LOGD_HW, "could not read %s properties", "sit"); + _LOGW (LOGD_PLATFORM, "could not read %s properties", "sit"); goto clear; } @@ -220,7 +220,7 @@ clear: lnk = nm_platform_link_get_lnk_ipip (NM_PLATFORM_GET, ifindex, NULL); if (!lnk) { - _LOGW (LOGD_HW, "could not read %s properties", "ipip"); + _LOGW (LOGD_PLATFORM, "could not read %s properties", "ipip"); goto clear; } @@ -236,7 +236,7 @@ clear: lnk = nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, ifindex, NULL); if (!lnk) { - _LOGW (LOGD_HW, "could not read %s properties", "ip6tnl"); + _LOGW (LOGD_PLATFORM, "could not read %s properties", "ip6tnl"); goto clear; } diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index 2bfc65cb2d..0a43646dde 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -180,7 +180,7 @@ update_properties (NMDevice *device) props = nm_platform_link_get_lnk_macvlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), &plink); if (!props) { - _LOGW (LOGD_HW, "could not get %s properties", priv->props.tap ? "macvtap" : "macvlan"); + _LOGW (LOGD_PLATFORM, "could not get %s properties", priv->props.tap ? "macvtap" : "macvlan"); return; } diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c index 1f42d06015..f818cd7c3a 100644 --- a/src/devices/nm-device-tun.c +++ b/src/devices/nm-device-tun.c @@ -171,7 +171,7 @@ update_connection (NMDevice *device, NMConnection *connection) } if (!nm_platform_link_tun_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (device), &props)) { - _LOGW (LOGD_HW, "failed to get TUN interface info while updating connection."); + _LOGW (LOGD_PLATFORM, "failed to get TUN interface info while updating connection."); return; } diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c index 56923315c6..c16df6d88b 100644 --- a/src/devices/nm-device-veth.c +++ b/src/devices/nm-device-veth.c @@ -91,7 +91,7 @@ get_peer (NMDeviceVeth *self) return priv->peer; if (!nm_platform_link_veth_get_properties (NM_PLATFORM_GET, nm_device_get_ifindex (device), &peer_ifindex)) { - _LOGW (LOGD_HW, "could not read veth properties"); + _LOGW (LOGD_PLATFORM, "could not read veth properties"); return NULL; } diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c index 674c2a787d..2453543d2a 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -84,7 +84,7 @@ update_properties (NMDevice *device) props = nm_platform_link_get_lnk_vxlan (NM_PLATFORM_GET, nm_device_get_ifindex (device), NULL); if (!props) { - _LOGW (LOGD_HW, "could not get vxlan properties"); + _LOGW (LOGD_PLATFORM, "could not get vxlan properties"); return; } diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 8a11d72681..940a670f4c 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -756,7 +756,7 @@ nm_device_set_ip_iface (NMDevice *self, const char *iface) nm_platform_link_set_up (NM_PLATFORM_GET, priv->ip_ifindex, NULL); } else { /* Device IP interface must always be a kernel network interface */ - _LOGW (LOGD_HW, "failed to look up interface index"); + _LOGW (LOGD_PLATFORM, "failed to look up interface index"); } } @@ -899,7 +899,7 @@ get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid) priv->dev_id, out_iid); if (!success) { - _LOGW (LOGD_HW, "failed to generate interface identifier " + _LOGW (LOGD_PLATFORM, "failed to generate interface identifier " "for link type %u hwaddr_len %u", pllink->type, (unsigned) pllink->addr.len); } return success; @@ -2298,7 +2298,7 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink) if (nm_device_has_capability (self, NM_DEVICE_CAP_CARRIER_DETECT)) { check_carrier (self); - _LOGD (LOGD_HW, + _LOGD (LOGD_PLATFORM, "carrier is %s%s", priv->carrier ? "ON" : "OFF", priv->ignore_carrier ? " (but ignored)" : ""); @@ -9033,7 +9033,7 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - _LOGD (LOGD_HW, "bringing up device"); + _LOGD (LOGD_PLATFORM, "bringing up device"); if (NM_DEVICE_GET_CLASS (self)->bring_up) { if (!NM_DEVICE_GET_CLASS (self)->bring_up (self, no_firmware)) @@ -9059,9 +9059,9 @@ nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware) if (!device_is_up) { if (block) - _LOGW (LOGD_HW, "device not up after timeout!"); + _LOGW (LOGD_PLATFORM, "device not up after timeout!"); else - _LOGD (LOGD_HW, "device not up immediately"); + _LOGD (LOGD_PLATFORM, "device not up immediately"); return FALSE; } @@ -9125,7 +9125,7 @@ nm_device_take_down (NMDevice *self, gboolean block) g_return_if_fail (NM_IS_DEVICE (self)); - _LOGD (LOGD_HW, "taking down device"); + _LOGD (LOGD_PLATFORM, "taking down device"); if (NM_DEVICE_GET_CLASS (self)->take_down) { if (!NM_DEVICE_GET_CLASS (self)->take_down (self)) @@ -9147,9 +9147,9 @@ nm_device_take_down (NMDevice *self, gboolean block) if (device_is_up) { if (block) - _LOGW (LOGD_HW, "device not down after timeout!"); + _LOGW (LOGD_PLATFORM, "device not down after timeout!"); else - _LOGD (LOGD_HW, "device not down immediately"); + _LOGD (LOGD_PLATFORM, "device not down immediately"); } } @@ -9162,7 +9162,7 @@ take_down (NMDevice *self) return nm_platform_link_set_down (NM_PLATFORM_GET, ifindex); /* devices without ifindex are always up. */ - _LOGD (LOGD_HW, "cannot take down device without ifindex"); + _LOGD (LOGD_PLATFORM, "cannot take down device without ifindex"); return FALSE; } @@ -11150,7 +11150,7 @@ _set_state_full (NMDevice *self, if (reason != NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED) { if (old_state == NM_DEVICE_STATE_UNMANAGED || priv->firmware_missing) { if (!nm_device_bring_up (self, TRUE, &no_firmware) && no_firmware) - _LOGW (LOGD_HW, "firmware may be missing."); + _LOGW (LOGD_PLATFORM, "firmware may be missing."); nm_device_set_firmware_missing (self, no_firmware ? TRUE : FALSE); } @@ -11533,7 +11533,7 @@ nm_device_update_hw_address (NMDevice *self) g_free (priv->hw_addr); priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen); - _LOGD (LOGD_HW | LOGD_DEVICE, "hw-addr: hardware address now %s", priv->hw_addr); + _LOGD (LOGD_PLATFORM | LOGD_DEVICE, "hw-addr: hardware address now %s", priv->hw_addr); _notify (self, PROP_HW_ADDRESS); if ( !priv->hw_addr_initial @@ -11550,11 +11550,11 @@ nm_device_update_hw_address (NMDevice *self) } else { /* Invalid or no hardware address */ if (priv->hw_addr_len != 0) { - _LOGD (LOGD_HW | LOGD_DEVICE, + _LOGD (LOGD_PLATFORM | LOGD_DEVICE, "hw-addr: failed reading current MAC address (stay with %s)", priv->hw_addr); } else { - _LOGD (LOGD_HW | LOGD_DEVICE, + _LOGD (LOGD_PLATFORM | LOGD_DEVICE, "hw-addr: failed reading current MAC address"); } } @@ -11614,7 +11614,7 @@ nm_device_update_permanent_hw_address (NMDevice *self) * * In some cases it might be necessary to know whether this is a "real" or * a temporary address (fake). */ - _LOGD (LOGD_HW | LOGD_ETHER, "hw-addr: %s (use current: %s)", + _LOGD (LOGD_PLATFORM | LOGD_ETHER, "hw-addr: %s (use current: %s)", success_read ? "read HW addr length of permanent MAC address differs" : "unable to read permanent MAC address", diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index f97e668935..f467c8141c 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -203,7 +203,7 @@ constructed (GObject *object) G_OBJECT_CLASS (nm_device_wifi_parent_class)->constructed (object); if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP) - _LOGI (LOGD_HW | LOGD_WIFI, "driver supports Access Point (AP) mode"); + _LOGI (LOGD_PLATFORM | LOGD_WIFI, "driver supports Access Point (AP) mode"); /* Connect to the supplicant manager */ priv->sup_mgr = g_object_ref (nm_supplicant_manager_get ()); diff --git a/src/devices/wifi/nm-wifi-factory.c b/src/devices/wifi/nm-wifi-factory.c index 2d5f8faf00..cf8cf03bdc 100644 --- a/src/devices/wifi/nm-wifi-factory.c +++ b/src/devices/wifi/nm-wifi-factory.c @@ -76,7 +76,7 @@ create_device (NMDeviceFactory *factory, if (!nm_platform_wifi_get_capabilities (NM_PLATFORM_GET, plink->ifindex, &capabilities)) { - nm_log_warn (LOGD_HW | LOGD_WIFI, "(%s) failed to initialize Wi-Fi driver for ifindex %d", iface, plink->ifindex); + nm_log_warn (LOGD_PLATFORM | LOGD_WIFI, "(%s) failed to initialize Wi-Fi driver for ifindex %d", iface, plink->ifindex); return NULL; } diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index 9d562be1e5..bf3aa3b281 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -1355,12 +1355,12 @@ constructor (GType type, priv = NM_MODEM_GET_PRIVATE (object); if (!priv->data_port && !priv->control_port) { - nm_log_err (LOGD_HW, "neither modem command nor data interface provided"); + nm_log_err (LOGD_PLATFORM, "neither modem command nor data interface provided"); goto err; } if (!priv->path) { - nm_log_err (LOGD_HW, "D-Bus path not provided"); + nm_log_err (LOGD_PLATFORM, "D-Bus path not provided"); goto err; } diff --git a/src/nm-logging.h b/src/nm-logging.h index 9e2b0108ef..72eb3db401 100644 --- a/src/nm-logging.h +++ b/src/nm-logging.h @@ -78,7 +78,6 @@ typedef enum { /*< skip >*/ /* aliases: */ LOGD_DHCP = LOGD_DHCP4 | LOGD_DHCP6, LOGD_IP = LOGD_IP4 | LOGD_IP6, - LOGD_HW = LOGD_PLATFORM, } NMLogDomain; /* Log levels */ diff --git a/src/nm-manager.c b/src/nm-manager.c index 836ab76857..a585fb5780 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2127,10 +2127,10 @@ platform_link_added (NMManager *self, device = nm_device_factory_create_device (factory, plink->name, plink, NULL, &ignore, &error); if (!device) { if (!ignore) { - _LOGW (LOGD_HW, "%s: factory failed to create device: %s", + _LOGW (LOGD_PLATFORM, "%s: factory failed to create device: %s", plink->name, error->message); } else { - _LOGD (LOGD_HW, "%s: factory failed to create device: %s", + _LOGD (LOGD_PLATFORM, "%s: factory failed to create device: %s", plink->name, error->message); } return; @@ -2144,7 +2144,7 @@ platform_link_added (NMManager *self, case NM_LINK_TYPE_OLPC_MESH: case NM_LINK_TYPE_TEAM: case NM_LINK_TYPE_WIFI: - _LOGI (LOGD_HW, "(%s): '%s' plugin not available; creating generic device", + _LOGI (LOGD_PLATFORM, "(%s): '%s' plugin not available; creating generic device", plink->name, nm_link_type_to_string (plink->type)); nm_plugin_missing = TRUE; /* fall through */ diff --git a/src/nm-rfkill-manager.c b/src/nm-rfkill-manager.c index 453a3b9bbb..e4e738c92e 100644 --- a/src/nm-rfkill-manager.c +++ b/src/nm-rfkill-manager.c @@ -347,7 +347,7 @@ handle_uevent (GUdevClient *client, subsys = g_udev_device_get_subsystem (device); g_return_if_fail (!g_strcmp0 (subsys, "rfkill")); - nm_log_dbg (LOGD_HW, "udev rfkill event: action '%s' device '%s'", + nm_log_dbg (LOGD_PLATFORM, "udev rfkill event: action '%s' device '%s'", action, g_udev_device_get_name (device)); if (!strcmp (action, "add")) diff --git a/src/platform/wifi/wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c index 79f217a8d5..2e222eb801 100644 --- a/src/platform/wifi/wifi-utils-nl80211.c +++ b/src/platform/wifi/wifi-utils-nl80211.c @@ -1003,7 +1003,7 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) case WLAN_CIPHER_SUITE_SMS4: break; default: - nm_log_dbg (LOGD_HW | LOGD_WIFI, "Don't know the meaning of NL80211_ATTR_CIPHER_SUITE %#8.8x.", ciphers[i]); + nm_log_dbg (LOGD_PLATFORM | LOGD_WIFI, "Don't know the meaning of NL80211_ATTR_CIPHER_SUITE %#8.8x.", ciphers[i]); break; } } @@ -1071,42 +1071,42 @@ wifi_nl80211_init (const char *iface, int ifindex) if (nl80211_send_and_recv (nl80211, msg, nl80211_wiphy_info_handler, &device_info) < 0) { - nm_log_dbg (LOGD_HW | LOGD_WIFI, + nm_log_dbg (LOGD_PLATFORM | LOGD_WIFI, "(%s): NL80211_CMD_GET_WIPHY request failed", nl80211->parent.iface); goto error; } if (!device_info.success) { - nm_log_dbg (LOGD_HW | LOGD_WIFI, + nm_log_dbg (LOGD_PLATFORM | LOGD_WIFI, "(%s): NL80211_CMD_GET_WIPHY request indicated failure", nl80211->parent.iface); goto error; } if (!device_info.supported) { - nm_log_dbg (LOGD_HW | LOGD_WIFI, + nm_log_dbg (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver does not fully support nl80211, falling back to WEXT", nl80211->parent.iface); goto error; } if (!device_info.can_scan_ssid) { - nm_log_err (LOGD_HW | LOGD_WIFI, + nm_log_err (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver does not support SSID scans", nl80211->parent.iface); goto error; } if (device_info.num_freqs == 0 || device_info.freqs == NULL) { - nm_log_err (LOGD_HW | LOGD_WIFI, + nm_log_err (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver reports no supported frequencies", nl80211->parent.iface); goto error; } if (device_info.caps == 0) { - nm_log_err (LOGD_HW | LOGD_WIFI, + nm_log_err (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver doesn't report support of any encryption", nl80211->parent.iface); goto error; @@ -1120,7 +1120,7 @@ wifi_nl80211_init (const char *iface, int ifindex) if (device_info.can_wowlan) nl80211->parent.get_wowlan = wifi_nl80211_get_wowlan; - nm_log_info (LOGD_HW | LOGD_WIFI, + nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): using nl80211 for WiFi device control", nl80211->parent.iface); diff --git a/src/platform/wifi/wifi-utils-wext.c b/src/platform/wifi/wifi-utils-wext.c index af285b45c3..66c13764f7 100644 --- a/src/platform/wifi/wifi-utils-wext.c +++ b/src/platform/wifi/wifi-utils-wext.c @@ -105,7 +105,7 @@ wifi_wext_get_mode (WifiData *data) if (ioctl (wext->fd, SIOCGIWMODE, &wrq) < 0) { if (errno != ENODEV) { - nm_log_warn (LOGD_HW | LOGD_WIFI, + nm_log_warn (LOGD_PLATFORM | LOGD_WIFI, "(%s): error %d getting card mode", wext->parent.iface, errno); } @@ -154,7 +154,7 @@ wifi_wext_set_mode (WifiData *data, const NM80211Mode mode) nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface); if (ioctl (wext->fd, SIOCSIWMODE, &wrq) < 0) { if (errno != ENODEV) { - nm_log_err (LOGD_HW | LOGD_WIFI, "(%s): error setting mode %d", + nm_log_err (LOGD_PLATFORM | LOGD_WIFI, "(%s): error setting mode %d", wext->parent.iface, mode); } return FALSE; @@ -178,7 +178,7 @@ wifi_wext_set_powersave (WifiData *data, guint32 powersave) nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface); if (ioctl (wext->fd, SIOCSIWPOWER, &wrq) < 0) { if (errno != ENODEV) { - nm_log_err (LOGD_HW | LOGD_WIFI, "(%s): error setting powersave %" G_GUINT32_FORMAT, + nm_log_err (LOGD_PLATFORM | LOGD_WIFI, "(%s): error setting powersave %" G_GUINT32_FORMAT, wext->parent.iface, powersave); } return FALSE; @@ -196,7 +196,7 @@ wifi_wext_get_freq (WifiData *data) memset (&wrq, 0, sizeof (struct iwreq)); nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface); if (ioctl (wext->fd, SIOCGIWFREQ, &wrq) < 0) { - nm_log_warn (LOGD_HW | LOGD_WIFI, + nm_log_warn (LOGD_PLATFORM | LOGD_WIFI, "(%s): error getting frequency: %s", wext->parent.iface, strerror (errno)); return 0; @@ -230,7 +230,7 @@ wifi_wext_get_bssid (WifiData *data, guint8 *out_bssid) memset (&wrq, 0, sizeof (wrq)); nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface); if (ioctl (wext->fd, SIOCGIWAP, &wrq) < 0) { - nm_log_warn (LOGD_HW | LOGD_WIFI, + nm_log_warn (LOGD_PLATFORM | LOGD_WIFI, "(%s): error getting associated BSSID: %s", wext->parent.iface, strerror (errno)); return FALSE; @@ -360,7 +360,7 @@ wifi_wext_get_qual (WifiData *data) nm_utils_ifname_cpy (wrq.ifr_name, wext->parent.iface); if (ioctl (wext->fd, SIOCGIWSTATS, &wrq) < 0) { - nm_log_warn (LOGD_HW | LOGD_WIFI, + nm_log_warn (LOGD_PLATFORM | LOGD_WIFI, "(%s): error getting signal strength: %s", wext->parent.iface, strerror (errno)); return -1; @@ -403,7 +403,7 @@ wifi_wext_set_mesh_channel (WifiData *data, guint32 channel) } if (ioctl (wext->fd, SIOCSIWFREQ, &wrq) < 0) { - nm_log_err (LOGD_HW | LOGD_WIFI | LOGD_OLPC, + nm_log_err (LOGD_PLATFORM | LOGD_WIFI | LOGD_OLPC, "(%s): error setting channel to %d: %s", wext->parent.iface, channel, strerror (errno)); return FALSE; @@ -431,7 +431,7 @@ wifi_wext_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len) return TRUE; if (errno != ENODEV) { - nm_log_err (LOGD_HW | LOGD_WIFI | LOGD_OLPC, + nm_log_err (LOGD_PLATFORM | LOGD_WIFI | LOGD_OLPC, "(%s): error setting SSID to '%s': %s", wext->parent.iface, ssid ? nm_utils_escape_ssid (ssid, len) : "(null)", @@ -482,7 +482,7 @@ wext_get_range (WifiDataWext *wext, success = TRUE; break; } else if (errno != EAGAIN) { - nm_log_err (LOGD_HW | LOGD_WIFI, + nm_log_err (LOGD_PLATFORM | LOGD_WIFI, "(%s): couldn't get driver range information (%d).", wext->parent.iface, errno); break; @@ -492,7 +492,7 @@ wext_get_range (WifiDataWext *wext, } if (i <= 0) { - nm_log_warn (LOGD_HW | LOGD_WIFI, + nm_log_warn (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver took too long to respond to IWRANGE query.", wext->parent.iface); } @@ -583,13 +583,13 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan) memset (&range, 0, sizeof (struct iw_range)); if (wext_get_range (wext, &range, &response_len) == FALSE) { - nm_log_info (LOGD_HW | LOGD_WIFI, "(%s): driver WEXT range request failed", + nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver WEXT range request failed", wext->parent.iface); goto error; } if ((response_len < 300) || (range.we_version_compiled < 21)) { - nm_log_info (LOGD_HW | LOGD_WIFI, + nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver WEXT version too old (got %d, expected >= 21)", wext->parent.iface, range.we_version_compiled); @@ -613,7 +613,7 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan) /* Check for scanning capability; cards that can't scan are not supported */ if (check_scan && (wext_can_scan (wext) == FALSE)) { - nm_log_info (LOGD_HW | LOGD_WIFI, + nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): drivers that cannot scan are unsupported", wext->parent.iface); goto error; @@ -625,12 +625,12 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan) */ scan_capa_range = (struct iw_range_with_scan_capa *) ⦥ if (scan_capa_range->scan_capa & NM_IW_SCAN_CAPA_ESSID) { - nm_log_info (LOGD_HW | LOGD_WIFI, + nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver supports SSID scans (scan_capa 0x%02X).", wext->parent.iface, scan_capa_range->scan_capa); } else { - nm_log_info (LOGD_HW | LOGD_WIFI, + nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver does not support SSID scans (scan_capa 0x%02X).", wext->parent.iface, scan_capa_range->scan_capa); @@ -644,7 +644,7 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan) if (has_5ghz) wext->parent.caps |= NM_WIFI_DEVICE_CAP_FREQ_5GHZ; - nm_log_info (LOGD_HW | LOGD_WIFI, + nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): using WEXT for WiFi device control", wext->parent.iface); From 7927d451fc7b6cfbd9cd3bf1078fa3cb4140789a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 15 Oct 2016 15:22:01 +0200 Subject: [PATCH 02/13] tools: fix starting tests with D-Bus session with NMTST_NO_VALGRIND=1 When running NMTST_NO_VALGRIND=1 make check -j we would not start separate D-Bus sessions, thus running tests with valgrind enabled failed. (cherry picked from commit c94dac0b5d9d77ef7d60d18eb835a0dd7bba4f42) --- tools/run-test-valgrind.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/run-test-valgrind.sh b/tools/run-test-valgrind.sh index d3dd915bf0..634ca2c4e6 100755 --- a/tools/run-test-valgrind.sh +++ b/tools/run-test-valgrind.sh @@ -91,6 +91,7 @@ if [ "$NMTST_LAUNCH_DBUS" == "yes" ]; then fi if [ "$NMTST_NO_VALGRIND" != "" ]; then + "${NMTST_DBUS_RUN_SESSION[@]}" \ "$TEST" "$@" exit $? fi From beeb676735d6242dd4c12de27bbc1b8fd3afaeee Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 28 Sep 2016 15:34:52 +0200 Subject: [PATCH 03/13] shared: add nm_clear_g_free() (cherry picked from commit b4e66c4818cf6ff14e8b5181ec9d71fa5c9f5452) --- libnm-core/tests/test-general.c | 2 +- shared/nm-utils/nm-macros-internal.h | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libnm-core/tests/test-general.c b/libnm-core/tests/test-general.c index f7945071f1..6631c89684 100644 --- a/libnm-core/tests/test-general.c +++ b/libnm-core/tests/test-general.c @@ -2527,7 +2527,7 @@ test_setting_compare_wireless_cloned_mac_address (void) g_assert_cmpstr ("stable-bia", ==, nm_setting_wireless_get_cloned_mac_address ((NMSettingWireless *) new)); g_object_get (new, NM_SETTING_WIRELESS_CLONED_MAC_ADDRESS, &str1, NULL); g_assert_cmpstr ("stable-bia", ==, str1); - g_clear_pointer (&str1, g_free); + nm_clear_g_free (&str1); success = nm_setting_compare (old, new, NM_SETTING_COMPARE_FLAG_EXACT); g_assert (!success); diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index e30a50a5ce..fd23a68a30 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -366,6 +366,27 @@ nm_g_object_unref (gpointer obj) g_object_unref (obj); } +/* basically, replaces + * g_clear_pointer (&location, g_free) + * with + * nm_clear_g_free (&location) + * + * Another advantage is that by using a macro and typeof(), it is more + * typesafe and gives you for example a compiler warning when pp is a const + * pointer or points to a const-pointer. + */ +#define nm_clear_g_free(pp) \ + ({ \ + typeof (*(pp)) *_pp = (pp); \ + typeof (**_pp) *_p = *_pp; \ + \ + if (_p) { \ + *_pp = NULL; \ + g_free (_p); \ + } \ + !!_p; \ + }) + static inline gboolean nm_clear_g_source (guint *id) { From d242fdc3193948cce078a55adec540f3489ee94a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 26 Oct 2016 14:44:02 +0200 Subject: [PATCH 04/13] shared: add nm_assert_se() macro We usually don't build NM with g_assert() disabled (G_DISABLE_ASSERT). But even if we would, there is no assertion macro that always evaluates the condition for possible side effects. I think that is a useful thing to have. (cherry picked from commit ba950cedee5c4a92d9fb7e00f58b9f97a151b9e8) --- shared/nm-utils/nm-macros-internal.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index fd23a68a30..b6b6bdee42 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -300,9 +300,11 @@ nm_strdup_not_empty (const char *str) #if NM_MORE_ASSERTS #define nm_assert(cond) G_STMT_START { g_assert (cond); } G_STMT_END +#define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } else { g_assert (FALSE && (cond)); } } G_STMT_END #define nm_assert_not_reached() G_STMT_START { g_assert_not_reached (); } G_STMT_END #else #define nm_assert(cond) G_STMT_START { if (FALSE) { if (cond) { } } } G_STMT_END +#define nm_assert_se(cond) G_STMT_START { if (G_LIKELY (cond)) { ; } } G_STMT_END #define nm_assert_not_reached() G_STMT_START { ; } G_STMT_END #endif From 977fbf70895f3a9dce3e178b5e4c03ecf4ee8fa3 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 13 Oct 2016 17:51:07 +0200 Subject: [PATCH 05/13] libnm-core/utils: update hwaddr utilities _nm_utils_hwaddr_length() did a validation of the string and returned the length of the address. In all cases where we were interested in that, we also either want to validate the address, get the address in binary form, or canonicalize the address. We can avoid these duplicate checks, by using _nm_utils_hwaddr_aton() which both does the parsing and returning the length. (cherry picked from commit e5fe5a4c033875679adbea3cae50108daef43eb3) --- libnm-core/nm-core-internal.h | 5 +- libnm-core/nm-utils.c | 309 +++++++++++++++++++--------------- src/devices/nm-device.c | 46 ++--- src/nm-core-utils.c | 7 +- 4 files changed, 206 insertions(+), 161 deletions(-) diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index e491bce6da..5d3c190a05 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -123,7 +123,10 @@ guint32 _nm_setting_get_setting_priority (NMSetting *setting); gboolean _nm_setting_get_property (NMSetting *setting, const char *name, GValue *value); -guint _nm_utils_hwaddr_length (const char *asc); +#define NM_UTILS_HWADDR_LEN_MAX_STR (NM_UTILS_HWADDR_LEN_MAX * 3) + +guint8 *_nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gsize *out_length); +const char *nm_utils_hwaddr_ntoa_buf (gconstpointer addr, gsize addr_len, gboolean upper_case, char *buf, gsize buf_len); char *_nm_utils_bin2str (gconstpointer addr, gsize length, gboolean upper_case); diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index df75d56557..fe8a371452 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -2965,17 +2965,64 @@ nm_utils_wifi_strength_bars (guint8 strength) gsize nm_utils_hwaddr_len (int type) { - g_return_val_if_fail (type == ARPHRD_ETHER || type == ARPHRD_INFINIBAND, 0); - if (type == ARPHRD_ETHER) return ETH_ALEN; else if (type == ARPHRD_INFINIBAND) return INFINIBAND_ALEN; - g_assert_not_reached (); + g_return_val_if_reached (0); } -#define HEXVAL(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10) +static guint8 * +hwaddr_aton (const char *asc, guint8 *buffer, gsize buffer_length, gsize *out_len) +{ + const char *in = asc; + guint8 *out = buffer; + guint8 delimiter = '\0'; + + nm_assert (asc); + nm_assert (buffer); + nm_assert (buffer_length); + nm_assert (out_len); + + while (TRUE) { + const guint8 d1 = in[0]; + guint8 d2; + + if (!g_ascii_isxdigit (d1)) + return NULL; + +#define HEXVAL(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - ('A' - 10)) + + /* If there's no leading zero (ie "aa:b:cc") then fake it */ + d2 = in[1]; + if (d2 && g_ascii_isxdigit (d2)) { + *out++ = (HEXVAL (d1) << 4) + HEXVAL (d2); + d2 = in[2]; + in += 3; + } else { + /* Fake leading zero */ + *out++ = HEXVAL (d1); + in += 2; + } + + if (!d2) + break; + if (--buffer_length == 0) + return NULL; + + if (d2 != delimiter) { + if ( delimiter == '\0' + && (d2 == ':' || d2 == '-')) + delimiter = d2; + else + return NULL; + } + } + + *out_len = out - buffer; + return buffer; +} /** * nm_utils_hwaddr_atoba: @@ -2992,18 +3039,52 @@ GByteArray * nm_utils_hwaddr_atoba (const char *asc, gsize length) { GByteArray *ba; + gsize l; - g_return_val_if_fail (asc != NULL, NULL); + g_return_val_if_fail (asc, NULL); g_return_val_if_fail (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX, NULL); ba = g_byte_array_sized_new (length); g_byte_array_set_size (ba, length); - if (!nm_utils_hwaddr_aton (asc, ba->data, length)) { - g_byte_array_unref (ba); - return NULL; - } + if (!hwaddr_aton (asc, ba->data, length, &l)) + goto fail; + if (length != l) + goto fail; return ba; +fail: + g_byte_array_unref (ba); + return NULL; +} + +/** + * _nm_utils_hwaddr_aton: + * @asc: the ASCII representation of a hardware address + * @buffer: buffer to store the result into. Must have + * at least a size of @buffer_length. + * @buffer_length: the length of the input buffer @buffer. + * The result must fit into that buffer, otherwise + * the function fails and returns %NULL. + * @out_length: the output length in case of success. + * + * Parses @asc and converts it to binary form in @buffer. + * Bytes in @asc can be sepatared by colons (:), or hyphens (-), but not mixed. + * + * It is like nm_utils_hwaddr_aton(), but contrary to that it + * can parse addresses of any length. That is, you don't need + * to know the length before-hand. + * + * Return value: @buffer, or %NULL if @asc couldn't be parsed. + */ +guint8 * +_nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize buffer_length, gsize *out_length) +{ + g_return_val_if_fail (asc, NULL); + g_return_val_if_fail (buffer, NULL); + g_return_val_if_fail (buffer_length > 0, NULL); + g_return_val_if_fail (out_length, NULL); + + return hwaddr_aton (asc, buffer, buffer_length, out_length); } /** @@ -3022,72 +3103,55 @@ nm_utils_hwaddr_atoba (const char *asc, gsize length) guint8 * nm_utils_hwaddr_aton (const char *asc, gpointer buffer, gsize length) { - const char *in = asc; - guint8 *out = (guint8 *)buffer; - char delimiter = '\0'; + gsize l; - g_return_val_if_fail (asc != NULL, NULL); - g_return_val_if_fail (buffer != NULL, NULL); + g_return_val_if_fail (asc, NULL); + g_return_val_if_fail (buffer, NULL); g_return_val_if_fail (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX, NULL); - while (length && *in) { - guint8 d1 = in[0], d2 = in[1]; + if (!hwaddr_aton (asc, buffer, length, &l)) + return NULL; + if (length != l) + return NULL; + return buffer; +} - if (!g_ascii_isxdigit (d1)) - return NULL; +static void +_bin2str_buf (gconstpointer addr, gsize length, gboolean upper_case, char *out) +{ + const guint8 *in = addr; + const char *LOOKUP = upper_case ? "0123456789ABCDEF" : "0123456789abcdef"; - /* If there's no leading zero (ie "aa:b:cc") then fake it */ - if (d2 && g_ascii_isxdigit (d2)) { - *out++ = (HEXVAL (d1) << 4) + HEXVAL (d2); - in += 2; - } else { - /* Fake leading zero */ - *out++ = (HEXVAL ('0') << 4) + HEXVAL (d1); - in += 1; - } + nm_assert (addr); + nm_assert (out); + nm_assert (length > 0); + /* @out must contain at least @length*3 bytes */ + + for (;;) { + const guint8 v = *in++; + + *out++ = LOOKUP[v >> 4]; + *out++ = LOOKUP[v & 0x0F]; length--; - if (*in) { - if (delimiter == '\0') { - if (*in == ':' || *in == '-') - delimiter = *in; - else - return NULL; - } else { - if (*in != delimiter) - return NULL; - } - in++; - } + if (!length) + break; + *out++ = ':'; } - if (length == 0 && !*in) - return buffer; - else - return NULL; + *out = 0; } static char * _bin2str (gconstpointer addr, gsize length, gboolean upper_case) { - const guint8 *in = addr; - char *out, *result; - const char *LOOKUP = upper_case ? "0123456789ABCDEF" : "0123456789abcdef"; + char *result; - g_return_val_if_fail (addr != NULL, g_strdup ("")); - g_return_val_if_fail (length > 0, g_strdup ("")); + nm_assert (addr); + nm_assert (length > 0); - result = out = g_malloc (length * 3); - while (length--) { - guint8 v = *in++; - - *out++ = LOOKUP[v >> 4]; - *out++ = LOOKUP[v & 0x0F]; - if (length) - *out++ = ':'; - } - - *out = 0; + result = g_malloc (length * 3); + _bin2str_buf (addr, length, upper_case, result); return result; } @@ -3103,9 +3167,25 @@ _bin2str (gconstpointer addr, gsize length, gboolean upper_case) char * nm_utils_hwaddr_ntoa (gconstpointer addr, gsize length) { + g_return_val_if_fail (addr, g_strdup ("")); + g_return_val_if_fail (length > 0, g_strdup ("")); + return _bin2str (addr, length, TRUE); } +const char * +nm_utils_hwaddr_ntoa_buf (gconstpointer addr, gsize addr_len, gboolean upper_case, char *buf, gsize buf_len) +{ + g_return_val_if_fail (addr, NULL); + g_return_val_if_fail (addr_len > 0, NULL); + g_return_val_if_fail (buf, NULL); + if (buf_len < addr_len * 3) + g_return_val_if_reached (NULL); + + _bin2str_buf (addr, addr_len, TRUE, buf); + return buf; +} + /** * _nm_utils_bin2str: * @addr: (type guint8) (array length=length): a binary hardware address @@ -3119,51 +3199,12 @@ nm_utils_hwaddr_ntoa (gconstpointer addr, gsize length) char * _nm_utils_bin2str (gconstpointer addr, gsize length, gboolean upper_case) { + g_return_val_if_fail (addr, g_strdup ("")); + g_return_val_if_fail (length > 0, g_strdup ("")); + return _bin2str (addr, length, upper_case); } -static int -hwaddr_binary_len (const char *asc) -{ - int octets = 1; - - if (!*asc) - return 0; - - for (; *asc; asc++) { - if (*asc == ':' || *asc == '-') - octets++; - } - return octets; -} - -/** - * _nm_utils_hwaddr_length: - * @asc: the ASCII representation of the hardware address - * - * Validates that @asc is a valid representation of a hardware - * address up to (including) %NM_UTILS_HWADDR_LEN_MAX bytes. - * - * Returns: binary length of the hardware address @asc or - * 0 on error. - */ -guint -_nm_utils_hwaddr_length (const char *asc) -{ - int l; - - if (!asc) - return 0; - - l = hwaddr_binary_len (asc); - if (l <= 0 || l > NM_UTILS_HWADDR_LEN_MAX) - return 0; - - if (!nm_utils_hwaddr_valid (asc, l)) - return 0; - return l; -} - /** * nm_utils_hwaddr_valid: * @asc: the ASCII representation of a hardware address @@ -3180,17 +3221,18 @@ gboolean nm_utils_hwaddr_valid (const char *asc, gssize length) { guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + gsize l; g_return_val_if_fail (asc != NULL, FALSE); - g_return_val_if_fail (length == -1 || (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX), FALSE); - if (length == -1) { - length = hwaddr_binary_len (asc); - if (length == 0 || length > NM_UTILS_HWADDR_LEN_MAX) + if (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX) { + if (!hwaddr_aton (asc, buf, length, &l)) return FALSE; - } - - return nm_utils_hwaddr_aton (asc, buf, length) != NULL; + return length == l; + } else if (length == -1) { + return !!hwaddr_aton (asc, buf, sizeof (buf), &l); + } else + g_return_val_if_reached (FALSE); } /** @@ -3210,20 +3252,23 @@ char * nm_utils_hwaddr_canonical (const char *asc, gssize length) { guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + gsize l; - g_return_val_if_fail (asc != NULL, NULL); + g_return_val_if_fail (asc, NULL); g_return_val_if_fail (length == -1 || (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX), NULL); - if (length == -1) { - length = hwaddr_binary_len (asc); - if (length == 0 || length > NM_UTILS_HWADDR_LEN_MAX) + if (length > 0 && length <= NM_UTILS_HWADDR_LEN_MAX) { + if (!hwaddr_aton (asc, buf, length, &l)) return NULL; - } + if (l != length) + return NULL; + } else if (length == -1) { + if (!hwaddr_aton (asc, buf, NM_UTILS_HWADDR_LEN_MAX, &l)) + return NULL; + } else + g_return_val_if_reached (NULL); - if (nm_utils_hwaddr_aton (asc, buf, length) == NULL) - return NULL; - - return nm_utils_hwaddr_ntoa (buf, length); + return nm_utils_hwaddr_ntoa (buf, l); } /* This is used to possibly canonicalize values passed to MAC address property @@ -3287,17 +3332,17 @@ nm_utils_hwaddr_matches (gconstpointer hwaddr1, gssize hwaddr2_len) { guint8 buf1[NM_UTILS_HWADDR_LEN_MAX], buf2[NM_UTILS_HWADDR_LEN_MAX]; + gsize l; if (hwaddr1_len == -1) { g_return_val_if_fail (hwaddr1 != NULL, FALSE); - hwaddr1_len = hwaddr_binary_len (hwaddr1); - if (hwaddr1_len == 0 || hwaddr1_len > NM_UTILS_HWADDR_LEN_MAX) + if (!hwaddr_aton (hwaddr1, buf1, sizeof (buf1), &l)) { + g_return_val_if_fail ((hwaddr2_len == -1 && hwaddr2) || (hwaddr2_len > 0 && hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX), FALSE); return FALSE; - if (!nm_utils_hwaddr_aton (hwaddr1, buf1, hwaddr1_len)) - return FALSE; - + } hwaddr1 = buf1; + hwaddr1_len = l; } else { g_return_val_if_fail (hwaddr1_len > 0 && hwaddr1_len <= NM_UTILS_HWADDR_LEN_MAX, FALSE); @@ -3310,23 +3355,24 @@ nm_utils_hwaddr_matches (gconstpointer hwaddr1, if (hwaddr2_len == -1) { g_return_val_if_fail (hwaddr2 != NULL, FALSE); - if (!nm_utils_hwaddr_aton (hwaddr2, buf2, hwaddr1_len)) + if (!hwaddr_aton (hwaddr2, buf2, sizeof (buf2), &l)) + return FALSE; + if (l != hwaddr1_len) return FALSE; - hwaddr2 = buf2; hwaddr2_len = hwaddr1_len; } else { g_return_val_if_fail (hwaddr2_len > 0 && hwaddr2_len <= NM_UTILS_HWADDR_LEN_MAX, FALSE); + if (hwaddr2_len != hwaddr1_len) + return FALSE; + if (!hwaddr2) { memset (buf2, 0, hwaddr2_len); hwaddr2 = buf2; } } - if (hwaddr1_len != hwaddr2_len) - return FALSE; - if (hwaddr1_len == INFINIBAND_ALEN) { hwaddr1 = (guint8 *)hwaddr1 + INFINIBAND_ALEN - 8; hwaddr2 = (guint8 *)hwaddr2 + INFINIBAND_ALEN - 8; @@ -3342,16 +3388,11 @@ static GVariant * _nm_utils_hwaddr_to_dbus_impl (const char *str) { guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; - int len; + gsize len; if (!str) return NULL; - - len = _nm_utils_hwaddr_length (str); - if (len == 0) - return NULL; - - if (!nm_utils_hwaddr_aton (str, buf, len)) + if (!hwaddr_aton (str, buf, sizeof (buf), &len)) return NULL; return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, buf, len, 1); diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 940a670f4c..1935f4568c 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -11718,25 +11718,25 @@ nm_device_hw_addr_is_explict (NMDevice *self) } static gboolean -_hw_addr_matches (NMDevice *self, const char *addr) +_hw_addr_matches (NMDevice *self, const guint8 *addr, gsize addr_len) { const char *cur_addr; cur_addr = nm_device_get_hw_address (self); - return cur_addr && nm_utils_hwaddr_matches (cur_addr, -1, addr, -1); + return cur_addr && nm_utils_hwaddr_matches (addr, addr_len, cur_addr, -1); } static gboolean _hw_addr_set (NMDevice *self, - const char *addr, - const char *operation, - const char *detail) + const char *const addr, + const char *const operation, + const char *const detail) { NMDevicePrivate *priv; gboolean success = FALSE; NMPlatformError plerr; guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX]; - guint hw_addr_len; + gsize addr_len; gboolean was_up; nm_assert (NM_IS_DEVICE (self)); @@ -11745,18 +11745,20 @@ _hw_addr_set (NMDevice *self, priv = NM_DEVICE_GET_PRIVATE (self); + if (!_nm_utils_hwaddr_aton (addr, addr_bytes, sizeof (addr_bytes), &addr_len)) + g_return_val_if_reached (FALSE); + /* Do nothing if current MAC is same */ - if (_hw_addr_matches (self, addr)) { + if (_hw_addr_matches (self, addr_bytes, addr_len)) { _LOGT (LOGD_DEVICE, "set-hw-addr: no MAC address change needed (%s)", addr); return TRUE; } - hw_addr_len = priv->hw_addr_len; - if (!hw_addr_len) - hw_addr_len = _nm_utils_hwaddr_length (addr); - if ( !hw_addr_len - || !nm_utils_hwaddr_aton (addr, addr_bytes, hw_addr_len)) - g_return_val_if_reached (FALSE); + if (priv->hw_addr_len != addr_len) { + if (priv->hw_addr_len) + g_return_val_if_reached (FALSE); + priv->hw_addr_len = addr_len; + } _LOGT (LOGD_DEVICE, "set-hw-addr: setting MAC address to '%s' (%s, %s)...", addr, operation, detail); @@ -11766,12 +11768,12 @@ _hw_addr_set (NMDevice *self, nm_device_take_down (self, FALSE); } - plerr = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, hw_addr_len); + plerr = nm_platform_link_set_address (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), addr_bytes, addr_len); success = (plerr == NM_PLATFORM_ERROR_SUCCESS); if (success) { /* MAC address succesfully changed; update the current MAC to match */ nm_device_update_hw_address (self); - if (_hw_addr_matches (self, addr)) { + if (_hw_addr_matches (self, addr_bytes, addr_len)) { _LOGI (LOGD_DEVICE, "set-hw-addr: %s MAC address to %s (%s)", operation, addr, detail); } else { @@ -11801,7 +11803,7 @@ _hw_addr_set (NMDevice *self, goto handle_fail; if (!nm_device_update_hw_address (self)) goto handle_wait; - if (!_hw_addr_matches (self, addr)) + if (!_hw_addr_matches (self, addr_bytes, addr_len)) goto handle_fail; break; @@ -11928,9 +11930,8 @@ nm_device_hw_addr_set_cloned (NMDevice *self, NMConnection *connection, gboolean addr = hw_addr_generated; } else { /* this must be a valid address. Otherwise, we shouldn't come here. */ - if (_nm_utils_hwaddr_length (addr) <= 0) { + if (!nm_utils_hwaddr_valid (addr, -1)) g_return_val_if_reached (FALSE); - } priv->hw_addr_type = HW_ADDR_TYPE_EXPLICIT; } @@ -12127,13 +12128,16 @@ constructor (GType type, } if (priv->hw_addr_perm) { - priv->hw_addr_len = _nm_utils_hwaddr_length (priv->hw_addr_perm); - if (!priv->hw_addr_len) { + guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + gsize l; + + if (!_nm_utils_hwaddr_aton (priv->hw_addr_perm, buf, sizeof (buf), &l)) { g_clear_pointer (&priv->hw_addr_perm, g_free); g_return_val_if_reached (object); } - priv->hw_addr = g_strdup (priv->hw_addr_perm); + priv->hw_addr_len = l; + priv->hw_addr = nm_utils_hwaddr_ntoa (buf, l); _LOGT (LOGD_DEVICE, "hw-addr: has permanent hw-address '%s'", priv->hw_addr_perm); } diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 6dfbb4ce10..6988a12436 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -1272,7 +1272,7 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr) { const GSList *iter; NMMatchSpecMatchType match = NM_MATCH_SPEC_NO_MATCH; - guint hwaddr_len = 0; + gsize hwaddr_len = 0; guint8 hwaddr_bin[NM_UTILS_HWADDR_LEN_MAX]; nm_assert (nm_utils_hwaddr_valid (hwaddr, -1)); @@ -1297,11 +1297,8 @@ nm_match_spec_hwaddr (const GSList *specs, const char *hwaddr) continue; if (G_UNLIKELY (hwaddr_len == 0)) { - hwaddr_len = _nm_utils_hwaddr_length (hwaddr); - if (!hwaddr_len) + if (!_nm_utils_hwaddr_aton (hwaddr, hwaddr_bin, sizeof (hwaddr_bin), &hwaddr_len)) g_return_val_if_reached (NM_MATCH_SPEC_NO_MATCH); - if (!nm_utils_hwaddr_aton (hwaddr, hwaddr_bin, hwaddr_len)) - nm_assert_not_reached (); } if (nm_utils_hwaddr_matches (spec_str, -1, hwaddr_bin, hwaddr_len)) { From b071c91eef15d6dbbf365d2db5aaca1b4eadcce0 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 13 Oct 2016 15:56:13 +0200 Subject: [PATCH 06/13] core: add nm_device_get_permanent_hw_address_full() function This is a partial cherry-pick from commit 5912b2f9a170893002b789fe37a7784eefac4e34. --- src/devices/nm-device.c | 32 ++++++++++++++++++++++++-------- src/devices/nm-device.h | 2 ++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 1935f4568c..db617c0be6 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -11609,8 +11609,10 @@ nm_device_update_permanent_hw_address (NMDevice *self) success_read = nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len); if (!success_read || len != priv->hw_addr_len) { - /* Fall back to current address. We use the fake address and keep it - * until the device unrealizes. + priv->hw_addr_perm_fake = TRUE; + + /* we failed to read a permanent MAC address, thus we use a fake address, + * that is the current MAC address of the device. * * In some cases it might be necessary to know whether this is a "real" or * a temporary address (fake). */ @@ -11619,14 +11621,16 @@ nm_device_update_permanent_hw_address (NMDevice *self) ? "read HW addr length of permanent MAC address differs" : "unable to read permanent MAC address", priv->hw_addr); - priv->hw_addr_perm_fake = TRUE; priv->hw_addr_perm = g_strdup (priv->hw_addr); - } else { - priv->hw_addr_perm_fake = FALSE; - priv->hw_addr_perm = nm_utils_hwaddr_ntoa (buf, len); - _LOGD (LOGD_DEVICE, "hw-addr: read permanent MAC address '%s'", - priv->hw_addr_perm); + goto out; } + + priv->hw_addr_perm_fake = FALSE; + priv->hw_addr_perm = nm_utils_hwaddr_ntoa (buf, len); + _LOGD (LOGD_DEVICE, "hw-addr: read permanent MAC address '%s'", + priv->hw_addr_perm); + +out: _notify (self, PROP_PERM_HW_ADDRESS); } @@ -11962,6 +11966,18 @@ nm_device_hw_addr_reset (NMDevice *self, const char *detail) return _hw_addr_set (self, addr, "reset", detail); } +const char * +nm_device_get_permanent_hw_address_full (NMDevice *self, gboolean *out_is_fake) +{ + NMDevicePrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + + priv = NM_DEVICE_GET_PRIVATE (self); + NM_SET_OUT (out_is_fake, priv->hw_addr_perm && priv->hw_addr_perm_fake); + return priv->hw_addr_perm; +} + const char * nm_device_get_permanent_hw_address (NMDevice *self, gboolean fallback_fake) { diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index a757a37eb9..010c9b9f0d 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -366,6 +366,8 @@ guint32 nm_device_get_ip6_route_metric (NMDevice *dev); const char * nm_device_get_hw_address (NMDevice *dev); const char * nm_device_get_permanent_hw_address (NMDevice *dev, gboolean fallback_fake); +const char * nm_device_get_permanent_hw_address_full (NMDevice *self, + gboolean *out_is_fake); const char * nm_device_get_initial_hw_address (NMDevice *dev); NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *dev); From bb5ee41dc440709c3f2e0a3e498ab70fde4cea1a Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 11 Oct 2016 07:47:25 +0000 Subject: [PATCH 07/13] config: allow fallback to fake permanent address for default wired connections The default wired connection is already generated allowing the use of a fake address, but for the state file and the device matching specs only non-fake addresses are used. Let's allow fake addresses consistently, so that default wired connections work properly in containers (where the veth address is considered fake) as well. Also, it would really be a better idea to use ifnames everywhere instead, but that would change the format of the state file. (cherry picked from commit bcb685c4cb2b126f4a8593083fed043aed74ed17) --- src/devices/nm-device.c | 2 +- src/nm-config.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index db617c0be6..ff253dd45c 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -12048,7 +12048,7 @@ spec_match_list (NMDevice *self, const GSList *specs) } } - hw_addr_perm = nm_device_get_permanent_hw_address (self, FALSE); + hw_addr_perm = nm_device_get_permanent_hw_address (self, TRUE); if (hw_addr_perm) { m = nm_match_spec_hwaddr (specs, hw_addr_perm); matched = MAX (matched, m); diff --git a/src/nm-config.c b/src/nm-config.c index 4bc4f48340..3823e34b3d 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -399,7 +399,7 @@ nm_config_set_no_auto_default_for_device (NMConfig *self, NMDevice *device) priv = NM_CONFIG_GET_PRIVATE (self); - hw_address = nm_device_get_permanent_hw_address (device, FALSE); + hw_address = nm_device_get_permanent_hw_address (device, TRUE); if (!hw_address) return; From 7bb7b17408de2a1001c3ed77e06d2b23c1125b72 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 13 Oct 2016 18:52:12 +0200 Subject: [PATCH 08/13] device: treat fake permanent MAC address mostly like a real one Now that we persist the fake permanent address across restart of NetworkManager, we want to consider fake addresses as good enough in most cases. (cherry picked from commit 416164aa29c45d8071c8767fed866e06ee0e9169) --- src/devices/nm-device-ethernet.c | 15 +++++++++------ src/devices/nm-device-infiniband.c | 6 +++--- src/devices/nm-device-macvlan.c | 2 +- src/devices/nm-device-vlan.c | 2 +- src/devices/nm-device.c | 25 +++++++++++-------------- src/devices/nm-device.h | 3 +-- src/devices/wifi/nm-device-wifi.c | 4 ++-- src/nm-config.c | 2 +- src/nm-manager.c | 2 +- src/settings/nm-settings.c | 2 +- 10 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index d2e15725f4..5e980ed9c5 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -396,7 +396,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) if (!match_subchans (self, s_wired, &try_mac)) return FALSE; - perm_hw_addr = nm_device_get_permanent_hw_address (device, TRUE); + perm_hw_addr = nm_device_get_permanent_hw_address (device); mac = nm_setting_wired_get_mac_address (s_wired); if (perm_hw_addr) { if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) @@ -1346,6 +1346,7 @@ complete_connection (NMDevice *device, NMSettingPppoe *s_pppoe; const char *setting_mac; const char *perm_hw_addr; + gboolean perm_hw_addr_is_fake; s_pppoe = nm_connection_get_setting_pppoe (connection); @@ -1373,8 +1374,8 @@ complete_connection (NMDevice *device, nm_connection_add_setting (connection, NM_SETTING (s_wired)); } - perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE); - if (perm_hw_addr) { + perm_hw_addr = nm_device_get_permanent_hw_address_full (device, &perm_hw_addr_is_fake); + if (perm_hw_addr && !perm_hw_addr_is_fake) { setting_mac = nm_setting_wired_get_mac_address (s_wired); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ @@ -1410,7 +1411,7 @@ new_default_connection (NMDevice *self) if (nm_config_get_no_auto_default_for_device (nm_config_get (), self)) return NULL; - perm_hw_addr = nm_device_get_permanent_hw_address (self, TRUE); + perm_hw_addr = nm_device_get_permanent_hw_address (self); if (!perm_hw_addr) return NULL; @@ -1470,7 +1471,8 @@ update_connection (NMDevice *device, NMConnection *connection) { NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE ((NMDeviceEthernet *) device); NMSettingWired *s_wired = nm_connection_get_setting_wired (connection); - const char *perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE); + gboolean perm_hw_addr_is_fake; + const char *perm_hw_addr; const char *mac = nm_device_get_hw_address (device); const char *mac_prop = NM_SETTING_WIRED_MAC_ADDRESS; GHashTableIter iter; @@ -1489,7 +1491,8 @@ update_connection (NMDevice *device, NMConnection *connection) /* If the device reports a permanent address, use that for the MAC address * and the current MAC, if different, is the cloned MAC. */ - if (perm_hw_addr) { + perm_hw_addr = nm_device_get_permanent_hw_address_full (device, &perm_hw_addr_is_fake); + if (perm_hw_addr && !perm_hw_addr_is_fake) { g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, perm_hw_addr, NULL); mac_prop = NULL; diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 17f50ba2c7..e2a67de4e9 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -151,7 +151,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) mac = nm_setting_infiniband_get_mac_address (s_infiniband); if (mac) { - hw_addr = nm_device_get_permanent_hw_address (device, TRUE); + hw_addr = nm_device_get_permanent_hw_address (device); if ( !hw_addr || !nm_utils_hwaddr_matches (mac, -1, hw_addr, -1)) return FALSE; @@ -188,7 +188,7 @@ complete_connection (NMDevice *device, } setting_mac = nm_setting_infiniband_get_mac_address (s_infiniband); - hw_address = nm_device_get_permanent_hw_address (device, TRUE); + hw_address = nm_device_get_permanent_hw_address (device); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's MAC */ if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) { @@ -214,7 +214,7 @@ static void update_connection (NMDevice *device, NMConnection *connection) { NMSettingInfiniband *s_infiniband = nm_connection_get_setting_infiniband (connection); - const char *mac = nm_device_get_permanent_hw_address (device, TRUE); + const char *mac = nm_device_get_permanent_hw_address (device); const char *transport_mode = "datagram"; int ifindex; diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index 0a43646dde..c53abb68c9 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -373,7 +373,7 @@ match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hw if (!priv->parent) return !fail_if_no_hwaddr; - parent_mac = nm_device_get_permanent_hw_address (priv->parent, FALSE); + parent_mac = nm_device_get_permanent_hw_address (priv->parent); return parent_mac && nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1); } diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index 16edc0d2ba..461bae6692 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -391,7 +391,7 @@ match_hwaddr (NMDevice *device, NMConnection *connection, gboolean fail_if_no_hw if (!priv->parent) return !fail_if_no_hwaddr; - parent_mac = nm_device_get_permanent_hw_address (priv->parent, FALSE); + parent_mac = nm_device_get_permanent_hw_address (priv->parent); return parent_mac && nm_utils_hwaddr_matches (setting_mac, -1, parent_mac, -1); } diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index ff253dd45c..b9f1de01a4 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -11890,7 +11890,7 @@ nm_device_hw_addr_set_cloned (NMDevice *self, NMConnection *connection, gboolean } if (nm_streq (addr, NM_CLONED_MAC_PERMANENT)) { - addr = nm_device_get_permanent_hw_address (self, TRUE); + addr = nm_device_get_permanent_hw_address (self); if (!addr) return FALSE; priv->hw_addr_type = HW_ADDR_TYPE_PERMANENT; @@ -11979,19 +11979,11 @@ nm_device_get_permanent_hw_address_full (NMDevice *self, gboolean *out_is_fake) } const char * -nm_device_get_permanent_hw_address (NMDevice *self, gboolean fallback_fake) +nm_device_get_permanent_hw_address (NMDevice *self) { - NMDevicePrivate *priv; - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); - priv = NM_DEVICE_GET_PRIVATE (self); - if (!priv->hw_addr_perm) - return NULL; - if ( priv->hw_addr_perm_fake - && !fallback_fake) - return NULL; - return priv->hw_addr_perm; + return NM_DEVICE_GET_PRIVATE (self)->hw_addr_perm; } const char * @@ -12048,7 +12040,7 @@ spec_match_list (NMDevice *self, const GSList *specs) } } - hw_addr_perm = nm_device_get_permanent_hw_address (self, TRUE); + hw_addr_perm = nm_device_get_permanent_hw_address (self); if (hw_addr_perm) { m = nm_match_spec_hwaddr (specs, hw_addr_perm); matched = MAX (matched, m); @@ -12522,10 +12514,15 @@ get_property (GObject *object, guint prop_id, case PROP_HW_ADDRESS: g_value_set_string (value, priv->hw_addr); break; - case PROP_PERM_HW_ADDRESS: + case PROP_PERM_HW_ADDRESS: { + const char *perm_hw_addr; + gboolean perm_hw_addr_is_fake; + + perm_hw_addr = nm_device_get_permanent_hw_address_full (self, &perm_hw_addr_is_fake); /* this property is exposed on D-Bus for NMDeviceEthernet and NMDeviceWifi. */ - g_value_set_string (value, nm_device_get_permanent_hw_address (self, FALSE)); + g_value_set_string (value, perm_hw_addr && !perm_hw_addr_is_fake ? perm_hw_addr : NULL); break; + } case PROP_HAS_PENDING_ACTION: g_value_set_boolean (value, nm_device_has_pending_action (self)); break; diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 010c9b9f0d..476a42bc0f 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -364,8 +364,7 @@ guint32 nm_device_get_ip4_route_metric (NMDevice *dev); guint32 nm_device_get_ip6_route_metric (NMDevice *dev); const char * nm_device_get_hw_address (NMDevice *dev); -const char * nm_device_get_permanent_hw_address (NMDevice *dev, - gboolean fallback_fake); +const char * nm_device_get_permanent_hw_address (NMDevice *self); const char * nm_device_get_permanent_hw_address_full (NMDevice *self, gboolean *out_is_fake); const char * nm_device_get_initial_hw_address (NMDevice *dev); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index f467c8141c..f65b0ccaf3 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -615,7 +615,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection) if (!s_wireless) return FALSE; - perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE); + perm_hw_addr = nm_device_get_permanent_hw_address (device); mac = nm_setting_wireless_get_mac_address (s_wireless); if (perm_hw_addr) { if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) @@ -907,7 +907,7 @@ complete_connection (NMDevice *device, if (hidden) g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); - perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE); + perm_hw_addr = nm_device_get_permanent_hw_address (device); if (perm_hw_addr) { setting_mac = nm_setting_wireless_get_mac_address (s_wifi); if (setting_mac) { diff --git a/src/nm-config.c b/src/nm-config.c index 3823e34b3d..f0f0c528bd 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -399,7 +399,7 @@ nm_config_set_no_auto_default_for_device (NMConfig *self, NMDevice *device) priv = NM_CONFIG_GET_PRIVATE (self); - hw_address = nm_device_get_permanent_hw_address (device, TRUE); + hw_address = nm_device_get_permanent_hw_address (device); if (!hw_address) return; diff --git a/src/nm-manager.c b/src/nm-manager.c index a585fb5780..722a4b7daa 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -610,7 +610,7 @@ find_device_by_permanent_hw_addr (NMManager *manager, const char *hwaddr) if (nm_utils_hwaddr_valid (hwaddr, -1)) { for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) { - device_addr = nm_device_get_permanent_hw_address (NM_DEVICE (iter->data), FALSE); + device_addr = nm_device_get_permanent_hw_address (NM_DEVICE (iter->data)); if (device_addr && nm_utils_hwaddr_matches (hwaddr, -1, device_addr, -1)) return NM_DEVICE (iter->data); } diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 1f691c0bd5..cd54e52c51 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -1874,7 +1874,7 @@ have_connection_for_device (NMSettings *self, NMDevice *device) g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); - perm_hw_addr = nm_device_get_permanent_hw_address (device, FALSE); + perm_hw_addr = nm_device_get_permanent_hw_address (device); /* Find a wired connection locked to the given MAC address, if any */ g_hash_table_iter_init (&iter, priv->connections); From e41284b3fca21123a6808cb1d5c262f678472d3f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 26 Oct 2016 12:20:12 +0200 Subject: [PATCH 09/13] device: don't allow mutating the device's hardware address length We repeatedly call nm_device_update_hw_address() to reset the cached MAC address of the device. However, we don't allow changing the address length once it is set. Multiple entities (initial, current and permanent MAC address) are all checked to have the same address length. Changing the length would be a very strange thing (and probably indicate a bug somewhere else). Just don't allow that. (cherry picked from commit cbea1f9f23fac42626134b38cf94dd4ebca4091d) --- src/devices/nm-device.c | 53 ++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index b9f1de01a4..ca84cdfa47 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -226,7 +226,10 @@ typedef struct _NMDevicePrivate { char * iface; /* may change, could be renamed by user */ int ifindex; - guint hw_addr_len; + union { + const guint8 hw_addr_len; /* read-only */ + guint8 hw_addr_len_; + }; guint8 /*HwAddrType*/ hw_addr_type; bool real; @@ -2474,11 +2477,6 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error) g_clear_pointer (&priv->udi, g_free); _notify (self, PROP_UDI); } - if (priv->hw_addr) { - priv->hw_addr_len = 0; - g_clear_pointer (&priv->hw_addr, g_free); - _notify (self, PROP_HW_ADDRESS); - } if (priv->physical_port_id) { g_clear_pointer (&priv->physical_port_id, g_free); _notify (self, PROP_PHYSICAL_PORT_ID); @@ -2487,9 +2485,12 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error) nm_clear_g_source (&priv->stats.timeout_id); _stats_update_counters (self, 0, 0); + priv->hw_addr_len_ = 0; + if (nm_clear_g_free (&priv->hw_addr)) + _notify (self, PROP_HW_ADDRESS); priv->hw_addr_type = HW_ADDR_TYPE_UNSET; - g_clear_pointer (&priv->hw_addr_perm, g_free); - _notify (self, PROP_PERM_HW_ADDRESS); + if (nm_clear_g_free (&priv->hw_addr_perm)) + _notify (self, PROP_PERM_HW_ADDRESS); g_clear_pointer (&priv->hw_addr_initial, g_free); priv->capabilities = NM_DEVICE_CAP_NM_SUPPORTED; @@ -11499,11 +11500,17 @@ const char * nm_device_get_hw_address (NMDevice *self) { NMDevicePrivate *priv; + char buf[NM_UTILS_HWADDR_LEN_MAX]; + gsize l; g_return_val_if_fail (NM_IS_DEVICE (self), NULL); + priv = NM_DEVICE_GET_PRIVATE (self); - nm_assert ((!priv->hw_addr) ^ (priv->hw_addr_len > 0)); + nm_assert ( (!priv->hw_addr && priv->hw_addr_len == 0) + || ( priv->hw_addr + && _nm_utils_hwaddr_aton (priv->hw_addr, buf, sizeof (buf), &l) + && l == priv->hw_addr_len)); return priv->hw_addr; } @@ -11528,9 +11535,25 @@ nm_device_update_hw_address (NMDevice *self) hwaddrlen = 0; if (hwaddrlen) { - priv->hw_addr_len = hwaddrlen; + if ( priv->hw_addr_len + && priv->hw_addr_len != hwaddrlen) { + char s_buf[NM_UTILS_HWADDR_LEN_MAX_STR]; + + /* we cannot change the address length of a device once it is set (except + * unrealizing the device). + * + * The reason is that the permanent and initial MAC addresses also must have the + * same address length, so it's unclear what it would mean that the length changes. */ + _LOGD (LOGD_PLATFORM | LOGD_DEVICE, + "hw-addr: read a MAC address with differing length (%s vs. %s)", + priv->hw_addr, + nm_utils_hwaddr_ntoa_buf (hwaddr, hwaddrlen, TRUE, s_buf, sizeof (s_buf))); + return FALSE; + } + if (!priv->hw_addr || !nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) { g_free (priv->hw_addr); + priv->hw_addr_len_ = hwaddrlen; priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen); _LOGD (LOGD_PLATFORM | LOGD_DEVICE, "hw-addr: hardware address now %s", priv->hw_addr); @@ -11758,11 +11781,9 @@ _hw_addr_set (NMDevice *self, return TRUE; } - if (priv->hw_addr_len != addr_len) { - if (priv->hw_addr_len) - g_return_val_if_reached (FALSE); - priv->hw_addr_len = addr_len; - } + if ( priv->hw_addr_len + && priv->hw_addr_len != addr_len) + g_return_val_if_reached (FALSE); _LOGT (LOGD_DEVICE, "set-hw-addr: setting MAC address to '%s' (%s, %s)...", addr, operation, detail); @@ -12144,7 +12165,7 @@ constructor (GType type, g_return_val_if_reached (object); } - priv->hw_addr_len = l; + priv->hw_addr_len_ = l; priv->hw_addr = nm_utils_hwaddr_ntoa (buf, l); _LOGT (LOGD_DEVICE, "hw-addr: has permanent hw-address '%s'", priv->hw_addr_perm); } From 38b6f36edcc1d908863f66fd20dd79f1ef084f91 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 24 Oct 2016 12:50:17 +0200 Subject: [PATCH 10/13] device: delay capturing permanent MAC address until UDEV is settled The permanent MAC address of an NMDevice shall not change as long as the device is realized. That is, we read it only once and don't change it afterwards. There are two issues that this commit tries to mitigate: (1) users are advised to use UDEV to rename interfaces. As we lookup the permenent MAC address using ethtool (which uses the interface name), there is a race where we could read the permanent MAC address using the wrong interface name. We should wait until UDEV finished initializing the device and until the interface name is stable (see rh#1388286). This commit still cannot avoid the race of ethtool entirely. It only tries to avoid ethtool until UDEV has done its work. That is, until we expect the interface name no longer to change. (2) some device types, don't have a permanent MAC address so we fall back to use the currently set address (fake). Again, users are advised to use UDEV to configure the MAC addresses on such software devices. Thus, we should not get the fake MAC address until UDEV initialized the device. This patch actually doesn't solve the problem at all yet. The reason is that a regular caller of nm_device_get_permanent_hw_address() can not afford to wait until UDEV settled. Thus, any user who requests the permanent MAC address before the link is initialized, runs into the problems above. In a next step, we shall revisit such calls to nm_device_get_permanent_hw_address() and delay them until the link is initialized. (cherry picked from commit 7b7c653c4f812f0ede676e8e0a08aa750e9e30b5) Conflicts: src/devices/nm-device.c src/nm-manager.c --- src/devices/nm-device-ethernet.c | 4 +- src/devices/nm-device.c | 96 +++++++++++++++++++++----------- src/devices/nm-device.h | 3 +- 3 files changed, 67 insertions(+), 36 deletions(-) diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 5e980ed9c5..51515c090a 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -1374,7 +1374,7 @@ complete_connection (NMDevice *device, nm_connection_add_setting (connection, NM_SETTING (s_wired)); } - perm_hw_addr = nm_device_get_permanent_hw_address_full (device, &perm_hw_addr_is_fake); + perm_hw_addr = nm_device_get_permanent_hw_address_full (device, TRUE, &perm_hw_addr_is_fake); if (perm_hw_addr && !perm_hw_addr_is_fake) { setting_mac = nm_setting_wired_get_mac_address (s_wired); if (setting_mac) { @@ -1491,7 +1491,7 @@ update_connection (NMDevice *device, NMConnection *connection) /* If the device reports a permanent address, use that for the MAC address * and the current MAC, if different, is the cloned MAC. */ - perm_hw_addr = nm_device_get_permanent_hw_address_full (device, &perm_hw_addr_is_fake); + perm_hw_addr = nm_device_get_permanent_hw_address_full (device, TRUE, &perm_hw_addr_is_fake); if (perm_hw_addr && !perm_hw_addr_is_fake) { g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, perm_hw_addr, NULL); diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index ca84cdfa47..0aee6fbf65 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1821,7 +1821,7 @@ device_link_changed (NMDevice *self) had_hw_addr = (priv->hw_addr != NULL); nm_device_update_hw_address (self); got_hw_addr = (!had_hw_addr && priv->hw_addr); - nm_device_update_permanent_hw_address (self); + nm_device_update_permanent_hw_address (self, FALSE); if (info.name[0] && strcmp (priv->iface, info.name) != 0) { _LOGI (LOGD_DEVICE, "interface index %d renamed iface from '%s' to '%s'", @@ -2287,7 +2287,7 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink) nm_device_update_hw_address (self); nm_device_update_initial_hw_address (self); - nm_device_update_permanent_hw_address (self); + nm_device_update_permanent_hw_address (self, FALSE); /* Note: initial hardware address must be read before calling get_ignore_carrier() */ config = nm_config_get (); @@ -11605,12 +11605,14 @@ nm_device_update_initial_hw_address (NMDevice *self) } void -nm_device_update_permanent_hw_address (NMDevice *self) +nm_device_update_permanent_hw_address (NMDevice *self, gboolean force_freeze) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; size_t len = 0; gboolean success_read; + int ifindex; + const NMPlatformLink *pllink; if (priv->hw_addr_perm) { /* the permanent hardware address is only read once and not @@ -11621,39 +11623,60 @@ nm_device_update_permanent_hw_address (NMDevice *self) return; } - if (priv->ifindex <= 0) + ifindex = priv->ifindex; + if (ifindex <= 0) return; - if (!priv->hw_addr_len) { - nm_device_update_hw_address (self); - if (!priv->hw_addr_len) + /* the user is advised to configure stable MAC addresses for software devices via + * UDEV. Thus, check whether the link is fully initialized. */ + pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex); + if ( !pllink + || !pllink->initialized) { + if (!force_freeze) { + /* we can afford to wait. Back off and leave the permanent MAC address + * undecided for now. */ return; - } + } + /* try to refresh the link just to give UDEV a bit more time... */ + nm_platform_link_refresh (NM_PLATFORM_GET, ifindex); + /* maybe the MAC address changed... */ + nm_device_update_hw_address (self); + } else if (!priv->hw_addr_len) + nm_device_update_hw_address (self); - success_read = nm_platform_link_get_permanent_address (NM_PLATFORM_GET, priv->ifindex, buf, &len); - if (!success_read || len != priv->hw_addr_len) { - priv->hw_addr_perm_fake = TRUE; - - /* we failed to read a permanent MAC address, thus we use a fake address, - * that is the current MAC address of the device. + if (!priv->hw_addr_len) { + /* we need the current MAC address because we require the permanent MAC address + * to have the same length as the current address. * - * In some cases it might be necessary to know whether this is a "real" or - * a temporary address (fake). */ - _LOGD (LOGD_PLATFORM | LOGD_ETHER, "hw-addr: %s (use current: %s)", - success_read - ? "read HW addr length of permanent MAC address differs" - : "unable to read permanent MAC address", - priv->hw_addr); - priv->hw_addr_perm = g_strdup (priv->hw_addr); - goto out; + * Abort if there is no current MAC address. */ + return; } - priv->hw_addr_perm_fake = FALSE; - priv->hw_addr_perm = nm_utils_hwaddr_ntoa (buf, len); - _LOGD (LOGD_DEVICE, "hw-addr: read permanent MAC address '%s'", - priv->hw_addr_perm); + success_read = nm_platform_link_get_permanent_address (NM_PLATFORM_GET, ifindex, buf, &len); + if (success_read && priv->hw_addr_len == len) { + priv->hw_addr_perm_fake = FALSE; + priv->hw_addr_perm = nm_utils_hwaddr_ntoa (buf, len); + _LOGD (LOGD_DEVICE, "hw-addr: read permanent MAC address '%s'", + priv->hw_addr_perm); + goto notify_and_out; + } -out: + /* we failed to read a permanent MAC address, thus we use a fake address, + * that is the current MAC address of the device. + * + * Note that the permanet MAC address of a NMDevice instance does not change + * after being set once. Thus, we use now a fake address and stick to that + * (until we unrealize the device). */ + priv->hw_addr_perm_fake = TRUE; + + _LOGD (LOGD_PLATFORM | LOGD_ETHER, "hw-addr: %s (use current: %s)", + success_read + ? "read HW addr length of permanent MAC address differs" + : "unable to read permanent MAC address", + priv->hw_addr); + priv->hw_addr_perm = g_strdup (priv->hw_addr); + +notify_and_out: _notify (self, PROP_PERM_HW_ADDRESS); } @@ -11988,13 +12011,22 @@ nm_device_hw_addr_reset (NMDevice *self, const char *detail) } const char * -nm_device_get_permanent_hw_address_full (NMDevice *self, gboolean *out_is_fake) +nm_device_get_permanent_hw_address_full (NMDevice *self, gboolean force_freeze, gboolean *out_is_fake) { NMDevicePrivate *priv; g_return_val_if_fail (NM_IS_DEVICE (self), NULL); priv = NM_DEVICE_GET_PRIVATE (self); + + if ( !priv->hw_addr_perm + && force_freeze) { + /* somebody requests a permanent MAC address, but we don't have it set + * yet. We cannot delay it any longer and try to get it without waiting + * for UDEV. */ + nm_device_update_permanent_hw_address (self, TRUE); + } + NM_SET_OUT (out_is_fake, priv->hw_addr_perm && priv->hw_addr_perm_fake); return priv->hw_addr_perm; } @@ -12002,9 +12034,7 @@ nm_device_get_permanent_hw_address_full (NMDevice *self, gboolean *out_is_fake) const char * nm_device_get_permanent_hw_address (NMDevice *self) { - g_return_val_if_fail (NM_IS_DEVICE (self), NULL); - - return NM_DEVICE_GET_PRIVATE (self)->hw_addr_perm; + return nm_device_get_permanent_hw_address_full (self, TRUE, NULL); } const char * @@ -12539,7 +12569,7 @@ get_property (GObject *object, guint prop_id, const char *perm_hw_addr; gboolean perm_hw_addr_is_fake; - perm_hw_addr = nm_device_get_permanent_hw_address_full (self, &perm_hw_addr_is_fake); + perm_hw_addr = nm_device_get_permanent_hw_address_full (self, FALSE, &perm_hw_addr_is_fake); /* this property is exposed on D-Bus for NMDeviceEthernet and NMDeviceWifi. */ g_value_set_string (value, perm_hw_addr && !perm_hw_addr_is_fake ? perm_hw_addr : NULL); break; diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 476a42bc0f..90443749ec 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -366,6 +366,7 @@ guint32 nm_device_get_ip6_route_metric (NMDevice *dev); const char * nm_device_get_hw_address (NMDevice *dev); const char * nm_device_get_permanent_hw_address (NMDevice *self); const char * nm_device_get_permanent_hw_address_full (NMDevice *self, + gboolean force_freeze, gboolean *out_is_fake); const char * nm_device_get_initial_hw_address (NMDevice *dev); @@ -591,7 +592,7 @@ void nm_device_reactivate_ip6_config (NMDevice *device, gboolean nm_device_update_hw_address (NMDevice *self); void nm_device_update_initial_hw_address (NMDevice *self); -void nm_device_update_permanent_hw_address (NMDevice *self); +void nm_device_update_permanent_hw_address (NMDevice *self, gboolean force_freeze); void nm_device_update_dynamic_ip_setup (NMDevice *self); #endif /* __NETWORKMANAGER_DEVICE_H__ */ From 9f51a93d973e673ff5a6ee286cef1b7347f09767 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 25 Oct 2016 15:27:57 +0200 Subject: [PATCH 11/13] device: delay evaluating unmanaged-by-user-settings flags until link initialized Before the link is initialized, that is before UDEV completed initializing the device, we should not evaluate the user-settings unmanaged flags. The reason is, that evaluating it likely involves looking at the permanent MAC address, which might use the wrong fake MAC address (before UDEV set the right one). Also, it might use the wrong ifname to lookup the permanent MAC address via ethtool. (cherry picked from commit c0d249b733325046ca192d112d468b86aac54ba4) --- src/devices/nm-device.c | 39 ++++++++++++++++++++++++++++++++------- src/devices/nm-device.h | 2 +- src/nm-manager.c | 15 +++++++-------- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 0aee6fbf65..7b7dd4d435 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1833,7 +1833,7 @@ device_link_changed (NMDevice *self) ip_ifname_changed = !priv->ip_iface; if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) - nm_device_set_unmanaged_by_user_settings (self, nm_settings_get_unmanaged_specs (priv->settings)); + nm_device_set_unmanaged_by_user_settings (self); else update_unmanaged_specs = TRUE; @@ -1912,7 +1912,7 @@ device_link_changed (NMDevice *self) } if (update_unmanaged_specs) - nm_device_set_unmanaged_by_user_settings (self, nm_settings_get_unmanaged_specs (priv->settings)); + nm_device_set_unmanaged_by_user_settings (self); if ( got_hw_addr && !priv->up @@ -9868,6 +9868,21 @@ _set_unmanaged_flags (NMDevice *self, allow_state_transition = FALSE; was_managed = allow_state_transition && nm_device_get_managed (self, FALSE); + if ( NM_FLAGS_HAS (priv->unmanaged_flags, NM_UNMANAGED_PLATFORM_INIT) + && NM_FLAGS_HAS (flags, NM_UNMANAGED_PLATFORM_INIT) + && NM_IN_SET (set_op, NM_UNMAN_FLAG_OP_SET_MANAGED)) { + /* we are clearing the platform-init flags. This triggers additional actions. */ + if (!NM_FLAGS_HAS (flags, NM_UNMANAGED_USER_SETTINGS)) { + gboolean unmanaged; + + unmanaged = nm_device_spec_match_list (self, + nm_settings_get_unmanaged_specs (NM_DEVICE_GET_PRIVATE (self)->settings)); + nm_device_set_unmanaged_flags (self, + NM_UNMANAGED_USER_SETTINGS, + !!unmanaged); + } + } + old_flags = priv->unmanaged_flags; old_mask = priv->unmanaged_mask; @@ -9982,20 +9997,30 @@ nm_device_set_unmanaged_by_flags_queue (NMDevice *self, } void -nm_device_set_unmanaged_by_user_settings (NMDevice *self, const GSList *unmanaged_specs) +nm_device_set_unmanaged_by_user_settings (NMDevice *self) { - NMDevicePrivate *priv; gboolean unmanaged; g_return_if_fail (NM_IS_DEVICE (self)); - priv = NM_DEVICE_GET_PRIVATE (self); + if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { + /* the device is already unmanaged due to platform-init. + * + * We want to delay evaluating the device spec, because it will freeze + * the permanent MAC address. That should not be done, before the platform + * link is fully initialized (via UDEV). + * + * Note that when clearing NM_UNMANAGED_PLATFORM_INIT, we will re-evaluate + * whether the device is unmanaged by user-settings. */ + return; + } - unmanaged = nm_device_spec_match_list (self, unmanaged_specs); + unmanaged = nm_device_spec_match_list (self, + nm_settings_get_unmanaged_specs (NM_DEVICE_GET_PRIVATE (self)->settings)); nm_device_set_unmanaged_by_flags (self, NM_UNMANAGED_USER_SETTINGS, - unmanaged, + !!unmanaged, unmanaged ? NM_DEVICE_STATE_REASON_NOW_UNMANAGED : NM_DEVICE_STATE_REASON_NOW_MANAGED); diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 90443749ec..f90444cd07 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -509,7 +509,7 @@ void nm_device_set_unmanaged_by_flags_queue (NMDevice *self, NMUnmanagedFlags flags, NMUnmanFlagOp set_op, NMDeviceStateReason reason); -void nm_device_set_unmanaged_by_user_settings (NMDevice *self, const GSList *unmanaged_specs); +void nm_device_set_unmanaged_by_user_settings (NMDevice *self); void nm_device_set_unmanaged_by_user_udev (NMDevice *self); void nm_device_set_unmanaged_by_quitting (NMDevice *device); diff --git a/src/nm-manager.c b/src/nm-manager.c index 722a4b7daa..94781cd0c5 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1320,11 +1320,10 @@ system_unmanaged_devices_changed_cb (NMSettings *settings, { NMManager *self = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - const GSList *unmanaged_specs, *iter; + const GSList *iter; - unmanaged_specs = nm_settings_get_unmanaged_specs (priv->settings); for (iter = priv->devices; iter; iter = g_slist_next (iter)) - nm_device_set_unmanaged_by_user_settings (NM_DEVICE (iter->data), unmanaged_specs); + nm_device_set_unmanaged_by_user_settings (NM_DEVICE (iter->data)); } static void @@ -1993,7 +1992,7 @@ add_device (NMManager *self, NMDevice *device, GError **error) type_desc = nm_device_get_type_desc (device); g_assert (type_desc); - nm_device_set_unmanaged_by_user_settings (device, nm_settings_get_unmanaged_specs (priv->settings)); + nm_device_set_unmanaged_by_user_settings (device); nm_device_set_unmanaged_flags (device, NM_UNMANAGED_SLEEPING, @@ -2812,15 +2811,15 @@ unmanaged_to_disconnected (NMDevice *device) if (nm_device_get_state (device) == NM_DEVICE_STATE_UNMANAGED) { nm_device_state_changed (device, - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_REASON_USER_REQUESTED); + NM_DEVICE_STATE_UNAVAILABLE, + NM_DEVICE_STATE_REASON_USER_REQUESTED); } if ( nm_device_is_available (device, NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST) && (nm_device_get_state (device) == NM_DEVICE_STATE_UNAVAILABLE)) { nm_device_state_changed (device, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_REASON_USER_REQUESTED); + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_USER_REQUESTED); } } From cc0a590d57d860582396a5d03b1a316c364fd9a7 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 26 Oct 2016 13:43:49 +0200 Subject: [PATCH 12/13] device: don't evaluate IP config changes until device is initialized The unmanaged flags PLATFORM_INIT indicates whether UDEV is done initializing the device. We should not handle IP config changes before that pointer. This avoids codepaths that require the permanent MAC address of the device. We should not freeze the permanent MAC address before UDEV initialized the device, for two reasons: - getting the permanent MAC address using ethtool is racy as UDEV might still rename the interface. - freezing a fake permanent MAC address should only happen after UDEV is done configuring the MAC address of software devices. #0 0x000055555568bc7a in nm_device_update_permanent_hw_address (self=self@entry=0x555555f0fb70 [NMDeviceVeth], force_freeze=force_freeze@entry=1) at src/devices/nm-device.c:11817 #1 0x000055555568c443 in nm_device_get_permanent_hw_address_full (self=self@entry=0x555555f0fb70 [NMDeviceVeth], force_freeze=force_freeze@entry=1, out_is_fake=out_is_fake@entry=0x0) at src/devices/nm-device.c:12227 #2 0x000055555568cb06 in nm_device_get_permanent_hw_address (self=self@entry=0x555555f0fb70 [NMDeviceVeth]) at src/devices/nm-device.c:12237 #3 0x000055555568cb50 in spec_match_list (self=0x555555f0fb70 [NMDeviceVeth], specs=0x555555a5c000 = {...}) at src/devices/nm-device.c:12294 #4 0x00005555556a4ee6 in spec_match_list (device=0x555555f0fb70 [NMDeviceVeth], specs=0x555555a5c000 = {...}) at src/devices/nm-device-ethernet.c:1461 #5 0x00005555556978db in nm_device_spec_match_list (self=self@entry=0x555555f0fb70 [NMDeviceVeth], specs=0x555555a5c000 = {...}) at src/devices/nm-device.c:12277 #6 0x000055555558e187 in _match_section_infos_lookup (match_section_infos=0x555555a5d500, keyfile=0x555555a46f80, property=property@entry=0x555555793123 "ipv4.route-metric", device=device@entry=0x555555f0fb70 [NMDeviceVeth], out_value=out_value@entry=0x7fffffffe018) at src/nm-config-data.c:1169 #7 0x00005555555922ca in nm_config_data_get_connection_default (self=0x555555a548c0 [NMConfigData], property=property@entry=0x555555793123 "ipv4.route-metric", device=device@entry=0x555555f0fb70 [NMDeviceVeth]) at src/nm-config-data.c:1234 #8 0x00005555556790cd in _get_ipx_route_metric (self=self@entry=0x555555f0fb70 [NMDeviceVeth], is_v4=is_v4@entry=1) at src/devices/nm-device.c:1142 #9 0x000055555567912e in nm_device_get_ip4_route_metric (self=self@entry=0x555555f0fb70 [NMDeviceVeth]) at src/devices/nm-device.c:1161 #10 0x000055555567da6c in ip4_config_merge_and_apply (self=self@entry=0x555555f0fb70 [NMDeviceVeth], config=config@entry=0x0, commit=commit@entry=0, out_reason=out_reason@entry=0x0) at src/devices/nm-device.c:4787 #11 0x000055555567e0fb in update_ip4_config (self=self@entry=0x555555f0fb70 [NMDeviceVeth], initial=initial@entry=0) at src/devices/nm-device.c:9532 #12 0x0000555555693acd in queued_ip4_config_change (user_data=0x555555f0fb70) at src/devices/nm-device.c:9651 #13 0x00007ffff4c966ba in g_main_context_dispatch (context=0x555555a46af0) at gmain.c:3154 #14 0x00007ffff4c966ba in g_main_context_dispatch (context=context@entry=0x555555a46af0) at gmain.c:3769 #15 0x00007ffff4c96a70 in g_main_context_iterate (context=0x555555a46af0, block=block@entry=1, dispatch=dispatch@entry=1, self=) at gmain.c:3840 #16 0x00007ffff4c96d92 in g_main_loop_run (loop=0x555555a47400) at gmain.c:4034 #17 0x000055555558372a in main (argc=, argv=) at src/main.c:411 (cherry picked from commit 31ca7962f8f7d1993f0a363b9677c7cee89e7ee3) --- src/devices/nm-device.c | 44 +++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 7b7dd4d435..69f052ba96 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -232,7 +232,12 @@ typedef struct _NMDevicePrivate { }; guint8 /*HwAddrType*/ hw_addr_type; - bool real; + bool real:1; + + /* there was a IP config change, but no idle action was scheduled because device + * is still not platform-init */ + bool queued_ip4_config_pending:1; + bool queued_ip6_config_pending:1; char * ip_iface; int ip_ifindex; @@ -2281,9 +2286,8 @@ realize_start_setup (NMDevice *self, const NMPlatformLink *plink) _notify (self, PROP_UDI); } - /* trigger initial ip config change to initialize ip-config */ - priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self); - priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self); + priv->queued_ip4_config_pending = TRUE; + priv->queued_ip6_config_pending = TRUE; nm_device_update_hw_address (self); nm_device_update_initial_hw_address (self); @@ -7626,6 +7630,7 @@ _cleanup_ip4_pre (NMDevice *self, CleanupType cleanup_type) if (nm_clear_g_source (&priv->queued_ip4_config_id)) _LOGD (LOGD_DEVICE, "clearing queued IP4 config change"); + priv->queued_ip4_config_pending = FALSE; dhcp4_cleanup (self, cleanup_type, FALSE); arp_cleanup (self); @@ -7642,6 +7647,7 @@ _cleanup_ip6_pre (NMDevice *self, CleanupType cleanup_type) if (nm_clear_g_source (&priv->queued_ip6_config_id)) _LOGD (LOGD_DEVICE, "clearing queued IP6 config change"); + priv->queued_ip6_config_pending = FALSE; g_clear_object (&priv->dad6_ip6_config); dhcp6_cleanup (self, cleanup_type, FALSE); @@ -9341,6 +9347,7 @@ update_ip4_config (NMDevice *self, gboolean initial) && activation_source_is_scheduled (self, activate_stage5_ip4_config_commit, AF_INET)) { + priv->queued_ip4_config_pending = FALSE; priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self); _LOGT (LOGD_DEVICE, "IP4 update was postponed"); return; @@ -9431,6 +9438,7 @@ update_ip6_config (NMDevice *self, gboolean initial) && activation_source_is_scheduled (self, activate_stage5_ip6_config_commit, AF_INET6)) { + priv->queued_ip6_config_pending = FALSE; priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self); _LOGT (LOGD_DEVICE, "IP6 update was postponed"); return; @@ -9508,6 +9516,8 @@ queued_ip4_config_change (gpointer user_data) priv = NM_DEVICE_GET_PRIVATE (self); + nm_assert (!priv->queued_ip4_config_pending); + /* Wait for any queued state changes */ if (priv->queued_state.id) return TRUE; @@ -9532,6 +9542,8 @@ queued_ip6_config_change (gpointer user_data) priv = NM_DEVICE_GET_PRIVATE (self); + nm_assert (!priv->queued_ip4_config_pending); + /* Wait for any queued state changes */ if (priv->queued_state.id) return TRUE; @@ -9609,7 +9621,11 @@ device_ipx_changed (NMPlatform *platform, switch (obj_type) { case NMP_OBJECT_TYPE_IP4_ADDRESS: case NMP_OBJECT_TYPE_IP4_ROUTE: - if (!priv->queued_ip4_config_id) { + if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { + priv->queued_ip4_config_pending = TRUE; + nm_assert_se (!nm_clear_g_source (&priv->queued_ip4_config_id)); + } else if (!priv->queued_ip4_config_id) { + priv->queued_ip4_config_pending = FALSE; priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self); _LOGD (LOGD_DEVICE, "queued IP4 config change"); } @@ -9626,7 +9642,11 @@ device_ipx_changed (NMPlatform *platform, } /* fallthrough */ case NMP_OBJECT_TYPE_IP6_ROUTE: - if (!priv->queued_ip6_config_id) { + if (nm_device_get_unmanaged_flags (self, NM_UNMANAGED_PLATFORM_INIT)) { + priv->queued_ip6_config_pending = TRUE; + nm_assert_se (!nm_clear_g_source (&priv->queued_ip6_config_id)); + } else if (!priv->queued_ip6_config_id) { + priv->queued_ip6_config_pending = FALSE; priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self); _LOGD (LOGD_DEVICE, "queued IP6 config change"); } @@ -9881,6 +9901,18 @@ _set_unmanaged_flags (NMDevice *self, NM_UNMANAGED_USER_SETTINGS, !!unmanaged); } + + if (priv->queued_ip4_config_pending) { + priv->queued_ip4_config_pending = FALSE; + nm_assert_se (!nm_clear_g_source (&priv->queued_ip4_config_id)); + priv->queued_ip4_config_id = g_idle_add (queued_ip4_config_change, self); + } + + if (priv->queued_ip6_config_pending) { + priv->queued_ip6_config_pending = FALSE; + nm_assert_se (!nm_clear_g_source (&priv->queued_ip6_config_id)); + priv->queued_ip6_config_id = g_idle_add (queued_ip6_config_change, self); + } } old_flags = priv->unmanaged_flags; From 37266b483bcaa89ae169c8e11ea9fbb42ba50d12 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 28 Oct 2016 17:06:13 +0200 Subject: [PATCH 13/13] device: suppress log message in nm_device_update_hw_address() when no MAC address For example for tun devices we get a lot of (tun7): hw-addr: failed reading current MAC address warnings. Just be silent about it. We log when something changes, we don't need to log when we fail to obtain a MAC address. Thereby, refactor nm_device_update_hw_address() to return early. (cherry picked from commit 0e0018c8016156b9a01028f1448e7baf76e14d4a) Conflicts: src/devices/nm-device.c --- src/devices/nm-device.c | 83 ++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 46 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 69f052ba96..a4b8d2528a 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -11578,7 +11578,6 @@ nm_device_update_hw_address (NMDevice *self) NMDevicePrivate *priv; const guint8 *hwaddr; gsize hwaddrlen = 0; - gboolean changed = FALSE; priv = NM_DEVICE_GET_PRIVATE (self); if (priv->ifindex <= 0) @@ -11591,54 +11590,46 @@ nm_device_update_hw_address (NMDevice *self) && nm_utils_hwaddr_matches (hwaddr, hwaddrlen, nm_ip_addr_zero.addr_eth, sizeof (nm_ip_addr_zero.addr_eth))) hwaddrlen = 0; - if (hwaddrlen) { - if ( priv->hw_addr_len - && priv->hw_addr_len != hwaddrlen) { - char s_buf[NM_UTILS_HWADDR_LEN_MAX_STR]; + if (!hwaddrlen) + return FALSE; - /* we cannot change the address length of a device once it is set (except - * unrealizing the device). - * - * The reason is that the permanent and initial MAC addresses also must have the - * same address length, so it's unclear what it would mean that the length changes. */ - _LOGD (LOGD_PLATFORM | LOGD_DEVICE, - "hw-addr: read a MAC address with differing length (%s vs. %s)", - priv->hw_addr, - nm_utils_hwaddr_ntoa_buf (hwaddr, hwaddrlen, TRUE, s_buf, sizeof (s_buf))); - return FALSE; - } + if ( priv->hw_addr_len + && priv->hw_addr_len != hwaddrlen) { + char s_buf[NM_UTILS_HWADDR_LEN_MAX_STR]; - if (!priv->hw_addr || !nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) { - g_free (priv->hw_addr); - priv->hw_addr_len_ = hwaddrlen; - priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen); - - _LOGD (LOGD_PLATFORM | LOGD_DEVICE, "hw-addr: hardware address now %s", priv->hw_addr); - _notify (self, PROP_HW_ADDRESS); - - if ( !priv->hw_addr_initial - || ( priv->hw_addr_type == HW_ADDR_TYPE_UNSET - && priv->state < NM_DEVICE_STATE_PREPARE - && !nm_device_is_activating (self))) { - /* when we get a hw_addr the first time or while the device - * is not activated (with no explict hw address set), always - * update our inital hw-address as well. */ - nm_device_update_initial_hw_address (self); - } - changed = TRUE; - } - } else { - /* Invalid or no hardware address */ - if (priv->hw_addr_len != 0) { - _LOGD (LOGD_PLATFORM | LOGD_DEVICE, - "hw-addr: failed reading current MAC address (stay with %s)", - priv->hw_addr); - } else { - _LOGD (LOGD_PLATFORM | LOGD_DEVICE, - "hw-addr: failed reading current MAC address"); - } + /* we cannot change the address length of a device once it is set (except + * unrealizing the device). + * + * The reason is that the permanent and initial MAC addresses also must have the + * same address length, so it's unclear what it would mean that the length changes. */ + _LOGD (LOGD_PLATFORM | LOGD_DEVICE, + "hw-addr: read a MAC address with differing length (%s vs. %s)", + priv->hw_addr, + nm_utils_hwaddr_ntoa_buf (hwaddr, hwaddrlen, TRUE, s_buf, sizeof (s_buf))); + return FALSE; } - return changed; + + if ( priv->hw_addr + && nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) + return FALSE; + + g_free (priv->hw_addr); + priv->hw_addr_len_ = hwaddrlen; + priv->hw_addr = nm_utils_hwaddr_ntoa (hwaddr, hwaddrlen); + + _LOGD (LOGD_PLATFORM | LOGD_DEVICE, "hw-addr: hardware address now %s", priv->hw_addr); + _notify (self, PROP_HW_ADDRESS); + + if ( !priv->hw_addr_initial + || ( priv->hw_addr_type == HW_ADDR_TYPE_UNSET + && priv->state < NM_DEVICE_STATE_PREPARE + && !nm_device_is_activating (self))) { + /* when we get a hw_addr the first time or while the device + * is not activated (with no explict hw address set), always + * update our inital hw-address as well. */ + nm_device_update_initial_hw_address (self); + } + return TRUE; } void