diff options
Diffstat (limited to 'src/devices')
| -rw-r--r-- | src/devices/adsl/nm-atm-manager.c | 14 | ||||
| -rw-r--r-- | src/devices/adsl/nm-device-adsl.c | 6 | ||||
| -rw-r--r-- | src/devices/bluetooth/nm-bluez5-dun.c | 4 | ||||
| -rw-r--r-- | src/devices/nm-device-bond.c | 2 | ||||
| -rw-r--r-- | src/devices/nm-device-ethernet.c | 31 | ||||
| -rw-r--r-- | src/devices/nm-device-factory.c | 18 | ||||
| -rw-r--r-- | src/devices/nm-device-infiniband.c | 6 | ||||
| -rw-r--r-- | src/devices/nm-device-ip-tunnel.c | 8 | ||||
| -rw-r--r-- | src/devices/nm-device-macvlan.c | 4 | ||||
| -rw-r--r-- | src/devices/nm-device-tun.c | 2 | ||||
| -rw-r--r-- | src/devices/nm-device-veth.c | 2 | ||||
| -rw-r--r-- | src/devices/nm-device-vlan.c | 2 | ||||
| -rw-r--r-- | src/devices/nm-device-vxlan.c | 2 | ||||
| -rw-r--r-- | src/devices/nm-device.c | 465 | ||||
| -rw-r--r-- | src/devices/nm-device.h | 10 | ||||
| -rw-r--r-- | src/devices/tests/test-lldp.c | 4 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 9 | ||||
| -rw-r--r-- | src/devices/wifi/nm-wifi-factory.c | 2 | ||||
| -rw-r--r-- | src/devices/wwan/nm-device-modem.c | 4 | ||||
| -rw-r--r-- | src/devices/wwan/nm-modem.c | 34 |
20 files changed, 358 insertions, 271 deletions
diff --git a/src/devices/adsl/nm-atm-manager.c b/src/devices/adsl/nm-atm-manager.c index 67085752..40c782fd 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/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c index ebb7a319..77c6e119 100644 --- a/src/devices/adsl/nm-device-adsl.c +++ b/src/devices/adsl/nm-device-adsl.c @@ -154,7 +154,7 @@ br2684_assign_vcc (NMDeviceAdsl *self, NMSettingAdsl *s_adsl) g_return_val_if_fail (priv->brfd == -1, FALSE); g_return_val_if_fail (priv->nas_ifname != NULL, FALSE); - priv->brfd = socket (PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); + priv->brfd = socket (PF_ATMPVC, SOCK_DGRAM | SOCK_CLOEXEC, ATM_AAL5); if (priv->brfd < 0) { errsv = errno; _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); @@ -338,7 +338,7 @@ br2684_create_iface (NMDeviceAdsl *self, nm_clear_g_source (&priv->nas_update_id); } - fd = socket (PF_ATMPVC, SOCK_DGRAM, ATM_AAL5); + fd = socket (PF_ATMPVC, SOCK_DGRAM | SOCK_CLOEXEC, ATM_AAL5); if (fd < 0) { errsv = errno; _LOGE (LOGD_ADSL, "failed to open ATM control socket (%d)", errsv); @@ -472,7 +472,7 @@ act_stage3_ip4_config_start (NMDevice *device, } priv->ppp_manager = nm_ppp_manager_new (ppp_iface); - if (nm_ppp_manager_start (priv->ppp_manager, req, nm_setting_adsl_get_username (s_adsl), 30, &err)) { + if (nm_ppp_manager_start (priv->ppp_manager, req, nm_setting_adsl_get_username (s_adsl), 30, 0, &err)) { g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_STATE_CHANGED, G_CALLBACK (ppp_state_changed), self); diff --git a/src/devices/bluetooth/nm-bluez5-dun.c b/src/devices/bluetooth/nm-bluez5-dun.c index 4c93feba..aba3a0dd 100644 --- a/src/devices/bluetooth/nm-bluez5-dun.c +++ b/src/devices/bluetooth/nm-bluez5-dun.c @@ -64,7 +64,7 @@ dun_connect (NMBluez5DunContext *context) .channel = context->rfcomm_channel }; - context->rfcomm_fd = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM); + context->rfcomm_fd = socket (AF_BLUETOOTH, SOCK_STREAM | SOCK_CLOEXEC, BTPROTO_RFCOMM); if (context->rfcomm_fd < 0) { int errsv = errno; error = g_error_new (NM_BT_ERROR, NM_BT_ERROR_DUN_CONNECT_FAILED, @@ -112,7 +112,7 @@ dun_connect (NMBluez5DunContext *context) context->rfcomm_id = devid; snprintf (tty, ttylen, "/dev/rfcomm%d", devid); - while ((context->rfcomm_tty_fd = open (tty, O_RDONLY | O_NOCTTY)) < 0 && try--) { + while ((context->rfcomm_tty_fd = open (tty, O_RDONLY | O_NOCTTY | O_CLOEXEC)) < 0 && try--) { if (try) { g_usleep (100 * 1000); continue; diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 3f17849b..75b2e315 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 b213a0cc..51515c09 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; } @@ -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)) @@ -935,7 +935,7 @@ pppoe_stage3_ip4_config_start (NMDeviceEthernet *self, NMDeviceStateReason *reas g_assert (s_pppoe); priv->ppp_manager = nm_ppp_manager_new (nm_device_get_iface (NM_DEVICE (self))); - if (nm_ppp_manager_start (priv->ppp_manager, req, nm_setting_pppoe_get_username (s_pppoe), 30, &err)) { + if (nm_ppp_manager_start (priv->ppp_manager, req, nm_setting_pppoe_get_username (s_pppoe), 30, 0, &err)) { g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_STATE_CHANGED, G_CALLBACK (ppp_state_changed), self); @@ -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); } @@ -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, 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) { /* 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, 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); mac_prop = NULL; @@ -1529,7 +1532,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 7873756f..a72c0bbb 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-infiniband.c b/src/devices/nm-device-infiniband.c index 17f50ba2..e2a67de4 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-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index 785010eb..72a13893 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 2bfc65cb..c53abb68 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; } @@ -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-tun.c b/src/devices/nm-device-tun.c index 1f42d060..f818cd7c 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 56923315..c16df6d8 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-vlan.c b/src/devices/nm-device-vlan.c index 16edc0d2..461bae66 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-vxlan.c b/src/devices/nm-device-vxlan.c index 674c2a78..2453543d 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 27d940c9..ac840ab9 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -33,7 +33,6 @@ #include <sys/wait.h> #include <arpa/inet.h> #include <fcntl.h> -#include <netlink/route/addr.h> #include <linux/if_addr.h> #include "nm-common-macros.h" @@ -227,10 +226,18 @@ 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; + 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; @@ -757,7 +764,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"); } } @@ -900,7 +907,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; @@ -1819,7 +1826,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'", @@ -1831,7 +1838,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; @@ -1910,7 +1917,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 @@ -2279,13 +2286,12 @@ 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); - 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 (); @@ -2299,7 +2305,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)" : ""); @@ -2475,11 +2481,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); @@ -2488,9 +2489,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; @@ -3493,95 +3497,35 @@ nm_device_can_assume_connections (NMDevice *self) return !!NM_DEVICE_GET_CLASS (self)->update_connection; } -/** - * nm_device_can_assume_active_connection: - * @self: #NMDevice instance - * - * This is a convenience function to determine whether the device's active - * connection can be assumed if NetworkManager restarts. This method returns - * %TRUE if and only if the device can assume connections, and the device has - * an active connection, and that active connection can be assumed. - * - * Returns: %TRUE if the device's active connection can be assumed, or %FALSE - * if there is no active connection or the active connection cannot be - * assumed. - */ static gboolean -nm_device_can_assume_active_connection (NMDevice *self) +unmanaged_on_quit (NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; - const char *method; - const char *assumable_ip6_methods[] = { - NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_METHOD_DHCP, - NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, - NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NULL - }; - const char *assumable_ip4_methods[] = { - NM_SETTING_IP4_CONFIG_METHOD_DISABLED, - NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NM_SETTING_IP6_CONFIG_METHOD_MANUAL, - NULL - }; + /* NMDeviceWifi overwrites this function to always unmanage wifi devices. + * + * For all other types, if the device type can assume connections, we leave + * it up on quit. + * + * Originally, we would only keep devices up that can be assumed afterwards. + * However, that meant we unmanged layer-2 only devices. So, this was step + * by step refined to unmanage less (commit 25aaaab3, rh#1311988, rh#1333983). + * But there are more scenarios where we also want to keep the device up + * (rh#1378418, rh#1371126). */ if (!nm_device_can_assume_connections (self)) - return FALSE; + return TRUE; + /* the only exception are IPv4 shared connections. We unmanage them on quit. */ connection = nm_device_get_applied_connection (self); - if (!connection) - return FALSE; - - /* Can't assume connections that aren't yet configured - * FIXME: what about bridges/bonds waiting for slaves? - */ - if (priv->state < NM_DEVICE_STATE_IP_CONFIG) - return FALSE; - if (priv->ip4_state != IP_DONE && priv->ip6_state != IP_DONE) - return FALSE; - - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - if (!g_strv_contains (assumable_ip6_methods, method)) - return FALSE; - - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (!g_strv_contains (assumable_ip4_methods, method)) - return FALSE; - - return TRUE; -} - -static gboolean -unmanaged_on_quit (NMDevice *self) -{ - /* Leave certain devices alone when quitting so their configuration - * can be taken over when NM restarts. This ensures connectivity while - * NM is stopped. - */ - if (nm_device_uses_assumed_connection (self)) { - /* An assume connection must be left alone */ - return FALSE; - } - - if (!nm_device_get_act_request (self)) { - /* a device without any active connection is either UNAVAILABLE or DISCONNECTED - * state. Since we don't know whether the device was upped by NetworkManager, - * we must leave it up on exit. - */ - return FALSE; - } - - if (!nm_platform_link_can_assume (NM_PLATFORM_GET, nm_device_get_ifindex (self))) { - /* The device has no layer 3 configuration. Leave it up. */ - return FALSE; + if (connection) { + if (NM_IN_STRSET (nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG), + NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { + /* shared connections are to be unmangaed. */ + return TRUE; + } } - if (nm_device_can_assume_active_connection (self)) - return FALSE; - - return TRUE; + return FALSE; } gboolean @@ -3768,7 +3712,7 @@ activation_source_schedule (NMDevice *self, ActivationHandleFunc func, int famil act_data = activation_source_get_by_family (self, family, &source_func); - if (act_data->id && act_data->func != func) { + if (act_data->id && act_data->func == func) { /* Don't bother rescheduling the same function that's about to * run anyway. Fixes issues with crappy wireless drivers sending * streams of associate events before NM has had a chance to process @@ -4869,8 +4813,6 @@ END_ADD_DEFAULT_ROUTE: priv->default_route.v4_has = _device_get_default_route_from_platform (self, AF_INET, (NMPlatformIPRoute *) &priv->default_route.v4); } - nm_ip4_config_addresses_sort (composite); - /* Allow setting MTU etc */ if (commit) { if (NM_DEVICE_GET_CLASS (self)->ip4_config_pre_commit) @@ -5490,13 +5432,15 @@ ip6_config_merge_and_apply (NMDevice *self, /* If no config was passed in, create a new one */ composite = nm_ip6_config_new (nm_device_get_ip_ifindex (self)); + nm_ip6_config_set_privacy (composite, + priv->rdisc ? + priv->rdisc_use_tempaddr : + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); init_ip6_config_dns_priority (self, composite); if (commit) ensure_con_ip6_config (self); - g_assert (composite); - /* Merge all the IP configs into the composite config */ if (priv->ac_ip6_config) { nm_ip6_config_merge (composite, priv->ac_ip6_config, @@ -5623,9 +5567,6 @@ END_ADD_DEFAULT_ROUTE: priv->default_route.v6_has = _device_get_default_route_from_platform (self, AF_INET6, (NMPlatformIPRoute *) &priv->default_route.v6); } - nm_ip6_config_addresses_sort (composite, - priv->rdisc ? priv->rdisc_use_tempaddr : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); - /* Allow setting MTU etc */ if (commit) { NMUtilsIPv6IfaceId iid; @@ -7686,6 +7627,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); @@ -7702,6 +7644,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); @@ -7911,6 +7854,7 @@ reapply_connection (NMDevice *self, error, NM_SETTING_CONNECTION_ID, NM_SETTING_CONNECTION_UUID, + NM_SETTING_CONNECTION_AUTOCONNECT, NM_SETTING_CONNECTION_ZONE, NM_SETTING_CONNECTION_METERED)) return FALSE; @@ -9094,7 +9038,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)) @@ -9120,9 +9064,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; } @@ -9186,7 +9130,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)) @@ -9208,9 +9152,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"); } } @@ -9223,7 +9167,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; } @@ -9401,6 +9345,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; @@ -9491,6 +9436,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; @@ -9568,6 +9514,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; @@ -9592,6 +9540,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; @@ -9669,7 +9619,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"); } @@ -9686,7 +9640,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"); } @@ -9928,6 +9886,33 @@ _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); + } + + 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; old_mask = priv->unmanaged_mask; @@ -10042,20 +10027,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); @@ -11211,7 +11206,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); } @@ -11560,11 +11555,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; } @@ -11575,7 +11576,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) @@ -11588,38 +11588,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) { - priv->hw_addr_len = hwaddrlen; - if (!priv->hw_addr || !nm_utils_hwaddr_matches (priv->hw_addr, -1, hwaddr, hwaddrlen)) { - 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); - _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_HW | LOGD_DEVICE, - "hw-addr: failed reading current MAC address (stay with %s)", - priv->hw_addr); - } else { - _LOGD (LOGD_HW | LOGD_DEVICE, - "hw-addr: failed reading current MAC address"); - } + if (!hwaddrlen) + return FALSE; + + 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; } - 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 @@ -11643,12 +11651,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 @@ -11659,35 +11669,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) { - /* Fall back to current address. We use the fake address and keep it - * until the device unrealizes. + 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_HW | 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_fake = TRUE; - priv->hw_addr_perm = g_strdup (priv->hw_addr); - } else { + * Abort if there is no current MAC address. */ + return; + } + + 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; } + + /* 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); } @@ -11779,25 +11814,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)); @@ -11806,17 +11841,17 @@ _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)) + 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); @@ -11827,12 +11862,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 { @@ -11862,7 +11897,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; @@ -11945,7 +11980,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; @@ -11989,9 +12024,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; } @@ -12023,22 +12057,33 @@ nm_device_hw_addr_reset (NMDevice *self, const char *detail) } const char * -nm_device_get_permanent_hw_address (NMDevice *self, gboolean fallback_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) - return NULL; - if ( priv->hw_addr_perm_fake - && !fallback_fake) - return NULL; + + 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; } const char * +nm_device_get_permanent_hw_address (NMDevice *self) +{ + return nm_device_get_permanent_hw_address_full (self, TRUE, NULL); +} + +const char * nm_device_get_initial_hw_address (NMDevice *self) { g_return_val_if_fail (NM_IS_DEVICE (self), NULL); @@ -12092,7 +12137,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); if (hw_addr_perm) { m = nm_match_spec_hwaddr (specs, hw_addr_perm); matched = MAX (matched, m); @@ -12188,13 +12233,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); } @@ -12563,10 +12611,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, FALSE, &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 a757a37e..f90444cd 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -364,8 +364,10 @@ 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 force_freeze, + gboolean *out_is_fake); const char * nm_device_get_initial_hw_address (NMDevice *dev); NMDhcp4Config * nm_device_get_dhcp4_config (NMDevice *dev); @@ -507,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); @@ -590,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__ */ diff --git a/src/devices/tests/test-lldp.c b/src/devices/tests/test-lldp.c index ff6f42a9..f6b6af90 100644 --- a/src/devices/tests/test-lldp.c +++ b/src/devices/tests/test-lldp.c @@ -352,7 +352,7 @@ _test_recv_fixture_setup (TestRecvFixture *fixture, gconstpointer user_data) struct ifreq ifr = { }; int fd, s; - fd = open ("/dev/net/tun", O_RDWR); + fd = open ("/dev/net/tun", O_RDWR | O_CLOEXEC); g_assert (fd >= 0); ifr.ifr_flags = IFF_TAP | IFF_NO_PI; @@ -360,7 +360,7 @@ _test_recv_fixture_setup (TestRecvFixture *fixture, gconstpointer user_data) g_assert (ioctl (fd, TUNSETIFF, &ifr) >= 0); /* Bring the interface up */ - s = socket (AF_INET, SOCK_DGRAM, 0); + s = socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); g_assert (s >= 0); ifr.ifr_flags |= IFF_UP; g_assert (ioctl (s, SIOCSIFFLAGS, &ifr) >= 0); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index f97e6689..c58b3fa8 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 ()); @@ -478,7 +478,6 @@ ap_add_remove (NMDeviceWifi *self, } g_signal_emit (self, signals[signum], 0, ap); - _notify (self, PROP_ACCESS_POINTS); if (signum == ACCESS_POINT_REMOVED) { g_hash_table_remove (priv->aps, nm_exported_object_get_path ((NMExportedObject *) ap)); @@ -486,6 +485,8 @@ ap_add_remove (NMDeviceWifi *self, g_object_unref (ap); } + _notify (self, PROP_ACCESS_POINTS); + nm_device_emit_recheck_auto_activate (NM_DEVICE (self)); if (recheck_available_connections) nm_device_recheck_available_connections (NM_DEVICE (self)); @@ -615,7 +616,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 +908,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/devices/wifi/nm-wifi-factory.c b/src/devices/wifi/nm-wifi-factory.c index 2d5f8faf..cf8cf03b 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-device-modem.c b/src/devices/wwan/nm-device-modem.c index 0f96dafb..b277b15b 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -351,7 +351,7 @@ device_state_changed (NMDevice *device, { NMDeviceModem *self = NM_DEVICE_MODEM (device); NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (device); - NMConnection *connection = nm_device_get_applied_connection (device); + NMSettingsConnection *connection = nm_device_get_settings_connection (device); g_assert (priv->modem); @@ -378,7 +378,7 @@ device_state_changed (NMDevice *device, * where a retry attempt would just fail again. */ if (connection) - nm_settings_connection_set_autoconnect_blocked_reason (NM_SETTINGS_CONNECTION (connection), reason); + nm_settings_connection_set_autoconnect_blocked_reason (connection, reason); break; default: break; diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index 2e3d63bb..459d212a 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -23,7 +23,9 @@ #include "nm-modem.h" +#include <fcntl.h> #include <string.h> +#include <termios.h> #include "nm-core-internal.h" #include "nm-platform.h" @@ -491,6 +493,23 @@ ppp_stats (NMPPPManager *ppp_manager, } } +static gboolean +port_speed_is_zero (const char *port) +{ + struct termios options; + nm_auto_close int fd = -1; + + fd = open (port, O_RDWR | O_NONBLOCK | O_NOCTTY | O_CLOEXEC); + if (fd < 0) + return FALSE; + + memset (&options, 0, sizeof (struct termios)); + if (tcgetattr (fd, &options) != 0) + return FALSE; + + return cfgetospeed (&options) == B0; +} + static NMActStageReturn ppp_stage3_ip_config_start (NMModem *self, NMActRequest *req, @@ -501,6 +520,7 @@ ppp_stage3_ip_config_start (NMModem *self, GError *error = NULL; NMActStageReturn ret; guint ip_timeout = 30; + guint baud_override = 0; g_return_val_if_fail (NM_IS_MODEM (self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (NM_IS_ACT_REQUEST (req), NM_ACT_STAGE_RETURN_FAILURE); @@ -530,8 +550,16 @@ ppp_stage3_ip_config_start (NMModem *self, ip_timeout = priv->mm_ip_timeout; } + /* Some tty drivers and modems ignore port speed, but pppd requires the + * port speed to be > 0 or it exits. If the port speed is 0 pass an + * explicit speed to pppd to prevent the exit. + * https://bugzilla.redhat.com/show_bug.cgi?id=1281731 + */ + if (port_speed_is_zero (priv->data_port)) + baud_override = 57600; + priv->ppp_manager = nm_ppp_manager_new (priv->data_port); - if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, ip_timeout, &error)) { + if (nm_ppp_manager_start (priv->ppp_manager, req, ppp_name, ip_timeout, baud_override, &error)) { g_signal_connect (priv->ppp_manager, NM_PPP_MANAGER_STATE_CHANGED, G_CALLBACK (ppp_state_changed), self); @@ -1327,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; } |