From bfe522304da217296e2a61040f58e35ec5d6f3f2 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Mon, 16 Aug 2021 09:51:46 +0200 Subject: New upstream version 1.30.6 --- src/core/devices/bluetooth/nm-bluez-manager.c | 2 + src/core/devices/nm-acd-manager.c | 11 +- src/core/devices/nm-device-bond.c | 42 +++++-- src/core/devices/nm-device-ethernet.c | 4 +- src/core/devices/nm-device.c | 147 ++++++++++--------------- src/core/devices/nm-device.h | 35 +++--- src/core/devices/ovs/nm-device-ovs-interface.c | 10 ++ src/core/devices/wifi/nm-device-iwd.c | 15 ++- src/core/devices/wifi/nm-device-wifi.c | 8 ++ src/core/devices/wifi/nm-iwd-manager.c | 1 + src/core/devices/wwan/nm-modem-broadband.c | 10 +- 11 files changed, 163 insertions(+), 122 deletions(-) (limited to 'src/core/devices') diff --git a/src/core/devices/bluetooth/nm-bluez-manager.c b/src/core/devices/bluetooth/nm-bluez-manager.c index dd998d29..459ea409 100644 --- a/src/core/devices/bluetooth/nm-bluez-manager.c +++ b/src/core/devices/bluetooth/nm-bluez-manager.c @@ -2879,6 +2879,8 @@ dispose(GObject *object) g_clear_object(&priv->dbus_connection); nm_clear_pointer(&priv->bzobjs, g_hash_table_destroy); + nm_clear_pointer(&priv->conn_data_heads, g_hash_table_destroy); + nm_clear_pointer(&priv->conn_data_elems, g_hash_table_destroy); } static void diff --git a/src/core/devices/nm-acd-manager.c b/src/core/devices/nm-acd-manager.c index b95f90fd..81a28797 100644 --- a/src/core/devices/nm-acd-manager.c +++ b/src/core/devices/nm-acd-manager.c @@ -188,6 +188,7 @@ acd_event(int fd, GIOCondition condition, gpointer data) char to_string_buffer[ACD_EVENT_TO_STRING_BUF_SIZE]; gs_free char *hwaddr_str = NULL; gboolean check_probing_done = FALSE; + char buf[ETH_ALEN * 3]; switch (event->event) { case N_ACD_EVENT_READY: @@ -202,8 +203,9 @@ acd_event(int fd, GIOCondition condition, gpointer data) nm_platform_link_get_name(NM_PLATFORM_GET, self->ifindex), acd_error_to_string(r)); } else { - _LOGD("announcing address %s", - _nm_utils_inet4_ntop(info->address, address_str)); + _LOGD("announcing address %s (hw-addr %s)", + _nm_utils_inet4_ntop(info->address, address_str), + _nm_utils_hwaddr_ntoa(self->hwaddr, ETH_ALEN, TRUE, buf, sizeof(buf))); } } check_probing_done = TRUE; @@ -394,6 +396,7 @@ nm_acd_manager_announce_addresses(NMAcdManager *self) int r; int fd; gboolean success = TRUE; + char buf[ETH_ALEN * 3]; r = acd_init(self); if (r) { @@ -428,7 +431,9 @@ nm_acd_manager_announce_addresses(NMAcdManager *self) acd_error_to_string(r)); success = FALSE; } else - _LOGD("announcing address %s", _nm_utils_inet4_ntop(info->address, sbuf)); + _LOGD("announcing address %s (hw-addr %s)", + _nm_utils_inet4_ntop(info->address, sbuf), + _nm_utils_hwaddr_ntoa(self->hwaddr, ETH_ALEN, TRUE, buf, sizeof(buf))); } } diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c index f68c080b..9c1c484f 100644 --- a/src/core/devices/nm-device-bond.c +++ b/src/core/devices/nm-device-bond.c @@ -34,7 +34,7 @@ NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, \ NM_SETTING_BOND_OPTION_RESEND_IGMP, NM_SETTING_BOND_OPTION_TLB_DYNAMIC_LB, \ NM_SETTING_BOND_OPTION_USE_CARRIER, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, \ - NM_SETTING_BOND_OPTION_NUM_GRAT_ARP + NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY #define OPTIONS_REAPPLY_SUBSET \ NM_SETTING_BOND_OPTION_MIIMON, NM_SETTING_BOND_OPTION_UPDELAY, \ @@ -46,7 +46,7 @@ NM_SETTING_BOND_OPTION_MIN_LINKS, NM_SETTING_BOND_OPTION_PACKETS_PER_SLAVE, \ NM_SETTING_BOND_OPTION_PRIMARY_RESELECT, NM_SETTING_BOND_OPTION_RESEND_IGMP, \ NM_SETTING_BOND_OPTION_USE_CARRIER, NM_SETTING_BOND_OPTION_XMIT_HASH_POLICY, \ - NM_SETTING_BOND_OPTION_NUM_GRAT_ARP + NM_SETTING_BOND_OPTION_NUM_GRAT_ARP, NM_SETTING_BOND_OPTION_PEER_NOTIF_DELAY #define OPTIONS_REAPPLY_FULL \ OPTIONS_REAPPLY_SUBSET, NM_SETTING_BOND_OPTION_ACTIVE_SLAVE, \ @@ -109,6 +109,24 @@ _set_bond_attr(NMDevice *device, const char *attr, const char *value) int ifindex = nm_device_get_ifindex(device); gboolean ret; + nm_assert(attr && attr[0]); + nm_assert(value); + + if (nm_streq(value, NM_BOND_AD_ACTOR_SYSTEM_DEFAULT) + && nm_streq(attr, NM_SETTING_BOND_OPTION_AD_ACTOR_SYSTEM)) { + gs_free char *cur_val = NULL; + + /* kernel does not allow setting ad_actor_system to "00:00:00:00:00:00". We would thus + * log an EINVAL error. Avoid that... at least, if the value is already "00:00:00:00:00:00". */ + cur_val = + nm_platform_sysctl_master_get_option(nm_device_get_platform(device), ifindex, attr); + if (nm_streq0(cur_val, NM_BOND_AD_ACTOR_SYSTEM_DEFAULT)) + return TRUE; + + /* OK, the current value is different, and we will proceed setting "00:00:00:00:00:00". + * That will fail, and we will log a warning. There is nothing else to do. */ + } + ret = nm_platform_sysctl_master_set_option(nm_device_get_platform(device), ifindex, attr, value); if (!ret) @@ -426,9 +444,10 @@ release_slave(NMDevice *device, NMDevice *slave, gboolean configure) _LOGD(LOGD_BOND, "bond slave %s is already released", nm_device_get_ip_iface(slave)); if (configure) { - /* When the last slave is released the bond MAC will be set to a random - * value by kernel; remember the current one and restore it afterwards. - */ + NMConnection * applied; + NMSettingWired *s_wired; + const char * cloned_mac; + address = g_strdup(nm_device_get_hw_address(device)); if (ifindex_slave > 0) { @@ -443,9 +462,16 @@ release_slave(NMDevice *device, NMDevice *slave, gboolean configure) } } - nm_platform_process_events(nm_device_get_platform(device)); - if (nm_device_update_hw_address(device)) - nm_device_hw_addr_set(device, address, "restore", FALSE); + if ((applied = nm_device_get_applied_connection(device)) + && ((s_wired = nm_connection_get_setting_wired(applied))) + && ((cloned_mac = nm_setting_wired_get_cloned_mac_address(s_wired)))) { + /* When the last slave is released the bond MAC will be set to a random + * value by kernel; if we have set a cloned-mac-address, we need to + * restore it to the previous value. */ + nm_platform_process_events(nm_device_get_platform(device)); + if (nm_device_update_hw_address(device)) + nm_device_hw_addr_set(device, address, "restore", FALSE); + } /* Kernel bonding code "closes" the slave when releasing it, (which clears * IFF_UP), so we must bring it back up here to ensure carrier changes and diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c index 44428869..59f6c613 100644 --- a/src/core/devices/nm-device-ethernet.c +++ b/src/core/devices/nm-device-ethernet.c @@ -730,7 +730,9 @@ supplicant_iface_state_cb(NMSupplicantInterface *iface, if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { supplicant_interface_release(self); - wired_auth_cond_fail(self, NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); + nm_device_state_changed(NM_DEVICE(self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED); return; } diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 040dd0b4..3874e586 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -125,7 +125,6 @@ typedef struct { typedef struct { NMDevice *device; guint idle_add_id; - int ifindex; } DeleteOnDeactivateData; typedef struct { @@ -4703,10 +4702,6 @@ nm_device_master_enslave_slave(NMDevice *self, NMDevice *slave, NMConnection *co */ nm_device_update_hw_address(self); - /* Send ARP announcements if did not yet and have addresses. */ - if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE && !priv->acd.announcing) - nm_device_arp_announce(self); - /* Restart IP configuration if we're waiting for slaves. Do this * after updating the hardware address as IP config may need the * new address. @@ -5053,6 +5048,10 @@ nm_device_set_carrier(NMDevice *self, gboolean carrier) nm_device_remove_pending_action(self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); _carrier_wait_check_queued_act_request(self); } + + /* Send ARP announcements if did not yet and have carrier. */ + if (priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE && !priv->acd.announcing) + nm_device_arp_announce(self); } else { if (priv->carrier_wait_id) nm_device_add_pending_action(self, NM_PENDING_ACTION_CARRIER_WAIT, FALSE); @@ -5415,11 +5414,11 @@ device_link_changed(NMDevice *self) /* Ensure the assume check is queued before any queued state changes * from the transition to UNAVAILABLE. */ - nm_device_queue_recheck_assume(self); reason = NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED; } } + nm_device_queue_recheck_assume(self); nm_device_set_unmanaged_by_flags(self, NM_UNMANAGED_PLATFORM_INIT, FALSE, reason); } @@ -8362,26 +8361,23 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode) static gboolean tc_commit(NMDevice *self) { - NMConnection * connection = NULL; gs_unref_ptrarray GPtrArray *qdiscs = NULL; gs_unref_ptrarray GPtrArray *tfilters = NULL; - NMSettingTCConfig * s_tc = NULL; + NMSettingTCConfig * s_tc; NMPlatform * platform; int ip_ifindex; - platform = nm_device_get_platform(self); - connection = nm_device_get_applied_connection(self); - if (connection) - s_tc = nm_connection_get_setting_tc_config(connection); + s_tc = nm_device_get_applied_setting(self, NM_TYPE_SETTING_TC_CONFIG); + if (!s_tc) + return TRUE; ip_ifindex = nm_device_get_ip_ifindex(self); if (!ip_ifindex) - return s_tc == NULL; + return FALSE; - if (s_tc) { - qdiscs = nm_utils_qdiscs_from_tc_setting(platform, s_tc, ip_ifindex); - tfilters = nm_utils_tfilters_from_tc_setting(platform, s_tc, ip_ifindex); - } + platform = nm_device_get_platform(self); + qdiscs = nm_utils_qdiscs_from_tc_setting(platform, s_tc, ip_ifindex); + tfilters = nm_utils_tfilters_from_tc_setting(platform, s_tc, ip_ifindex); if (!nm_platform_qdisc_sync(platform, ip_ifindex, qdiscs)) return FALSE; @@ -9980,7 +9976,9 @@ nm_device_request_ip6_prefixes(NMDevice *self, int needed_prefixes) _LOGD(LOGD_IP6, "ipv6-pd: asking DHCPv6 for %d prefixes", needed_prefixes); nm_device_dhcp6_renew(self, FALSE); } else { - _LOGI(LOGD_IP6, "ipv6-pd: device doesn't use DHCPv6, can't request prefixes"); + priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_OTHERCONF; + _LOGD(LOGD_DEVICE | LOGD_DHCP6, "ipv6-pd: starting DHCPv6 to request a prefix"); + dhcp6_start(self, FALSE); } } @@ -11679,8 +11677,6 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error) nm_utils_share_rules_add_all_rules(share_rules, ip_iface, ip4_addr->address, ip4_addr->plen); - nm_utils_share_rules_apply(share_rules, TRUE); - nm_act_request_set_shared(req, share_rules); conn = nm_act_request_get_applied_connection(req); @@ -11792,7 +11788,6 @@ activate_stage5_ip_config_result_x(NMDevice *self, int addr_family) const char * method; int ip_ifindex; int errsv; - gboolean do_announce = FALSE; req = nm_device_get_act_request(self); g_assert(req); @@ -11918,31 +11913,13 @@ activate_stage5_ip_config_result_x(NMDevice *self, int addr_family) } } - if (IS_IPv4) { - /* Send ARP announcements */ - - if (nm_device_is_master(self)) { - CList * iter; - SlaveInfo *info; - - /* Skip announcement if there are no device enslaved, for two reasons: - * 1) the master has a temporary MAC address until the first slave comes - * 2) announcements are going to be dropped anyway without slaves - */ - do_announce = FALSE; - - c_list_for_each (iter, &priv->slaves) { - info = c_list_entry(iter, SlaveInfo, lst_slave); - if (info->slave_is_enslaved) { - do_announce = TRUE; - break; - } - } - } else - do_announce = TRUE; - - if (do_announce) - nm_device_arp_announce(self); + if (IS_IPv4 && priv->carrier) { + /* We send ARP announcements only when the link gets carrier, + * otherwise the announcements would be lost. Furthermore, for + * controllers having carrier implies that there is at least one + * port and therefore the MAC address is the correct one. + */ + nm_device_arp_announce(self); } if (IS_IPv4) { @@ -12141,28 +12118,19 @@ nm_device_is_nm_owned(NMDevice *self) static gboolean delete_on_deactivate_link_delete(gpointer user_data) { - DeleteOnDeactivateData *data = user_data; - NMDevice * self = data->device; + DeleteOnDeactivateData *data = user_data; + nm_auto_unref_object NMDevice *self = data->device; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + gs_free_error GError *error = NULL; _LOGD(LOGD_DEVICE, - "delete_on_deactivate: cleanup and delete virtual link #%d (id=%u)", - data->ifindex, + "delete_on_deactivate: cleanup and delete virtual link (id=%u)", data->idle_add_id); - if (data->device) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(data->device); - gs_free_error GError *error = NULL; - - g_object_remove_weak_pointer(G_OBJECT(data->device), (void **) &data->device); - priv->delete_on_deactivate_data = NULL; + priv->delete_on_deactivate_data = NULL; - if (!nm_device_unrealize(data->device, TRUE, &error)) - _LOGD(LOGD_DEVICE, - "delete_on_deactivate: unrealizing %d failed (%s)", - data->ifindex, - error->message); - } else if (data->ifindex > 0) - nm_platform_link_delete(nm_device_get_platform(self), data->ifindex); + if (!nm_device_unrealize(self, TRUE, &error)) + _LOGD(LOGD_DEVICE, "delete_on_deactivate: unrealizing failed (%s)", error->message); nm_device_emit_recheck_auto_activate(self); @@ -12181,17 +12149,16 @@ delete_on_deactivate_unschedule(NMDevice *self) priv->delete_on_deactivate_data = NULL; g_source_remove(data->idle_add_id); - g_object_remove_weak_pointer(G_OBJECT(self), (void **) &data->device); _LOGD(LOGD_DEVICE, - "delete_on_deactivate: cancel cleanup and delete virtual link #%d (id=%u)", - data->ifindex, + "delete_on_deactivate: cancel cleanup and delete virtual link (id=%u)", data->idle_add_id); + g_object_unref(data->device); g_free(data); } } static void -delete_on_deactivate_check_and_schedule(NMDevice *self, int ifindex) +delete_on_deactivate_check_and_schedule(NMDevice *self) { NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); DeleteOnDeactivateData *data; @@ -12208,16 +12175,13 @@ delete_on_deactivate_check_and_schedule(NMDevice *self, int ifindex) return; delete_on_deactivate_unschedule(self); /* always cancel and reschedule */ - data = g_new(DeleteOnDeactivateData, 1); - g_object_add_weak_pointer(G_OBJECT(self), (void **) &data->device); - data->device = self; - data->ifindex = ifindex; + data = g_new(DeleteOnDeactivateData, 1); + data->device = g_object_ref(self); data->idle_add_id = g_idle_add(delete_on_deactivate_link_delete, data); priv->delete_on_deactivate_data = data; _LOGD(LOGD_DEVICE, - "delete_on_deactivate: schedule cleanup and delete virtual link #%d (id=%u)", - ifindex, + "delete_on_deactivate: schedule cleanup and delete virtual link (id=%u)", data->idle_add_id); } @@ -13478,12 +13442,13 @@ nm_device_set_ip_config(NMDevice * self, gboolean commit, GPtrArray * ip4_dev_route_blacklist) { - NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); - const int IS_IPv4 = NM_IS_IPv4(addr_family); - NMIPConfig * old_config; - gboolean has_changes = FALSE; - gboolean success = TRUE; - NMSettingsConnection *settings_connection; + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + const int IS_IPv4 = NM_IS_IPv4(addr_family); + NMIPConfig * old_config; + gboolean has_changes = FALSE; + gboolean success = TRUE; + NMSettingsConnection * settings_connection; + NMIPRouteTableSyncMode route_table_sync_mode; nm_assert_addr_family(addr_family); nm_assert(!new_config || nm_ip_config_get_addr_family(new_config) == addr_family); @@ -13495,11 +13460,18 @@ nm_device_set_ip_config(NMDevice * self, }))); nm_assert(IS_IPv4 || !ip4_dev_route_blacklist); + if (commit && new_config) + route_table_sync_mode = _get_route_table_sync_mode_stateful(self, addr_family); + else + route_table_sync_mode = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE; + _LOGD(LOGD_IPX(IS_IPv4), - "ip%c-config: update (commit=%d, new-config=%p)", + "ip%c-config: update (commit=%d, new-config=" NM_HASH_OBFUSCATE_PTR_FMT + ", route-table-sync-mode=%d)", nm_utils_addr_family_to_char(addr_family), commit, - new_config); + NM_HASH_OBFUSCATE_PTR(new_config), + (int) route_table_sync_mode); /* Always commit to nm-platform to update lifetimes */ if (commit && new_config) { @@ -13508,7 +13480,7 @@ nm_device_set_ip_config(NMDevice * self, if (IS_IPv4) { success = nm_ip4_config_commit(NM_IP4_CONFIG(new_config), nm_device_get_platform(self), - _get_route_table_sync_mode_stateful(self, AF_INET)); + route_table_sync_mode); nm_platform_ip4_dev_route_blacklist_set(nm_device_get_platform(self), nm_ip_config_get_ifindex(new_config), ip4_dev_route_blacklist); @@ -13517,7 +13489,7 @@ nm_device_set_ip_config(NMDevice * self, success = nm_ip6_config_commit(NM_IP6_CONFIG(new_config), nm_device_get_platform(self), - _get_route_table_sync_mode_stateful(self, AF_INET6), + route_table_sync_mode, &temporary_not_available); if (!_rt6_temporary_not_available_set(self, temporary_not_available)) @@ -15846,7 +15818,7 @@ _cleanup_generic_post(NMDevice *self, CleanupType cleanup_type) /* Check if the device was deactivated, and if so, delete_link. * Don't call delete_link synchronously because we are currently * handling a state change -- which is not reentrant. */ - delete_on_deactivate_check_and_schedule(self, nm_device_get_ip_ifindex(self)); + delete_on_deactivate_check_and_schedule(self); } /* ip_iface should be cleared after flushing all routes and addresses, since @@ -15906,9 +15878,12 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu nm_platform_ip_route_flush(platform, AF_UNSPEC, ifindex); nm_platform_ip_address_flush(platform, AF_UNSPEC, ifindex); - nm_platform_tfilter_sync(platform, ifindex, NULL); - nm_platform_qdisc_sync(platform, ifindex, NULL); set_ipv6_token(self, iid, "::"); + + if (nm_device_get_applied_setting(self, NM_TYPE_SETTING_TC_CONFIG)) { + nm_platform_tfilter_sync(platform, ifindex, NULL); + nm_platform_qdisc_sync(platform, ifindex, NULL); + } } } diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h index 72777d0a..68343ef5 100644 --- a/src/core/devices/nm-device.h +++ b/src/core/devices/nm-device.h @@ -627,27 +627,28 @@ void nm_device_copy_ip6_dns_config(NMDevice *self, NMDevice *from_device); * setting the NM_UNMANAGED_IS_SLAVE to %TRUE makes no sense, this flag has only * meaning to set a slave device as managed if the parent is managed too. */ -typedef enum { /*< skip >*/ - NM_UNMANAGED_NONE = 0, +typedef enum { + NM_UNMANAGED_NONE = 0, - /* these flags are authoritative. If one of them is set, + /* these flags are authoritative. If one of them is set, * the device cannot be managed. */ - NM_UNMANAGED_SLEEPING = (1LL << 0), - NM_UNMANAGED_QUITTING = (1LL << 1), - NM_UNMANAGED_PARENT = (1LL << 2), - NM_UNMANAGED_BY_TYPE = (1LL << 3), - NM_UNMANAGED_PLATFORM_INIT = (1LL << 4), - NM_UNMANAGED_USER_EXPLICIT = (1LL << 5), - NM_UNMANAGED_USER_SETTINGS = (1LL << 6), - - /* These flags can be non-effective and be overwritten + NM_UNMANAGED_SLEEPING = (1LL << 0), + NM_UNMANAGED_QUITTING = (1LL << 1), + NM_UNMANAGED_PARENT = (1LL << 2), + NM_UNMANAGED_BY_TYPE = (1LL << 3), + NM_UNMANAGED_PLATFORM_INIT = (1LL << 4), + NM_UNMANAGED_USER_EXPLICIT = (1LL << 5), + NM_UNMANAGED_USER_SETTINGS = (1LL << 6), + + /* These flags can be non-effective and be overwritten * by other flags. */ - NM_UNMANAGED_BY_DEFAULT = (1LL << 8), - NM_UNMANAGED_USER_CONF = (1LL << 9), - NM_UNMANAGED_USER_UDEV = (1LL << 10), - NM_UNMANAGED_EXTERNAL_DOWN = (1LL << 11), - NM_UNMANAGED_IS_SLAVE = (1LL << 12), + NM_UNMANAGED_BY_DEFAULT = (1LL << 7), + NM_UNMANAGED_USER_CONF = (1LL << 8), + NM_UNMANAGED_USER_UDEV = (1LL << 9), + NM_UNMANAGED_EXTERNAL_DOWN = (1LL << 10), + NM_UNMANAGED_IS_SLAVE = (1LL << 11), + NM_UNMANAGED_ALL = ((1LL << 12) - 1), } NMUnmanagedFlags; typedef enum { diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c index 5d07c211..0a537f7a 100644 --- a/src/core/devices/ovs/nm-device-ovs-interface.c +++ b/src/core/devices/ovs/nm-device-ovs-interface.c @@ -77,6 +77,15 @@ is_available(NMDevice *device, NMDeviceCheckDevAvailableFlags flags) return nm_ovsdb_is_ready(priv->ovsdb); } +static gboolean +can_auto_connect(NMDevice *device, NMSettingsConnection *sett_conn, char **specific_object) +{ + NMDeviceOvsInterface * self = NM_DEVICE_OVS_INTERFACE(device); + NMDeviceOvsInterfacePrivate *priv = NM_DEVICE_OVS_INTERFACE_GET_PRIVATE(self); + + return nm_ovsdb_is_ready(priv->ovsdb); +} + static gboolean check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { @@ -427,6 +436,7 @@ nm_device_ovs_interface_class_init(NMDeviceOvsInterfaceClass *klass) device_class->connection_type_check_compatible = NM_SETTING_OVS_INTERFACE_SETTING_NAME; device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_OPENVSWITCH); + device_class->can_auto_connect = can_auto_connect; device_class->can_update_from_platform_link = can_update_from_platform_link; device_class->deactivate = deactivate; device_class->deactivate_async = deactivate_async; diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c index 95ade44b..01f2a303 100644 --- a/src/core/devices/wifi/nm-device-iwd.c +++ b/src/core/devices/wifi/nm-device-iwd.c @@ -588,10 +588,16 @@ deactivate(NMDevice *device) return; } - cleanup_association_attempt(self, TRUE); + cleanup_association_attempt(self, FALSE); priv->act_mode_switch = FALSE; - if (!priv->dbus_station_proxy) + /* Don't trigger any actions on the IWD side until the device is managed */ + if (priv->iwd_autoconnect && nm_device_get_state(device) < NM_DEVICE_STATE_DISCONNECTED) + return; + + if (priv->dbus_station_proxy) + send_disconnect(self); + else reset_mode(self, NULL, NULL, NULL); } @@ -647,6 +653,11 @@ deactivate_async(NMDevice * device, cleanup_association_attempt(self, FALSE); priv->act_mode_switch = FALSE; + if (priv->iwd_autoconnect && nm_device_get_state(device) < NM_DEVICE_STATE_DISCONNECTED) { + nm_utils_invoke_on_idle(cancellable, disconnect_cb_on_idle, user_data); + return; + } + if (priv->dbus_station_proxy) { g_dbus_proxy_call(priv->dbus_station_proxy, "Disconnect", diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c index 042d4887..c9655eea 100644 --- a/src/core/devices/wifi/nm-device-wifi.c +++ b/src/core/devices/wifi/nm-device-wifi.c @@ -2565,6 +2565,7 @@ supplicant_iface_notify_current_bss(NMSupplicantInterface *iface, NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); NMRefString * current_bss; NMWifiAP * new_ap = NULL; + NMActRequest * req; current_bss = nm_supplicant_interface_get_current_bss(iface); if (current_bss) @@ -2612,6 +2613,13 @@ supplicant_iface_notify_current_bss(NMSupplicantInterface *iface, } set_current_ap(self, new_ap, TRUE); + + req = nm_device_get_act_request(NM_DEVICE(self)); + if (req) { + nm_active_connection_set_specific_object( + NM_ACTIVE_CONNECTION(req), + new_ap ? nm_dbus_object_get_path(NM_DBUS_OBJECT(new_ap)) : NULL); + } } } diff --git a/src/core/devices/wifi/nm-iwd-manager.c b/src/core/devices/wifi/nm-iwd-manager.c index b4b019d3..68a74438 100644 --- a/src/core/devices/wifi/nm-iwd-manager.c +++ b/src/core/devices/wifi/nm-iwd-manager.c @@ -1119,6 +1119,7 @@ object_compare_interfaces(gconstpointer a, gconstpointer b) NM_IWD_KNOWN_NETWORK_INTERFACE, NM_IWD_NETWORK_INTERFACE, NM_IWD_DEVICE_INTERFACE, + NULL, }; int rank_a = G_N_ELEMENTS(interface_order); int rank_b = G_N_ELEMENTS(interface_order); diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c index ca028804..1297d964 100644 --- a/src/core/devices/wwan/nm-modem-broadband.c +++ b/src/core/devices/wwan/nm-modem-broadband.c @@ -369,10 +369,10 @@ static void connect_ready(MMModemSimple *simple_iface, GAsyncResult *res, NMModemBroadband *self) { ConnectContext *ctx; - GError * error = NULL; - NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; - NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; - MMBearer * bearer; + GError * error = NULL; + NMModemIPMethod ip4_method = NM_MODEM_IP_METHOD_UNKNOWN; + NMModemIPMethod ip6_method = NM_MODEM_IP_METHOD_UNKNOWN; + gs_unref_object MMBearer *bearer = NULL; bearer = mm_modem_simple_connect_finish(simple_iface, res, &error); @@ -386,7 +386,7 @@ connect_ready(MMModemSimple *simple_iface, GAsyncResult *res, NMModemBroadband * if (!ctx) return; - self->_priv.bearer = bearer; + self->_priv.bearer = g_steal_pointer(&bearer); if (!self->_priv.bearer) { if (g_error_matches(error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_PIN) -- cgit 1.3.0-6-gf8a5 From e74c568b07b50b97873fb4ee1d776dedefbd54d6 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Fri, 1 Oct 2021 23:05:04 +0200 Subject: New upstream version 1.32.12 --- src/core/devices/adsl/meson.build | 1 - src/core/devices/adsl/nm-atm-manager.c | 4 +- src/core/devices/adsl/nm-device-adsl.c | 10 +- src/core/devices/bluetooth/meson.build | 2 +- src/core/devices/bluetooth/nm-bluez-manager.c | 18 +- src/core/devices/bluetooth/nm-device-bt.c | 18 +- src/core/devices/nm-acd-manager.c | 2 +- src/core/devices/nm-device-6lowpan.c | 2 +- src/core/devices/nm-device-bond.c | 16 +- src/core/devices/nm-device-bridge.c | 18 +- src/core/devices/nm-device-dummy.c | 12 +- src/core/devices/nm-device-ethernet.c | 86 +- src/core/devices/nm-device-factory.c | 4 +- src/core/devices/nm-device-generic.c | 12 +- src/core/devices/nm-device-infiniband.c | 14 +- src/core/devices/nm-device-ip-tunnel.c | 62 +- src/core/devices/nm-device-macsec.c | 66 +- src/core/devices/nm-device-macvlan.c | 18 +- src/core/devices/nm-device-ppp.c | 7 +- src/core/devices/nm-device-private.h | 10 - src/core/devices/nm-device-tun.c | 30 +- src/core/devices/nm-device-utils.c | 356 ++++++ src/core/devices/nm-device-utils.h | 98 ++ src/core/devices/nm-device-veth.c | 10 +- src/core/devices/nm-device-vlan.c | 33 +- src/core/devices/nm-device-vrf.c | 4 +- src/core/devices/nm-device-vxlan.c | 62 +- src/core/devices/nm-device-wireguard.c | 22 +- src/core/devices/nm-device-wpan.c | 4 +- src/core/devices/nm-device.c | 1392 +++++++++++++---------- src/core/devices/nm-device.h | 63 +- src/core/devices/nm-lldp-listener.c | 402 +++---- src/core/devices/nm-lldp-listener.h | 31 +- src/core/devices/ovs/meson.build | 1 - src/core/devices/ovs/nm-device-ovs-bridge.c | 6 +- src/core/devices/ovs/nm-device-ovs-interface.c | 5 +- src/core/devices/ovs/nm-device-ovs-port.c | 4 +- src/core/devices/ovs/nm-ovs-factory.c | 4 +- src/core/devices/ovs/nm-ovsdb.c | 6 +- src/core/devices/team/meson.build | 1 - src/core/devices/team/nm-device-team.c | 32 +- src/core/devices/team/nm-team-factory.c | 4 +- src/core/devices/tests/test-acd.c | 4 +- src/core/devices/tests/test-lldp.c | 66 +- src/core/devices/wifi/meson.build | 2 - src/core/devices/wifi/nm-device-iwd.c | 191 ++-- src/core/devices/wifi/nm-device-olpc-mesh.c | 32 +- src/core/devices/wifi/nm-device-wifi-p2p.c | 9 +- src/core/devices/wifi/nm-device-wifi.c | 137 +-- src/core/devices/wifi/nm-device-wifi.h | 2 +- src/core/devices/wifi/nm-iwd-manager.c | 434 ++++++- src/core/devices/wifi/nm-iwd-manager.h | 1 + src/core/devices/wifi/nm-wifi-ap.c | 153 ++- src/core/devices/wifi/nm-wifi-ap.h | 3 +- src/core/devices/wifi/nm-wifi-common.c | 38 +- src/core/devices/wifi/nm-wifi-factory.c | 15 +- src/core/devices/wifi/nm-wifi-p2p-peer.c | 7 +- src/core/devices/wifi/nm-wifi-utils.c | 902 ++++++++++++++- src/core/devices/wifi/nm-wifi-utils.h | 9 +- src/core/devices/wifi/tests/test-devices-wifi.c | 58 +- src/core/devices/wwan/meson.build | 2 - src/core/devices/wwan/nm-device-modem.c | 36 +- src/core/devices/wwan/nm-modem-broadband.c | 4 +- src/core/devices/wwan/nm-modem-manager.c | 2 +- src/core/devices/wwan/nm-modem-ofono.c | 172 ++- src/core/devices/wwan/nm-modem-ofono.h | 2 + src/core/devices/wwan/nm-modem.c | 13 +- src/core/devices/wwan/nm-wwan-factory.c | 2 +- 68 files changed, 3499 insertions(+), 1749 deletions(-) create mode 100644 src/core/devices/nm-device-utils.c create mode 100644 src/core/devices/nm-device-utils.h (limited to 'src/core/devices') diff --git a/src/core/devices/adsl/meson.build b/src/core/devices/adsl/meson.build index 95f61d95..ef87c6e8 100644 --- a/src/core/devices/adsl/meson.build +++ b/src/core/devices/adsl/meson.build @@ -7,7 +7,6 @@ libnm_device_plugin_adsl = shared_module( 'nm-device-adsl.c', ), dependencies: core_plugin_dep, - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/adsl/nm-atm-manager.c b/src/core/devices/adsl/nm-atm-manager.c index 9be9b5ce..bd9ed8cc 100644 --- a/src/core/devices/adsl/nm-atm-manager.c +++ b/src/core/devices/adsl/nm-atm-manager.c @@ -11,8 +11,8 @@ #include "nm-setting-adsl.h" #include "nm-device-adsl.h" #include "devices/nm-device-factory.h" -#include "platform/nm-platform.h" -#include "nm-udev-aux/nm-udev-utils.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-udev-aux/nm-udev-utils.h" /*****************************************************************************/ diff --git a/src/core/devices/adsl/nm-device-adsl.c b/src/core/devices/adsl/nm-device-adsl.c index 34c062a8..4e4c9dcc 100644 --- a/src/core/devices/adsl/nm-device-adsl.c +++ b/src/core/devices/adsl/nm-device-adsl.c @@ -17,7 +17,7 @@ #include "nm-ip4-config.h" #include "devices/nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "ppp/nm-ppp-manager-call.h" #include "ppp/nm-ppp-status.h" #include "nm-setting-adsl.h" @@ -265,7 +265,7 @@ pppoe_vcc_config(NMDeviceAdsl *self) _LOGD(LOGD_ADSL, "ATM setup successful"); /* otherwise we're good for stage3 */ - nm_platform_link_set_up(nm_device_get_platform(device), priv->nas_ifindex, NULL); + nm_platform_link_change_flags(nm_device_get_platform(device), priv->nas_ifindex, IFF_UP, TRUE); return TRUE; } @@ -674,12 +674,8 @@ dispose(GObject *object) static const NMDBusInterfaceInfoExtended interface_info_device_adsl = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_ADSL, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", - "b", - NM_DEVICE_CARRIER), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), ), ), }; static void diff --git a/src/core/devices/bluetooth/meson.build b/src/core/devices/bluetooth/meson.build index d5f26068..5b196d08 100644 --- a/src/core/devices/bluetooth/meson.build +++ b/src/core/devices/bluetooth/meson.build @@ -8,11 +8,11 @@ libnm_device_plugin_bluetooth_static = static_library( 'nm-device-bt.c', ) + (enable_bluez5_dun ? files('nm-bluez5-dun.c') : files()), dependencies: [ + libnm_core_public_dep, core_default_dep, libnm_wwan_dep, bluez5_dep, ], - c_args: daemon_c_flags, ) libnm_device_plugin_bluetooth_static_dep = declare_dependency( diff --git a/src/core/devices/bluetooth/nm-bluez-manager.c b/src/core/devices/bluetooth/nm-bluez-manager.c index 459ea409..fc081580 100644 --- a/src/core/devices/bluetooth/nm-bluez-manager.c +++ b/src/core/devices/bluetooth/nm-bluez-manager.c @@ -12,8 +12,9 @@ #include #include -#include "nm-glib-aux/nm-dbus-aux.h" -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-dbus-aux.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-dbus-manager.h" #include "devices/nm-device-factory.h" #include "devices/nm-device-bridge.h" @@ -23,9 +24,9 @@ #include "nm-device-bt.h" #include "nm-manager.h" #include "nm-bluez5-dun.h" -#include "nm-core-internal.h" -#include "platform/nm-platform.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-std-aux/nm-dbus-compat.h" /*****************************************************************************/ @@ -574,11 +575,12 @@ _bzobj_to_string(const BzDBusObj *bzobj, char *buf, gsize len) #define _LOG_bzobj(bzobj, context) \ G_STMT_START \ { \ - const BzDBusObj *const _bzobj = (bzobj); \ + const BzDBusObj *const _bzobj = (bzobj); \ + const char *const _context = (context); \ char _buf[500]; \ \ _LOGT("change %-21s %s : { %s }", \ - (context), \ + _context, \ _bzobj->object_path, \ _bzobj_to_string(_bzobj, _buf, sizeof(_buf))); \ } \ @@ -1321,7 +1323,7 @@ _conn_create_panu_connection(NMBluezManager *self, BzDBusObj *bzobj) char uuid[37]; gs_free_error GError *error = NULL; - nm_utils_uuid_generate_buf(uuid); + nm_uuid_generate_random_str_arr(uuid); id = g_strdup_printf(_("%s Network"), bzobj->d_device.name); connection = nm_simple_connection_new(); diff --git a/src/core/devices/bluetooth/nm-device-bt.c b/src/core/devices/bluetooth/nm-device-bt.c index c07be2d3..8f4ceba7 100644 --- a/src/core/devices/bluetooth/nm-device-bt.c +++ b/src/core/devices/bluetooth/nm-device-bt.c @@ -10,7 +10,7 @@ #include #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-bluez-common.h" #include "nm-bluez-manager.h" #include "devices/nm-device-private.h" @@ -26,7 +26,7 @@ #include "nm-utils.h" #include "nm-bt-error.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "devices/wwan/nm-modem-manager.h" #include "devices/wwan/nm-modem.h" @@ -1317,16 +1317,12 @@ finalize(GObject *object) static const NMDBusInterfaceInfoExtended interface_info_device_bluetooth = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Name", "s", NM_DEVICE_BT_NAME), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("BtCapabilities", - "u", - NM_DEVICE_BT_CAPABILITIES), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Name", "s", NM_DEVICE_BT_NAME), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("BtCapabilities", + "u", + NM_DEVICE_BT_CAPABILITIES), ), ), }; static void diff --git a/src/core/devices/nm-acd-manager.c b/src/core/devices/nm-acd-manager.c index 81a28797..145947bb 100644 --- a/src/core/devices/nm-acd-manager.c +++ b/src/core/devices/nm-acd-manager.c @@ -12,7 +12,7 @@ #include #include -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" #include "NetworkManagerUtils.h" #include "n-acd/src/n-acd.h" diff --git a/src/core/devices/nm-device-6lowpan.c b/src/core/devices/nm-device-6lowpan.c index fe116dd4..96218658 100644 --- a/src/core/devices/nm-device-6lowpan.c +++ b/src/core/devices/nm-device-6lowpan.c @@ -9,7 +9,7 @@ #include "nm-device-private.h" #include "settings/nm-settings.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-6lowpan.h" #include "nm-utils.h" diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c index 9c1c484f..b208e2c0 100644 --- a/src/core/devices/nm-device-bond.c +++ b/src/core/devices/nm-device-bond.c @@ -12,9 +12,9 @@ #include "NetworkManagerUtils.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-ip4-config.h" #define _NMLOG_DEVICE_TYPE NMDeviceBond @@ -601,16 +601,10 @@ nm_device_bond_init(NMDeviceBond *self) static const NMDBusInterfaceInfoExtended interface_info_device_bond = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_BOND, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", "b", NM_DEVICE_CARRIER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Slaves", - "ao", - NM_DEVICE_SLAVES), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), ), }; static void diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c index c919d85d..a095dc3e 100644 --- a/src/core/devices/nm-device-bridge.c +++ b/src/core/devices/nm-device-bridge.c @@ -12,9 +12,9 @@ #include "NetworkManagerUtils.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceBridge #include "nm-device-logging.h" @@ -1033,7 +1033,7 @@ create_and_realize(NMDevice * device, const char * iface = nm_device_get_iface(device); const char * hwaddr; gs_free char * hwaddr_cloned = NULL; - guint8 mac_address[NM_UTILS_HWADDR_LEN_MAX]; + guint8 mac_address[_NM_UTILS_HWADDR_LEN_MAX]; NMPlatformLnkBridge props; int r; guint32 mtu = 0; @@ -1142,16 +1142,10 @@ nm_device_bridge_init(NMDeviceBridge *self) static const NMDBusInterfaceInfoExtended interface_info_device_bridge = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_BRIDGE, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", "b", NM_DEVICE_CARRIER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Slaves", - "ao", - NM_DEVICE_SLAVES), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), ), }; static void diff --git a/src/core/devices/nm-device-dummy.c b/src/core/devices/nm-device-dummy.c index 13cfd3b0..488f0ba0 100644 --- a/src/core/devices/nm-device-dummy.c +++ b/src/core/devices/nm-device-dummy.c @@ -13,10 +13,10 @@ #include "nm-act-request.h" #include "nm-device-private.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-dummy.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceDummy #include "nm-device-logging.h" @@ -121,12 +121,10 @@ nm_device_dummy_init(NMDeviceDummy *self) static const NMDBusInterfaceInfoExtended interface_info_device_dummy = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_DUMMY, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), ), ), }; static void diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c index 59f6c613..95336c7a 100644 --- a/src/core/devices/nm-device-ethernet.c +++ b/src/core/devices/nm-device-ethernet.c @@ -14,6 +14,7 @@ #include #include +#include "libnm-glib-aux/nm-uuid.h" #include "nm-device-private.h" #include "nm-act-request.h" #include "nm-ip4-config.h" @@ -24,17 +25,17 @@ #include "ppp/nm-ppp-manager.h" #include "ppp/nm-ppp-manager-call.h" #include "ppp/nm-ppp-status.h" -#include "platform/nm-platform.h" -#include "nm-platform/nm-platform-utils.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nm-platform-utils.h" #include "nm-dcb.h" #include "settings/nm-settings-connection.h" #include "nm-config.h" #include "nm-device-ethernet-utils.h" #include "settings/nm-settings.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" -#include "nm-udev-aux/nm-udev-utils.h" +#include "libnm-udev-aux/nm-udev-utils.h" #include "nm-device-veth.h" #define _NMLOG_DEVICE_TYPE NMDeviceEthernet @@ -922,31 +923,33 @@ link_negotiation_set(NMDevice *device) return; } - /* If link negotiation setting are already in place do nothing and return with success */ - if (!!autoneg == !!link_autoneg && speed == link_speed && duplex == link_duplex) { - _LOGD(LOGD_DEVICE, "set-link: link negotiation is already configured"); - return; - } - if (autoneg && !speed && !duplex) _LOGD(LOGD_DEVICE, "set-link: configure auto-negotiation"); else { _LOGD(LOGD_DEVICE, - "set-link: configure %snegotiation (%u Mbit%s, %s duplex%s)", + "set-link: configure %snegotiation (%u Mbit, %s duplex)", autoneg ? "auto-" : "static ", - speed ?: link_speed, - speed ? "" : "*", - duplex ? nm_platform_link_duplex_type_to_string(duplex) - : nm_platform_link_duplex_type_to_string(link_duplex), - duplex ? "" : "*"); + speed, + nm_platform_link_duplex_type_to_string(duplex)); } if (!priv->ethtool_prev_set) { /* remember the values we had before setting it. */ priv->ethtool_prev_autoneg = link_autoneg; - priv->ethtool_prev_speed = link_speed; - priv->ethtool_prev_duplex = link_duplex; - priv->ethtool_prev_set = TRUE; + if (link_autoneg) { + /* with autoneg, we only support advertising one speed/duplex. Likewise + * our nm_platform_ethtool_get_link_settings() can only return the current + * speed/duplex, but not all the modes that we were advertising. + * + * Do the best we can do: remember to re-enable autoneg, but don't restrict + * the mode. */ + priv->ethtool_prev_speed = 0; + priv->ethtool_prev_duplex = NM_PLATFORM_LINK_DUPLEX_UNKNOWN; + } else { + priv->ethtool_prev_speed = link_speed; + priv->ethtool_prev_duplex = link_duplex; + } + priv->ethtool_prev_set = TRUE; } if (!nm_platform_ethtool_set_link_settings(nm_device_get_platform(device), @@ -1718,11 +1721,11 @@ new_default_connection(NMDevice *self) /* Create a stable UUID. The UUID is also the Network_ID for stable-privacy addr-gen-mode, * thus when it changes we will also generate different IPv6 addresses. */ - uuid = _nm_utils_uuid_generate_from_strings("default-wired", - nm_utils_machine_id_str(), - defname, - perm_hw_addr ?: iface, - NULL); + uuid = nm_uuid_generate_from_strings("default-wired", + nm_utils_machine_id_str(), + defname, + perm_hw_addr ?: iface, + NULL); g_object_set(setting, NM_SETTING_CONNECTION_ID, @@ -1747,7 +1750,7 @@ new_default_connection(NMDevice *self) if (dev) uprop = udev_device_get_property_value(dev, "NM_AUTO_DEFAULT_LINK_LOCAL_ONLY"); - if (nm_udev_utils_property_as_boolean(uprop)) { + if (_nm_utils_ascii_str_to_bool(uprop, FALSE)) { setting = nm_setting_ip4_config_new(); g_object_set(setting, NM_SETTING_IP_CONFIG_METHOD, @@ -1786,7 +1789,8 @@ update_connection(NMDevice *device, NMConnection *connection) const char * mac = nm_device_get_hw_address(device); const char * mac_prop = NM_SETTING_WIRED_MAC_ADDRESS; GHashTableIter iter; - gpointer key, value; + const char * key; + const char * value; if (!s_wired) { s_wired = (NMSettingWired *) nm_setting_wired_new(); @@ -1824,8 +1828,8 @@ update_connection(NMDevice *device, NMConnection *connection) _nm_setting_wired_clear_s390_options(s_wired); g_hash_table_iter_init(&iter, priv->s390_options); - while (g_hash_table_iter_next(&iter, &key, &value)) - nm_setting_wired_add_s390_option(s_wired, (const char *) key, (const char *) value); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &value)) + nm_setting_wired_add_s390_option(s_wired, key, value); } static void @@ -2000,24 +2004,16 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps static const NMDBusInterfaceInfoExtended interface_info_device_wired = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_WIRED, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("PermHwAddress", - "s", - NM_DEVICE_PERM_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Speed", - "u", - NM_DEVICE_ETHERNET_SPEED), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("S390Subchannels", - "as", - NM_DEVICE_ETHERNET_S390_SUBCHANNELS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", - "b", - NM_DEVICE_CARRIER), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("PermHwAddress", + "s", + NM_DEVICE_PERM_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Speed", "u", NM_DEVICE_ETHERNET_SPEED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("S390Subchannels", + "as", + NM_DEVICE_ETHERNET_S390_SUBCHANNELS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), ), ), }; static void diff --git a/src/core/devices/nm-device-factory.c b/src/core/devices/nm-device-factory.c index 81124a8d..bdc64135 100644 --- a/src/core/devices/nm-device-factory.c +++ b/src/core/devices/nm-device-factory.c @@ -11,9 +11,9 @@ #include #include -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-setting-bluetooth.h" #define PLUGIN_PREFIX "libnm-device-plugin-" diff --git a/src/core/devices/nm-device-generic.c b/src/core/devices/nm-device-generic.c index a319666a..08ea5ac5 100644 --- a/src/core/devices/nm-device-generic.c +++ b/src/core/devices/nm-device-generic.c @@ -8,8 +8,8 @@ #include "nm-device-generic.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" /*****************************************************************************/ @@ -191,16 +191,12 @@ dispose(GObject *object) static const NMDBusInterfaceInfoExtended interface_info_device_generic = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_GENERIC, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE( "TypeDescription", "s", NM_DEVICE_GENERIC_TYPE_DESCRIPTION), ), ), - .legacy_property_changed = TRUE, }; static void diff --git a/src/core/devices/nm-device-infiniband.c b/src/core/devices/nm-device-infiniband.c index f54ffcf0..37065bc8 100644 --- a/src/core/devices/nm-device-infiniband.c +++ b/src/core/devices/nm-device-infiniband.c @@ -14,9 +14,9 @@ #include "nm-device-private.h" #include "nm-act-request.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define NM_DEVICE_INFINIBAND_IS_PARTITION "is-partition" @@ -366,15 +366,9 @@ nm_device_infiniband_init(NMDeviceInfiniband *self) static const NMDBusInterfaceInfoExtended interface_info_device_infiniband = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_INFINIBAND, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", - "b", - NM_DEVICE_CARRIER), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), ), ), }; static void diff --git a/src/core/devices/nm-device-ip-tunnel.c b/src/core/devices/nm-device-ip-tunnel.c index da6afb3b..c55dd9f6 100644 --- a/src/core/devices/nm-device-ip-tunnel.c +++ b/src/core/devices/nm-device-ip-tunnel.c @@ -16,9 +16,9 @@ #include "nm-device-private.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-ip4-config.h" @@ -1050,39 +1050,33 @@ dispose(GObject *object) static const NMDBusInterfaceInfoExtended interface_info_device_ip_tunnel = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_IP_TUNNEL, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mode", "u", NM_DEVICE_IP_TUNNEL_MODE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Parent", "o", NM_DEVICE_PARENT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Local", - "s", - NM_DEVICE_IP_TUNNEL_LOCAL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Remote", - "s", - NM_DEVICE_IP_TUNNEL_REMOTE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ttl", "y", NM_DEVICE_IP_TUNNEL_TTL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Tos", "y", NM_DEVICE_IP_TUNNEL_TOS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L( - "PathMtuDiscovery", - "b", - NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("InputKey", - "s", - NM_DEVICE_IP_TUNNEL_INPUT_KEY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("OutputKey", - "s", - NM_DEVICE_IP_TUNNEL_OUTPUT_KEY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L( - "EncapsulationLimit", - "y", - NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("FlowLabel", - "u", - NM_DEVICE_IP_TUNNEL_FLOW_LABEL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Flags", - "u", - NM_DEVICE_IP_TUNNEL_FLAGS), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mode", "u", NM_DEVICE_IP_TUNNEL_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Local", "s", NM_DEVICE_IP_TUNNEL_LOCAL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Remote", + "s", + NM_DEVICE_IP_TUNNEL_REMOTE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ttl", "y", NM_DEVICE_IP_TUNNEL_TTL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Tos", "y", NM_DEVICE_IP_TUNNEL_TOS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("PathMtuDiscovery", + "b", + NM_DEVICE_IP_TUNNEL_PATH_MTU_DISCOVERY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("InputKey", + "s", + NM_DEVICE_IP_TUNNEL_INPUT_KEY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("OutputKey", + "s", + NM_DEVICE_IP_TUNNEL_OUTPUT_KEY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("EncapsulationLimit", + "y", + NM_DEVICE_IP_TUNNEL_ENCAPSULATION_LIMIT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("FlowLabel", + "u", + NM_DEVICE_IP_TUNNEL_FLOW_LABEL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Flags", + "u", + NM_DEVICE_IP_TUNNEL_FLAGS), ), ), }; static void diff --git a/src/core/devices/nm-device-macsec.c b/src/core/devices/nm-device-macsec.c index 51b820a1..51b7225b 100644 --- a/src/core/devices/nm-device-macsec.c +++ b/src/core/devices/nm-device-macsec.c @@ -11,11 +11,11 @@ #include "nm-act-request.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-manager.h" #include "nm-setting-macsec.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "supplicant/nm-supplicant-manager.h" #include "supplicant/nm-supplicant-interface.h" #include "supplicant/nm-supplicant-config.h" @@ -870,40 +870,36 @@ dispose(GObject *object) static const NMDBusInterfaceInfoExtended interface_info_device_macsec = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_MACSEC, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Parent", "o", NM_DEVICE_PARENT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Sci", "t", NM_DEVICE_MACSEC_SCI), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("IcvLength", - "y", - NM_DEVICE_MACSEC_ICV_LENGTH), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("CipherSuite", - "t", - NM_DEVICE_MACSEC_CIPHER_SUITE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Window", - "u", - NM_DEVICE_MACSEC_WINDOW), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("EncodingSa", - "y", - NM_DEVICE_MACSEC_ENCODING_SA), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Validation", - "s", - NM_DEVICE_MACSEC_VALIDATION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Encrypt", - "b", - NM_DEVICE_MACSEC_ENCRYPT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Protect", - "b", - NM_DEVICE_MACSEC_PROTECT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("IncludeSci", - "b", - NM_DEVICE_MACSEC_INCLUDE_SCI), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Es", "b", NM_DEVICE_MACSEC_ES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Scb", "b", NM_DEVICE_MACSEC_SCB), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("ReplayProtect", - "b", - NM_DEVICE_MACSEC_REPLAY_PROTECT), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Sci", "t", NM_DEVICE_MACSEC_SCI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("IcvLength", + "y", + NM_DEVICE_MACSEC_ICV_LENGTH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("CipherSuite", + "t", + NM_DEVICE_MACSEC_CIPHER_SUITE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Window", "u", NM_DEVICE_MACSEC_WINDOW), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("EncodingSa", + "y", + NM_DEVICE_MACSEC_ENCODING_SA), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Validation", + "s", + NM_DEVICE_MACSEC_VALIDATION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Encrypt", + "b", + NM_DEVICE_MACSEC_ENCRYPT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Protect", + "b", + NM_DEVICE_MACSEC_PROTECT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("IncludeSci", + "b", + NM_DEVICE_MACSEC_INCLUDE_SCI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Es", "b", NM_DEVICE_MACSEC_ES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Scb", "b", NM_DEVICE_MACSEC_SCB), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ReplayProtect", + "b", + NM_DEVICE_MACSEC_REPLAY_PROTECT), ), ), }; static void diff --git a/src/core/devices/nm-device-macvlan.c b/src/core/devices/nm-device-macvlan.c index e8b39ed6..7302ecdf 100644 --- a/src/core/devices/nm-device-macvlan.c +++ b/src/core/devices/nm-device-macvlan.c @@ -13,7 +13,7 @@ #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-macvlan.h" #include "nm-setting-wired.h" @@ -502,17 +502,13 @@ dispose(GObject *object) static const NMDBusInterfaceInfoExtended interface_info_device_macvlan = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_MACVLAN, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Parent", "o", NM_DEVICE_PARENT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mode", "s", NM_DEVICE_MACVLAN_MODE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("NoPromisc", - "b", - NM_DEVICE_MACVLAN_NO_PROMISC), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Tab", - "b", - NM_DEVICE_MACVLAN_TAP), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mode", "s", NM_DEVICE_MACVLAN_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("NoPromisc", + "b", + NM_DEVICE_MACVLAN_NO_PROMISC), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Tab", "b", NM_DEVICE_MACVLAN_TAP), ), ), }; static void diff --git a/src/core/devices/nm-device-ppp.c b/src/core/devices/nm-device-ppp.c index 4040f2d3..8df245bb 100644 --- a/src/core/devices/nm-device-ppp.c +++ b/src/core/devices/nm-device-ppp.c @@ -13,7 +13,7 @@ #include "nm-device-private.h" #include "nm-manager.h" #include "nm-setting-pppoe.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "ppp/nm-ppp-manager.h" #include "ppp/nm-ppp-manager-call.h" #include "ppp/nm-ppp-status.h" @@ -274,10 +274,7 @@ dispose(GObject *object) } static const NMDBusInterfaceInfoExtended interface_info_device_ppp = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( - NM_DBUS_INTERFACE_DEVICE_PPP, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(NM_DBUS_INTERFACE_DEVICE_PPP, ), }; static void diff --git a/src/core/devices/nm-device-private.h b/src/core/devices/nm-device-private.h index 8675a699..eb37b14f 100644 --- a/src/core/devices/nm-device-private.h +++ b/src/core/devices/nm-device-private.h @@ -17,14 +17,6 @@ typedef enum { NM_DEVICE_STAGE_STATE_COMPLETED = 2, } NMDeviceStageState; -typedef enum { - NM_DEVICE_IP_STATE_NONE, - NM_DEVICE_IP_STATE_WAIT, - NM_DEVICE_IP_STATE_CONF, - NM_DEVICE_IP_STATE_DONE, - NM_DEVICE_IP_STATE_FAIL, -} NMDeviceIPState; - enum NMActStageReturn { NM_ACT_STAGE_RETURN_FAILURE = 0, /* Hard failure of activation */ NM_ACT_STAGE_RETURN_SUCCESS, /* Activation stage done */ @@ -117,8 +109,6 @@ nm_device_activate_ip6_state_done(NMDevice *self) return nm_device_activate_get_ip_state(self, AF_INET6) == NM_DEVICE_IP_STATE_DONE; } -void nm_device_set_dhcp_anycast_address(NMDevice *device, const char *addr); - gboolean nm_device_dhcp4_renew(NMDevice *device, gboolean release); gboolean nm_device_dhcp6_renew(NMDevice *device, gboolean release); diff --git a/src/core/devices/nm-device-tun.c b/src/core/devices/nm-device-tun.c index edca69e9..ebccddfc 100644 --- a/src/core/devices/nm-device-tun.c +++ b/src/core/devices/nm-device-tun.c @@ -14,10 +14,10 @@ #include "nm-act-request.h" #include "nm-device-private.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-tun.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceTun #include "nm-device-logging.h" @@ -444,22 +444,18 @@ nm_device_tun_init(NMDeviceTun *self) static const NMDBusInterfaceInfoExtended interface_info_device_tun = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_TUN, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Owner", "x", NM_DEVICE_TUN_OWNER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Group", "x", NM_DEVICE_TUN_GROUP), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mode", "s", NM_DEVICE_TUN_MODE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("NoPi", "b", NM_DEVICE_TUN_NO_PI), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("VnetHdr", - "b", - NM_DEVICE_TUN_VNET_HDR), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("MultiQueue", - "b", - NM_DEVICE_TUN_MULTI_QUEUE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Owner", "x", NM_DEVICE_TUN_OWNER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Group", "x", NM_DEVICE_TUN_GROUP), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mode", "s", NM_DEVICE_TUN_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("NoPi", "b", NM_DEVICE_TUN_NO_PI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("VnetHdr", "b", NM_DEVICE_TUN_VNET_HDR), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("MultiQueue", + "b", + NM_DEVICE_TUN_MULTI_QUEUE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", + "s", + NM_DEVICE_HW_ADDRESS), ), ), }; static void diff --git a/src/core/devices/nm-device-utils.c b/src/core/devices/nm-device-utils.c new file mode 100644 index 00000000..f40ca570 --- /dev/null +++ b/src/core/devices/nm-device-utils.c @@ -0,0 +1,356 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "src/core/nm-default-daemon.h" +#include "src/core/dns/nm-dns-manager.h" +#include "src/core/dns/nm-dns-systemd-resolved.h" + +#include "nm-device-utils.h" +#include "nm-core-utils.h" + +/*****************************************************************************/ + +NM_UTILS_LOOKUP_STR_DEFINE( + nm_device_state_queued_state_to_str, + NMDeviceState, + NM_UTILS_LOOKUP_DEFAULT(NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "???"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNKNOWN, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNMANAGED, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unmanaged"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNAVAILABLE, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unavailable"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_DISCONNECTED, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "disconnected"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_PREPARE, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "prepare"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_CONFIG, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "config"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_NEED_AUTH, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "need-auth"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_IP_CONFIG, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-config"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_IP_CHECK, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-check"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_SECONDARIES, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "secondaries"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_ACTIVATED, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "activated"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_DEACTIVATING, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "deactivating"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_FAILED, + NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "failed"), ); + +const char * +nm_device_state_to_str(NMDeviceState state) +{ + return nm_device_state_queued_state_to_str(state) + + NM_STRLEN(NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE); +} + +NM_UTILS_LOOKUP_STR_DEFINE( + nm_device_state_reason_to_str, + NMDeviceStateReason, + NM_UTILS_LOOKUP_DEFAULT(NULL), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNKNOWN, "unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NONE, "none"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NOW_MANAGED, "managed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NOW_UNMANAGED, "unmanaged"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONFIG_FAILED, "config-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE, "ip-config-unavailable"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED, "ip-config-expired"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NO_SECRETS, "no-secrets"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT, "supplicant-disconnect"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED, + "supplicant-config-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED, "supplicant-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT, "supplicant-timeout"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_START_FAILED, "ppp-start-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_DISCONNECT, "ppp-disconnect"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_FAILED, "ppp-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_START_FAILED, "dhcp-start-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_ERROR, "dhcp-error"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_FAILED, "dhcp-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SHARED_START_FAILED, "sharing-start-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SHARED_FAILED, "sharing-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED, "autoip-start-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_ERROR, "autoip-error"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_FAILED, "autoip-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_BUSY, "modem-busy"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE, "modem-no-dialtone"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER, "modem-no-carrier"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT, "modem-dial-timeout"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, "modem-dial-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, "modem-init-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_APN_FAILED, "gsm-apn-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING, + "gsm-registration-idle"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED, + "gsm-registration-denied"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT, + "gsm-registration-timeout"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED, + "gsm-registration-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED, "gsm-pin-check-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_FIRMWARE_MISSING, "firmware-missing"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_REMOVED, "removed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SLEEPING, "sleeping"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, "connection-removed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_USER_REQUESTED, "user-requested"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CARRIER, "carrier-changed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, "connection-assumed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, "supplicant-available"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND, "modem-not-found"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_BT_FAILED, "bluetooth-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED, "gsm-sim-not-inserted"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED, "gsm-sim-pin-required"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED, "gsm-sim-puk-required"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_WRONG, "gsm-sim-wrong"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_INFINIBAND_MODE, "infiniband-mode"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED, "dependency-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_BR2684_FAILED, "br2684-bridge-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE, + "modem-manager-unavailable"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SSID_NOT_FOUND, "ssid-not-found"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED, + "secondary-connection-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED, "dcb-fcoe-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED, "teamd-control-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_FAILED, "modem-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, "modem-available"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT, "sim-pin-incorrect"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NEW_ACTIVATION, "new-activation"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PARENT_CHANGED, "parent-changed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED, + "parent-managed-changed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_OVSDB_FAILED, "ovsdb-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE, "ip-address-duplicate"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED, "ip-method-unsupported"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED, + "sriov-configuration-failed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PEER_NOT_FOUND, "peer-not-found"), ); + +NM_UTILS_LOOKUP_STR_DEFINE(nm_device_mtu_source_to_str, + NMDeviceMtuSource, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_NONE, "none"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_PARENT, "parent"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_IP_CONFIG, "ip-config"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_CONNECTION, + "connection"), ); + +NM_UTILS_LOOKUP_STR_DEFINE(nm_device_sys_iface_state_to_str, + NMDeviceSysIfaceState, + NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, "external"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_ASSUME, "assume"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_MANAGED, "managed"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_REMOVED, + "removed"), ); + +NM_UTILS_LOOKUP_STR_DEFINE(nm_device_ip_state_to_str, + NMDeviceIPState, + NM_UTILS_LOOKUP_DEFAULT_WARN("unknown"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_NONE, "none"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_WAIT, "wait"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_CONF, "conf"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_DONE, "done"), + NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_FAIL, "fail"), ); + +/*****************************************************************************/ + +#define SD_RESOLVED_DNS (1UL << 0) +/* Don't answer request from locally synthesized records (which includes /etc/hosts) */ +#define SD_RESOLVED_NO_SYNTHESIZE (1UL << 11) + +typedef struct { + int addr_family; + NMIPAddr address; + gulong cancellable_id; + GTask * task; + NMDnsSystemdResolvedResolveHandle *resolved_handle; +} ResolveAddrInfo; + +#define _NMLOG_PREFIX_NAME "resolve-addr" +#define _NMLOG_DOMAIN LOGD_CORE +#define _NMLOG2(level, info, ...) \ + G_STMT_START \ + { \ + if (nm_logging_enabled((level), (_NMLOG_DOMAIN))) { \ + ResolveAddrInfo *_info = (info); \ + char _addr_str[NM_UTILS_INET_ADDRSTRLEN]; \ + \ + _nm_log((level), \ + (_NMLOG_DOMAIN), \ + 0, \ + NULL, \ + NULL, \ + _NMLOG_PREFIX_NAME "[" NM_HASH_OBFUSCATE_PTR_FMT \ + ",%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + NM_HASH_OBFUSCATE_PTR(_info), \ + nm_utils_inet_ntop(_info->addr_family, &_info->address, _addr_str) \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ + G_STMT_END + +static void +resolve_addr_info_free(ResolveAddrInfo *info) +{ + nm_assert(info->cancellable_id == 0); + nm_assert(!info->resolved_handle); + g_object_unref(info->task); + g_free(info); +} + +static void +resolve_addr_complete(ResolveAddrInfo *info, char *hostname_take, GError *error_take) +{ + nm_assert(!!hostname_take != !!error_take); + + nm_clear_g_cancellable_disconnect(g_task_get_cancellable(info->task), &info->cancellable_id); + if (error_take) + g_task_return_error(info->task, error_take); + else + g_task_return_pointer(info->task, hostname_take, g_free); + + resolve_addr_info_free(info); +} + +static void +resolve_addr_helper_cb(GObject *source, GAsyncResult *result, gpointer user_data) +{ + ResolveAddrInfo *info = user_data; + gs_free_error GError *error = NULL; + gs_free char * output = NULL; + + output = nm_utils_spawn_helper_finish(result, &error); + if (nm_utils_error_is_cancelled(error)) + return; + + _LOG2D(info, "helper returned hostname '%s'", output); + + resolve_addr_complete(info, g_steal_pointer(&output), g_steal_pointer(&error)); +} + +static void +resolve_addr_spawn_helper(ResolveAddrInfo *info) +{ + char addr_str[NM_UTILS_INET_ADDRSTRLEN]; + + nm_utils_inet_ntop(info->addr_family, &info->address, addr_str); + _LOG2D(info, "start lookup via nm-daemon-helper"); + nm_utils_spawn_helper(NM_MAKE_STRV("resolve-address", addr_str), + g_task_get_cancellable(info->task), + resolve_addr_helper_cb, + info); +} + +static void +resolve_addr_resolved_cb(NMDnsSystemdResolved * resolved, + NMDnsSystemdResolvedResolveHandle * handle, + const NMDnsSystemdResolvedAddressResult *names, + guint names_len, + guint64 flags, + GError * error, + gpointer user_data) +{ + ResolveAddrInfo *info = user_data; + + info->resolved_handle = NULL; + + if (nm_utils_error_is_cancelled(error)) + return; + + if (error) { + gs_free char *dbus_error = NULL; + + _LOG2D(info, "error resolving via systemd-resolved: %s", error->message); + + dbus_error = g_dbus_error_get_remote_error(error); + if (nm_streq0(dbus_error, "org.freedesktop.resolve1.DnsError.NXDOMAIN")) { + resolve_addr_complete(info, NULL, g_error_copy(error)); + return; + } + + resolve_addr_spawn_helper(info); + return; + } + + if (names_len == 0) { + _LOG2D(info, "systemd-resolved returned no result"); + resolve_addr_complete(info, g_strdup(""), NULL); + return; + } + + _LOG2D(info, "systemd-resolved returned hostname '%s'", names[0].name); + resolve_addr_complete(info, g_strdup(names[0].name), NULL); +} + +static void +resolve_addr_cancelled(GObject *object, gpointer user_data) +{ + ResolveAddrInfo *info = user_data; + GError * error = NULL; + + nm_clear_g_signal_handler(g_task_get_cancellable(info->task), &info->cancellable_id); + nm_clear_pointer(&info->resolved_handle, nm_dns_systemd_resolved_resolve_cancel); + nm_utils_error_set_cancelled(&error, FALSE, NULL); + resolve_addr_complete(info, NULL, error); +} + +void +nm_device_resolve_address(int addr_family, + gconstpointer address, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer cb_data) +{ + ResolveAddrInfo * info; + NMDnsSystemdResolved *resolved; + + info = g_new(ResolveAddrInfo, 1); + *info = (ResolveAddrInfo){ + .task = nm_g_task_new(NULL, cancellable, nm_device_resolve_address, callback, cb_data), + .addr_family = addr_family, + .address = nm_ip_addr_init(addr_family, address), + }; + + if (cancellable) { + gulong signal_id; + + signal_id = + g_cancellable_connect(cancellable, G_CALLBACK(resolve_addr_cancelled), info, NULL); + if (signal_id == 0) { + /* the request is already cancelled. Return. */ + return; + } + info->cancellable_id = signal_id; + } + + resolved = (NMDnsSystemdResolved *) nm_dns_manager_get_systemd_resolved(nm_dns_manager_get()); + if (resolved) { + _LOG2D(info, "start lookup via systemd-resolved"); + info->resolved_handle = + nm_dns_systemd_resolved_resolve_address(resolved, + 0, + addr_family, + address, + SD_RESOLVED_DNS | SD_RESOLVED_NO_SYNTHESIZE, + 20000, + resolve_addr_resolved_cb, + info); + return; + } + + resolve_addr_spawn_helper(info); +} + +char * +nm_device_resolve_address_finish(GAsyncResult *result, GError **error) +{ + GTask *task = G_TASK(result); + + nm_assert(nm_g_task_is_valid(result, NULL, nm_device_resolve_address)); + + return g_task_propagate_pointer(task, error); +} diff --git a/src/core/devices/nm-device-utils.h b/src/core/devices/nm-device-utils.h new file mode 100644 index 00000000..8bc957a4 --- /dev/null +++ b/src/core/devices/nm-device-utils.h @@ -0,0 +1,98 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __DEVICES_NM_DEVICE_UTILS_H__ +#define __DEVICES_NM_DEVICE_UTILS_H__ + +/*****************************************************************************/ + +const char *nm_device_state_to_str(NMDeviceState state); +const char *nm_device_state_reason_to_str(NMDeviceStateReason reason); + +#define nm_device_state_reason_to_str_a(reason) \ + NM_UTILS_LOOKUP_STR_A(nm_device_state_reason_to_str, reason) + +static inline NMDeviceStateReason +nm_device_state_reason_check(NMDeviceStateReason reason) +{ + /* the device-state-reason serves mostly informational purpose during a state + * change. In some cases however, decisions are made based on the reason. + * I tend to think that interpreting the state reason to derive some behaviors + * is confusing, because the cause and effect are so far apart. + * + * This function is here to mark source that inspects the reason to make + * a decision -- contrary to places that set the reason. Thus, by grepping + * for nm_device_state_reason_check() you can find the "effect" to a certain + * reason. + */ + return reason; +} + +/*****************************************************************************/ + +#define NM_PENDING_ACTION_AUTOACTIVATE "autoactivate" +#define NM_PENDING_ACTION_IN_STATE_CHANGE "in-state-change" +#define NM_PENDING_ACTION_RECHECK_AVAILABLE "recheck-available" +#define NM_PENDING_ACTION_CARRIER_WAIT "carrier-wait" +#define NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT "waiting-for-supplicant" +#define NM_PENDING_ACTION_WIFI_SCAN "wifi-scan" +#define NM_PENDING_ACTION_WAITING_FOR_COMPANION "waiting-for-companion" +#define NM_PENDING_ACTION_LINK_INIT "link-init" + +#define NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "queued-state-change-" +#define NM_PENDING_ACTIONPREFIX_ACTIVATION "activation-" + +const char *nm_device_state_queued_state_to_str(NMDeviceState state); + +/*****************************************************************************/ + +typedef enum { + NM_DEVICE_MTU_SOURCE_NONE, + NM_DEVICE_MTU_SOURCE_PARENT, + NM_DEVICE_MTU_SOURCE_IP_CONFIG, + NM_DEVICE_MTU_SOURCE_CONNECTION, +} NMDeviceMtuSource; + +const char *nm_device_mtu_source_to_str(NMDeviceMtuSource mtu_source); + +/*****************************************************************************/ + +typedef enum _nm_packed { + NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, + NM_DEVICE_SYS_IFACE_STATE_ASSUME, + NM_DEVICE_SYS_IFACE_STATE_MANAGED, + + /* the REMOVED state applies when the device is manually set to unmanaged + * or the link was externally removed. In both cases, we move the device + * to UNMANAGED state, without touching the link -- be it, because the link + * is already gone or because we want to release it (give it up). + */ + NM_DEVICE_SYS_IFACE_STATE_REMOVED, +} NMDeviceSysIfaceState; + +const char *nm_device_sys_iface_state_to_str(NMDeviceSysIfaceState sys_iface_state); + +/*****************************************************************************/ + +typedef enum { + NM_DEVICE_IP_STATE_NONE, + NM_DEVICE_IP_STATE_WAIT, + NM_DEVICE_IP_STATE_CONF, + NM_DEVICE_IP_STATE_DONE, + NM_DEVICE_IP_STATE_FAIL, +} NMDeviceIPState; + +const char *nm_device_ip_state_to_str(NMDeviceIPState ip_state); + +/*****************************************************************************/ + +/*****************************************************************************/ + +void nm_device_resolve_address(int addr_family, + gconstpointer address, + GCancellable * cancellable, + GAsyncReadyCallback callback, + gpointer cb_data); + +char *nm_device_resolve_address_finish(GAsyncResult *result, GError **error); + +#endif /* __DEVICES_NM_DEVICE_UTILS_H__ */ diff --git a/src/core/devices/nm-device-veth.c b/src/core/devices/nm-device-veth.c index e0ba843d..28831b75 100644 --- a/src/core/devices/nm-device-veth.c +++ b/src/core/devices/nm-device-veth.c @@ -7,11 +7,11 @@ #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-device-veth.h" #include "nm-device-private.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-veth.h" @@ -161,12 +161,8 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) static const NMDBusInterfaceInfoExtended interface_info_device_veth = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_VETH, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Peer", - "o", - NM_DEVICE_VETH_PEER), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Peer", "o", NM_DEVICE_VETH_PEER), ), ), }; static void diff --git a/src/core/devices/nm-device-vlan.c b/src/core/devices/nm-device-vlan.c index bfde60ef..548245f8 100644 --- a/src/core/devices/nm-device-vlan.c +++ b/src/core/devices/nm-device-vlan.c @@ -16,11 +16,12 @@ #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-manager.h" -#include "nm-core-internal.h" -#include "platform/nmp-object.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nm-platform-utils.h" #define _NMLOG_DEVICE_TYPE NMDeviceVlan #include "nm-device-logging.h" @@ -436,7 +437,7 @@ update_connection(NMDevice *device, NMConnection *connection) const NMPlatformLink *plink; const NMPObject * polnk; guint vlan_id; - guint vlan_flags; + _NMVlanFlags vlan_flags; if (!s_vlan) { s_vlan = (NMSettingVlan *) nm_setting_vlan_new(); @@ -463,9 +464,9 @@ update_connection(NMDevice *device, NMConnection *connection) if (polnk) vlan_flags = polnk->lnk_vlan.flags; else - vlan_flags = NM_VLAN_FLAG_REORDER_HEADERS; - if (vlan_flags != nm_setting_vlan_get_flags(s_vlan)) - g_object_set(s_vlan, NM_SETTING_VLAN_FLAGS, (NMVlanFlags) vlan_flags, NULL); + vlan_flags = _NM_VLAN_FLAG_REORDER_HEADERS; + if (NM_VLAN_FLAGS_CAST(vlan_flags) != nm_setting_vlan_get_flags(s_vlan)) + g_object_set(s_vlan, NM_SETTING_VLAN_FLAGS, NM_VLAN_FLAGS_CAST(vlan_flags), NULL); if (polnk) { _nm_setting_vlan_set_priorities(s_vlan, @@ -507,7 +508,7 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) nm_platform_link_vlan_change(nm_device_get_platform(device), nm_device_get_ifindex(device), - NM_VLAN_FLAGS_ALL, + _NM_VLAN_FLAGS_ALL, nm_setting_vlan_get_flags(s_vlan), TRUE, ingress_map, @@ -546,17 +547,11 @@ nm_device_vlan_init(NMDeviceVlan *self) static const NMDBusInterfaceInfoExtended interface_info_device_vlan = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_VLAN, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", "b", NM_DEVICE_CARRIER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Parent", "o", NM_DEVICE_PARENT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("VlanId", - "u", - NM_DEVICE_VLAN_ID), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("VlanId", "u", NM_DEVICE_VLAN_ID), ), ), }; static void @@ -674,7 +669,7 @@ get_connection_iface(NMDeviceFactory *factory, NMConnection *connection, const c * device, we create one for it using the VLAN ID and the parent * interface's name. */ - return nm_utils_new_vlan_name(parent_iface, nm_setting_vlan_get_id(s_vlan)); + return nmp_utils_new_vlan_name(parent_iface, nm_setting_vlan_get_id(s_vlan)); } NM_DEVICE_FACTORY_DEFINE_INTERNAL( diff --git a/src/core/devices/nm-device-vrf.c b/src/core/devices/nm-device-vrf.c index 4fec59ba..2a1f42c6 100644 --- a/src/core/devices/nm-device-vrf.c +++ b/src/core/devices/nm-device-vrf.c @@ -4,12 +4,12 @@ #include "nm-device-vrf.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-device-factory.h" #include "nm-device-private.h" #include "nm-manager.h" #include "nm-setting-vrf.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "settings/nm-settings.h" #define _NMLOG_DEVICE_TYPE NMDeviceVrf diff --git a/src/core/devices/nm-device-vxlan.c b/src/core/devices/nm-device-vxlan.c index f16a52c4..f9dfad2a 100644 --- a/src/core/devices/nm-device-vxlan.c +++ b/src/core/devices/nm-device-vxlan.c @@ -9,7 +9,7 @@ #include "nm-device-private.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-utils.h" #include "nm-device-factory.h" #include "nm-setting-vxlan.h" @@ -17,7 +17,7 @@ #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-ip4-config.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceVxlan #include "nm-device-logging.h" @@ -576,38 +576,34 @@ nm_device_vxlan_init(NMDeviceVxlan *self) static const NMDBusInterfaceInfoExtended interface_info_device_vxlan = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_VXLAN, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Parent", "o", NM_DEVICE_PARENT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Id", "u", NM_DEVICE_VXLAN_ID), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Group", "s", NM_DEVICE_VXLAN_GROUP), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Local", "s", NM_DEVICE_VXLAN_LOCAL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Tos", "y", NM_DEVICE_VXLAN_TOS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ttl", "y", NM_DEVICE_VXLAN_TTL), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Learning", - "b", - NM_DEVICE_VXLAN_LEARNING), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ageing", "u", NM_DEVICE_VXLAN_AGEING), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Limit", "u", NM_DEVICE_VXLAN_LIMIT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("DstPort", - "q", - NM_DEVICE_VXLAN_DST_PORT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("SrcPortMin", - "q", - NM_DEVICE_VXLAN_SRC_PORT_MIN), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("SrcPortMax", - "q", - NM_DEVICE_VXLAN_SRC_PORT_MAX), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Proxy", "b", NM_DEVICE_VXLAN_PROXY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Rsc", "b", NM_DEVICE_VXLAN_RSC), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("L2miss", "b", NM_DEVICE_VXLAN_L2MISS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("L3miss", - "b", - NM_DEVICE_VXLAN_L3MISS), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Parent", "o", NM_DEVICE_PARENT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Id", "u", NM_DEVICE_VXLAN_ID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Group", "s", NM_DEVICE_VXLAN_GROUP), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Local", "s", NM_DEVICE_VXLAN_LOCAL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Tos", "y", NM_DEVICE_VXLAN_TOS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ttl", "y", NM_DEVICE_VXLAN_TTL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Learning", + "b", + NM_DEVICE_VXLAN_LEARNING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ageing", "u", NM_DEVICE_VXLAN_AGEING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Limit", "u", NM_DEVICE_VXLAN_LIMIT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DstPort", + "q", + NM_DEVICE_VXLAN_DST_PORT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("SrcPortMin", + "q", + NM_DEVICE_VXLAN_SRC_PORT_MIN), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("SrcPortMax", + "q", + NM_DEVICE_VXLAN_SRC_PORT_MAX), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Proxy", "b", NM_DEVICE_VXLAN_PROXY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Rsc", "b", NM_DEVICE_VXLAN_RSC), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("L2miss", "b", NM_DEVICE_VXLAN_L2MISS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("L3miss", + "b", + NM_DEVICE_VXLAN_L3MISS), ), ), }; static void diff --git a/src/core/devices/nm-device-wireguard.c b/src/core/devices/nm-device-wireguard.c index 5bee09e6..aa9c46eb 100644 --- a/src/core/devices/nm-device-wireguard.c +++ b/src/core/devices/nm-device-wireguard.c @@ -11,12 +11,12 @@ #include #include "nm-setting-wireguard.h" -#include "nm-core-internal.h" -#include "nm-glib-aux/nm-secret-utils.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-glib-aux/nm-secret-utils.h" #include "nm-device-private.h" -#include "platform/nm-platform.h" -#include "platform/nmp-object.h" -#include "platform/nmp-rules-manager.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nmp-rules-manager.h" #include "nm-device-factory.h" #include "nm-active-connection.h" #include "nm-act-request.h" @@ -66,7 +66,7 @@ G_STATIC_ASSERT(NM_WIREGUARD_SYMMETRIC_KEY_LEN == NMP_WIREGUARD_SYMMETRIC_KEY_LE * timestamp. */ #define RETRY_IN_MSEC_ASAP ((gint64) G_MAXINT64) -#define RETRY_IN_MSEC_MAX ((gint64)(30 * 60 * 1000)) +#define RETRY_IN_MSEC_MAX ((gint64) (30 * 60 * 1000)) typedef enum { LINK_CONFIG_MODE_FULL, @@ -669,7 +669,7 @@ _peers_resolve_retry_reschedule(NMDeviceWireGuard *self, gint64 new_next_try_at_ * than expected. Also, rate-limit to 500 msec. */ interval_ms = NM_CLAMP((new_next_try_at_nsec - now) / NM_UTILS_NSEC_PER_MSEC, (gint64) 500, - (gint64)(24 * 60 * 60 * 1000)); + (gint64) (24 * 60 * 60 * 1000)); _LOGT(LOGD_DEVICE, "wireguard-peers: schedule rechecking peer endpoints in %u msec", @@ -1939,11 +1939,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) switch (prop_id) { case PROP_PUBLIC_KEY: - g_value_take_variant(value, - g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, - priv->lnk_curr.public_key, - sizeof(priv->lnk_curr.public_key), - 1)); + g_value_take_variant( + value, + nm_g_variant_new_ay(priv->lnk_curr.public_key, sizeof(priv->lnk_curr.public_key))); break; case PROP_LISTEN_PORT: g_value_set_uint(value, priv->lnk_curr.listen_port); diff --git a/src/core/devices/nm-device-wpan.c b/src/core/devices/nm-device-wpan.c index 2f3b16ff..73d79410 100644 --- a/src/core/devices/nm-device-wpan.c +++ b/src/core/devices/nm-device-wpan.c @@ -15,10 +15,10 @@ #include "nm-act-request.h" #include "nm-device-private.h" #include "nm-ip4-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-wpan.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceWpan #include "nm-device-logging.h" diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 3874e586..50386d00 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -23,22 +23,23 @@ #include #include -#include "nm-std-aux/unaligned.h" -#include "nm-glib-aux/nm-dedup-multi.h" -#include "nm-glib-aux/nm-random-utils.h" -#include "systemd/nm-sd-utils-shared.h" - -#include "nm-base/nm-ethtool-base.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-dedup-multi.h" +#include "libnm-glib-aux/nm-random-utils.h" +#include "libnm-systemd-shared/nm-sd-utils-shared.h" + +#include "libnm-base/nm-ethtool-base.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-device-private.h" #include "nm-l3cfg.h" #include "nm-l3-config-data.h" #include "NetworkManagerUtils.h" #include "nm-manager.h" -#include "platform/nm-platform.h" -#include "nm-platform/nm-platform-utils.h" -#include "platform/nmp-object.h" -#include "platform/nmp-rules-manager.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nm-platform-utils.h" +#include "libnm-platform/nmp-object.h" +#include "libnm-platform/nmp-rules-manager.h" #include "ndisc/nm-ndisc.h" #include "ndisc/nm-lndp-ndisc.h" #include "dhcp/nm-dhcp-manager.h" @@ -51,7 +52,8 @@ #include "dnsmasq/nm-dnsmasq-manager.h" #include "nm-dhcp-config.h" #include "nm-rfkill-manager.h" -#include "nm-firewall-manager.h" +#include "nm-firewall-utils.h" +#include "nm-firewalld-manager.h" #include "settings/nm-settings-connection.h" #include "settings/nm-settings.h" #include "nm-setting-ethtool.h" @@ -65,12 +67,13 @@ #include "c-list/src/c-list.h" #include "dns/nm-dns-manager.h" #include "nm-acd-manager.h" -#include "nm-core-internal.h" -#include "systemd/nm-sd.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-systemd-core/nm-sd.h" #include "nm-lldp-listener.h" #include "nm-audit-manager.h" #include "nm-connectivity.h" #include "nm-dbus-interface.h" +#include "nm-hostname-manager.h" #include "nm-device-generic.h" #include "nm-device-vlan.h" @@ -207,6 +210,7 @@ typedef struct { NMOptionBool requested[_NM_ETHTOOL_ID_FEATURE_NUM]; NMEthtoolCoalesceState *coalesce; NMEthtoolRingState * ring; + NMEthtoolPauseState * pause; } EthtoolState; typedef enum { @@ -217,7 +221,6 @@ typedef enum { typedef struct { ResolverState state; - GResolver * resolver; GInetAddress *address; GCancellable *cancellable; char * hostname; @@ -496,11 +499,18 @@ typedef struct _NMDevicePrivate { NMDeviceStageState stage1_sriov_state : 3; - /* Generic DHCP stuff */ - char *dhcp_anycast_address; + bool ip_config_started : 1; char *current_stable_id; + union { + struct { + GSource *ip_req_timeout_source_6; + GSource *ip_req_timeout_source_4; + }; + GSource *ip_req_timeout_source_x[2]; + }; + /* Proxy Configuration */ NMProxyConfig * proxy_config; NMPacrunnerConfId *pacrunner_conf_id; @@ -592,9 +602,9 @@ typedef struct _NMDevicePrivate { gulong dnsmasq_state_id; /* Firewall */ - FirewallState fw_state : 4; - NMFirewallManager * fw_mgr; - NMFirewallManagerCallId *fw_call; + FirewallState fw_state : 4; + NMFirewalldManager * fw_mgr; + NMFirewalldManagerCallId *fw_call; /* IPv4LL stuff */ sd_ipv4ll *ipv4ll; @@ -693,6 +703,8 @@ typedef struct _NMDevicePrivate { } stats; bool mtu_force_set_done : 1; + + NMOptionBool promisc_reset; } NMDevicePrivate; G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT) @@ -764,139 +776,7 @@ static void sriov_op_cb(GError *error, gpointer user_data); static void device_ifindex_changed_cb(NMManager *manager, NMDevice *device_changed, NMDevice *self); static gboolean device_link_changed(NMDevice *self); - -/*****************************************************************************/ - -static NM_UTILS_LOOKUP_STR_DEFINE( - queued_state_to_string, - NMDeviceState, - NM_UTILS_LOOKUP_DEFAULT(NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "???"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNKNOWN, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unknown"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNMANAGED, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unmanaged"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNAVAILABLE, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "unavailable"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_DISCONNECTED, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "disconnected"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_PREPARE, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "prepare"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_CONFIG, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "config"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_NEED_AUTH, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "need-auth"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_IP_CONFIG, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-config"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_IP_CHECK, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "ip-check"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_SECONDARIES, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "secondaries"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_ACTIVATED, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "activated"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_DEACTIVATING, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "deactivating"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_FAILED, - NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "failed"), ); - -const char * -nm_device_state_to_str(NMDeviceState state) -{ - return queued_state_to_string(state) + NM_STRLEN(NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE); -} - -NM_UTILS_LOOKUP_STR_DEFINE( - nm_device_state_reason_to_str, - NMDeviceStateReason, - NM_UTILS_LOOKUP_DEFAULT(NULL), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNKNOWN, "unknown"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NONE, "none"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NOW_MANAGED, "managed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NOW_UNMANAGED, "unmanaged"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONFIG_FAILED, "config-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE, "ip-config-unavailable"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED, "ip-config-expired"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NO_SECRETS, "no-secrets"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT, "supplicant-disconnect"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_CONFIG_FAILED, - "supplicant-config-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_FAILED, "supplicant-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT, "supplicant-timeout"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_START_FAILED, "ppp-start-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_DISCONNECT, "ppp-disconnect"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PPP_FAILED, "ppp-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_START_FAILED, "dhcp-start-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_ERROR, "dhcp-error"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DHCP_FAILED, "dhcp-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SHARED_START_FAILED, "sharing-start-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SHARED_FAILED, "sharing-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED, "autoip-start-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_ERROR, "autoip-error"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_AUTOIP_FAILED, "autoip-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_BUSY, "modem-busy"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_DIAL_TONE, "modem-no-dialtone"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER, "modem-no-carrier"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_TIMEOUT, "modem-dial-timeout"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_DIAL_FAILED, "modem-dial-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED, "modem-init-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_APN_FAILED, "gsm-apn-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_NOT_SEARCHING, - "gsm-registration-idle"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_DENIED, - "gsm-registration-denied"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_TIMEOUT, - "gsm-registration-timeout"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_REGISTRATION_FAILED, - "gsm-registration-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED, "gsm-pin-check-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_FIRMWARE_MISSING, "firmware-missing"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_REMOVED, "removed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SLEEPING, "sleeping"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_REMOVED, "connection-removed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_USER_REQUESTED, "user-requested"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CARRIER, "carrier-changed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED, "connection-assumed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SUPPLICANT_AVAILABLE, "supplicant-available"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND, "modem-not-found"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_BT_FAILED, "bluetooth-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_NOT_INSERTED, "gsm-sim-not-inserted"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED, "gsm-sim-pin-required"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_PUK_REQUIRED, "gsm-sim-puk-required"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_GSM_SIM_WRONG, "gsm-sim-wrong"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_INFINIBAND_MODE, "infiniband-mode"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DEPENDENCY_FAILED, "dependency-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_BR2684_FAILED, "br2684-bridge-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE, - "modem-manager-unavailable"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SSID_NOT_FOUND, "ssid-not-found"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED, - "secondary-connection-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED, "dcb-fcoe-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_TEAMD_CONTROL_FAILED, "teamd-control-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_FAILED, "modem-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_AVAILABLE, "modem-available"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SIM_PIN_INCORRECT, "sim-pin-incorrect"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NEW_ACTIVATION, "new-activation"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PARENT_CHANGED, "parent-changed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED, - "parent-managed-changed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_OVSDB_FAILED, "ovsdb-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE, "ip-address-duplicate"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_IP_METHOD_UNSUPPORTED, "ip-method-unsupported"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED, - "sriov-configuration-failed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PEER_NOT_FOUND, "peer-not-found"), ); - -#define reason_to_string_a(reason) NM_UTILS_LOOKUP_STR_A(nm_device_state_reason_to_str, reason) - -static NM_UTILS_LOOKUP_STR_DEFINE(mtu_source_to_str, - NMDeviceMtuSource, - NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_NONE, "none"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_PARENT, "parent"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_IP_CONFIG, - "ip-config"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_CONNECTION, - "connection"), ); +static void check_ip_state(NMDevice *self, gboolean may_fail, gboolean full_state_update); /*****************************************************************************/ @@ -908,7 +788,6 @@ _hostname_resolver_free(HostnameResolver *resolver) nm_clear_g_source(&resolver->timeout_id); nm_clear_g_cancellable(&resolver->cancellable); - nm_g_object_unref(resolver->resolver); nm_g_object_unref(resolver->address); g_free(resolver->hostname); nm_g_slice_free(resolver); @@ -952,8 +831,7 @@ _prop_get_connection_stable_id(NMDevice * self, * Especially with ${RANDOM} stable-id we want to generate *one* configuration * for each activation. */ if (G_UNLIKELY(!priv->current_stable_id)) { - gs_free char * default_id = NULL; - gs_free char * generated = NULL; + gs_free char * generated = NULL; NMUtilsStableType stable_type; NMSettingConnection *s_con; gboolean hwaddr_is_fake; @@ -966,11 +844,10 @@ _prop_get_connection_stable_id(NMDevice * self, stable_id = nm_setting_connection_get_stable_id(s_con); if (!stable_id) { - default_id = + stable_id = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, NM_CON_DEFAULT("connection.stable-id"), self); - stable_id = default_id; } uuid = nm_connection_get_uuid(connection); @@ -1029,7 +906,6 @@ _prop_get_ipv6_dhcp_duid(NMDevice * self, { NMSettingIPConfig *s_ip6; const char * duid; - gs_free char * duid_default = NULL; const char * duid_error; GBytes * duid_out; gboolean duid_enforce = TRUE; @@ -1042,10 +918,9 @@ _prop_get_ipv6_dhcp_duid(NMDevice * self, duid = nm_setting_ip6_config_get_dhcp_duid(NM_SETTING_IP6_CONFIG(s_ip6)); if (!duid) { - duid_default = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, - NM_CON_DEFAULT("ipv6.dhcp-duid"), - self); - duid = duid_default; + duid = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv6.dhcp-duid"), + self); if (!duid) duid = "lease"; } @@ -1396,7 +1271,7 @@ _prop_get_ipvx_route_table(NMDevice *self, int addr_family) _LOGT(LOGD_DEVICE, "ipv%c.route-table = %u%s", nm_utils_addr_family_to_char(addr_family), - (guint)(route_table ?: RT_TABLE_MAIN), + (guint) (route_table ?: RT_TABLE_MAIN), route_table != 0u ? "" : " (policy routing not enabled)"); return route_table; @@ -1500,6 +1375,40 @@ out: return timeout; } +static guint32 +_prop_get_ipvx_required_timeout(NMDevice *self, int addr_family) +{ + NMConnection * connection; + NMSettingIPConfig *s_ip; + int timeout; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert_addr_family(addr_family); + + connection = nm_device_get_applied_connection(self); + if (!connection) + return 0; + + s_ip = nm_connection_get_setting_ip_config(connection, addr_family); + if (!s_ip) + return 0; + + timeout = nm_setting_ip_config_get_required_timeout(s_ip); + nm_assert(timeout >= -1); + + if (timeout > -1) + return (guint32) timeout; + + return nm_config_data_get_connection_default_int64( + NM_CONFIG_GET_DATA, + NM_IS_IPv4(addr_family) ? NM_CON_DEFAULT("ipv4.required-timeout") + : NM_CON_DEFAULT("ipv6.required-timeout"), + self, + 0, + G_MAXINT32, + 0); +} + /** * _prop_get_ipvx_dhcp_iaid: * @self: the #NMDevice @@ -1522,7 +1431,6 @@ _prop_get_ipvx_dhcp_iaid(NMDevice * self, const int IS_IPv4 = NM_IS_IPv4(addr_family); NMSettingIPConfig *s_ip; const char * iaid_str; - gs_free char * iaid_str_free = NULL; guint32 iaid; const char * iface; const char * fail_reason; @@ -1531,11 +1439,10 @@ _prop_get_ipvx_dhcp_iaid(NMDevice * self, s_ip = nm_connection_get_setting_ip_config(connection, addr_family); iaid_str = nm_setting_ip_config_get_dhcp_iaid(s_ip); if (!iaid_str) { - iaid_str_free = nm_config_data_get_connection_default( - NM_CONFIG_GET_DATA, - IS_IPv4 ? NM_CON_DEFAULT("ipv4.dhcp-iaid") : NM_CON_DEFAULT("ipv6.dhcp-iaid"), - self); - iaid_str = iaid_str_free; + iaid_str = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, + IS_IPv4 ? NM_CON_DEFAULT("ipv4.dhcp-iaid") + : NM_CON_DEFAULT("ipv6.dhcp-iaid"), + self); if (!iaid_str) { iaid_str = NM_IAID_IFNAME; is_explicit = FALSE; @@ -1566,7 +1473,7 @@ _prop_get_ipvx_dhcp_iaid(NMDevice * self, iaid = unaligned_read_be32(&pllink->l_address.data[pllink->l_address.len - 4]); goto out_good; } else if (nm_streq0(iaid_str, NM_IAID_PERM_MAC)) { - guint8 hwaddr_buf[NM_UTILS_HWADDR_LEN_MAX]; + guint8 hwaddr_buf[_NM_UTILS_HWADDR_LEN_MAX]; const char *hwaddr_str; gsize hwaddr_len; @@ -1692,12 +1599,10 @@ _prop_get_ipvx_dhcp_hostname_flags(NMDevice *self, int addr_family) } static const char * -_prop_get_connection_mud_url(NMDevice *self, NMSettingConnection *s_con, char **out_mud_url) +_prop_get_connection_mud_url(NMDevice *self, NMSettingConnection *s_con) { - const char * mud_url; - gs_free char *s = NULL; - - nm_assert(out_mud_url && !*out_mud_url); + const char *mud_url; + const char *s; mud_url = nm_setting_connection_get_mud_url(s_con); @@ -1714,7 +1619,7 @@ _prop_get_connection_mud_url(NMDevice *self, NMSettingConnection *s_con, char ** if (nm_streq(s, NM_CONNECTION_MUD_URL_NONE)) return NULL; if (nm_sd_http_url_is_valid_https(s)) - return (*out_mud_url = g_steal_pointer(&s)); + return s; } return NULL; @@ -1725,10 +1630,9 @@ _prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes * { NMSettingIPConfig *s_ip4; const char * client_id; - gs_free char * client_id_default = NULL; guint8 * client_id_buf; const char * fail_reason; - guint8 hwaddr_bin_buf[NM_UTILS_HWADDR_LEN_MAX]; + guint8 hwaddr_bin_buf[_NM_UTILS_HWADDR_LEN_MAX]; const guint8 * hwaddr_bin; int arp_type; gsize hwaddr_len; @@ -1739,13 +1643,12 @@ _prop_get_ipv4_dhcp_client_id(NMDevice *self, NMConnection *connection, GBytes * client_id = nm_setting_ip4_config_get_dhcp_client_id(NM_SETTING_IP4_CONFIG(s_ip4)); if (!client_id) { - client_id_default = - nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, - NM_CON_DEFAULT("ipv4.dhcp-client-id"), - self); - if (client_id_default && client_id_default[0]) { + client_id = nm_config_data_get_connection_default(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("ipv4.dhcp-client-id"), + self); + if (client_id && !client_id[0]) { /* a non-empty client-id is always valid, see nm_dhcp_utils_client_id_string_to_bytes(). */ - client_id = client_id_default; + client_id = NULL; } } @@ -1877,8 +1780,7 @@ out_good: static GBytes * _prop_get_ipv4_dhcp_vendor_class_identifier(NMDevice *self, NMSettingIP4Config *s_ip4) { - gs_free char *config_data_prop = NULL; - gs_free char *to_free = NULL; + gs_free char *to_free = NULL; const char * conn_prop; GBytes * bytes = NULL; const char * bin; @@ -1888,13 +1790,13 @@ _prop_get_ipv4_dhcp_vendor_class_identifier(NMDevice *self, NMSettingIP4Config * if (!conn_prop) { /* set in NetworkManager.conf ? */ - config_data_prop = nm_config_data_get_connection_default( + conn_prop = nm_config_data_get_connection_default( NM_CONFIG_GET_DATA, NM_CON_DEFAULT("ipv4.dhcp-vendor-class-identifier"), self); - if (config_data_prop && nm_utils_validate_dhcp4_vendor_class_id(config_data_prop, NULL)) - conn_prop = config_data_prop; + if (conn_prop && !nm_utils_validate_dhcp4_vendor_class_id(conn_prop, NULL)) + conn_prop = NULL; } if (conn_prop) { @@ -1960,16 +1862,11 @@ _prop_get_ipv6_ip6_privacy(NMDevice *self) } static const char * -_prop_get_x_cloned_mac_address(NMDevice * self, - NMConnection *connection, - gboolean is_wifi, - char ** out_addr) +_prop_get_x_cloned_mac_address(NMDevice *self, NMConnection *connection, gboolean is_wifi) { NMSetting * setting; const char *addr = NULL; - nm_assert(out_addr && !*out_addr); - setting = nm_connection_get_setting(connection, is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED); if (setting) { @@ -1978,7 +1875,7 @@ _prop_get_x_cloned_mac_address(NMDevice * self, } if (!addr) { - gs_free char *a = NULL; + const char *a; a = nm_config_data_get_connection_default( NM_CONFIG_GET_DATA, @@ -1993,36 +1890,28 @@ _prop_get_x_cloned_mac_address(NMDevice * self, NMSettingMacRandomization v; /* for backward compatibility, read the deprecated wifi.mac-address-randomization setting. */ - a = nm_config_data_get_connection_default( + v = nm_config_data_get_connection_default_int64( NM_CONFIG_GET_DATA, NM_CON_DEFAULT("wifi.mac-address-randomization"), - self); - v = _nm_utils_ascii_str_to_int64(a, - 10, - NM_SETTING_MAC_RANDOMIZATION_DEFAULT, - NM_SETTING_MAC_RANDOMIZATION_ALWAYS, - NM_SETTING_MAC_RANDOMIZATION_DEFAULT); + self, + NM_SETTING_MAC_RANDOMIZATION_DEFAULT, + NM_SETTING_MAC_RANDOMIZATION_ALWAYS, + NM_SETTING_MAC_RANDOMIZATION_DEFAULT); if (v == NM_SETTING_MAC_RANDOMIZATION_ALWAYS) addr = NM_CLONED_MAC_RANDOM; } } else if (NM_CLONED_MAC_IS_SPECIAL(a) || nm_utils_hwaddr_valid(a, ETH_ALEN)) - addr = *out_addr = g_steal_pointer(&a); + addr = a; } return addr; } static const char * -_prop_get_x_generate_mac_address_mask(NMDevice * self, - NMConnection *connection, - gboolean is_wifi, - char ** out_value) +_prop_get_x_generate_mac_address_mask(NMDevice *self, NMConnection *connection, gboolean is_wifi) { NMSetting * setting; - const char *value = NULL; - char * a; - - nm_assert(out_value && !*out_value); + const char *value; setting = nm_connection_get_setting(connection, is_wifi ? NM_TYPE_SETTING_WIRELESS : NM_TYPE_SETTING_WIRED); @@ -2035,15 +1924,11 @@ _prop_get_x_generate_mac_address_mask(NMDevice * self, return value; } - a = nm_config_data_get_connection_default( + return nm_config_data_get_connection_default( NM_CONFIG_GET_DATA, is_wifi ? NM_CON_DEFAULT("wifi.generate-mac-address-mask") : NM_CON_DEFAULT("ethernet.generate-mac-address-mask"), self); - if (!a) - return NULL; - *out_value = a; - return a; } /*****************************************************************************/ @@ -2271,6 +2156,113 @@ _ethtool_ring_set(NMDevice * self, _LOGD(LOGD_DEVICE, "ethtool: ring settings successfully set"); } +static void +_ethtool_pause_reset(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state) +{ + gs_free NMEthtoolPauseState *pause = NULL; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_PLATFORM(platform)); + nm_assert(ethtool_state); + + pause = g_steal_pointer(ðtool_state->pause); + if (!pause) + return; + + if (!nm_platform_ethtool_set_pause(platform, ethtool_state->ifindex, pause)) + _LOGW(LOGD_DEVICE, "ethtool: failure resetting one or more pause settings"); + else + _LOGD(LOGD_DEVICE, "ethtool: pause settings successfully reset"); +} + +static void +_ethtool_pause_set(NMDevice * self, + NMPlatform * platform, + EthtoolState * ethtool_state, + NMSettingEthtool *s_ethtool) +{ + NMEthtoolPauseState pause_old; + NMEthtoolPauseState pause_new; + GHashTable * hash; + GHashTableIter iter; + const char * name; + GVariant * variant; + gboolean has_old = FALSE; + NMTernary pause_autoneg = NM_TERNARY_DEFAULT; + NMTernary pause_rx = NM_TERNARY_DEFAULT; + NMTernary pause_tx = NM_TERNARY_DEFAULT; + + nm_assert(NM_IS_DEVICE(self)); + nm_assert(NM_IS_PLATFORM(platform)); + nm_assert(NM_IS_SETTING_ETHTOOL(s_ethtool)); + nm_assert(ethtool_state); + nm_assert(!ethtool_state->pause); + + hash = _nm_setting_option_hash(NM_SETTING(s_ethtool), FALSE); + if (!hash) + return; + + g_hash_table_iter_init(&iter, hash); + while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) { + NMEthtoolID ethtool_id = nm_ethtool_id_get_by_name(name); + + if (!nm_ethtool_id_is_pause(ethtool_id)) + continue; + + nm_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_BOOLEAN)); + + if (!has_old) { + if (!nm_platform_ethtool_get_link_pause(platform, ethtool_state->ifindex, &pause_old)) { + _LOGW(LOGD_DEVICE, + "ethtool: failure setting pause options (cannot read " + "existing setting)"); + return; + } + has_old = TRUE; + } + + switch (ethtool_id) { + case NM_ETHTOOL_ID_PAUSE_AUTONEG: + pause_autoneg = g_variant_get_boolean(variant); + break; + case NM_ETHTOOL_ID_PAUSE_RX: + pause_rx = g_variant_get_boolean(variant); + break; + case NM_ETHTOOL_ID_PAUSE_TX: + pause_tx = g_variant_get_boolean(variant); + break; + default: + nm_assert_not_reached(); + } + } + + if (!has_old) + return; + + if (pause_rx != NM_TERNARY_DEFAULT || pause_tx != NM_TERNARY_DEFAULT) { + /* this implies to explicitly disable autoneg. */ + nm_assert(pause_autoneg != NM_TERNARY_TRUE); + pause_autoneg = NM_TERNARY_FALSE; + } + + pause_new = pause_old; + if (pause_autoneg != NM_TERNARY_DEFAULT) + pause_new.autoneg = !!pause_autoneg; + if (pause_rx != NM_TERNARY_DEFAULT) + pause_new.rx = !!pause_rx; + if (pause_tx != NM_TERNARY_DEFAULT) + pause_new.tx = !!pause_tx; + + ethtool_state->pause = nm_memdup(&pause_old, sizeof(pause_old)); + + if (!nm_platform_ethtool_set_pause(platform, ethtool_state->ifindex, &pause_new)) { + _LOGW(LOGD_DEVICE, "ethtool: failure setting pause settings"); + return; + } + + _LOGD(LOGD_DEVICE, "ethtool: pause settings successfully set"); +} + static void _ethtool_state_reset(NMDevice *self) { @@ -2287,6 +2279,8 @@ _ethtool_state_reset(NMDevice *self) _ethtool_coalesce_reset(self, platform, ethtool_state); if (ethtool_state->ring) _ethtool_ring_reset(self, platform, ethtool_state); + if (ethtool_state->pause) + _ethtool_pause_reset(self, platform, ethtool_state); } static void @@ -2320,8 +2314,10 @@ _ethtool_state_set(NMDevice *self) _ethtool_features_set(self, platform, ethtool_state, s_ethtool); _ethtool_coalesce_set(self, platform, ethtool_state, s_ethtool); _ethtool_ring_set(self, platform, ethtool_state, s_ethtool); + _ethtool_pause_set(self, platform, ethtool_state, s_ethtool); - if (ethtool_state->features || ethtool_state->coalesce || ethtool_state->ring) + if (ethtool_state->features || ethtool_state->coalesce || ethtool_state->ring + || ethtool_state->pause) priv->ethtool_state = g_steal_pointer(ðtool_state); } @@ -2520,15 +2516,6 @@ applied_config_reset_nameservers(AppliedConfig *config) /*****************************************************************************/ -static NM_UTILS_LOOKUP_STR_DEFINE( - _sys_iface_state_to_str, - NMDeviceSysIfaceState, - NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, "external"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_ASSUME, "assume"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_MANAGED, "managed"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_REMOVED, "removed"), ); - NMDeviceSysIfaceState nm_device_sys_iface_state_get(NMDevice *self) { @@ -2567,8 +2554,8 @@ nm_device_sys_iface_state_set(NMDevice *self, NMDeviceSysIfaceState sys_iface_st if (priv->sys_iface_state != sys_iface_state) { _LOGT(LOGD_DEVICE, "sys-iface-state: %s -> %s", - _sys_iface_state_to_str(priv->sys_iface_state), - _sys_iface_state_to_str(sys_iface_state)); + nm_device_sys_iface_state_to_str(priv->sys_iface_state), + nm_device_sys_iface_state_to_str(sys_iface_state)); priv->sys_iface_state_ = sys_iface_state; } @@ -2599,6 +2586,42 @@ _active_connection_set_state_flags(NMDevice *self, NMActivationStateFlags flags) /*****************************************************************************/ +static gboolean +set_interface_flags_full(NMDevice * self, + NMDeviceInterfaceFlags mask, + NMDeviceInterfaceFlags interface_flags, + gboolean notify) +{ + NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceInterfaceFlags f; + + nm_assert(!!mask); + nm_assert(!NM_FLAGS_ANY(mask, ~_NM_DEVICE_INTERFACE_FLAG_ALL)); + nm_assert(!NM_FLAGS_ANY(interface_flags, ~mask)); + + f = (priv->interface_flags & ~mask) | (interface_flags & mask); + + if (f == priv->interface_flags) + return FALSE; + + priv->interface_flags = f; + if (notify) + _notify(self, PROP_INTERFACE_FLAGS); + return TRUE; +} + +static gboolean +set_interface_flags(NMDevice * self, + NMDeviceInterfaceFlags interface_flags, + gboolean set, + gboolean notify) +{ + return set_interface_flags_full(self, + interface_flags, + set ? interface_flags : NM_DEVICE_INTERFACE_FLAG_NONE, + notify); +} + void nm_device_assume_state_get(NMDevice * self, gboolean * out_assume_state_guess_assume, @@ -2809,23 +2832,72 @@ _add_capabilities(NMDevice *self, NMDeviceCapabilities capabilities) /*****************************************************************************/ -static NM_UTILS_LOOKUP_STR_DEFINE(_ip_state_to_string, - NMDeviceIPState, - NM_UTILS_LOOKUP_DEFAULT_WARN("unknown"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_NONE, "none"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_WAIT, "wait"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_CONF, "conf"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_DONE, "done"), - NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_FAIL, "fail"), ); +static gboolean +ip_required_timeout_x(NMDevice *self, int addr_family) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + + _LOGD(LOGD_CORE, + "required-timeout expired for IPv%c", + nm_utils_addr_family_to_char(addr_family)); + nm_clear_g_source_inst(&priv->ip_req_timeout_source_x[NM_IS_IPv4(addr_family)]); + check_ip_state(self, FALSE, TRUE); + return G_SOURCE_CONTINUE; +} + +static gboolean +ip_required_timeout_4(gpointer data) +{ + return ip_required_timeout_x(data, AF_INET); +} + +static gboolean +ip_required_timeout_6(gpointer data) +{ + return ip_required_timeout_x(data, AF_INET6); +} static void _set_ip_state(NMDevice *self, int addr_family, NMDeviceIPState new_state) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); const int IS_IPv4 = NM_IS_IPv4(addr_family); + guint timeout_msec; + int v4; nm_assert_addr_family(addr_family); + if (new_state == NM_DEVICE_IP_STATE_CONF && !priv->ip_config_started) { + /* Start the required-timeout timers when one of IPv4/IPv6 + * enters the CONF state. This means that if there is no carrier and + * ipv4.method=auto,ipv6.method=manual, the timeout for IPv4 will + * start as soon as connection is activated, even if DHCPv4 did not + * start yet. + */ + priv->ip_config_started = TRUE; + + for (v4 = 1; v4 >= 0; v4--) { + char buf[32]; + + nm_assert(!priv->ip_req_timeout_source_x[v4]); + if ((timeout_msec = _prop_get_ipvx_required_timeout(self, v4 ? AF_INET : AF_INET6))) { + _LOGD(LOGD_CORE, + "required-timeout in %s msec for IPv%c", + timeout_msec == G_MAXINT32 ? "∞" : nm_sprintf_buf(buf, "%u", timeout_msec), + v4 ? '4' : '6'); + + if (timeout_msec == G_MAXINT32) { + priv->ip_req_timeout_source_x[v4] = g_source_ref(nm_g_source_sentinel_get(0)); + } else { + priv->ip_req_timeout_source_x[v4] = + nm_g_timeout_add_source(timeout_msec, + v4 ? ip_required_timeout_4 : ip_required_timeout_6, + self); + } + } + } + } + if (priv->ip_state_x[IS_IPv4] == new_state) return; @@ -2833,7 +2905,7 @@ _set_ip_state(NMDevice *self, int addr_family, NMDeviceIPState new_state) "ip%c-state: set to %d (%s)", nm_utils_addr_family_to_char(addr_family), (int) new_state, - _ip_state_to_string(new_state)); + nm_device_ip_state_to_str(new_state)); priv->ip_state_x_[IS_IPv4] = new_state; @@ -2942,10 +3014,10 @@ nm_device_take_over_link(NMDevice *self, int ifindex, char **old_name, GError ** /* Rename the link to the device ifname */ if (up) - nm_platform_link_set_down(platform, ifindex); + nm_platform_link_change_flags(platform, ifindex, IFF_UP, FALSE); success = nm_platform_link_set_name(platform, ifindex, nm_device_get_iface(self)); if (up) - nm_platform_link_set_up(platform, ifindex, NULL); + nm_platform_link_change_flags(platform, ifindex, IFF_UP, TRUE); if (!success) { nm_utils_error_set(error, NM_UTILS_ERROR_UNKNOWN, "failure renaming link %d", ifindex); @@ -3073,7 +3145,7 @@ _set_ip_ifindex(NMDevice *self, int ifindex, const char *ifname) nm_platform_link_set_user_ipv6ll_enabled(platform, priv->ip_ifindex, TRUE); if (!nm_platform_link_is_up(platform, priv->ip_ifindex)) - nm_platform_link_set_up(platform, priv->ip_ifindex, NULL); + nm_platform_link_change_flags(platform, priv->ip_ifindex, IFF_UP, TRUE); } /* We don't care about any saved values from the old iface */ @@ -4865,7 +4937,6 @@ void nm_device_update_dynamic_ip_setup(NMDevice *self) { NMDevicePrivate *priv; - GError * error = NULL; g_return_if_fail(NM_IS_DEVICE(self)); @@ -4898,17 +4969,6 @@ nm_device_update_dynamic_ip_setup(NMDevice *self) if (priv->dnsmasq_manager) { /* FIXME: todo */ } - - if (priv->lldp_listener && nm_lldp_listener_is_running(priv->lldp_listener)) { - nm_lldp_listener_stop(priv->lldp_listener); - if (!nm_lldp_listener_start(priv->lldp_listener, nm_device_get_ifindex(self), &error)) { - _LOGD(LOGD_DEVICE, - "LLDP listener %p could not be restarted: %s", - priv->lldp_listener, - error->message); - g_clear_error(&error); - } - } } /*****************************************************************************/ @@ -5025,18 +5085,12 @@ nm_device_set_carrier(NMDevice *self, gboolean carrier) if (NM_FLAGS_ALL(priv->capabilities, NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NONSTANDARD_CARRIER)) { - if (carrier) - priv->interface_flags |= NM_DEVICE_INTERFACE_FLAG_CARRIER; - else - priv->interface_flags &= ~NM_DEVICE_INTERFACE_FLAG_CARRIER; - notify_flags = TRUE; + notify_flags = set_interface_flags(self, NM_DEVICE_INTERFACE_FLAG_CARRIER, carrier, FALSE); } priv->carrier = carrier; - if (notify_flags) - nm_gobject_notify_together(self, PROP_CARRIER, PROP_INTERFACE_FLAGS); - else - _notify(self, PROP_CARRIER); + + nm_gobject_notify_together(self, PROP_CARRIER, notify_flags ? PROP_INTERFACE_FLAGS : PROP_0); if (priv->carrier) { _LOGI(LOGD_DEVICE, "carrier: link connected"); @@ -5215,11 +5269,11 @@ ndisc_set_router_config(NMNDisc *ndisc, NMDevice *self) if (addr->plen != 64) continue; - lifetime = nm_utils_lifetime_get(addr->timestamp, - addr->lifetime, - addr->preferred, - NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000, - &preferred); + lifetime = nmp_utils_lifetime_get(addr->timestamp, + addr->lifetime, + addr->preferred, + NM_NDISC_EXPIRY_BASE_TIMESTAMP / 1000, + &preferred); if (!lifetime) continue; @@ -5271,6 +5325,8 @@ device_update_interface_flags(NMDevice *self, const NMPlatformLink *plink) flags |= NM_DEVICE_INTERFACE_FLAG_UP; if (plink && NM_FLAGS_HAS(plink->n_ifi_flags, IFF_LOWER_UP)) flags |= NM_DEVICE_INTERFACE_FLAG_LOWER_UP; + if (plink && NM_FLAGS_HAS(plink->n_ifi_flags, IFF_PROMISC)) + flags |= NM_DEVICE_INTERFACE_FLAG_PROMISC; if (NM_FLAGS_ALL(priv->capabilities, NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_NONSTANDARD_CARRIER)) { @@ -5281,10 +5337,12 @@ device_update_interface_flags(NMDevice *self, const NMPlatformLink *plink) flags |= NM_DEVICE_INTERFACE_FLAG_CARRIER; } - if (flags != priv->interface_flags) { - priv->interface_flags = flags; - _notify(self, PROP_INTERFACE_FLAGS); - } + set_interface_flags_full(self, + NM_DEVICE_INTERFACE_FLAG_UP | NM_DEVICE_INTERFACE_FLAG_LOWER_UP + | NM_DEVICE_INTERFACE_FLAG_CARRIER + | NM_DEVICE_INTERFACE_FLAG_PROMISC, + flags, + TRUE); } static gboolean @@ -5891,16 +5949,19 @@ sriov_op_queue(NMDevice * self, static void device_init_static_sriov_num_vfs(NMDevice *self) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - gs_free char * value = NULL; - int num_vfs; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); if (priv->ifindex > 0 && nm_device_has_capability(self, NM_DEVICE_CAP_SRIOV)) { - value = nm_config_data_get_device_config(NM_CONFIG_GET_DATA, - NM_CONFIG_KEYFILE_KEY_DEVICE_SRIOV_NUM_VFS, - self, - NULL); - num_vfs = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXINT32, -1); + int num_vfs; + + num_vfs = nm_config_data_get_device_config_int64(NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_SRIOV_NUM_VFS, + self, + 10, + 0, + G_MAXINT32, + -1, + -1); if (num_vfs >= 0) sriov_op_queue(self, num_vfs, NM_OPTION_BOOL_DEFAULT, NULL, NULL); } @@ -6618,6 +6679,7 @@ check_ip_state(NMDevice *self, gboolean may_fail, gboolean full_state_update) gboolean ip4_disabled = FALSE, ip6_disabled = FALSE; NMSettingIPConfig *s_ip4, *s_ip6; NMDeviceState state; + int IS_IPv4; if (full_state_update && nm_device_get_state(self) != NM_DEVICE_STATE_IP_CONFIG) return; @@ -6647,6 +6709,13 @@ check_ip_state(NMDevice *self, gboolean may_fail, gboolean full_state_update) return; } + for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) { + if (priv->ip_state_x[IS_IPv4] == NM_DEVICE_IP_STATE_CONF + && priv->ip_req_timeout_source_x[IS_IPv4]) { + return; + } + } + if ((priv->ip_state_4 == NM_DEVICE_IP_STATE_FAIL || (ip4_disabled && priv->ip_state_4 == NM_DEVICE_IP_STATE_DONE)) && (priv->ip_state_6 == NM_DEVICE_IP_STATE_FAIL @@ -7170,6 +7239,16 @@ _get_maybe_ipv6_disabled(NMDevice *self) return (nm_platform_sysctl_get_int32(platform, NMP_SYSCTL_PATHID_ABSOLUTE(path), 0) == 0); } +/* + * nm_device_generate_connection: + * + * Generates a connection from an existing interface. + * + * If the device doesn't have an IP configuration and it's not a port or a + * controller, then no connection gets generated and the function returns + * %NULL. In such case, @maybe_later is set to %TRUE if a connection can be + * generated later when an IP address is assigned to the interface. + */ NMConnection * nm_device_generate_connection(NMDevice *self, NMDevice *master, @@ -7214,7 +7293,7 @@ nm_device_generate_connection(NMDevice *self, g_object_set(s_con, NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_buf(uuid), + nm_uuid_generate_random_str_arr(uuid), NM_SETTING_CONNECTION_ID, ifname, NM_SETTING_CONNECTION_AUTOCONNECT, @@ -7426,6 +7505,8 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e gs_free char * conn_iface = NULL; NMDeviceClass * klass; NMSettingMatch * s_match; + const GSList * specs; + gboolean has_match = FALSE; klass = NM_DEVICE_GET_CLASS(self); if (klass->connection_type_check_compatible) { @@ -7466,11 +7547,10 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e s_match = (NMSettingMatch *) nm_connection_get_setting(connection, NM_TYPE_SETTING_MATCH); if (s_match) { const char *const *patterns; - const char * device_driver; guint num_patterns = 0; patterns = nm_setting_match_get_interface_names(s_match, &num_patterns); - if (!nm_wildcard_match_check(device_iface, patterns, num_patterns)) { + if (num_patterns > 0 && !nm_wildcard_match_check(device_iface, patterns, num_patterns)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "device does not satisfy match.interface-name property"); @@ -7485,9 +7565,9 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e error)) return FALSE; - device_driver = nm_device_get_driver(self); - patterns = nm_setting_match_get_drivers(s_match, &num_patterns); - if (!nm_wildcard_match_check(device_driver, patterns, num_patterns)) { + patterns = nm_setting_match_get_drivers(s_match, &num_patterns); + if (num_patterns > 0 + && !nm_wildcard_match_check(nm_device_get_driver(self), patterns, num_patterns)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "device does not satisfy match.driver property"); @@ -7495,7 +7575,7 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e } patterns = nm_setting_match_get_paths(s_match, &num_patterns); - if (!nm_wildcard_match_check(priv->path, patterns, num_patterns)) { + if (num_patterns > 0 && !nm_wildcard_match_check(priv->path, patterns, num_patterns)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, "device does not satisfy match.path property"); @@ -7503,6 +7583,15 @@ check_connection_compatible(NMDevice *self, NMConnection *connection, GError **e } } + specs = + nm_config_data_get_device_allowed_connections_specs(NM_CONFIG_GET_DATA, self, &has_match); + if (has_match && !nm_utils_connection_match_spec_list(connection, specs, FALSE)) { + nm_utils_error_set_literal(error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_DISALLOWED, + "device configuration doesn't allow this connection"); + return FALSE; + } + return TRUE; } @@ -7569,7 +7658,7 @@ nm_device_check_slave_connection_compatible(NMDevice *self, NMConnection *slave) * * Returns: %TRUE if the device is capable of assuming connections, %FALSE if not */ -static gboolean +gboolean nm_device_can_assume_connections(NMDevice *self) { return !!NM_DEVICE_GET_CLASS(self)->update_connection; @@ -7924,14 +8013,6 @@ master_ready_cb(NMActiveConnection *active, GParamSpec *pspec, NMDevice *self) nm_device_activate_schedule_stage1_device_prepare(self, FALSE); } -static void -lldp_neighbors_changed(NMLldpListener *lldp_listener, GParamSpec *pspec, gpointer user_data) -{ - NMDevice *self = NM_DEVICE(user_data); - - _notify(self, PROP_LLDP_NEIGHBORS); -} - static NMPlatformVF * sriov_vf_config_to_platform(NMDevice *self, NMSriovVF *vf, GError **error) { @@ -8219,38 +8300,56 @@ act_stage2_config(NMDevice *self, NMDeviceStateReason *out_failure_reason) } static void -lldp_init(NMDevice *self, gboolean restart) +_lldp_neighbors_changed_cb(NMLldpListener *lldp_listener, gpointer user_data) +{ + _notify(user_data, PROP_LLDP_NEIGHBORS); +} + +static void +lldp_setup(NMDevice *self, NMTernary enabled) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + int ifindex; + gboolean notify_lldp_neighbors = FALSE; + gboolean notify_interface_flags = FALSE; - if (priv->ifindex > 0 && _prop_get_connection_lldp(self)) { - gs_free_error GError *error = NULL; + ifindex = nm_device_get_ifindex(self); - if (priv->lldp_listener) { - if (restart && nm_lldp_listener_is_running(priv->lldp_listener)) - nm_lldp_listener_stop(priv->lldp_listener); - } else { - priv->lldp_listener = nm_lldp_listener_new(); - g_signal_connect(priv->lldp_listener, - "notify::" NM_LLDP_LISTENER_NEIGHBORS, - G_CALLBACK(lldp_neighbors_changed), - self); - } + if (ifindex <= 0) + enabled = FALSE; + else if (enabled == NM_TERNARY_DEFAULT) + enabled = _prop_get_connection_lldp(self); - if (!nm_lldp_listener_is_running(priv->lldp_listener)) { - if (nm_lldp_listener_start(priv->lldp_listener, nm_device_get_ifindex(self), &error)) - _LOGD(LOGD_DEVICE, "LLDP listener %p started", priv->lldp_listener); - else { - _LOGD(LOGD_DEVICE, - "LLDP listener %p could not be started: %s", - priv->lldp_listener, - error->message); - } + if (priv->lldp_listener) { + if (!enabled || nm_lldp_listener_get_ifindex(priv->lldp_listener) != ifindex) { + nm_clear_pointer(&priv->lldp_listener, nm_lldp_listener_destroy); + notify_lldp_neighbors = TRUE; } - } else { - if (priv->lldp_listener) - nm_lldp_listener_stop(priv->lldp_listener); } + + if (enabled && !priv->lldp_listener) { + gs_free_error GError *error = NULL; + + priv->lldp_listener = + nm_lldp_listener_new(ifindex, _lldp_neighbors_changed_cb, self, &error); + if (!priv->lldp_listener) { + /* This really shouldn't happen. It's likely a bug. Investigate when this happens! */ + _LOGW(LOGD_DEVICE, + "LLDP listener for ifindex %d could not be started: %s", + ifindex, + error->message); + } else + notify_lldp_neighbors = TRUE; + } + + notify_interface_flags = set_interface_flags(self, + NM_DEVICE_INTERFACE_FLAG_LLDP_CLIENT_ENABLED, + !!priv->lldp_listener, + FALSE); + + nm_gobject_notify_together(self, + notify_lldp_neighbors ? PROP_LLDP_NEIGHBORS : PROP_0, + notify_interface_flags ? PROP_INTERFACE_FLAGS : PROP_0); } /* set-mode can be: @@ -8401,8 +8500,10 @@ activate_stage2_device_config(NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); NMDeviceClass * klass; NMActStageReturn ret; + NMSettingWired * s_wired; gboolean no_firmware = FALSE; CList * iter; + NMTernary accept_all_mac_addresses; nm_device_state_changed(self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE); @@ -8460,7 +8561,30 @@ activate_stage2_device_config(NMDevice *self) nm_device_queue_recheck_assume(info->slave); } - lldp_init(self, TRUE); + s_wired = nm_device_get_applied_setting(self, NM_TYPE_SETTING_WIRED); + accept_all_mac_addresses = + s_wired ? nm_setting_wired_get_accept_all_mac_addresses(s_wired) : NM_TERNARY_DEFAULT; + if (accept_all_mac_addresses != NM_TERNARY_DEFAULT) { + int ifindex = nm_device_get_ip_ifindex(self); + + if (ifindex > 0) { + int ifi_flags = + nm_platform_link_get_ifi_flags(nm_device_get_platform(self), ifindex, IFF_PROMISC); + + if (ifi_flags >= 0 && ((!!ifi_flags) != (!!accept_all_mac_addresses))) { + nm_platform_link_change_flags(nm_device_get_platform(self), + ifindex, + IFF_PROMISC, + !!accept_all_mac_addresses); + if (priv->promisc_reset == NM_OPTION_BOOL_DEFAULT) + priv->promisc_reset = !accept_all_mac_addresses; + } + } + } + + lldp_setup(self, NM_TERNARY_DEFAULT); + + _commit_mtu(self, NULL); nm_device_activate_schedule_stage3_ip_config_start(self); } @@ -8877,6 +9001,21 @@ ensure_con_ip_config(NMDevice *self, int addr_family) /*****************************************************************************/ +static const char * +_device_get_dhcp_anycast_address(NMDevice *self) +{ + NMDeviceClass *klass; + + nm_assert(NM_IS_DEVICE(self)); + + klass = NM_DEVICE_GET_CLASS(self); + + if (klass->get_dhcp_anycast_address) + return klass->get_dhcp_anycast_address(self); + + return NULL; +} + static void dhcp4_cleanup(NMDevice *self, CleanupType cleanup_type, gboolean release) { @@ -9234,7 +9373,7 @@ dhcp4_fail(NMDevice *self, NMDhcpState dhcp_state) _LOGD(LOGD_DHCP4, "DHCPv4 failed (ip_state %s, was_active %d)", - _ip_state_to_string(priv->ip_state_4), + nm_device_ip_state_to_str(priv->ip_state_4), priv->dhcp_data_4.was_active); /* The client is always left running after a failure. */ @@ -9382,12 +9521,13 @@ dhcp4_start(NMDevice *self) gs_unref_bytes GBytes *hwaddr = NULL; gs_unref_bytes GBytes *bcast_hwaddr = NULL; gs_unref_bytes GBytes *client_id = NULL; - gs_free char * mud_url_free = NULL; NMConnection * connection; NMSettingConnection * s_con; GError * error = NULL; const NMPlatformLink * pllink; const char *const * reject_servers; + gboolean request_broadcast; + const char * str; connection = nm_device_get_applied_connection(self); g_return_val_if_fail(connection, FALSE); @@ -9401,10 +9541,22 @@ dhcp4_start(NMDevice *self) nm_dbus_object_clear_and_unexport(&priv->dhcp_data_4.config); priv->dhcp_data_4.config = nm_dhcp_config_new(AF_INET); + request_broadcast = FALSE; + pllink = nm_platform_link_get(nm_device_get_platform(self), nm_device_get_ip_ifindex(self)); if (pllink) { hwaddr = nmp_link_address_get_as_bytes(&pllink->l_address); bcast_hwaddr = nmp_link_address_get_as_bytes(&pllink->l_broadcast); + + str = nmp_object_link_udev_device_get_property_value(NMP_OBJECT_UP_CAST(pllink), + "ID_NET_DHCP_BROADCAST"); + if (str && _nm_utils_ascii_str_to_bool(str, FALSE)) { + /* Use the device property ID_NET_DHCP_BROADCAST setting, which may be set for interfaces + * requiring that the DHCPOFFER message is being broadcast because they can't handle unicast + * messages while not fully configured. + */ + request_broadcast = TRUE; + } } client_id = _prop_get_ipv4_dhcp_client_id(self, connection, hwaddr); @@ -9413,28 +9565,29 @@ dhcp4_start(NMDevice *self) reject_servers = nm_setting_ip_config_get_dhcp_reject_servers(s_ip4, NULL); g_warn_if_fail(priv->dhcp_data_4.client == NULL); - priv->dhcp_data_4.client = - nm_dhcp_manager_start_ip4(nm_dhcp_manager_get(), - nm_netns_get_multi_idx(nm_device_get_netns(self)), - nm_device_get_ip_iface(self), - nm_device_get_ip_ifindex(self), - hwaddr, - bcast_hwaddr, - nm_connection_get_uuid(connection), - nm_device_get_route_table(self, AF_INET), - nm_device_get_route_metric(self, AF_INET), - nm_setting_ip_config_get_dhcp_send_hostname(s_ip4), - nm_setting_ip_config_get_dhcp_hostname(s_ip4), - nm_setting_ip4_config_get_dhcp_fqdn(NM_SETTING_IP4_CONFIG(s_ip4)), - _prop_get_ipvx_dhcp_hostname_flags(self, AF_INET), - _prop_get_connection_mud_url(self, s_con, &mud_url_free), - client_id, - _prop_get_ipvx_dhcp_timeout(self, AF_INET), - priv->dhcp_anycast_address, - NULL, - vendor_class_identifier, - reject_servers, - &error); + priv->dhcp_data_4.client = nm_dhcp_manager_start_ip4( + nm_dhcp_manager_get(), + nm_netns_get_multi_idx(nm_device_get_netns(self)), + nm_device_get_ip_iface(self), + nm_device_get_ip_ifindex(self), + hwaddr, + bcast_hwaddr, + nm_connection_get_uuid(connection), + nm_device_get_route_table(self, AF_INET), + nm_device_get_route_metric(self, AF_INET), + request_broadcast ? NM_DHCP_CLIENT_FLAGS_REQUEST_BROADCAST : NM_DHCP_CLIENT_FLAGS_NONE, + nm_setting_ip_config_get_dhcp_send_hostname(s_ip4), + nm_setting_ip_config_get_dhcp_hostname(s_ip4), + nm_setting_ip4_config_get_dhcp_fqdn(NM_SETTING_IP4_CONFIG(s_ip4)), + _prop_get_ipvx_dhcp_hostname_flags(self, AF_INET), + _prop_get_connection_mud_url(self, s_con), + client_id, + _prop_get_ipvx_dhcp_timeout(self, AF_INET), + _device_get_dhcp_anycast_address(self), + NULL, + vendor_class_identifier, + reject_servers, + &error); if (!priv->dhcp_data_4.client) { _LOGW(LOGD_DHCP4, "failure to start DHCP: %s", error->message); g_clear_error(&error); @@ -9665,7 +9818,7 @@ dhcp6_fail(NMDevice *self, NMDhcpState dhcp_state) _LOGD(LOGD_DHCP6, "DHCPv6 failed (ip_state %s, was_active %d)", - _ip_state_to_string(priv->ip_state_6), + nm_device_ip_state_to_str(priv->ip_state_6), priv->dhcp_data_6.was_active); /* The client is always left running after a failure. */ @@ -9831,12 +9984,12 @@ dhcp6_start_with_link_ready(NMDevice *self, NMConnection *connection) gs_unref_bytes GBytes * duid = NULL; gboolean enforce_duid = FALSE; const NMPlatformLink * pllink; - gs_free char * mud_url_free = NULL; - GError * error = NULL; + GError * error = NULL; guint32 iaid; gboolean iaid_explicit; NMSettingConnection * s_con; const NMPlatformIP6Address *ll_addr = NULL; + int ip_ifindex; g_return_val_if_fail(connection, FALSE); @@ -9846,9 +9999,9 @@ dhcp6_start_with_link_ready(NMDevice *self, NMConnection *connection) nm_assert(s_con); if (priv->ext_ip6_config_captured) { - ll_addr = nm_ip6_config_find_first_address(priv->ext_ip6_config_captured, - NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL); + ll_addr = nm_ip_config_find_first_address(NM_IP_CONFIG(priv->ext_ip6_config_captured), + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL); } if (!ll_addr) { @@ -9856,7 +10009,13 @@ dhcp6_start_with_link_ready(NMDevice *self, NMConnection *connection) return FALSE; } - pllink = nm_platform_link_get(nm_device_get_platform(self), nm_device_get_ip_ifindex(self)); + ip_ifindex = nm_device_get_ip_ifindex(self); + if (ip_ifindex <= 0) { + _LOGD(LOGD_DHCP6, "can't start DHCPv6: interface is gone"); + return FALSE; + } + + pllink = nm_platform_link_get(nm_device_get_platform(self), ip_ifindex); if (pllink) hwaddr = nmp_link_address_get_as_bytes(&pllink->l_address); @@ -9867,22 +10026,23 @@ dhcp6_start_with_link_ready(NMDevice *self, NMConnection *connection) nm_dhcp_manager_get(), nm_device_get_multi_index(self), nm_device_get_ip_iface(self), - nm_device_get_ip_ifindex(self), + ip_ifindex, &ll_addr->address, nm_connection_get_uuid(connection), nm_device_get_route_table(self, AF_INET6), nm_device_get_route_metric(self, AF_INET6), + (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? NM_DHCP_CLIENT_FLAGS_INFO_ONLY + : NM_DHCP_CLIENT_FLAGS_NONE, nm_setting_ip_config_get_dhcp_send_hostname(s_ip6), nm_setting_ip_config_get_dhcp_hostname(s_ip6), _prop_get_ipvx_dhcp_hostname_flags(self, AF_INET6), - _prop_get_connection_mud_url(self, s_con, &mud_url_free), + _prop_get_connection_mud_url(self, s_con), duid, enforce_duid, iaid, iaid_explicit, _prop_get_ipvx_dhcp_timeout(self, AF_INET6), - priv->dhcp_anycast_address, - (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, + _device_get_dhcp_anycast_address(self), nm_setting_ip6_config_get_ip6_privacy(NM_SETTING_IP6_CONFIG(s_ip6)), priv->dhcp6.needed_prefixes, &error); @@ -10088,9 +10248,9 @@ linklocal6_check_complete(NMDevice *self) } if (!priv->ext_ip6_config_captured - || !nm_ip6_config_find_first_address(priv->ext_ip6_config_captured, - NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) { + || !nm_ip_config_find_first_address(NM_IP_CONFIG(priv->ext_ip6_config_captured), + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) { /* we don't have a non-tentative link local address yet. Wait longer. */ return; } @@ -10136,10 +10296,10 @@ check_and_add_ipv6ll_addr(NMDevice *self) return; if (priv->ext_ip6_config_captured - && nm_ip6_config_find_first_address(priv->ext_ip6_config_captured, - NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE)) { + && nm_ip_config_find_first_address(NM_IP_CONFIG(priv->ext_ip6_config_captured), + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_TENTATIVE)) { /* Already have an LL address, nothing to do */ return; } @@ -10209,9 +10369,9 @@ linklocal6_start(NMDevice *self) nm_clear_g_source(&priv->linklocal6_timeout_id); if (priv->ext_ip6_config_captured - && nm_ip6_config_find_first_address(priv->ext_ip6_config_captured, - NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) + && nm_ip_config_find_first_address(NM_IP_CONFIG(priv->ext_ip6_config_captured), + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL)) return TRUE; _LOGD(LOGD_DEVICE, @@ -10456,9 +10616,9 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config) _LOGT(LOGD_DEVICE, "mtu: value %u from source '%s' (%u), current source '%s' (%u)%s", (guint) mtu, - mtu_source_to_str(source), + nm_device_mtu_source_to_str(source), (guint) source, - mtu_source_to_str(priv->mtu_source), + nm_device_mtu_source_to_str(priv->mtu_source), (guint) priv->mtu_source, force ? " (forced)" : ""); } @@ -10522,10 +10682,30 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config) } } +#define _IP6_MTU_SYS() \ + ({ \ + if (!ip6_mtu_sysctl.initialized) { \ + ip6_mtu_sysctl.value = nm_device_sysctl_ip_conf_get_int_checked(self, \ + AF_INET6, \ + "mtu", \ + 10, \ + 0, \ + G_MAXUINT32, \ + 0); \ + ip6_mtu_sysctl.initialized = TRUE; \ + } \ + ip6_mtu_sysctl.value; \ + }) + if (mtu_desired && NM_DEVICE_GET_CLASS(self)->mtu_force_set && !priv->mtu_force_set_done) { priv->mtu_force_set_done = TRUE; - if (mtu_desired == mtu_plat) { + if (!priv->mtu_initial && !priv->ip6_mtu_initial) { + /* before touching any of the MTU parameters, record the + * original setting to restore on deactivation. */ + priv->mtu_initial = mtu_plat; + priv->ip6_mtu_initial = _IP6_MTU_SYS(); + } mtu_plat--; if (NM_DEVICE_GET_CLASS(self)->set_platform_mtu(self, mtu_desired - 1)) { _LOGD(LOGD_DEVICE, "mtu: force-set MTU to %u", mtu_desired - 1); @@ -10544,20 +10724,6 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config) ip6_mtu == ip6_mtu_orig ? "" : nm_sprintf_buf(sbuf2, " (was %u)", (guint) ip6_mtu_orig), ifindex); -#define _IP6_MTU_SYS() \ - ({ \ - if (!ip6_mtu_sysctl.initialized) { \ - ip6_mtu_sysctl.value = nm_device_sysctl_ip_conf_get_int_checked(self, \ - AF_INET6, \ - "mtu", \ - 10, \ - 0, \ - G_MAXUINT32, \ - 0); \ - ip6_mtu_sysctl.initialized = TRUE; \ - } \ - ip6_mtu_sysctl.value; \ - }) if ((mtu_desired && mtu_desired != mtu_plat) || (ip6_mtu && ip6_mtu != _IP6_MTU_SYS())) { gboolean anticipated_failure = FALSE; @@ -10790,9 +10956,9 @@ ndisc_ra_timeout(NMNDisc *ndisc, NMDevice *self) * addresses we find inside priv->ip_config_6. */ if (priv->ip_config_6 - && nm_ip6_config_find_first_address(priv->ip_config_6, - NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL - | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY)) + && nm_ip_config_find_first_address(NM_IP_CONFIG(priv->ip_config_6), + NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY)) nm_device_activate_schedule_ip_config_result(self, AF_INET6, NULL); else nm_device_activate_schedule_ip_config_timeout(self, AF_INET6); @@ -11395,10 +11561,10 @@ activate_stage3_ip_config_start(NMDevice *self) } static void -fw_change_zone_cb(NMFirewallManager * firewall_manager, - NMFirewallManagerCallId *call_id, - GError * error, - gpointer user_data) +fw_change_zone_cb(NMFirewalldManager * firewalld_manager, + NMFirewalldManagerCallId *call_id, + GError * error, + gpointer user_data) { NMDevice * self = user_data; NMDevicePrivate *priv; @@ -11450,12 +11616,12 @@ fw_change_zone(NMDevice *self) nm_assert(s_con); if (priv->fw_call) { - nm_firewall_manager_cancel_call(priv->fw_call); + nm_firewalld_manager_cancel_call(priv->fw_call); nm_assert(!priv->fw_call); } if (G_UNLIKELY(!priv->fw_mgr)) - priv->fw_mgr = g_object_ref(nm_firewall_manager_get()); + priv->fw_mgr = g_object_ref(nm_firewalld_manager_get()); zone = nm_setting_connection_get_zone(s_con); #if WITH_FIREWALLD_ZONE @@ -11467,12 +11633,12 @@ fw_change_zone(NMDevice *self) zone = "nm-shared"; } #endif - priv->fw_call = nm_firewall_manager_add_or_change_zone(priv->fw_mgr, - nm_device_get_ip_iface(self), - zone, - FALSE, /* change zone */ - fw_change_zone_cb, - self); + priv->fw_call = nm_firewalld_manager_add_or_change_zone(priv->fw_mgr, + nm_device_get_ip_iface(self), + zone, + FALSE, /* change zone */ + fw_change_zone_cb, + self); } /* @@ -11632,7 +11798,7 @@ share_init(NMDevice *self, GError **error) } for (i = 0; i < G_N_ELEMENTS(modules); i++) - nm_utils_modprobe(NULL, FALSE, modules[i], NULL); + nmp_utils_modprobe(NULL, FALSE, modules[i], NULL); return TRUE; } @@ -11648,7 +11814,7 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error) NMConnection * conn; NMSettingConnection * s_con; gboolean announce_android_metered; - NMUtilsShareRules * share_rules; + NMFirewallConfig * firewall_config; g_return_val_if_fail(config, FALSE); @@ -11673,11 +11839,9 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error) req = nm_device_get_act_request(self); g_return_val_if_fail(req, FALSE); - share_rules = nm_utils_share_rules_new(); - - nm_utils_share_rules_add_all_rules(share_rules, ip_iface, ip4_addr->address, ip4_addr->plen); + firewall_config = nm_firewall_config_new(ip_iface, ip4_addr->address, ip4_addr->plen); - nm_act_request_set_shared(req, share_rules); + nm_act_request_set_shared(req, firewall_config); conn = nm_act_request_get_applied_connection(req); s_con = nm_connection_get_setting_connection(conn); @@ -11792,13 +11956,15 @@ activate_stage5_ip_config_result_x(NMDevice *self, int addr_family) req = nm_device_get_act_request(self); g_assert(req); + nm_clear_g_source_inst(&priv->ip_req_timeout_source_x[IS_IPv4]); + /* Interface must be IFF_UP before IP config can be applied */ ip_ifindex = nm_device_get_ip_ifindex(self); g_return_if_fail(ip_ifindex); if (!nm_platform_link_is_up(nm_device_get_platform(self), ip_ifindex) && !nm_device_sys_iface_state_is_external_or_assume(self)) { - nm_platform_link_set_up(nm_device_get_platform(self), ip_ifindex, NULL); + nm_platform_link_change_flags(nm_device_get_platform(self), ip_ifindex, IFF_UP, TRUE); if (!nm_platform_link_is_up(nm_device_get_platform(self), ip_ifindex)) _LOGW(LOGD_DEVICE, "interface %s not up for IP configuration", @@ -12660,7 +12826,7 @@ check_and_reapply_connection(NMDevice * self, klass->reapply_connection(self, con_old, con_new); if (priv->state >= NM_DEVICE_STATE_CONFIG) - lldp_init(self, FALSE); + lldp_setup(self, NM_TERNARY_DEFAULT); if (priv->state >= NM_DEVICE_STATE_IP_CONFIG) { s_ip4_old = nm_connection_get_setting_ip4_config(con_old); @@ -12891,9 +13057,10 @@ impl_device_get_applied_connection(NMDBusObject * obj, return; } - var_settings = nm_connection_to_dbus(applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS); + var_settings = + nm_connection_to_dbus(applied_connection, NM_CONNECTION_SERIALIZE_WITH_NON_SECRET); if (!var_settings) - var_settings = g_variant_new_array(G_VARIANT_TYPE("{sa{sv}}"), NULL, 0); + var_settings = nm_g_variant_singleton_aLsaLsvII(); g_dbus_method_invocation_return_value( invocation, @@ -13568,7 +13735,7 @@ nm_device_set_ip_config(NMDevice * self, NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY, NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, NM_SETTINGS_CONNECTION_INT_FLAGS_NONE, - NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE, + NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET, "update-external", NULL); } @@ -13660,18 +13827,24 @@ void nm_device_replace_vpn6_config(NMDevice *self, NMIP6Config *old, NMIP6Config *config) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMDeviceState state; nm_assert(!old || NM_IS_IP6_CONFIG(old)); + nm_assert(!old || nm_ip6_config_get_ifindex(old) > 0); + nm_assert(!old || nm_device_get_ip_ifindex(self) == 0 + || nm_device_get_ip_ifindex(self) == nm_ip6_config_get_ifindex(old)); nm_assert(!config || NM_IS_IP6_CONFIG(config)); - nm_assert(!old || nm_ip6_config_get_ifindex(old) == nm_device_get_ip_ifindex(self)); - nm_assert(!config || nm_ip6_config_get_ifindex(config) == nm_device_get_ip_ifindex(self)); + nm_assert(!config || nm_ip6_config_get_ifindex(config) > 0); + nm_assert(!config || nm_device_get_ip_ifindex(self) == nm_ip6_config_get_ifindex(config)); if (!_replace_vpn_config_in_list(&priv->vpn_configs_6, (GObject *) old, (GObject *) config)) return; - /* NULL to use existing configs */ - if (!ip_config_merge_and_apply(self, AF_INET6, TRUE)) - _LOGW(LOGD_IP6, "failed to set VPN routes for device"); + state = nm_device_get_state(self); + if (state >= NM_DEVICE_STATE_IP_CONFIG && state <= NM_DEVICE_STATE_ACTIVATED) { + if (!ip_config_merge_and_apply(self, AF_INET6, TRUE)) + _LOGW(LOGD_IP6, "failed to set VPN routes for device"); + } } NMIP6Config * @@ -13979,13 +14152,14 @@ nm_device_is_up(NMDevice *self) static gint64 _get_carrier_wait_ms(NMDevice *self) { - gs_free char *value = NULL; - - value = nm_config_data_get_device_config(NM_CONFIG_GET_DATA, - NM_CONFIG_KEYFILE_KEY_DEVICE_CARRIER_WAIT_TIMEOUT, - self, - NULL); - return _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXINT32, CARRIER_WAIT_TIME_MS); + return nm_config_data_get_device_config_int64(NM_CONFIG_GET_DATA, + NM_CONFIG_KEYFILE_KEY_DEVICE_CARRIER_WAIT_TIMEOUT, + self, + 10, + 0, + G_MAXINT32, + CARRIER_WAIT_TIME_MS, + CARRIER_WAIT_TIME_MS); } gboolean @@ -13995,6 +14169,7 @@ nm_device_bring_up(NMDevice *self, gboolean block, gboolean *no_firmware) gboolean device_is_up = FALSE; NMDeviceCapabilities capabilities; int ifindex; + int r; g_return_val_if_fail(NM_IS_DEVICE(self), FALSE); @@ -14010,7 +14185,9 @@ nm_device_bring_up(NMDevice *self, gboolean block, gboolean *no_firmware) if (ifindex <= 0) { /* assume success. */ } else { - if (!nm_platform_link_set_up(nm_device_get_platform(self), ifindex, no_firmware)) + r = nm_platform_link_change_flags(nm_device_get_platform(self), ifindex, IFF_UP, TRUE); + NM_SET_OUT(no_firmware, (r == -NME_PL_NO_FIRMWARE)); + if (r < 0) return FALSE; } @@ -14097,7 +14274,7 @@ nm_device_take_down(NMDevice *self, gboolean block) return; } - if (!nm_platform_link_set_down(nm_device_get_platform(self), ifindex)) + if (!nm_platform_link_change_flags(nm_device_get_platform(self), ifindex, IFF_UP, FALSE)) return; device_is_up = nm_device_is_up(self); @@ -14827,7 +15004,7 @@ _set_unmanaged_flags(NMDevice * self, flags, NM_PRINT_FMT_QUOTED(allow_state_transition, ", reason ", - reason_to_string_a(reason), + nm_device_state_reason_to_str_a(reason), transition_state ? ", transition-state" : "", "")); @@ -15016,20 +15193,6 @@ nm_device_set_unmanaged_by_quitting(NMDevice *self) /*****************************************************************************/ -void -nm_device_set_dhcp_anycast_address(NMDevice *self, const char *addr) -{ - NMDevicePrivate *priv; - - g_return_if_fail(NM_IS_DEVICE(self)); - g_return_if_fail(!addr || nm_utils_hwaddr_valid(addr, ETH_ALEN)); - - priv = NM_DEVICE_GET_PRIVATE(self); - - g_free(priv->dhcp_anycast_address); - priv->dhcp_anycast_address = g_strdup(addr); -} - void nm_device_reapply_settings_immediately(NMDevice *self) { @@ -15702,7 +15865,7 @@ _cancel_activation(NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); if (priv->fw_call) { - nm_firewall_manager_cancel_call(priv->fw_call); + nm_firewalld_manager_cancel_call(priv->fw_call); nm_assert(!priv->fw_call); priv->fw_call = NULL; priv->fw_state = FIREWALL_STATE_INITIALIZED; @@ -15732,11 +15895,11 @@ _cleanup_generic_pre(NMDevice *self, CleanupType cleanup_type) if (cleanup_type == CLEANUP_TYPE_DECONFIGURE && priv->fw_state >= FIREWALL_STATE_INITIALIZED && priv->fw_mgr && !nm_device_sys_iface_state_is_external(self)) { - nm_firewall_manager_remove_from_zone(priv->fw_mgr, - nm_device_get_ip_iface(self), - NULL, - NULL, - NULL); + nm_firewalld_manager_remove_from_zone(priv->fw_mgr, + nm_device_get_ip_iface(self), + NULL, + NULL, + NULL); } priv->fw_state = FIREWALL_STATE_UNMANAGED; g_clear_object(&priv->fw_mgr); @@ -15750,6 +15913,10 @@ _cleanup_generic_pre(NMDevice *self, CleanupType cleanup_type) _cleanup_ip_pre(self, AF_INET, cleanup_type); _cleanup_ip_pre(self, AF_INET6, cleanup_type); + + priv->ip_config_started = FALSE; + nm_clear_g_source_inst(&priv->ip_req_timeout_source_4); + nm_clear_g_source_inst(&priv->ip_req_timeout_source_6); } static void @@ -15847,7 +16014,7 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu else _LOGD(LOGD_DEVICE, "deactivating device (reason '%s') [%d]", - reason_to_string_a(reason), + nm_device_state_reason_to_str_a(reason), reason); /* Save whether or not we tried IPv6 for later */ @@ -15902,8 +16069,7 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu FALSE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); - if (priv->lldp_listener) - nm_lldp_listener_stop(priv->lldp_listener); + lldp_setup(self, NM_TERNARY_FALSE); nm_device_update_metered(self); @@ -15954,6 +16120,14 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu _ethtool_state_reset(self); + if (priv->promisc_reset != NM_OPTION_BOOL_DEFAULT && ifindex > 0) { + nm_platform_link_change_flags(nm_device_get_platform(self), + ifindex, + IFF_PROMISC, + !!priv->promisc_reset); + priv->promisc_reset = NM_OPTION_BOOL_DEFAULT; + } + _cleanup_generic_post(self, cleanup_type); } @@ -16068,7 +16242,8 @@ nm_device_spawn_iface_helper(NMDevice *self) hostname = nm_dhcp_client_get_hostname(priv->dhcp_data_4.client); if (hostname) { - if (nm_dhcp_client_get_use_fqdn(priv->dhcp_data_4.client)) + if (NM_FLAGS_HAS(nm_dhcp_client_get_client_flags(priv->dhcp_data_4.client), + NM_DHCP_CLIENT_FLAGS_USE_FQDN)) g_ptr_array_add(argv, g_strdup("--dhcp4-fqdn")); else g_ptr_array_add(argv, g_strdup("--dhcp4-hostname")); @@ -16335,8 +16510,8 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, "state change: %s -> %s (reason '%s', sys-iface-state: '%s'%s)", nm_device_state_to_str(old_state), nm_device_state_to_str(state), - reason_to_string_a(reason), - _sys_iface_state_to_str(priv->sys_iface_state), + nm_device_state_reason_to_str_a(reason), + nm_device_sys_iface_state_to_str(priv->sys_iface_state), priv->firmware_missing ? ", missing firmware" : ""); return; } @@ -16345,8 +16520,8 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, "state change: %s -> %s (reason '%s', sys-iface-state: '%s')", nm_device_state_to_str(old_state), nm_device_state_to_str(state), - reason_to_string_a(reason), - _sys_iface_state_to_str(priv->sys_iface_state)); + nm_device_state_reason_to_str_a(reason), + nm_device_sys_iface_state_to_str(priv->sys_iface_state)); /* in order to prevent triggering any callback caused * by the device not having any pending action anymore @@ -16692,7 +16867,7 @@ queued_state_set(gpointer user_data) _LOGD(LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", nm_device_state_to_str(priv->queued_state.state), - reason_to_string_a(priv->queued_state.reason), + nm_device_state_reason_to_str_a(priv->queued_state.reason), priv->queued_state.id, "change state"); @@ -16704,7 +16879,7 @@ queued_state_set(gpointer user_data) new_reason = priv->queued_state.reason; nm_device_state_changed(self, new_state, new_reason); - nm_device_remove_pending_action(self, queued_state_to_string(new_state), TRUE); + nm_device_remove_pending_action(self, nm_device_state_queued_state_to_str(new_state), TRUE); return G_SOURCE_REMOVE; } @@ -16722,12 +16897,12 @@ nm_device_queue_state(NMDevice *self, NMDeviceState state, NMDeviceStateReason r _LOGD(LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s%s%s%s", nm_device_state_to_str(priv->queued_state.state), - reason_to_string_a(priv->queued_state.reason), + nm_device_state_reason_to_str_a(priv->queued_state.reason), priv->queued_state.id, "ignore queuing same state change", NM_PRINT_FMT_QUOTED(priv->queued_state.reason != reason, " (reason differs: ", - reason_to_string_a(reason), + nm_device_state_reason_to_str_a(reason), ")", "")); return; @@ -16735,20 +16910,21 @@ nm_device_queue_state(NMDevice *self, NMDeviceState state, NMDeviceStateReason r /* Add pending action for the new state before clearing the queued states, so * that we don't accidentally pop all pending states and reach 'startup complete' */ - nm_device_add_pending_action(self, queued_state_to_string(state), TRUE); + nm_device_add_pending_action(self, nm_device_state_queued_state_to_str(state), TRUE); /* We should only ever have one delayed state transition at a time */ if (priv->queued_state.id) { _LOGW(LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", nm_device_state_to_str(priv->queued_state.state), - reason_to_string_a(priv->queued_state.reason), + nm_device_state_reason_to_str_a(priv->queued_state.reason), priv->queued_state.id, "replace previously queued state change"); nm_clear_g_source(&priv->queued_state.id); - nm_device_remove_pending_action(self, - queued_state_to_string(priv->queued_state.state), - TRUE); + nm_device_remove_pending_action( + self, + nm_device_state_queued_state_to_str(priv->queued_state.state), + TRUE); } priv->queued_state.state = state; @@ -16758,7 +16934,7 @@ nm_device_queue_state(NMDevice *self, NMDeviceState state, NMDeviceStateReason r _LOGD(LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", nm_device_state_to_str(state), - reason_to_string_a(reason), + nm_device_state_reason_to_str_a(reason), priv->queued_state.id, "queue state change"); } @@ -16774,11 +16950,13 @@ queued_state_clear(NMDevice *self) _LOGD(LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", nm_device_state_to_str(priv->queued_state.state), - reason_to_string_a(priv->queued_state.reason), + nm_device_state_reason_to_str_a(priv->queued_state.reason), priv->queued_state.id, "clear queued state change"); nm_clear_g_source(&priv->queued_state.id); - nm_device_remove_pending_action(self, queued_state_to_string(priv->queued_state.state), TRUE); + nm_device_remove_pending_action(self, + nm_device_state_queued_state_to_str(priv->queued_state.state), + TRUE); } NMDeviceState @@ -16796,7 +16974,7 @@ const char * nm_device_get_hw_address(NMDevice *self) { NMDevicePrivate *priv; - char buf[NM_UTILS_HWADDR_LEN_MAX]; + char buf[_NM_UTILS_HWADDR_LEN_MAX]; gsize l; g_return_val_if_fail(NM_IS_DEVICE(self), NULL); @@ -16890,7 +17068,7 @@ void 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]; + guint8 buf[_NM_UTILS_HWADDR_LEN_MAX]; size_t len = 0; gboolean success_read; int ifindex; @@ -17008,7 +17186,7 @@ _hw_addr_set(NMDevice * self, NMDevicePrivate *priv; gboolean success = FALSE; int r; - guint8 addr_bytes[NM_UTILS_HWADDR_LEN_MAX]; + guint8 addr_bytes[_NM_UTILS_HWADDR_LEN_MAX]; gsize addr_len; gboolean was_taken_down = FALSE; gboolean retry_down; @@ -17209,14 +17387,13 @@ _hw_addr_get_cloned(NMDevice * self, gboolean * preserve, char ** hwaddr, HwAddrType * hwaddr_type, - char ** hwaddr_detail, + const char ** hwaddr_detail, GError ** error) { NMDevicePrivate *priv; - gs_free char * addr_setting_free = NULL; - gs_free char * hw_addr_generated = NULL; - gs_free char * generate_mac_address_mask_tmp = NULL; - const char * addr, *addr_setting; + gs_free char * hw_addr_generated = NULL; + const char * addr; + const char * addr_setting; char * addr_out; HwAddrType type_out; @@ -17229,15 +17406,16 @@ _hw_addr_get_cloned(NMDevice * self, if (!connection) g_return_val_if_reached(FALSE); - addr = addr_setting = - _prop_get_x_cloned_mac_address(self, connection, is_wifi, &addr_setting_free); + addr_setting = _prop_get_x_cloned_mac_address(self, connection, is_wifi); + + addr = addr_setting; if (nm_streq(addr, NM_CLONED_MAC_PRESERVE)) { /* "preserve" means to reset the initial MAC address. */ NM_SET_OUT(preserve, TRUE); NM_SET_OUT(hwaddr, NULL); NM_SET_OUT(hwaddr_type, HW_ADDR_TYPE_UNSET); - NM_SET_OUT(hwaddr_detail, g_steal_pointer(&addr_setting_free) ?: g_strdup(addr_setting)); + NM_SET_OUT(hwaddr_detail, addr_setting); return TRUE; } @@ -17250,8 +17428,7 @@ _hw_addr_get_cloned(NMDevice * self, NM_SET_OUT(preserve, TRUE); NM_SET_OUT(hwaddr, NULL); NM_SET_OUT(hwaddr_type, HW_ADDR_TYPE_UNSET); - NM_SET_OUT(hwaddr_detail, - g_steal_pointer(&addr_setting_free) ?: g_strdup(addr_setting)); + NM_SET_OUT(hwaddr_detail, addr_setting); return TRUE; } else if (!addr) { g_set_error_literal(error, @@ -17271,10 +17448,7 @@ _hw_addr_get_cloned(NMDevice * self, } hw_addr_generated = nm_utils_hw_addr_gen_random_eth( nm_device_get_initial_hw_address(self), - _prop_get_x_generate_mac_address_mask(self, - connection, - is_wifi, - &generate_mac_address_mask_tmp)); + _prop_get_x_generate_mac_address_mask(self, connection, is_wifi)); if (!hw_addr_generated) { g_set_error(error, NM_DEVICE_ERROR, @@ -17302,10 +17476,7 @@ _hw_addr_get_cloned(NMDevice * self, stable_id, nm_device_get_ip_iface(self), nm_device_get_initial_hw_address(self), - _prop_get_x_generate_mac_address_mask(self, - connection, - is_wifi, - &generate_mac_address_mask_tmp)); + _prop_get_x_generate_mac_address_mask(self, connection, is_wifi)); if (!hw_addr_generated) { g_set_error(error, NM_DEVICE_ERROR, @@ -17329,7 +17500,7 @@ _hw_addr_get_cloned(NMDevice * self, NM_SET_OUT(preserve, FALSE); NM_SET_OUT(hwaddr, addr_out); NM_SET_OUT(hwaddr_type, type_out); - NM_SET_OUT(hwaddr_detail, g_steal_pointer(&addr_setting_free) ?: g_strdup(addr_setting)); + NM_SET_OUT(hwaddr_detail, addr_setting); return TRUE; out_no_action: NM_SET_OUT(preserve, FALSE); @@ -17359,7 +17530,7 @@ nm_device_hw_addr_set_cloned(NMDevice *self, NMConnection *connection, gboolean NMDevicePrivate *priv; gboolean preserve = FALSE; gs_free char * hwaddr = NULL; - gs_free char * detail = NULL; + const char * detail = NULL; HwAddrType type = HW_ADDR_TYPE_UNSET; gs_free_error GError *error = NULL; @@ -17599,23 +17770,38 @@ hostname_dns_lookup_callback(GObject *source, GAsyncResult *result, gpointer use { HostnameResolver *resolver; NMDevice * self; - gs_free char * hostname = NULL; gs_free char * addr_str = NULL; + gs_free char * output = NULL; gs_free_error GError *error = NULL; - hostname = g_resolver_lookup_by_address_finish(G_RESOLVER(source), result, &error); + output = nm_device_resolve_address_finish(result, &error); if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; - resolver = user_data; - self = resolver->device; - resolver->state = RESOLVER_DONE; - resolver->hostname = g_strdup(hostname); + resolver = user_data; + self = resolver->device; + resolver->state = RESOLVER_DONE; + + if (error) { + _LOGD(LOGD_DNS, + "hostname-from-dns: lookup error for %s: %s", + (addr_str = g_inet_address_to_string(resolver->address)), + error->message); + } else { + gboolean valid; + + resolver->hostname = g_steal_pointer(&output); + valid = nm_hostname_manager_validate_hostname(resolver->hostname); + + _LOGD(LOGD_DNS, + "hostname-from-dns: lookup done for %s, result %s%s%s%s", + (addr_str = g_inet_address_to_string(resolver->address)), + NM_PRINT_FMT_QUOTE_STRING(resolver->hostname), + valid ? "" : " (invalid)"); - _LOGD(LOGD_DNS, - "hostname-from-dns: lookup done for %s, result %s%s%s", - (addr_str = g_inet_address_to_string(resolver->address)), - NM_PRINT_FMT_QUOTE_STRING(hostname)); + if (!valid) + g_clear_pointer(&resolver->hostname, g_free); + } nm_clear_g_cancellable(&resolver->cancellable); g_signal_emit(self, signals[DNS_LOOKUP_DONE], 0); @@ -17713,7 +17899,6 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean if (!resolver) { resolver = g_slice_new(HostnameResolver); *resolver = (HostnameResolver){ - .resolver = g_resolver_get_default(), .device = self, .addr_family = addr_family, .state = RESOLVER_WAIT_ADDRESS, @@ -17721,13 +17906,36 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean priv->hostname_resolver_x[IS_IPv4] = resolver; } - /* Determine the first address of the interface and - * whether it changed from the previous lookup */ + /* Determine the most suitable address of the interface + * and whether it changed from the previous lookup */ ip_config = priv->ip_config_x[IS_IPv4]; if (ip_config) { - const NMPlatformIPAddress *addr; + const NMPlatformIPAddress *addr = NULL; + + if (IS_IPv4) { + addr = nm_ip_config_get_first_address(ip_config); + } else { + /* For IPv6 prefer, in order: + * - !link-local, !deprecated + * - !link-local, deprecated + * - link-local + */ + addr = nm_ip_config_find_first_address(ip_config, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_NORMAL); + if (!addr) { + addr = nm_ip_config_find_first_address( + ip_config, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_NORMAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE_DEPRECATED); + } + if (!addr) { + addr = nm_ip_config_find_first_address(ip_config, + NM_PLATFORM_MATCH_WITH_ADDRTYPE_LINKLOCAL + | NM_PLATFORM_MATCH_WITH_ADDRSTATE__ANY); + } + } - addr = nm_ip_config_get_first_address(ip_config); if (addr) { new_address = g_inet_address_new_from_bytes(addr->address_ptr, IS_IPv4 ? G_SOCKET_FAMILY_IPV4 @@ -17763,20 +17971,15 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean } if (address_changed && new_address) { - gs_free char *str = NULL; - - _LOGT(LOGD_DNS, - "hostname-from-dns: starting lookup for address %s", - (str = g_inet_address_to_string(new_address))); - resolver->state = RESOLVER_IN_PROGRESS; resolver->cancellable = g_cancellable_new(); resolver->address = g_steal_pointer(&new_address); - g_resolver_lookup_by_address_async(resolver->resolver, - resolver->address, - resolver->cancellable, - hostname_dns_lookup_callback, - resolver); + + nm_device_resolve_address(addr_family, + g_inet_address_to_bytes(resolver->address), + resolver->cancellable, + hostname_dns_lookup_callback, + resolver); nm_clear_g_source(&resolver->timeout_id); } @@ -17826,7 +18029,6 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMDevice * self = NM_DEVICE(object); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - GVariantBuilder array_builder; switch (prop_id) { case PROP_UDI: @@ -17977,12 +18179,10 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) g_value_set_uint(value, priv->metered); break; case PROP_LLDP_NEIGHBORS: - if (priv->lldp_listener) - g_value_set_variant(value, nm_lldp_listener_get_neighbors(priv->lldp_listener)); - else { - g_variant_builder_init(&array_builder, G_VARIANT_TYPE("aa{sv}")); - g_value_take_variant(value, g_variant_builder_end(&array_builder)); - } + g_value_set_variant(value, + priv->lldp_listener + ? nm_lldp_listener_get_neighbors(priv->lldp_listener) + : nm_g_variant_singleton_aaLsvI()); break; case PROP_REAL: g_value_set_boolean(value, nm_device_is_real(self)); @@ -18162,6 +18362,8 @@ nm_device_init(NMDevice *self) priv->v4_commit_first_time = TRUE; priv->v6_commit_first_time = TRUE; + + priv->promisc_reset = NM_OPTION_BOOL_DEFAULT; } static GObject * @@ -18191,7 +18393,7 @@ constructor(GType type, guint n_construct_params, GObjectConstructParam *constru } if (priv->hw_addr_perm) { - guint8 buf[NM_UTILS_HWADDR_LEN_MAX]; + guint8 buf[_NM_UTILS_HWADDR_LEN_MAX]; gsize l; if (!_nm_utils_hwaddr_aton(priv->hw_addr_perm, buf, sizeof(buf), &l)) { @@ -18339,13 +18541,7 @@ dispose(GObject *object) nm_clear_g_source(&priv->device_link_changed_id); nm_clear_g_source(&priv->device_ip_link_changed_id); - if (priv->lldp_listener) { - g_signal_handlers_disconnect_by_func(priv->lldp_listener, - G_CALLBACK(lldp_neighbors_changed), - self); - nm_lldp_listener_stop(priv->lldp_listener); - g_clear_object(&priv->lldp_listener); - } + lldp_setup(self, FALSE); nm_clear_g_source(&priv->concheck_x[0].p_cur_id); nm_clear_g_source(&priv->concheck_x[1].p_cur_id); @@ -18388,7 +18584,6 @@ finalize(GObject *object) g_free(priv->driver_version); g_free(priv->firmware_version); g_free(priv->type_desc); - g_free(priv->dhcp_anycast_address); g_free(priv->current_stable_id); g_hash_table_unref(priv->ip6_saved_properties); @@ -18443,75 +18638,69 @@ static const NMDBusInterfaceInfoExtended interface_info_device = { .handle = impl_device_delete, ), ), .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&signal_info_state_changed, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Udi", "s", NM_DEVICE_UDI), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Path", "s", NM_DEVICE_PATH), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Interface", "s", NM_DEVICE_IFACE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("IpInterface", - "s", - NM_DEVICE_IP_IFACE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Driver", "s", NM_DEVICE_DRIVER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("DriverVersion", - "s", - NM_DEVICE_DRIVER_VERSION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("FirmwareVersion", - "s", - NM_DEVICE_FIRMWARE_VERSION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Capabilities", - "u", - NM_DEVICE_CAPABILITIES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ip4Address", - "u", - NM_DEVICE_IP4_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("State", "u", NM_DEVICE_STATE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("StateReason", - "(uu)", - NM_DEVICE_STATE_REASON), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("ActiveConnection", - "o", - NM_DEVICE_ACTIVE_CONNECTION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ip4Config", - "o", - NM_DEVICE_IP4_CONFIG), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Dhcp4Config", - "o", - NM_DEVICE_DHCP4_CONFIG), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ip6Config", - "o", - NM_DEVICE_IP6_CONFIG), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Dhcp6Config", - "o", - NM_DEVICE_DHCP6_CONFIG), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L("Managed", - "b", - NM_DEVICE_MANAGED, - NM_AUTH_PERMISSION_NETWORK_CONTROL, - NM_AUDIT_OP_DEVICE_MANAGED), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE_L("Autoconnect", - "b", - NM_DEVICE_AUTOCONNECT, - NM_AUTH_PERMISSION_NETWORK_CONTROL, - NM_AUDIT_OP_DEVICE_AUTOCONNECT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("FirmwareMissing", - "b", - NM_DEVICE_FIRMWARE_MISSING), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("NmPluginMissing", - "b", - NM_DEVICE_NM_PLUGIN_MISSING), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("DeviceType", - "u", - NM_DEVICE_DEVICE_TYPE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("AvailableConnections", - "ao", - NM_DEVICE_AVAILABLE_CONNECTIONS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("PhysicalPortId", - "s", - NM_DEVICE_PHYSICAL_PORT_ID), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mtu", "u", NM_DEVICE_MTU), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Metered", "u", NM_DEVICE_METERED), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("LldpNeighbors", - "aa{sv}", - NM_DEVICE_LLDP_NEIGHBORS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Real", "b", NM_DEVICE_REAL), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Udi", "s", NM_DEVICE_UDI), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Path", "s", NM_DEVICE_PATH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Interface", "s", NM_DEVICE_IFACE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("IpInterface", "s", NM_DEVICE_IP_IFACE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Driver", "s", NM_DEVICE_DRIVER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DriverVersion", + "s", + NM_DEVICE_DRIVER_VERSION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("FirmwareVersion", + "s", + NM_DEVICE_FIRMWARE_VERSION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Capabilities", + "u", + NM_DEVICE_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ip4Address", + "u", + NM_DEVICE_IP4_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("State", "u", NM_DEVICE_STATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("StateReason", + "(uu)", + NM_DEVICE_STATE_REASON), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ActiveConnection", + "o", + NM_DEVICE_ACTIVE_CONNECTION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ip4Config", "o", NM_DEVICE_IP4_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Dhcp4Config", + "o", + NM_DEVICE_DHCP4_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ip6Config", "o", NM_DEVICE_IP6_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Dhcp6Config", + "o", + NM_DEVICE_DHCP6_CONFIG), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE("Managed", + "b", + NM_DEVICE_MANAGED, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + NM_AUDIT_OP_DEVICE_MANAGED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE("Autoconnect", + "b", + NM_DEVICE_AUTOCONNECT, + NM_AUTH_PERMISSION_NETWORK_CONTROL, + NM_AUDIT_OP_DEVICE_AUTOCONNECT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("FirmwareMissing", + "b", + NM_DEVICE_FIRMWARE_MISSING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("NmPluginMissing", + "b", + NM_DEVICE_NM_PLUGIN_MISSING), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DeviceType", + "u", + NM_DEVICE_DEVICE_TYPE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("AvailableConnections", + "ao", + NM_DEVICE_AVAILABLE_CONNECTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("PhysicalPortId", + "s", + NM_DEVICE_PHYSICAL_PORT_ID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mtu", "u", NM_DEVICE_MTU), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Metered", "u", NM_DEVICE_METERED), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("LldpNeighbors", + "aa{sv}", + NM_DEVICE_LLDP_NEIGHBORS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Real", "b", NM_DEVICE_REAL), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ip4Connectivity", "u", NM_DEVICE_IP4_CONNECTIVITY), @@ -18526,10 +18715,9 @@ static const NMDBusInterfaceInfoExtended interface_info_device = { NM_DEVICE_HW_ADDRESS), ), ), }; -const NMDBusInterfaceInfoExtended nm_interface_info_device_statistics = { +static const NMDBusInterfaceInfoExtended interface_info_device_statistics = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_STATISTICS, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READWRITABLE( "RefreshRateMs", @@ -18555,7 +18743,7 @@ nm_device_class_init(NMDeviceClass *klass) dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH "/Devices"); dbus_object_class->interface_infos = - NM_DBUS_INTERFACE_INFOS(&interface_info_device, &nm_interface_info_device_statistics); + NM_DBUS_INTERFACE_INFOS(&interface_info_device, &interface_info_device_statistics); object_class->dispose = dispose; object_class->finalize = finalize; diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h index 68343ef5..f59b6fa8 100644 --- a/src/core/devices/nm-device.h +++ b/src/core/devices/nm-device.h @@ -15,54 +15,7 @@ #include "nm-connection.h" #include "nm-rfkill-manager.h" #include "NetworkManagerUtils.h" - -typedef enum _nm_packed { - NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, - NM_DEVICE_SYS_IFACE_STATE_ASSUME, - NM_DEVICE_SYS_IFACE_STATE_MANAGED, - - /* the REMOVED state applies when the device is manually set to unmanaged - * or the link was externally removed. In both cases, we move the device - * to UNMANAGED state, without touching the link -- be it, because the link - * is already gone or because we want to release it (give it up). - */ - NM_DEVICE_SYS_IFACE_STATE_REMOVED, -} NMDeviceSysIfaceState; - -typedef enum { - NM_DEVICE_MTU_SOURCE_NONE, - NM_DEVICE_MTU_SOURCE_PARENT, - NM_DEVICE_MTU_SOURCE_IP_CONFIG, - NM_DEVICE_MTU_SOURCE_CONNECTION, -} NMDeviceMtuSource; - -static inline NMDeviceStateReason -nm_device_state_reason_check(NMDeviceStateReason reason) -{ - /* the device-state-reason serves mostly informational purpose during a state - * change. In some cases however, decisions are made based on the reason. - * I tend to think that interpreting the state reason to derive some behaviors - * is confusing, because the cause and effect are so far apart. - * - * This function is here to mark source that inspects the reason to make - * a decision -- contrary to places that set the reason. Thus, by grepping - * for nm_device_state_reason_check() you can find the "effect" to a certain - * reason. - */ - return reason; -} - -#define NM_PENDING_ACTION_AUTOACTIVATE "autoactivate" -#define NM_PENDING_ACTION_IN_STATE_CHANGE "in-state-change" -#define NM_PENDING_ACTION_RECHECK_AVAILABLE "recheck-available" -#define NM_PENDING_ACTION_CARRIER_WAIT "carrier-wait" -#define NM_PENDING_ACTION_WAITING_FOR_SUPPLICANT "waiting-for-supplicant" -#define NM_PENDING_ACTION_WIFI_SCAN "wifi-scan" -#define NM_PENDING_ACTION_WAITING_FOR_COMPANION "waiting-for-companion" -#define NM_PENDING_ACTION_LINK_INIT "link-init" - -#define NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "queued-state-change-" -#define NM_PENDING_ACTIONPREFIX_ACTIVATION "activation-" +#include "nm-device-utils.h" /* Properties */ #define NM_DEVICE_UDI "udi" @@ -109,10 +62,10 @@ nm_device_state_reason_check(NMDeviceStateReason reason) * NMDeviceOvsBridge and NMDeviceOvsPort. */ #define NM_DEVICE_SLAVES "slaves" /* partially internal */ -#define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */ -#define NM_DEVICE_RFKILL_TYPE "rfkill-type" /* Internal only */ -#define NM_DEVICE_IFINDEX "ifindex" /* Internal only */ -#define NM_DEVICE_MASTER "master" /* Internal only */ +#define NM_DEVICE_TYPE_DESC "type-desc" /* Internal only */ +#define NM_DEVICE_RFKILL_TYPE "rfkill-type" /* Internal only */ +#define NM_DEVICE_IFINDEX "ifindex" /* Internal only */ +#define NM_DEVICE_MASTER "master" /* Internal only */ #define NM_DEVICE_HAS_PENDING_ACTION "has-pending-action" /* Internal only */ /* Internal signals */ @@ -459,6 +412,8 @@ typedef struct _NMDeviceClass { gboolean (*set_platform_mtu)(NMDevice *self, guint32 mtu); + const char *(*get_dhcp_anycast_address)(NMDevice *self); + } NMDeviceClass; GType nm_device_get_type(void); @@ -572,6 +527,7 @@ nm_device_check_connection_compatible(NMDevice *device, NMConnection *connection gboolean nm_device_check_slave_connection_compatible(NMDevice *device, NMConnection *connection); +gboolean nm_device_can_assume_connections(NMDevice *self); gboolean nm_device_unmanage_on_quit(NMDevice *self); gboolean nm_device_spec_match_list(NMDevice *device, const GSList *specs); @@ -862,9 +818,6 @@ struct _NMBtVTableNetworkServer { gboolean (*unregister_bridge)(const NMBtVTableNetworkServer *vtable, NMDevice *device); }; -const char *nm_device_state_to_str(NMDeviceState state); -const char *nm_device_state_reason_to_str(NMDeviceStateReason reason); - gboolean nm_device_is_vpn(NMDevice *self); const char * diff --git a/src/core/devices/nm-lldp-listener.c b/src/core/devices/nm-lldp-listener.c index c60fb3ad..aba972ae 100644 --- a/src/core/devices/nm-lldp-listener.c +++ b/src/core/devices/nm-lldp-listener.c @@ -9,12 +9,15 @@ #include -#include "nm-std-aux/unaligned.h" -#include "platform/nm-platform.h" -#include "nm-glib-aux/nm-c-list.h" +#include "NetworkManagerUtils.h" +#include "libnm-core-public/nm-errors.h" +#include "libnm-glib-aux/nm-time-utils.h" +#include "libnm-std-aux/unaligned.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-utils.h" -#include "systemd/nm-sd.h" +#include "libnm-systemd-core/nm-sd.h" #define MAX_NEIGHBORS 128 #define MIN_UPDATE_INTERVAL_NSEC (2 * NM_UTILS_NSEC_PER_SEC) @@ -28,34 +31,21 @@ /*****************************************************************************/ -NM_GOBJECT_PROPERTIES_DEFINE(NMLldpListener, PROP_NEIGHBORS, ); - -typedef struct { +struct _NMLldpListener { sd_lldp * lldp_handle; GHashTable *lldp_neighbors; GVariant * variant; + NMLldpListenerNotify notify_callback; + gpointer notify_user_data; + /* the timestamp in nsec until which we delay updates. */ - gint64 ratelimit_next_nsec; - guint ratelimit_id; + GSource *ratelimit_source; + gint64 ratelimit_next_nsec; int ifindex; -} NMLldpListenerPrivate; - -struct _NMLldpListener { - GObject parent; - NMLldpListenerPrivate _priv; -}; - -struct _NMLldpListenerClass { - GObjectClass parent; }; -G_DEFINE_TYPE(NMLldpListener, nm_lldp_listener, G_TYPE_OBJECT) - -#define NM_LLDP_LISTENER_GET_PRIVATE(self) \ - _NM_GET_PRIVATE(self, NMLldpListener, NM_IS_LLDP_LISTENER) - /*****************************************************************************/ typedef struct { @@ -71,27 +61,28 @@ typedef struct { #define _NMLOG_PREFIX_NAME "lldp" #define _NMLOG_DOMAIN LOGD_DEVICE -#define _NMLOG(level, ...) \ - G_STMT_START \ - { \ - const NMLogLevel _level = (level); \ - \ - if (nm_logging_enabled(_level, _NMLOG_DOMAIN)) { \ - char _sbuf[64]; \ - int _ifindex = (self) ? NM_LLDP_LISTENER_GET_PRIVATE(self)->ifindex : 0; \ - \ - _nm_log(_level, \ - _NMLOG_DOMAIN, \ - 0, \ - _ifindex > 0 ? nm_platform_link_get_name(NM_PLATFORM_GET, _ifindex) : NULL, \ - NULL, \ - "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME, \ - ((_ifindex > 0) ? nm_sprintf_buf(_sbuf, "[%p,%d]", (self), _ifindex) \ - : ((self) ? nm_sprintf_buf(_sbuf, "[%p]", (self)) : "")) \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - } \ +#define _NMLOG(level, ...) \ + G_STMT_START \ + { \ + const NMLogLevel _level = (level); \ + \ + if (nm_logging_enabled(_level, _NMLOG_DOMAIN)) { \ + char _sbuf[100]; \ + \ + _nm_log(_level, \ + _NMLOG_DOMAIN, \ + 0, \ + (self) ? nm_platform_link_get_name(NM_PLATFORM_GET, (self)->ifindex) : NULL, \ + NULL, \ + "%s%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + _NMLOG_PREFIX_NAME, \ + ((self) ? nm_sprintf_buf(_sbuf, \ + "[" NM_HASH_OBFUSCATE_PTR_FMT ",%d]", \ + NM_HASH_OBFUSCATE_PTR(self), \ + (self)->ifindex) \ + : "") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ G_STMT_END #define LOG_NEIGH_FMT "CHASSIS=%u/%s PORT=%u/%s" @@ -809,80 +800,73 @@ nmtst_lldp_parse_from_raw(const guint8 *raw_data, gsize raw_len) /*****************************************************************************/ static void -data_changed_notify(NMLldpListener *self, NMLldpListenerPrivate *priv) +data_changed_notify(NMLldpListener *self) { - nm_clear_g_variant(&priv->variant); - _notify(self, PROP_NEIGHBORS); + nm_clear_g_variant(&self->variant); + + self->notify_callback(self, self->notify_user_data); } static gboolean data_changed_timeout(gpointer user_data) { - NMLldpListener * self = user_data; - NMLldpListenerPrivate *priv; + NMLldpListener *self = user_data; - g_return_val_if_fail(NM_IS_LLDP_LISTENER(self), G_SOURCE_REMOVE); - - priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - - priv->ratelimit_id = 0; - priv->ratelimit_next_nsec = nm_utils_get_monotonic_timestamp_nsec() + MIN_UPDATE_INTERVAL_NSEC; - data_changed_notify(self, priv); - return G_SOURCE_REMOVE; + nm_clear_g_source_inst(&self->ratelimit_source); + self->ratelimit_next_nsec = nm_utils_get_monotonic_timestamp_nsec() + MIN_UPDATE_INTERVAL_NSEC; + data_changed_notify(self); + return G_SOURCE_CONTINUE; } static void data_changed_schedule(NMLldpListener *self) { - NMLldpListenerPrivate *priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - gint64 now_nsec; + gint64 now_nsec; - if (priv->ratelimit_id != 0) + if (self->ratelimit_source) return; now_nsec = nm_utils_get_monotonic_timestamp_nsec(); - if (now_nsec < priv->ratelimit_next_nsec) { - priv->ratelimit_id = - g_timeout_add_full(G_PRIORITY_LOW, - NM_UTILS_NSEC_TO_MSEC_CEIL(priv->ratelimit_next_nsec - now_nsec), - data_changed_timeout, - self, - NULL); - return; + if (now_nsec < self->ratelimit_next_nsec) { + self->ratelimit_source = nm_g_timeout_source_new( + NM_UTILS_NSEC_TO_MSEC_CEIL(self->ratelimit_next_nsec - now_nsec), + G_PRIORITY_LOW, + data_changed_timeout, + self, + NULL); + } else { + self->ratelimit_source = + nm_g_idle_source_new(G_PRIORITY_LOW, data_changed_timeout, self, NULL); } - priv->ratelimit_id = g_idle_add_full(G_PRIORITY_LOW, data_changed_timeout, self, NULL); + g_source_attach(self->ratelimit_source, NULL); } static void process_lldp_neighbor(NMLldpListener *self, sd_lldp_neighbor *neighbor_sd, gboolean remove) { - NMLldpListenerPrivate * priv; nm_auto(lldp_neighbor_freep) LldpNeighbor *neigh = NULL; LldpNeighbor * neigh_old; - g_return_if_fail(NM_IS_LLDP_LISTENER(self)); + nm_assert(self); + nm_assert(self->lldp_handle); + nm_assert(self->lldp_neighbors); - priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - - g_return_if_fail(priv->lldp_handle); g_return_if_fail(neighbor_sd); - nm_assert(priv->lldp_neighbors); - neigh = lldp_neighbor_new(neighbor_sd); if (!neigh) { _LOGT("process: failed to parse neighbor"); return; } - neigh_old = g_hash_table_lookup(priv->lldp_neighbors, neigh); + neigh_old = g_hash_table_lookup(self->lldp_neighbors, neigh); if (remove) { if (neigh_old) { _LOGT("process: %s neigh: " LOG_NEIGH_FMT, "remove", LOG_NEIGH_ARG(neigh)); - g_hash_table_remove(priv->lldp_neighbors, neigh_old); + g_hash_table_remove(self->lldp_neighbors, neigh_old); goto handle_changed; } return; @@ -893,14 +877,14 @@ process_lldp_neighbor(NMLldpListener *self, sd_lldp_neighbor *neighbor_sd, gbool _LOGD("process: %s neigh: " LOG_NEIGH_FMT, neigh_old ? "update" : "new", LOG_NEIGH_ARG(neigh)); - g_hash_table_add(priv->lldp_neighbors, g_steal_pointer(&neigh)); + g_hash_table_add(self->lldp_neighbors, g_steal_pointer(&neigh)); handle_changed: data_changed_schedule(self); } static void -lldp_event_handler(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void *userdata) +lldp_event_handler(sd_lldp *lldp, sd_lldp_event_t event, sd_lldp_neighbor *n, void *userdata) { process_lldp_neighbor( userdata, @@ -908,25 +892,57 @@ lldp_event_handler(sd_lldp *lldp, sd_lldp_event event, sd_lldp_neighbor *n, void !NM_IN_SET(event, SD_LLDP_EVENT_ADDED, SD_LLDP_EVENT_UPDATED, SD_LLDP_EVENT_REFRESHED)); } -gboolean -nm_lldp_listener_start(NMLldpListener *self, int ifindex, GError **error) +/*****************************************************************************/ + +int +nm_lldp_listener_get_ifindex(NMLldpListener *self) { - NMLldpListenerPrivate *priv; - int ret; + g_return_val_if_fail(self, 0); - g_return_val_if_fail(NM_IS_LLDP_LISTENER(self), FALSE); - g_return_val_if_fail(ifindex > 0, FALSE); - g_return_val_if_fail(!error || !*error, FALSE); + return self->ifindex; +} - priv = NM_LLDP_LISTENER_GET_PRIVATE(self); +/*****************************************************************************/ - if (priv->lldp_handle) { - g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "already running"); - return FALSE; +GVariant * +nm_lldp_listener_get_neighbors(NMLldpListener *self) +{ + g_return_val_if_fail(self, FALSE); + + if (G_UNLIKELY(!self->variant)) { + gs_free LldpNeighbor **neighbors = NULL; + GVariantBuilder array_builder; + guint i, n; + + g_variant_builder_init(&array_builder, G_VARIANT_TYPE("aa{sv}")); + neighbors = (LldpNeighbor **) + nm_utils_hash_keys_to_array(self->lldp_neighbors, lldp_neighbor_id_cmp_p, NULL, &n); + for (i = 0; i < n; i++) + g_variant_builder_add_value(&array_builder, lldp_neighbor_to_variant(neighbors[i])); + self->variant = g_variant_ref_sink(g_variant_builder_end(&array_builder)); } - ret = sd_lldp_new(&priv->lldp_handle); - if (ret < 0) { + return self->variant; +} + +/*****************************************************************************/ + +NMLldpListener * +nm_lldp_listener_new(int ifindex, + NMLldpListenerNotify notify_callback, + gpointer notify_user_data, + GError ** error) +{ + NMLldpListener *self = NULL; + sd_lldp * lldp_handle; + int r; + + g_return_val_if_fail(ifindex > 0, FALSE); + g_return_val_if_fail(!error || !*error, FALSE); + g_return_val_if_fail(notify_callback, FALSE); + + r = sd_lldp_new(&lldp_handle); + if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, @@ -934,189 +950,77 @@ nm_lldp_listener_start(NMLldpListener *self, int ifindex, GError **error) return FALSE; } - ret = sd_lldp_set_ifindex(priv->lldp_handle, ifindex); - if (ret < 0) { + r = sd_lldp_set_ifindex(lldp_handle, ifindex); + if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "failed setting ifindex"); - goto err; + goto fail_handle; } - ret = sd_lldp_set_callback(priv->lldp_handle, lldp_event_handler, self); - if (ret < 0) { - g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "set callback failed"); - goto err; - } + r = sd_lldp_set_neighbors_max(lldp_handle, MAX_NEIGHBORS); + nm_assert(r == 0); - ret = sd_lldp_set_neighbors_max(priv->lldp_handle, MAX_NEIGHBORS); - nm_assert(ret == 0); + self = g_slice_new(NMLldpListener); + *self = (NMLldpListener){ + .ifindex = ifindex, + .notify_callback = notify_callback, + .notify_user_data = notify_user_data, + }; - priv->ifindex = ifindex; + r = sd_lldp_set_callback(lldp_handle, lldp_event_handler, self); + if (r < 0) { + g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "set callback failed"); + goto fail_handle; + } - ret = sd_lldp_attach_event(priv->lldp_handle, NULL, 0); - if (ret < 0) { + r = sd_lldp_attach_event(lldp_handle, NULL, 0); + if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "attach event failed"); - goto err_free; + goto fail_attached; } - ret = sd_lldp_start(priv->lldp_handle); - if (ret < 0) { + r = sd_lldp_start(lldp_handle); + if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "start failed"); - goto err; + goto fail_attached; } - priv->lldp_neighbors = g_hash_table_new_full(lldp_neighbor_id_hash, + self->lldp_neighbors = g_hash_table_new_full(lldp_neighbor_id_hash, lldp_neighbor_id_equal, (GDestroyNotify) lldp_neighbor_free, NULL); - - _LOGD("start"); - - return TRUE; - -err: - sd_lldp_detach_event(priv->lldp_handle); -err_free: - sd_lldp_unref(priv->lldp_handle); - priv->lldp_handle = NULL; - priv->ifindex = 0; - return FALSE; + self->lldp_handle = lldp_handle; + + _LOGD("start lldp listener"); + return self; + +fail_attached: + sd_lldp_detach_event(lldp_handle); +fail_handle: + if (self) + nm_g_slice_free(self); + sd_lldp_unref(lldp_handle); + return NULL; } void -nm_lldp_listener_stop(NMLldpListener *self) +nm_lldp_listener_destroy(NMLldpListener *self) { - NMLldpListenerPrivate *priv; - guint size; - gboolean changed = FALSE; - - g_return_if_fail(NM_IS_LLDP_LISTENER(self)); - priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - - if (priv->lldp_handle) { - _LOGD("stop"); - sd_lldp_stop(priv->lldp_handle); - sd_lldp_detach_event(priv->lldp_handle); - sd_lldp_unref(priv->lldp_handle); - priv->lldp_handle = NULL; - - size = g_hash_table_size(priv->lldp_neighbors); - g_hash_table_remove_all(priv->lldp_neighbors); - nm_clear_pointer(&priv->lldp_neighbors, g_hash_table_unref); - if (size > 0 || priv->ratelimit_id != 0) - changed = TRUE; - } + g_return_if_fail(self); - nm_clear_g_source(&priv->ratelimit_id); - priv->ratelimit_next_nsec = 0; - priv->ifindex = 0; + sd_lldp_stop(self->lldp_handle); + sd_lldp_detach_event(self->lldp_handle); + sd_lldp_unref(self->lldp_handle); - if (changed) - data_changed_notify(self, priv); -} - -gboolean -nm_lldp_listener_is_running(NMLldpListener *self) -{ - NMLldpListenerPrivate *priv; - - g_return_val_if_fail(NM_IS_LLDP_LISTENER(self), FALSE); - - priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - return !!priv->lldp_handle; -} - -GVariant * -nm_lldp_listener_get_neighbors(NMLldpListener *self) -{ - NMLldpListenerPrivate *priv; - - g_return_val_if_fail(NM_IS_LLDP_LISTENER(self), FALSE); - - priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - - if (G_UNLIKELY(!priv->variant)) { - gs_free LldpNeighbor **neighbors = NULL; - GVariantBuilder array_builder; - guint i, n; - - g_variant_builder_init(&array_builder, G_VARIANT_TYPE("aa{sv}")); - neighbors = (LldpNeighbor **) - nm_utils_hash_keys_to_array(priv->lldp_neighbors, lldp_neighbor_id_cmp_p, NULL, &n); - for (i = 0; i < n; i++) - g_variant_builder_add_value(&array_builder, lldp_neighbor_to_variant(neighbors[i])); - priv->variant = g_variant_ref_sink(g_variant_builder_end(&array_builder)); - } - return priv->variant; -} - -static void -get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - NMLldpListener *self = NM_LLDP_LISTENER(object); - - switch (prop_id) { - case PROP_NEIGHBORS: - g_value_set_variant(value, nm_lldp_listener_get_neighbors(self)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); - break; - } -} - -static void -nm_lldp_listener_init(NMLldpListener *self) -{ - _LOGT("lldp listener created"); -} + nm_clear_g_source_inst(&self->ratelimit_source); -NMLldpListener * -nm_lldp_listener_new(void) -{ - return g_object_new(NM_TYPE_LLDP_LISTENER, NULL); -} + g_hash_table_destroy(self->lldp_neighbors); -static void -dispose(GObject *object) -{ - nm_lldp_listener_stop(NM_LLDP_LISTENER(object)); - - G_OBJECT_CLASS(nm_lldp_listener_parent_class)->dispose(object); -} - -static void -finalize(GObject *object) -{ - NMLldpListener * self = NM_LLDP_LISTENER(object); - NMLldpListenerPrivate *priv = NM_LLDP_LISTENER_GET_PRIVATE(self); - - nm_lldp_listener_stop(self); - - nm_clear_g_variant(&priv->variant); + nm_g_variant_unref(self->variant); _LOGT("lldp listener destroyed"); - G_OBJECT_CLASS(nm_lldp_listener_parent_class)->finalize(object); -} - -static void -nm_lldp_listener_class_init(NMLldpListenerClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS(klass); - - object_class->dispose = dispose; - object_class->finalize = finalize; - object_class->get_property = get_property; - - obj_properties[PROP_NEIGHBORS] = - g_param_spec_variant(NM_LLDP_LISTENER_NEIGHBORS, - "", - "", - G_VARIANT_TYPE("aa{sv}"), - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + nm_g_slice_free(self); } diff --git a/src/core/devices/nm-lldp-listener.h b/src/core/devices/nm-lldp-listener.h index 9d3e2436..762eb3d2 100644 --- a/src/core/devices/nm-lldp-listener.h +++ b/src/core/devices/nm-lldp-listener.h @@ -6,28 +6,21 @@ #ifndef __NM_LLDP_LISTENER__ #define __NM_LLDP_LISTENER__ -#define NM_TYPE_LLDP_LISTENER (nm_lldp_listener_get_type()) -#define NM_LLDP_LISTENER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_LLDP_LISTENER, NMLldpListener)) -#define NM_LLDP_LISTENER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_LLDP_LISTENER, NMLldpListenerClass)) -#define NM_IS_LLDP_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_LLDP_LISTENER)) -#define NM_IS_LLDP_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_LLDP_LISTENER)) -#define NM_LLDP_LISTENER_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_LLDP_LISTENER, NMLldpListenerClass)) - -#define NM_LLDP_LISTENER_NEIGHBORS "neighbors" - -typedef struct _NMLldpListenerClass NMLldpListenerClass; - -GType nm_lldp_listener_get_type(void); -NMLldpListener *nm_lldp_listener_new(void); -gboolean nm_lldp_listener_start(NMLldpListener *self, int ifindex, GError **error); -void nm_lldp_listener_stop(NMLldpListener *self); -gboolean nm_lldp_listener_is_running(NMLldpListener *self); +/*****************************************************************************/ +typedef void (*NMLldpListenerNotify)(NMLldpListener *self, gpointer user_data); + +NMLldpListener *nm_lldp_listener_new(int ifindex, + NMLldpListenerNotify notify_callback, + gpointer notify_user_data, + GError ** error); +void nm_lldp_listener_destroy(NMLldpListener *self); + +int nm_lldp_listener_get_ifindex(NMLldpListener *self); GVariant *nm_lldp_listener_get_neighbors(NMLldpListener *self); +/*****************************************************************************/ + GVariant *nmtst_lldp_parse_from_raw(const guint8 *raw_data, gsize raw_len); #endif /* __NM_LLDP_LISTENER__ */ diff --git a/src/core/devices/ovs/meson.build b/src/core/devices/ovs/meson.build index 81c29bd6..1974ff4c 100644 --- a/src/core/devices/ovs/meson.build +++ b/src/core/devices/ovs/meson.build @@ -13,7 +13,6 @@ libnm_device_plugin_ovs = shared_module( core_plugin_dep, jansson_dep, ], - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/ovs/nm-device-ovs-bridge.c b/src/core/devices/ovs/nm-device-ovs-bridge.c index 3ae8a481..26a5ba00 100644 --- a/src/core/devices/ovs/nm-device-ovs-bridge.c +++ b/src/core/devices/ovs/nm-device-ovs-bridge.c @@ -16,7 +16,7 @@ #include "nm-setting-connection.h" #include "nm-setting-ovs-bridge.h" #include "nm-setting-ovs-external-ids.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceOvsBridge #include "devices/nm-device-logging.h" @@ -134,9 +134,7 @@ static const NMDBusInterfaceInfoExtended interface_info_device_ovs_bridge = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_OVS_BRIDGE, .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), ), }; static void diff --git a/src/core/devices/ovs/nm-device-ovs-interface.c b/src/core/devices/ovs/nm-device-ovs-interface.c index 0a537f7a..46a612ac 100644 --- a/src/core/devices/ovs/nm-device-ovs-interface.c +++ b/src/core/devices/ovs/nm-device-ovs-interface.c @@ -414,10 +414,7 @@ dispose(GObject *object) } static const NMDBusInterfaceInfoExtended interface_info_device_ovs_interface = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( - NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), ), - .legacy_property_changed = TRUE, + .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(NM_DBUS_INTERFACE_DEVICE_OVS_INTERFACE, ), }; static void diff --git a/src/core/devices/ovs/nm-device-ovs-port.c b/src/core/devices/ovs/nm-device-ovs-port.c index 2ecb95e8..f11c5852 100644 --- a/src/core/devices/ovs/nm-device-ovs-port.c +++ b/src/core/devices/ovs/nm-device-ovs-port.c @@ -167,9 +167,7 @@ static const NMDBusInterfaceInfoExtended interface_info_device_ovs_port = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_OVS_PORT, .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), ), ), }; static void diff --git a/src/core/devices/ovs/nm-ovs-factory.c b/src/core/devices/ovs/nm-ovs-factory.c index e7af38d8..6f5d8832 100644 --- a/src/core/devices/ovs/nm-ovs-factory.c +++ b/src/core/devices/ovs/nm-ovs-factory.c @@ -10,8 +10,8 @@ #include "nm-device-ovs-interface.h" #include "nm-device-ovs-port.h" #include "nm-device-ovs-bridge.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" #include "settings/nm-settings.h" #include "devices/nm-device-factory.h" #include "devices/nm-device-private.h" diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c index da3a7989..b8d5311a 100644 --- a/src/core/devices/ovs/nm-ovsdb.c +++ b/src/core/devices/ovs/nm-ovsdb.c @@ -10,10 +10,10 @@ #include #include -#include "nm-glib-aux/nm-jansson.h" -#include "nm-glib-aux/nm-str-buf.h" +#include "libnm-glib-aux/nm-jansson.h" +#include "libnm-glib-aux/nm-str-buf.h" #include "nm-core-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "devices/nm-device.h" #include "nm-manager.h" #include "nm-setting-ovs-external-ids.h" diff --git a/src/core/devices/team/meson.build b/src/core/devices/team/meson.build index d0ff4caa..b1ee9103 100644 --- a/src/core/devices/team/meson.build +++ b/src/core/devices/team/meson.build @@ -11,7 +11,6 @@ libnm_device_plugin_team = shared_module( jansson_dep, libteamdctl_dep, ], - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/team/nm-device-team.c b/src/core/devices/team/nm-device-team.c index d2d71729..0f1a8c4c 100644 --- a/src/core/devices/team/nm-device-team.c +++ b/src/core/devices/team/nm-device-team.c @@ -15,15 +15,15 @@ #include #include -#include "nm-glib-aux/nm-jansson.h" +#include "libnm-glib-aux/nm-jansson.h" #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-config.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" #include "nm-ip4-config.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #define _NMLOG_DEVICE_TYPE NMDeviceTeam #include "devices/nm-device-logging.h" @@ -829,12 +829,12 @@ enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gbool "enslaved team port %s config not changed, not connected to teamd", slave_iface); } else { - int err; - char *sanitized_config; + gs_free char *sanitized_config = NULL; + int err; - sanitized_config = g_strdelimit(g_strdup(config), "\r\n", ' '); + sanitized_config = g_strdup(config); + g_strdelimit(sanitized_config, "\r\n", ' '); err = teamdctl_port_config_update_raw(priv->tdc, slave_iface, sanitized_config); - g_free(sanitized_config); if (err != 0) { _LOGE(LOGD_TEAM, "failed to update config for port %s (err=%d)", @@ -1042,17 +1042,13 @@ dispose(GObject *object) static const NMDBusInterfaceInfoExtended interface_info_device_team = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_TEAM, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Carrier", "b", NM_DEVICE_CARRIER), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Slaves", "ao", NM_DEVICE_SLAVES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Config", - "s", - NM_DEVICE_TEAM_CONFIG), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Carrier", "b", NM_DEVICE_CARRIER), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Slaves", "ao", NM_DEVICE_SLAVES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Config", + "s", + NM_DEVICE_TEAM_CONFIG), ), ), }; static void diff --git a/src/core/devices/team/nm-team-factory.c b/src/core/devices/team/nm-team-factory.c index 57b51bf8..e2040d19 100644 --- a/src/core/devices/team/nm-team-factory.c +++ b/src/core/devices/team/nm-team-factory.c @@ -10,8 +10,8 @@ #include "nm-manager.h" #include "devices/nm-device-factory.h" #include "nm-device-team.h" -#include "platform/nm-platform.h" -#include "nm-core-internal.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" /*****************************************************************************/ diff --git a/src/core/devices/tests/test-acd.c b/src/core/devices/tests/test-acd.c index b0af59db..b4b65165 100644 --- a/src/core/devices/tests/test-acd.c +++ b/src/core/devices/tests/test-acd.c @@ -78,8 +78,8 @@ fixture_setup(test_fixture *fixture, gconstpointer user_data) fixture->ifindex1 = nmtstp_link_get_typed(NM_PLATFORM_GET, -1, IFACE_VETH1, NM_LINK_TYPE_VETH)->ifindex; - g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, fixture->ifindex0, NULL)); - g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, fixture->ifindex1, NULL)); + g_assert(nm_platform_link_change_flags(NM_PLATFORM_GET, fixture->ifindex0, IFF_UP, TRUE) >= 0); + g_assert(nm_platform_link_change_flags(NM_PLATFORM_GET, fixture->ifindex1, IFF_UP, TRUE) >= 0); fixture->hwaddr0 = nm_platform_link_get_address(NM_PLATFORM_GET, fixture->ifindex0, &fixture->hwaddr0_len); diff --git a/src/core/devices/tests/test-lldp.c b/src/core/devices/tests/test-lldp.c index ef0b1549..c64c7c11 100644 --- a/src/core/devices/tests/test-lldp.c +++ b/src/core/devices/tests/test-lldp.c @@ -13,7 +13,7 @@ #include #include "devices/nm-lldp-listener.h" -#include "systemd/nm-sd.h" +#include "libnm-systemd-core/nm-sd.h" #include "platform/tests/test-common.h" @@ -83,6 +83,7 @@ typedef struct { const uint8_t *frame; const char * as_variant; } TestRecvFrame; + #define TEST_RECV_FRAME_DEFINE(name, _as_variant, ...) \ static const guint8 _##name##_v[] = {__VA_ARGS__}; \ static const TestRecvFrame name = { \ @@ -91,12 +92,18 @@ typedef struct { .frame = _##name##_v, \ } +typedef struct { + int num_called; + GMainLoop *loop_to_quit; +} TestRecvCallbackInfo; + typedef struct { guint expected_num_called; gsize frames_len; const TestRecvFrame *frames[10]; - void (*check)(GMainLoop *loop, NMLldpListener *listener); + void (*check)(GMainLoop *loop, NMLldpListener *listener, TestRecvCallbackInfo *info); } TestRecvData; + #define TEST_RECV_DATA_DEFINE(name, _expected_num_called, _check, ...) \ static const TestRecvData name = { \ .expected_num_called = _expected_num_called, \ @@ -213,7 +220,7 @@ _test_recv_data0_check_do(GMainLoop *loop, NMLldpListener *listener, const TestR } static void -_test_recv_data0_check(GMainLoop *loop, NMLldpListener *listener) +_test_recv_data0_check(GMainLoop *loop, NMLldpListener *listener, TestRecvCallbackInfo *info) { _test_recv_data0_check_do(loop, listener, &_test_recv_data0_frame0); } @@ -528,7 +535,7 @@ TEST_RECV_FRAME_DEFINE( ); static void -_test_recv_data1_check(GMainLoop *loop, NMLldpListener *listener) +_test_recv_data1_check(GMainLoop *loop, NMLldpListener *listener, TestRecvCallbackInfo *info) { GVariant * neighbors, *attr, *child; gs_unref_variant GVariant *neighbor = NULL; @@ -756,21 +763,17 @@ TEST_RECV_FRAME_DEFINE( ); static void -_test_recv_data2_ttl1_check(GMainLoop *loop, NMLldpListener *listener) +_test_recv_data2_ttl1_check(GMainLoop *loop, NMLldpListener *listener, TestRecvCallbackInfo *info) { - gulong notify_id; GVariant *neighbors; _test_recv_data0_check_do(loop, listener, &_test_recv_data2_frame0_ttl1); /* wait for signal. */ - notify_id = g_signal_connect(listener, - "notify::" NM_LLDP_LISTENER_NEIGHBORS, - nmtst_main_loop_quit_on_notify, - loop); + info->loop_to_quit = loop; if (!nmtst_main_loop_run(loop, 5000)) g_assert_not_reached(); - nm_clear_g_signal_handler(listener, ¬ify_id); + info->loop_to_quit = NULL; neighbors = nm_lldp_listener_get_neighbors(listener); nmtst_assert_variant_is_of_type(neighbors, G_VARIANT_TYPE("aa{sv}")); @@ -852,46 +855,37 @@ again: memcpy(fixture->mac, link->l_address.data, ETH_ALEN); } -typedef struct { - int num_called; -} TestRecvCallbackInfo; - static void -lldp_neighbors_changed(NMLldpListener *lldp_listener, GParamSpec *pspec, gpointer user_data) +lldp_neighbors_changed(NMLldpListener *lldp_listener, gpointer user_data) { TestRecvCallbackInfo *info = user_data; info->num_called++; + if (info->loop_to_quit) + g_main_loop_quit(info->loop_to_quit); } static void test_recv(TestRecvFixture *fixture, gconstpointer user_data) { - const TestRecvData *data = user_data; - gs_unref_object NMLldpListener *listener = NULL; - GMainLoop * loop; - TestRecvCallbackInfo info = {}; - gsize i_frames; - gulong notify_id; - GError * error = NULL; - guint sd_id; + const TestRecvData * data = user_data; + NMLldpListener * listener; + GMainLoop * loop; + TestRecvCallbackInfo info = {}; + gsize i_frames; + GError * error = NULL; + guint sd_id; if (fixture->ifindex == 0) { g_test_skip("Tun device not available"); return; } - listener = nm_lldp_listener_new(); - g_assert(listener != NULL); - g_assert(nm_lldp_listener_start(listener, fixture->ifindex, &error)); - g_assert_no_error(error); + listener = nm_lldp_listener_new(fixture->ifindex, lldp_neighbors_changed, &info, &error); + nmtst_assert_success(listener, error); - notify_id = g_signal_connect(listener, - "notify::" NM_LLDP_LISTENER_NEIGHBORS, - (GCallback) lldp_neighbors_changed, - &info); - loop = g_main_loop_new(NULL, FALSE); - sd_id = nm_sd_event_attach_default(); + loop = g_main_loop_new(NULL, FALSE); + sd_id = nm_sd_event_attach_default(); for (i_frames = 0; i_frames < data->frames_len; i_frames++) { const TestRecvFrame *f = data->frames[i_frames]; @@ -904,9 +898,9 @@ test_recv(TestRecvFixture *fixture, gconstpointer user_data) g_assert_cmpint(info.num_called, ==, data->expected_num_called); - nm_clear_g_signal_handler(listener, ¬ify_id); + data->check(loop, listener, &info); - data->check(loop, listener); + nm_clear_pointer(&listener, nm_lldp_listener_destroy); nm_clear_g_source(&sd_id); nm_clear_pointer(&loop, g_main_loop_unref); diff --git a/src/core/devices/wifi/meson.build b/src/core/devices/wifi/meson.build index 743937db..85553c53 100644 --- a/src/core/devices/wifi/meson.build +++ b/src/core/devices/wifi/meson.build @@ -22,7 +22,6 @@ libnm_device_plugin_wifi_static = static_library( dependencies: [ core_plugin_dep, ], - c_args: daemon_c_flags, ) libnm_device_plugin_wifi_static_dep = declare_dependency( @@ -38,7 +37,6 @@ libnm_device_plugin_wifi = shared_module( core_plugin_dep, libnm_device_plugin_wifi_static_dep ], - c_args: daemon_c_flags, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c index 01f2a303..56338743 100644 --- a/src/core/devices/wifi/nm-device-iwd.c +++ b/src/core/devices/wifi/nm-device-iwd.c @@ -13,16 +13,16 @@ #include "devices/nm-device.h" #include "nm-act-request.h" #include "nm-config.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-iwd-manager.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "nm-setting-8021x.h" #include "nm-setting-connection.h" #include "nm-setting-wireless-security.h" #include "nm-setting-wireless.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-utils.h" #include "nm-wifi-common.h" #include "nm-wifi-utils.h" @@ -55,7 +55,7 @@ typedef struct { CList aps_lst_head; NMWifiAP * current_ap; GCancellable * cancellable; - NMDeviceWifiCapabilities capabilities; + _NMDeviceWifiCapabilities capabilities; NMActRequestGetSecretsCallId *wifi_secrets_id; guint periodic_scan_id; guint periodic_update_id; @@ -265,7 +265,7 @@ ap_from_network(NMDeviceIwd *self, .bss_path = bss_path, .last_seen_msec = last_seen_msec, .bssid_valid = TRUE, - .mode = NM_802_11_MODE_INFRA, + .mode = _NM_802_11_MODE_INFRA, .rsn_flags = ap_security_flags_from_network_type(type), .ssid = ssid, .signal_percent = nm_wifi_utils_level_to_quality(signal / 100), @@ -812,7 +812,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * NMSettingWirelessSecurity *s_wireless_sec = nm_connection_get_setting_wireless_security(connection); - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_AP)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, "device does not support Access Point mode"); @@ -830,7 +830,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * NMSettingWirelessSecurity *s_wireless_sec = nm_connection_get_setting_wireless_security(connection); - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_ADHOC)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, "device does not support Ad-Hoc mode"); @@ -1045,16 +1045,15 @@ complete_connection(NMDevice * device, } ssid_utf8 = iwd_ssid_to_str(ssid); - nm_utils_complete_generic( - nm_device_get_platform(device), - connection, - NM_SETTING_WIRELESS_SETTING_NAME, - existing_connections, - ssid_utf8, - ssid_utf8, - NULL, - nm_setting_wireless_get_mac_address(s_wifi) ? NULL : nm_device_get_iface(device), - TRUE); + nm_utils_complete_generic(nm_device_get_platform(device), + connection, + NM_SETTING_WIRELESS_SETTING_NAME, + existing_connections, + ssid_utf8, + ssid_utf8, + NULL, + NULL, + TRUE); if (hidden) g_object_set(s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); @@ -1317,6 +1316,7 @@ static gboolean try_reply_agent_request(NMDeviceIwd * self, NMConnection * connection, GDBusMethodInvocation *invocation, + gboolean allow_existing, const char ** setting_name, const char ** setting_key, gboolean * replied) @@ -1331,56 +1331,64 @@ try_reply_agent_request(NMDeviceIwd * self, *replied = FALSE; if (nm_streq(method_name, "RequestPassphrase")) { - const char *psk; - if (!s_wireless_sec) return FALSE; - psk = nm_setting_wireless_security_get_psk(s_wireless_sec); - if (psk) { - _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the PSK to the IWD Agent"); + if (allow_existing) { + const char *psk = nm_setting_wireless_security_get_psk(s_wireless_sec); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", psk)); - *replied = TRUE; - return TRUE; + if (psk) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the PSK to the IWD Agent"); + + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", psk)); + *replied = TRUE; + return TRUE; + } } *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME; *setting_key = NM_SETTING_WIRELESS_SECURITY_PSK; return TRUE; } else if (nm_streq(method_name, "RequestPrivateKeyPassphrase")) { - const char *password; - if (!s_8021x) return FALSE; - password = nm_setting_802_1x_get_private_key_password(s_8021x); - if (password) { - _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the private key password to the IWD Agent"); + if (allow_existing) { + const char *password = nm_setting_802_1x_get_private_key_password(s_8021x); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); - *replied = TRUE; - return TRUE; + if (password) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, + "Returning the private key password to the IWD Agent"); + + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); + *replied = TRUE; + return TRUE; + } } *setting_name = NM_SETTING_802_1X_SETTING_NAME; *setting_key = NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD; return TRUE; } else if (nm_streq(method_name, "RequestUserNameAndPassword")) { - const char *identity, *password; + const char *identity; if (!s_8021x) return FALSE; identity = nm_setting_802_1x_get_identity(s_8021x); - password = nm_setting_802_1x_get_password(s_8021x); - if (identity && password) { - _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the username and password to the IWD Agent"); - g_dbus_method_invocation_return_value(invocation, - g_variant_new("(ss)", identity, password)); - *replied = TRUE; - return TRUE; + if (allow_existing) { + const char *password = nm_setting_802_1x_get_password(s_8021x); + + if (identity && password) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, + "Returning the username and password to the IWD Agent"); + + g_dbus_method_invocation_return_value(invocation, + g_variant_new("(ss)", identity, password)); + *replied = TRUE; + return TRUE; + } } *setting_name = NM_SETTING_802_1X_SETTING_NAME; @@ -1390,18 +1398,19 @@ try_reply_agent_request(NMDeviceIwd * self, *setting_key = NM_SETTING_802_1X_PASSWORD; return TRUE; } else if (nm_streq(method_name, "RequestUserPassword")) { - const char *password; - if (!s_8021x) return FALSE; - password = nm_setting_802_1x_get_password(s_8021x); - if (password) { - _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the user password to the IWD Agent"); + if (allow_existing) { + const char *password = nm_setting_802_1x_get_password(s_8021x); - g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); - *replied = TRUE; - return TRUE; + if (password) { + _LOGD(LOGD_DEVICE | LOGD_WIFI, "Returning the user password to the IWD Agent"); + + g_dbus_method_invocation_return_value(invocation, g_variant_new("(s)", password)); + *replied = TRUE; + return TRUE; + } } *setting_name = NM_SETTING_802_1X_SETTING_NAME; @@ -1452,6 +1461,8 @@ wifi_secrets_cb(NMActRequest * req, gboolean replied; NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMIwdNetworkSecurity security; + NMConnection * connection; nm_utils_user_data_unpack(user_data, &self, &invocation); @@ -1484,9 +1495,18 @@ wifi_secrets_cb(NMActRequest * req, goto secrets_error; } + connection = nm_device_get_applied_connection(device); + + if (nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security) + && security == NM_IWD_NETWORK_SECURITY_PSK) { + if (nm_settings_connection_get_timestamp(nm_device_get_settings_connection(device), NULL)) + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + } + if (!try_reply_agent_request(self, - nm_act_request_get_applied_connection(req), + connection, invocation, + TRUE, &setting_name, &setting_key, &replied)) @@ -1512,9 +1532,6 @@ wifi_secrets_cb(NMActRequest * req, return; } - if (nm_settings_connection_get_timestamp(nm_act_request_get_settings_connection(req), NULL)) - get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - /* Request further secrets if we still need something */ wifi_secrets_get_one(self, setting_name, get_secret_flags, setting_key, invocation); return; @@ -1606,8 +1623,6 @@ network_connect_cb(GObject *source, GAsyncResult *res, gpointer user_data) dbus_error = g_dbus_error_get_remote_error(error); if (nm_streq0(dbus_error, "net.connman.iwd.Failed")) { - nm_connection_clear_secrets(connection); - /* If secrets were wrong, we'd be getting a net.connman.iwd.Failed */ reason = NM_DEVICE_STATE_REASON_NO_SECRETS; } else if (nm_streq0(dbus_error, "net.connman.iwd.Aborted") && priv->secrets_failed) { @@ -2621,9 +2636,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) switch (prop_id) { case PROP_MODE: if (!priv->current_ap) - g_value_set_uint(value, NM_802_11_MODE_UNKNOWN); + g_value_set_uint(value, _NM_802_11_MODE_UNKNOWN); else if (nm_wifi_ap_is_hotspot(priv->current_ap)) - g_value_set_uint(value, NM_802_11_MODE_AP); + g_value_set_uint(value, _NM_802_11_MODE_AP); else g_value_set_uint(value, nm_wifi_ap_get_mode(priv->current_ap)); @@ -3045,7 +3060,7 @@ nm_device_iwd_set_dbus_object(NMDeviceIwd *self, GDBusObject *object) GVariantIter * iter; const char * mode; gboolean powered; - NMDeviceWifiCapabilities capabilities; + _NMDeviceWifiCapabilities capabilities; if (!nm_g_object_ref_set(&priv->dbus_obj, object)) return; @@ -3107,14 +3122,14 @@ nm_device_iwd_set_dbus_object(NMDeviceIwd *self, GDBusObject *object) goto error; } - capabilities = NM_WIFI_DEVICE_CAP_CIPHER_CCMP | NM_WIFI_DEVICE_CAP_RSN; + capabilities = _NM_WIFI_DEVICE_CAP_CIPHER_CCMP | _NM_WIFI_DEVICE_CAP_RSN; g_variant_get(value, "as", &iter); while (g_variant_iter_next(iter, "&s", &mode)) { if (nm_streq(mode, "ap")) - capabilities |= NM_WIFI_DEVICE_CAP_AP; + capabilities |= _NM_WIFI_DEVICE_CAP_AP; else if (nm_streq(mode, "ad-hoc")) - capabilities |= NM_WIFI_DEVICE_CAP_ADHOC; + capabilities |= _NM_WIFI_DEVICE_CAP_ADHOC; } g_variant_iter_free(iter); @@ -3156,8 +3171,11 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation) const char * setting_key; gboolean replied; NMWifiAP * ap; + gboolean allow_existing = FALSE; NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; + NMIwdNetworkSecurity security; + NMConnection * connection; nm_auto_ref_string NMRefString *network_path = NULL; if (!invocation) { @@ -3261,9 +3279,37 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation) /* Otherwise handle as usual */ } + /* Normally for PSK networks require new secret every time IWD asks for + * it. IWD only queries us if it has not saved the PSK (e.g. by policy) + * or a previous attempt has failed with current secrets so it wants a + * fresh value. It doesn't know about agent-owned secrets so whenever + * possible and the PSK is saved and not asked from NM. However if this + * is a new connection it may include all of the needed settings already + * so allow using these, too. Connection timestamp is set after + * activation or after first activation failure (to 0). + * + * For 802.1x, since IWD assumes the network is pre-provisioned by an + * admin and tested, there's no reason for IWD to save secrets in + * the network config file and there's no reason to ask for a new value + * of a saved (i.e. system-owned) secret because it can't be wrong. + * Since NM has a richer set of secret storage options we never specify + * NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW and let + * nm_settings_connection_get_secrets decide. + */ + connection = nm_device_get_applied_connection(device); + + if (nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security) + && security == NM_IWD_NETWORK_SECURITY_PSK) { + if (nm_settings_connection_get_timestamp(nm_device_get_settings_connection(device), NULL)) + get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; + else + allow_existing = TRUE; + } + if (!try_reply_agent_request(self, - nm_device_get_applied_connection(device), + connection, invocation, + allow_existing, &setting_name, &setting_key, &replied)) { @@ -3274,17 +3320,6 @@ nm_device_iwd_agent_query(NMDeviceIwd *self, GDBusMethodInvocation *invocation) if (replied) return TRUE; - /* Normally require new secrets every time IWD asks for them. - * IWD only queries us if it has not saved the secrets (e.g. by policy) - * or a previous attempt has failed with current secrets so it wants - * a fresh set. However if this is a new connection it may include - * all of the needed settings already so allow using these, too. - * Connection timestamp is set after activation or after first - * activation failure (to 0). - */ - if (nm_settings_connection_get_timestamp(nm_device_get_settings_connection(device), NULL)) - get_secret_flags |= NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW; - nm_device_state_changed(device, NM_DEVICE_STATE_NEED_AUTH, NM_DEVICE_STATE_REASON_NO_SECRETS); wifi_secrets_get_one(self, setting_name, get_secret_flags, setting_key, invocation); @@ -3463,9 +3498,9 @@ nm_device_iwd_class_init(NMDeviceIwdClass *klass) obj_properties[PROP_MODE] = g_param_spec_uint(NM_DEVICE_IWD_MODE, "", "", - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_AP, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_UNKNOWN, + _NM_802_11_MODE_AP, + _NM_802_11_MODE_INFRA, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_BITRATE] = g_param_spec_uint(NM_DEVICE_IWD_BITRATE, @@ -3496,7 +3531,7 @@ nm_device_iwd_class_init(NMDeviceIwdClass *klass) "", 0, G_MAXUINT32, - NM_WIFI_DEVICE_CAP_NONE, + _NM_WIFI_DEVICE_CAP_NONE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_SCANNING] = g_param_spec_boolean(NM_DEVICE_IWD_SCANNING, diff --git a/src/core/devices/wifi/nm-device-olpc-mesh.c b/src/core/devices/wifi/nm-device-olpc-mesh.c index af83c4a3..040350d5 100644 --- a/src/core/devices/wifi/nm-device-olpc-mesh.c +++ b/src/core/devices/wifi/nm-device-olpc-mesh.c @@ -28,7 +28,7 @@ #include "nm-setting-connection.h" #include "nm-setting-olpc-mesh.h" #include "nm-manager.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #define _NMLOG_DEVICE_TYPE NMDeviceOlpcMesh #include "devices/nm-device-logging.h" @@ -122,6 +122,17 @@ complete_connection(NMDevice * device, /*****************************************************************************/ +static const char * +get_dhcp_anycast_address(NMDevice *device) +{ + NMSettingOlpcMesh *s_mesh; + + s_mesh = nm_device_get_applied_setting(device, NM_TYPE_SETTING_OLPC_MESH); + return s_mesh ? nm_setting_olpc_mesh_get_dhcp_anycast_address(s_mesh) : NULL; +} + +/*****************************************************************************/ + static NMActStageReturn act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) { @@ -178,7 +189,6 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) NMDeviceOlpcMesh * self = NM_DEVICE_OLPC_MESH(device); NMSettingOlpcMesh *s_mesh; GBytes * ssid; - const char * anycast_addr; gboolean success; s_mesh = nm_device_get_applied_setting(device, NM_TYPE_SETTING_OLPC_MESH); @@ -197,9 +207,6 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) return NM_ACT_STAGE_RETURN_FAILURE; } - anycast_addr = nm_setting_olpc_mesh_get_dhcp_anycast_address(s_mesh); - nm_device_set_dhcp_anycast_address(device, anycast_addr); - if (!_mesh_set_channel(self, nm_setting_olpc_mesh_get_channel(s_mesh))) { _LOGW(LOGD_WIFI, "Unable to set the mesh channel"); return NM_ACT_STAGE_RETURN_FAILURE; @@ -492,19 +499,15 @@ dispose(GObject *object) static const NMDBusInterfaceInfoExtended interface_info_device_olpc_mesh = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_OLPC_MESH, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Companion", - "o", - NM_DEVICE_OLPC_MESH_COMPANION), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L( + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Companion", + "o", + NM_DEVICE_OLPC_MESH_COMPANION), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE( "ActiveChannel", "u", NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL), ), ), - .legacy_property_changed = TRUE, }; static void @@ -531,6 +534,7 @@ nm_device_olpc_mesh_class_init(NMDeviceOlpcMeshClass *klass) device_class->act_stage2_config = act_stage2_config; device_class->state_changed = state_changed; device_class->get_dhcp_timeout_for_device = get_dhcp_timeout_for_device; + device_class->get_dhcp_anycast_address = get_dhcp_anycast_address; obj_properties[PROP_COMPANION] = g_param_spec_string(NM_DEVICE_OLPC_MESH_COMPANION, "", diff --git a/src/core/devices/wifi/nm-device-wifi-p2p.c b/src/core/devices/wifi/nm-device-wifi-p2p.c index fb987600..a8ea2ed7 100644 --- a/src/core/devices/wifi/nm-device-wifi-p2p.c +++ b/src/core/devices/wifi/nm-device-wifi-p2p.c @@ -15,16 +15,16 @@ #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" #include "nm-act-request.h" -#include "nm-core-internal.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-ip4-config.h" #include "nm-manager.h" #include "nm-manager.h" #include "nm-setting-wifi-p2p.h" #include "nm-utils.h" #include "nm-wifi-p2p-peer.h" -#include "platform/nm-platform.h" -#include "platform/nmp-object.h" +#include "libnm-platform/nm-platform.h" +#include "libnm-platform/nmp-object.h" #include "settings/nm-settings.h" #define _NMLOG_DEVICE_TYPE NMDeviceWifiP2P @@ -1149,7 +1149,6 @@ static const NMDBusInterfaceInfoExtended interface_info_device_wifi_p2p = { NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Peers", "ao", NM_DEVICE_WIFI_P2P_PEERS), ), ), - .legacy_property_changed = FALSE, }; /*****************************************************************************/ diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c index c9655eea..fca2fde5 100644 --- a/src/core/devices/wifi/nm-device-wifi.c +++ b/src/core/devices/wifi/nm-device-wifi.c @@ -12,11 +12,11 @@ #include #include -#include "nm-glib-aux/nm-ref-string.h" -#include "nm-glib-aux/nm-c-list.h" +#include "libnm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-c-list.h" #include "nm-device-wifi-p2p.h" #include "nm-wifi-ap.h" -#include "nm-libnm-core-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-common-macros.h" #include "devices/nm-device.h" #include "devices/nm-device-private.h" #include "nm-dbus-manager.h" @@ -33,13 +33,13 @@ #include "nm-setting-ip4-config.h" #include "nm-ip4-config.h" #include "nm-setting-ip6-config.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-auth-utils.h" #include "settings/nm-settings-connection.h" #include "settings/nm-settings.h" #include "nm-wifi-utils.h" #include "nm-wifi-common.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-config.h" #define _NMLOG_DEVICE_TYPE NMDeviceWifi @@ -114,11 +114,11 @@ typedef struct { guint wps_timeout_id; guint sup_timeout_id; /* supplicant association timeout */ - NMDeviceWifiCapabilities capabilities; - NMSettingWirelessWakeOnWLan wowlan_restore; + _NMDeviceWifiCapabilities capabilities; + _NMSettingWirelessWakeOnWLan wowlan_restore; NMDeviceWifiP2P *p2p_device; - NM80211Mode mode; + _NM80211Mode mode; guint32 failed_iface_count; gint32 hw_addr_scan_expire; @@ -487,7 +487,7 @@ _scan_notify_allowed(NMDeviceWifi *self, NMTernary do_kickoff) if (!c_list_is_empty(&priv->scanning_prohibited_lst_head)) { /* something prohibits scanning. */ - } else if (NM_IN_SET(priv->mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_AP)) { + } else if (NM_IN_SET(priv->mode, _NM_802_11_MODE_ADHOC, _NM_802_11_MODE_AP)) { /* Don't scan when a an AP or Ad-Hoc connection is active as it will * disrupt connected clients or peers. */ } else if (NM_IN_SET(state, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_FAILED)) { @@ -678,7 +678,7 @@ update_seen_bssids_cache(NMDeviceWifi *self, NMWifiAP *ap) return; /* Don't cache the BSSID for Ad-Hoc APs */ - if (nm_wifi_ap_get_mode(ap) != NM_802_11_MODE_INFRA) + if (nm_wifi_ap_get_mode(ap) != _NM_802_11_MODE_INFRA) return; if (nm_device_get_state(NM_DEVICE(self)) == NM_DEVICE_STATE_ACTIVATED @@ -712,10 +712,11 @@ set_current_ap(NMDeviceWifi *self, NMWifiAP *new_ap, gboolean recheck_available_ priv->current_ap = NULL; if (old_ap) { - NM80211Mode mode = nm_wifi_ap_get_mode(old_ap); + _NM80211Mode mode = nm_wifi_ap_get_mode(old_ap); /* Remove any AP from the internal list if it was created by NM or isn't known to the supplicant */ - if (NM_IN_SET(mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_AP) || nm_wifi_ap_get_fake(old_ap)) + if (NM_IN_SET(mode, _NM_802_11_MODE_ADHOC, _NM_802_11_MODE_AP) + || nm_wifi_ap_get_fake(old_ap)) ap_add_remove(self, FALSE, old_ap, recheck_available_connections); g_object_unref(old_ap); } @@ -750,7 +751,7 @@ periodic_update(NMDeviceWifi *self) return; } - if (priv->mode == NM_802_11_MODE_AP) { + if (priv->mode == _NM_802_11_MODE_AP) { /* In AP mode we currently have nothing to do. */ return; } @@ -845,14 +846,14 @@ remove_all_aps(NMDeviceWifi *self) static gboolean wake_on_wlan_restore(NMDeviceWifi *self) { - NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - NMSettingWirelessWakeOnWLan w; + NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + _NMSettingWirelessWakeOnWLan w; w = priv->wowlan_restore; - if (w == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) + if (w == _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) return TRUE; - priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; + priv->wowlan_restore = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; return nm_platform_wifi_set_wake_on_wlan(NM_PLATFORM_GET, nm_device_get_ifindex(NM_DEVICE(self)), w); @@ -937,14 +938,14 @@ deactivate(NMDevice *device) * (usually older ones) don't scan well in adhoc mode. */ if (nm_platform_wifi_get_mode(nm_device_get_platform(device), ifindex) - != NM_802_11_MODE_INFRA) { + != _NM_802_11_MODE_INFRA) { nm_device_take_down(NM_DEVICE(self), TRUE); - nm_platform_wifi_set_mode(nm_device_get_platform(device), ifindex, NM_802_11_MODE_INFRA); + nm_platform_wifi_set_mode(nm_device_get_platform(device), ifindex, _NM_802_11_MODE_INFRA); nm_device_bring_up(NM_DEVICE(self), TRUE, NULL); } - if (priv->mode != NM_802_11_MODE_INFRA) { - priv->mode = NM_802_11_MODE_INFRA; + if (priv->mode != _NM_802_11_MODE_INFRA) { + priv->mode = _NM_802_11_MODE_INFRA; _notify(self, PROP_MODE); } @@ -1010,14 +1011,14 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * /* Early exit if supplicant or device doesn't support requested mode */ mode = nm_setting_wireless_get_mode(s_wireless); if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_ADHOC)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "the device does not support Ad-Hoc networks"); return FALSE; } } else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_AP) == 0) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_AP)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "the device does not support Access Point mode"); @@ -1034,7 +1035,7 @@ check_connection_compatible(NMDevice *device, NMConnection *connection, GError * } } } else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) { - if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_MESH)) { + if (!(priv->capabilities & _NM_WIFI_DEVICE_CAP_MESH)) { nm_utils_error_set_literal(error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, "the device does not support Mesh mode"); @@ -1381,8 +1382,8 @@ _hw_addr_set_scanning(NMDeviceWifi *self, gboolean do_reset) now = nm_utils_get_monotonic_timestamp_sec(); if (now >= priv->hw_addr_scan_expire) { - gs_free char *generate_mac_address_mask = NULL; - gs_free char *hw_addr_scan = NULL; + gs_free char *hw_addr_scan = NULL; + const char * generate_mac_address_mask; /* the random MAC address for scanning expires after a while. * @@ -1433,7 +1434,7 @@ ssids_options_to_ptrarray(GVariant *value, GError **error) v = g_variant_get_child_value(value, i); bytes = g_variant_get_fixed_array(v, &len, sizeof(guint8)); - if (len > 32) { + if (len > NM_IW_ESSID_MAX_SIZE) { g_set_error(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_ARGUMENT, @@ -1822,7 +1823,7 @@ _scan_kickoff(NMDeviceWifi *self) strv = g_new(char *, ssids->len + 1u); for (i = 0; i < ssids->len; i++) - strv[i] = _nm_utils_ssid_to_string(ssids->pdata[i]); + strv[i] = _nm_utils_ssid_to_string_gbytes(ssids->pdata[i]); strv[i] = NULL; nm_assert(ssids->len > 0); @@ -1884,13 +1885,13 @@ ap_list_dump(gpointer user_data) _LOGD(LOGD_WIFI_SCAN, "APs: [now:%u.%03u, last:%s]", - (guint)(now_msec / NM_UTILS_MSEC_PER_SEC), - (guint)(now_msec % NM_UTILS_MSEC_PER_SEC), + (guint) (now_msec / NM_UTILS_MSEC_PER_SEC), + (guint) (now_msec % NM_UTILS_MSEC_PER_SEC), priv->scan_last_complete_msec > 0 ? nm_sprintf_buf(str_buf, "%u.%03u", - (guint)(priv->scan_last_complete_msec / NM_UTILS_MSEC_PER_SEC), - (guint)(priv->scan_last_complete_msec % NM_UTILS_MSEC_PER_SEC)) + (guint) (priv->scan_last_complete_msec / NM_UTILS_MSEC_PER_SEC), + (guint) (priv->scan_last_complete_msec % NM_UTILS_MSEC_PER_SEC)) : "-1"); c_list_for_each_entry (ap, &priv->aps_lst_head, aps_lst) _ap_dump(self, LOGL_DEBUG, ap, "dump", now_msec); @@ -1986,19 +1987,19 @@ supplicant_iface_bss_changed_cb(NMSupplicantInterface *iface, /* Let the manager try to fill in the SSID from seen-bssids lists */ ssid = nm_wifi_ap_get_ssid(ap); - if (!ssid || _nm_utils_is_empty_ssid(ssid)) { + if (!ssid || _nm_utils_is_empty_ssid_gbytes(ssid)) { /* Try to fill the SSID from the AP database */ try_fill_ssid_for_hidden_ap(self, ap); ssid = nm_wifi_ap_get_ssid(ap); - if (ssid && !_nm_utils_is_empty_ssid(ssid)) { + if (ssid && !_nm_utils_is_empty_ssid_gbytes(ssid)) { gs_free char *s = NULL; /* Yay, matched it, no longer treat as hidden */ _LOGD(LOGD_WIFI, "matched hidden AP %s => %s", nm_wifi_ap_get_address(ap), - (s = _nm_utils_ssid_to_string(ssid))); + (s = _nm_utils_ssid_to_string_gbytes(ssid))); } else { /* Didn't have an entry for this AP in the database */ _LOGD(LOGD_WIFI, "failed to match hidden AP %s", nm_wifi_ap_get_address(ap)); @@ -2481,9 +2482,9 @@ supplicant_iface_state(NMDeviceWifi * self, _LOGI(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) Stage 2 of 5 (Device Configure) successful. %s %s", - priv->mode == NM_802_11_MODE_AP ? "Started Wi-Fi Hotspot" - : "Connected to wireless network", - (ssid_str = _nm_utils_ssid_to_string(ssid))); + priv->mode == _NM_802_11_MODE_AP ? "Started Wi-Fi Hotspot" + : "Connected to wireless network", + (ssid_str = _nm_utils_ssid_to_string_gbytes(ssid))); nm_device_activate_schedule_stage3_ip_config_start(device); } else if (devstate == NM_DEVICE_STATE_ACTIVATED) periodic_update(self); @@ -2599,9 +2600,9 @@ supplicant_iface_notify_current_bss(NMSupplicantInterface *iface, _LOGD(LOGD_WIFI, "roamed from BSSID %s (%s) to %s (%s)", old_bssid ?: "(none)", - (old_ssid_s = _nm_utils_ssid_to_string(old_ssid)), + (old_ssid_s = _nm_utils_ssid_to_string_gbytes(old_ssid)), new_bssid ?: "(none)", - (new_ssid_s = _nm_utils_ssid_to_string(new_ssid))); + (new_ssid_s = _nm_utils_ssid_to_string_gbytes(new_ssid))); if (new_bssid) { /* The new AP could be in a different layer 3 network @@ -2790,21 +2791,21 @@ supplicant_connection_timeout_cb(gpointer user_data) connection = nm_act_request_get_applied_connection(req); g_assert(connection); - if (NM_IN_SET(priv->mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_MESH, NM_802_11_MODE_AP)) { + if (NM_IN_SET(priv->mode, _NM_802_11_MODE_ADHOC, _NM_802_11_MODE_MESH, _NM_802_11_MODE_AP)) { /* In Ad-Hoc and AP modes there's nothing to check the encryption key * (if any), so supplicant timeouts here are almost certainly the wifi * driver being really stupid. */ _LOGW(LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) %s network creation took too long, failing activation", - priv->mode == NM_802_11_MODE_ADHOC ? "Ad-Hoc" : "Hotspot"); + priv->mode == _NM_802_11_MODE_ADHOC ? "Ad-Hoc" : "Hotspot"); nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SUPPLICANT_TIMEOUT); return FALSE; } - g_assert(priv->mode == NM_802_11_MODE_INFRA); + g_assert(priv->mode == _NM_802_11_MODE_INFRA); if (priv->ssid_found && nm_connection_get_setting_wireless_security(connection)) { guint64 timestamp = 0; @@ -2956,9 +2957,10 @@ error: static gboolean wake_on_wlan_enable(NMDeviceWifi *self) { - NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); - NMSettingWirelessWakeOnWLan wowl; - NMSettingWireless * s_wireless; + NMDeviceWifiPrivate * priv = NM_DEVICE_WIFI_GET_PRIVATE(self); + NMSettingWirelessWakeOnWLan wowl; + _NMSettingWirelessWakeOnWLan wowl2; + NMSettingWireless * s_wireless; s_wireless = nm_device_get_applied_setting(NM_DEVICE(self), NM_TYPE_SETTING_WIRELESS); if (s_wireless) { @@ -2990,9 +2992,11 @@ wake_on_wlan_enable(NMDeviceWifi *self) goto found; wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; + found: - if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) { - priv->wowlan_restore = wowl; + wowl2 = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_CAST(wowl); + if (wowl2 == _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) { + priv->wowlan_restore = wowl2; return TRUE; } @@ -3001,7 +3005,7 @@ found: return nm_platform_wifi_set_wake_on_wlan(NM_PLATFORM_GET, nm_device_get_ifindex(NM_DEVICE(self)), - wowl); + wowl2); } static NMActStageReturn @@ -3030,16 +3034,16 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) mode = nm_setting_wireless_get_mode(s_wireless); if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_INFRA) == 0) - priv->mode = NM_802_11_MODE_INFRA; + priv->mode = _NM_802_11_MODE_INFRA; else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0) - priv->mode = NM_802_11_MODE_ADHOC; + priv->mode = _NM_802_11_MODE_ADHOC; else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_AP) == 0) { - priv->mode = NM_802_11_MODE_AP; + priv->mode = _NM_802_11_MODE_AP; /* Scanning not done in AP mode; clear the scan list */ remove_all_aps(self); } else if (g_strcmp0(mode, NM_SETTING_WIRELESS_MODE_MESH) == 0) - priv->mode = NM_802_11_MODE_MESH; + priv->mode = _NM_802_11_MODE_MESH; _notify(self, PROP_MODE); /* expire the temporary MAC address used during scanning */ @@ -3052,7 +3056,7 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) } /* AP and Mesh modes never use a specific object or existing scanned AP */ - if (!NM_IN_SET(priv->mode, NM_802_11_MODE_AP, NM_802_11_MODE_MESH)) { + if (!NM_IN_SET(priv->mode, _NM_802_11_MODE_AP, _NM_802_11_MODE_MESH)) { ap_path = nm_active_connection_get_specific_object(NM_ACTIVE_CONNECTION(req)); ap = ap_path ? nm_wifi_ap_lookup_for_device(NM_DEVICE(self), ap_path) : NULL; } @@ -3154,7 +3158,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) NMDeviceWifi * self = NM_DEVICE_WIFI(device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE(self); gs_unref_object NMSupplicantConfig *config = NULL; - NM80211Mode ap_mode; + _NM80211Mode ap_mode; NMActRequest * req; NMWifiAP * ap; NMConnection * connection; @@ -3221,10 +3225,11 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) * if the user didn't specify one and we didn't find an AP that matched * the connection, just pick a frequency the device supports. */ - if (NM_IN_SET(ap_mode, NM_802_11_MODE_ADHOC, NM_802_11_MODE_MESH) || nm_wifi_ap_is_hotspot(ap)) + if (NM_IN_SET(ap_mode, _NM_802_11_MODE_ADHOC, _NM_802_11_MODE_MESH) + || nm_wifi_ap_is_hotspot(ap)) ensure_hotspot_frequency(self, s_wireless, ap); - if (ap_mode == NM_802_11_MODE_INFRA) + if (ap_mode == _NM_802_11_MODE_INFRA) set_powersave(device); /* Build up the supplicant configuration */ @@ -3341,7 +3346,7 @@ act_stage4_ip_config_timeout(NMDevice * device, s_ip = nm_connection_get_setting_ip_config(connection, addr_family); may_fail = nm_setting_ip_config_get_may_fail(s_ip); - if (priv->mode == NM_802_11_MODE_AP) + if (priv->mode == _NM_802_11_MODE_AP) goto call_parent; if (may_fail || !is_static_wep(connection)) { @@ -3694,8 +3699,8 @@ nm_device_wifi_init(NMDeviceWifi *self) priv->scan_last_request_started_at_msec = G_MININT64; priv->hidden_probe_scan_warn = TRUE; - priv->mode = NM_802_11_MODE_INFRA; - priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; + priv->mode = _NM_802_11_MODE_INFRA; + priv->wowlan_restore = _NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; } static void @@ -3706,7 +3711,7 @@ constructed(GObject *object) G_OBJECT_CLASS(nm_device_wifi_parent_class)->constructed(object); - if (priv->capabilities & NM_WIFI_DEVICE_CAP_AP) + if (priv->capabilities & _NM_WIFI_DEVICE_CAP_AP) _LOGI(LOGD_PLATFORM | LOGD_WIFI, "driver supports Access Point (AP) mode"); /* Connect to the supplicant manager */ @@ -3714,7 +3719,7 @@ constructed(GObject *object) } NMDevice * -nm_device_wifi_new(const char *iface, NMDeviceWifiCapabilities capabilities) +nm_device_wifi_new(const char *iface, _NMDeviceWifiCapabilities capabilities) { return g_object_new(NM_TYPE_DEVICE_WIFI, NM_DEVICE_IFACE, @@ -3822,9 +3827,9 @@ nm_device_wifi_class_init(NMDeviceWifiClass *klass) obj_properties[PROP_MODE] = g_param_spec_uint(NM_DEVICE_WIFI_MODE, "", "", - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_AP, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_UNKNOWN, + _NM_802_11_MODE_AP, + _NM_802_11_MODE_INFRA, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_BITRATE] = g_param_spec_uint(NM_DEVICE_WIFI_BITRATE, @@ -3855,7 +3860,7 @@ nm_device_wifi_class_init(NMDeviceWifiClass *klass) "", 0, G_MAXUINT32, - NM_WIFI_DEVICE_CAP_NONE, + _NM_WIFI_DEVICE_CAP_NONE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); obj_properties[PROP_SCANNING] = g_param_spec_boolean(NM_DEVICE_WIFI_SCANNING, diff --git a/src/core/devices/wifi/nm-device-wifi.h b/src/core/devices/wifi/nm-device-wifi.h index d9e9038c..c7ff1a14 100644 --- a/src/core/devices/wifi/nm-device-wifi.h +++ b/src/core/devices/wifi/nm-device-wifi.h @@ -33,7 +33,7 @@ typedef struct _NMDeviceWifiClass NMDeviceWifiClass; GType nm_device_wifi_get_type(void); -NMDevice *nm_device_wifi_new(const char *iface, NMDeviceWifiCapabilities capabilities); +NMDevice *nm_device_wifi_new(const char *iface, _NMDeviceWifiCapabilities capabilities); const CList *_nm_device_wifi_get_aps(NMDeviceWifi *self); diff --git a/src/core/devices/wifi/nm-iwd-manager.c b/src/core/devices/wifi/nm-iwd-manager.c index 68a74438..56386c57 100644 --- a/src/core/devices/wifi/nm-iwd-manager.c +++ b/src/core/devices/wifi/nm-iwd-manager.c @@ -8,14 +8,20 @@ #include "nm-iwd-manager.h" #include +#include +#include +#include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-manager.h" #include "nm-device-iwd.h" #include "nm-wifi-utils.h" -#include "nm-glib-aux/nm-random-utils.h" +#include "libnm-glib-aux/nm-uuid.h" +#include "libnm-glib-aux/nm-random-utils.h" +#include "libnm-glib-aux/nm-io-utils.h" #include "settings/nm-settings.h" -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" +#include "nm-config.h" /*****************************************************************************/ @@ -28,6 +34,7 @@ typedef struct { typedef struct { GDBusProxy * known_network; NMSettingsConnection *mirror_connection; + const KnownNetworkId *id; } KnownNetworkData; typedef struct { @@ -40,6 +47,8 @@ typedef struct { char * agent_path; GHashTable * known_networks; NMDeviceIwd * last_agent_call_device; + char * last_state_dir; + char * warned_state_dir; } NMIwdManagerPrivate; struct _NMIwdManager { @@ -419,25 +428,94 @@ known_network_update_cb(GObject *source, GAsyncResult *res, gpointer user_data) variant = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); if (!variant) { nm_log_warn(LOGD_WIFI, - "Updating %s on IWD known network %s failed: %s", + "iwd: updating %s on IWD known network %s failed: %s", (const char *) user_data, g_dbus_proxy_get_object_path(G_DBUS_PROXY(source)), error->message); } } +static gboolean +iwd_config_write(GKeyFile * config, + const char * filepath, + const struct timespec *mtime, + GError ** error) +{ + gsize length; + gs_free char * data = g_key_file_to_data(config, &length, NULL); + struct timespec times[2] = {{.tv_nsec = UTIME_OMIT}, *mtime}; + + /* Atomically write or replace the file with the right permission bits + * and timestamps set. We rely on the temporary file created by + * nm_utils_file_set_contents having only upper-case letters and digits + * in the last few filename characters -- it cannot end in .open, .psk + * or .8021x. + */ + return nm_utils_file_set_contents(filepath, data, length, 0600, times, NULL, error); +} + +static const char * +get_config_path(NMIwdManager *self) +{ + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE(self); + const char * path; + + path = nm_config_data_get_iwd_config_path(NM_CONFIG_GET_DATA); + if (path && path[0] == '\0') { + nm_clear_g_free(&priv->warned_state_dir); + return NULL; + } + + if (!path || nm_streq(path, "auto")) { + path = priv->last_state_dir; + if (!path) { + nm_clear_g_free(&priv->warned_state_dir); + return NULL; + } + } + + if (priv->warned_state_dir && !nm_streq(priv->warned_state_dir, path)) + nm_clear_g_free(&priv->warned_state_dir); + + if (path && (path[0] != '/' || !g_file_test(path, G_FILE_TEST_IS_DIR))) { + if (!priv->warned_state_dir) { + priv->warned_state_dir = g_strdup(path); + _LOGW("IWD StateDirectory '%s' not accessible", priv->warned_state_dir); + } + return NULL; + } + + return path; +} + static void -sett_conn_changed(NMSettingsConnection *sett_conn, guint update_reason, KnownNetworkData *data) +sett_conn_changed(NMSettingsConnection * sett_conn, + guint update_reason, + const KnownNetworkData *data) { NMSettingsConnectionIntFlags flags; - NMConnection * conn = nm_settings_connection_get_connection(sett_conn); - NMSettingConnection * s_conn = nm_connection_get_setting_connection(conn); - gboolean nm_autoconnectable = nm_setting_connection_get_autoconnect(s_conn); - gboolean iwd_autoconnectable = get_property_bool(data->known_network, "AutoConnect", TRUE); + NMConnection * conn = nm_settings_connection_get_connection(sett_conn); + NMSettingConnection * s_conn = nm_connection_get_setting_connection(conn); + NMSettingWireless * s_wifi = nm_connection_get_setting_wireless(conn); + nm_auto_unref_keyfile GKeyFile *iwd_config = NULL; + const char * iwd_dir; + gs_free char * filename = NULL; + gs_free char * full_path = NULL; + gs_free_error GError *error = NULL; + NMIwdNetworkSecurity security; + GBytes * ssid; + const guint8 * ssid_data; + gsize ssid_len; + gboolean removed; + GStatBuf statbuf; + gboolean have_mtime; nm_assert(sett_conn == data->mirror_connection); - if (iwd_autoconnectable == nm_autoconnectable) + if (!NM_FLAGS_ANY(update_reason, + NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET + | NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS + | NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS)) return; /* If this is a generated connection it may be ourselves updating it */ @@ -445,21 +523,131 @@ sett_conn_changed(NMSettingsConnection *sett_conn, guint update_reason, KnownNet if (NM_FLAGS_HAS(flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) return; + iwd_dir = get_config_path(nm_iwd_manager_get()); + if (!iwd_dir) { + gboolean nm_autoconnectable = nm_setting_connection_get_autoconnect(s_conn); + gboolean iwd_autoconnectable = get_property_bool(data->known_network, "AutoConnect", TRUE); + + if (iwd_autoconnectable != nm_autoconnectable) { + nm_log_dbg(LOGD_WIFI, + "iwd: updating AutoConnect on known network at %s based on connection %s", + g_dbus_proxy_get_object_path(data->known_network), + nm_settings_connection_get_id(data->mirror_connection)); + g_dbus_proxy_call(data->known_network, + DBUS_INTERFACE_PROPERTIES ".Set", + g_variant_new("(ssv)", + NM_IWD_KNOWN_NETWORK_INTERFACE, + "AutoConnect", + g_variant_new_boolean(nm_autoconnectable)), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + known_network_update_cb, + "AutoConnect"); + } + + return; + } + + /* If the SSID and the security type in the NMSettingsConnection haven't + * changed, we just need to overwrite the original IWD config file. + * Otherwise we need to call Forget on the original KnownNetwork or + * remove its file. IWD will have to delete one D-Bus object and + * create another anyway because the SSID and security type are in the + * D-Bus object path, so no point renaming the file. + */ + ssid = nm_setting_wireless_get_ssid(s_wifi); + ssid_data = ssid ? g_bytes_get_data(ssid, &ssid_len) : NULL; + removed = FALSE; + have_mtime = FALSE; + + if (!nm_wifi_connection_get_iwd_ssid_and_security(conn, NULL, &security) + || security != data->id->security || !ssid_data || ssid_len != strlen(data->id->name) + || memcmp(ssid_data, data->id->name, ssid_len)) { + gs_free char *orig_filename = + nm_wifi_utils_get_iwd_config_filename(data->id->name, -1, data->id->security); + gs_free char *orig_full_path = g_strdup_printf("%s/%s", iwd_dir, orig_filename); + + if (g_stat(orig_full_path, &statbuf) == 0) + have_mtime = TRUE; + + if (g_remove(orig_full_path) == 0) + nm_log_dbg(LOGD_WIFI, "iwd: profile at %s removed", orig_full_path); + else if (errno != ENOENT) + nm_log_dbg(LOGD_WIFI, + "iwd: profile at %s not removed: %s (%i)", + orig_full_path, + strerror(errno), + errno); + + removed = TRUE; + } + + if (!nm_streq(nm_settings_connection_get_connection_type(sett_conn), "802-11-wireless") + || !s_wifi) + return; + + /* If the connection has any permissions other than the default we don't + * want to save it as an IWD profile. IWD will make it available for + * everybody to attempt a connection, remove, or toggle "autoconnectable". + */ + if (s_conn && nm_setting_connection_get_num_permissions(s_conn)) { + nm_log_dbg( + LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile because of non-default " + "permissions", + nm_settings_connection_get_id(sett_conn)); + return; + } + + iwd_config = nm_wifi_utils_connection_to_iwd_config(conn, &filename, &error); + if (!iwd_config) { + /* The error message here is not translated and it only goes in + * the logs. + */ + nm_log_dbg(LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + + full_path = g_strdup_printf("%s/%s", iwd_dir, filename); + if (removed && g_file_test(full_path, G_FILE_TEST_EXISTS)) { + nm_log_dbg(LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile because %s " + "already exists", + nm_settings_connection_get_id(sett_conn), + full_path); + return; + } + + if (!removed && g_stat(full_path, &statbuf) == 0) + have_mtime = TRUE; + + /* If modifying an existing network try to preserve the file mtime, + * otherwise use a small non-zero timespec value to signal that the + * network is autoconnectable (according to its AutoConnect value) + * but hasn't recently been connected to and thus shouldn't be + * prioritized by autoconnect. + */ + if (!have_mtime) { + statbuf.st_mtim.tv_sec = 1; + statbuf.st_mtim.tv_nsec = 0; + } + + if (!iwd_config_write(iwd_config, full_path, &statbuf.st_mtim, &error)) { + nm_log_dbg(LOGD_WIFI, + "iwd: changed Wi-Fi connection %s not mirrored as IWD profile: save error: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + nm_log_dbg(LOGD_WIFI, - "Updating AutoConnect on known network at %s based on connection %s", - g_dbus_proxy_get_object_path(data->known_network), - nm_settings_connection_get_id(data->mirror_connection)); - g_dbus_proxy_call(data->known_network, - DBUS_INTERFACE_PROPERTIES ".Set", - g_variant_new("(ssv)", - NM_IWD_KNOWN_NETWORK_INTERFACE, - "AutoConnect", - g_variant_new_boolean(nm_autoconnectable)), - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - known_network_update_cb, - "AutoConnect"); + "iwd: changed Wi-Fi connection %s mirrored as IWD profile %s", + nm_settings_connection_get_id(sett_conn), + full_path); } /* Look up an existing NMSettingsConnection for a network that has been @@ -590,8 +778,10 @@ mirror_connection(NMIwdManager * self, NULL); g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_HIDDEN, hidden, NULL); } else { - KnownNetworkData data = {known_network, settings_connection}; - sett_conn_changed(settings_connection, 0, &data); + KnownNetworkData data = {known_network, settings_connection, id}; + sett_conn_changed(settings_connection, + NM_SETTINGS_CONNECTION_UPDATE_REASON_UPDATE_NON_SECRET, + &data); } } @@ -621,7 +811,7 @@ mirror_connection(NMIwdManager * self, NM_SETTING_CONNECTION_ID, id->name, NM_SETTING_CONNECTION_UUID, - nm_utils_uuid_generate_buf(uuid), + nm_uuid_generate_random_str_arr(uuid), NM_SETTING_CONNECTION_AUTOCONNECT, autoconnectable, NULL); @@ -779,6 +969,7 @@ interface_added(GDBusObjectManager *object_manager, } else { data = g_slice_new0(KnownNetworkData); data->known_network = g_object_ref(proxy); + data->id = id; g_hash_table_insert(priv->known_networks, id, data); } @@ -907,6 +1098,9 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint const guint8 * ssid_bytes; gsize ssid_len; NMSettingsConnection *new_mirror_conn; + const char * iwd_dir; + gs_free char * filename = NULL; + gs_free char * full_path = NULL; if (!nm_wifi_connection_get_iwd_ssid_and_security(conn, NULL, &id.security)) return; @@ -923,8 +1117,12 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint ssid_buf[ssid_len] = '\0'; id.name = ssid_buf; data = g_hash_table_lookup(priv->known_networks, &id); - if (!data) - return; + if (!data) { + if (!g_utf8_validate((const char *) ssid_bytes, ssid_len, NULL)) + return; + + goto try_delete_file; + } if (data->mirror_connection != sett_conn) return; @@ -941,7 +1139,7 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint } if (!priv->running) - return; + goto try_delete_file; g_dbus_proxy_call(data->known_network, "Forget", @@ -951,6 +1149,91 @@ connection_removed(NMSettings *settings, NMSettingsConnection *sett_conn, gpoint NULL, NULL, NULL); + return; + +try_delete_file: + if (mirror_connection(self, &id, FALSE, NULL)) + return; + + iwd_dir = get_config_path(self); + if (!iwd_dir) + return; + + filename = nm_wifi_utils_get_iwd_config_filename(id.name, ssid_len, id.security); + full_path = g_strdup_printf("%s/%s", iwd_dir, filename); + if (g_remove(full_path) == 0) + _LOGD("IWD profile at %s removed", full_path); + else if (errno != ENOENT) + _LOGD("IWD profile at %s not removed: %s (%i)", full_path, strerror(errno), errno); +} + +static void +connection_added(NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data) +{ + NMIwdManager * self = user_data; + NMConnection * conn = nm_settings_connection_get_connection(sett_conn); + NMSettingConnection *s_conn = nm_connection_get_setting_connection(conn); + const char * iwd_dir; + gs_free char * filename = NULL; + gs_free char * full_path = NULL; + gs_free_error GError *error = NULL; + nm_auto_unref_keyfile GKeyFile *iwd_config = NULL; + NMSettingsConnectionIntFlags flags; + + if (!nm_streq(nm_settings_connection_get_connection_type(sett_conn), "802-11-wireless")) + return; + + iwd_dir = get_config_path(self); + if (!iwd_dir) + return; + + /* If this is a generated connection it may be ourselves creating it and + * directly assigning it to a KnownNetwork's .mirror_connection. + */ + flags = nm_settings_connection_get_flags(sett_conn); + if (NM_FLAGS_HAS(flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) + return; + + /* If the connection has any permissions other than the default we don't + * want to save it as an IWD profile. IWD will make it available for + * everybody to attempt a connection, remove, or toggle "autoconnectable". + */ + if (s_conn && nm_setting_connection_get_num_permissions(s_conn)) { + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile because of non-default " + "permissions", + nm_settings_connection_get_id(sett_conn)); + return; + } + + iwd_config = nm_wifi_utils_connection_to_iwd_config(conn, &filename, &error); + if (!iwd_config) { + /* The error message here is not translated and it only goes in + * the logs. + */ + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + + full_path = g_strdup_printf("%s/%s", iwd_dir, filename); + if (g_file_test(full_path, G_FILE_TEST_EXISTS)) { + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile because %s already exists", + nm_settings_connection_get_id(sett_conn), + full_path); + return; + } + + if (!g_key_file_save_to_file(iwd_config, full_path, &error)) { + _LOGD("New Wi-Fi connection %s not mirrored as IWD profile: save error: %s", + nm_settings_connection_get_id(sett_conn), + error->message); + return; + } + + _LOGD("New Wi-Fi connection %s mirrored as IWD profile %s", + nm_settings_connection_get_id(sett_conn), + full_path); } static gboolean @@ -1115,7 +1398,7 @@ device_removed(NMManager *manager, NMDevice *device, gpointer user_data) static int object_compare_interfaces(gconstpointer a, gconstpointer b) { - static const char *interface_order[] = { + static const char *const interface_order[] = { NM_IWD_KNOWN_NETWORK_INTERFACE, NM_IWD_NETWORK_INTERFACE, NM_IWD_DEVICE_INTERFACE, @@ -1145,6 +1428,56 @@ object_compare_interfaces(gconstpointer a, gconstpointer b) return rank_a - rank_b; } +static void +get_daemon_info_cb(GObject *source, GAsyncResult *res, gpointer user_data) +{ + NMIwdManager * self = user_data; + NMIwdManagerPrivate *priv; + gs_unref_variant GVariant *properties = NULL; + gs_free_error GError *error = NULL; + GVariantIter * properties_iter; + const char * key; + GVariant * value; + + properties = g_dbus_proxy_call_finish(G_DBUS_PROXY(source), res, &error); + if (!properties) { + if (nm_utils_error_is_cancelled(error)) + return; + + nm_log_warn(LOGD_WIFI, "iwd: Daemon.GetInfo() failed: %s", error->message); + return; + } + + priv = NM_IWD_MANAGER_GET_PRIVATE(self); + + if (!g_variant_is_of_type(properties, G_VARIANT_TYPE("(a{sv})"))) { + _LOGE("Daemon.GetInfo returned type %s instead of (a{sv})", + g_variant_get_type_string(properties)); + return; + } + + g_variant_get(properties, "(a{sv})", &properties_iter); + + while (g_variant_iter_next(properties_iter, "{&sv}", &key, &value)) { + if (nm_streq(key, "StateDirectory")) { + if (!g_variant_is_of_type(value, G_VARIANT_TYPE_STRING)) { + _LOGE("Daemon.GetInfo property %s is typed '%s' instead of 's'", + key, + g_variant_get_type_string(value)); + goto next; + } + + nm_clear_g_free(&priv->last_state_dir); + priv->last_state_dir = g_variant_dup_string(value, NULL); + } + +next: + g_variant_unref(value); + } + + g_variant_iter_free(properties_iter); +} + static void got_object_manager(GObject *object, GAsyncResult *result, gpointer user_data) { @@ -1182,7 +1515,8 @@ got_object_manager(GObject *object, GAsyncResult *result, gpointer user_data) } if (_om_has_name_owner(object_manager)) { - GList *objects, *iter; + GList * objects, *iter; + gs_unref_object GDBusInterface *daemon = NULL; priv->running = true; @@ -1208,6 +1542,19 @@ got_object_manager(GObject *object, GAsyncResult *result, gpointer user_data) if (priv->agent_id) register_agent(self); + + daemon = g_dbus_object_manager_get_interface(object_manager, + "/net/connman/iwd", /* IWD 1.15+ */ + NM_IWD_DAEMON_INTERFACE); + if (daemon) + g_dbus_proxy_call(G_DBUS_PROXY(daemon), + "GetInfo", + g_variant_new("()"), + G_DBUS_CALL_FLAGS_NONE, + -1, + priv->cancellable, + get_daemon_info_cb, + self); } } @@ -1305,11 +1652,31 @@ nm_iwd_manager_init(NMIwdManager *self) g_signal_connect(priv->manager, NM_MANAGER_DEVICE_ADDED, G_CALLBACK(device_added), self); g_signal_connect(priv->manager, NM_MANAGER_DEVICE_REMOVED, G_CALLBACK(device_removed), self); + /* The current logic is that we track all creations and removals but + * for modifications we only listen to those connections that are + * currently a KnownNetwork's mirror_connection. There may be multiple + * NMSettingsConnections referring to the same SSID+Security type tuple + * so to the same KnownNetwork. So to make connection profile editing + * work at least for the simple cases, we track one NMSettingsConnection + * out of those, and we map its changes to the IWD KnownNetwork. + * + * When an NMSettingsConnection is created by a user for a completely + * new network and the settings are compatible with IWD, we create an + * IWD KnownNetwork config file for it. IWD will notice that and a + * KnownNetwork objects pops up on D-Bus. We look up a suitable + * mirror_connection for it and only then subscribe to modification + * signals. There are various different ways that this could be done, + * it's not clear which one's the best. + */ priv->settings = g_object_ref(NM_SETTINGS_GET); g_signal_connect(priv->settings, NM_SETTINGS_SIGNAL_CONNECTION_REMOVED, G_CALLBACK(connection_removed), self); + g_signal_connect(priv->settings, + NM_SETTINGS_SIGNAL_CONNECTION_ADDED, + G_CALLBACK(connection_added), + self); priv->cancellable = g_cancellable_new(); @@ -1348,6 +1715,9 @@ dispose(GObject *object) priv->last_agent_call_device = NULL; + nm_clear_g_free(&priv->last_state_dir); + nm_clear_g_free(&priv->warned_state_dir); + G_OBJECT_CLASS(nm_iwd_manager_parent_class)->dispose(object); } diff --git a/src/core/devices/wifi/nm-iwd-manager.h b/src/core/devices/wifi/nm-iwd-manager.h index 466f67c7..e794e661 100644 --- a/src/core/devices/wifi/nm-iwd-manager.h +++ b/src/core/devices/wifi/nm-iwd-manager.h @@ -13,6 +13,7 @@ #define NM_IWD_BUS_TYPE G_BUS_TYPE_SYSTEM #define NM_IWD_SERVICE "net.connman.iwd" +#define NM_IWD_DAEMON_INTERFACE "net.connman.iwd.Daemon" #define NM_IWD_AGENT_MANAGER_INTERFACE "net.connman.iwd.AgentManager" #define NM_IWD_WIPHY_INTERFACE "net.connman.iwd.Adapter" #define NM_IWD_DEVICE_INTERFACE "net.connman.iwd.Device" diff --git a/src/core/devices/wifi/nm-wifi-ap.c b/src/core/devices/wifi/nm-wifi-ap.c index 08fa10ec..20ed6833 100644 --- a/src/core/devices/wifi/nm-wifi-ap.c +++ b/src/core/devices/wifi/nm-wifi-ap.c @@ -13,13 +13,13 @@ #include "NetworkManagerUtils.h" #include "devices/nm-device.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-setting-wireless.h" #include "nm-utils.h" #include "nm-wifi-utils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "supplicant/nm-supplicant-interface.h" #define PROTO_WPA "wpa" @@ -41,12 +41,12 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMWifiAP, struct _NMWifiAPPrivate { /* Scanned or cached values */ - GBytes * ssid; - char * address; - NM80211Mode mode; - guint8 strength; - guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */ - guint32 max_bitrate; /* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */ + GBytes * ssid; + char * address; + _NM80211Mode mode; + guint8 strength; + guint32 freq; /* Frequency in MHz; ie 2412 (== 2.412 GHz) */ + guint32 max_bitrate; /* Maximum bitrate of the AP in Kbit/s (ie 54000 Kb/s == 54Mbit/s) */ gint64 last_seen_msec; /* Timestamp when the AP was seen lastly (in nm_utils_get_monotonic_timestamp_*() scale). @@ -98,7 +98,7 @@ nm_wifi_ap_set_ssid(NMWifiAP *ap, GBytes *ssid) } l = g_bytes_get_size(ssid); - if (l == 0 || l > 32) + if (l == 0 || l > NM_IW_ESSID_MAX_SIZE) g_return_val_if_reached(FALSE); priv = NM_WIFI_AP_GET_PRIVATE(ap); @@ -191,24 +191,24 @@ nm_wifi_ap_set_address(NMWifiAP *ap, const char *addr) return nm_wifi_ap_set_address_bin(ap, &addr_buf); } -NM80211Mode +_NM80211Mode nm_wifi_ap_get_mode(NMWifiAP *ap) { - g_return_val_if_fail(NM_IS_WIFI_AP(ap), NM_802_11_MODE_UNKNOWN); + g_return_val_if_fail(NM_IS_WIFI_AP(ap), _NM_802_11_MODE_UNKNOWN); return NM_WIFI_AP_GET_PRIVATE(ap)->mode; } static gboolean -nm_wifi_ap_set_mode(NMWifiAP *ap, NM80211Mode mode) +nm_wifi_ap_set_mode(NMWifiAP *ap, _NM80211Mode mode) { NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE(ap); nm_assert(NM_IN_SET(mode, - NM_802_11_MODE_UNKNOWN, - NM_802_11_MODE_ADHOC, - NM_802_11_MODE_INFRA, - NM_802_11_MODE_MESH)); + _NM_802_11_MODE_UNKNOWN, + _NM_802_11_MODE_ADHOC, + _NM_802_11_MODE_INFRA, + _NM_802_11_MODE_MESH)); if (priv->mode != mode) { priv->mode = mode; @@ -513,34 +513,35 @@ nm_wifi_ap_to_string(const NMWifiAP *self, char *str_buf, gulong buf_len, gint64 nm_utils_get_monotonic_timestamp_msec_cached(&now_msec); - g_snprintf(str_buf, - buf_len, - "%17s %-35s [ %c %3u %3u%% %c%c %c%c W:%04X R:%04X ] %s sup:%s [nm:%s]", - priv->address ?: "(none)", - (ssid_to_free = _nm_utils_ssid_to_string(priv->ssid)), - (priv->mode == NM_802_11_MODE_ADHOC - ? '*' - : (priv->hotspot - ? '#' - : (priv->fake ? 'f' : (priv->mode == NM_802_11_MODE_MESH ? 'm' : 'a')))), - chan, - priv->strength, - priv->flags & NM_802_11_AP_FLAGS_PRIVACY ? 'P' : '_', - priv->metered ? 'M' : '_', - priv->flags & NM_802_11_AP_FLAGS_WPS ? 'W' : '_', - priv->flags & NM_802_11_AP_FLAGS_WPS_PIN - ? 'p' - : (priv->flags & NM_802_11_AP_FLAGS_WPS_PBC ? '#' : '_'), - priv->wpa_flags & 0xFFFF, - priv->rsn_flags & 0xFFFF, - priv->last_seen_msec != G_MININT64 - ? nm_sprintf_buf(str_buf_ts, - "%3u.%03us", - (guint)((now_msec - priv->last_seen_msec) / 1000), - (guint)((now_msec - priv->last_seen_msec) % 1000)) - : " ", - supplicant_id, - export_path); + g_snprintf( + str_buf, + buf_len, + "%17s %-35s [ %c %3u %3u%% %c%c %c%c W:%04X R:%04X ] %s sup:%s [nm:%s]", + priv->address ?: "(none)", + (ssid_to_free = _nm_utils_ssid_to_string_gbytes(priv->ssid)), + (priv->mode == _NM_802_11_MODE_ADHOC + ? '*' + : (priv->hotspot + ? '#' + : (priv->fake ? 'f' : (priv->mode == _NM_802_11_MODE_MESH ? 'm' : 'a')))), + chan, + priv->strength, + priv->flags & NM_802_11_AP_FLAGS_PRIVACY ? 'P' : '_', + priv->metered ? 'M' : '_', + priv->flags & NM_802_11_AP_FLAGS_WPS ? 'W' : '_', + priv->flags & NM_802_11_AP_FLAGS_WPS_PIN + ? 'p' + : (priv->flags & NM_802_11_AP_FLAGS_WPS_PBC ? '#' : '_'), + priv->wpa_flags & 0xFFFF, + priv->rsn_flags & 0xFFFF, + priv->last_seen_msec != G_MININT64 + ? nm_sprintf_buf(str_buf_ts, + "%3u.%03us", + (guint) ((now_msec - priv->last_seen_msec) / 1000), + (guint) ((now_msec - priv->last_seen_msec) % 1000)) + : " ", + supplicant_id, + export_path); return str_buf; } @@ -589,13 +590,13 @@ nm_wifi_ap_check_compatible(NMWifiAP *self, NMConnection *connection) mode = nm_setting_wireless_get_mode(s_wireless); if (mode) { - if (!strcmp(mode, "infrastructure") && (priv->mode != NM_802_11_MODE_INFRA)) + if (!strcmp(mode, "infrastructure") && (priv->mode != _NM_802_11_MODE_INFRA)) return FALSE; - if (!strcmp(mode, "adhoc") && (priv->mode != NM_802_11_MODE_ADHOC)) + if (!strcmp(mode, "adhoc") && (priv->mode != _NM_802_11_MODE_ADHOC)) return FALSE; - if (!strcmp(mode, "ap") && (priv->mode != NM_802_11_MODE_INFRA || priv->hotspot != TRUE)) + if (!strcmp(mode, "ap") && (priv->mode != _NM_802_11_MODE_INFRA || priv->hotspot != TRUE)) return FALSE; - if (!strcmp(mode, "mesh") && (priv->mode != NM_802_11_MODE_MESH)) + if (!strcmp(mode, "mesh") && (priv->mode != _NM_802_11_MODE_MESH)) return FALSE; } @@ -624,7 +625,7 @@ nm_wifi_ap_check_compatible(NMWifiAP *self, NMConnection *connection) priv->flags, priv->wpa_flags, priv->rsn_flags, - priv->mode); + NM_802_11_MODE_CAST(priv->mode)); } gboolean @@ -713,7 +714,7 @@ nm_wifi_ap_init(NMWifiAP *self) c_list_init(&self->aps_lst); - priv->mode = NM_802_11_MODE_INFRA; + priv->mode = _NM_802_11_MODE_INFRA; priv->flags = NM_802_11_AP_FLAGS_NONE; priv->wpa_flags = NM_802_11_AP_SEC_NONE; priv->rsn_flags = NM_802_11_AP_SEC_NONE; @@ -758,19 +759,19 @@ nm_wifi_ap_new_fake_from_connection(NMConnection *connection) mode = nm_setting_wireless_get_mode(s_wireless); if (mode) { if (!strcmp(mode, "infrastructure")) - nm_wifi_ap_set_mode(ap, NM_802_11_MODE_INFRA); + nm_wifi_ap_set_mode(ap, _NM_802_11_MODE_INFRA); else if (!strcmp(mode, "adhoc")) { - nm_wifi_ap_set_mode(ap, NM_802_11_MODE_ADHOC); + nm_wifi_ap_set_mode(ap, _NM_802_11_MODE_ADHOC); adhoc = TRUE; } else if (!strcmp(mode, "mesh")) - nm_wifi_ap_set_mode(ap, NM_802_11_MODE_MESH); + nm_wifi_ap_set_mode(ap, _NM_802_11_MODE_MESH); else if (!strcmp(mode, "ap")) { - nm_wifi_ap_set_mode(ap, NM_802_11_MODE_INFRA); + nm_wifi_ap_set_mode(ap, _NM_802_11_MODE_INFRA); NM_WIFI_AP_GET_PRIVATE(ap)->hotspot = TRUE; } else goto error; } else { - nm_wifi_ap_set_mode(ap, NM_802_11_MODE_INFRA); + nm_wifi_ap_set_mode(ap, _NM_802_11_MODE_INFRA); } band = nm_setting_wireless_get_band(s_wireless); @@ -861,27 +862,21 @@ finalize(GObject *object) static const NMDBusInterfaceInfoExtended interface_info_access_point = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_ACCESS_POINT, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Flags", "u", NM_WIFI_AP_FLAGS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("WpaFlags", "u", NM_WIFI_AP_WPA_FLAGS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("RsnFlags", "u", NM_WIFI_AP_RSN_FLAGS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Ssid", "ay", NM_WIFI_AP_SSID), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Frequency", - "u", - NM_WIFI_AP_FREQUENCY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_WIFI_AP_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mode", "u", NM_WIFI_AP_MODE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("MaxBitrate", - "u", - NM_WIFI_AP_MAX_BITRATE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Strength", "y", NM_WIFI_AP_STRENGTH), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("LastSeen", - "i", - NM_WIFI_AP_LAST_SEEN), ), ), - .legacy_property_changed = TRUE, + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Flags", "u", NM_WIFI_AP_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("WpaFlags", "u", NM_WIFI_AP_WPA_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("RsnFlags", "u", NM_WIFI_AP_RSN_FLAGS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ssid", "ay", NM_WIFI_AP_SSID), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Frequency", "u", NM_WIFI_AP_FREQUENCY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_WIFI_AP_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mode", "u", NM_WIFI_AP_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("MaxBitrate", + "u", + NM_WIFI_AP_MAX_BITRATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Strength", "y", NM_WIFI_AP_STRENGTH), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("LastSeen", + "i", + NM_WIFI_AP_LAST_SEEN), ), ), }; static void @@ -955,9 +950,9 @@ nm_wifi_ap_class_init(NMWifiAPClass *ap_class) obj_properties[PROP_MODE] = g_param_spec_uint(NM_WIFI_AP_MODE, "", "", - NM_802_11_MODE_ADHOC, - NM_802_11_MODE_INFRA, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_ADHOC, + _NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_MAX_BITRATE] = g_param_spec_uint(NM_WIFI_AP_MAX_BITRATE, diff --git a/src/core/devices/wifi/nm-wifi-ap.h b/src/core/devices/wifi/nm-wifi-ap.h index bdd72415..bffd28a8 100644 --- a/src/core/devices/wifi/nm-wifi-ap.h +++ b/src/core/devices/wifi/nm-wifi-ap.h @@ -10,6 +10,7 @@ #include "nm-dbus-object.h" #include "nm-dbus-interface.h" #include "nm-connection.h" +#include "libnm-base/nm-base.h" #define NM_TYPE_WIFI_AP (nm_wifi_ap_get_type()) #define NM_WIFI_AP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_WIFI_AP, NMWifiAP)) @@ -69,7 +70,7 @@ gboolean nm_wifi_ap_set_ssid(NMWifiAP *ap, GBytes *ssid); const char * nm_wifi_ap_get_address(const NMWifiAP *ap); gboolean nm_wifi_ap_set_address(NMWifiAP *ap, const char *addr); gboolean nm_wifi_ap_set_address_bin(NMWifiAP *ap, const NMEtherAddr *addr); -NM80211Mode nm_wifi_ap_get_mode(NMWifiAP *ap); +_NM80211Mode nm_wifi_ap_get_mode(NMWifiAP *ap); gboolean nm_wifi_ap_is_hotspot(NMWifiAP *ap); gint8 nm_wifi_ap_get_strength(NMWifiAP *ap); gboolean nm_wifi_ap_set_strength(NMWifiAP *ap, gint8 strength); diff --git a/src/core/devices/wifi/nm-wifi-common.c b/src/core/devices/wifi/nm-wifi-common.c index c715c07c..b98ef222 100644 --- a/src/core/devices/wifi/nm-wifi-common.c +++ b/src/core/devices/wifi/nm-wifi-common.c @@ -146,31 +146,25 @@ const NMDBusInterfaceInfoExtended nm_interface_info_device_wireless = { .in_args = NM_DEFINE_GDBUS_ARG_INFOS( NM_DEFINE_GDBUS_ARG_INFO("options", "a{sv}"), ), ), .handle = impl_device_wifi_request_scan, ), ), - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, - &nm_signal_info_wireless_access_point_added, + .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_wireless_access_point_added, &nm_signal_info_wireless_access_point_removed, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("PermHwAddress", - "s", - NM_DEVICE_PERM_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Mode", "u", NM_DEVICE_WIFI_MODE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("Bitrate", - "u", - NM_DEVICE_WIFI_BITRATE), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("AccessPoints", - "ao", - NM_DEVICE_WIFI_ACCESS_POINTS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("ActiveAccessPoint", - "o", - NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("WirelessCapabilities", - "u", - NM_DEVICE_WIFI_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("PermHwAddress", + "s", + NM_DEVICE_PERM_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Mode", "u", NM_DEVICE_WIFI_MODE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Bitrate", "u", NM_DEVICE_WIFI_BITRATE), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("AccessPoints", + "ao", + NM_DEVICE_WIFI_ACCESS_POINTS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ActiveAccessPoint", + "o", + NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("WirelessCapabilities", + "u", + NM_DEVICE_WIFI_CAPABILITIES), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("LastScan", "x", NM_DEVICE_WIFI_LAST_SCAN), ), ), - .legacy_property_changed = TRUE, }; diff --git a/src/core/devices/wifi/nm-wifi-factory.c b/src/core/devices/wifi/nm-wifi-factory.c index 40375e1c..d2269c74 100644 --- a/src/core/devices/wifi/nm-wifi-factory.c +++ b/src/core/devices/wifi/nm-wifi-factory.c @@ -15,7 +15,7 @@ #include "nm-device-olpc-mesh.h" #include "nm-device-iwd.h" #include "settings/nm-settings-connection.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-config.h" /*****************************************************************************/ @@ -74,7 +74,8 @@ create_device(NMDeviceFactory * factory, NMConnection * connection, gboolean * out_ignore) { - gs_free char *backend = NULL; + gs_free char *backend_free = NULL; + const char * backend; g_return_val_if_fail(iface != NULL, NULL); g_return_val_if_fail(plink != NULL, NULL); @@ -89,7 +90,7 @@ create_device(NMDeviceFactory * factory, plink, "wifi", NULL); - nm_strstrip(backend); + backend = nm_strstrip_avoid_copy_a(300, backend, &backend_free); nm_log_dbg(LOGD_PLATFORM | LOGD_WIFI, "(%s) config: backend is %s%s%s%s", @@ -97,9 +98,9 @@ create_device(NMDeviceFactory * factory, NM_PRINT_FMT_QUOTE_STRING(backend), WITH_IWD ? " (iwd support enabled)" : ""); if (!backend || !g_ascii_strcasecmp(backend, "wpa_supplicant")) { - NMDevice * device; - NMDeviceWifiCapabilities capabilities; - NM80211Mode mode; + NMDevice * device; + _NMDeviceWifiCapabilities capabilities; + _NM80211Mode mode; if (!nm_platform_wifi_get_capabilities(NM_PLATFORM_GET, plink->ifindex, &capabilities)) { nm_log_warn(LOGD_PLATFORM | LOGD_WIFI, @@ -114,7 +115,7 @@ create_device(NMDeviceFactory * factory, * them if/when they change to a handled type. */ mode = nm_platform_wifi_get_mode(NM_PLATFORM_GET, plink->ifindex); - if (mode == NM_802_11_MODE_UNKNOWN) { + if (mode == _NM_802_11_MODE_UNKNOWN) { *out_ignore = TRUE; return NULL; } diff --git a/src/core/devices/wifi/nm-wifi-p2p-peer.c b/src/core/devices/wifi/nm-wifi-p2p-peer.c index 8488f32d..433c2833 100644 --- a/src/core/devices/wifi/nm-wifi-p2p-peer.c +++ b/src/core/devices/wifi/nm-wifi-p2p-peer.c @@ -12,13 +12,13 @@ #include "NetworkManagerUtils.h" #include "devices/nm-device.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" -#include "nm-glib-aux/nm-ref-string.h" +#include "libnm-glib-aux/nm-ref-string.h" #include "nm-setting-wireless.h" #include "nm-utils.h" #include "nm-wifi-utils.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "supplicant/nm-supplicant-types.h" /*****************************************************************************/ @@ -608,7 +608,6 @@ static const NMDBusInterfaceInfoExtended interface_info_p2p_peer = { NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("LastSeen", "i", NM_WIFI_P2P_PEER_LAST_SEEN), ), ), - .legacy_property_changed = FALSE, }; static void diff --git a/src/core/devices/wifi/nm-wifi-utils.c b/src/core/devices/wifi/nm-wifi-utils.c index aed236cc..15ced990 100644 --- a/src/core/devices/wifi/nm-wifi-utils.c +++ b/src/core/devices/wifi/nm-wifi-utils.c @@ -7,10 +7,14 @@ #include "nm-wifi-utils.h" +#include +#include #include #include "nm-utils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-aux-intern/nm-common-macros.h" +#include "libnm-base/nm-config-base.h" static gboolean verify_no_wep(NMSettingWirelessSecurity *s_wsec, const char *tag, GError **error) @@ -526,7 +530,7 @@ verify_adhoc(NMSettingWirelessSecurity *s_wsec, gboolean nm_wifi_utils_complete_connection(GBytes * ap_ssid, const char * bssid, - NM80211Mode ap_mode, + _NM80211Mode ap_mode, guint32 ap_freq, guint32 ap_flags, guint32 ap_wpa_flags, @@ -575,14 +579,14 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, /* Make sure the supplied mode matches the AP's */ if (!strcmp(mode, NM_SETTING_WIRELESS_MODE_INFRA) || !strcmp(mode, NM_SETTING_WIRELESS_MODE_AP)) { - if (ap_mode == NM_802_11_MODE_INFRA) + if (ap_mode == _NM_802_11_MODE_INFRA) valid = TRUE; } else if (!strcmp(mode, NM_SETTING_WIRELESS_MODE_ADHOC)) { - if (ap_mode == NM_802_11_MODE_ADHOC) + if (ap_mode == _NM_802_11_MODE_ADHOC) valid = TRUE; adhoc = TRUE; } else if (!strcmp(mode, NM_SETTING_WIRELESS_MODE_MESH)) { - if (ap_mode == NM_802_11_MODE_MESH) + if (ap_mode == _NM_802_11_MODE_MESH) valid = TRUE; mesh = TRUE; } @@ -600,10 +604,10 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, } } else { mode = NM_SETTING_WIRELESS_MODE_INFRA; - if (ap_mode == NM_802_11_MODE_ADHOC) { + if (ap_mode == _NM_802_11_MODE_ADHOC) { mode = NM_SETTING_WIRELESS_MODE_ADHOC; adhoc = TRUE; - } else if (ap_mode == NM_802_11_MODE_MESH) { + } else if (ap_mode == _NM_802_11_MODE_MESH) { mode = NM_SETTING_WIRELESS_MODE_MESH; mesh = TRUE; } @@ -810,15 +814,24 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, * setting. Since there's so much configuration required for it, there's * no way it can be automatically completed. */ - } else if ((key_mgmt && !strcmp(key_mgmt, "sae")) - || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE)) { + } else if (nm_streq0(key_mgmt, "wpa-psk") + || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE + && (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK + || ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK))) { + g_object_set(s_wsec, + NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, + "wpa-psk", + NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, + "open", + NULL); + } else if (nm_streq0(key_mgmt, "sae") || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE)) { g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL); - } else if ((key_mgmt && !strcmp(key_mgmt, "owe")) + } else if (nm_streq0(key_mgmt, "owe") || NM_FLAGS_ANY(ap_rsn_flags, NM_802_11_AP_SEC_KEY_MGMT_OWE | NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) { g_object_set(s_wsec, @@ -827,9 +840,8 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", NULL); - } else if ((key_mgmt && !strcmp(key_mgmt, "wpa-psk")) - || (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) - || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)) { + } else if (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK + || ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) { g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", @@ -839,7 +851,7 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, /* Leave proto/pairwise/group as client set them; if they are unset the * supplicant will figure out the best combination at connect time. */ - } else if ((key_mgmt && !strcmp(key_mgmt, "wpa-eap-suite-b-192")) + } else if (nm_streq0(key_mgmt, "wpa-eap-suite-b-192") || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_EAP_SUITE_B_192)) { g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, @@ -943,3 +955,865 @@ nm_wifi_connection_get_iwd_ssid_and_security(NMConnection * connection, return TRUE; } + +/*****************************************************************************/ + +/* Builds the IWD network configuration file name for a given SSID + * and security type pair. The SSID should be valid UTF-8 and in + * any case must contain no NUL-bytes. If @ssid is NUL-terminated, + * @ssid_len can be -1 instead of actual SSID length. + */ +char * +nm_wifi_utils_get_iwd_config_filename(const char * ssid, + gssize ssid_len, + NMIwdNetworkSecurity security) +{ + const char *security_suffix; + const char *ptr; + gboolean alnum_ssid = TRUE; + + for (ptr = ssid; ssid_len != 0 && *ptr != '\0'; ptr++, ssid_len--) + if (!g_ascii_isalnum(*ptr) && !strchr("-_ ", *ptr)) + alnum_ssid = FALSE; + + g_return_val_if_fail(ptr != ssid && ptr - ssid <= NM_IW_ESSID_MAX_SIZE, NULL); + + switch (security) { + case NM_IWD_NETWORK_SECURITY_OPEN: + security_suffix = "open"; + break; + case NM_IWD_NETWORK_SECURITY_PSK: + security_suffix = "psk"; + break; + case NM_IWD_NETWORK_SECURITY_8021X: + security_suffix = "8021x"; + break; + default: + return NULL; + } + + if (alnum_ssid) { + return g_strdup_printf("%.*s.%s", (int) (ptr - ssid), ssid, security_suffix); + } else { + char ssid_buf[NM_IW_ESSID_MAX_SIZE * 2 + 1]; + + return g_strdup_printf("=%s.%s", + nm_utils_bin2hexstr_full(ssid, ptr - ssid, '\0', FALSE, ssid_buf), + security_suffix); + } +} + +/*****************************************************************************/ + +#define SECRETS_DONT_STORE_FLAGS \ + (NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED) + +static gboolean +psk_setting_to_iwd_config(GKeyFile *file, NMSettingWirelessSecurity *s_wsec, GError **error) +{ + NMSettingSecretFlags psk_flags = nm_setting_wireless_security_get_psk_flags(s_wsec); + const char * psk = nm_setting_wireless_security_get_psk(s_wsec); + gsize psk_len; + guint8 buffer[32]; + const char * key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); + + if (!psk || NM_FLAGS_ANY(psk_flags, SECRETS_DONT_STORE_FLAGS)) { + if (NM_FLAGS_ANY(psk_flags, SECRETS_DONT_STORE_FLAGS)) { + nm_log_info( + LOGD_WIFI, + "IWD network config is being created wihout the PSK but IWD will save the PSK on " + "successful activation not honoring the psk-flags property"); + } + return TRUE; + } + + psk_len = strlen(psk); + if (nm_streq0(key_mgmt, "sae")) { + g_key_file_set_string(file, "Security", "Passphrase", psk); + } else if (psk_len >= 8 && psk_len <= 63) { + g_key_file_set_string(file, "Security", "Passphrase", psk); + } else if (psk_len == 64 && nm_utils_hexstr2bin_buf(psk, FALSE, FALSE, NULL, buffer)) { + g_key_file_set_string(file, "Security", "PreSharedKey", psk); + } else { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Unknown PSK format"); + return FALSE; + } + + return TRUE; +} + +static gboolean +eap_certs_to_iwd_config(GKeyFile * file, + NMSetting8021x *s_8021x, + bool phase2, + char * iwd_prefix, + GError ** error) +{ + NMSetting8021xCKScheme ca_cert_scheme = + phase2 ? nm_setting_802_1x_get_phase2_ca_cert_scheme(s_8021x) + : nm_setting_802_1x_get_ca_cert_scheme(s_8021x); + NMSetting8021xCKScheme client_cert_scheme = + phase2 ? nm_setting_802_1x_get_phase2_client_cert_scheme(s_8021x) + : nm_setting_802_1x_get_client_cert_scheme(s_8021x); + NMSetting8021xCKScheme key_scheme; + NMSettingSecretFlags key_password_flags; + const char * ca_path = phase2 ? nm_setting_802_1x_get_phase2_ca_path(s_8021x) + : nm_setting_802_1x_get_ca_path(s_8021x); + const char * cert_path; + const char * key_path = NULL; + const char * key_password; + const char * domain_suffix_match; + const char * domain_match; + char setting_buf[128]; + + /* TODO: should check that all certificates and the key are RSA */ + /* Note: up to IWD 1.9 only the PEM encoding was supported for certificates + * and only PKCS#8 PEM for keys but we don't know the IWD version here. + * From IWD 1.10 raw (DER) X.509 certificates and PKCS#12 are also supported + * for certificates but a certificate list or chain still has to be PEM + * (i.e. if it contains more than one certificate.) Raw PKCS#12 and + * old-style OpenSSL PEM formats are also supported for keys. Hopefully + * this is in practice the same set of file:// formats as supported by + * nm_crypto_* / wpa_supplicant so we need no conversions here. + */ + + if (nm_setting_802_1x_get_system_ca_certs(s_8021x)) { + /* Either overrides or is added to the certificates in (phase2-)ca-cert + * and ca-path depending on whether it points to a file or a directory. + * We can't ignore this property so it's an error if it is set. + * Fortunately not used by nm-connection-editor. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "The system-ca-certs property is not supported"); + return FALSE; + } + + if (ca_path) { + /* To support this (and this could be applied to system-ca-certs as + * well) we'd have to scan the directory, parse the certificates and + * write a new certificate-list file to point to in the IWD config. + * This is going to create issues of where to store these files, for + * how long and with what permission bits. Fortunately this doesn't + * seem to be used by nm-connection-editor either. + * + * That file would also have to contain whatever the (phase2-)ca-cert + * propterty points to because IWD has only one CACert setting per + * phase. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "The (phase2-)ca-path property is not supported"); + return FALSE; + } + + if (ca_cert_scheme != NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) { + if (ca_cert_scheme != NM_SETTING_802_1X_CK_SCHEME_PATH) { + /* To support the blob scheme we'd have to either convert the + * certificate data into a PEM payload and embed the PEM file in + * the IWD config file, which is not supported by GKeyFile, or write + * it into a new file to point to in the IWD config. This is again + * is going to create issues of where to store these files, for how + * long and with what permission bits. Fortunately this scheme isn't + * used in nm-connection-editor either. + * + * PKCS#11 is not supported by IWD in any way so we don't need to + * support the PKCS#11 URI scheme. + * + * If scheme is unknown, assume no value is set. + */ + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)ca-cert property schemes other than file:// not supported"); + return FALSE; + } + + cert_path = phase2 ? nm_setting_802_1x_get_phase2_ca_cert_path(s_8021x) + : nm_setting_802_1x_get_ca_cert_path(s_8021x); + if (cert_path) + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "CACert"), + cert_path); + } + + if (client_cert_scheme == NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) + goto private_key_done; + + if (client_cert_scheme != NM_SETTING_802_1X_CK_SCHEME_PATH) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)client-cert property schemes other than file:// not supported"); + return FALSE; + } + + cert_path = phase2 ? nm_setting_802_1x_get_phase2_client_cert_path(s_8021x) + : nm_setting_802_1x_get_client_cert_path(s_8021x); + if (!cert_path) + goto private_key_done; + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ClientCert"), + cert_path); + + key_scheme = phase2 ? nm_setting_802_1x_get_phase2_private_key_scheme(s_8021x) + : nm_setting_802_1x_get_private_key_scheme(s_8021x); + if (key_scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) + key_path = phase2 ? nm_setting_802_1x_get_phase2_private_key_path(s_8021x) + : nm_setting_802_1x_get_private_key_path(s_8021x); + if (key_scheme != NM_SETTING_802_1X_CK_SCHEME_PATH || !key_path) { + /* The same comments apply to writing the key into a temporary file + * as for the certificates (above), except this is even more + * sensitive. + */ + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)private-key property schemes other than file:// not supported"); + return FALSE; + } + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ClientKey"), + key_path); + + key_password = phase2 ? nm_setting_802_1x_get_phase2_private_key_password(s_8021x) + : nm_setting_802_1x_get_private_key_password(s_8021x); + key_password_flags = phase2 ? nm_setting_802_1x_get_phase2_private_key_password_flags(s_8021x) + : nm_setting_802_1x_get_private_key_password_flags(s_8021x); + if (!key_password || NM_FLAGS_ANY(key_password_flags, SECRETS_DONT_STORE_FLAGS)) { + g_key_file_set_comment( + file, + "Security", + setting_buf, + "ClientKeyPassphrase not to be saved, will be queried through the agent if needed", + NULL); + goto private_key_done; + } + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ClientKeyPassphrase"), + key_password); + +private_key_done: + if (phase2 ? nm_setting_802_1x_get_phase2_subject_match(s_8021x) + : nm_setting_802_1x_get_subject_match(s_8021x)) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)subject-match not supported, use domain-match or domain-suffix-match"); + return FALSE; + } + + if (phase2 ? nm_setting_802_1x_get_num_phase2_altsubject_matches(s_8021x) + : nm_setting_802_1x_get_num_altsubject_matches(s_8021x)) { + /* We could convert the "DNS:" entries into a ServerDomainMask but we'd + * have to leave out the "EMAIL:" and "URI:" types or report error. + * The interpretation still wouldn't be exactly the same as in + * wpa_supplicant. + */ + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "(phase2-)altsubject-matches not supported, use domain-match or domain-suffix-match"); + return FALSE; + } + + domain_suffix_match = phase2 ? nm_setting_802_1x_get_phase2_domain_suffix_match(s_8021x) + : nm_setting_802_1x_get_domain_suffix_match(s_8021x); + domain_match = phase2 ? nm_setting_802_1x_get_phase2_domain_match(s_8021x) + : nm_setting_802_1x_get_domain_match(s_8021x); + + if (domain_suffix_match || domain_match) { + GString * s = g_string_sized_new(128); + const char *ptr; + const char *end; + + for (ptr = domain_suffix_match; ptr; ptr = *end == ';' ? end + 1 : NULL) { + if (s->len) + g_string_append_c(s, ';'); + end = strchrnul(ptr, ';'); + /* Use *. to get the suffix match effect */ + g_string_append(s, "*."); + g_string_append_len(s, ptr, end - ptr); + } + + /* domain-match can be appended as-is */ + if (domain_match) { + if (s->len) + g_string_append_c(s, ';'); + g_string_append(s, domain_match); + } + + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "ServerDomainMask"), + s->str); + g_string_free(s, TRUE); + } + + return TRUE; +} + +static void +eap_method_name_to_iwd_config(GKeyFile *file, const char *iwd_prefix, const char *method) +{ + char setting_buf[128]; + + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Method"), + method); +} + +static void +eap_optional_identity_to_iwd_config(GKeyFile *file, const char *iwd_prefix, const char *identity) +{ + char setting_buf[128]; + + /* The identity is optional for some methods where an authenticator may + * in theory not ask for it. For our usage here we treat it as always + * optional because it can be omitted in the config file if the user + * wants IWD to query for it on every connection. + */ + if (identity) { + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Identity"), + identity); + } else { + g_key_file_set_comment( + file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Method"), + "Identity not to be saved, will be queried through the agent if needed", + NULL); + } +} + +static gboolean +eap_optional_password_to_iwd_config(GKeyFile * file, + const char * iwd_prefix, + NMSetting8021x *s_8021x, + GError ** error) +{ + char setting_buf[128]; + const char * password = nm_setting_802_1x_get_password(s_8021x); + NMSettingSecretFlags flags = nm_setting_802_1x_get_password_flags(s_8021x); + + if (!password && nm_setting_802_1x_get_password_raw(s_8021x)) { + /* IWD doesn't support passwords that can't be encoded in the config + * file, i.e. containing NUL characters. Those that don't have NULs + * could in theory be written to the config file but GKeyFile may not + * like that if they're no UTF-8, and the password-raw property is + * not written by nm-connection-editor anyway. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Non-UTF-8 passwords are not supported, if the password is UTF-8 set " + "the \"password\" property"); + return FALSE; + } + if (!password || NM_FLAGS_ANY(flags, SECRETS_DONT_STORE_FLAGS)) { + return g_key_file_set_comment(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Method"), + "Password not to be saved, will be queried through the agent", + error); + } else { + g_key_file_set_string(file, + "Security", + nm_sprintf_buf(setting_buf, "%s%s", iwd_prefix, "Password"), + password); + return TRUE; + } +} + +static void +eap_phase1_identity_to_iwd_config(GKeyFile *file, const char *iwd_prefix, NMSetting8021x *s_8021x) +{ + const char *phase1_identity = nm_setting_802_1x_get_anonymous_identity(s_8021x); + + if (!phase1_identity) { + phase1_identity = nm_setting_802_1x_get_identity(s_8021x); + + if (phase1_identity) { + nm_log_info(LOGD_WIFI, + "IWD network config will send the same EAP Identity string in " + "plaintext in phase 1 as in phase 2 (encrypted) to mimic legacy " + "behavior, set [%s].%s=anonymous to prevent exposing the value", + NM_SETTING_802_1X_SETTING_NAME, + NM_SETTING_802_1X_ANONYMOUS_IDENTITY); + } + } + + eap_optional_identity_to_iwd_config(file, iwd_prefix, phase1_identity); +} + +static gboolean +eap_method_config_to_iwd_config(GKeyFile * file, + NMSetting8021x *s_8021x, + gboolean phase2, + const char * method, + const char * iwd_prefix, + GError ** error) +{ + char prefix_buf[128]; + + if (nm_streq0(method, "tls")) { + eap_method_name_to_iwd_config(file, iwd_prefix, "TLS"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + + return eap_certs_to_iwd_config(file, + s_8021x, + phase2, + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "TLS-"), + error); + } else if (nm_streq0(method, "ttls") && !phase2) { + const char *noneap_method = nm_setting_802_1x_get_phase2_auth(s_8021x); + + eap_method_name_to_iwd_config(file, iwd_prefix, "TTLS"); + eap_phase1_identity_to_iwd_config(file, iwd_prefix, s_8021x); + + if (!eap_certs_to_iwd_config(file, + s_8021x, + phase2, + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "TTLS-"), + error)) + return FALSE; + + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "TTLS-Phase2-"); + + if (nm_setting_802_1x_get_phase2_autheap(s_8021x)) { + if (noneap_method) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Only one TTLS phase 2 method can be set"); + return FALSE; + } + return eap_method_config_to_iwd_config(file, + s_8021x, + TRUE, + nm_setting_802_1x_get_phase2_autheap(s_8021x), + prefix_buf, + error); + } + + if (NM_IN_STRSET(noneap_method, "chap", "mschap", "mschapv2", "pap")) { + const char *iwd_method; + + if (nm_streq0(noneap_method, "chap")) { + iwd_method = "Tunneled-CHAP"; + } else if (nm_streq0(noneap_method, "mschap")) { + iwd_method = "Tunneled-MSCHAP"; + } else if (nm_streq0(noneap_method, "mschapv2")) { + iwd_method = "Tunneled-MSCHAPv2"; + } else { + iwd_method = "Tunneled-PAP"; + } + + eap_method_name_to_iwd_config(file, prefix_buf, iwd_method); + eap_optional_identity_to_iwd_config(file, + prefix_buf, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, prefix_buf, s_8021x, error); + } + + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Unsupported TTLS non-EAP inner method"); + return FALSE; + } else if (nm_streq0(method, "peap") && !phase2) { + eap_method_name_to_iwd_config(file, iwd_prefix, "PEAP"); + eap_phase1_identity_to_iwd_config(file, iwd_prefix, s_8021x); + + if (!eap_certs_to_iwd_config(file, + s_8021x, + phase2, + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "PEAP-"), + error)) + return FALSE; + + if (nm_setting_802_1x_get_phase1_peapver(s_8021x) + || nm_setting_802_1x_get_phase1_peaplabel(s_8021x)) + nm_log_info(LOGD_WIFI, + "IWD network config will not honour the PEAP version and label properties " + "in the 802.1x setting (unsupported)"); + + if (!nm_setting_802_1x_get_phase2_auth(s_8021x)) { + /* Apparently PEAP can be used without a phase 2 but this is not + * supported by either NM or IWD. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "PEAP without an inner method is unsupported"); + return FALSE; + } + + return eap_method_config_to_iwd_config( + file, + s_8021x, + TRUE, + nm_setting_802_1x_get_phase2_auth(s_8021x), + nm_sprintf_buf(prefix_buf, "%s%s", iwd_prefix, "PEAP-Phase2-"), + error); + } else if (nm_streq0(method, "md5") && phase2) { + eap_method_name_to_iwd_config(file, iwd_prefix, "MD5"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "gtc") && phase2) { + eap_method_name_to_iwd_config(file, iwd_prefix, "GTC"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "pwd")) { + eap_method_name_to_iwd_config(file, iwd_prefix, "PWD"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "mschapv2")) { + eap_method_name_to_iwd_config(file, iwd_prefix, "MSCHAPV2"); + eap_optional_identity_to_iwd_config(file, + iwd_prefix, + nm_setting_802_1x_get_identity(s_8021x)); + /* In this case we can support password-raw but would have to + * MD4-hash it and set as Password-Hash + */ + return eap_optional_password_to_iwd_config(file, iwd_prefix, s_8021x, error); + } else if (nm_streq0(method, "external")) { + /* This may be a connection created by NMIwdManager in whch case there + * may be no need to be convert it back to the IWD format. Ideally we + * would still rewrite the other sections/groups in the IWD settings + * file and preserve the [Security] group -- TODO. Possibly this should + * also not be reported as an error. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection contains no EAP method configuration"); + return FALSE; + } else { + /* Some methods are only allowed in phase 1 or only phase 2. + * OTP, LEAP and FAST are not supported by IWD at all. + */ + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + phase2 ? "Unsupported phase 2 EAP method" + : "Unsupported phase 1 EAP method"); + return FALSE; + } + + return TRUE; +} + +static gboolean +eap_setting_to_iwd_config(GKeyFile *file, NMSetting8021x *s_8021x, GError **error) +{ + const char *method; + + if (!s_8021x || nm_setting_802_1x_get_num_eap_methods(s_8021x) == 0) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "The 802.1x setting is missing or no EAP method set"); + return FALSE; + } + + if (!nm_setting_verify(NM_SETTING(s_8021x), NULL, error)) + return FALSE; + + method = nm_setting_802_1x_get_eap_method(s_8021x, 0); + + if (nm_setting_802_1x_get_num_eap_methods(s_8021x) > 1) + nm_log_info(LOGD_WIFI, + "IWD network config will only contain the first EAP method: %s", + method); + + if (nm_setting_802_1x_get_phase1_auth_flags(s_8021x)) + nm_log_info(LOGD_WIFI, + "IWD network config will not honour the TLSv1.x-disable flags in the 802.1x " + "setting (unsupported)"); + + if (nm_setting_802_1x_get_auth_timeout(s_8021x)) + nm_log_info(LOGD_WIFI, + "IWD network config will not honour the auth-timeout property in the 802.1x " + "setting (unsupported)"); + + return eap_method_config_to_iwd_config(file, s_8021x, FALSE, method, "EAP-", error); +} + +static gboolean +ip4_config_to_iwd_config(GKeyFile *file, NMSettingIPConfig *s_ip, GError **error) +{ + guint num; + struct in_addr ip; + + /* These settings are not acutally used unless global + * [General].EnableNetworkConfiguration is true, which we don't support. + * We add them for sake of completness, although many NMSettingIPConfig + * configurations can't be mapped to IWD configs and we simply ignore + * them. If they were to be used we'd need to add a few warnings. + */ + + if (!s_ip) + return TRUE; + + num = nm_setting_ip_config_get_num_dns(s_ip); + if (num) { + nm_auto_free_gstring GString *s = g_string_sized_new(128); + guint i; + + for (i = 0; i < num; i++) { + if (s->len) + g_string_append_c(s, ' '); + g_string_append(s, nm_setting_ip_config_get_dns(s_ip, i)); + } + /* It doesn't matter whether we add the DNS under [IPv4] or [IPv6] + * except that with method=auto the list will override the + * DNS addresses received over the DHCP version corresponing to + * v4 or v6. + * Note ignore-auto-dns=false isn't supported, this list always + * overrides the DHCP DNSes. + */ + g_key_file_set_string(file, "IPv4", "DNS", s->str); + } + + if (!nm_streq0(nm_setting_ip_config_get_method(s_ip), NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) + return TRUE; + + num = nm_setting_ip_config_get_num_addresses(s_ip); + if (num) { + NMIPAddress *addr = nm_setting_ip_config_get_address(s_ip, 0); + guint prefix = nm_ip_address_get_prefix(addr); + in_addr_t netmask = _nm_utils_ip4_prefix_to_netmask(prefix); + char buf[INET_ADDRSTRLEN]; + + nm_ip_address_get_address_binary(addr, &ip); + g_key_file_set_string(file, "IPv4", "Address", nm_ip_address_get_address(addr)); + g_key_file_set_string(file, "IPv4", "Netmask", _nm_utils_inet4_ntop(netmask, buf)); + } else { + inet_pton(AF_INET, "10.42.0.100", &ip); + g_key_file_set_string(file, "IPv4", "Address", "10.42.0.100"); + } + + if (nm_setting_ip_config_get_gateway(s_ip)) { + g_key_file_set_string(file, "IPv4", "Gateway", nm_setting_ip_config_get_gateway(s_ip)); + } else { + uint32_t val; + char buf[INET_ADDRSTRLEN]; + + /* IWD won't enable static IP unless both Address and Gateway are + * set so generate a gateway address if not known. + */ + val = (ntohl(ip.s_addr) & 0xfffffff0) + 1; + if (val == ntohl(ip.s_addr)) + val += 1; + g_key_file_set_string(file, "IPv4", "Gateway", _nm_utils_inet4_ntop(htonl(val), buf)); + } + + return TRUE; +} + +static gboolean +ip6_config_to_iwd_config(GKeyFile *file, NMSettingIPConfig *s_ip, GError **error) +{ + guint num; + NMIPAddress *addr; + char buf[INET6_ADDRSTRLEN + 10]; + + if (!s_ip) + return TRUE; + + num = nm_setting_ip_config_get_num_dns(s_ip); + if (num) { + nm_auto_free_gstring GString *s = g_string_sized_new(128); + guint i; + + for (i = 0; i < num; i++) { + if (s->len) + g_string_append_c(s, ' '); + g_string_append(s, nm_setting_ip_config_get_dns(s_ip, i)); + } + g_key_file_set_string(file, "IPv6", "DNS", s->str); + } + + if (!NM_IN_STRSET(nm_setting_ip_config_get_method(s_ip), + NM_SETTING_IP6_CONFIG_METHOD_AUTO, + NM_SETTING_IP6_CONFIG_METHOD_DHCP, + NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) + return TRUE; + + g_key_file_set_boolean(file, "IPv6", "Enabled", TRUE); + + if (!nm_streq0(nm_setting_ip_config_get_method(s_ip), NM_SETTING_IP6_CONFIG_METHOD_MANUAL)) + return TRUE; + + if (!nm_setting_ip_config_get_num_addresses(s_ip)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "IP address required for IPv6 manual config"); + return FALSE; + } + + addr = nm_setting_ip_config_get_address(s_ip, 0); + g_key_file_set_string(file, + "IPv6", + "Address", + nm_sprintf_buf(buf, + "%s/%u", + nm_ip_address_get_address(addr), + nm_ip_address_get_prefix(addr))); + if (nm_setting_ip_config_get_gateway(s_ip)) + g_key_file_set_string(file, "IPv6", "Gateway", nm_setting_ip_config_get_gateway(s_ip)); + return TRUE; +} + +GKeyFile * +nm_wifi_utils_connection_to_iwd_config(NMConnection *connection, + char ** out_filename, + GError ** error) +{ + NMSettingConnection * s_conn = nm_connection_get_setting_connection(connection); + NMSettingWireless * s_wifi = nm_connection_get_setting_wireless(connection); + GBytes * ssid; + const guint8 * ssid_data; + gsize ssid_len; + NMIwdNetworkSecurity security; + const char * cloned_mac_addr; + gs_free char * comment = NULL; + nm_auto_unref_keyfile GKeyFile *file = NULL; + + if (!s_conn || !s_wifi + || !nm_streq(nm_setting_connection_get_connection_type(s_conn), + NM_SETTING_WIRELESS_SETTING_NAME)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection and/or wireless settings are missing"); + return NULL; + } + + if (!NM_IN_STRSET(nm_setting_wireless_get_mode(s_wifi), NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { + g_set_error_literal( + error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Non-infrastructure-mode connections don't have IWD profiles (or aren't supported)"); + return NULL; + } + + ssid = nm_setting_wireless_get_ssid(s_wifi); + ssid_data = ssid ? g_bytes_get_data(ssid, &ssid_len) : NULL; + if (!ssid_data || ssid_len <= 0 || ssid_len > NM_IW_ESSID_MAX_SIZE + || !g_utf8_validate((const char *) ssid_data, ssid_len, NULL)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Empty or non-UTF-8 SSIDs not supported by IWD"); + return NULL; + } + + if (!nm_wifi_connection_get_iwd_ssid_and_security(connection, NULL, &security)) { + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection's security type unrecognised"); + return NULL; + } + + file = g_key_file_new(); + + comment = g_strdup_printf(" Auto-generated from NetworkManager connection \"%s\"\n" + " Changes to that connection overwrite this file when " + "enabled by NM's [%s].%s value", + nm_setting_connection_get_id(s_conn), + NM_CONFIG_KEYFILE_GROUP_MAIN, + NM_CONFIG_KEYFILE_KEY_MAIN_IWD_CONFIG_PATH); + g_key_file_set_comment(file, NULL, NULL, comment, NULL); + + if (!nm_setting_connection_get_autoconnect(s_conn)) + g_key_file_set_boolean(file, "Settings", "AutoConnect", FALSE); + + if (nm_setting_wireless_get_hidden(s_wifi)) + g_key_file_set_boolean(file, "Settings", "Hidden", TRUE); + + /* Only effective if IWD's global [General].AddressRandomization is set + * to "network". "random" maps to [Settings].AlwaysRandomizeAddress=true, + * "stable" is the default, specific address maps to + * [Settings].AddressOverride set to that address. "permanent" is not + * supported and "preserve" can only be achieved using the global + * [General].AddressRandomization=disabled setting. We don't print + * warnings when we can't map the value here because we don't know what + * IWD's [General].AddressRandomization is set to. + */ + cloned_mac_addr = nm_setting_wireless_get_cloned_mac_address(s_wifi); + if (nm_streq0(cloned_mac_addr, NM_CLONED_MAC_RANDOM)) + g_key_file_set_boolean(file, "Settings", "AlwaysRandomizeAddress", TRUE); + else if (cloned_mac_addr && nm_utils_hwaddr_valid(cloned_mac_addr, ETH_ALEN)) + g_key_file_set_string(file, "Settings", "AddressOverride", cloned_mac_addr); + + if (!ip4_config_to_iwd_config( + file, + NM_SETTING_IP_CONFIG(nm_connection_get_setting_ip4_config(connection)), + error)) + return NULL; + + if (!ip6_config_to_iwd_config( + file, + NM_SETTING_IP_CONFIG(nm_connection_get_setting_ip6_config(connection)), + error)) + return NULL; + + switch (security) { + case NM_IWD_NETWORK_SECURITY_OPEN: + break; + case NM_IWD_NETWORK_SECURITY_PSK: + if (!psk_setting_to_iwd_config(file, + nm_connection_get_setting_wireless_security(connection), + error)) + return NULL; + + break; + case NM_IWD_NETWORK_SECURITY_8021X: + if (!eap_setting_to_iwd_config(file, nm_connection_get_setting_802_1x(connection), error)) + return NULL; + + break; + default: + g_set_error_literal(error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + "Connection security type is not supported"); + return NULL; + } + + if (out_filename) + *out_filename = + nm_wifi_utils_get_iwd_config_filename((const char *) ssid_data, ssid_len, security); + + return g_steal_pointer(&file); +} diff --git a/src/core/devices/wifi/nm-wifi-utils.h b/src/core/devices/wifi/nm-wifi-utils.h index 474bea41..2664c03e 100644 --- a/src/core/devices/wifi/nm-wifi-utils.h +++ b/src/core/devices/wifi/nm-wifi-utils.h @@ -11,6 +11,7 @@ #include "nm-setting-wireless.h" #include "nm-setting-wireless-security.h" #include "nm-setting-8021x.h" +#include "libnm-base/nm-base.h" typedef enum { NM_IWD_NETWORK_SECURITY_OPEN, @@ -21,7 +22,7 @@ typedef enum { gboolean nm_wifi_utils_complete_connection(GBytes * ssid, const char * bssid, - NM80211Mode mode, + _NM80211Mode mode, guint32 ap_freq, guint32 flags, guint32 wpa_flags, @@ -35,5 +36,11 @@ gboolean nm_wifi_utils_is_manf_default_ssid(GBytes *ssid); gboolean nm_wifi_connection_get_iwd_ssid_and_security(NMConnection * connection, char ** ssid, NMIwdNetworkSecurity *security); +char * nm_wifi_utils_get_iwd_config_filename(const char * ssid, + gssize ssid_len, + NMIwdNetworkSecurity security); + +GKeyFile * +nm_wifi_utils_connection_to_iwd_config(NMConnection *conn, char **out_filename, GError **error); #endif /* __NM_WIFI_UTILS_H__ */ diff --git a/src/core/devices/wifi/tests/test-devices-wifi.c b/src/core/devices/wifi/tests/test-devices-wifi.c index bc0ba126..dc278c94 100644 --- a/src/core/devices/wifi/tests/test-devices-wifi.c +++ b/src/core/devices/wifi/tests/test-devices-wifi.c @@ -7,7 +7,7 @@ #include "devices/wifi/nm-wifi-utils.h" #include "devices/wifi/nm-device-wifi.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "nm-test-utils-core.h" @@ -49,7 +49,7 @@ static gboolean complete_connection(const char * ssid, const char * bssid, - NM80211Mode mode, + _NM80211Mode mode, guint32 flags, guint32 wpa_flags, guint32 rsn_flags, @@ -197,7 +197,7 @@ fill_8021x(NMConnection *connection, const KeyData items[]) } static NMConnection * -create_basic(const char *ssid, const char *bssid, NM80211Mode mode) +create_basic(const char *ssid, const char *bssid, _NM80211Mode mode) { NMConnection * connection; NMSettingWireless *s_wifi = NULL; @@ -217,9 +217,9 @@ create_basic(const char *ssid, const char *bssid, NM80211Mode mode) if (bssid) g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); - if (mode == NM_802_11_MODE_INFRA) + if (mode == _NM_802_11_MODE_INFRA) g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_MODE, "infrastructure", NULL); - else if (mode == NM_802_11_MODE_ADHOC) + else if (mode == _NM_802_11_MODE_ADHOC) g_object_set(G_OBJECT(s_wifi), NM_SETTING_WIRELESS_MODE, "adhoc", NULL); else g_assert_not_reached(); @@ -241,14 +241,14 @@ test_lock_bssid(void) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, TRUE, src, &error); - expected = create_basic(ssid, bssid, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, bssid, _NM_802_11_MODE_INFRA); COMPARE(src, expected, success, error, 0, 0); g_object_unref(src); @@ -273,14 +273,14 @@ test_open_ap_empty_connection(void) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, FALSE, src, &error); - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); COMPARE(src, expected, success, error, 0, 0); g_object_unref(src); @@ -311,7 +311,7 @@ test_open_ap_leap_connection_1(gconstpointer add_wifi) success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -345,7 +345,7 @@ test_open_ap_leap_connection_2(void) success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -383,7 +383,7 @@ test_open_ap_wep_connection(gconstpointer add_wifi) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_NONE, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -427,7 +427,7 @@ test_ap_wpa_psk_connection_base(const char * key_mgmt, fill_wsec(src, both_wsec); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, flags, wpa_flags, rsn_flags, @@ -553,7 +553,7 @@ test_ap_wpa_eap_connection_base(const char *key_mgmt, fill_8021x(src, src_empty); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, flags, wpa_flags, rsn_flags, @@ -751,7 +751,7 @@ test_priv_ap_empty_connection(void) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -760,7 +760,7 @@ test_priv_ap_empty_connection(void) &error); /* Static WEP connection expected */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); COMPARE(src, expected, success, error, 0, 0); @@ -798,7 +798,7 @@ test_priv_ap_leap_connection_1(gconstpointer add_wifi) fill_wsec(src, src_wsec); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -809,7 +809,7 @@ test_priv_ap_leap_connection_1(gconstpointer add_wifi) * there's no way to determine from the AP's beacon whether it's static WEP, * dynamic WEP, or LEAP. */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); COMPARE(src, expected, success, error, 0, 0); @@ -840,7 +840,7 @@ test_priv_ap_leap_connection_2(void) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -885,7 +885,7 @@ test_priv_ap_dynamic_wep_1(void) fill_8021x(src, both_8021x); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -894,7 +894,7 @@ test_priv_ap_dynamic_wep_1(void) &error); /* We expect a completed Dynamic WEP connection */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); fill_8021x(expected, both_8021x); COMPARE(src, expected, success, error, 0, 0); @@ -933,7 +933,7 @@ test_priv_ap_dynamic_wep_2(void) fill_8021x(src, both_8021x); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -942,7 +942,7 @@ test_priv_ap_dynamic_wep_2(void) &error); /* We expect a completed Dynamic WEP connection */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); fill_8021x(expected, both_8021x); COMPARE(src, expected, success, error, 0, 0); @@ -976,7 +976,7 @@ test_priv_ap_dynamic_wep_3(void) fill_8021x(src, src_8021x); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, NM_802_11_AP_SEC_NONE, NM_802_11_AP_SEC_NONE, @@ -1102,7 +1102,7 @@ test_wpa_ap_empty_connection(gconstpointer data) src = nm_simple_connection_new(); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), @@ -1111,7 +1111,7 @@ test_wpa_ap_empty_connection(gconstpointer data) &error); /* WPA connection expected */ - expected = create_basic(ssid, NULL, NM_802_11_MODE_INFRA); + expected = create_basic(ssid, NULL, _NM_802_11_MODE_INFRA); fill_wsec(expected, exp_wsec); COMPARE(src, expected, success, error, 0, 0); @@ -1144,7 +1144,7 @@ test_wpa_ap_leap_connection_1(gconstpointer data) fill_wsec(src, src_wsec); success = complete_connection(ssid, bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), @@ -1180,7 +1180,7 @@ test_wpa_ap_leap_connection_2(gconstpointer data) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), @@ -1214,7 +1214,7 @@ test_wpa_ap_dynamic_wep_connection(gconstpointer data) fill_wsec(src, src_wsec); success = complete_connection("blahblah", bssid, - NM_802_11_MODE_INFRA, + _NM_802_11_MODE_INFRA, NM_802_11_AP_FLAGS_PRIVACY, wpa_flags_for_idx(idx), rsn_flags_for_idx(idx), diff --git a/src/core/devices/wwan/meson.build b/src/core/devices/wwan/meson.build index 87af0429..37ef738c 100644 --- a/src/core/devices/wwan/meson.build +++ b/src/core/devices/wwan/meson.build @@ -17,7 +17,6 @@ libnm_wwan = shared_module( libsystemd_dep, mm_glib_dep, ], - c_args: daemon_c_flags, link_args: '-Wl,--version-script,@0@'.format(linker_script), link_depends: linker_script, install: true, @@ -51,7 +50,6 @@ libnm_device_plugin_wwan = shared_module( libsystemd_dep, mm_glib_dep, ], - c_args: daemon_c_flags, link_with: libnm_wwan, link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, diff --git a/src/core/devices/wwan/nm-device-modem.c b/src/core/devices/wwan/nm-device-modem.c index 3ea89d2c..4d892e6f 100644 --- a/src/core/devices/wwan/nm-device-modem.c +++ b/src/core/devices/wwan/nm-device-modem.c @@ -14,7 +14,7 @@ #include "settings/nm-settings-connection.h" #include "nm-modem-broadband.h" #include "NetworkManagerUtils.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceModem #include "devices/nm-device-logging.h" @@ -193,15 +193,20 @@ modem_ip4_config_result(NMModem *modem, NMIP4Config *config, GError *error, gpoi NMDeviceModem *self = NM_DEVICE_MODEM(user_data); NMDevice * device = NM_DEVICE(self); - g_return_if_fail(nm_device_activate_ip4_state_in_conf(device) == TRUE); + if (!nm_device_activate_ip4_state_in_conf(device)) { + _LOGD(LOGD_MB | LOGD_IP4, + "retrieving IPv4 configuration while no longer in state IPv4 conf"); + return; + } if (error) { _LOGW(LOGD_MB | LOGD_IP4, "retrieving IPv4 configuration failed: %s", error->message); nm_device_ip_method_failed(device, AF_INET, NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE); - } else { - nm_device_set_dev2_ip_config(device, AF_INET, NM_IP_CONFIG_CAST(config)); - nm_device_activate_schedule_ip_config_result(device, AF_INET, NULL); + return; } + + nm_device_set_dev2_ip_config(device, AF_INET, NM_IP_CONFIG_CAST(config)); + nm_device_activate_schedule_ip_config_result(device, AF_INET, NULL); } static void @@ -218,7 +223,11 @@ modem_ip6_config_result(NMModem * modem, gs_unref_object NMIP6Config *ignored = NULL; gboolean got_config = !!config; - g_return_if_fail(nm_device_activate_ip6_state_in_conf(device) == TRUE); + if (!nm_device_activate_ip6_state_in_conf(device)) { + _LOGD(LOGD_MB | LOGD_IP6, + "retrieving IPv6 configuration while no longer in state IPv6 conf"); + return; + } if (error) { _LOGW(LOGD_MB | LOGD_IP6, "retrieving IPv6 configuration failed: %s", error->message); @@ -357,7 +366,6 @@ modem_state_cb(NMModem *modem, int new_state_i, int old_state_i, gpointer user_d nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_MODEM_NO_CARRIER); - return; } if (new_state > NM_MODEM_STATE_LOCKED && old_state == NM_MODEM_STATE_LOCKED) { @@ -856,14 +864,13 @@ dispose(GObject *object) static const NMDBusInterfaceInfoExtended interface_info_device_modem = { .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT( NM_DBUS_INTERFACE_DEVICE_MODEM, - .signals = NM_DEFINE_GDBUS_SIGNAL_INFOS(&nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("ModemCapabilities", - "u", - NM_DEVICE_MODEM_CAPABILITIES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L("CurrentCapabilities", - "u", - NM_DEVICE_MODEM_CURRENT_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ModemCapabilities", + "u", + NM_DEVICE_MODEM_CAPABILITIES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("CurrentCapabilities", + "u", + NM_DEVICE_MODEM_CURRENT_CAPABILITIES), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DeviceId", "s", NM_DEVICE_MODEM_DEVICE_ID), @@ -871,7 +878,6 @@ static const NMDBusInterfaceInfoExtended interface_info_device_modem = { "s", NM_DEVICE_MODEM_OPERATOR_CODE), NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Apn", "s", NM_DEVICE_MODEM_APN), ), ), - .legacy_property_changed = TRUE, }; static void diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c index 1297d964..0872a8a1 100644 --- a/src/core/devices/wwan/nm-modem-broadband.c +++ b/src/core/devices/wwan/nm-modem-broadband.c @@ -11,10 +11,10 @@ #include #include -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" diff --git a/src/core/devices/wwan/nm-modem-manager.c b/src/core/devices/wwan/nm-modem-manager.c index 598c6898..4fb9a378 100644 --- a/src/core/devices/wwan/nm-modem-manager.c +++ b/src/core/devices/wwan/nm-modem-manager.c @@ -17,7 +17,7 @@ #define sd_booted() FALSE #endif -#include "nm-std-aux/nm-dbus-compat.h" +#include "libnm-std-aux/nm-dbus-compat.h" #include "nm-modem.h" #include "nm-modem-broadband.h" diff --git a/src/core/devices/wwan/nm-modem-ofono.c b/src/core/devices/wwan/nm-modem-ofono.c index 21734cee..78ad7b68 100644 --- a/src/core/devices/wwan/nm-modem-ofono.c +++ b/src/core/devices/wwan/nm-modem-ofono.c @@ -7,10 +7,10 @@ #include "nm-modem-ofono.h" -#include "nm-core-internal.h" +#include "libnm-core-intern/nm-core-internal.h" #include "devices/nm-device-private.h" #include "nm-modem.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" #include "nm-ip4-config.h" #define VARIANT_IS_OF_TYPE_BOOLEAN(v) \ @@ -316,10 +316,9 @@ handle_sim_property(GDBusProxy *proxy, const char *property, GVariant *v, gpoint static void sim_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - GVariant *v_child = g_variant_get_child_value(v, 0); + gs_unref_variant GVariant *v_child = g_variant_get_child_value(v, 0); handle_sim_property(proxy, property, v_child, user_data); - g_variant_unref(v_child); } static void @@ -330,7 +329,7 @@ sim_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_dat gs_free_error GError *error = NULL; gs_unref_variant GVariant *v_properties = NULL; gs_unref_variant GVariant *v_dict = NULL; - GVariant * v; + gs_unref_variant GVariant *v = NULL; GVariantIter i; const char * property; @@ -370,9 +369,8 @@ sim_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_dat */ g_variant_iter_init(&i, v_dict); - while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) { handle_sim_property(NULL, property, v, self); - g_variant_unref(v); } } @@ -477,10 +475,9 @@ handle_connman_property(GDBusProxy *proxy, const char *property, GVariant *v, gp static void connman_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) { - GVariant *v_child = g_variant_get_child_value(v, 0); + gs_unref_variant GVariant *v_child = g_variant_get_child_value(v, 0); handle_connman_property(proxy, property, v_child, user_data); - g_variant_unref(v_child); } static void @@ -491,7 +488,7 @@ connman_get_properties_done(GObject *source, GAsyncResult *result, gpointer user gs_free_error GError *error = NULL; gs_unref_variant GVariant *v_properties = NULL; gs_unref_variant GVariant *v_dict = NULL; - GVariant * v; + gs_unref_variant GVariant *v = NULL; GVariantIter i; const char * property; @@ -523,9 +520,8 @@ connman_get_properties_done(GObject *source, GAsyncResult *result, gpointer user */ g_variant_iter_init(&i, v_dict); - while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) { handle_connman_property(NULL, property, v, self); - g_variant_unref(v); } } @@ -700,9 +696,8 @@ modem_get_properties_done(GObject *source, GAsyncResult *result, gpointer user_d */ g_variant_iter_init(&i, v_dict); - while (g_variant_iter_next(&i, "{&sv}", &property, &v)) { + while (g_variant_iter_loop(&i, "{&sv}", &property, &v)) { handle_modem_property(NULL, property, v, self); - g_variant_unref(v); } } @@ -726,35 +721,30 @@ stage1_prepare_done(GObject *source, GAsyncResult *result, gpointer user_data) nm_clear_pointer(&priv->connect_properties, g_hash_table_destroy); if (error) { - _LOGW("connection failed: %s", error->message); - - nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY); - /* - * FIXME: add code to check for InProgress so that the - * connection doesn't continue to try and activate, - * leading to the connection being disabled, and a 5m - * timeout... - */ + if (!g_strstr_len(error->message, + NM_STRLEN(OFONO_ERROR_IN_PROGRESS), + OFONO_ERROR_IN_PROGRESS)) { + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY); + } } } static void -context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) +handle_settings(GVariant *v_dict, gpointer user_data) { NMModemOfono * self = NM_MODEM_OFONO(user_data); NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE(self); NMPlatformIP4Address addr; - gboolean ret = FALSE; - gs_unref_variant GVariant *v_dict = NULL; - const char * interface; - const char * s; - const char ** array, **iter; - guint32 address_network, gateway_network; - guint32 ip4_route_table, ip4_route_metric; - int ifindex; - GError * error = NULL; + gboolean ret = FALSE; + const char * interface; + const char * s; + const char ** array, **iter; + guint32 address_network, gateway_network; + guint32 ip4_route_table, ip4_route_metric; + int ifindex; + GError * error = NULL; - _LOGD("PropertyChanged: %s", property); + //_LOGD("PropertyChanged: %s", property); /* * TODO: might be a good idea and re-factor this to mimic bluez-device, @@ -762,15 +752,6 @@ context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, g * handle the action. */ - if (g_strcmp0(property, "Settings") != 0) - return; - - v_dict = g_variant_get_child_value(v, 0); - if (!v_dict) { - _LOGW("error getting IPv4 Settings: no v_dict"); - goto out; - } - _LOGI("IPv4 static Settings:"); if (!g_variant_lookup(v_dict, "Interface", "&s", &interface)) { @@ -909,6 +890,28 @@ out: } } +static void +context_property_changed(GDBusProxy *proxy, const char *property, GVariant *v, gpointer user_data) +{ + NMModemOfono * self = NM_MODEM_OFONO(user_data); + gs_unref_variant GVariant *v_dict = NULL; + + _LOGD("PropertyChanged: %s", property); + + if (g_strcmp0(property, "Settings") != 0) + return; + + v_dict = g_variant_get_child_value(v, 0); + if (!v_dict) { + _LOGW("ofono: (%s): error getting IPv4 Settings", nm_modem_get_uid(NM_MODEM(self))); + return; + } + + g_assert(g_variant_is_of_type(v_dict, G_VARIANT_TYPE_VARDICT)); + + handle_settings(v_dict, user_data); +} + static NMActStageReturn static_stage3_ip4_config_start(NMModem * modem, NMActRequest * req, @@ -935,6 +938,72 @@ static_stage3_ip4_config_start(NMModem * modem, return NM_ACT_STAGE_RETURN_POSTPONE; } +static void +context_properties_cb(GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) +{ + NMModemOfono * self; + NMModemOfonoPrivate *priv; + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *properties = NULL; + gs_unref_variant GVariant *settings = NULL; + gs_unref_variant GVariant *v_dict = NULL; + gboolean active; + + self = NM_MODEM_OFONO(user_data); + priv = NM_MODEM_OFONO_GET_PRIVATE(self); + + properties = g_dbus_proxy_call_finish(proxy, result, &error); + + if (!properties) { + _LOGW("ofono: connection failed: no context properties returned %s", error->message); + g_clear_error(&error); + goto error; + } + + v_dict = g_variant_get_child_value(properties, 0); + if (!v_dict || !g_variant_is_of_type(v_dict, G_VARIANT_TYPE_VARDICT)) { + _LOGW("ofono: connection failed; could not read connection properties"); + goto error; + } + + if (!g_variant_lookup(v_dict, "Active", "b", &active)) { + _LOGW("ofono: connection failed; can not read 'Active' property"); + goto error; + } + + /* Watch for custom ofono PropertyChanged signals */ + _nm_dbus_signal_connect(priv->context_proxy, + "PropertyChanged", + G_VARIANT_TYPE("(sv)"), + G_CALLBACK(context_property_changed), + self); + + if (active) { + _LOGD("ofono: connection is already Active"); + + settings = g_variant_lookup_value(v_dict, "Settings", G_VARIANT_TYPE_VARDICT); + if (settings == NULL) { + _LOGW("ofono: connection failed; can not read 'Settings' property"); + goto error; + } + + handle_settings(settings, user_data); + } else { + g_dbus_proxy_call(priv->context_proxy, + "SetProperty", + g_variant_new("(sv)", "Active", g_variant_new("b", TRUE)), + G_DBUS_CALL_FLAGS_NONE, + 20000, + NULL, + (GAsyncReadyCallback) stage1_prepare_done, + self); + } + return; + +error: + nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_BUSY); +} + static void context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data) { @@ -973,19 +1042,15 @@ context_proxy_new_cb(GObject *source, GAsyncResult *result, gpointer user_data) */ g_clear_object(&priv->ip4_config); - _nm_dbus_signal_connect(priv->context_proxy, - "PropertyChanged", - G_VARIANT_TYPE("(sv)"), - G_CALLBACK(context_property_changed), - self); - + /* We need to directly query ConnectionContextinteface to get the current + * property values */ g_dbus_proxy_call(priv->context_proxy, - "SetProperty", - g_variant_new("(sv)", "Active", g_variant_new("b", TRUE)), + "GetProperties", + NULL, G_DBUS_CALL_FLAGS_NONE, 20000, - priv->context_proxy_cancellable, - stage1_prepare_done, + NULL, + (GAsyncReadyCallback) context_properties_cb, self); } @@ -1069,6 +1134,7 @@ modem_act_stage1_prepare(NMModem * modem, _LOGI("activating context %s", priv->context_path); + update_modem_state(self); if (nm_modem_get_state(modem) == NM_MODEM_STATE_REGISTERED) { do_context_activate(self); } else { diff --git a/src/core/devices/wwan/nm-modem-ofono.h b/src/core/devices/wwan/nm-modem-ofono.h index 260e3954..ebe21023 100644 --- a/src/core/devices/wwan/nm-modem-ofono.h +++ b/src/core/devices/wwan/nm-modem-ofono.h @@ -25,6 +25,8 @@ #define OFONO_DBUS_INTERFACE_CONNECTION_CONTEXT "org.ofono.ConnectionContext" #define OFONO_DBUS_INTERFACE_SIM_MANAGER "org.ofono.SimManager" +#define OFONO_ERROR_IN_PROGRESS "org.ofono.Error.InProgress" + typedef struct _NMModemOfono NMModemOfono; typedef struct _NMModemOfonoClass NMModemOfonoClass; diff --git a/src/core/devices/wwan/nm-modem.c b/src/core/devices/wwan/nm-modem.c index 0d334fa4..15baa677 100644 --- a/src/core/devices/wwan/nm-modem.c +++ b/src/core/devices/wwan/nm-modem.c @@ -10,10 +10,11 @@ #include #include +#include #include -#include "nm-core-internal.h" -#include "platform/nm-platform.h" +#include "libnm-core-intern/nm-core-internal.h" +#include "libnm-platform/nm-platform.h" #include "nm-setting-connection.h" #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" @@ -799,8 +800,10 @@ nm_modem_ip4_pre_commit(NMModem *modem, NMDevice *device, NMIP4Config *config) g_assert(address); if (address->plen == 32) - nm_platform_link_set_noarp(nm_device_get_platform(device), - nm_device_get_ip_ifindex(device)); + nm_platform_link_change_flags(nm_device_get_platform(device), + nm_device_get_ip_ifindex(device), + IFF_NOARP, + TRUE); } } @@ -1199,7 +1202,7 @@ deactivate_cleanup(NMModem *self, NMDevice *device, gboolean stop_ppp_manager) nm_platform_ip_route_flush(platform, AF_UNSPEC, ifindex); nm_platform_ip_address_flush(platform, AF_UNSPEC, ifindex); - nm_platform_link_set_down(platform, ifindex); + nm_platform_link_change_flags(platform, ifindex, IFF_UP, FALSE); } } } diff --git a/src/core/devices/wwan/nm-wwan-factory.c b/src/core/devices/wwan/nm-wwan-factory.c index 5d2ce2b3..0d802ae1 100644 --- a/src/core/devices/wwan/nm-wwan-factory.c +++ b/src/core/devices/wwan/nm-wwan-factory.c @@ -12,7 +12,7 @@ #include "nm-setting-cdma.h" #include "nm-modem-manager.h" #include "nm-device-modem.h" -#include "platform/nm-platform.h" +#include "libnm-platform/nm-platform.h" /*****************************************************************************/ -- cgit 1.3.0-6-gf8a5 From 88c227d90a6b7b388c5c85d72802a0ca8f05ed5c Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Thu, 13 Jan 2022 22:30:39 +0100 Subject: New upstream version 1.34.0 --- src/core/devices/adsl/nm-device-adsl.c | 2 +- src/core/devices/bluetooth/nm-bluez-manager.c | 163 +++-- src/core/devices/bluetooth/nm-bluez5-dun.c | 44 +- src/core/devices/bluetooth/nm-device-bt.c | 31 +- src/core/devices/bluetooth/tests/nm-bt-test.c | 2 - src/core/devices/nm-acd-manager.c | 8 +- src/core/devices/nm-device-6lowpan.c | 8 +- src/core/devices/nm-device-bond.c | 99 ++- src/core/devices/nm-device-bridge.c | 22 +- src/core/devices/nm-device-dummy.c | 36 +- src/core/devices/nm-device-ethernet.c | 36 +- src/core/devices/nm-device-infiniband.c | 21 +- src/core/devices/nm-device-ip-tunnel.c | 13 +- src/core/devices/nm-device-logging.h | 12 +- src/core/devices/nm-device-macvlan.c | 13 +- src/core/devices/nm-device-ppp.c | 57 +- src/core/devices/nm-device-private.h | 2 +- src/core/devices/nm-device-tun.c | 7 +- src/core/devices/nm-device-utils.c | 27 +- src/core/devices/nm-device-utils.h | 16 +- src/core/devices/nm-device-vlan.c | 8 +- src/core/devices/nm-device-vrf.c | 8 +- src/core/devices/nm-device-vxlan.c | 12 +- src/core/devices/nm-device-wireguard.c | 11 +- src/core/devices/nm-device-wpan.c | 9 +- src/core/devices/nm-device.c | 776 +++++++++++++----------- src/core/devices/nm-device.h | 1 + src/core/devices/nm-lldp-listener.c | 42 +- src/core/devices/ovs/nm-ovsdb.c | 141 +++-- src/core/devices/team/nm-device-team.c | 22 +- src/core/devices/wifi/nm-device-iwd.c | 11 +- src/core/devices/wifi/nm-device-olpc-mesh.c | 7 +- src/core/devices/wifi/nm-device-wifi-p2p.c | 44 +- src/core/devices/wifi/nm-device-wifi.c | 23 +- src/core/devices/wifi/nm-wifi-ap.c | 2 +- src/core/devices/wifi/nm-wifi-common.c | 2 +- src/core/devices/wifi/nm-wifi-p2p-peer.c | 18 +- src/core/devices/wifi/nm-wifi-utils.c | 27 +- src/core/devices/wifi/tests/test-devices-wifi.c | 2 +- src/core/devices/wwan/nm-device-modem.c | 22 +- src/core/devices/wwan/nm-modem-broadband.c | 7 +- src/core/devices/wwan/nm-modem-manager.c | 6 +- src/core/devices/wwan/nm-modem.c | 49 +- src/core/devices/wwan/nm-modem.h | 2 +- 44 files changed, 934 insertions(+), 937 deletions(-) (limited to 'src/core/devices') diff --git a/src/core/devices/adsl/nm-device-adsl.c b/src/core/devices/adsl/nm-device-adsl.c index 4e4c9dcc..adcf8785 100644 --- a/src/core/devices/adsl/nm-device-adsl.c +++ b/src/core/devices/adsl/nm-device-adsl.c @@ -356,7 +356,7 @@ br2684_create_iface(NMDeviceAdsl *self) return FALSE; } - nm_utils_strdup_reset(&priv->nas_ifname, ni.ifname); + nm_strdup_reset(&priv->nas_ifname, ni.ifname); _LOGD(LOGD_ADSL, "waiting for br2684 iface '%s' to appear", priv->nas_ifname); priv->nas_update_count = 0; priv->nas_update_id = g_timeout_add(100, nas_update_cb, self); diff --git a/src/core/devices/bluetooth/nm-bluez-manager.c b/src/core/devices/bluetooth/nm-bluez-manager.c index fc081580..36e442ad 100644 --- a/src/core/devices/bluetooth/nm-bluez-manager.c +++ b/src/core/devices/bluetooth/nm-bluez-manager.c @@ -31,9 +31,9 @@ /*****************************************************************************/ #if WITH_BLUEZ5_DUN - #define _NM_BT_CAPABILITY_SUPPORTED_DUN NM_BT_CAPABILITY_DUN +#define _NM_BT_CAPABILITY_SUPPORTED_DUN NM_BT_CAPABILITY_DUN #else - #define _NM_BT_CAPABILITY_SUPPORTED_DUN NM_BT_CAPABILITY_NONE +#define _NM_BT_CAPABILITY_SUPPORTED_DUN NM_BT_CAPABILITY_NONE #endif #define _NM_BT_CAPABILITY_SUPPORTED (NM_BT_CAPABILITY_NAP | _NM_BT_CAPABILITY_SUPPORTED_DUN) @@ -382,64 +382,56 @@ _bzobj_to_string(const BzDBusObj *bzobj, char *buf, gsize len) buf[0] = '\0'; if (bzobj->d_has_adapter_iface) { - nm_utils_strbuf_append_str(&buf, &len, prefix); + nm_strbuf_append_str(&buf, &len, prefix); prefix = ", "; - nm_utils_strbuf_append_str(&buf, &len, "Adapter1 {"); + nm_strbuf_append_str(&buf, &len, "Adapter1 {"); if (bzobj->d_adapter.address) { - nm_utils_strbuf_append(&buf, &len, " d.address: \"%s\"", bzobj->d_adapter.address); + nm_strbuf_append(&buf, &len, " d.address: \"%s\"", bzobj->d_adapter.address); if (bzobj->d_adapter_powered) - nm_utils_strbuf_append_str(&buf, &len, ","); + nm_strbuf_append_str(&buf, &len, ","); } if (bzobj->d_adapter_powered) - nm_utils_strbuf_append(&buf, &len, " d.powered: 1"); - nm_utils_strbuf_append_str(&buf, &len, " }"); + nm_strbuf_append(&buf, &len, " d.powered: 1"); + nm_strbuf_append_str(&buf, &len, " }"); } if (bzobj->d_has_device_iface) { const char *prefix1 = ""; - nm_utils_strbuf_append_str(&buf, &len, prefix); + nm_strbuf_append_str(&buf, &len, prefix); prefix = ", "; - nm_utils_strbuf_append_str(&buf, &len, "Device1 {"); + nm_strbuf_append_str(&buf, &len, "Device1 {"); if (bzobj->d_device.address) { - nm_utils_strbuf_append(&buf, - &len, - "%s d.address: \"%s\"", - prefix1, - bzobj->d_device.address); + nm_strbuf_append(&buf, &len, "%s d.address: \"%s\"", prefix1, bzobj->d_device.address); prefix1 = ","; } if (bzobj->d_device.name) { - nm_utils_strbuf_append(&buf, &len, "%s d.name: \"%s\"", prefix1, bzobj->d_device.name); + nm_strbuf_append(&buf, &len, "%s d.name: \"%s\"", prefix1, bzobj->d_device.name); prefix1 = ","; } if (bzobj->d_device.adapter) { - nm_utils_strbuf_append(&buf, - &len, - "%s d.adapter: \"%s\"", - prefix1, - bzobj->d_device.adapter); + nm_strbuf_append(&buf, &len, "%s d.adapter: \"%s\"", prefix1, bzobj->d_device.adapter); prefix1 = ","; } if (bzobj->d_device_capabilities != NM_BT_CAPABILITY_NONE) { - nm_utils_strbuf_append(&buf, - &len, - "%s d.capabilities: \"%s\"", - prefix1, - nm_bluetooth_capability_to_string(bzobj->d_device_capabilities, - sbuf_cap, - sizeof(sbuf_cap))); + nm_strbuf_append(&buf, + &len, + "%s d.capabilities: \"%s\"", + prefix1, + nm_bluetooth_capability_to_string(bzobj->d_device_capabilities, + sbuf_cap, + sizeof(sbuf_cap))); prefix1 = ","; } if (bzobj->d_device_connected) { - nm_utils_strbuf_append(&buf, &len, "%s d.connected: 1", prefix1); + nm_strbuf_append(&buf, &len, "%s d.connected: 1", prefix1); prefix1 = ","; } if (bzobj->d_device_paired) { - nm_utils_strbuf_append(&buf, &len, "%s d.paired: 1", prefix1); + nm_strbuf_append(&buf, &len, "%s d.paired: 1", prefix1); prefix1 = ","; } - nm_utils_strbuf_append_str(&buf, &len, " }"); + nm_strbuf_append_str(&buf, &len, " }"); } network_server_is_usable = _bzobjs_network_server_is_usable(bzobj, TRUE); @@ -450,43 +442,43 @@ _bzobj_to_string(const BzDBusObj *bzobj, char *buf, gsize len) || !nm_streq0(bzobj->d_has_adapter_iface ? bzobj->d_adapter.address : NULL, bzobj->x_network_server.adapter_address) || bzobj->x_network_server.device_br || bzobj->x_network_server.r_req_data) { - nm_utils_strbuf_append_str(&buf, &len, prefix); + nm_strbuf_append_str(&buf, &len, prefix); prefix = ", "; - nm_utils_strbuf_append(&buf, &len, "NetworkServer1 { "); + nm_strbuf_append(&buf, &len, "NetworkServer1 { "); if (!bzobj->d_has_network_server_iface) - nm_utils_strbuf_append(&buf, &len, " has-d-iface: 0, "); + nm_strbuf_append(&buf, &len, " has-d-iface: 0, "); if (network_server_is_usable != (!c_list_is_empty(&bzobj->x_network_server.lst))) - nm_utils_strbuf_append(&buf, - &len, - "usable: %d, used: %d", - !!network_server_is_usable, - !network_server_is_usable); + nm_strbuf_append(&buf, + &len, + "usable: %d, used: %d", + !!network_server_is_usable, + !network_server_is_usable); else if (network_server_is_usable) - nm_utils_strbuf_append(&buf, &len, "used: 1"); + nm_strbuf_append(&buf, &len, "used: 1"); else - nm_utils_strbuf_append(&buf, &len, "usable: 0"); + nm_strbuf_append(&buf, &len, "usable: 0"); if (!nm_streq0(bzobj->d_has_adapter_iface ? bzobj->d_adapter.address : NULL, bzobj->x_network_server.adapter_address)) { if (bzobj->x_network_server.adapter_address) - nm_utils_strbuf_append(&buf, - &len, - ", adapter-address: \"%s\"", - bzobj->x_network_server.adapter_address); + nm_strbuf_append(&buf, + &len, + ", adapter-address: \"%s\"", + bzobj->x_network_server.adapter_address); else - nm_utils_strbuf_append(&buf, &len, ", adapter-address: "); + nm_strbuf_append(&buf, &len, ", adapter-address: "); } if (bzobj->x_network_server.device_br) - nm_utils_strbuf_append(&buf, &len, ", bridge-device: 1"); + nm_strbuf_append(&buf, &len, ", bridge-device: 1"); if (bzobj->x_network_server.r_req_data) - nm_utils_strbuf_append(&buf, &len, ", register-in-progress: 1"); + nm_strbuf_append(&buf, &len, ", register-in-progress: 1"); - nm_utils_strbuf_append_str(&buf, &len, " }"); + nm_strbuf_append_str(&buf, &len, " }"); } device_is_usable = _bzobjs_device_is_usable(bzobj, NULL, &create_panu_connection); @@ -497,76 +489,72 @@ _bzobj_to_string(const BzDBusObj *bzobj, char *buf, gsize len) || bzobj->x_device_connect_bt_type != NM_BT_CAPABILITY_NONE || bzobj->x_device.connect_dun_context || bzobj->x_device.c_req_data || bzobj->x_device_is_connected != bzobj->d_network_connected) { - nm_utils_strbuf_append_str(&buf, &len, prefix); + nm_strbuf_append_str(&buf, &len, prefix); prefix = ", "; - nm_utils_strbuf_append_str(&buf, &len, "Network1 {"); + nm_strbuf_append_str(&buf, &len, "Network1 {"); if (bzobj->d_network.interface) - nm_utils_strbuf_append(&buf, - &len, - " d.interface: \"%s\", ", - bzobj->d_network.interface); + nm_strbuf_append(&buf, &len, " d.interface: \"%s\", ", bzobj->d_network.interface); if (bzobj->d_network_connected) - nm_utils_strbuf_append(&buf, &len, " d.connected: %d, ", !!bzobj->d_network_connected); + nm_strbuf_append(&buf, &len, " d.connected: %d, ", !!bzobj->d_network_connected); if (!bzobj->d_has_network_iface) - nm_utils_strbuf_append(&buf, &len, " has-d-iface: 0, "); + nm_strbuf_append(&buf, &len, " has-d-iface: 0, "); if (device_is_usable != bzobj->x_device_is_usable) - nm_utils_strbuf_append(&buf, - &len, - " usable: %d, used: %d", - !!device_is_usable, - !device_is_usable); + nm_strbuf_append(&buf, + &len, + " usable: %d, used: %d", + !!device_is_usable, + !device_is_usable); else if (device_is_usable) - nm_utils_strbuf_append(&buf, &len, " used: 1"); + nm_strbuf_append(&buf, &len, " used: 1"); else - nm_utils_strbuf_append(&buf, &len, " usable: 0"); + nm_strbuf_append(&buf, &len, " usable: 0"); if (create_panu_connection) - nm_utils_strbuf_append(&buf, &len, ", create-panu-connection: 1"); + nm_strbuf_append(&buf, &len, ", create-panu-connection: 1"); if (bzobj->x_device.panu_connection) - nm_utils_strbuf_append(&buf, &len, ", has-panu-connection: 1"); + nm_strbuf_append(&buf, &len, ", has-panu-connection: 1"); if (bzobj->x_device.device_bt) - nm_utils_strbuf_append(&buf, &len, ", has-device: 1"); + nm_strbuf_append(&buf, &len, ", has-device: 1"); if (bzobj->x_device_connect_bt_type != NM_BT_CAPABILITY_NONE || bzobj->x_device.connect_dun_context) { - nm_utils_strbuf_append( - &buf, - &len, - ", connect: %s%s", - nm_bluetooth_capability_to_string(bzobj->x_device_connect_bt_type, - sbuf_cap, - sizeof(sbuf_cap)), - bzobj->x_device.connect_dun_context ? ",with-dun-context" : ""); + nm_strbuf_append(&buf, + &len, + ", connect: %s%s", + nm_bluetooth_capability_to_string(bzobj->x_device_connect_bt_type, + sbuf_cap, + sizeof(sbuf_cap)), + bzobj->x_device.connect_dun_context ? ",with-dun-context" : ""); } if (bzobj->x_device.c_req_data) - nm_utils_strbuf_append(&buf, &len, ", connecting: 1"); + nm_strbuf_append(&buf, &len, ", connecting: 1"); if (bzobj->x_device_is_connected != bzobj->d_network_connected) - nm_utils_strbuf_append(&buf, &len, ", connected: %d", !!bzobj->x_device_is_connected); + nm_strbuf_append(&buf, &len, ", connected: %d", !!bzobj->x_device_is_connected); - nm_utils_strbuf_append_str(&buf, &len, " }"); + nm_strbuf_append_str(&buf, &len, " }"); } if (_bzobjs_is_dead(bzobj)) { - nm_utils_strbuf_append_str(&buf, &len, prefix); + nm_strbuf_append_str(&buf, &len, prefix); prefix = ", "; - nm_utils_strbuf_append_str(&buf, &len, "dead: 1"); + nm_strbuf_append_str(&buf, &len, "dead: 1"); } if (!c_list_is_empty(&bzobj->process_change_lst)) { - nm_utils_strbuf_append_str(&buf, &len, prefix); + nm_strbuf_append_str(&buf, &len, prefix); prefix = ", "; - nm_utils_strbuf_append(&buf, &len, "change-pending-on-idle: 1"); + nm_strbuf_append(&buf, &len, "change-pending-on-idle: 1"); } if (_bzobjs_adapter_is_usable_for_device(bzobj) != bzobj->was_usable_adapter_for_device_before) { - nm_utils_strbuf_append_str(&buf, &len, prefix); + nm_strbuf_append_str(&buf, &len, prefix); prefix = ", "; - nm_utils_strbuf_append(&buf, &len, "change-usable-adapter-for-device: 1"); + nm_strbuf_append(&buf, &len, "change-usable-adapter-for-device: 1"); } return buf0; @@ -2864,9 +2852,7 @@ dispose(GObject *object) * BzDBusObj instances and do necessary cleanup actions (like disconnecting devices * or deleting panu_connection). */ - nm_assert(c_list_is_empty(&priv->network_server_lst_head)); - nm_assert(c_list_is_empty(&priv->process_change_lst_head)); - nm_assert(priv->process_change_idle_id == 0); + nm_clear_g_source(&priv->process_change_idle_id); g_atomic_pointer_compare_and_exchange(&nm_bt_vtable_network_server, &priv->vtable_network_server, @@ -2883,6 +2869,9 @@ dispose(GObject *object) nm_clear_pointer(&priv->bzobjs, g_hash_table_destroy); nm_clear_pointer(&priv->conn_data_heads, g_hash_table_destroy); nm_clear_pointer(&priv->conn_data_elems, g_hash_table_destroy); + + nm_assert(c_list_is_empty(&priv->network_server_lst_head)); + nm_assert(c_list_is_empty(&priv->process_change_lst_head)); } static void diff --git a/src/core/devices/bluetooth/nm-bluez5-dun.c b/src/core/devices/bluetooth/nm-bluez5-dun.c index e29884d8..7efbfaf4 100644 --- a/src/core/devices/bluetooth/nm-bluez5-dun.c +++ b/src/core/devices/bluetooth/nm-bluez5-dun.c @@ -182,25 +182,18 @@ _connect_open_tty(NMBluez5DunContext *context) nm_strerror_native(errsv), errsv); context->cdat->connect_open_tty_started_at = nm_utils_get_monotonic_timestamp_nsec(); - context->cdat->source = nm_g_timeout_source_new(100, - G_PRIORITY_DEFAULT, - _connect_open_tty_retry_cb, - context, - NULL); - g_source_attach(context->cdat->source, NULL); + context->cdat->source = + nm_g_timeout_add_source(100, _connect_open_tty_retry_cb, context); } return -errsv; } context->rfcomm_tty_fd = fd; - context->rfcomm_tty_poll_source = nm_g_unix_fd_source_new(context->rfcomm_tty_fd, + context->rfcomm_tty_poll_source = nm_g_unix_fd_add_source(context->rfcomm_tty_fd, G_IO_ERR | G_IO_HUP, - G_PRIORITY_DEFAULT, _rfcomm_tty_poll_cb, - context, - NULL); - g_source_attach(context->rfcomm_tty_poll_source, NULL); + context); _context_invoke_callback_success(context); return 0; @@ -369,13 +362,10 @@ _connect_socket_connect(NMBluez5DunContext *context) context->dst_str, context->rfcomm_channel); - context->cdat->source = nm_g_unix_fd_source_new(context->rfcomm_sock_fd, + context->cdat->source = nm_g_unix_fd_add_source(context->rfcomm_sock_fd, G_IO_OUT, - G_PRIORITY_DEFAULT, _connect_socket_connect_cb, - context, - NULL); - g_source_attach(context->cdat->source, NULL); + context); return; } @@ -567,12 +557,8 @@ _connect_sdp_io_cb(int fd, GIOCondition condition, gpointer user_data) nm_strerror_native(errsv), errsv); nm_clear_g_source_inst(&context->cdat->source); - context->cdat->source = nm_g_timeout_source_new(1000, - G_PRIORITY_DEFAULT, - _connect_sdp_session_start_on_idle_cb, - context, - NULL); - g_source_attach(context->cdat->source, NULL); + context->cdat->source = + nm_g_timeout_add_source(1000, _connect_sdp_session_start_on_idle_cb, context); return G_SOURCE_REMOVE; } @@ -616,13 +602,10 @@ _connect_sdp_io_cb(int fd, GIOCondition condition, gpointer user_data) } /* Set callback responsible for update the internal SDP transaction */ - context->cdat->source = nm_g_unix_fd_source_new(fd, + context->cdat->source = nm_g_unix_fd_add_source(fd, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - G_PRIORITY_DEFAULT, _connect_sdp_search_io_cb, - context, - NULL); - g_source_attach(context->cdat->source, NULL); + context); done: if (error) @@ -664,13 +647,10 @@ _connect_sdp_session_start(NMBluez5DunContext *context, GError **error) return FALSE; } - context->cdat->source = nm_g_unix_fd_source_new(sdp_get_socket(context->cdat->sdp_session), + context->cdat->source = nm_g_unix_fd_add_source(sdp_get_socket(context->cdat->sdp_session), G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - G_PRIORITY_DEFAULT, _connect_sdp_io_cb, - context, - NULL); - g_source_attach(context->cdat->source, NULL); + context); return TRUE; } diff --git a/src/core/devices/bluetooth/nm-device-bt.c b/src/core/devices/bluetooth/nm-device-bt.c index 8f4ceba7..3dbfbbe0 100644 --- a/src/core/devices/bluetooth/nm-device-bt.c +++ b/src/core/devices/bluetooth/nm-device-bt.c @@ -10,6 +10,7 @@ #include #include +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "nm-bluez-common.h" #include "nm-bluez-manager.h" @@ -273,11 +274,7 @@ complete_connection(NMDevice * device, s_serial = nm_connection_get_setting_serial(connection); s_ppp = nm_connection_get_setting_ppp(connection); - s_bt = nm_connection_get_setting_bluetooth(connection); - if (!s_bt) { - s_bt = (NMSettingBluetooth *) nm_setting_bluetooth_new(); - nm_connection_add_setting(connection, NM_SETTING(s_bt)); - } + s_bt = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BLUETOOTH); ctype = nm_setting_bluetooth_get_connection_type(s_bt); if (ctype) { @@ -1007,21 +1004,21 @@ act_stage3_ip_config_start(NMDevice * device, gpointer * out_config, NMDeviceStateReason *out_failure_reason) { - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(device); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE(device); + gboolean autoip4 = FALSE; + NMActStageReturn ret; - nm_assert_addr_family(addr_family); + if (priv->connect_bt_type != NM_BT_CAPABILITY_DUN) + goto out_chain_up; - if (priv->connect_bt_type == NM_BT_CAPABILITY_DUN) { - if (addr_family == AF_INET) { - return nm_modem_stage3_ip4_config_start(priv->modem, - device, - NM_DEVICE_CLASS(nm_device_bt_parent_class), - out_failure_reason); - } else { - return nm_modem_stage3_ip6_config_start(priv->modem, device, out_failure_reason); - } - } + if (!NM_IS_IPv4(addr_family)) + return nm_modem_stage3_ip6_config_start(priv->modem, device, out_failure_reason); + + ret = nm_modem_stage3_ip4_config_start(priv->modem, device, &autoip4, out_failure_reason); + if (ret != NM_ACT_STAGE_RETURN_SUCCESS || !autoip4) + return ret; +out_chain_up: return NM_DEVICE_CLASS(nm_device_bt_parent_class) ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } diff --git a/src/core/devices/bluetooth/tests/nm-bt-test.c b/src/core/devices/bluetooth/tests/nm-bt-test.c index 0fc8aa87..548e7249 100644 --- a/src/core/devices/bluetooth/tests/nm-bt-test.c +++ b/src/core/devices/bluetooth/tests/nm-bt-test.c @@ -2,8 +2,6 @@ #include "src/core/nm-default-daemon.h" -#include - #include "devices/bluetooth/nm-bluez5-dun.h" #include "nm-test-utils-core.h" diff --git a/src/core/devices/nm-acd-manager.c b/src/core/devices/nm-acd-manager.c index 145947bb..c041163e 100644 --- a/src/core/devices/nm-acd-manager.c +++ b/src/core/devices/nm-acd-manager.c @@ -349,9 +349,7 @@ nm_acd_manager_start_probe(NMAcdManager *self, guint timeout) nm_assert(!self->event_source); n_acd_get_fd(self->acd, &fd); - self->event_source = - nm_g_unix_fd_source_new(fd, G_IO_IN, G_PRIORITY_DEFAULT, acd_event, self, NULL); - g_source_attach(self->event_source, NULL); + self->event_source = nm_g_unix_fd_add_source(fd, G_IO_IN, acd_event, self); return success ? 0 : -NME_UNSPEC; } @@ -439,9 +437,7 @@ nm_acd_manager_announce_addresses(NMAcdManager *self) if (!self->event_source) { n_acd_get_fd(self->acd, &fd); - self->event_source = - nm_g_unix_fd_source_new(fd, G_IO_IN, G_PRIORITY_DEFAULT, acd_event, self, NULL); - g_source_attach(self->event_source, NULL); + self->event_source = nm_g_unix_fd_add_source(fd, G_IO_IN, acd_event, self); } return success ? 0 : -NME_UNSPEC; diff --git a/src/core/devices/nm-device-6lowpan.c b/src/core/devices/nm-device-6lowpan.c index 96218658..8b77c22c 100644 --- a/src/core/devices/nm-device-6lowpan.c +++ b/src/core/devices/nm-device-6lowpan.c @@ -9,6 +9,7 @@ #include "nm-device-private.h" #include "settings/nm-settings.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-6lowpan.h" @@ -221,12 +222,7 @@ static void update_connection(NMDevice *device, NMConnection *connection) { NMSetting6Lowpan *s_6lowpan = - NM_SETTING_6LOWPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_6LOWPAN)); - - if (!s_6lowpan) { - s_6lowpan = (NMSetting6Lowpan *) nm_setting_6lowpan_new(); - nm_connection_add_setting(connection, (NMSetting *) s_6lowpan); - } + _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_6LOWPAN); g_object_set( s_6lowpan, diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c index b208e2c0..f7d78f57 100644 --- a/src/core/devices/nm-device-bond.c +++ b/src/core/devices/nm-device-bond.c @@ -14,8 +14,10 @@ #include "nm-device-private.h" #include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "nm-ip4-config.h" +#include "nm-setting-bond-port.h" #define _NMLOG_DEVICE_TYPE NMDeviceBond #include "nm-device-logging.h" @@ -79,8 +81,6 @@ complete_connection(NMDevice * device, NMConnection *const *existing_connections, GError ** error) { - NMSettingBond *s_bond; - nm_utils_complete_generic(nm_device_get_platform(device), connection, NM_SETTING_BOND_SETTING_NAME, @@ -91,11 +91,7 @@ complete_connection(NMDevice * device, NULL, TRUE); - s_bond = nm_connection_get_setting_bond(connection); - if (!s_bond) { - s_bond = (NMSettingBond *) nm_setting_bond_new(); - nm_connection_add_setting(connection, NM_SETTING(s_bond)); - } + _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BOND); return TRUE; } @@ -168,16 +164,11 @@ static void update_connection(NMDevice *device, NMConnection *connection) { NMDeviceBond * self = NM_DEVICE_BOND(device); - NMSettingBond *s_bond = nm_connection_get_setting_bond(connection); + NMSettingBond *s_bond = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BOND); int ifindex = nm_device_get_ifindex(device); NMBondMode mode = NM_BOND_MODE_UNKNOWN; const char ** options; - if (!s_bond) { - s_bond = (NMSettingBond *) nm_setting_bond_new(); - nm_connection_add_setting(connection, (NMSetting *) s_bond); - } - /* Read bond options from sysfs and update the Bond setting to match */ options = nm_setting_bond_get_valid_options(NULL); for (; options[0]; options++) { @@ -225,11 +216,29 @@ update_connection(NMDevice *device, NMConnection *connection) } static gboolean -master_update_slave_connection(NMDevice * self, - NMDevice * slave, - NMConnection *connection, - GError ** error) +controller_update_port_connection(NMDevice * self, + NMDevice * port, + NMConnection *connection, + GError ** error) { + NMSettingBondPort *s_port; + int ifindex_port = nm_device_get_ifindex(port); + uint queue_id = NM_BOND_PORT_QUEUE_ID_DEF; + gs_free char * queue_id_str = NULL; + + g_return_val_if_fail(ifindex_port > 0, FALSE); + + s_port = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BOND_PORT); + + queue_id_str = + nm_platform_sysctl_slave_get_option(nm_device_get_platform(self), ifindex_port, "queue_id"); + if (queue_id_str) { + queue_id = + _nm_utils_ascii_str_to_int64(queue_id_str, 10, 0, 65535, NM_BOND_PORT_QUEUE_ID_DEF); + g_object_set(s_port, NM_SETTING_BOND_PORT_QUEUE_ID, queue_id, NULL); + } else + _LOGW(LOGD_BOND, "failed to read bond port setting '%s'", NM_SETTING_BOND_PORT_QUEUE_ID); + g_object_set(nm_connection_get_setting_connection(connection), NM_SETTING_CONNECTION_MASTER, nm_device_get_iface(self), @@ -250,9 +259,8 @@ set_arp_targets(NMDevice *device, const char *cur_arp_ip_target, const char *new gsize i; gsize j; - cur_strv = nm_utils_strsplit_set_full(cur_arp_ip_target, - NM_ASCII_SPACES, - NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP); + cur_strv = + nm_strsplit_set_full(cur_arp_ip_target, NM_ASCII_SPACES, NM_STRSPLIT_SET_FLAGS_STRSTRIP); new_strv = nm_utils_bond_option_arp_ip_targets_split(new_arp_ip_target); cur_len = NM_PTRARRAY_LEN(cur_strv); @@ -276,7 +284,7 @@ set_arp_targets(NMDevice *device, const char *cur_arp_ip_target, const char *new } } - if (nm_utils_strv_find_first((char **) new_strv, i, s) < 0) + if (nm_strv_find_first(new_strv, i, s) < 0) new_strv[j++] = s; } new_strv[j] = NULL; @@ -286,7 +294,7 @@ set_arp_targets(NMDevice *device, const char *cur_arp_ip_target, const char *new if (cur_len == 0 && new_len == 0) return; - if (nm_utils_strv_equal(cur_strv, new_strv)) + if (nm_strv_equal(cur_strv, new_strv)) return; for (i = 0; i < cur_len; i++) @@ -395,30 +403,57 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) return ret; } +static void +commit_port_options(NMDevice *bond_device, NMDevice *port, NMSettingBondPort *s_port) +{ + char queue_id_str[IFNAMSIZ + NM_STRLEN(":") + 5 + 100]; + + /* + * The queue-id of bond port is read only, we should modify bond interface using: + * echo "eth1:2" > /sys/class/net/bond0/bonding/queue_id + * Kernel allows parital editing, so no need to care about other bond ports. + */ + g_snprintf(queue_id_str, + sizeof(queue_id_str), + "%s:%" G_GUINT32_FORMAT, + nm_device_get_iface(port), + s_port ? nm_setting_bond_port_get_queue_id(s_port) : NM_BOND_PORT_QUEUE_ID_DEF); + + nm_platform_sysctl_master_set_option(nm_device_get_platform(bond_device), + nm_device_get_ifindex(bond_device), + "queue_id", + queue_id_str); +} + static gboolean -enslave_slave(NMDevice *device, NMDevice *slave, NMConnection *connection, gboolean configure) +enslave_slave(NMDevice *device, NMDevice *port, NMConnection *connection, gboolean configure) { - NMDeviceBond *self = NM_DEVICE_BOND(device); + NMDeviceBond * self = NM_DEVICE_BOND(device); + NMSettingBondPort *s_port; - nm_device_master_check_slave_physical_port(device, slave, LOGD_BOND); + nm_device_master_check_slave_physical_port(device, port, LOGD_BOND); if (configure) { gboolean success; - nm_device_take_down(slave, TRUE); + nm_device_take_down(port, TRUE); success = nm_platform_link_enslave(nm_device_get_platform(device), nm_device_get_ip_ifindex(device), - nm_device_get_ip_ifindex(slave)); - nm_device_bring_up(slave, TRUE, NULL); + nm_device_get_ip_ifindex(port)); + nm_device_bring_up(port, TRUE, NULL); if (!success) { - _LOGI(LOGD_BOND, "enslaved bond slave %s: failed", nm_device_get_ip_iface(slave)); + _LOGI(LOGD_BOND, "assigning bond port %s: failed", nm_device_get_ip_iface(port)); return FALSE; } - _LOGI(LOGD_BOND, "enslaved bond slave %s", nm_device_get_ip_iface(slave)); + s_port = _nm_connection_get_setting(connection, NM_TYPE_SETTING_BOND_PORT); + + commit_port_options(device, port, s_port); + + _LOGI(LOGD_BOND, "assigned bond port %s", nm_device_get_ip_iface(port)); } else - _LOGI(LOGD_BOND, "bond slave %s was enslaved", nm_device_get_ip_iface(slave)); + _LOGI(LOGD_BOND, "bond port %s was assigned", nm_device_get_ip_iface(port)); return TRUE; } @@ -624,7 +659,7 @@ nm_device_bond_class_init(NMDeviceBondClass *klass) device_class->complete_connection = complete_connection; device_class->update_connection = update_connection; - device_class->master_update_slave_connection = master_update_slave_connection; + device_class->master_update_slave_connection = controller_update_port_connection; device_class->create_and_realize = create_and_realize; device_class->act_stage1_prepare = act_stage1_prepare; diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c index a095dc3e..36a73978 100644 --- a/src/core/devices/nm-device-bridge.c +++ b/src/core/devices/nm-device-bridge.c @@ -14,6 +14,7 @@ #include "nm-device-private.h" #include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceBridge @@ -145,8 +146,6 @@ complete_connection(NMDevice * device, NMConnection *const *existing_connections, GError ** error) { - NMSettingBridge *s_bridge; - nm_utils_complete_generic(nm_device_get_platform(device), connection, NM_SETTING_BRIDGE_SETTING_NAME, @@ -157,11 +156,7 @@ complete_connection(NMDevice * device, NULL, TRUE); - s_bridge = nm_connection_get_setting_bridge(connection); - if (!s_bridge) { - s_bridge = (NMSettingBridge *) nm_setting_bridge_new(); - nm_connection_add_setting(connection, NM_SETTING(s_bridge)); - } + _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BRIDGE); return TRUE; } @@ -576,17 +571,12 @@ static void update_connection(NMDevice *device, NMConnection *connection) { NMDeviceBridge * self = NM_DEVICE_BRIDGE(device); - NMSettingBridge *s_bridge = nm_connection_get_setting_bridge(connection); + NMSettingBridge *s_bridge = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BRIDGE); int ifindex = nm_device_get_ifindex(device); const Option * option; gs_free char * stp = NULL; int stp_value; - if (!s_bridge) { - s_bridge = (NMSettingBridge *) nm_setting_bridge_new(); - nm_connection_add_setting(connection, (NMSetting *) s_bridge); - } - option = master_options; nm_assert(nm_streq(option->sysname, "stp_state")); @@ -690,11 +680,7 @@ master_update_slave_connection(NMDevice * device, g_return_val_if_fail(ifindex_slave > 0, FALSE); s_con = nm_connection_get_setting_connection(connection); - s_port = nm_connection_get_setting_bridge_port(connection); - if (!s_port) { - s_port = (NMSettingBridgePort *) nm_setting_bridge_port_new(); - nm_connection_add_setting(connection, NM_SETTING(s_port)); - } + s_port = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BRIDGE_PORT); for (option = slave_options; option->name; option++) { gs_free char *str = nm_platform_sysctl_slave_get_option(nm_device_get_platform(device), diff --git a/src/core/devices/nm-device-dummy.c b/src/core/devices/nm-device-dummy.c index 488f0ba0..4c12648f 100644 --- a/src/core/devices/nm-device-dummy.c +++ b/src/core/devices/nm-device-dummy.c @@ -16,6 +16,7 @@ #include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-dummy.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceDummy @@ -48,26 +49,16 @@ complete_connection(NMDevice * device, NMConnection *const *existing_connections, GError ** error) { - NMSettingDummy *s_dummy; + nm_utils_complete_generic_with_params(nm_device_get_platform(device), + connection, + NM_SETTING_DUMMY_SETTING_NAME, + existing_connections, + NULL, + _("Dummy connection"), + NULL, + nm_device_get_ip_iface(device)); - nm_utils_complete_generic(nm_device_get_platform(device), - connection, - NM_SETTING_DUMMY_SETTING_NAME, - existing_connections, - NULL, - _("Dummy connection"), - NULL, - NULL, - TRUE); - - s_dummy = nm_connection_get_setting_dummy(connection); - if (!s_dummy) { - g_set_error_literal(error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_INVALID_CONNECTION, - "A 'dummy' setting is required."); - return FALSE; - } + _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_DUMMY); return TRUE; } @@ -75,12 +66,7 @@ complete_connection(NMDevice * device, static void update_connection(NMDevice *device, NMConnection *connection) { - NMSettingDummy *s_dummy = nm_connection_get_setting_dummy(connection); - - if (!s_dummy) { - s_dummy = (NMSettingDummy *) nm_setting_dummy_new(); - nm_connection_add_setting(connection, (NMSetting *) s_dummy); - } + _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_DUMMY); } static gboolean diff --git a/src/core/devices/nm-device-ethernet.c b/src/core/devices/nm-device-ethernet.c index 95336c7a..667ea9b9 100644 --- a/src/core/devices/nm-device-ethernet.c +++ b/src/core/devices/nm-device-ethernet.c @@ -33,6 +33,7 @@ #include "nm-device-ethernet-utils.h" #include "settings/nm-settings.h" #include "nm-device-factory.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" #include "libnm-udev-aux/nm-udev-utils.h" @@ -1618,11 +1619,7 @@ complete_connection(NMDevice * device, NULL, TRUE); - s_veth = _nm_connection_get_setting(connection, NM_TYPE_SETTING_VETH); - if (!s_veth) { - s_veth = (NMSettingVeth *) nm_setting_veth_new(); - nm_connection_add_setting(connection, NM_SETTING(s_veth)); - } + s_veth = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_VETH); ifindex = nm_device_get_ip_ifindex(device); if (ifindex > 0) { @@ -1664,11 +1661,7 @@ complete_connection(NMDevice * device, if (s_pppoe && !nm_setting_verify(NM_SETTING(s_pppoe), NULL, error)) return FALSE; - s_wired = nm_connection_get_setting_wired(connection); - if (!s_wired) { - s_wired = (NMSettingWired *) nm_setting_wired_new(); - nm_connection_add_setting(connection, NM_SETTING(s_wired)); - } + s_wired = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_WIRED); /* Default to an ethernet-only connection, but if a PPPoE setting was given * then PPPoE should be our connection type. @@ -1782,20 +1775,15 @@ get_s390_subchannels(NMDevice *device) static void update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(device); - NMSettingWired * s_wired = nm_connection_get_setting_wired(connection); - 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; - const char * key; - const char * value; - - if (!s_wired) { - s_wired = (NMSettingWired *) nm_setting_wired_new(); - nm_connection_add_setting(connection, (NMSetting *) s_wired); - } + NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(device); + NMSettingWired *s_wired = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_WIRED); + 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; + const char * key; + const char * value; g_object_set(nm_connection_get_setting_connection(connection), NM_SETTING_CONNECTION_TYPE, diff --git a/src/core/devices/nm-device-infiniband.c b/src/core/devices/nm-device-infiniband.c index 37065bc8..df14dfa8 100644 --- a/src/core/devices/nm-device-infiniband.c +++ b/src/core/devices/nm-device-infiniband.c @@ -16,6 +16,7 @@ #include "nm-ip4-config.h" #include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #define NM_DEVICE_INFINIBAND_IS_PARTITION "is-partition" @@ -146,11 +147,7 @@ complete_connection(NMDevice * device, { NMSettingInfiniband *s_infiniband; - s_infiniband = nm_connection_get_setting_infiniband(connection); - if (!s_infiniband) { - s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new(); - nm_connection_add_setting(connection, NM_SETTING(s_infiniband)); - } + s_infiniband = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_INFINIBAND); nm_utils_complete_generic( nm_device_get_platform(device), @@ -175,15 +172,11 @@ complete_connection(NMDevice * device, 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); - const char * transport_mode = "datagram"; - int ifindex; - - if (!s_infiniband) { - s_infiniband = (NMSettingInfiniband *) nm_setting_infiniband_new(); - nm_connection_add_setting(connection, (NMSetting *) s_infiniband); - } + NMSettingInfiniband *s_infiniband = + _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_INFINIBAND); + const char *mac = nm_device_get_permanent_hw_address(device); + const char *transport_mode = "datagram"; + int ifindex; if (mac && !nm_utils_hwaddr_matches(mac, -1, NULL, INFINIBAND_ALEN)) g_object_set(s_infiniband, NM_SETTING_INFINIBAND_MAC_ADDRESS, mac, NULL); diff --git a/src/core/devices/nm-device-ip-tunnel.c b/src/core/devices/nm-device-ip-tunnel.c index c55dd9f6..fe2e2023 100644 --- a/src/core/devices/nm-device-ip-tunnel.c +++ b/src/core/devices/nm-device-ip-tunnel.c @@ -18,6 +18,7 @@ #include "nm-manager.h" #include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "settings/nm-settings.h" #include "nm-act-request.h" @@ -416,14 +417,10 @@ complete_connection(NMDevice * device, static void update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceIPTunnel * self = NM_DEVICE_IP_TUNNEL(device); - NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE(self); - NMSettingIPTunnel * s_ip_tunnel = nm_connection_get_setting_ip_tunnel(connection); - - if (!s_ip_tunnel) { - s_ip_tunnel = (NMSettingIPTunnel *) nm_setting_ip_tunnel_new(); - nm_connection_add_setting(connection, (NMSetting *) s_ip_tunnel); - } + NMDeviceIPTunnel * self = NM_DEVICE_IP_TUNNEL(device); + NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE(self); + NMSettingIPTunnel * s_ip_tunnel = + _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_IP_TUNNEL); if (nm_setting_ip_tunnel_get_mode(s_ip_tunnel) != priv->mode) g_object_set(G_OBJECT(s_ip_tunnel), NM_SETTING_IP_TUNNEL_MODE, priv->mode, NULL); diff --git a/src/core/devices/nm-device-logging.h b/src/core/devices/nm-device-logging.h index 844e9949..c2602189 100644 --- a/src/core/devices/nm-device-logging.h +++ b/src/core/devices/nm-device-logging.h @@ -9,15 +9,13 @@ #include "nm-device.h" #if !_NM_CC_SUPPORT_GENERIC - #define _NM_DEVICE_CAST(self) ((NMDevice *) (self)) +#define _NM_DEVICE_CAST(self) ((NMDevice *) (self)) #elif !defined(_NMLOG_DEVICE_TYPE) - #define _NM_DEVICE_CAST(self) \ - _Generic((self), NMDevice * \ - : ((NMDevice *) (self)), NMDevice *const \ - : ((NMDevice *) (self))) +#define _NM_DEVICE_CAST(self) \ + _Generic((self), NMDevice * : ((NMDevice *) (self)), NMDevice *const : ((NMDevice *) (self))) #else - #define _NM_DEVICE_CAST(self) \ - _Generic((self), \ +#define _NM_DEVICE_CAST(self) \ + _Generic((self), \ _NMLOG_DEVICE_TYPE * : ((NMDevice *) (self)), \ _NMLOG_DEVICE_TYPE * const: ((NMDevice *) (self)), \ NMDevice * : ((NMDevice *) (self)), \ diff --git a/src/core/devices/nm-device-macvlan.c b/src/core/devices/nm-device-macvlan.c index 7302ecdf..937ba9e4 100644 --- a/src/core/devices/nm-device-macvlan.c +++ b/src/core/devices/nm-device-macvlan.c @@ -13,6 +13,7 @@ #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-manager.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-macvlan.h" @@ -419,14 +420,10 @@ complete_connection(NMDevice * device, static void update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE(device); - NMSettingMacvlan * s_macvlan = nm_connection_get_setting_macvlan(connection); - int new_mode; - - if (!s_macvlan) { - s_macvlan = (NMSettingMacvlan *) nm_setting_macvlan_new(); - nm_connection_add_setting(connection, (NMSetting *) s_macvlan); - } + NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE(device); + NMSettingMacvlan * s_macvlan = + _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_MACVLAN); + int new_mode; new_mode = platform_mode_to_setting(priv->props.mode); if (new_mode != nm_setting_macvlan_get_mode(s_macvlan)) diff --git a/src/core/devices/nm-device-ppp.c b/src/core/devices/nm-device-ppp.c index 8df245bb..04051bec 100644 --- a/src/core/devices/nm-device-ppp.c +++ b/src/core/devices/nm-device-ppp.c @@ -93,28 +93,35 @@ ppp_ifindex_set(NMPPPManager *ppp_manager, int ifindex, const char *iface, gpoin } static void -ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data) +_ppp_ip4_config_handle(NMDevicePpp *self) { - NMDevice * device = NM_DEVICE(user_data); - NMDevicePpp * self = NM_DEVICE_PPP(device); + NMDevice * device = NM_DEVICE(self); NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); - _LOGT(LOGD_DEVICE | LOGD_PPP, "received IPv4 config from pppd"); + if (!priv->ip4_config) + return; - if (nm_device_get_state(device) == NM_DEVICE_STATE_IP_CONFIG) { - if (nm_device_activate_ip4_state_in_conf(device)) { - nm_device_activate_schedule_ip_config_result(device, - AF_INET, - NM_IP_CONFIG_CAST(config)); - return; - } - } else { - if (priv->ip4_config) - g_object_unref(priv->ip4_config); - priv->ip4_config = g_object_ref(config); + if (nm_device_get_state(device) == NM_DEVICE_STATE_IP_CONFIG + && nm_device_activate_ip4_state_in_conf(device)) { + nm_device_activate_schedule_ip_config_result( + device, + AF_INET, + NM_IP_CONFIG_CAST(g_steal_pointer(&priv->ip4_config))); + return; } } +static void +ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data) +{ + NMDevicePpp * self = NM_DEVICE_PPP(user_data); + NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); + + _LOGT(LOGD_DEVICE | LOGD_PPP, "received IPv4 config from pppd"); + nm_g_object_ref_set(&priv->ip4_config, config); + _ppp_ip4_config_handle(self); +} + static gboolean check_connection_compatible(NMDevice *device, NMConnection *connection, GError **error) { @@ -193,6 +200,15 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason) return NM_ACT_STAGE_RETURN_POSTPONE; } +static gboolean +_schedule_ip_config_result(gpointer user_data) +{ + gs_unref_object NMDevicePpp *self = user_data; + + _ppp_ip4_config_handle(self); + return G_SOURCE_REMOVE; +} + static NMActStageReturn act_stage3_ip_config_start(NMDevice * device, int addr_family, @@ -203,13 +219,8 @@ act_stage3_ip_config_start(NMDevice * device, NMDevicePpp * self = NM_DEVICE_PPP(device); NMDevicePppPrivate *priv = NM_DEVICE_PPP_GET_PRIVATE(self); - if (priv->ip4_config) { - if (out_config) - *out_config = g_steal_pointer(&priv->ip4_config); - else - g_clear_object(&priv->ip4_config); - return NM_ACT_STAGE_RETURN_SUCCESS; - } + if (priv->ip4_config) + nm_g_idle_add(_schedule_ip_config_result, g_object_ref(self)); /* Wait IPCP termination */ return NM_ACT_STAGE_RETURN_POSTPONE; @@ -256,6 +267,8 @@ deactivate(NMDevice *device) nm_ppp_manager_stop(priv->ppp_manager, NULL, NULL, NULL); g_clear_object(&priv->ppp_manager); } + + g_clear_object(&priv->ip4_config); } static void diff --git a/src/core/devices/nm-device-private.h b/src/core/devices/nm-device-private.h index eb37b14f..b55e8b43 100644 --- a/src/core/devices/nm-device-private.h +++ b/src/core/devices/nm-device-private.h @@ -143,7 +143,7 @@ NMIP6Config *nm_device_ip6_config_new(NMDevice *self); NMIPConfig *nm_device_ip_config_new(NMDevice *self, int addr_family); -NML3ConfigData *nm_device_create_l3_config_data(NMDevice *self); +NML3ConfigData *nm_device_create_l3_config_data(NMDevice *self, NMIPConfigSource source); /*****************************************************************************/ diff --git a/src/core/devices/nm-device-tun.c b/src/core/devices/nm-device-tun.c index ebccddfc..0ab08f65 100644 --- a/src/core/devices/nm-device-tun.c +++ b/src/core/devices/nm-device-tun.c @@ -17,6 +17,7 @@ #include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-tun.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceTun @@ -186,11 +187,7 @@ update_connection(NMDevice *device, NMConnection *connection) return; } - s_tun = nm_connection_get_setting_tun(connection); - if (!s_tun) { - s_tun = (NMSettingTun *) nm_setting_tun_new(); - nm_connection_add_setting(connection, (NMSetting *) s_tun); - } + s_tun = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_TUN); if (mode != nm_setting_tun_get_mode(s_tun)) g_object_set(G_OBJECT(s_tun), NM_SETTING_TUN_MODE, (guint) mode, NULL); diff --git a/src/core/devices/nm-device-utils.c b/src/core/devices/nm-device-utils.c index f40ca570..2a6ab04e 100644 --- a/src/core/devices/nm-device-utils.c +++ b/src/core/devices/nm-device-utils.c @@ -10,7 +10,7 @@ /*****************************************************************************/ NM_UTILS_LOOKUP_STR_DEFINE( - nm_device_state_queued_state_to_str, + nm_device_state_queued_state_to_string, NMDeviceState, NM_UTILS_LOOKUP_DEFAULT(NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "???"), NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_UNKNOWN, @@ -41,14 +41,14 @@ NM_UTILS_LOOKUP_STR_DEFINE( NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "failed"), ); const char * -nm_device_state_to_str(NMDeviceState state) +nm_device_state_to_string(NMDeviceState state) { - return nm_device_state_queued_state_to_str(state) + return nm_device_state_queued_state_to_string(state) + NM_STRLEN(NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE); } NM_UTILS_LOOKUP_STR_DEFINE( - nm_device_state_reason_to_str, + nm_device_state_reason_to_string, NMDeviceStateReason, NM_UTILS_LOOKUP_DEFAULT(NULL), NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNKNOWN, "unknown"), @@ -129,7 +129,7 @@ NM_UTILS_LOOKUP_STR_DEFINE( "sriov-configuration-failed"), NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_PEER_NOT_FOUND, "peer-not-found"), ); -NM_UTILS_LOOKUP_STR_DEFINE(nm_device_mtu_source_to_str, +NM_UTILS_LOOKUP_STR_DEFINE(nm_device_mtu_source_to_string, NMDeviceMtuSource, NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"), NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_NONE, "none"), @@ -138,7 +138,7 @@ NM_UTILS_LOOKUP_STR_DEFINE(nm_device_mtu_source_to_str, NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_MTU_SOURCE_CONNECTION, "connection"), ); -NM_UTILS_LOOKUP_STR_DEFINE(nm_device_sys_iface_state_to_str, +NM_UTILS_LOOKUP_STR_DEFINE(nm_device_sys_iface_state_to_string, NMDeviceSysIfaceState, NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT("unknown"), NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_EXTERNAL, "external"), @@ -147,7 +147,7 @@ NM_UTILS_LOOKUP_STR_DEFINE(nm_device_sys_iface_state_to_str, NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_SYS_IFACE_STATE_REMOVED, "removed"), ); -NM_UTILS_LOOKUP_STR_DEFINE(nm_device_ip_state_to_str, +NM_UTILS_LOOKUP_STR_DEFINE(nm_device_ip_state_to_string, NMDeviceIPState, NM_UTILS_LOOKUP_DEFAULT_WARN("unknown"), NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_IP_STATE_NONE, "none"), @@ -267,7 +267,18 @@ resolve_addr_resolved_cb(NMDnsSystemdResolved * resolved, _LOG2D(info, "error resolving via systemd-resolved: %s", error->message); dbus_error = g_dbus_error_get_remote_error(error); - if (nm_streq0(dbus_error, "org.freedesktop.resolve1.DnsError.NXDOMAIN")) { + if (NM_STR_HAS_PREFIX(dbus_error, "org.freedesktop.resolve1.")) { + /* systemd-resolved is enabled but it couldn't resolve the + * address via DNS. Don't fall back to spawning the helper, + * because the helper will possibly ask again to + * systemd-resolved (via /etc/resolv.conf), potentially using + * other protocols than DNS or returning synthetic results. + * + * Consider the error as the final indication that the address + * can't be resolved. + * + * See: https://www.freedesktop.org/wiki/Software/systemd/resolved/#commonerrors + */ resolve_addr_complete(info, NULL, g_error_copy(error)); return; } diff --git a/src/core/devices/nm-device-utils.h b/src/core/devices/nm-device-utils.h index 8bc957a4..7200b0ea 100644 --- a/src/core/devices/nm-device-utils.h +++ b/src/core/devices/nm-device-utils.h @@ -5,11 +5,11 @@ /*****************************************************************************/ -const char *nm_device_state_to_str(NMDeviceState state); -const char *nm_device_state_reason_to_str(NMDeviceStateReason reason); +const char *nm_device_state_to_string(NMDeviceState state); +const char *nm_device_state_reason_to_string(NMDeviceStateReason reason); -#define nm_device_state_reason_to_str_a(reason) \ - NM_UTILS_LOOKUP_STR_A(nm_device_state_reason_to_str, reason) +#define nm_device_state_reason_to_string_a(reason) \ + NM_UTILS_LOOKUP_STR_A(nm_device_state_reason_to_string, reason) static inline NMDeviceStateReason nm_device_state_reason_check(NMDeviceStateReason reason) @@ -41,7 +41,7 @@ nm_device_state_reason_check(NMDeviceStateReason reason) #define NM_PENDING_ACTIONPREFIX_QUEUED_STATE_CHANGE "queued-state-change-" #define NM_PENDING_ACTIONPREFIX_ACTIVATION "activation-" -const char *nm_device_state_queued_state_to_str(NMDeviceState state); +const char *nm_device_state_queued_state_to_string(NMDeviceState state); /*****************************************************************************/ @@ -52,7 +52,7 @@ typedef enum { NM_DEVICE_MTU_SOURCE_CONNECTION, } NMDeviceMtuSource; -const char *nm_device_mtu_source_to_str(NMDeviceMtuSource mtu_source); +const char *nm_device_mtu_source_to_string(NMDeviceMtuSource mtu_source); /*****************************************************************************/ @@ -69,7 +69,7 @@ typedef enum _nm_packed { NM_DEVICE_SYS_IFACE_STATE_REMOVED, } NMDeviceSysIfaceState; -const char *nm_device_sys_iface_state_to_str(NMDeviceSysIfaceState sys_iface_state); +const char *nm_device_sys_iface_state_to_string(NMDeviceSysIfaceState sys_iface_state); /*****************************************************************************/ @@ -81,7 +81,7 @@ typedef enum { NM_DEVICE_IP_STATE_FAIL, } NMDeviceIPState; -const char *nm_device_ip_state_to_str(NMDeviceIPState ip_state); +const char *nm_device_ip_state_to_string(NMDeviceIPState ip_state); /*****************************************************************************/ diff --git a/src/core/devices/nm-device-vlan.c b/src/core/devices/nm-device-vlan.c index 548245f8..d1e57411 100644 --- a/src/core/devices/nm-device-vlan.c +++ b/src/core/devices/nm-device-vlan.c @@ -19,6 +19,7 @@ #include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-manager.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "libnm-platform/nmp-object.h" #include "libnm-platform/nm-platform-utils.h" @@ -432,18 +433,13 @@ static void update_connection(NMDevice *device, NMConnection *connection) { NMDeviceVlanPrivate * priv = NM_DEVICE_VLAN_GET_PRIVATE(device); - NMSettingVlan * s_vlan = nm_connection_get_setting_vlan(connection); + NMSettingVlan * s_vlan = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_VLAN); int ifindex = nm_device_get_ifindex(device); const NMPlatformLink *plink; const NMPObject * polnk; guint vlan_id; _NMVlanFlags vlan_flags; - if (!s_vlan) { - s_vlan = (NMSettingVlan *) nm_setting_vlan_new(); - nm_connection_add_setting(connection, (NMSetting *) s_vlan); - } - polnk = nm_platform_link_get_lnk(nm_device_get_platform(device), ifindex, NM_LINK_TYPE_VLAN, diff --git a/src/core/devices/nm-device-vrf.c b/src/core/devices/nm-device-vrf.c index 2a1f42c6..c752fa0a 100644 --- a/src/core/devices/nm-device-vrf.c +++ b/src/core/devices/nm-device-vrf.c @@ -9,6 +9,7 @@ #include "nm-device-private.h" #include "nm-manager.h" #include "nm-setting-vrf.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-platform/nm-platform.h" #include "settings/nm-settings.h" @@ -199,12 +200,7 @@ static void update_connection(NMDevice *device, NMConnection *connection) { NMDeviceVrfPrivate *priv = NM_DEVICE_VRF_GET_PRIVATE(device); - NMSettingVrf * s_vrf = _nm_connection_get_setting(connection, NM_TYPE_SETTING_VRF); - - if (!s_vrf) { - s_vrf = (NMSettingVrf *) nm_setting_vrf_new(); - nm_connection_add_setting(connection, (NMSetting *) s_vrf); - } + NMSettingVrf * s_vrf = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_VRF); if (priv->props.table != nm_setting_vrf_get_table(s_vrf)) g_object_set(G_OBJECT(s_vrf), NM_SETTING_VRF_TABLE, priv->props.table, NULL); diff --git a/src/core/devices/nm-device-vxlan.c b/src/core/devices/nm-device-vxlan.c index f9dfad2a..fcd6950b 100644 --- a/src/core/devices/nm-device-vxlan.c +++ b/src/core/devices/nm-device-vxlan.c @@ -17,6 +17,7 @@ #include "settings/nm-settings.h" #include "nm-act-request.h" #include "nm-ip4-config.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceVxlan @@ -399,14 +400,9 @@ complete_connection(NMDevice * device, static void update_connection(NMDevice *device, NMConnection *connection) { - NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE(device); - NMSettingVxlan * s_vxlan = nm_connection_get_setting_vxlan(connection); - char sbuf[NM_UTILS_INET_ADDRSTRLEN]; - - if (!s_vxlan) { - s_vxlan = (NMSettingVxlan *) nm_setting_vxlan_new(); - nm_connection_add_setting(connection, (NMSetting *) s_vxlan); - } + NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE(device); + NMSettingVxlan *s_vxlan = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_VXLAN); + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; if (priv->props.id != nm_setting_vxlan_get_id(s_vxlan)) g_object_set(G_OBJECT(s_vxlan), NM_SETTING_VXLAN_ID, priv->props.id, NULL); diff --git a/src/core/devices/nm-device-wireguard.c b/src/core/devices/nm-device-wireguard.c index aa9c46eb..f129478f 100644 --- a/src/core/devices/nm-device-wireguard.c +++ b/src/core/devices/nm-device-wireguard.c @@ -11,6 +11,7 @@ #include #include "nm-setting-wireguard.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "libnm-glib-aux/nm-secret-utils.h" #include "nm-device-private.h" @@ -1891,17 +1892,11 @@ static void update_connection(NMDevice *device, NMConnection *connection) { NMDeviceWireGuardPrivate *priv = NM_DEVICE_WIREGUARD_GET_PRIVATE(device); - NMSettingWireGuard * s_wg = - NM_SETTING_WIREGUARD(nm_connection_get_setting(connection, NM_TYPE_SETTING_WIREGUARD)); - const NMPObject * obj_wg; + NMSettingWireGuard *s_wg = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_WIREGUARD); + const NMPObject * obj_wg; const NMPObjectLnkWireGuard *olnk_wg; guint i; - if (!s_wg) { - s_wg = NM_SETTING_WIREGUARD(nm_setting_wireguard_new()); - nm_connection_add_setting(connection, NM_SETTING(s_wg)); - } - g_object_set(s_wg, NM_SETTING_WIREGUARD_FWMARK, (guint) priv->lnk_curr.fwmark, diff --git a/src/core/devices/nm-device-wpan.c b/src/core/devices/nm-device-wpan.c index 73d79410..9bc43a85 100644 --- a/src/core/devices/nm-device-wpan.c +++ b/src/core/devices/nm-device-wpan.c @@ -18,6 +18,7 @@ #include "libnm-platform/nm-platform.h" #include "nm-device-factory.h" #include "nm-setting-wpan.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #define _NMLOG_DEVICE_TYPE NMDeviceWpan @@ -71,13 +72,7 @@ complete_connection(NMDevice * device, static void update_connection(NMDevice *device, NMConnection *connection) { - NMSettingWpan *s_wpan = - NM_SETTING_WPAN(nm_connection_get_setting(connection, NM_TYPE_SETTING_WPAN)); - - if (!s_wpan) { - s_wpan = (NMSettingWpan *) nm_setting_wpan_new(); - nm_connection_add_setting(connection, (NMSetting *) s_wpan); - } + _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_WPAN); } static gboolean diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 50386d00..ea1b9647 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -185,7 +185,7 @@ typedef struct { typedef struct { NMDhcpClient *client; NMDhcpConfig *config; - gulong state_sigid; + gulong notify_sigid; guint grace_id; bool grace_pending : 1; bool was_active : 1; @@ -290,7 +290,8 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMDevice, PROP_STATISTICS_RX_BYTES, PROP_IP4_CONNECTIVITY, PROP_IP6_CONNECTIVITY, - PROP_INTERFACE_FLAGS, ); + PROP_INTERFACE_FLAGS, + PROP_PORTS, ); typedef struct _NMDevicePrivate { bool in_state_changed; @@ -316,7 +317,12 @@ typedef struct _NMDevicePrivate { guint queued_ip_config_id_x[2]; }; - GSList *pending_actions; + struct { + const char **arr; + guint len; + guint alloc; + } pending_actions; + GSList *dad6_failed_addrs; NMDBusTrackObjPath parent_device; @@ -500,6 +506,7 @@ typedef struct _NMDevicePrivate { NMDeviceStageState stage1_sriov_state : 3; bool ip_config_started : 1; + bool tc_committed : 1; char *current_stable_id; @@ -574,7 +581,6 @@ typedef struct _NMDevicePrivate { AppliedConfig ip6_config; /* Event ID of the current IP6 config from DHCP */ char * event_id; - gulong prefix_sigid; NMNDiscDHCPLevel mode; guint needed_prefixes; } dhcp6; @@ -696,15 +702,17 @@ typedef struct _NMDevicePrivate { guint sriov_reset_pending; struct { - guint timeout_id; - guint refresh_rate_ms; - guint64 tx_bytes; - guint64 rx_bytes; + GSource *timeout_source; + guint refresh_rate_ms; + guint64 tx_bytes; + guint64 rx_bytes; } stats; bool mtu_force_set_done : 1; NMOptionBool promisc_reset; + + GVariant *ports_variant; /* Array of port devices D-Bus path */ } NMDevicePrivate; G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT) @@ -1190,6 +1198,29 @@ _prop_get_connection_llmnr(NMDevice *self) NM_SETTING_CONNECTION_LLMNR_DEFAULT); } +static NMSettingConnectionDnsOverTls +_prop_get_connection_dns_over_tls(NMDevice *self) +{ + NMConnection * connection; + NMSettingConnectionDnsOverTls dns_over_tls = NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT; + + g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT); + + connection = nm_device_get_applied_connection(self); + if (connection) + dns_over_tls = nm_setting_connection_get_dns_over_tls( + nm_connection_get_setting_connection(connection)); + if (dns_over_tls != NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT) + return dns_over_tls; + + return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA, + NM_CON_DEFAULT("connection.dns-over-tls"), + self, + NM_SETTING_CONNECTION_DNS_OVER_TLS_NO, + NM_SETTING_CONNECTION_DNS_OVER_TLS_YES, + NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT); +} + static guint32 _prop_get_ipvx_route_table(NMDevice *self, int addr_family) { @@ -2407,7 +2438,7 @@ nm_device_ip_config_new(NMDevice *self, int addr_family) } NML3ConfigData * -nm_device_create_l3_config_data(NMDevice *self) +nm_device_create_l3_config_data(NMDevice *self, NMIPConfigSource source) { int ifindex; @@ -2417,7 +2448,7 @@ nm_device_create_l3_config_data(NMDevice *self) if (ifindex <= 0) g_return_val_if_reached(NULL); - return nm_l3_config_data_new(nm_device_get_multi_index(self), ifindex); + return nm_l3_config_data_new(nm_device_get_multi_index(self), ifindex, source); } static void @@ -2554,8 +2585,8 @@ nm_device_sys_iface_state_set(NMDevice *self, NMDeviceSysIfaceState sys_iface_st if (priv->sys_iface_state != sys_iface_state) { _LOGT(LOGD_DEVICE, "sys-iface-state: %s -> %s", - nm_device_sys_iface_state_to_str(priv->sys_iface_state), - nm_device_sys_iface_state_to_str(sys_iface_state)); + nm_device_sys_iface_state_to_string(priv->sys_iface_state), + nm_device_sys_iface_state_to_string(sys_iface_state)); priv->sys_iface_state_ = sys_iface_state; } @@ -2741,7 +2772,7 @@ nm_device_sysctl_ip_conf_get_int_checked(NMDevice * self, } static void -set_ipv6_token(NMDevice *self, NMUtilsIPv6IfaceId iid, const char *token_str) +set_ipv6_token(NMDevice *self, const NMUtilsIPv6IfaceId *iid, const char *token_str) { NMPlatform * platform; int ifindex; @@ -2757,7 +2788,7 @@ set_ipv6_token(NMDevice *self, NMUtilsIPv6IfaceId iid, const char *token_str) ifindex = nm_device_get_ip_ifindex(self); link = nm_platform_link_get(platform, ifindex); - if (link && link->inet6_token.id == iid.id) { + if (link && link->inet6_token.id == iid->id) { _LOGT(LOGD_DEVICE | LOGD_IP6, "token %s already set", token_str); return; } @@ -2905,7 +2936,7 @@ _set_ip_state(NMDevice *self, int addr_family, NMDeviceIPState new_state) "ip%c-state: set to %d (%s)", nm_utils_addr_family_to_char(addr_family), (int) new_state, - nm_device_ip_state_to_str(new_state)); + nm_device_ip_state_to_string(new_state)); priv->ip_state_x_[IS_IPv4] = new_state; @@ -3141,8 +3172,9 @@ _set_ip_ifindex(NMDevice *self, int ifindex, const char *ifname) nm_platform_process_events_ensure_link(platform, priv->ip_ifindex, priv->ip_iface); - if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) - nm_platform_link_set_user_ipv6ll_enabled(platform, priv->ip_ifindex, TRUE); + nm_platform_link_set_inet6_addr_gen_mode(platform, + priv->ip_ifindex, + NM_IN6_ADDR_GEN_MODE_NONE); if (!nm_platform_link_is_up(platform, priv->ip_ifindex)) nm_platform_link_change_flags(platform, priv->ip_ifindex, IFF_UP, TRUE); @@ -3444,7 +3476,7 @@ _stats_set_refresh_rate(NMDevice *self, guint refresh_rate_ms) if (_stats_refresh_rate_real(old_rate) == refresh_rate_ms) return; - nm_clear_g_source(&priv->stats.timeout_id); + nm_clear_g_source_inst(&priv->stats.timeout_source); if (!refresh_rate_ms) return; @@ -3456,7 +3488,7 @@ _stats_set_refresh_rate(NMDevice *self, guint refresh_rate_ms) if (ifindex > 0) nm_platform_link_refresh(nm_device_get_platform(self), ifindex); - priv->stats.timeout_id = g_timeout_add(refresh_rate_ms, _stats_timeout_cb, self); + priv->stats.timeout_source = nm_g_timeout_add_source(refresh_rate_ms, _stats_timeout_cb, self); } /*****************************************************************************/ @@ -4509,7 +4541,7 @@ concheck_cb(NMConnectivity * connectivity, seq = handle->seq; _LOGT(LOGD_CONCHECK, - "connectivity: [Ipv%c] complete check (seq:%llu, state:%s)", + "connectivity: [IPv%c] complete check (seq:%llu, state:%s)", nm_utils_addr_family_to_char(handle->addr_family), (long long unsigned) handle->seq, nm_connectivity_state_to_string(state)); @@ -5803,7 +5835,7 @@ nm_device_update_from_platform_link(NMDevice *self, const NMPlatformLink *plink) _notify(self, PROP_PATH); } - if (plink && !nm_str_is_empty(plink->name) && nm_utils_strdup_reset(&priv->iface_, plink->name)) + if (plink && !nm_str_is_empty(plink->name) && nm_strdup_reset(&priv->iface_, plink->name)) _notify(self, PROP_IFACE); str = plink ? plink->driver : NULL; @@ -5976,9 +6008,10 @@ config_changed(NMConfig * config, { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->state <= NM_DEVICE_STATE_DISCONNECTED || priv->state > NM_DEVICE_STATE_ACTIVATED) { + if (priv->state <= NM_DEVICE_STATE_DISCONNECTED || priv->state >= NM_DEVICE_STATE_ACTIVATED) { priv->ignore_carrier = nm_config_data_get_ignore_carrier(config_data, self); - if (NM_FLAGS_HAS(changes, NM_CONFIG_CHANGE_VALUES)) + if (NM_FLAGS_HAS(changes, NM_CONFIG_CHANGE_VALUES) + && !nm_device_get_applied_setting(self, NM_TYPE_SETTING_SRIOV)) device_init_static_sriov_num_vfs(self); } } @@ -6023,7 +6056,7 @@ realize_start_setup(NMDevice * self, NMPlatform * platform; NMDeviceCapabilities capabilities = 0; NMConfig * config; - guint real_rate; + guint refresh_rate_ms; gboolean unmanaged; /* plink is a NMPlatformLink type, however, we require it to come from the platform @@ -6087,8 +6120,8 @@ realize_start_setup(NMDevice * self, if (priv->firmware_version) _notify(self, PROP_FIRMWARE_VERSION); - if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) - priv->ipv6ll_handle = nm_platform_link_get_user_ipv6ll_enabled(platform, priv->ifindex); + priv->ipv6ll_handle = (nm_platform_link_get_inet6_addr_gen_mode(platform, priv->ifindex) + == NM_IN6_ADDR_GEN_MODE_NONE); if (nm_platform_link_supports_sriov(platform, priv->ifindex)) capabilities |= NM_DEVICE_CAP_SRIOV; @@ -6131,10 +6164,12 @@ realize_start_setup(NMDevice * self, nm_device_set_carrier_from_platform(self); - nm_assert(!priv->stats.timeout_id); - real_rate = _stats_refresh_rate_real(priv->stats.refresh_rate_ms); - if (real_rate) - priv->stats.timeout_id = g_timeout_add(real_rate, _stats_timeout_cb, self); + nm_assert(!priv->stats.timeout_source); + refresh_rate_ms = _stats_refresh_rate_real(priv->stats.refresh_rate_ms); + if (refresh_rate_ms > 0) { + priv->stats.timeout_source = + nm_g_timeout_add_source(refresh_rate_ms, _stats_timeout_cb, self); + } klass->realize_start_notify(self, plink); @@ -6320,7 +6355,7 @@ nm_device_unrealize(NMDevice *self, gboolean remove_resources, GError **error) _notify(self, PROP_PHYSICAL_PORT_ID); } - nm_clear_g_source(&priv->stats.timeout_id); + nm_clear_g_source_inst(&priv->stats.timeout_source); _stats_update_counters(self, 0, 0); priv->hw_addr_len_ = 0; @@ -6442,9 +6477,9 @@ slave_state_changed(NMDevice * slave, "slave %s state change %d (%s) -> %d (%s)", nm_device_get_iface(slave), slave_old_state, - nm_device_state_to_str(slave_old_state), + nm_device_state_to_string(slave_old_state), slave_new_state, - nm_device_state_to_str(slave_new_state)); + nm_device_state_to_string(slave_new_state)); /* Don't try to enslave slaves until the master is ready */ if (priv->state < NM_DEVICE_STATE_CONFIG) @@ -6788,7 +6823,9 @@ nm_device_slave_notify_enslave(NMDevice *self, gboolean success) priv->is_enslaved = TRUE; _notify(self, PROP_MASTER); - _notify(priv->master, PROP_SLAVES); + + nm_clear_pointer(&NM_DEVICE_GET_PRIVATE(priv->master)->ports_variant, g_variant_unref); + nm_gobject_notify_together(priv->master, PROP_PORTS, PROP_SLAVES); } else if (activating) { _LOGW(LOGD_DEVICE, "Activation: connection '%s' could not be enslaved", @@ -6852,8 +6889,11 @@ nm_device_slave_notify_release(NMDevice *self, NMDeviceStateReason reason) if (priv->is_enslaved) { priv->is_enslaved = FALSE; + _notify(self, PROP_MASTER); - _notify(priv->master, PROP_SLAVES); + + nm_clear_pointer(&NM_DEVICE_GET_PRIVATE(priv->master)->ports_variant, g_variant_unref); + nm_gobject_notify_together(priv->master, PROP_PORTS, PROP_SLAVES); } } @@ -7339,7 +7379,7 @@ nm_device_generate_connection(NMDevice *self, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, NM_IN6_ADDR_GEN_MODE_EUI64, NM_SETTING_IP6_CONFIG_TOKEN, - nm_utils_inet6_interface_identifier_to_token(pllink->inet6_token, sbuf), + nm_utils_inet6_interface_identifier_to_token(&pllink->inet6_token, sbuf), NULL); } } @@ -7756,7 +7796,8 @@ recheck_available(gpointer user_data) now_available ? "" : "not ", new_state == NM_DEVICE_STATE_UNAVAILABLE ? "no change required for" : "will transition to", - nm_device_state_to_str(new_state == NM_DEVICE_STATE_UNAVAILABLE ? state : new_state)); + nm_device_state_to_string(new_state == NM_DEVICE_STATE_UNAVAILABLE ? state + : new_state)); priv->recheck_available.available_reason = NM_DEVICE_STATE_REASON_NONE; priv->recheck_available.unavailable_reason = NM_DEVICE_STATE_REASON_NONE; @@ -8259,7 +8300,7 @@ activate_stage1_device_prepare(NMDevice *self) priv->master_ready_id = g_signal_connect(active, "notify::" NM_ACTIVE_CONNECTION_INT_MASTER_READY, - (GCallback) master_ready_cb, + G_CALLBACK(master_ready_cb), self); } return; @@ -8478,10 +8519,7 @@ tc_commit(NMDevice *self) qdiscs = nm_utils_qdiscs_from_tc_setting(platform, s_tc, ip_ifindex); tfilters = nm_utils_tfilters_from_tc_setting(platform, s_tc, ip_ifindex); - if (!nm_platform_qdisc_sync(platform, ip_ifindex, qdiscs)) - return FALSE; - - if (!nm_platform_tfilter_sync(platform, ip_ifindex, tfilters)) + if (!nm_platform_tc_sync(platform, ip_ifindex, qdiscs, tfilters)) return FALSE; return TRUE; @@ -8511,13 +8549,14 @@ activate_stage2_device_config(NMDevice *self) _ethtool_state_set(self); if (!nm_device_sys_iface_state_is_external_or_assume(self)) { - if (!tc_commit(self)) { - _LOGW(LOGD_IP6, "failed applying traffic control rules"); + if (!priv->tc_committed && !tc_commit(self)) { + _LOGW(LOGD_DEVICE, "failed applying traffic control rules"); nm_device_state_changed(self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED); return; } + priv->tc_committed = TRUE; } _routing_rules_sync(self, NM_TERNARY_TRUE); @@ -8981,6 +9020,7 @@ ensure_con_ip_config(NMDevice *self, int addr_family) nm_connection_get_setting_ip4_config(connection), _prop_get_connection_mdns(self), _prop_get_connection_llmnr(self), + _prop_get_connection_dns_over_tls(self), nm_device_get_route_table(self, addr_family), nm_device_get_route_metric(self, addr_family)); } else { @@ -9028,7 +9068,7 @@ dhcp4_cleanup(NMDevice *self, CleanupType cleanup_type, gboolean release) if (priv->dhcp_data_4.client) { /* Stop any ongoing DHCP transaction on this device */ - nm_clear_g_signal_handler(priv->dhcp_data_4.client, &priv->dhcp_data_4.state_sigid); + nm_clear_g_signal_handler(priv->dhcp_data_4.client, &priv->dhcp_data_4.notify_sigid); if (cleanup_type == CLEANUP_TYPE_DECONFIGURE || cleanup_type == CLEANUP_TYPE_REMOVED) nm_dhcp_client_stop(priv->dhcp_data_4.client, release); @@ -9251,7 +9291,7 @@ ip_config_merge_and_apply(NMDevice *self, int addr_family, gboolean commit) if (commit && priv->ndisc_started && ip6_addr_gen_token && nm_utils_ipv6_interface_identifier_get_from_token(&iid, ip6_addr_gen_token)) { - set_ipv6_token(self, iid, ip6_addr_gen_token); + set_ipv6_token(self, &iid, ip6_addr_gen_token); } } @@ -9291,7 +9331,7 @@ dhcp4_lease_change(NMDevice *self, NMIP4Config *config, gboolean bound) return FALSE; } - nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP4_CHANGE, self, NULL, NULL, NULL, NULL); + nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP_CHANGE_4, self, NULL, NULL, NULL, NULL); return TRUE; } @@ -9373,7 +9413,7 @@ dhcp4_fail(NMDevice *self, NMDhcpState dhcp_state) _LOGD(LOGD_DHCP4, "DHCPv4 failed (ip_state %s, was_active %d)", - nm_device_ip_state_to_str(priv->ip_state_4), + nm_device_ip_state_to_string(priv->ip_state_4), priv->dhcp_data_4.was_active); /* The client is always left running after a failure. */ @@ -9429,21 +9469,27 @@ dhcp4_dad_cb(NMDevice *self, NMIP4Config **configs, gboolean success) } static void -dhcp4_state_changed(NMDhcpClient *client, - NMDhcpState state, - NMIP4Config * ip4_config, - GHashTable * options, - gpointer user_data) +dhcp4_notify(NMDhcpClient *client, const NMDhcpClientNotifyData *notify_data, NMDevice *self) { - NMDevice * self = NM_DEVICE(user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - NMIP4Config * manual, **configs; + NMIP4Config * manual; + NMIP4Config ** configs; NMConnection * connection; + NMDhcpState state; + NMIP4Config * ip4_config; + GHashTable * options; + + nm_assert(nm_dhcp_client_get_addr_family(client) == AF_INET); + nm_assert(notify_data); + nm_assert(notify_data->notify_type == NM_DHCP_CLIENT_NOTIFY_TYPE_STATE_CHANGED); - g_return_if_fail(nm_dhcp_client_get_addr_family(client) == AF_INET); - g_return_if_fail(!ip4_config || NM_IS_IP4_CONFIG(ip4_config)); + state = notify_data->state_changed.dhcp_state; + ip4_config = NM_IP4_CONFIG(notify_data->state_changed.ip_config); + options = notify_data->state_changed.options; - _LOGD(LOGD_DHCP4, "new DHCPv4 client state %d", state); + nm_assert(!ip4_config || NM_IS_IP4_CONFIG(ip4_config)); + + _LOGD(LOGD_DHCP4, "new DHCPv4 client state %d", (int) state); switch (state) { case NM_DHCP_STATE_BOUND: @@ -9479,6 +9525,7 @@ dhcp4_state_changed(NMDhcpClient *client, nm_connection_get_setting_ip4_config(connection), NM_SETTING_CONNECTION_MDNS_DEFAULT, NM_SETTING_CONNECTION_LLMNR_DEFAULT, + NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT, nm_device_get_route_table(self, AF_INET), nm_device_get_route_metric(self, AF_INET)); @@ -9594,10 +9641,10 @@ dhcp4_start(NMDevice *self) return NM_ACT_STAGE_RETURN_FAILURE; } - priv->dhcp_data_4.state_sigid = g_signal_connect(priv->dhcp_data_4.client, - NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, - G_CALLBACK(dhcp4_state_changed), - self); + priv->dhcp_data_4.notify_sigid = g_signal_connect(priv->dhcp_data_4.client, + NM_DHCP_CLIENT_NOTIFY, + G_CALLBACK(dhcp4_notify), + self); if (nm_device_sys_iface_state_is_external_or_assume(self)) priv->dhcp_data_4.was_active = TRUE; @@ -9768,8 +9815,7 @@ dhcp6_cleanup(NMDevice *self, CleanupType cleanup_type, gboolean release) priv->dhcp_data_6.grace_pending = FALSE; if (priv->dhcp_data_6.client) { - nm_clear_g_signal_handler(priv->dhcp_data_6.client, &priv->dhcp_data_6.state_sigid); - nm_clear_g_signal_handler(priv->dhcp_data_6.client, &priv->dhcp6.prefix_sigid); + nm_clear_g_signal_handler(priv->dhcp_data_6.client, &priv->dhcp_data_6.notify_sigid); if (cleanup_type == CLEANUP_TYPE_DECONFIGURE || cleanup_type == CLEANUP_TYPE_REMOVED) nm_dhcp_client_stop(priv->dhcp_data_6.client, release); @@ -9805,7 +9851,7 @@ dhcp6_lease_change(NMDevice *self) return FALSE; } - nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP6_CHANGE, self, NULL, NULL, NULL, NULL); + nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP_CHANGE_6, self, NULL, NULL, NULL, NULL); return TRUE; } @@ -9818,7 +9864,7 @@ dhcp6_fail(NMDevice *self, NMDhcpState dhcp_state) _LOGD(LOGD_DHCP6, "DHCPv6 failed (ip_state %s, was_active %d)", - nm_device_ip_state_to_str(priv->ip_state_6), + nm_device_ip_state_to_string(priv->ip_state_6), priv->dhcp_data_6.was_active); /* The client is always left running after a failure. */ @@ -9869,20 +9915,34 @@ clear_config: } static void -dhcp6_state_changed(NMDhcpClient *client, - NMDhcpState state, - NMIP6Config * ip6_config, - GHashTable * options, - gpointer user_data) +dhcp6_notify(NMDhcpClient *client, const NMDhcpClientNotifyData *notify_data, NMDevice *self) { - NMDevice * self = NM_DEVICE(user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); gs_free char * event_id = NULL; + NMDhcpState state; + NMIP6Config * ip6_config; + GHashTable * options; + + nm_assert(nm_dhcp_client_get_addr_family(client) == AF_INET6); + nm_assert(notify_data); + + if (notify_data->notify_type == NM_DHCP_CLIENT_NOTIFY_TYPE_PREFIX_DELEGATED) { + /* Just re-emit. The device just contributes the prefix to the + * pool in NMPolicy, which decides about subnet allocation + * on the shared devices. */ + g_signal_emit(self, signals[IP6_PREFIX_DELEGATED], 0, notify_data->prefix_delegated.prefix); + return; + } + + nm_assert(notify_data->notify_type == NM_DHCP_CLIENT_NOTIFY_TYPE_STATE_CHANGED); - g_return_if_fail(nm_dhcp_client_get_addr_family(client) == AF_INET6); - g_return_if_fail(!ip6_config || NM_IS_IP6_CONFIG(ip6_config)); + state = notify_data->state_changed.dhcp_state; + ip6_config = NM_IP6_CONFIG(notify_data->state_changed.ip_config); + options = notify_data->state_changed.options; - _LOGD(LOGD_DHCP6, "new DHCPv6 client state %d", state); + nm_assert(!ip6_config || NM_IS_IP6_CONFIG(ip6_config)); + + _LOGD(LOGD_DHCP6, "new DHCPv6 client state %d", (int) state); switch (state) { case NM_DHCP_STATE_BOUND: @@ -9962,17 +10022,6 @@ dhcp6_state_changed(NMDhcpClient *client, } } -static void -dhcp6_prefix_delegated(NMDhcpClient *client, NMPlatformIP6Address *prefix, gpointer user_data) -{ - NMDevice *self = NM_DEVICE(user_data); - - /* Just re-emit. The device just contributes the prefix to the - * pool in NMPolicy, which decides about subnet allocation - * on the shared devices. */ - g_signal_emit(self, signals[IP6_PREFIX_DELEGATED], 0, prefix); -} - /*****************************************************************************/ static gboolean @@ -10054,14 +10103,10 @@ dhcp6_start_with_link_ready(NMDevice *self, NMConnection *connection) return FALSE; } - priv->dhcp_data_6.state_sigid = g_signal_connect(priv->dhcp_data_6.client, - NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, - G_CALLBACK(dhcp6_state_changed), - self); - priv->dhcp6.prefix_sigid = g_signal_connect(priv->dhcp_data_6.client, - NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED, - G_CALLBACK(dhcp6_prefix_delegated), - self); + priv->dhcp_data_6.notify_sigid = g_signal_connect(priv->dhcp_data_6.client, + NM_DHCP_CLIENT_NOTIFY, + G_CALLBACK(dhcp6_notify), + self); if (nm_device_sys_iface_state_is_external_or_assume(self)) priv->dhcp_data_6.was_active = TRUE; @@ -10321,12 +10366,12 @@ check_and_add_ipv6ll_addr(NMDevice *self) const char * stable_id; stable_id = _prop_get_connection_stable_id(self, connection, &stable_type); - if (!nm_utils_ipv6_addr_set_stable_privacy(stable_type, - &lladdr, - nm_device_get_iface(self), - stable_id, - priv->linklocal6_dad_counter++, - &error)) { + if (!nm_utils_ipv6_addr_set_stable_privacy_may_fail(stable_type, + &lladdr, + nm_device_get_iface(self), + stable_id, + priv->linklocal6_dad_counter++, + &error)) { _LOGW(LOGD_IP6, "linklocal6: failed to generate an address: %s", error->message); g_clear_error(&error); linklocal6_failed(self); @@ -10348,7 +10393,7 @@ check_and_add_ipv6ll_addr(NMDevice *self) _LOGW(LOGD_IP6, "linklocal6: failed to get interface identifier; IPv6 cannot continue"); return; } - nm_utils_ipv6_addr_set_interface_identifier(&lladdr, iid); + nm_utils_ipv6_addr_set_interface_identifier(&lladdr, &iid); addr_type = "EUI-64"; } @@ -10616,9 +10661,9 @@ _commit_mtu(NMDevice *self, const NMIP4Config *config) _LOGT(LOGD_DEVICE, "mtu: value %u from source '%s' (%u), current source '%s' (%u)%s", (guint) mtu, - nm_device_mtu_source_to_str(source), + nm_device_mtu_source_to_string(source), (guint) source, - nm_device_mtu_source_to_str(priv->mtu_source), + nm_device_mtu_source_to_string(priv->mtu_source), (guint) priv->mtu_source, force ? " (forced)" : ""); } @@ -10801,7 +10846,7 @@ nm_device_commit_mtu(NMDevice *self) } else _LOGT(LOGD_DEVICE, "mtu: commit-mtu... skip due to state %s", - nm_device_state_to_str(state)); + nm_device_state_to_string(state)); } static void @@ -10809,66 +10854,68 @@ ndisc_config_changed(NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int { NMNDiscConfigMap changed = changed_int; NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + int ifindex; guint i; g_return_if_fail(priv->act_request.obj); + ifindex = nm_device_get_ip_ifindex(self); + + if (ifindex <= 0 + || (applied_config_get_current(&priv->ac_ip6_config) + && ifindex + != nm_ip_config_get_ifindex(applied_config_get_current(&priv->ac_ip6_config)))) + applied_config_clear(&priv->ac_ip6_config); + + if (ifindex <= 0) + return; + if (!applied_config_get_current(&priv->ac_ip6_config)) applied_config_init_new(&priv->ac_ip6_config, self, AF_INET6); if (changed & NM_NDISC_CONFIG_ADDRESSES) { - guint8 plen; guint32 ifa_flags; /* Check, whether kernel is recent enough to help user space handling RA. * If it's not supported, we have no ipv6-privacy and must add autoconf * addresses as /128. The reason for the /128 is to prevent the kernel * from adding a prefix route for this address. */ - ifa_flags = 0; - if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) { - ifa_flags |= IFA_F_NOPREFIXROUTE; - if (NM_IN_SET(priv->ndisc_use_tempaddr, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)) - ifa_flags |= IFA_F_MANAGETEMPADDR; - plen = 64; - } else - plen = 128; + ifa_flags = IFA_F_NOPREFIXROUTE; + if (NM_IN_SET(priv->ndisc_use_tempaddr, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR)) + ifa_flags |= IFA_F_MANAGETEMPADDR; nm_ip6_config_reset_addresses_ndisc((NMIP6Config *) priv->ac_ip6_config.orig, rdata->addresses, rdata->addresses_n, - plen, + 64, ifa_flags); if (priv->ac_ip6_config.current) { nm_ip6_config_reset_addresses_ndisc((NMIP6Config *) priv->ac_ip6_config.current, rdata->addresses, rdata->addresses_n, - plen, + 64, ifa_flags); } } if (NM_FLAGS_ANY(changed, NM_NDISC_CONFIG_ROUTES | NM_NDISC_CONFIG_GATEWAYS)) { - nm_ip6_config_reset_routes_ndisc( - (NMIP6Config *) priv->ac_ip6_config.orig, - rdata->gateways, - rdata->gateways_n, - rdata->routes, - rdata->routes_n, - nm_device_get_route_table(self, AF_INET6), - nm_device_get_route_metric(self, AF_INET6), - nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)); + nm_ip6_config_reset_routes_ndisc((NMIP6Config *) priv->ac_ip6_config.orig, + rdata->gateways, + rdata->gateways_n, + rdata->routes, + rdata->routes_n, + nm_device_get_route_table(self, AF_INET6), + nm_device_get_route_metric(self, AF_INET6)); if (priv->ac_ip6_config.current) { - nm_ip6_config_reset_routes_ndisc( - (NMIP6Config *) priv->ac_ip6_config.current, - rdata->gateways, - rdata->gateways_n, - rdata->routes, - rdata->routes_n, - nm_device_get_route_table(self, AF_INET6), - nm_device_get_route_metric(self, AF_INET6), - nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF)); + nm_ip6_config_reset_routes_ndisc((NMIP6Config *) priv->ac_ip6_config.current, + rdata->gateways, + rdata->gateways_n, + rdata->routes, + rdata->routes_n, + nm_device_get_route_table(self, AF_INET6), + nm_device_get_route_metric(self, AF_INET6)); } } @@ -11024,6 +11071,11 @@ addrconf6_start(NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) guint32 ra_timeout; guint32 default_ra_timeout; + if (!g_file_test("/proc/sys/net/ipv6", G_FILE_TEST_IS_DIR)) { + _LOGI(LOGD_IP6, "addrconf6: kernel does not support IPv6"); + return FALSE; + } + connection = nm_device_get_applied_connection(self); g_assert(connection); @@ -11037,17 +11089,17 @@ addrconf6_start(NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) g_assert(s_ip6); if (nm_streq(nm_device_get_effective_ip_config_method(self, AF_INET6), - NM_SETTING_IP4_CONFIG_METHOD_SHARED)) + NM_SETTING_IP6_CONFIG_METHOD_SHARED)) node_type = NM_NDISC_NODE_TYPE_ROUTER; else node_type = NM_NDISC_NODE_TYPE_HOST; - nm_lndp_ndisc_get_sysctl(nm_device_get_platform(self), - nm_device_get_ip_iface(self), - &max_addresses, - &router_solicitations, - &router_solicitation_interval, - &default_ra_timeout); + nm_ndisc_get_sysctl(nm_device_get_platform(self), + nm_device_get_ip_iface(self), + &max_addresses, + &router_solicitations, + &router_solicitation_interval, + &default_ra_timeout); if (node_type == NM_NDISC_NODE_TYPE_ROUTER) ra_timeout = 0u; @@ -11078,15 +11130,6 @@ addrconf6_start(NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) priv->ndisc_use_tempaddr = use_tempaddr; - if (NM_IN_SET(use_tempaddr, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) - && !nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) { - _LOGW(LOGD_IP6, - "The kernel does not support extended IFA_FLAGS needed by NM for " - "IPv6 private addresses. This feature is not available"); - } - /* ensure link local is ready... */ if (!linklocal6_start(self)) { /* wait for the LL address to show up */ @@ -11181,21 +11224,20 @@ set_nm_ipv6ll(NMDevice *self, gboolean enable) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); int ifindex = nm_device_get_ip_ifindex(self); - if (!nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_USER_IPV6LL)) - return; - priv->ipv6ll_handle = enable; if (ifindex > 0) { - const char *detail = enable ? "enable" : "disable"; - int r; + int r; - _LOGD(LOGD_IP6, "will %s userland IPv6LL", detail); - r = nm_platform_link_set_user_ipv6ll_enabled(nm_device_get_platform(self), ifindex, enable); + _LOGD(LOGD_IP6, "will %s userland IPv6LL", enable ? "enable" : "disable"); + r = nm_platform_link_set_inet6_addr_gen_mode(nm_device_get_platform(self), + ifindex, + enable ? NM_IN6_ADDR_GEN_MODE_NONE + : NM_IN6_ADDR_GEN_MODE_EUI64); if (r < 0) { _NMLOG(NM_IN_SET(r, -NME_PL_NOT_FOUND, -NME_PL_OPNOTSUPP) ? LOGL_DEBUG : LOGL_WARN, LOGD_IP6, "failed to %s userspace IPv6LL address handling (%s)", - detail, + enable ? "enable" : "disable", nm_strerror(r)); } @@ -11310,6 +11352,7 @@ act_stage3_ip_config_start(NMDevice * self, nm_connection_get_setting_ip4_config(connection), NM_SETTING_CONNECTION_MDNS_DEFAULT, NM_SETTING_CONNECTION_LLMNR_DEFAULT, + NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT, nm_device_get_route_table(self, AF_INET), nm_device_get_route_metric(self, AF_INET)); configs = g_new0(NMIP4Config *, 2); @@ -11521,45 +11564,6 @@ nm_device_activate_stage3_ip_start(NMDevice *self, int addr_family) return TRUE; } -/* - * activate_stage3_ip_config_start - * - * Begin automatic/manual IP configuration - * - */ -static void -activate_stage3_ip_config_start(NMDevice *self) -{ - int ifindex; - - _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_WAIT); - _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_WAIT); - - _active_connection_set_state_flags(self, NM_ACTIVATION_STATE_FLAG_LAYER2_READY); - - nm_device_state_changed(self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE); - - /* Device should be up before we can do anything with it */ - if ((ifindex = nm_device_get_ip_ifindex(self)) > 0 - && !nm_platform_link_is_up(nm_device_get_platform(self), ifindex)) - _LOGW(LOGD_DEVICE, - "interface %s not up for IP configuration", - nm_device_get_ip_iface(self)); - - if (nm_device_activate_ip4_state_in_wait(self) - && !nm_device_activate_stage3_ip_start(self, AF_INET)) - return; - - if (nm_device_activate_ip6_state_in_wait(self) - && !nm_device_activate_stage3_ip_start(self, AF_INET6)) - return; - - /* Proxy */ - nm_device_set_proxy_config(self, NULL); - - check_ip_state(self, TRUE, TRUE); -} - static void fw_change_zone_cb(NMFirewalldManager * firewalld_manager, NMFirewalldManagerCallId *call_id, @@ -11642,20 +11646,19 @@ fw_change_zone(NMDevice *self) } /* - * nm_device_activate_schedule_stage3_ip_config_start + * activate_stage3_ip_config_start + * + * Begin automatic/manual IP configuration * - * Schedule IP configuration start */ -void -nm_device_activate_schedule_stage3_ip_config_start(NMDevice *self) +static void +activate_stage3_ip_config_start(NMDevice *self) { - NMDevicePrivate *priv; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); int ifindex; - g_return_if_fail(NM_IS_DEVICE(self)); - - priv = NM_DEVICE_GET_PRIVATE(self); g_return_if_fail(priv->act_request.obj); + ifindex = nm_device_get_ip_ifindex(self); /* Add the interface to the specified firewall zone */ @@ -11676,6 +11679,51 @@ nm_device_activate_schedule_stage3_ip_config_start(NMDevice *self) nm_assert(ifindex <= 0 || priv->fw_state == FIREWALL_STATE_INITIALIZED); + _set_ip_state(self, AF_INET, NM_DEVICE_IP_STATE_WAIT); + _set_ip_state(self, AF_INET6, NM_DEVICE_IP_STATE_WAIT); + + _active_connection_set_state_flags(self, NM_ACTIVATION_STATE_FLAG_LAYER2_READY); + + nm_device_state_changed(self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE); + + /* Device should be up before we can do anything with it */ + if (!nm_device_sys_iface_state_is_external(self) + && (ifindex = nm_device_get_ip_ifindex(self)) > 0 + && !nm_platform_link_is_up(nm_device_get_platform(self), ifindex)) + _LOGW(LOGD_DEVICE, + "interface %s not up for IP configuration", + nm_device_get_ip_iface(self)); + + if (nm_device_activate_ip4_state_in_wait(self) + && !nm_device_activate_stage3_ip_start(self, AF_INET)) + return; + + if (nm_device_activate_ip6_state_in_wait(self) + && !nm_device_activate_stage3_ip_start(self, AF_INET6)) + return; + + /* Proxy */ + nm_device_set_proxy_config(self, NULL); + + check_ip_state(self, TRUE, TRUE); +} + +/* + * nm_device_activate_schedule_stage3_ip_config_start + * + * Schedule IP configuration start + */ +void +nm_device_activate_schedule_stage3_ip_config_start(NMDevice *self) +{ + NMDevicePrivate *priv; + + g_return_if_fail(NM_IS_DEVICE(self)); + + priv = NM_DEVICE_GET_PRIVATE(self); + + g_return_if_fail(priv->act_request.obj); + activation_source_schedule(self, activate_stage3_ip_config_start, AF_INET); } @@ -11728,22 +11776,23 @@ activate_stage4_ip_config_timeout_6(NMDevice *self) activate_stage4_ip_config_timeout_x(self, AF_INET6); } +#define activate_stage4_ip_config_timeout_x_fcn(addr_family) \ + (NM_IS_IPv4(addr_family) ? activate_stage4_ip_config_timeout_4 \ + : activate_stage4_ip_config_timeout_6) + void nm_device_activate_schedule_ip_config_timeout(NMDevice *self, int addr_family) { NMDevicePrivate *priv; - const int IS_IPv4 = NM_IS_IPv4(addr_family); g_return_if_fail(NM_IS_DEVICE(self)); - g_return_if_fail(NM_IN_SET(addr_family, AF_INET, AF_INET6)); priv = NM_DEVICE_GET_PRIVATE(self); g_return_if_fail(priv->act_request.obj); activation_source_schedule(self, - IS_IPv4 ? activate_stage4_ip_config_timeout_4 - : activate_stage4_ip_config_timeout_6, + activate_stage4_ip_config_timeout_x_fcn(addr_family), addr_family); } @@ -11963,7 +12012,7 @@ activate_stage5_ip_config_result_x(NMDevice *self, int addr_family) g_return_if_fail(ip_ifindex); if (!nm_platform_link_is_up(nm_device_get_platform(self), ip_ifindex) - && !nm_device_sys_iface_state_is_external_or_assume(self)) { + && !nm_device_sys_iface_state_is_external(self)) { nm_platform_link_change_flags(nm_device_get_platform(self), ip_ifindex, IFF_UP, TRUE); if (!nm_platform_link_is_up(nm_device_get_platform(self), ip_ifindex)) _LOGW(LOGD_DEVICE, @@ -11986,7 +12035,7 @@ activate_stage5_ip_config_result_x(NMDevice *self, int addr_family) /* If IPv6 wasn't the first IP to complete, and DHCP was used, * then ensure dispatcher scripts get the DHCP lease information. */ - nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP6_CHANGE, + nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP_CHANGE_6, self, NULL, NULL, @@ -12052,7 +12101,7 @@ activate_stage5_ip_config_result_x(NMDevice *self, int addr_family) */ if (priv->dhcp_data_4.client && nm_device_activate_ip4_state_in_conf(self) && (nm_device_get_state(self) > NM_DEVICE_STATE_IP_CONFIG)) { - nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP4_CHANGE, + nm_dispatcher_call_device(NM_DISPATCHER_ACTION_DHCP_CHANGE_4, self, NULL, NULL, @@ -12425,7 +12474,7 @@ _nm_device_hash_check_invalid_keys(GHashTable * hash, g_hash_table_iter_init(&iter, hash); while (g_hash_table_iter_next(&iter, (gpointer *) &k, NULL)) { - if (nm_utils_strv_find_first((char **) whitelist, -1, k) < 0) { + if (nm_strv_find_first(whitelist, -1, k) < 0) { first_invalid_key = k; break; } @@ -12490,6 +12539,7 @@ nm_device_reactivate_ip_config(NMDevice * self, s_ip_new, _prop_get_connection_mdns(self), _prop_get_connection_llmnr(self), + _prop_get_connection_dns_over_tls(self), nm_device_get_route_table(self, AF_INET), nm_device_get_route_metric(self, AF_INET)); } else { @@ -12623,7 +12673,8 @@ can_reapply_change(NMDevice * self, NM_SETTING_CONNECTION_METERED, NM_SETTING_CONNECTION_LLDP, NM_SETTING_CONNECTION_MDNS, - NM_SETTING_CONNECTION_LLMNR); + NM_SETTING_CONNECTION_LLMNR, + NM_SETTING_CONNECTION_DNS_OVER_TLS); } if (NM_IN_STRSET(setting_name, @@ -12912,12 +12963,12 @@ reapply_cb(NMDevice * self, audit_args, subject, local->message); - g_dbus_method_invocation_take_error(context, local); - local = NULL; - } else { - nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY, self, TRUE, audit_args, subject, NULL); - g_dbus_method_invocation_return_value(context, NULL); + g_dbus_method_invocation_take_error(context, g_steal_pointer(&local)); + return; } + + nm_audit_log_device_op(NM_AUDIT_OP_DEVICE_REAPPLY, self, TRUE, audit_args, subject, NULL); + g_dbus_method_invocation_return_value(context, NULL); } static void @@ -14737,15 +14788,15 @@ _unmanaged_flags2str(NMUnmanagedFlags flags, NMUnmanagedFlags mask, char *buf, g tmp = buf2; while (TRUE) { if (add_separator) - nm_utils_strbuf_append_c(&b, &len, ','); + nm_strbuf_append_c(&b, &len, ','); add_separator = TRUE; tmp2 = strchr(tmp, ','); if (tmp2) tmp2[0] = '\0'; - nm_utils_strbuf_append_c(&b, &len, '!'); - nm_utils_strbuf_append_str(&b, &len, tmp); + nm_strbuf_append_c(&b, &len, '!'); + nm_strbuf_append_str(&b, &len, tmp); if (!tmp2) break; @@ -14950,7 +15001,7 @@ _set_unmanaged_flags(NMDevice * self, priv->queued_ip_config_id_4 = g_idle_add(queued_ip4_config_change, self); priv->queued_ip_config_id_6 = g_idle_add(queued_ip6_config_change, self); - if (!priv->pending_actions) { + if (priv->pending_actions.len == 0) { do_notify_has_pending_actions = TRUE; had_pending_actions = nm_device_has_pending_action(self); } @@ -15004,7 +15055,7 @@ _set_unmanaged_flags(NMDevice * self, flags, NM_PRINT_FMT_QUOTED(allow_state_transition, ", reason ", - nm_device_state_reason_to_str_a(reason), + nm_device_state_reason_to_string_a(reason), transition_state ? ", transition-state" : "", "")); @@ -15744,37 +15795,39 @@ gboolean nm_device_add_pending_action(NMDevice *self, const char *action, gboolean assert_not_yet_pending) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - GSList * iter; - guint count = 0; + gssize idx; g_return_val_if_fail(action, FALSE); - /* Check if the action is already pending. Cannot add duplicate actions */ - for (iter = priv->pending_actions; iter; iter = iter->next) { - if (nm_streq(action, iter->data)) { - if (assert_not_yet_pending) { - _LOGW(LOGD_DEVICE, - "add_pending_action (%d): '%s' already pending", - count + g_slist_length(iter), - action); - g_return_val_if_reached(FALSE); - } else { - _LOGT(LOGD_DEVICE, - "add_pending_action (%d): '%s' already pending (expected)", - count + g_slist_length(iter), - action); - } - return FALSE; + idx = nm_strv_find_binary_search(priv->pending_actions.arr, priv->pending_actions.len, action); + if (idx >= 0) { + if (assert_not_yet_pending) { + _LOGW(LOGD_DEVICE, + "add_pending_action (%u): '%s' already pending", + priv->pending_actions.len, + action); + g_return_val_if_reached(FALSE); + } else { + _LOGT(LOGD_DEVICE, + "add_pending_action (%u): '%s' already pending (expected)", + priv->pending_actions.len, + action); } - count++; + return FALSE; } - priv->pending_actions = g_slist_prepend(priv->pending_actions, (char *) action); - count++; + if (priv->pending_actions.len == priv->pending_actions.alloc) { + nm_assert(priv->pending_actions.alloc < G_MAXUINT / 2u); + priv->pending_actions.alloc = NM_MAX(priv->pending_actions.alloc * 2u, 4u); + priv->pending_actions.arr = + g_renew(const char *, priv->pending_actions.arr, priv->pending_actions.alloc); + } + nm_arr_insert_at(priv->pending_actions.arr, priv->pending_actions.len, ~idx, action); + priv->pending_actions.len++; - _LOGD(LOGD_DEVICE, "add_pending_action (%d): '%s'", count, action); + _LOGD(LOGD_DEVICE, "add_pending_action (%u): '%s'", priv->pending_actions.len, action); - if (count == 1) + if (priv->pending_actions.len == 1) _notify(self, PROP_HAS_PENDING_ACTION); return TRUE; @@ -15796,37 +15849,38 @@ gboolean nm_device_remove_pending_action(NMDevice *self, const char *action, gboolean assert_is_pending) { NMDevicePrivate *priv; - GSList * iter, *next; - guint count = 0; + gssize idx; g_return_val_if_fail(self, FALSE); g_return_val_if_fail(action, FALSE); priv = NM_DEVICE_GET_PRIVATE(self); - for (iter = priv->pending_actions; iter; iter = next) { - next = iter->next; - if (nm_streq(action, iter->data)) { - _LOGD(LOGD_DEVICE, - "remove_pending_action (%d): '%s'", - count + g_slist_length(iter->next), /* length excluding 'iter' */ - action); - priv->pending_actions = g_slist_delete_link(priv->pending_actions, iter); - if (priv->pending_actions == NULL) - _notify(self, PROP_HAS_PENDING_ACTION); - return TRUE; - } - count++; + idx = nm_strv_find_binary_search(priv->pending_actions.arr, priv->pending_actions.len, action); + if (idx >= 0) { + _LOGD(LOGD_DEVICE, + "remove_pending_action (%u): '%s'", + priv->pending_actions.len - 1u, + action); + nm_arr_remove_at(priv->pending_actions.arr, priv->pending_actions.len, idx); + priv->pending_actions.len--; + if (priv->pending_actions.len == 0) + _notify(self, PROP_HAS_PENDING_ACTION); + return TRUE; } if (assert_is_pending) { - _LOGW(LOGD_DEVICE, "remove_pending_action (%d): '%s' not pending", count, action); + _LOGW(LOGD_DEVICE, + "remove_pending_action (%u): '%s' not pending", + priv->pending_actions.len, + action); g_return_val_if_reached(FALSE); - } else + } else { _LOGT(LOGD_DEVICE, - "remove_pending_action (%d): '%s' not pending (expected)", - count, + "remove_pending_action (%u): '%s' not pending (expected)", + priv->pending_actions.len, action); + } return FALSE; } @@ -15836,15 +15890,15 @@ nm_device_has_pending_action_reason(NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - if (priv->pending_actions) { - if (!priv->pending_actions->next && nm_device_get_state(self) == NM_DEVICE_STATE_ACTIVATED - && nm_streq(priv->pending_actions->data, NM_PENDING_ACTION_CARRIER_WAIT)) { + if (priv->pending_actions.len > 0) { + if (priv->pending_actions.len == 1 && nm_device_get_state(self) == NM_DEVICE_STATE_ACTIVATED + && nm_streq(priv->pending_actions.arr[0], NM_PENDING_ACTION_CARRIER_WAIT)) { /* if the device is already in activated state, and the only reason * why it appears still busy is "carrier-wait", then we are already complete. */ return NULL; } - return priv->pending_actions->data; + return priv->pending_actions.arr[0]; } if (nm_device_is_real(self) @@ -16014,7 +16068,7 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu else _LOGD(LOGD_DEVICE, "deactivating device (reason '%s') [%d]", - nm_device_state_reason_to_str_a(reason), + nm_device_state_reason_to_string_a(reason), reason); /* Save whether or not we tried IPv6 for later */ @@ -16045,15 +16099,16 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu nm_platform_ip_route_flush(platform, AF_UNSPEC, ifindex); nm_platform_ip_address_flush(platform, AF_UNSPEC, ifindex); - set_ipv6_token(self, iid, "::"); + set_ipv6_token(self, &iid, "::"); if (nm_device_get_applied_setting(self, NM_TYPE_SETTING_TC_CONFIG)) { - nm_platform_tfilter_sync(platform, ifindex, NULL); - nm_platform_qdisc_sync(platform, ifindex, NULL); + nm_platform_tc_sync(platform, ifindex, NULL, NULL); } } } + priv->tc_committed = FALSE; + _routing_rules_sync(self, cleanup_type == CLEANUP_TYPE_KEEP ? NM_TERNARY_DEFAULT : NM_TERNARY_FALSE); @@ -16508,20 +16563,20 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, && (state != NM_DEVICE_STATE_UNAVAILABLE || !priv->firmware_missing)) { _LOGD(LOGD_DEVICE, "state change: %s -> %s (reason '%s', sys-iface-state: '%s'%s)", - nm_device_state_to_str(old_state), - nm_device_state_to_str(state), - nm_device_state_reason_to_str_a(reason), - nm_device_sys_iface_state_to_str(priv->sys_iface_state), + nm_device_state_to_string(old_state), + nm_device_state_to_string(state), + nm_device_state_reason_to_string_a(reason), + nm_device_sys_iface_state_to_string(priv->sys_iface_state), priv->firmware_missing ? ", missing firmware" : ""); return; } _LOGI(LOGD_DEVICE, "state change: %s -> %s (reason '%s', sys-iface-state: '%s')", - nm_device_state_to_str(old_state), - nm_device_state_to_str(state), - nm_device_state_reason_to_str_a(reason), - nm_device_sys_iface_state_to_str(priv->sys_iface_state)); + nm_device_state_to_string(old_state), + nm_device_state_to_string(state), + nm_device_state_reason_to_string_a(reason), + nm_device_sys_iface_state_to_string(priv->sys_iface_state)); /* in order to prevent triggering any callback caused * by the device not having any pending action anymore @@ -16866,8 +16921,8 @@ queued_state_set(gpointer user_data) _LOGD(LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", - nm_device_state_to_str(priv->queued_state.state), - nm_device_state_reason_to_str_a(priv->queued_state.reason), + nm_device_state_to_string(priv->queued_state.state), + nm_device_state_reason_to_string_a(priv->queued_state.reason), priv->queued_state.id, "change state"); @@ -16879,7 +16934,7 @@ queued_state_set(gpointer user_data) new_reason = priv->queued_state.reason; nm_device_state_changed(self, new_state, new_reason); - nm_device_remove_pending_action(self, nm_device_state_queued_state_to_str(new_state), TRUE); + nm_device_remove_pending_action(self, nm_device_state_queued_state_to_string(new_state), TRUE); return G_SOURCE_REMOVE; } @@ -16896,13 +16951,13 @@ nm_device_queue_state(NMDevice *self, NMDeviceState state, NMDeviceStateReason r if (priv->queued_state.id && priv->queued_state.state == state) { _LOGD(LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s%s%s%s", - nm_device_state_to_str(priv->queued_state.state), - nm_device_state_reason_to_str_a(priv->queued_state.reason), + nm_device_state_to_string(priv->queued_state.state), + nm_device_state_reason_to_string_a(priv->queued_state.reason), priv->queued_state.id, "ignore queuing same state change", NM_PRINT_FMT_QUOTED(priv->queued_state.reason != reason, " (reason differs: ", - nm_device_state_reason_to_str_a(reason), + nm_device_state_reason_to_string_a(reason), ")", "")); return; @@ -16910,20 +16965,20 @@ nm_device_queue_state(NMDevice *self, NMDeviceState state, NMDeviceStateReason r /* Add pending action for the new state before clearing the queued states, so * that we don't accidentally pop all pending states and reach 'startup complete' */ - nm_device_add_pending_action(self, nm_device_state_queued_state_to_str(state), TRUE); + nm_device_add_pending_action(self, nm_device_state_queued_state_to_string(state), TRUE); /* We should only ever have one delayed state transition at a time */ if (priv->queued_state.id) { _LOGW(LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", - nm_device_state_to_str(priv->queued_state.state), - nm_device_state_reason_to_str_a(priv->queued_state.reason), + nm_device_state_to_string(priv->queued_state.state), + nm_device_state_reason_to_string_a(priv->queued_state.reason), priv->queued_state.id, "replace previously queued state change"); nm_clear_g_source(&priv->queued_state.id); nm_device_remove_pending_action( self, - nm_device_state_queued_state_to_str(priv->queued_state.state), + nm_device_state_queued_state_to_string(priv->queued_state.state), TRUE); } @@ -16933,8 +16988,8 @@ nm_device_queue_state(NMDevice *self, NMDeviceState state, NMDeviceStateReason r _LOGD(LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", - nm_device_state_to_str(state), - nm_device_state_reason_to_str_a(reason), + nm_device_state_to_string(state), + nm_device_state_reason_to_string_a(reason), priv->queued_state.id, "queue state change"); } @@ -16949,14 +17004,15 @@ queued_state_clear(NMDevice *self) _LOGD(LOGD_DEVICE, "queue-state[%s, reason:%s, id:%u]: %s", - nm_device_state_to_str(priv->queued_state.state), - nm_device_state_reason_to_str_a(priv->queued_state.reason), + nm_device_state_to_string(priv->queued_state.state), + nm_device_state_reason_to_string_a(priv->queued_state.reason), priv->queued_state.id, "clear queued state change"); nm_clear_g_source(&priv->queued_state.id); - nm_device_remove_pending_action(self, - nm_device_state_queued_state_to_str(priv->queued_state.state), - TRUE); + nm_device_remove_pending_action( + self, + nm_device_state_queued_state_to_string(priv->queued_state.state), + TRUE); } NMDeviceState @@ -17069,11 +17125,11 @@ 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; const NMConfigDeviceStateData *dev_state; + NMPLinkAddress cached_hw_addr_perm; if (priv->hw_addr_perm) { /* the permanent hardware address is only read once and not @@ -17112,11 +17168,13 @@ nm_device_update_permanent_hw_address(NMDevice *self, gboolean force_freeze) return; } - success_read = - nm_platform_link_get_permanent_address(nm_device_get_platform(self), ifindex, buf, &len); - if (success_read && priv->hw_addr_len == len) { + success_read = nm_platform_link_get_permanent_address(nm_device_get_platform(self), + pllink, + &cached_hw_addr_perm); + if (success_read && priv->hw_addr_len == cached_hw_addr_perm.len) { priv->hw_addr_perm_fake = FALSE; - priv->hw_addr_perm = nm_utils_hwaddr_ntoa(buf, len); + priv->hw_addr_perm = + nm_utils_hwaddr_ntoa(cached_hw_addr_perm.data, cached_hw_addr_perm.len); _LOGD(LOGD_DEVICE, "hw-addr: read permanent MAC address '%s'", priv->hw_addr_perm); goto notify_and_out; } @@ -17791,7 +17849,7 @@ hostname_dns_lookup_callback(GObject *source, GAsyncResult *result, gpointer use gboolean valid; resolver->hostname = g_steal_pointer(&output); - valid = nm_hostname_manager_validate_hostname(resolver->hostname); + valid = nm_utils_validate_hostname(resolver->hostname); _LOGD(LOGD_DNS, "hostname-from-dns: lookup done for %s, result %s%s%s%s", @@ -17800,7 +17858,7 @@ hostname_dns_lookup_callback(GObject *source, GAsyncResult *result, gpointer use valid ? "" : " (invalid)"); if (!valid) - g_clear_pointer(&resolver->hostname, g_free); + nm_clear_g_free(&resolver->hostname); } nm_clear_g_cancellable(&resolver->cancellable); @@ -18022,6 +18080,37 @@ _activation_func_to_string(ActivationHandleFunc func) g_return_val_if_reached("unknown"); } +static GVariant * +_device_get_ports_variant(NMDevice *device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(device); + SlaveInfo * info; + GVariantBuilder builder; + gboolean any = FALSE; + + if (priv->ports_variant) + return priv->ports_variant; + + c_list_for_each_entry (info, &priv->slaves, lst_slave) { + const char *path; + + if (!NM_DEVICE_GET_PRIVATE(info->slave)->is_enslaved) + continue; + path = nm_dbus_object_get_path(NM_DBUS_OBJECT(info->slave)); + if (!path) + continue; + if (!any) { + any = TRUE; + g_variant_builder_init(&builder, G_VARIANT_TYPE("ao")); + } + g_variant_builder_add(&builder, "o", path); + } + priv->ports_variant = any ? g_variant_ref_sink(g_variant_builder_end(&builder)) + : g_variant_ref(nm_g_variant_singleton_ao()); + + return priv->ports_variant; +} + /*****************************************************************************/ static void @@ -18188,29 +18277,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) g_value_set_boolean(value, nm_device_is_real(self)); break; case PROP_SLAVES: - { - CList *slave_iter; - char **slave_list; - gsize i, n; - - n = c_list_length(&priv->slaves); - slave_list = g_new(char *, n + 1); - i = 0; - c_list_for_each (slave_iter, &priv->slaves) { - SlaveInfo * info = c_list_entry(slave_iter, SlaveInfo, lst_slave); - const char *path; - - if (!NM_DEVICE_GET_PRIVATE(info->slave)->is_enslaved) - continue; - path = nm_dbus_object_get_path(NM_DBUS_OBJECT(info->slave)); - if (path) - slave_list[i++] = g_strdup(path); - } - nm_assert(i <= n); - slave_list[i] = NULL; - g_value_take_boxed(value, slave_list); + case PROP_PORTS: + g_value_set_variant(value, _device_get_ports_variant(self)); break; - } case PROP_STATISTICS_REFRESH_RATE_MS: g_value_set_uint(value, priv->stats.refresh_rate_ms); break; @@ -18518,7 +18587,7 @@ dispose(GObject *object) nm_clear_g_source(&priv->check_delete_unrealized_id); - nm_clear_g_source(&priv->stats.timeout_id); + nm_clear_g_source_inst(&priv->stats.timeout_source); carrier_disconnected_action_cancel(self); @@ -18573,7 +18642,7 @@ finalize(GObject *object) g_free(priv->hw_addr); g_free(priv->hw_addr_perm); g_free(priv->hw_addr_initial); - g_slist_free(priv->pending_actions); + g_free(priv->pending_actions.arr); g_slist_free_full(priv->dad6_failed_addrs, (GDestroyNotify) nmp_object_unref); nm_clear_g_free(&priv->physical_port_id); g_free(priv->udi); @@ -18592,6 +18661,8 @@ finalize(GObject *object) nm_dbus_track_obj_path_deinit(&priv->parent_device); nm_dbus_track_obj_path_deinit(&priv->act_request); + nm_g_variant_unref(priv->ports_variant); + G_OBJECT_CLASS(nm_device_parent_class)->finalize(object); /* for testing, NMDeviceTest does not invoke NMDevice::constructed, @@ -18710,9 +18781,8 @@ static const NMDBusInterfaceInfoExtended interface_info_device = { NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("InterfaceFlags", "u", NM_DEVICE_INTERFACE_FLAGS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", - "s", - NM_DEVICE_HW_ADDRESS), ), ), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("HwAddress", "s", NM_DEVICE_HW_ADDRESS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ports", "ao", NM_DEVICE_PORTS), ), ), }; static const NMDBusInterfaceInfoExtended interface_info_device_statistics = { @@ -19007,11 +19077,18 @@ nm_device_class_init(NMDeviceClass *klass) "", FALSE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_SLAVES] = g_param_spec_boxed(NM_DEVICE_SLAVES, - "", - "", - G_TYPE_STRV, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_SLAVES] = g_param_spec_variant(NM_DEVICE_SLAVES, + "", + "", + G_VARIANT_TYPE("ao"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_PORTS] = g_param_spec_variant(NM_DEVICE_PORTS, + "", + "", + G_VARIANT_TYPE("ao"), + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); obj_properties[PROP_STATISTICS_REFRESH_RATE_MS] = g_param_spec_uint(NM_DEVICE_STATISTICS_REFRESH_RATE_MS, @@ -19113,16 +19190,17 @@ nm_device_class_init(NMDeviceClass *klass) G_TYPE_OBJECT, G_TYPE_OBJECT); - signals[IP6_PREFIX_DELEGATED] = g_signal_new(NM_DEVICE_IP6_PREFIX_DELEGATED, - G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, - 0, - NULL, - NULL, - NULL, - G_TYPE_NONE, - 1, - G_TYPE_POINTER); + signals[IP6_PREFIX_DELEGATED] = + g_signal_new(NM_DEVICE_IP6_PREFIX_DELEGATED, + G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, + 0, + NULL, + NULL, + NULL, + G_TYPE_NONE, + 1, + G_TYPE_POINTER /* const NMPlatformIP6Address *prefix */); signals[IP6_SUBNET_NEEDED] = g_signal_new(NM_DEVICE_IP6_SUBNET_NEEDED, G_OBJECT_CLASS_TYPE(object_class), diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h index f59b6fa8..d967bcb2 100644 --- a/src/core/devices/nm-device.h +++ b/src/core/devices/nm-device.h @@ -45,6 +45,7 @@ #define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id" #define NM_DEVICE_MTU "mtu" #define NM_DEVICE_HW_ADDRESS "hw-address" +#define NM_DEVICE_PORTS "ports" /* "perm-hw-address" is exposed on D-Bus both for NMDeviceEthernet * and NMDeviceWifi. */ diff --git a/src/core/devices/nm-lldp-listener.c b/src/core/devices/nm-lldp-listener.c index aba972ae..4e178491 100644 --- a/src/core/devices/nm-lldp-listener.c +++ b/src/core/devices/nm-lldp-listener.c @@ -32,7 +32,7 @@ /*****************************************************************************/ struct _NMLldpListener { - sd_lldp * lldp_handle; + sd_lldp_rx *lldp_handle; GHashTable *lldp_neighbors; GVariant * variant; @@ -711,9 +711,9 @@ lldp_neighbor_to_variant(LldpNeighbor *neigh) g_variant_new_uint32(unaligned_read_be16(data8)); break; } - } else if (memcmp(oui, SD_LLDP_OUI_MUD, sizeof(oui)) == 0) { + } else if (memcmp(oui, SD_LLDP_OUI_IANA, sizeof(oui)) == 0) { switch (subtype) { - case SD_LLDP_OUI_SUBTYPE_MUD_USAGE_DESCRIPTION: + case SD_LLDP_OUI_IANA_SUBTYPE_MUD: if (!v_mud_url) { gs_free char *s_free = NULL; const char * s; @@ -884,12 +884,14 @@ handle_changed: } static void -lldp_event_handler(sd_lldp *lldp, sd_lldp_event_t event, sd_lldp_neighbor *n, void *userdata) +lldp_event_handler(sd_lldp_rx *lldp, sd_lldp_rx_event_t event, sd_lldp_neighbor *n, void *userdata) { - process_lldp_neighbor( - userdata, - n, - !NM_IN_SET(event, SD_LLDP_EVENT_ADDED, SD_LLDP_EVENT_UPDATED, SD_LLDP_EVENT_REFRESHED)); + process_lldp_neighbor(userdata, + n, + !NM_IN_SET(event, + SD_LLDP_RX_EVENT_ADDED, + SD_LLDP_RX_EVENT_UPDATED, + SD_LLDP_RX_EVENT_REFRESHED)); } /*****************************************************************************/ @@ -934,14 +936,14 @@ nm_lldp_listener_new(int ifindex, GError ** error) { NMLldpListener *self = NULL; - sd_lldp * lldp_handle; + sd_lldp_rx * lldp_handle; int r; g_return_val_if_fail(ifindex > 0, FALSE); g_return_val_if_fail(!error || !*error, FALSE); g_return_val_if_fail(notify_callback, FALSE); - r = sd_lldp_new(&lldp_handle); + r = sd_lldp_rx_new(&lldp_handle); if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, @@ -950,7 +952,7 @@ nm_lldp_listener_new(int ifindex, return FALSE; } - r = sd_lldp_set_ifindex(lldp_handle, ifindex); + r = sd_lldp_rx_set_ifindex(lldp_handle, ifindex); if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, @@ -959,7 +961,7 @@ nm_lldp_listener_new(int ifindex, goto fail_handle; } - r = sd_lldp_set_neighbors_max(lldp_handle, MAX_NEIGHBORS); + r = sd_lldp_rx_set_neighbors_max(lldp_handle, MAX_NEIGHBORS); nm_assert(r == 0); self = g_slice_new(NMLldpListener); @@ -969,19 +971,19 @@ nm_lldp_listener_new(int ifindex, .notify_user_data = notify_user_data, }; - r = sd_lldp_set_callback(lldp_handle, lldp_event_handler, self); + r = sd_lldp_rx_set_callback(lldp_handle, lldp_event_handler, self); if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "set callback failed"); goto fail_handle; } - r = sd_lldp_attach_event(lldp_handle, NULL, 0); + r = sd_lldp_rx_attach_event(lldp_handle, NULL, 0); if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "attach event failed"); goto fail_attached; } - r = sd_lldp_start(lldp_handle); + r = sd_lldp_rx_start(lldp_handle); if (r < 0) { g_set_error_literal(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED, "start failed"); goto fail_attached; @@ -997,11 +999,11 @@ nm_lldp_listener_new(int ifindex, return self; fail_attached: - sd_lldp_detach_event(lldp_handle); + sd_lldp_rx_detach_event(lldp_handle); fail_handle: if (self) nm_g_slice_free(self); - sd_lldp_unref(lldp_handle); + sd_lldp_rx_unref(lldp_handle); return NULL; } @@ -1010,9 +1012,9 @@ nm_lldp_listener_destroy(NMLldpListener *self) { g_return_if_fail(self); - sd_lldp_stop(self->lldp_handle); - sd_lldp_detach_event(self->lldp_handle); - sd_lldp_unref(self->lldp_handle); + sd_lldp_rx_stop(self->lldp_handle); + sd_lldp_rx_detach_event(self->lldp_handle); + sd_lldp_rx_unref(self->lldp_handle); nm_clear_g_source_inst(&self->ratelimit_source); diff --git a/src/core/devices/ovs/nm-ovsdb.c b/src/core/devices/ovs/nm-ovsdb.c index b8d5311a..e5673347 100644 --- a/src/core/devices/ovs/nm-ovsdb.c +++ b/src/core/devices/ovs/nm-ovsdb.c @@ -17,6 +17,7 @@ #include "devices/nm-device.h" #include "nm-manager.h" #include "nm-setting-ovs-external-ids.h" +#include "nm-priv-helper-call.h" /*****************************************************************************/ @@ -25,7 +26,7 @@ /*****************************************************************************/ #if JANSSON_VERSION_HEX < 0x020400 - #warning "requires at least libjansson 2.4" +#warning "requires at least libjansson 2.4" #endif typedef struct { @@ -118,9 +119,8 @@ enum { static guint signals[LAST_SIGNAL] = {0}; typedef struct { - GSocketClient * client; GSocketConnection *conn; - GCancellable * cancellable; + GCancellable * conn_cancellable; char buf[4096]; /* Input buffer */ size_t bufp; /* Last decoded byte in the input buffer. */ GString * input; /* JSON stream waiting for decoding. */ @@ -753,6 +753,7 @@ _insert_interface(json_t * params, NMSettingOvsInterface *s_ovs_iface; NMSettingOvsDpdk * s_ovs_dpdk; NMSettingOvsPatch * s_ovs_patch; + const char * dpdk_devargs; json_t * options = json_array(); json_t * row; guint32 mtu = 0; @@ -777,9 +778,11 @@ _insert_interface(json_t * params, s_ovs_patch = nm_connection_get_setting_ovs_patch(interface); if (s_ovs_dpdk) { - json_array_append_new( - options, - json_pack("[[s, s]]", "dpdk-devargs", nm_setting_ovs_dpdk_get_devargs(s_ovs_dpdk))); + dpdk_devargs = nm_setting_ovs_dpdk_get_devargs(s_ovs_dpdk); + if (dpdk_devargs) + json_array_append_new(options, json_pack("[[s, s]]", "dpdk-devargs", dpdk_devargs)); + else + json_array_append_new(options, json_array()); } else if (s_ovs_patch) { json_array_append_new( options, @@ -1595,7 +1598,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) iter = json_object_iter(ovs); s = json_object_iter_key(iter); if (s) - nm_utils_strdup_reset(&priv->db_uuid, s); + nm_strdup_reset(&priv->db_uuid, s); } json_object_foreach (interface, key, value) { @@ -1665,8 +1668,8 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) nm_assert(nm_streq0(ovs_interface->name, name)); - changed |= nm_utils_strdup_reset(&ovs_interface->type, type); - changed |= nm_utils_strdup_reset(&ovs_interface->connection_uuid, connection_uuid); + changed |= nm_strdup_reset(&ovs_interface->type, type); + changed |= nm_strdup_reset(&ovs_interface->connection_uuid, connection_uuid); if (!_external_ids_equal(ovs_interface->external_ids, external_ids_arr)) { NM_SWAP(&ovs_interface->external_ids, &external_ids_arr); changed = TRUE; @@ -1776,8 +1779,8 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) nm_assert(nm_streq0(ovs_port->name, name)); - changed |= nm_utils_strdup_reset(&ovs_port->name, name); - changed |= nm_utils_strdup_reset(&ovs_port->connection_uuid, connection_uuid); + changed |= nm_strdup_reset(&ovs_port->name, name); + changed |= nm_strdup_reset(&ovs_port->connection_uuid, connection_uuid); if (nm_strv_ptrarray_cmp(ovs_port->interfaces, interfaces) != 0) { NM_SWAP(&ovs_port->interfaces, &interfaces); changed = TRUE; @@ -1881,8 +1884,8 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg) nm_assert(nm_streq0(ovs_bridge->name, name)); - changed = nm_utils_strdup_reset(&ovs_bridge->name, name); - changed = nm_utils_strdup_reset(&ovs_bridge->connection_uuid, connection_uuid); + changed = nm_strdup_reset(&ovs_bridge->name, name); + changed = nm_strdup_reset(&ovs_bridge->connection_uuid, connection_uuid); if (nm_strv_ptrarray_cmp(ovs_bridge->ports, ports) != 0) { NM_SWAP(&ovs_bridge->ports, &ports); changed = TRUE; @@ -2223,7 +2226,7 @@ ovsdb_disconnect(NMOvsdb *self, gboolean retry, gboolean is_disposing) nm_assert(!retry || !is_disposing); - if (!priv->client) + if (!priv->conn && !priv->conn_cancellable) return; _LOGD("disconnecting from ovsdb, retry %d", retry); @@ -2250,10 +2253,9 @@ ovsdb_disconnect(NMOvsdb *self, gboolean retry, gboolean is_disposing) priv->bufp = 0; g_string_truncate(priv->input, 0); g_string_truncate(priv->output, 0); - g_clear_object(&priv->client); g_clear_object(&priv->conn); nm_clear_g_free(&priv->db_uuid); - nm_clear_g_cancellable(&priv->cancellable); + nm_clear_g_cancellable(&priv->conn_cancellable); if (retry) ovsdb_try_connect(self); @@ -2348,32 +2350,82 @@ _monitor_bridges_cb(NMOvsdb *self, json_t *result, GError *error, gpointer user_ } static void -_client_connect_cb(GObject *source_object, GAsyncResult *res, gpointer user_data) +_ovsdb_connect_complete_with_fd(NMOvsdb *self, int fd_take) { - GSocketClient * client = G_SOCKET_CLIENT(source_object); - NMOvsdb * self = NM_OVSDB(user_data); - NMOvsdbPrivate * priv; - GError * error = NULL; - GSocketConnection *conn; - - conn = g_socket_client_connect_finish(client, res, &error); - if (conn == NULL) { - if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - _LOGI("%s", error->message); + NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); + gs_unref_object GSocket *socket = NULL; + gs_free_error GError *error = NULL; + socket = g_socket_new_from_fd(nm_steal_fd(&fd_take), &error); + if (!socket) { + _LOGT("connect: failure to open socket for new FD: %s", error->message); ovsdb_disconnect(self, FALSE, FALSE); - g_clear_error(&error); return; } - priv = NM_OVSDB_GET_PRIVATE(self); - priv->conn = conn; - g_clear_object(&priv->cancellable); + priv->conn = g_socket_connection_factory_create_connection(socket); + g_clear_object(&priv->conn_cancellable); ovsdb_read(self); ovsdb_next_command(self); } +static void +_ovsdb_connect_priv_helper_cb(int fd_take, GError *error, gpointer user_data) +{ + nm_auto_close int fd = fd_take; + NMOvsdb * self; + + if (nm_utils_error_is_cancelled(error)) + return; + + self = user_data; + + if (error) { + _LOGT("connect: failure to get FD from nm-priv-helper: %s", error->message); + ovsdb_disconnect(self, FALSE, FALSE); + return; + } + + _LOGT("connect: connected successfully with FD from nm-priv-helper"); + _ovsdb_connect_complete_with_fd(self, nm_steal_fd(&fd)); +} + +static void +_ovsdb_connect_idle(gpointer user_data, GCancellable *cancellable) +{ + NMOvsdb * self; + NMOvsdbPrivate * priv; + nm_auto_close int fd = -1; + gs_free_error GError *error = NULL; + + if (g_cancellable_is_cancelled(cancellable)) + return; + + self = user_data; + priv = NM_OVSDB_GET_PRIVATE(self); + + fd = nm_priv_helper_utils_open_fd(NM_PRIV_HELPER_GET_FD_TYPE_OVSDB_SOCKET, &error); + if (fd == -ENOENT) { + _LOGT("connect: opening %s failed (\"%s\")", NM_OVSDB_SOCKET, error->message); + ovsdb_disconnect(self, FALSE, FALSE); + return; + } + if (fd < 0) { + _LOGT("connect: opening %s failed (\"%s\"). Retry with nm-priv-helper", + NM_OVSDB_SOCKET, + error->message); + nm_priv_helper_call_get_fd(NM_PRIV_HELPER_GET_FD_TYPE_OVSDB_SOCKET, + priv->conn_cancellable, + _ovsdb_connect_priv_helper_cb, + self); + return; + } + + _LOGT("connect: opening %s succeeded", NM_OVSDB_SOCKET); + _ovsdb_connect_complete_with_fd(self, nm_steal_fd(&fd)); +} + /** * ovsdb_try_connect: * @@ -2385,22 +2437,13 @@ static void ovsdb_try_connect(NMOvsdb *self) { NMOvsdbPrivate *priv = NM_OVSDB_GET_PRIVATE(self); - GSocketAddress *addr; - if (priv->client) + if (priv->conn || priv->conn_cancellable) return; - /* TODO: This should probably be made configurable via NetworkManager.conf */ - addr = g_unix_socket_address_new(RUNSTATEDIR "/openvswitch/db.sock"); - - priv->client = g_socket_client_new(); - priv->cancellable = g_cancellable_new(); - g_socket_client_connect_async(priv->client, - G_SOCKET_CONNECTABLE(addr), - priv->cancellable, - _client_connect_cb, - self); - g_object_unref(addr); + _LOGT("connect: start connecting socket %s on idle", NM_OVSDB_SOCKET); + priv->conn_cancellable = g_cancellable_new(); + nm_utils_invoke_on_idle(priv->conn_cancellable, _ovsdb_connect_idle, self); /* Queue a monitor call before any other command, ensuring that we have an up * to date view of existing bridged that we need for add and remove ops. */ @@ -2534,12 +2577,10 @@ nm_ovsdb_set_external_ids(NMOvsdb * self, gs_unref_hashtable GHashTable *exid_old = NULL; gs_unref_hashtable GHashTable *exid_new = NULL; - exid_old = s_exid_old - ? nm_utils_strdict_clone(_nm_setting_ovs_external_ids_get_data(s_exid_old)) - : NULL; - exid_new = s_exid_new - ? nm_utils_strdict_clone(_nm_setting_ovs_external_ids_get_data(s_exid_new)) - : NULL; + exid_old = + s_exid_old ? nm_strdict_clone(_nm_setting_ovs_external_ids_get_data(s_exid_old)) : NULL; + exid_new = + s_exid_new ? nm_strdict_clone(_nm_setting_ovs_external_ids_get_data(s_exid_new)) : NULL; ovsdb_call_method(self, NULL, diff --git a/src/core/devices/team/nm-device-team.c b/src/core/devices/team/nm-device-team.c index 0f1a8c4c..3398e467 100644 --- a/src/core/devices/team/nm-device-team.c +++ b/src/core/devices/team/nm-device-team.c @@ -20,6 +20,7 @@ #include "devices/nm-device-private.h" #include "libnm-platform/nm-platform.h" #include "nm-config.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "nm-dbus-manager.h" #include "nm-ip4-config.h" @@ -78,8 +79,6 @@ complete_connection(NMDevice * device, NMConnection *const *existing_connections, GError ** error) { - NMSettingTeam *s_team; - nm_utils_complete_generic(nm_device_get_platform(device), connection, NM_SETTING_TEAM_SETTING_NAME, @@ -90,11 +89,7 @@ complete_connection(NMDevice * device, NULL, TRUE); - s_team = nm_connection_get_setting_team(connection); - if (!s_team) { - s_team = (NMSettingTeam *) nm_setting_team_new(); - nm_connection_add_setting(connection, NM_SETTING(s_team)); - } + _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_TEAM); return TRUE; } @@ -168,15 +163,10 @@ static void update_connection(NMDevice *device, NMConnection *connection) { NMDeviceTeam * self = NM_DEVICE_TEAM(device); - NMSettingTeam * s_team = nm_connection_get_setting_team(connection); + NMSettingTeam * s_team = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_TEAM); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); struct teamdctl * tdc = priv->tdc; - if (!s_team) { - s_team = (NMSettingTeam *) nm_setting_team_new(); - nm_connection_add_setting(connection, (NMSetting *) s_team); - } - /* Read the configuration only if not already set */ if (!priv->config && ensure_teamd_connection(device)) teamd_read_config(self); @@ -250,11 +240,7 @@ master_update_slave_connection(NMDevice * self, return FALSE; } - s_port = nm_connection_get_setting_team_port(connection); - if (!s_port) { - s_port = (NMSettingTeamPort *) nm_setting_team_port_new(); - nm_connection_add_setting(connection, NM_SETTING(s_port)); - } + s_port = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_TEAM_PORT); g_object_set(G_OBJECT(s_port), NM_SETTING_TEAM_PORT_CONFIG, port_config, NULL); g_free(port_config); diff --git a/src/core/devices/wifi/nm-device-iwd.c b/src/core/devices/wifi/nm-device-iwd.c index 56338743..27a3188b 100644 --- a/src/core/devices/wifi/nm-device-iwd.c +++ b/src/core/devices/wifi/nm-device-iwd.c @@ -18,6 +18,7 @@ #include "libnm-glib-aux/nm-ref-string.h" #include "nm-iwd-manager.h" #include "libnm-core-aux-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "nm-setting-8021x.h" #include "nm-setting-connection.h" #include "nm-setting-wireless-security.h" @@ -966,7 +967,7 @@ complete_connection(NMDevice * device, gboolean hidden = FALSE; const char * mode; - s_wifi = nm_connection_get_setting_wireless(connection); + s_wifi = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_WIRELESS); mode = s_wifi ? nm_setting_wireless_get_mode(s_wifi) : NULL; @@ -1031,12 +1032,6 @@ complete_connection(NMDevice * device, } ssid = nm_wifi_ap_get_ssid(ap); - - /* Add a wifi setting if one doesn't exist yet */ - if (!s_wifi) { - s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); - nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - } } if (ap) { @@ -2651,7 +2646,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) break; case PROP_ACCESS_POINTS: list = nm_wifi_aps_get_paths(&priv->aps_lst_head, TRUE); - g_value_take_boxed(value, nm_utils_strv_make_deep_copied(list)); + g_value_take_boxed(value, nm_strv_make_deep_copied(list)); break; case PROP_ACTIVE_ACCESS_POINT: nm_dbus_utils_g_value_set_object_path(value, priv->current_ap); diff --git a/src/core/devices/wifi/nm-device-olpc-mesh.c b/src/core/devices/wifi/nm-device-olpc-mesh.c index 040350d5..d829f9ae 100644 --- a/src/core/devices/wifi/nm-device-olpc-mesh.c +++ b/src/core/devices/wifi/nm-device-olpc-mesh.c @@ -28,6 +28,7 @@ #include "nm-setting-connection.h" #include "nm-setting-olpc-mesh.h" #include "nm-manager.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-platform/nm-platform.h" #define _NMLOG_DEVICE_TYPE NMDeviceOlpcMesh @@ -88,11 +89,7 @@ complete_connection(NMDevice * device, { NMSettingOlpcMesh *s_mesh; - s_mesh = nm_connection_get_setting_olpc_mesh(connection); - if (!s_mesh) { - s_mesh = (NMSettingOlpcMesh *) nm_setting_olpc_mesh_new(); - nm_connection_add_setting(connection, NM_SETTING(s_mesh)); - } + s_mesh = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_OLPC_MESH); if (!nm_setting_olpc_mesh_get_ssid(s_mesh)) { gs_unref_bytes GBytes *ssid = NULL; diff --git a/src/core/devices/wifi/nm-device-wifi-p2p.c b/src/core/devices/wifi/nm-device-wifi-p2p.c index a8ea2ed7..67202a67 100644 --- a/src/core/devices/wifi/nm-device-wifi-p2p.c +++ b/src/core/devices/wifi/nm-device-wifi-p2p.c @@ -15,6 +15,7 @@ #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" #include "nm-act-request.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "libnm-glib-aux/nm-ref-string.h" #include "nm-ip4-config.h" @@ -302,10 +303,7 @@ complete_connection(NMDevice * device, } /* Add a Wi-Fi P2P setting if one doesn't exist yet */ - if (!s_wifi_p2p) { - s_wifi_p2p = NM_SETTING_WIFI_P2P(nm_setting_wifi_p2p_new()); - nm_connection_add_setting(connection, NM_SETTING(s_wifi_p2p)); - } + s_wifi_p2p = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_WIFI_P2P); g_object_set(G_OBJECT(s_wifi_p2p), NM_SETTING_WIFI_P2P_PEER, setting_peer, NULL); @@ -560,14 +558,39 @@ act_stage3_ip_config_start(NMDevice * device, gpointer * out_config, NMDeviceStateReason *out_failure_reason) { - gboolean indicate_addressing_running; - NMConnection *connection; - const char * method; + NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(device); + gboolean indicate_addressing_running; + NMConnection * connection; + const char * method; connection = nm_device_get_applied_connection(device); method = nm_utils_get_ip_config_method(connection, addr_family); + /* We may have an address assigned by the group owner */ + if (NM_IN_STRSET(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) && priv->group_iface + && !nm_supplicant_interface_get_p2p_group_owner(priv->group_iface)) { + in_addr_t addr; + guint8 plen; + + if (nm_supplicant_interface_get_p2p_assigned_addr(priv->group_iface, &addr, &plen)) { + NMPlatformIP4Address address = { + .addr_source = NM_IP_CONFIG_SOURCE_DHCP, + }; + gs_unref_object NMIP4Config *ip4_config = NULL; + + nm_platform_ip4_address_set_addr(&address, addr, plen); + + ip4_config = nm_device_ip4_config_new(device); + nm_ip4_config_add_address(ip4_config, &address); + + nm_device_set_dev2_ip_config(device, AF_INET, NM_IP_CONFIG(ip4_config)); + + /* This just disables the addressing indicator. */ + method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + } + } + if (addr_family == AF_INET) indicate_addressing_running = NM_IN_STRSET(method, NM_SETTING_IP4_CONFIG_METHOD_AUTO); else { @@ -622,6 +645,11 @@ get_auto_ip_config_method(NMDevice *device, int addr_family) NMDeviceWifiP2P * self = NM_DEVICE_WIFI_P2P(device); NMDeviceWifiP2PPrivate *priv = NM_DEVICE_WIFI_P2P_GET_PRIVATE(self); + if (addr_family == AF_INET && priv->group_iface + && !nm_supplicant_interface_get_p2p_group_owner(priv->group_iface) + && nm_supplicant_interface_get_p2p_assigned_addr(priv->group_iface, NULL, NULL)) + return NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + /* Override the AUTO method to mean shared if we are group owner. */ if (priv->group_iface && nm_supplicant_interface_get_p2p_group_owner(priv->group_iface)) { if (addr_family == AF_INET) @@ -1163,7 +1191,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) switch (prop_id) { case PROP_PEERS: list = nm_wifi_p2p_peers_get_paths(&priv->peers_lst_head); - g_value_take_boxed(value, nm_utils_strv_make_deep_copied(list)); + g_value_take_boxed(value, nm_strv_make_deep_copied(list)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); diff --git a/src/core/devices/wifi/nm-device-wifi.c b/src/core/devices/wifi/nm-device-wifi.c index fca2fde5..82896c77 100644 --- a/src/core/devices/wifi/nm-device-wifi.c +++ b/src/core/devices/wifi/nm-device-wifi.c @@ -17,6 +17,7 @@ #include "nm-device-wifi-p2p.h" #include "nm-wifi-ap.h" #include "libnm-core-aux-intern/nm-common-macros.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "devices/nm-device.h" #include "devices/nm-device-private.h" #include "nm-dbus-manager.h" @@ -321,7 +322,7 @@ _scan_request_ssids_track(NMDeviceWifiPrivate *priv, const GPtrArray *ssids) now_msec = nm_utils_get_monotonic_timestamp_msec(); if (!priv->scan_request_ssids_hash) - priv->scan_request_ssids_hash = g_hash_table_new(nm_pgbytes_hash, nm_pgbytes_equal); + priv->scan_request_ssids_hash = g_hash_table_new(nm_pg_bytes_hash, nm_pg_bytes_equal); /* Do a little dance. New elements shall keep their order as in @ssids, but all * new elements should be sorted in the list preexisting elements of the list. @@ -1205,10 +1206,7 @@ complete_connection(NMDevice * device, } /* Add a wifi setting if one doesn't exist yet */ - if (!s_wifi) { - s_wifi = (NMSettingWireless *) nm_setting_wireless_new(); - nm_connection_add_setting(connection, NM_SETTING(s_wifi)); - } + s_wifi = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_WIRELESS); if (ap) ssid = nm_wifi_ap_get_ssid(ap); @@ -1571,7 +1569,7 @@ _scan_request_ssids_build_hidden(NMDeviceWifi *self, if (ssids) { if (ssids->len < max_scan_ssids) { /* Add wildcard SSID using a static wildcard SSID used for every scan */ - g_ptr_array_insert(ssids, 0, g_bytes_ref(nm_gbytes_get_empty())); + g_ptr_array_insert(ssids, 0, g_bytes_ref(nm_g_bytes_get_empty())); } if (ssids->len >= max_scan_ssids) { /* there is no more space. Use what we have. */ @@ -1592,10 +1590,10 @@ _scan_request_ssids_build_hidden(NMDeviceWifi *self, if (!ssids) { ssids = g_ptr_array_new_full(max_scan_ssids, (GDestroyNotify) g_bytes_unref); /* Add wildcard SSID using a static wildcard SSID used for every scan */ - g_ptr_array_insert(ssids, 0, g_bytes_ref(nm_gbytes_get_empty())); + g_ptr_array_insert(ssids, 0, g_bytes_ref(nm_g_bytes_get_empty())); } - unique_ssids = g_hash_table_new(nm_gbytes_hash, nm_gbytes_equal); + unique_ssids = g_hash_table_new(nm_g_bytes_hash, nm_g_bytes_equal); for (i = 1; i < ssids->len; i++) { if (!g_hash_table_add(unique_ssids, ssids->pdata[i])) nm_assert_not_reached(); @@ -1673,12 +1671,7 @@ _scan_supplicant_request_scan_cb(NMSupplicantInterface *supp_iface, * Artificially keep the scanning state on, for another SCAN_EXTRA_DELAY_MSEC msec. */ nm_clear_g_source_inst(&priv->scan_request_delay_source); priv->scan_request_delay_source = - nm_g_source_attach(nm_g_timeout_source_new(SCAN_EXTRA_DELAY_MSEC, - G_PRIORITY_DEFAULT, - _scan_request_delay_cb, - self, - NULL), - NULL); + nm_g_timeout_add_source(SCAN_EXTRA_DELAY_MSEC, _scan_request_delay_cb, self); g_clear_object(&priv->scan_request_cancellable); _scan_notify_is_scanning(self); @@ -3646,7 +3639,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) break; case PROP_ACCESS_POINTS: list = nm_wifi_aps_get_paths(&priv->aps_lst_head, TRUE); - g_value_take_boxed(value, nm_utils_strv_make_deep_copied(list)); + g_value_take_boxed(value, nm_strv_make_deep_copied(list)); break; case PROP_ACTIVE_ACCESS_POINT: nm_dbus_utils_g_value_set_object_path(value, priv->current_ap); diff --git a/src/core/devices/wifi/nm-wifi-ap.c b/src/core/devices/wifi/nm-wifi-ap.c index 20ed6833..72a60885 100644 --- a/src/core/devices/wifi/nm-wifi-ap.c +++ b/src/core/devices/wifi/nm-wifi-ap.c @@ -669,7 +669,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) g_value_set_uint(value, priv->rsn_flags); break; case PROP_SSID: - g_value_take_variant(value, nm_utils_gbytes_to_variant_ay(priv->ssid)); + g_value_take_variant(value, nm_g_bytes_to_variant_ay(priv->ssid)); break; case PROP_FREQUENCY: g_value_set_uint(value, priv->freq); diff --git a/src/core/devices/wifi/nm-wifi-common.c b/src/core/devices/wifi/nm-wifi-common.c index b98ef222..d029ce7f 100644 --- a/src/core/devices/wifi/nm-wifi-common.c +++ b/src/core/devices/wifi/nm-wifi-common.c @@ -13,7 +13,7 @@ #include "nm-dbus-manager.h" #if WITH_IWD - #include "nm-device-iwd.h" +#include "nm-device-iwd.h" #endif /*****************************************************************************/ diff --git a/src/core/devices/wifi/nm-wifi-p2p-peer.c b/src/core/devices/wifi/nm-wifi-p2p-peer.c index 433c2833..ac13952d 100644 --- a/src/core/devices/wifi/nm-wifi-p2p-peer.c +++ b/src/core/devices/wifi/nm-wifi-p2p-peer.c @@ -168,7 +168,7 @@ nm_wifi_p2p_peer_set_name(NMWifiP2PPeer *peer, const char *str) { NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (!nm_utils_strdup_reset(&priv->name, str)) + if (!nm_strdup_reset(&priv->name, str)) return FALSE; _notify(peer, PROP_NAME); return TRUE; @@ -187,7 +187,7 @@ nm_wifi_p2p_peer_set_manufacturer(NMWifiP2PPeer *peer, const char *str) { NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (!nm_utils_strdup_reset(&priv->manufacturer, str)) + if (!nm_strdup_reset(&priv->manufacturer, str)) return FALSE; _notify(peer, PROP_MANUFACTURER); return TRUE; @@ -206,7 +206,7 @@ nm_wifi_p2p_peer_set_model(NMWifiP2PPeer *peer, const char *str) { NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (!nm_utils_strdup_reset(&priv->model, str)) + if (!nm_strdup_reset(&priv->model, str)) return FALSE; _notify(peer, PROP_MODEL); return TRUE; @@ -225,7 +225,7 @@ nm_wifi_p2p_peer_set_model_number(NMWifiP2PPeer *peer, const char *str) { NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (!nm_utils_strdup_reset(&priv->model_number, str)) + if (!nm_strdup_reset(&priv->model_number, str)) return FALSE; _notify(peer, PROP_MODEL_NUMBER); return TRUE; @@ -244,7 +244,7 @@ nm_wifi_p2p_peer_set_serial(NMWifiP2PPeer *peer, const char *str) { NMWifiP2PPeerPrivate *priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (!nm_utils_strdup_reset(&priv->serial, str)) + if (!nm_strdup_reset(&priv->serial, str)) return FALSE; _notify(peer, PROP_SERIAL); return TRUE; @@ -268,7 +268,7 @@ nm_wifi_p2p_peer_set_wfd_ies(NMWifiP2PPeer *peer, GBytes *wfd_ies) priv = NM_WIFI_P2P_PEER_GET_PRIVATE(peer); - if (nm_gbytes_equal0(priv->wfd_ies, wfd_ies)) + if (nm_g_bytes_equal0(priv->wfd_ies, wfd_ies)) return FALSE; wfd_ies_old = g_steal_pointer(&priv->wfd_ies); @@ -408,9 +408,9 @@ nm_wifi_p2p_peer_update_from_properties(NMWifiP2PPeer *peer, const NMSupplicantP /* We currently only use the groups information internally to check if * the peer is still joined. */ - if (!nm_utils_strv_equal(priv->groups, peer_info->groups)) { + if (!nm_strv_equal(priv->groups, peer_info->groups)) { g_free(priv->groups); - priv->groups = nm_utils_strv_dup_packed(peer_info->groups, -1); + priv->groups = nm_strv_dup_packed(peer_info->groups, -1); changed |= TRUE; } @@ -509,7 +509,7 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) g_value_set_string(value, priv->serial); break; case PROP_WFD_IES: - g_value_take_variant(value, nm_utils_gbytes_to_variant_ay(priv->wfd_ies)); + g_value_take_variant(value, nm_g_bytes_to_variant_ay(priv->wfd_ies)); break; case PROP_HW_ADDRESS: g_value_set_string(value, priv->address); diff --git a/src/core/devices/wifi/nm-wifi-utils.c b/src/core/devices/wifi/nm-wifi-utils.c index 15ced990..4939e786 100644 --- a/src/core/devices/wifi/nm-wifi-utils.c +++ b/src/core/devices/wifi/nm-wifi-utils.c @@ -13,6 +13,7 @@ #include "nm-utils.h" #include "libnm-core-intern/nm-core-internal.h" +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-aux-intern/nm-common-macros.h" #include "libnm-base/nm-config-base.h" @@ -679,10 +680,7 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, } /* Everything else requires security */ - if (!s_wsec) { - s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new(); - nm_connection_add_setting(connection, NM_SETTING(s_wsec)); - } + s_wsec = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_WIRELESS_SECURITY); key_mgmt = nm_setting_wireless_security_get_key_mgmt(s_wsec); auth_alg = nm_setting_wireless_security_get_auth_alg(s_wsec); @@ -825,21 +823,11 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, "open", NULL); } else if (nm_streq0(key_mgmt, "sae") || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_SAE)) { - g_object_set(s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, - "sae", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, - "open", - NULL); + g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "sae", NULL); } else if (nm_streq0(key_mgmt, "owe") || NM_FLAGS_ANY(ap_rsn_flags, NM_802_11_AP_SEC_KEY_MGMT_OWE | NM_802_11_AP_SEC_KEY_MGMT_OWE_TM)) { - g_object_set(s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, - "owe", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, - "open", - NULL); + g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "owe", NULL); } else if (ap_wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK || ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) { g_object_set(s_wsec, @@ -853,12 +841,7 @@ nm_wifi_utils_complete_connection(GBytes * ap_ssid, */ } else if (nm_streq0(key_mgmt, "wpa-eap-suite-b-192") || (ap_rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_EAP_SUITE_B_192)) { - g_object_set(s_wsec, - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, - "wpa-eap-suite-b-192", - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, - "open", - NULL); + g_object_set(s_wsec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap-suite-b-192", NULL); } else { g_set_error_literal(error, NM_CONNECTION_ERROR, diff --git a/src/core/devices/wifi/tests/test-devices-wifi.c b/src/core/devices/wifi/tests/test-devices-wifi.c index dc278c94..5d1167cf 100644 --- a/src/core/devices/wifi/tests/test-devices-wifi.c +++ b/src/core/devices/wifi/tests/test-devices-wifi.c @@ -1445,7 +1445,7 @@ do_test_ssids_options_to_ptrarray(const char *const *ssids) const char *ssid = ssids[i]; GBytes * bytes = ssids_arr->pdata[i]; - g_assert(nm_utils_gbytes_equal_mem(bytes, ssid, strlen(ssid))); + g_assert(nm_g_bytes_equal_mem(bytes, ssid, strlen(ssid))); } } diff --git a/src/core/devices/wwan/nm-device-modem.c b/src/core/devices/wwan/nm-device-modem.c index 4d892e6f..1b285469 100644 --- a/src/core/devices/wwan/nm-device-modem.c +++ b/src/core/devices/wwan/nm-device-modem.c @@ -616,18 +616,20 @@ act_stage3_ip_config_start(NMDevice * device, gpointer * out_config, NMDeviceStateReason *out_failure_reason) { - NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); - - nm_assert_addr_family(addr_family); + NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE(device); + gboolean autoip4 = FALSE; + NMActStageReturn ret; - if (addr_family == AF_INET) { - return nm_modem_stage3_ip4_config_start(priv->modem, - device, - NM_DEVICE_CLASS(nm_device_modem_parent_class), - out_failure_reason); - } else { + if (!NM_IS_IPv4(addr_family)) return nm_modem_stage3_ip6_config_start(priv->modem, device, out_failure_reason); - } + + ret = nm_modem_stage3_ip4_config_start(priv->modem, device, &autoip4, out_failure_reason); + + if (ret != NM_ACT_STAGE_RETURN_SUCCESS || !autoip4) + return ret; + + return NM_DEVICE_CLASS(nm_device_modem_parent_class) + ->act_stage3_ip_config_start(device, addr_family, out_config, out_failure_reason); } static void diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c index 0872a8a1..a5139f08 100644 --- a/src/core/devices/wwan/nm-modem-broadband.c +++ b/src/core/devices/wwan/nm-modem-broadband.c @@ -11,6 +11,7 @@ #include #include +#include "libnm-core-aux-intern/nm-libnm-core-utils.h" #include "libnm-core-intern/nm-core-internal.h" #include "NetworkManagerUtils.h" #include "devices/nm-device-private.h" @@ -829,11 +830,7 @@ complete_connection(NMModem * modem, if (MODEM_CAPS_3GPP2(modem_caps)) { NMSettingCdma *s_cdma; - s_cdma = nm_connection_get_setting_cdma(connection); - if (!s_cdma) { - s_cdma = (NMSettingCdma *) nm_setting_cdma_new(); - nm_connection_add_setting(connection, NM_SETTING(s_cdma)); - } + s_cdma = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_CDMA); if (!nm_setting_cdma_get_number(s_cdma)) g_object_set(G_OBJECT(s_cdma), NM_SETTING_CDMA_NUMBER, "#777", NULL); diff --git a/src/core/devices/wwan/nm-modem-manager.c b/src/core/devices/wwan/nm-modem-manager.c index 4fb9a378..8d087d13 100644 --- a/src/core/devices/wwan/nm-modem-manager.c +++ b/src/core/devices/wwan/nm-modem-manager.c @@ -12,9 +12,9 @@ #include #if HAVE_LIBSYSTEMD - #include +#include #else - #define sd_booted() FALSE +#define sd_booted() FALSE #endif #include "libnm-std-aux/nm-dbus-compat.h" @@ -22,7 +22,7 @@ #include "nm-modem-broadband.h" #if WITH_OFONO - #include "nm-modem-ofono.h" +#include "nm-modem-ofono.h" #endif #define MODEM_POKE_INTERVAL 120 diff --git a/src/core/devices/wwan/nm-modem.c b/src/core/devices/wwan/nm-modem.c index 15baa677..ccea69db 100644 --- a/src/core/devices/wwan/nm-modem.c +++ b/src/core/devices/wwan/nm-modem.c @@ -526,48 +526,6 @@ static void ppp_ip4_config(NMPPPManager *ppp_manager, NMIP4Config *config, gpointer user_data) { NMModem *self = NM_MODEM(user_data); - guint32 i, num; - guint32 bad_dns1 = htonl(0x0A0B0C0D); - guint32 good_dns1 = htonl(0x04020201); /* GTE nameserver */ - guint32 bad_dns2 = htonl(0x0A0B0C0E); - guint32 good_dns2 = htonl(0x04020202); /* GTE nameserver */ - gboolean dns_workaround = FALSE; - - /* Work around a PPP bug (#1732) which causes many mobile broadband - * providers to return 10.11.12.13 and 10.11.12.14 for the DNS servers. - * Apparently fixed in ppp-2.4.5 but we've had some reports that this is - * not the case. - * - * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=2e09ef6886bbf00bc5a9a641110f801e372ffde6 - * http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=f8191bf07df374f119a07910a79217c7618f113e - */ - - num = nm_ip4_config_get_num_nameservers(config); - if (num == 2) { - gboolean found1 = FALSE, found2 = FALSE; - - for (i = 0; i < num; i++) { - guint32 ns = nm_ip4_config_get_nameserver(config, i); - - if (ns == bad_dns1) - found1 = TRUE; - else if (ns == bad_dns2) - found2 = TRUE; - } - - /* Be somewhat conservative about substitutions; the "bad" nameservers - * could actually be valid in some cases, so only substitute if ppp - * returns *only* the two bad nameservers. - */ - dns_workaround = (found1 && found2); - } - - if (!num || dns_workaround) { - _LOGW("compensating for invalid PPP-provided nameservers"); - nm_ip4_config_reset_nameservers(config); - nm_ip4_config_add_nameserver(config, good_dns1); - nm_ip4_config_add_nameserver(config, good_dns2); - } g_signal_emit(self, signals[IP4_CONFIG_RESULT], 0, config, NULL); } @@ -727,7 +685,7 @@ ppp_stage3_ip_config_start(NMModem * self, NMActStageReturn nm_modem_stage3_ip4_config_start(NMModem * self, NMDevice * device, - NMDeviceClass * device_class, + gboolean * out_autoip4, NMDeviceStateReason *out_failure_reason) { NMModemPrivate * priv; @@ -740,7 +698,7 @@ nm_modem_stage3_ip4_config_start(NMModem * self, g_return_val_if_fail(NM_IS_MODEM(self), NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail(NM_IS_DEVICE(device), NM_ACT_STAGE_RETURN_FAILURE); - g_return_val_if_fail(NM_IS_DEVICE_CLASS(device_class), NM_ACT_STAGE_RETURN_FAILURE); + nm_assert(out_autoip4 && !*out_autoip4); req = nm_device_get_act_request(device); g_return_val_if_fail(req, NM_ACT_STAGE_RETURN_FAILURE); @@ -774,7 +732,8 @@ nm_modem_stage3_ip4_config_start(NMModem * self, break; case NM_MODEM_IP_METHOD_AUTO: _LOGD("MODEM_IP_METHOD_AUTO"); - ret = device_class->act_stage3_ip_config_start(device, AF_INET, NULL, out_failure_reason); + *out_autoip4 = TRUE; + ret = NM_ACT_STAGE_RETURN_SUCCESS; break; default: _LOGI("IPv4 configuration disabled"); diff --git a/src/core/devices/wwan/nm-modem.h b/src/core/devices/wwan/nm-modem.h index 87162cfc..4bc81ff8 100644 --- a/src/core/devices/wwan/nm-modem.h +++ b/src/core/devices/wwan/nm-modem.h @@ -210,7 +210,7 @@ void nm_modem_act_stage2_config(NMModem *modem); NMActStageReturn nm_modem_stage3_ip4_config_start(NMModem * modem, NMDevice * device, - NMDeviceClass * device_class, + gboolean * out_autoip4, NMDeviceStateReason *out_failure_reason); NMActStageReturn nm_modem_stage3_ip6_config_start(NMModem * modem, -- cgit 1.3.0-6-gf8a5