diff options
| author | Aron Xu <aron@debian.org> | 2016-12-20 20:06:37 +0800 |
|---|---|---|
| committer | Aron Xu <aron@debian.org> | 2016-12-20 20:06:37 +0800 |
| commit | 45cb5bb3c0e6edb887cf69b417fcaf7053814a9b (patch) | |
| tree | 795f8d6a3aa1145e4ba8fa1564f39425ea0c6ed9 /src | |
| parent | 270c4830551c9810ad4e83f9a1db2b1cb946208c (diff) | |
Imported Upstream version 1.4.4 upstream/1.4.4
Diffstat (limited to 'src')
55 files changed, 813 insertions, 543 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; } diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index ce8f4d93..5a758a9e 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -707,7 +707,7 @@ update_resolv_conf (NMDnsManager *self, } } - if ((f = fopen (MY_RESOLV_CONF_TMP, "w")) == NULL) { + if ((f = fopen (MY_RESOLV_CONF_TMP, "we")) == NULL) { errsv = errno; g_set_error (error, NM_MANAGER_ERROR, @@ -1576,7 +1576,7 @@ _check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager) } } - fd = open (_PATH_RESCONF, O_RDONLY); + fd = open (_PATH_RESCONF, O_RDONLY | O_CLOEXEC); if (fd != -1) { if (ioctl (fd, FS_IOC_GETFLAGS, &flags) != -1) immutable = NM_FLAGS_HAS (flags, FS_IMMUTABLE_FL); diff --git a/src/main-utils.c b/src/main-utils.c index c2ed9d1c..6497ea25 100644 --- a/src/main-utils.c +++ b/src/main-utils.c @@ -94,7 +94,7 @@ nm_main_utils_write_pidfile (const char *pidfile) int fd; gboolean success = FALSE; - if ((fd = open (pidfile, O_CREAT|O_WRONLY|O_TRUNC, 00644)) < 0) { + if ((fd = open (pidfile, O_CREAT | O_WRONLY | O_TRUNC | O_CLOEXEC, 00644)) < 0) { fprintf (stderr, _("Opening %s failed: %s\n"), pidfile, strerror (errno)); return FALSE; } diff --git a/src/nm-config.c b/src/nm-config.c index 4bc4f483..f0f0c528 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); if (!hw_address) return; diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 6dfbb4ce..ed2a871e 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)) { @@ -2813,7 +2810,7 @@ nm_utils_read_urandom (void *p, size_t nbytes) int r; again: - fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY); + fd = open ("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOCTTY); if (fd < 0) { r = errno; if (r == EINTR) diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index a4d43612..7b422359 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -55,6 +55,8 @@ typedef struct { gint64 route_metric; gboolean metered; gint dns_priority; + GVariant *address_data_variant; + GVariant *addresses_variant; } NMIP4ConfigPrivate; struct _NMIP4Config { @@ -207,8 +209,9 @@ _addresses_sort_cmp_get_prio (in_addr_t addr) static gint _addresses_sort_cmp (gconstpointer a, gconstpointer b) { - gint p1, p2, c; + gint p1, p2; const NMPlatformIP4Address *a1 = a, *a2 = b; + guint32 n1, n2; /* Sort by address type. For example link local will * be sorted *after* a global address. */ @@ -224,43 +227,30 @@ _addresses_sort_cmp (gconstpointer a, gconstpointer b) if ((a1->label[0] == '\0') != (a2->label[0] == '\0')) return (a1->label[0] == '\0') ? -1 : 1; - /* finally sort addresses lexically */ - c = memcmp (&a1->address, &a2->address, sizeof (a2->address)); - return c != 0 ? c : memcmp (a1, a2, sizeof (*a1)); -} - -gboolean -nm_ip4_config_addresses_sort (NMIP4Config *self) -{ - NMIP4ConfigPrivate *priv; - size_t data_len = 0; - char *data_pre = NULL; - gboolean changed; - - g_return_val_if_fail (NM_IS_IP4_CONFIG (self), FALSE); + /* Finally, sort addresses lexically. We compare only the + * network part so that the order of addresses in the same + * subnet (and thus also the primary/secondary role) is + * preserved. + */ + n1 = a1->address & nm_utils_ip4_prefix_to_netmask (a1->plen); + n2 = a2->address & nm_utils_ip4_prefix_to_netmask (a2->plen); - priv = NM_IP4_CONFIG_GET_PRIVATE (self); - if (priv->addresses->len > 1) { - data_len = priv->addresses->len * g_array_get_element_size (priv->addresses); - data_pre = g_new (char, data_len); - memcpy (data_pre, priv->addresses->data, data_len); + return memcmp (&n1, &n2, sizeof (guint32)); +} - g_array_sort (priv->addresses, _addresses_sort_cmp); +/*****************************************************************************/ - changed = memcmp (data_pre, priv->addresses->data, data_len) != 0; - g_free (data_pre); +static void +notify_addresses (NMIP4Config *self) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); - if (changed) { - _notify (self, PROP_ADDRESS_DATA); - _notify (self, PROP_ADDRESSES); - return TRUE; - } - } - return FALSE; + nm_clear_g_variant (&priv->address_data_variant); + nm_clear_g_variant (&priv->addresses_variant); + _notify (self, PROP_ADDRESS_DATA); + _notify (self, PROP_ADDRESSES); } -/*****************************************************************************/ - NMIP4Config * nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf) { @@ -347,7 +337,6 @@ gboolean nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_full_sync, gint64 default_route_metric) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); - int i; gs_unref_ptrarray GPtrArray *added_addresses = NULL; g_return_val_if_fail (ifindex > 0, FALSE); @@ -359,7 +348,8 @@ nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_fu /* Routes */ { - int count = nm_ip4_config_get_num_routes (config); + guint i; + guint count = nm_ip4_config_get_num_routes (config); GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Route), count); gboolean success; gs_unref_array GArray *device_route_purge_list = NULL; @@ -1366,7 +1356,7 @@ gboolean nm_ip4_config_destination_is_direct (const NMIP4Config *config, guint32 network, guint8 plen) { guint naddresses = nm_ip4_config_get_num_addresses (config); - int i; + guint i; in_addr_t peer_network; for (i = 0; i < naddresses; i++) { @@ -1473,8 +1463,7 @@ nm_ip4_config_reset_addresses (NMIP4Config *config) if (priv->addresses->len != 0) { g_array_set_size (priv->addresses, 0); - _notify (config, PROP_ADDRESS_DATA); - _notify (config, PROP_ADDRESSES); + notify_addresses (config); } } @@ -1531,8 +1520,7 @@ nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *new) g_array_append_val (priv->addresses, *new); NOTIFY: - _notify (config, PROP_ADDRESS_DATA); - _notify (config, PROP_ADDRESSES); + notify_addresses (config); } void @@ -1543,8 +1531,8 @@ nm_ip4_config_del_address (NMIP4Config *config, guint i) g_return_if_fail (i < priv->addresses->len); g_array_remove_index (priv->addresses, i); - _notify (config, PROP_ADDRESS_DATA); - _notify (config, PROP_ADDRESSES); + + notify_addresses (config); } guint @@ -1725,7 +1713,7 @@ nm_ip4_config_del_nameserver (NMIP4Config *config, guint i) _notify (config, PROP_NAMESERVERS); } -guint32 +guint nm_ip4_config_get_num_nameservers (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -1782,7 +1770,7 @@ nm_ip4_config_del_domain (NMIP4Config *config, guint i) _notify (config, PROP_DOMAINS); } -guint32 +guint nm_ip4_config_get_num_domains (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -1854,7 +1842,7 @@ nm_ip4_config_del_search (NMIP4Config *config, guint i) _notify (config, PROP_SEARCHES); } -guint32 +guint nm_ip4_config_get_num_searches (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -1911,7 +1899,7 @@ nm_ip4_config_del_dns_option(NMIP4Config *config, guint i) _notify (config, PROP_DNS_OPTIONS); } -guint32 +guint nm_ip4_config_get_num_dns_options (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -1999,7 +1987,7 @@ nm_ip4_config_del_nis_server (NMIP4Config *config, guint i) g_array_remove_index (priv->nis, i); } -guint32 +guint nm_ip4_config_get_num_nis_servers (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -2072,7 +2060,7 @@ nm_ip4_config_del_wins (NMIP4Config *config, guint i) _notify (config, PROP_WINS_SERVERS); } -guint32 +guint nm_ip4_config_get_num_wins (const NMIP4Config *config) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); @@ -2147,7 +2135,7 @@ hash_u32 (GChecksum *sum, guint32 n) void nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only) { - guint32 i; + guint i; const char *s; g_return_if_fail (config); @@ -2267,6 +2255,8 @@ finalize (GObject *object) NMIP4Config *self = NM_IP4_CONFIG (object); NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + nm_clear_g_variant (&priv->address_data_variant); + nm_clear_g_variant (&priv->addresses_variant); g_array_unref (priv->addresses); g_array_unref (priv->routes); g_array_unref (priv->nameservers); @@ -2292,14 +2282,26 @@ get_property (GObject *object, guint prop_id, g_value_set_int (value, priv->ifindex); break; case PROP_ADDRESS_DATA: + case PROP_ADDRESSES: { GVariantBuilder array_builder, addr_builder; - int naddr = nm_ip4_config_get_num_addresses (config); - int i; + gs_unref_array GArray *new = NULL; + guint naddr, i; + + g_return_if_fail (!!priv->address_data_variant == !!priv->addresses_variant); + + if (priv->address_data_variant) + goto return_cached; + naddr = nm_ip4_config_get_num_addresses (config); + new = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP4Address), naddr); + g_array_append_vals (new, priv->addresses->data, priv->addresses->len); + g_array_sort (new, _addresses_sort_cmp); + + /* Build address data variant */ g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}")); for (i = 0; i < naddr; i++) { - const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, i); + const NMPlatformIP4Address *address = &g_array_index (new, NMPlatformIP4Address, i); g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (&addr_builder, "{sv}", @@ -2322,19 +2324,12 @@ get_property (GObject *object, guint prop_id, g_variant_builder_add (&array_builder, "a{sv}", &addr_builder); } + priv->address_data_variant = g_variant_ref_sink (g_variant_builder_end (&array_builder)); - g_value_take_variant (value, g_variant_builder_end (&array_builder)); - } - break; - case PROP_ADDRESSES: - { - GVariantBuilder array_builder; - int naddr = nm_ip4_config_get_num_addresses (config); - int i; - + /* Build addresses variant */ g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aau")); for (i = 0; i < naddr; i++) { - const NMPlatformIP4Address *address = nm_ip4_config_get_address (config, i); + const NMPlatformIP4Address *address = &g_array_index (new, NMPlatformIP4Address, i); guint32 dbus_addr[3]; dbus_addr[0] = address->address; @@ -2345,15 +2340,20 @@ get_property (GObject *object, guint prop_id, g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, dbus_addr, 3, sizeof (guint32))); } + priv->addresses_variant = g_variant_ref_sink (g_variant_builder_end (&array_builder)); - g_value_take_variant (value, g_variant_builder_end (&array_builder)); +return_cached: + g_value_set_variant (value, + prop_id == PROP_ADDRESS_DATA ? + priv->address_data_variant : + priv->addresses_variant); } break; case PROP_ROUTE_DATA: { GVariantBuilder array_builder, route_builder; guint nroutes = nm_ip4_config_get_num_routes (config); - int i; + guint i; g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}")); for (i = 0; i < nroutes; i++) { @@ -2385,7 +2385,7 @@ get_property (GObject *object, guint prop_id, { GVariantBuilder array_builder; guint nroutes = nm_ip4_config_get_num_routes (config); - int i; + guint i; g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aau")); for (i = 0; i < nroutes; i++) { diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index f302630a..6fc45dc2 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -58,13 +58,13 @@ NMIP4Config * nm_ip4_config_new (int ifindex); int nm_ip4_config_get_ifindex (const NMIP4Config *config); -/* Integration with nm-platform and nm-setting */ + NMIP4Config *nm_ip4_config_capture (int ifindex, gboolean capture_resolv_conf); gboolean nm_ip4_config_commit (const NMIP4Config *config, int ifindex, gboolean routes_full_sync, gint64 default_route_metric); void nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, guint32 default_route_metric); NMSetting *nm_ip4_config_create_setting (const NMIP4Config *config); -/* Utility functions */ + void nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFlags merge_flags); void nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src); void nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src); @@ -72,7 +72,7 @@ gboolean nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboole gboolean nm_ip4_config_destination_is_direct (const NMIP4Config *config, guint32 dest, guint8 plen); void nm_ip4_config_dump (const NMIP4Config *config, const char *detail); -/* Gateways */ + void nm_ip4_config_set_never_default (NMIP4Config *config, gboolean never_default); gboolean nm_ip4_config_get_never_default (const NMIP4Config *config); void nm_ip4_config_set_gateway (NMIP4Config *config, guint32 gateway); @@ -81,82 +81,69 @@ gboolean nm_ip4_config_has_gateway (const NMIP4Config *config); guint32 nm_ip4_config_get_gateway (const NMIP4Config *config); gint64 nm_ip4_config_get_route_metric (const NMIP4Config *config); -/* Addresses */ void nm_ip4_config_reset_addresses (NMIP4Config *config); void nm_ip4_config_add_address (NMIP4Config *config, const NMPlatformIP4Address *address); void nm_ip4_config_del_address (NMIP4Config *config, guint i); guint nm_ip4_config_get_num_addresses (const NMIP4Config *config); const NMPlatformIP4Address *nm_ip4_config_get_address (const NMIP4Config *config, guint i); gboolean nm_ip4_config_address_exists (const NMIP4Config *config, const NMPlatformIP4Address *address); -gboolean nm_ip4_config_addresses_sort (NMIP4Config *config); -/* Routes */ void nm_ip4_config_reset_routes (NMIP4Config *config); void nm_ip4_config_add_route (NMIP4Config *config, const NMPlatformIP4Route *route); void nm_ip4_config_del_route (NMIP4Config *config, guint i); -guint32 nm_ip4_config_get_num_routes (const NMIP4Config *config); -const NMPlatformIP4Route *nm_ip4_config_get_route (const NMIP4Config *config, guint32 i); +guint nm_ip4_config_get_num_routes (const NMIP4Config *config); +const NMPlatformIP4Route *nm_ip4_config_get_route (const NMIP4Config *config, guint i); const NMPlatformIP4Route *nm_ip4_config_get_direct_route_for_host (const NMIP4Config *config, guint32 host); -/* Nameservers */ void nm_ip4_config_reset_nameservers (NMIP4Config *config); void nm_ip4_config_add_nameserver (NMIP4Config *config, guint32 nameserver); void nm_ip4_config_del_nameserver (NMIP4Config *config, guint i); -guint32 nm_ip4_config_get_num_nameservers (const NMIP4Config *config); +guint nm_ip4_config_get_num_nameservers (const NMIP4Config *config); guint32 nm_ip4_config_get_nameserver (const NMIP4Config *config, guint i); -/* Domains */ void nm_ip4_config_reset_domains (NMIP4Config *config); void nm_ip4_config_add_domain (NMIP4Config *config, const char *domain); void nm_ip4_config_del_domain (NMIP4Config *config, guint i); -guint32 nm_ip4_config_get_num_domains (const NMIP4Config *config); +guint nm_ip4_config_get_num_domains (const NMIP4Config *config); const char * nm_ip4_config_get_domain (const NMIP4Config *config, guint i); -/* Search lists */ void nm_ip4_config_reset_searches (NMIP4Config *config); void nm_ip4_config_add_search (NMIP4Config *config, const char *search); void nm_ip4_config_del_search (NMIP4Config *config, guint i); -guint32 nm_ip4_config_get_num_searches (const NMIP4Config *config); +guint nm_ip4_config_get_num_searches (const NMIP4Config *config); const char * nm_ip4_config_get_search (const NMIP4Config *config, guint i); -/* DNS options */ void nm_ip4_config_reset_dns_options (NMIP4Config *config); void nm_ip4_config_add_dns_option (NMIP4Config *config, const char *option); void nm_ip4_config_del_dns_option (NMIP4Config *config, guint i); -guint32 nm_ip4_config_get_num_dns_options (const NMIP4Config *config); +guint nm_ip4_config_get_num_dns_options (const NMIP4Config *config); const char * nm_ip4_config_get_dns_option (const NMIP4Config *config, guint i); -/* DNS priority */ void nm_ip4_config_set_dns_priority (NMIP4Config *config, gint priority); gint nm_ip4_config_get_dns_priority (const NMIP4Config *config); -/* MSS */ void nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss); guint32 nm_ip4_config_get_mss (const NMIP4Config *config); -/* NIS */ void nm_ip4_config_reset_nis_servers (NMIP4Config *config); void nm_ip4_config_add_nis_server (NMIP4Config *config, guint32 nis); void nm_ip4_config_del_nis_server (NMIP4Config *config, guint i); -guint32 nm_ip4_config_get_num_nis_servers (const NMIP4Config *config); +guint nm_ip4_config_get_num_nis_servers (const NMIP4Config *config); guint32 nm_ip4_config_get_nis_server (const NMIP4Config *config, guint i); void nm_ip4_config_set_nis_domain (NMIP4Config *config, const char *domain); const char * nm_ip4_config_get_nis_domain (const NMIP4Config *config); -/* WINS */ void nm_ip4_config_reset_wins (NMIP4Config *config); void nm_ip4_config_add_wins (NMIP4Config *config, guint32 wins); void nm_ip4_config_del_wins (NMIP4Config *config, guint i); -guint32 nm_ip4_config_get_num_wins (const NMIP4Config *config); +guint nm_ip4_config_get_num_wins (const NMIP4Config *config); guint32 nm_ip4_config_get_wins (const NMIP4Config *config, guint i); -/* MTU */ void nm_ip4_config_set_mtu (NMIP4Config *config, guint32 mtu, NMIPConfigSource source); guint32 nm_ip4_config_get_mtu (const NMIP4Config *config); NMIPConfigSource nm_ip4_config_get_mtu_source (const NMIP4Config *config); -/* Metered */ void nm_ip4_config_set_metered (NMIP4Config *config, gboolean metered); gboolean nm_ip4_config_get_metered (const NMIP4Config *config); diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 8002d61a..a0211246 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -48,6 +48,9 @@ typedef struct { int ifindex; gint64 route_metric; gint dns_priority; + GVariant *address_data_variant; + GVariant *addresses_variant; + NMSettingIP6ConfigPrivacy privacy; } NMIP6ConfigPrivate; struct _NMIP6Config { @@ -104,7 +107,26 @@ nm_ip6_config_get_ifindex (const NMIP6Config *config) return NM_IP6_CONFIG_GET_PRIVATE (config)->ifindex; } -/******************************************************************/ +void +nm_ip6_config_set_privacy (NMIP6Config *config, NMSettingIP6ConfigPrivacy privacy) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + + priv->privacy = privacy; +} + +/*****************************************************************************/ + +static void +notify_addresses (NMIP6Config *self) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + + nm_clear_g_variant (&priv->address_data_variant); + nm_clear_g_variant (&priv->addresses_variant); + _notify (self, PROP_ADDRESS_DATA); + _notify (self, PROP_ADDRESSES); +} /** * nm_ip6_config_capture_resolv_conf(): @@ -266,7 +288,7 @@ _addresses_sort_cmp (gconstpointer a, gconstpointer b, gpointer user_data) } gboolean -nm_ip6_config_addresses_sort (NMIP6Config *self, NMSettingIP6ConfigPrivacy use_temporary) +nm_ip6_config_addresses_sort (NMIP6Config *self) { NMIP6ConfigPrivate *priv; size_t data_len = 0; @@ -281,14 +303,14 @@ nm_ip6_config_addresses_sort (NMIP6Config *self, NMSettingIP6ConfigPrivacy use_t data_pre = g_new (char, data_len); memcpy (data_pre, priv->addresses->data, data_len); - g_array_sort_with_data (priv->addresses, _addresses_sort_cmp, GINT_TO_POINTER (use_temporary)); + g_array_sort_with_data (priv->addresses, _addresses_sort_cmp, + GINT_TO_POINTER (priv->privacy)); changed = memcmp (data_pre, priv->addresses->data, data_len) != 0; g_free (data_pre); if (changed) { - _notify (self, PROP_ADDRESS_DATA); - _notify (self, PROP_ADDRESSES); + notify_addresses (self); return TRUE; } } @@ -384,7 +406,6 @@ gboolean nm_ip6_config_commit (const NMIP6Config *config, int ifindex, gboolean routes_full_sync) { const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); - int i; gboolean success; g_return_val_if_fail (ifindex > 0, FALSE); @@ -395,7 +416,8 @@ nm_ip6_config_commit (const NMIP6Config *config, int ifindex, gboolean routes_fu /* Routes */ { - int count = nm_ip6_config_get_num_routes (config); + guint i; + guint count = nm_ip6_config_get_num_routes (config); GArray *routes = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP6Route), count); const NMPlatformIP6Route *route; @@ -712,8 +734,8 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFl gboolean nm_ip6_config_destination_is_direct (const NMIP6Config *config, const struct in6_addr *network, guint8 plen) { - int num = nm_ip6_config_get_num_addresses (config); - int i; + guint num = nm_ip6_config_get_num_addresses (config); + guint i; nm_assert (network); nm_assert (plen <= 128); @@ -1156,6 +1178,11 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev has_minor_changes = TRUE; } + if (src_priv->privacy != dst_priv->privacy) { + nm_ip6_config_set_privacy (dst, src_priv->privacy); + has_minor_changes = TRUE; + } + #if NM_MORE_ASSERTS /* config_equal does not compare *all* the fields, therefore, we might have has_minor_changes * regardless of config_equal. But config_equal must correspond to has_relevant_changes. */ @@ -1282,8 +1309,7 @@ nm_ip6_config_reset_addresses (NMIP6Config *config) if (priv->addresses->len != 0) { g_array_set_size (priv->addresses, 0); - _notify (config, PROP_ADDRESS_DATA); - _notify (config, PROP_ADDRESSES); + notify_addresses (config); } } @@ -1340,8 +1366,7 @@ nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *new) g_array_append_val (priv->addresses, *new); NOTIFY: - _notify (config, PROP_ADDRESS_DATA); - _notify (config, PROP_ADDRESSES); +notify_addresses (config); } void @@ -1352,8 +1377,8 @@ nm_ip6_config_del_address (NMIP6Config *config, guint i) g_return_if_fail (i < priv->addresses->len); g_array_remove_index (priv->addresses, i); - _notify (config, PROP_ADDRESS_DATA); - _notify (config, PROP_ADDRESSES); + + notify_addresses (config); } guint @@ -1626,7 +1651,7 @@ nm_ip6_config_del_nameserver (NMIP6Config *config, guint i) _notify (config, PROP_NAMESERVERS); } -guint32 +guint nm_ip6_config_get_num_nameservers (const NMIP6Config *config) { const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); @@ -1683,7 +1708,7 @@ nm_ip6_config_del_domain (NMIP6Config *config, guint i) _notify (config, PROP_DOMAINS); } -guint32 +guint nm_ip6_config_get_num_domains (const NMIP6Config *config) { const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); @@ -1755,7 +1780,7 @@ nm_ip6_config_del_search (NMIP6Config *config, guint i) _notify (config, PROP_SEARCHES); } -guint32 +guint nm_ip6_config_get_num_searches (const NMIP6Config *config) { const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); @@ -1812,7 +1837,7 @@ nm_ip6_config_del_dns_option (NMIP6Config *config, guint i) _notify (config, PROP_DNS_OPTIONS); } -guint32 +guint nm_ip6_config_get_num_dns_options (const NMIP6Config *config) { const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); @@ -2000,6 +2025,8 @@ finalize (GObject *object) g_ptr_array_unref (priv->domains); g_ptr_array_unref (priv->searches); g_ptr_array_unref (priv->dns_options); + nm_clear_g_variant (&priv->address_data_variant); + nm_clear_g_variant (&priv->addresses_variant); G_OBJECT_CLASS (nm_ip6_config_parent_class)->finalize (object); } @@ -2036,14 +2063,28 @@ get_property (GObject *object, guint prop_id, g_value_set_int (value, priv->ifindex); break; case PROP_ADDRESS_DATA: + case PROP_ADDRESSES: { GVariantBuilder array_builder, addr_builder; - int naddr = nm_ip6_config_get_num_addresses (config); - int i; + gs_unref_array GArray *new = NULL; + const struct in6_addr *gateway; + guint naddr, i; + + g_return_if_fail (!!priv->address_data_variant == !!priv->addresses_variant); + + if (priv->address_data_variant) + goto return_cached; + + naddr = nm_ip6_config_get_num_addresses (config); + gateway = nm_ip6_config_get_gateway (config); + new = g_array_sized_new (FALSE, FALSE, sizeof (NMPlatformIP6Address), naddr); + g_array_append_vals (new, priv->addresses->data, naddr); + g_array_sort_with_data (new, _addresses_sort_cmp, + GINT_TO_POINTER (priv->privacy)); g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("aa{sv}")); for (i = 0; i < naddr; i++) { - const NMPlatformIP6Address *address = nm_ip6_config_get_address (config, i); + const NMPlatformIP6Address *address = &g_array_index (new, NMPlatformIP6Address, i); g_variant_builder_init (&addr_builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (&addr_builder, "{sv}", @@ -2061,20 +2102,11 @@ get_property (GObject *object, guint prop_id, g_variant_builder_add (&array_builder, "a{sv}", &addr_builder); } - - g_value_take_variant (value, g_variant_builder_end (&array_builder)); - } - break; - case PROP_ADDRESSES: - { - GVariantBuilder array_builder; - const struct in6_addr *gateway = nm_ip6_config_get_gateway (config); - int naddr = nm_ip6_config_get_num_addresses (config); - int i; + priv->address_data_variant = g_variant_ref_sink (g_variant_builder_end (&array_builder)); g_variant_builder_init (&array_builder, G_VARIANT_TYPE ("a(ayuay)")); for (i = 0; i < naddr; i++) { - const NMPlatformIP6Address *address = nm_ip6_config_get_address (config, i); + const NMPlatformIP6Address *address = &g_array_index (new, NMPlatformIP6Address, i); g_variant_builder_add (&array_builder, "(@ayu@ay)", g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, @@ -2085,7 +2117,12 @@ get_property (GObject *object, guint prop_id, 16, 1)); } - g_value_take_variant (value, g_variant_builder_end (&array_builder)); + priv->addresses_variant = g_variant_ref_sink (g_variant_builder_end (&array_builder)); +return_cached: + g_value_set_variant (value, + prop_id == PROP_ADDRESS_DATA ? + priv->address_data_variant : + priv->addresses_variant); } break; case PROP_ROUTE_DATA: diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index c3f8d9f8..9454c0f7 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -60,13 +60,13 @@ NMIP6Config * nm_ip6_config_new_cloned (const NMIP6Config *src); int nm_ip6_config_get_ifindex (const NMIP6Config *config); -/* Integration with nm-platform and nm-setting */ + NMIP6Config *nm_ip6_config_capture (int ifindex, gboolean capture_resolv_conf, NMSettingIP6ConfigPrivacy use_temporary); gboolean nm_ip6_config_commit (const NMIP6Config *config, int ifindex, gboolean routes_full_sync); void nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, guint32 default_route_metric); NMSetting *nm_ip6_config_create_setting (const NMIP6Config *config); -/* Utility functions */ + void nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFlags merge_flags); void nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src); void nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src); @@ -74,14 +74,13 @@ gboolean nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboole int nm_ip6_config_destination_is_direct (const NMIP6Config *config, const struct in6_addr *dest, guint8 plen); void nm_ip6_config_dump (const NMIP6Config *config, const char *detail); -/* Gateways */ + void nm_ip6_config_set_never_default (NMIP6Config *config, gboolean never_default); gboolean nm_ip6_config_get_never_default (const NMIP6Config *config); void nm_ip6_config_set_gateway (NMIP6Config *config, const struct in6_addr *); const struct in6_addr *nm_ip6_config_get_gateway (const NMIP6Config *config); gint64 nm_ip6_config_get_route_metric (const NMIP6Config *config); -/* Addresses */ void nm_ip6_config_reset_addresses (NMIP6Config *config); void nm_ip6_config_add_address (NMIP6Config *config, const NMPlatformIP6Address *address); void nm_ip6_config_del_address (NMIP6Config *config, guint i); @@ -89,60 +88,54 @@ guint nm_ip6_config_get_num_addresses (const NMIP6Config *config); const NMPlatformIP6Address *nm_ip6_config_get_address (const NMIP6Config *config, guint i); const NMPlatformIP6Address *nm_ip6_config_get_address_first_nontentative (const NMIP6Config *config, gboolean linklocal); gboolean nm_ip6_config_address_exists (const NMIP6Config *config, const NMPlatformIP6Address *address); -gboolean nm_ip6_config_addresses_sort (NMIP6Config *config, NMSettingIP6ConfigPrivacy use_temporary); +gboolean nm_ip6_config_addresses_sort (NMIP6Config *config); gboolean nm_ip6_config_has_any_dad_pending (const NMIP6Config *self, const NMIP6Config *candidates); -/* Routes */ void nm_ip6_config_reset_routes (NMIP6Config *config); void nm_ip6_config_add_route (NMIP6Config *config, const NMPlatformIP6Route *route); void nm_ip6_config_del_route (NMIP6Config *config, guint i); -guint32 nm_ip6_config_get_num_routes (const NMIP6Config *config); -const NMPlatformIP6Route *nm_ip6_config_get_route (const NMIP6Config *config, guint32 i); +guint nm_ip6_config_get_num_routes (const NMIP6Config *config); +const NMPlatformIP6Route *nm_ip6_config_get_route (const NMIP6Config *config, guint i); const NMPlatformIP6Route *nm_ip6_config_get_direct_route_for_host (const NMIP6Config *config, const struct in6_addr *host); const NMPlatformIP6Address *nm_ip6_config_get_subnet_for_host (const NMIP6Config *config, const struct in6_addr *host); -/* Nameservers */ void nm_ip6_config_reset_nameservers (NMIP6Config *config); void nm_ip6_config_add_nameserver (NMIP6Config *config, const struct in6_addr *nameserver); void nm_ip6_config_del_nameserver (NMIP6Config *config, guint i); -guint32 nm_ip6_config_get_num_nameservers (const NMIP6Config *config); +guint nm_ip6_config_get_num_nameservers (const NMIP6Config *config); const struct in6_addr *nm_ip6_config_get_nameserver (const NMIP6Config *config, guint i); -/* Domains */ void nm_ip6_config_reset_domains (NMIP6Config *config); void nm_ip6_config_add_domain (NMIP6Config *config, const char *domain); void nm_ip6_config_del_domain (NMIP6Config *config, guint i); -guint32 nm_ip6_config_get_num_domains (const NMIP6Config *config); +guint nm_ip6_config_get_num_domains (const NMIP6Config *config); const char * nm_ip6_config_get_domain (const NMIP6Config *config, guint i); -/* Search lists */ void nm_ip6_config_reset_searches (NMIP6Config *config); void nm_ip6_config_add_search (NMIP6Config *config, const char *search); void nm_ip6_config_del_search (NMIP6Config *config, guint i); -guint32 nm_ip6_config_get_num_searches (const NMIP6Config *config); +guint nm_ip6_config_get_num_searches (const NMIP6Config *config); const char * nm_ip6_config_get_search (const NMIP6Config *config, guint i); -/* DNS options */ void nm_ip6_config_reset_dns_options (NMIP6Config *config); void nm_ip6_config_add_dns_option (NMIP6Config *config, const char *option); void nm_ip6_config_del_dns_option (NMIP6Config *config, guint i); -guint32 nm_ip6_config_get_num_dns_options (const NMIP6Config *config); +guint nm_ip6_config_get_num_dns_options (const NMIP6Config *config); const char * nm_ip6_config_get_dns_option (const NMIP6Config *config, guint i); -/* DNS priority */ void nm_ip6_config_set_dns_priority (NMIP6Config *config, gint priority); gint nm_ip6_config_get_dns_priority (const NMIP6Config *config); -/* MSS */ void nm_ip6_config_set_mss (NMIP6Config *config, guint32 mss); guint32 nm_ip6_config_get_mss (const NMIP6Config *config); void nm_ip6_config_hash (const NMIP6Config *config, GChecksum *sum, gboolean dns_only); gboolean nm_ip6_config_equal (const NMIP6Config *a, const NMIP6Config *b); -/******************************************************/ +void nm_ip6_config_set_privacy (NMIP6Config *config, NMSettingIP6ConfigPrivacy privacy); + /* Testing-only functions */ gboolean nm_ip6_config_capture_resolv_conf (GArray *nameservers, diff --git a/src/nm-logging.h b/src/nm-logging.h index 9e2b0108..72eb3db4 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 836ab768..c3d65cd1 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); } @@ -746,9 +746,7 @@ checked_connectivity (GObject *object, GAsyncResult *result, gpointer user_data) if (connectivity == NM_CONNECTIVITY_FULL) set_state (manager, NM_STATE_CONNECTED_GLOBAL); - else if ( connectivity == NM_CONNECTIVITY_PORTAL - || connectivity == NM_CONNECTIVITY_LIMITED) - set_state (manager, NM_STATE_CONNECTED_SITE); + _notify (manager, PROP_CONNECTIVITY); } @@ -756,7 +754,7 @@ checked_connectivity (GObject *object, GAsyncResult *result, gpointer user_data) } static NMState -find_best_device_state (NMManager *manager) +find_best_device_state (NMManager *manager, gboolean *force_connectivity_check) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); NMState best_state = NM_STATE_DISCONNECTED; @@ -774,6 +772,7 @@ find_best_device_state (NMManager *manager) return NM_STATE_CONNECTED_GLOBAL; best_state = NM_STATE_CONNECTED_SITE; + NM_SET_OUT (force_connectivity_check, TRUE); } else { if (best_state < NM_STATE_CONNECTING) best_state = NM_STATE_CONNECTED_LOCAL; @@ -827,6 +826,7 @@ nm_manager_update_state (NMManager *manager) { NMManagerPrivate *priv; NMState new_state = NM_STATE_DISCONNECTED; + gboolean force_connectivity_check = FALSE; g_return_if_fail (NM_IS_MANAGER (manager)); @@ -835,11 +835,11 @@ nm_manager_update_state (NMManager *manager) if (manager_sleeping (manager)) new_state = NM_STATE_ASLEEP; else - new_state = find_best_device_state (manager); + new_state = find_best_device_state (manager, &force_connectivity_check); nm_connectivity_set_online (priv->connectivity, new_state >= NM_STATE_CONNECTED_LOCAL); - if (new_state == NM_STATE_CONNECTED_SITE) { + if (new_state == NM_STATE_CONNECTED_SITE || force_connectivity_check) { nm_connectivity_check_async (priv->connectivity, checked_connectivity, g_object_ref (manager)); @@ -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, @@ -2127,10 +2126,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 +2143,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 */ @@ -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); } } @@ -4060,16 +4059,26 @@ do_sleep_wake (NMManager *self, gboolean sleeping_changed) if (waking_from_suspend) { sleep_devices_clear (self); - /* Belatedly take down Wake-on-LAN devices; ideally we wouldn't have to do this - * but for now it's the only way to make sure we re-check their connectivity. - */ for (iter = priv->devices; iter; iter = iter->next) { NMDevice *device = iter->data; if (nm_device_is_software (device)) continue; + + /* Belatedly take down Wake-on-LAN devices; ideally we wouldn't have to do this + * but for now it's the only way to make sure we re-check their connectivity. + */ if (device_is_wake_on_lan (device)) nm_device_set_unmanaged_by_flags (device, NM_UNMANAGED_SLEEPING, TRUE, NM_DEVICE_STATE_REASON_SLEEPING); + + /* Check if the device is unmanaged but the state transition is still pending. + * If so, change state now so that later we re-manage the device forcing a + * re-check of available connections. + */ + if ( !nm_device_get_managed (device, FALSE) + && nm_device_get_state (device) != NM_DEVICE_STATE_UNMANAGED) { + nm_device_state_changed (device, NM_DEVICE_STATE_UNMANAGED, NM_DEVICE_STATE_REASON_SLEEPING); + } } } @@ -5323,7 +5332,7 @@ rfkill_change (NMManager *self, const char *desc, RfKillType rtype, gboolean ena g_return_if_fail (rtype == RFKILL_TYPE_WLAN || rtype == RFKILL_TYPE_WWAN); errno = 0; - fd = open ("/dev/rfkill", O_RDWR); + fd = open ("/dev/rfkill", O_RDWR | O_CLOEXEC); if (fd < 0) { if (errno == EACCES) _LOGW (LOGD_RFKILL, "(%s): failed to open killswitch device", desc); @@ -5644,7 +5653,6 @@ get_property (GObject *object, guint prop_id, g_value_set_string (value, VERSION); break; case PROP_STATE: - nm_manager_update_state (self); g_value_set_uint (value, priv->state); break; case PROP_STARTUP: diff --git a/src/nm-rfkill-manager.c b/src/nm-rfkill-manager.c index 453a3b9b..e4e738c9 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/nm-session-monitor.c b/src/nm-session-monitor.c index 279a8886..fb656c6b 100644 --- a/src/nm-session-monitor.c +++ b/src/nm-session-monitor.c @@ -78,6 +78,19 @@ static guint signals[LAST_SIGNAL] = { 0 }; /********************************************************************/ +#define _NMLOG_PREFIX_NAME "session-monitor" +#define _NMLOG_DOMAIN LOGD_CORE + +#define _NMLOG(level, ...) \ + G_STMT_START { \ + nm_log (level, _NMLOG_DOMAIN, \ + "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } G_STMT_END + +/*****************************************************************************/ + #ifdef SESSION_TRACKING_SYSTEMD static gboolean st_sd_session_exists (NMSessionMonitor *monitor, uid_t uid, gboolean active) @@ -90,8 +103,7 @@ st_sd_session_exists (NMSessionMonitor *monitor, uid_t uid, gboolean active) status = sd_uid_get_sessions (uid, active, NULL); if (status < 0) - nm_log_err (LOGD_CORE, "Failed to get systemd sessions for uid %d: %d", - uid, status); + _LOGE ("failed to get systemd sessions for uid %d: %d", uid, status); return status > 0; } @@ -118,7 +130,7 @@ st_sd_init (NMSessionMonitor *monitor) return; if ((status = sd_login_monitor_new (NULL, &monitor->sd.monitor)) < 0) { - nm_log_err (LOGD_CORE, "Failed to create systemd login monitor: %d", status); + _LOGE ("failed to create systemd login monitor: %d", status); return; } @@ -156,7 +168,7 @@ ck_load_cache (GHashTable *cache) goto out; if (!(groups = g_key_file_get_groups (keyfile, &len))) { - nm_log_err (LOGD_CORE, "Could not load groups from " CKDB_PATH); + _LOGE ("could not load groups from " CKDB_PATH); goto out; } @@ -166,7 +178,7 @@ ck_load_cache (GHashTable *cache) guint uid = G_MAXUINT; CkSession session = { .active = FALSE }; - if (!g_str_has_prefix (groups[i], "CkSession ")) + if (!g_str_has_prefix (groups[i], "Session ")) continue; uid = g_key_file_get_integer (keyfile, groups[i], "uid", &error); @@ -183,7 +195,7 @@ ck_load_cache (GHashTable *cache) finished = TRUE; out: if (error) - nm_log_err (LOGD_CORE, "ConsoleKit: Failed to load database: %s", error->message); + _LOGE ("failed to load ConsoleKit database: %s", error->message); g_clear_error (&error); g_clear_pointer (&groups, g_strfreev); g_clear_pointer (&keyfile, g_key_file_free); @@ -201,7 +213,7 @@ ck_update_cache (NMSessionMonitor *monitor) /* Check the database file */ if (stat (CKDB_PATH, &statbuf) != 0) { - nm_log_err (LOGD_CORE, "Failed to check ConsoleKit timestamp: %s", strerror (errno)); + _LOGE ("failed to check ConsoleKit timestamp: %s", strerror (errno)); return FALSE; } if (statbuf.st_mtime == monitor->ck.timestamp) @@ -258,7 +270,7 @@ ck_init (NMSessionMonitor *monitor) G_CALLBACK (ck_changed), monitor); } else { - nm_log_err (LOGD_CORE, "Error monitoring " CKDB_PATH ": %s", error->message); + _LOGE ("error monitoring " CKDB_PATH ": %s", error->message); g_clear_error (&error); } } @@ -363,10 +375,12 @@ nm_session_monitor_init (NMSessionMonitor *monitor) { #ifdef SESSION_TRACKING_SYSTEMD st_sd_init (monitor); + _LOGD ("using systemd-logind session tracking"); #endif #ifdef SESSION_TRACKING_CONSOLEKIT ck_init (monitor); + _LOGD ("using ConsoleKit session tracking"); #endif } diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 070a83ea..f9f4b088 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -36,12 +36,7 @@ #include <linux/if_tun.h> #include <linux/if_tunnel.h> #include <netlink/netlink.h> -#include <netlink/object.h> -#include <netlink/cache.h> -#include <netlink/route/link.h> -#include <netlink/route/link/vlan.h> -#include <netlink/route/addr.h> -#include <netlink/route/route.h> +#include <netlink/msg.h> #include <gudev/gudev.h> #include "nm-utils.h" @@ -54,6 +49,7 @@ #include "nm-platform-utils.h" #include "wifi/wifi-utils.h" #include "wifi/wifi-utils-wext.h" +#include "nm-utils/unaligned.h" #define offset_plus_sizeof(t,m) (offsetof (t,m) + sizeof (((t *) NULL)->m)) @@ -61,6 +57,7 @@ /* nm-internal error codes for libnl. Make sure they don't overlap. */ #define _NLE_NM_NOBUFS 500 +#define _NLE_MSG_TRUNC 501 /*********************************************************************************************/ @@ -724,7 +721,7 @@ _linktype_get_type (NMPlatform *platform, } /* Fallback for drivers that don't call SET_NETDEV_DEVTYPE() */ - if (wifi_utils_is_wifi (ifname)) + if (wifi_utils_is_wifi (ifindex, ifname)) return NM_LINK_TYPE_WIFI; if (arptype == ARPHRD_ETHER) { @@ -1477,12 +1474,18 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr } if (tb[IFLA_STATS64]) { - struct rtnl_link_stats64 *stats = nla_data (tb[IFLA_STATS64]); + /* tb[IFLA_STATS64] is only guaranteed to be 32bit-aligned, + * so in general we can't access the rtnl_link_stats64 struct + * members directly on 64bit architectures. */ + char *stats = nla_data (tb[IFLA_STATS64]); - obj->link.rx_packets = stats->rx_packets; - obj->link.rx_bytes = stats->rx_bytes; - obj->link.tx_packets = stats->tx_packets; - obj->link.tx_bytes = stats->tx_bytes; +#define READ_STAT64(member) \ + unaligned_read_ne64 (stats + offsetof (struct rtnl_link_stats64, member)) + + obj->link.rx_packets = READ_STAT64 (rx_packets); + obj->link.rx_bytes = READ_STAT64 (rx_bytes); + obj->link.tx_packets = READ_STAT64 (tx_packets); + obj->link.tx_bytes = READ_STAT64 (tx_bytes); } obj->link.n_ifi_flags = ifi->ifi_flags; @@ -5144,7 +5147,7 @@ tun_add (NMPlatform *platform, const char *name, gboolean tap, _LOGD ("link: add %s '%s' owner %" G_GINT64_FORMAT " group %" G_GINT64_FORMAT, tap ? "tap" : "tun", name, owner, group); - fd = open ("/dev/net/tun", O_RDWR); + fd = open ("/dev/net/tun", O_RDWR | O_CLOEXEC); if (fd < 0) return FALSE; @@ -5967,6 +5970,23 @@ continue_reading: n = -NLE_AGAIN; } break; + case -NLE_MSG_TRUNC: { + int buf_size; + + /* the message receive buffer was too small. We lost one message, which + * is unfortunate. Try to double the buffer size for the next time. */ + buf_size = nl_socket_get_msg_buf_size (sk); + if (buf_size < 512*1024) { + buf_size *= 2; + _LOGT ("netlink: recvmsg: increase message buffer size for recvmsg() to %d bytes", buf_size); + if (nl_socket_set_msg_buf_size (sk, buf_size) < 0) + nm_assert_not_reached (); + if (!handle_events) + goto continue_reading; + } + n = -_NLE_MSG_TRUNC; + break; + } case -NLE_NOMEM: if (errno == ENOBUFS) { /* we are very much interested in a overrun of the receive buffer. @@ -6155,8 +6175,17 @@ event_handler_read_netlink (NMPlatform *platform, gboolean wait_for_acks) case -NLE_DUMP_INTR: _LOGD ("netlink: read: uncritical failure to retrieve incoming events: %s (%d)", nl_geterror (nle), nle); break; + case -_NLE_MSG_TRUNC: case -_NLE_NM_NOBUFS: - _LOGI ("netlink: read: too many netlink events. Need to resynchronize platform cache"); + _LOGI ("netlink: read: %s. Need to resynchronize platform cache", + ({ + const char *_reason = "unknown"; + switch (nle) { + case -_NLE_MSG_TRUNC: _reason = "message truncated"; break; + case -_NLE_NM_NOBUFS: _reason = "too many netlink events"; break; + } + _reason; + })); event_handler_recvmsgs (platform, FALSE); delayed_action_wait_for_nl_response_complete_all (platform, WAIT_FOR_NL_RESPONSE_RESULT_FAILED_RESYNC); delayed_action_schedule (platform, @@ -6413,6 +6442,12 @@ constructed (GObject *_object) nle = nl_socket_set_buffer_size (priv->nlh, 8*1024*1024, 0); g_assert (!nle); + /* explicitly set the msg buffer size and disable MSG_PEEK. + * If we later encounter NLE_MSG_TRUNC, we will adjust the buffer size. */ + nl_socket_disable_msg_peek (priv->nlh); + nle = nl_socket_set_msg_buf_size (priv->nlh, 32 * 1024); + g_assert (!nle); + nle = nl_socket_add_memberships (priv->nlh, RTNLGRP_LINK, RTNLGRP_IPV4_IFADDR, RTNLGRP_IPV6_IFADDR, diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 068801ee..b939e783 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -31,12 +31,15 @@ #include <linux/mii.h> #include <linux/version.h> #include <linux/rtnetlink.h> +#include <fcntl.h> #include "nm-utils.h" #include "nm-setting-wired.h" #include "nm-core-utils.h" +extern char *if_indextoname (unsigned int __ifindex, char *__ifname); + /****************************************************************** * ethtool ******************************************************************/ @@ -60,7 +63,7 @@ ethtool_get (const char *name, gpointer edata) nm_utils_ifname_cpy (ifr.ifr_name, name); ifr.ifr_data = edata; - fd = socket (PF_INET, SOCK_DGRAM, 0); + fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (fd < 0) { nm_log_err (LOGD_PLATFORM, "ethtool: Could not open socket."); return FALSE; @@ -342,7 +345,7 @@ nmp_utils_mii_supports_carrier_detect (const char *ifname) if (!nmp_utils_device_exists (ifname)) return FALSE; - fd = socket (PF_INET, SOCK_DGRAM, 0); + fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (fd < 0) { nm_log_err (LOGD_PLATFORM, "mii: couldn't open control socket (%s)", ifname); return FALSE; @@ -558,3 +561,83 @@ nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize return buf; } +/** + * nmp_utils_sysctl_open_netdir: + * @ifindex: the ifindex for which to open "/sys/class/net/%s" + * @ifname_guess: (allow-none): optional argument, if present used as initial + * guess as the current name for @ifindex. If guessed right, + * it saves an addtional if_indextoname() call. + * @out_ifname: (allow-none): if present, must be at least IFNAMSIZ + * characters. On success, this will contain the actual ifname + * found while opening the directory. + * + * Returns: a negative value on failure, on success returns the open fd + * to the "/sys/class/net/%s" directory for @ifindex. + */ +int +nmp_utils_sysctl_open_netdir (int ifindex, + const char *ifname_guess, + char *out_ifname) +{ + #define SYS_CLASS_NET "/sys/class/net/" + const char *ifname = ifname_guess; + char ifname_buf_last_try[IFNAMSIZ]; + char ifname_buf[IFNAMSIZ]; + guint try_count = 0; + char sysdir[NM_STRLEN (SYS_CLASS_NET) + IFNAMSIZ] = SYS_CLASS_NET; + char fd_buf[256]; + ssize_t nn; + + g_return_val_if_fail (ifindex >= 0, -1); + + ifname_buf_last_try[0] = '\0'; + + for (try_count = 0; try_count < 10; try_count++, ifname = NULL) { + nm_auto_close int fd_dir = -1; + nm_auto_close int fd_ifindex = -1; + int fd; + + if (!ifname) { + ifname = if_indextoname (ifindex, ifname_buf); + if (!ifname) + return -1; + } + + nm_assert (nm_utils_iface_valid_name (ifname)); + + if (g_strlcpy (&sysdir[NM_STRLEN (SYS_CLASS_NET)], ifname, IFNAMSIZ) >= IFNAMSIZ) + g_return_val_if_reached (-1); + + /* we only retry, if the name changed since previous attempt. + * Hence, it is extremely unlikely that this loop runes until the + * end of the @try_count. */ + if (nm_streq (ifname, ifname_buf_last_try)) + return -1; + strcpy (ifname_buf_last_try, ifname); + + fd_dir = open (sysdir, O_DIRECTORY | O_CLOEXEC); + if (fd_dir < 0) + continue; + + fd_ifindex = openat (fd_dir, "ifindex", O_CLOEXEC); + if (fd_ifindex < 0) + continue; + + nn = nm_utils_fd_read_loop (fd_ifindex, fd_buf, sizeof (fd_buf) - 2, FALSE); + if (nn <= 0) + continue; + fd_buf[nn] = '\0'; + + if (ifindex != _nm_utils_ascii_str_to_int64 (fd_buf, 10, 1, G_MAXINT, -1)) + continue; + + if (out_ifname) + strcpy (out_ifname, ifname); + + fd = fd_dir; + fd_dir = -1; + return fd; + } + + return -1; +} diff --git a/src/platform/nm-platform-utils.h b/src/platform/nm-platform-utils.h index 456c0865..92a06fdf 100644 --- a/src/platform/nm-platform-utils.h +++ b/src/platform/nm-platform-utils.h @@ -60,4 +60,8 @@ NMIPConfigSource nmp_utils_ip_config_source_coerce_from_rtprot (NMIPConfigSource NMIPConfigSource nmp_utils_ip_config_source_round_trip_rtprot (NMIPConfigSource source) _nm_const; const char * nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize len); +int nmp_utils_sysctl_open_netdir (int ifindex, + const char *ifname_guess, + char *out_ifname); + #endif /* __NM_PLATFORM_UTILS_H__ */ diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 9dace699..9274a31d 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -28,11 +28,10 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> -#include <netlink/route/addr.h> -#include <netlink/route/rtnl.h> #include <linux/ip.h> #include <linux/if_tun.h> #include <linux/if_tunnel.h> +#include <linux/rtnetlink.h> #include "nm-utils.h" #include "nm-core-internal.h" diff --git a/src/platform/nmp-netns.c b/src/platform/nmp-netns.c index 26295855..07e134c1 100644 --- a/src/platform/nmp-netns.c +++ b/src/platform/nmp-netns.c @@ -277,7 +277,7 @@ _netns_new (GError **error) int fd_net, fd_mnt; int errsv; - fd_net = open (PROC_SELF_NS_NET, O_RDONLY); + fd_net = open (PROC_SELF_NS_NET, O_RDONLY | O_CLOEXEC); if (fd_net == -1) { errsv = errno; g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, @@ -286,7 +286,7 @@ _netns_new (GError **error) return NULL; } - fd_mnt = open (PROC_SELF_NS_MNT, O_RDONLY); + fd_mnt = open (PROC_SELF_NS_MNT, O_RDONLY | O_CLOEXEC); if (fd_mnt == -1) { errsv = errno; g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, @@ -623,7 +623,7 @@ nmp_netns_bind_to_path (NMPNetns *self, const char *filename, int *out_fd) } if (out_fd) { - if ((fd = open (filename, O_RDONLY)) == -1) { + if ((fd = open (filename, O_RDONLY | O_CLOEXEC)) == -1) { errsv = errno; _LOGE (self, "bind: failed to open %s: %s", filename, g_strerror (errsv)); umount2 (filename, MNT_DETACH); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 30a52c25..993c23d6 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -23,6 +23,7 @@ #include "nmp-object.h" #include <unistd.h> +#include <linux/rtnetlink.h> #include "nm-utils.h" diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index d295f7a0..b6d6709c 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -21,7 +21,6 @@ #ifndef __NMP_OBJECT_H__ #define __NMP_OBJECT_H__ -#include <netlink/netlink.h> #include <gudev/gudev.h> #include "nm-platform.h" diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index b1947a6d..d636ebeb 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -1398,7 +1398,7 @@ nmtstp_namespace_create (int unshare_flags, GError **error) int pipefd_p2c[2]; ssize_t r; - e = pipe (pipefd_c2p); + e = pipe2 (pipefd_c2p, O_CLOEXEC); if (e != 0) { errsv = errno; g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, @@ -1406,7 +1406,7 @@ nmtstp_namespace_create (int unshare_flags, GError **error) return FALSE; } - e = pipe (pipefd_p2c); + e = pipe2 (pipefd_p2c, O_CLOEXEC); if (e != 0) { errsv = errno; g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, @@ -1540,7 +1540,7 @@ nmtstp_namespace_get_fd_for_process (pid_t pid, const char *ns_name) nm_sprintf_buf (p, "/proc/%lu/ns/%s", (long unsigned) pid, ns_name); - return open(p, O_RDONLY); + return open(p, O_RDONLY | O_CLOEXEC); } /*****************************************************************************/ @@ -1564,21 +1564,21 @@ unshare_user (void) /* Since Linux 3.19 we have to disable setgroups() in order to map users. * Just proceed if the file is not there. */ - f = fopen ("/proc/self/setgroups", "w"); + f = fopen ("/proc/self/setgroups", "we"); if (f) { fprintf (f, "deny"); fclose (f); } /* Map current UID to root in NS to be created. */ - f = fopen ("/proc/self/uid_map", "w"); + f = fopen ("/proc/self/uid_map", "we"); if (!f) return FALSE; fprintf (f, "0 %d 1", uid); fclose (f); /* Map current GID to root in NS to be created. */ - f = fopen ("/proc/self/gid_map", "w"); + f = fopen ("/proc/self/gid_map", "we"); if (!f) return FALSE; fprintf (f, "0 %d 1", gid); diff --git a/src/platform/wifi/wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c index 79f217a8..2e222eb8 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 af285b45..d4ed86eb 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); } @@ -577,19 +577,19 @@ wifi_wext_init (const char *iface, int ifindex, gboolean check_scan) wext->parent.set_mesh_channel = wifi_wext_set_mesh_channel; wext->parent.set_mesh_ssid = wifi_wext_set_mesh_ssid; - wext->fd = socket (PF_INET, SOCK_DGRAM, 0); + wext->fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (wext->fd < 0) goto error; 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); @@ -665,7 +665,7 @@ wifi_wext_is_wifi (const char *iface) if (!nmp_utils_device_exists (iface)) return FALSE; - fd = socket (PF_INET, SOCK_DGRAM, 0); + fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (fd >= 0) { nm_utils_ifname_cpy (iwr.ifr_ifrn.ifrn_name, iface); if (ioctl (fd, SIOCGIWNAME, &iwr) == 0) diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c index b7fe86bb..2ce6eb77 100644 --- a/src/platform/wifi/wifi-utils.c +++ b/src/platform/wifi/wifi-utils.c @@ -26,6 +26,7 @@ #include <sys/stat.h> #include <stdio.h> #include <string.h> +#include <fcntl.h> #include "wifi-utils-private.h" #include "wifi-utils-nl80211.h" @@ -34,6 +35,8 @@ #endif #include "nm-core-utils.h" +#include "platform/nm-platform-utils.h" + gpointer wifi_data_new (const char *iface, int ifindex, gsize len) { @@ -180,23 +183,32 @@ wifi_utils_deinit (WifiData *data) } gboolean -wifi_utils_is_wifi (const char *iface) +wifi_utils_is_wifi (int ifindex, const char *ifname) { - char phy80211_path[NM_STRLEN ("/sys/class/net/123456789012345/phy80211\0") + 100 /*safety*/]; - struct stat s; + int fd_sysnet; + int fd_phy80211; + char ifname_verified[IFNAMSIZ]; + + g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (iface != NULL, FALSE); + fd_sysnet = nmp_utils_sysctl_open_netdir (ifindex, ifname, ifname_verified); + if (fd_sysnet < 0) + return FALSE; - nm_sprintf_buf (phy80211_path, - "/sys/class/net/%s/phy80211", - NM_ASSERT_VALID_PATH_COMPONENT (iface)); - nm_assert (strlen (phy80211_path) < sizeof (phy80211_path) - 1); + /* there might have been a race and ifname might be wrong. Below for checking + * wext, use the possibly improved name that we just verified. */ + ifname = ifname_verified; - if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR))) + fd_phy80211 = openat (fd_sysnet, "phy80211", O_CLOEXEC); + close (fd_sysnet); + + if (fd_phy80211 >= 0) { + close (fd_phy80211); return TRUE; + } #if HAVE_WEXT - if (wifi_wext_is_wifi (iface)) + if (wifi_wext_is_wifi (ifname)) return TRUE; #endif diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h index 8e2b93f1..3dca2ac1 100644 --- a/src/platform/wifi/wifi-utils.h +++ b/src/platform/wifi/wifi-utils.h @@ -28,7 +28,7 @@ typedef struct WifiData WifiData; -gboolean wifi_utils_is_wifi (const char *iface); +gboolean wifi_utils_is_wifi (int ifindex, const char *ifname); WifiData *wifi_utils_init (const char *iface, int ifindex, gboolean check_scan); diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index a51f7cfa..34c550fa 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -197,7 +197,7 @@ monitor_cb (gpointer user_data) if (errno != ENODEV) _LOGW ("could not read ppp stats: %s", strerror (errno)); } else { - g_signal_emit (manager, signals[STATS], 0, + g_signal_emit (manager, signals[STATS], 0, stats.p.ppp_ibytes, stats.p.ppp_obytes); } @@ -214,7 +214,7 @@ monitor_stats (NMPPPManager *manager) if (priv->monitor_fd >= 0) return; - priv->monitor_fd = socket (AF_INET, SOCK_DGRAM, 0); + priv->monitor_fd = socket (AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (priv->monitor_fd >= 0) { g_warn_if_fail (priv->monitor_id == 0); if (priv->monitor_id) @@ -595,7 +595,7 @@ nm_ppp_manager_class_init (NMPPPManagerClass *manager_class) g_type_class_add_private (manager_class, sizeof (NMPPPManagerPrivate)); - exported_object_class->export_path = NM_DBUS_PATH "/PPP"; + exported_object_class->export_path = NM_DBUS_PATH "/PPP/%u"; exported_object_class->export_on_construction = TRUE; object_class->dispose = dispose; @@ -834,6 +834,7 @@ create_pppd_cmd_line (NMPPPManager *self, NMSettingPppoe *pppoe, NMSettingAdsl *adsl, const char *ppp_name, + guint baud_override, GError **err) { NMPPPManagerPrivate *priv = NM_PPP_MANAGER_GET_PRIVATE (self); @@ -925,6 +926,8 @@ create_pppd_cmd_line (NMPPPManager *self, if (nm_setting_ppp_get_baud (setting)) nm_cmd_line_add_int (cmd, nm_setting_ppp_get_baud (setting)); + else if (baud_override) + nm_cmd_line_add_int (cmd, (int) baud_override); /* noauth by default, because we certainly don't have any information * with which to verify anything the peer gives us if we ask it to @@ -1023,6 +1026,7 @@ nm_ppp_manager_start (NMPPPManager *manager, NMActRequest *req, const char *ppp_name, guint32 timeout_secs, + guint baud_override, GError **err) { NMPPPManagerPrivate *priv; @@ -1076,7 +1080,7 @@ nm_ppp_manager_start (NMPPPManager *manager, adsl_setting = (NMSettingAdsl *) nm_connection_get_setting (connection, NM_TYPE_SETTING_ADSL); - ppp_cmd = create_pppd_cmd_line (manager, s_ppp, pppoe_setting, adsl_setting, ppp_name, err); + ppp_cmd = create_pppd_cmd_line (manager, s_ppp, pppoe_setting, adsl_setting, ppp_name, baud_override, err); if (!ppp_cmd) goto out; diff --git a/src/ppp-manager/nm-ppp-manager.h b/src/ppp-manager/nm-ppp-manager.h index 188be84e..9a8b13dc 100644 --- a/src/ppp-manager/nm-ppp-manager.h +++ b/src/ppp-manager/nm-ppp-manager.h @@ -69,6 +69,7 @@ gboolean nm_ppp_manager_start (NMPPPManager *manager, NMActRequest *req, const char *ppp_name, guint32 timeout_secs, + guint baud_override, GError **err); void nm_ppp_manager_stop (NMPPPManager *manager, diff --git a/src/settings/nm-inotify-helper.c b/src/settings/nm-inotify-helper.c index ce15246c..46112648 100644 --- a/src/settings/nm-inotify-helper.c +++ b/src/settings/nm-inotify-helper.c @@ -128,7 +128,7 @@ init_inotify (NMInotifyHelper *self) GIOChannel *channel; guint source_id; - priv->ifd = inotify_init (); + priv->ifd = inotify_init1 (IN_CLOEXEC); if (priv->ifd == -1) { int errsv = errno; diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 1f691c0b..cd54e52c 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); diff --git a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c index 184e95b2..a83bd35d 100644 --- a/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c +++ b/src/settings/plugins/ifcfg-rh/nm-ifcfg-connection.c @@ -106,7 +106,7 @@ devtimeout_ready (gpointer user_data) } static void -link_changed (NMPlatform *platform, NMPObjectType *obj_type, int ifindex, const NMPlatformLink *link, +link_changed (NMPlatform *platform, NMPObjectType obj_type, int ifindex, const NMPlatformLink *link, NMPlatformSignalChangeType change_type, NMConnection *self) { @@ -117,7 +117,6 @@ link_changed (NMPlatform *platform, NMPObjectType *obj_type, int ifindex, const if (g_strcmp0 (link->name, ifname) != 0) return; - /* Shouldn't happen, but... */ if (change_type == NM_PLATFORM_SIGNAL_REMOVED) return; diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index 75b19d53..a865c7df 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -53,11 +53,11 @@ svOpenFileInternal (const char *name, gboolean create, GError **error) s->fd = -1; if (create) - s->fd = open (name, O_RDWR); /* NOT O_CREAT */ + s->fd = open (name, O_RDWR | O_CLOEXEC); /* NOT O_CREAT */ if (!create || s->fd == -1) { /* try read-only */ - s->fd = open (name, O_RDONLY); /* NOT O_CREAT */ + s->fd = open (name, O_RDONLY | O_CLOEXEC); /* NOT O_CREAT */ if (s->fd == -1) errsv = errno; else @@ -461,7 +461,7 @@ svWriteFile (shvarFile *s, int mode, GError **error) if (s->modified) { if (s->fd == -1) - s->fd = open (s->fileName, O_WRONLY | O_CREAT, mode); + s->fd = open (s->fileName, O_WRONLY | O_CREAT | O_CLOEXEC, mode); if (s->fd == -1) { int errsv = errno; diff --git a/src/settings/plugins/ifupdown/interface_parser.c b/src/settings/plugins/ifupdown/interface_parser.c index 764ba5c9..3386a6ba 100644 --- a/src/settings/plugins/ifupdown/interface_parser.c +++ b/src/settings/plugins/ifupdown/interface_parser.c @@ -117,7 +117,7 @@ _recursive_ifparser (const char *eni_file, int quiet) nm_log_warn (LOGD_SETTINGS, "interfaces file %s doesn't exist\n", eni_file); return; } - inp = fopen (eni_file, "r"); + inp = fopen (eni_file, "re"); if (inp == NULL) { if (!quiet) nm_log_warn (LOGD_SETTINGS, "Can't open %s\n", eni_file); diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 626472d0..05d9aa67 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -1288,6 +1288,7 @@ nm_supplicant_interface_set_config (NMSupplicantInterface *self, g_clear_object (&priv->cfg); if (cfg) { + priv->assoc_cancellable = g_cancellable_new (); priv->cfg = g_object_ref (cfg); g_dbus_proxy_call (priv->iface_proxy, DBUS_INTERFACE_PROPERTIES ".Set", @@ -1525,13 +1526,9 @@ dispose (GObject *object) g_signal_handlers_disconnect_by_data (priv->iface_proxy, NM_SUPPLICANT_INTERFACE (object)); g_clear_object (&priv->iface_proxy); - if (priv->init_cancellable) - g_cancellable_cancel (priv->init_cancellable); - g_clear_object (&priv->init_cancellable); - - if (priv->other_cancellable) - g_cancellable_cancel (priv->other_cancellable); - g_clear_object (&priv->other_cancellable); + nm_clear_g_cancellable (&priv->init_cancellable); + nm_clear_g_cancellable (&priv->other_cancellable); + nm_clear_g_cancellable (&priv->assoc_cancellable); g_clear_object (&priv->wpas_proxy); g_clear_pointer (&priv->bss_proxies, (GDestroyNotify) g_hash_table_destroy); diff --git a/src/tests/test-general-with-expect.c b/src/tests/test-general-with-expect.c index ab2b15b5..f04c147f 100644 --- a/src/tests/test-general-with-expect.c +++ b/src/tests/test-general-with-expect.c @@ -26,6 +26,7 @@ #include <netinet/ether.h> #include <sys/types.h> #include <sys/wait.h> +#include <fcntl.h> #include "NetworkManagerUtils.h" #include "nm-multi-index.h" @@ -173,7 +174,7 @@ test_nm_utils_kill_child_create_and_join_pgroup (void) int pipefd[2]; pid_t pgid; - err = pipe (pipefd); + err = pipe2 (pipefd, O_CLOEXEC); g_assert (err == 0); pgid = fork(); diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c index 3eceec0c..de890141 100644 --- a/src/tests/test-ip6-config.c +++ b/src/tests/test-ip6-config.c @@ -238,10 +238,13 @@ test_nm_ip6_config_addresses_sort_check (NMIP6Config *config, NMSettingIP6Config { int addr_count = nm_ip6_config_get_num_addresses (config); int i, irepeat; - NMIP6Config *copy = nmtst_ip6_config_clone (config); - NMIP6Config *copy2 = nmtst_ip6_config_clone (config); + NMIP6Config *copy, *copy2; int *idx = g_new (int, addr_count); + nm_ip6_config_set_privacy (config, use_tempaddr); + copy = nmtst_ip6_config_clone (config); + copy2 = nmtst_ip6_config_clone (config); + /* initialize the array of indeces, and keep shuffling them for every @repeat iteration. */ for (i = 0; i < addr_count; i++) idx[i] = i; @@ -257,7 +260,7 @@ test_nm_ip6_config_addresses_sort_check (NMIP6Config *config, NMSettingIP6Config } /* reorder them again */ - nm_ip6_config_addresses_sort (copy, use_tempaddr); + nm_ip6_config_addresses_sort (copy); /* check equality using nm_ip6_config_equal() */ if (!nm_ip6_config_equal (copy, config)) { diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 69b45dcc..1441c3c6 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -1369,6 +1369,11 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) if (priv->vpn_state == STATE_CONNECT) _set_vpn_state (self, STATE_IP_CONFIG_GET, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE); + if (priv->vpn_state > STATE_ACTIVATED) { + _LOGI ("VPN connection: (IP4 Config Get) ignoring, the connection is no longer active"); + return; + } + if (priv->has_ip4) { _LOGI ("VPN connection: (IP4 Config Get) reply received"); @@ -1538,6 +1543,11 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) if (priv->vpn_state == STATE_CONNECT) _set_vpn_state (self, STATE_IP_CONFIG_GET, NM_VPN_CONNECTION_STATE_REASON_NONE, FALSE); + if (priv->vpn_state > STATE_ACTIVATED) { + _LOGI ("VPN connection: (IP6 Config Get) ignoring, the connection is no longer active"); + return; + } + if (g_variant_n_children (dict) == 0) { priv->has_ip6 = FALSE; nm_vpn_connection_config_maybe_complete (self, TRUE); |