diff options
Diffstat (limited to 'src/devices')
| -rw-r--r-- | src/devices/nm-device-6lowpan.c | 10 | ||||
| -rw-r--r-- | src/devices/nm-device-wpan.c | 8 | ||||
| -rw-r--r-- | src/devices/nm-device.c | 71 | ||||
| -rw-r--r-- | src/devices/nm-device.h | 4 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-iwd.c | 148 | ||||
| -rw-r--r-- | src/devices/wifi/nm-device-wifi.c | 1 |
6 files changed, 158 insertions, 84 deletions
diff --git a/src/devices/nm-device-6lowpan.c b/src/devices/nm-device-6lowpan.c index 600d1b80..b6b9157c 100644 --- a/src/devices/nm-device-6lowpan.c +++ b/src/devices/nm-device-6lowpan.c @@ -114,7 +114,7 @@ create_and_realize (NMDevice *device, NMSetting6Lowpan *s_6lowpan; int parent_ifindex; - s_6lowpan = nm_connection_get_setting_6lowpan (connection); + s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN)); g_return_val_if_fail (s_6lowpan, FALSE); parent_ifindex = parent ? nm_device_get_ifindex (parent) : 0; @@ -192,7 +192,7 @@ complete_connection (NMDevice *device, NULL, TRUE); - s_6lowpan = nm_connection_get_setting_6lowpan (connection); + s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN)); if (!s_6lowpan) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "A '6lowpan' setting is required."); @@ -215,7 +215,7 @@ complete_connection (NMDevice *device, static void update_connection (NMDevice *device, NMConnection *connection) { - NMSetting6Lowpan *s_6lowpan = nm_connection_get_setting_6lowpan (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 (); @@ -310,7 +310,7 @@ get_connection_parent (NMDeviceFactory *factory, NMConnection *connection) g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL); - s_6lowpan = nm_connection_get_setting_6lowpan (connection); + s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN)); g_assert (s_6lowpan); return nm_setting_6lowpan_get_parent (s_6lowpan); @@ -326,7 +326,7 @@ get_connection_iface (NMDeviceFactory *factory, g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL); - s_6lowpan = nm_connection_get_setting_6lowpan (connection); + s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN)); g_assert (s_6lowpan); if (!parent_iface) diff --git a/src/devices/nm-device-wpan.c b/src/devices/nm-device-wpan.c index dd2ebac1..f910b0b8 100644 --- a/src/devices/nm-device-wpan.c +++ b/src/devices/nm-device-wpan.c @@ -69,7 +69,7 @@ complete_connection (NMDevice *device, NULL, TRUE); - s_wpan = nm_connection_get_setting_wpan (connection); + s_wpan = NM_SETTING_WPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_WPAN)); if (!s_wpan) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'wpan' setting is required."); @@ -82,7 +82,7 @@ complete_connection (NMDevice *device, static void update_connection (NMDevice *device, NMConnection *connection) { - NMSettingWpan *s_wpan = nm_connection_get_setting_wpan (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 (); @@ -99,7 +99,7 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError if (!NM_DEVICE_CLASS (nm_device_wpan_parent_class)->check_connection_compatible (device, connection, error)) return FALSE; - s_wpan = nm_connection_get_setting_wpan (connection); + s_wpan = NM_SETTING_WPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_WPAN)); mac = nm_setting_wpan_get_mac_address (s_wpan); if (mac) { @@ -143,7 +143,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) connection = nm_device_get_applied_connection (device); g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - s_wpan = nm_connection_get_setting_wpan (connection); + s_wpan = NM_SETTING_WPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_WPAN)); g_return_val_if_fail (s_wpan, NM_ACT_STAGE_RETURN_FAILURE); hwaddr = nm_platform_link_get_address (platform, ifindex, &hwaddr_len); diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 515e6334..8ca899a2 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -80,7 +80,10 @@ #include "nm-audit-manager.h" #include "nm-connectivity.h" #include "nm-dbus-interface.h" + +#include "nm-device-generic.h" #include "nm-device-vlan.h" +#include "nm-device-wireguard.h" #include "nm-device-logging.h" _LOG_DECLARE_SELF (NMDevice); @@ -823,6 +826,13 @@ _ethtool_state_set (NMDevice *self) /*****************************************************************************/ +static gboolean +is_loopback (NMDevice *self) +{ + return NM_IS_DEVICE_GENERIC (self) + && NM_DEVICE_GET_PRIVATE (self)->ifindex == 1; +} + NMSettings * nm_device_get_settings (NMDevice *self) { @@ -2460,7 +2470,7 @@ concheck_is_possible (NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if ( !nm_device_is_real (self) - || NM_FLAGS_HAS (priv->unmanaged_flags, NM_UNMANAGED_LOOPBACK)) + || is_loopback (self)) return FALSE; /* we enable periodic checks for every device state (except UNKNOWN). Especially with @@ -4289,10 +4299,13 @@ realize_start_setup (NMDevice *self, NM_UNMANAGED_EXTERNAL_DOWN, is_unmanaged_external_down (self, TRUE)); - /* Unmanaged the loopback device with an explicit NM_UNMANAGED_LOOPBACK flag. + /* Unmanaged the loopback device with an explicit NM_UNMANAGED_BY_TYPE flag. * Later we might want to manage 'lo' too. Currently that doesn't work because * NetworkManager might down the interface or remove the 127.0.0.1 address. */ - nm_device_set_unmanaged_flags (self, NM_UNMANAGED_LOOPBACK, priv->ifindex == 1); + nm_device_set_unmanaged_flags (self, + NM_UNMANAGED_BY_TYPE, + is_loopback (self) + || NM_IS_DEVICE_WIREGUARD (self)); nm_device_set_unmanaged_by_user_udev (self); nm_device_set_unmanaged_by_user_conf (self); @@ -4488,7 +4501,7 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error) nm_device_set_unmanaged_flags (self, NM_UNMANAGED_PARENT | - NM_UNMANAGED_LOOPBACK | + NM_UNMANAGED_BY_TYPE | NM_UNMANAGED_USER_UDEV | NM_UNMANAGED_USER_EXPLICIT | NM_UNMANAGED_EXTERNAL_DOWN | @@ -5596,6 +5609,14 @@ check_connection_compatible (NMDevice *self, NMConnection *connection, GError ** klass->connection_type_check_compatible, error)) return FALSE; + } else if (klass->check_connection_compatible == check_connection_compatible) { + /* the device class does not implement check_connection_compatible nor set + * connection_type_check_compatible. That means, it is by default not compatible + * with any connection type. */ + nm_utils_error_set_literal (error, + NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, + "device does not support any connections"); + return FALSE; } conn_iface = nm_manager_get_connection_iface (nm_manager_get (), @@ -7540,6 +7561,7 @@ dhcp4_start (NMDevice *self) gs_unref_bytes GBytes *hwaddr = NULL; gs_unref_bytes GBytes *client_id = NULL; NMConnection *connection; + GError *error = NULL; connection = nm_device_get_applied_connection (self); g_return_val_if_fail (connection, FALSE); @@ -7570,10 +7592,14 @@ dhcp4_start (NMDevice *self) client_id, get_dhcp_timeout (self, AF_INET), priv->dhcp_anycast_address, - NULL); + NULL, + &error); - if (!priv->dhcp4.client) + if (!priv->dhcp4.client) { + _LOGW (LOGD_DHCP4, "failure to start DHCP: %s", error->message); + g_clear_error (&error); return NM_ACT_STAGE_RETURN_FAILURE; + } priv->dhcp4.state_sigid = g_signal_connect (priv->dhcp4.client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, @@ -8375,6 +8401,7 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) gs_unref_bytes GBytes *hwaddr = NULL; gs_unref_bytes GBytes *duid = NULL; gboolean enforce_duid = FALSE; + GError *error = NULL; const NMPlatformIP6Address *ll_addr = NULL; @@ -8414,23 +8441,29 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) priv->dhcp_anycast_address, (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)), - priv->dhcp6.needed_prefixes); - - if (priv->dhcp6.client) { - priv->dhcp6.state_sigid = g_signal_connect (priv->dhcp6.client, - NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, - G_CALLBACK (dhcp6_state_changed), - self); - priv->dhcp6.prefix_sigid = g_signal_connect (priv->dhcp6.client, - NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED, - G_CALLBACK (dhcp6_prefix_delegated), - self); + priv->dhcp6.needed_prefixes, + &error); + if (!priv->dhcp6.client) { + _LOGW (LOGD_DHCP6, "failure to start DHCPv6: %s", error->message); + g_clear_error (&error); + if (nm_device_sys_iface_state_is_external_or_assume (self)) + priv->dhcp6.was_active = TRUE; + return FALSE; } + priv->dhcp6.state_sigid = g_signal_connect (priv->dhcp6.client, + NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, + G_CALLBACK (dhcp6_state_changed), + self); + priv->dhcp6.prefix_sigid = g_signal_connect (priv->dhcp6.client, + NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED, + G_CALLBACK (dhcp6_prefix_delegated), + self); + if (nm_device_sys_iface_state_is_external_or_assume (self)) priv->dhcp6.was_active = TRUE; - return !!priv->dhcp6.client; + return TRUE; } static gboolean @@ -12859,7 +12892,7 @@ NM_UTILS_FLAGS2STR_DEFINE (nm_unmanaged_flags2str, NMUnmanagedFlags, NM_UTILS_FLAGS2STR (NM_UNMANAGED_SLEEPING, "sleeping"), NM_UTILS_FLAGS2STR (NM_UNMANAGED_QUITTING, "quitting"), NM_UTILS_FLAGS2STR (NM_UNMANAGED_PARENT, "parent"), - NM_UTILS_FLAGS2STR (NM_UNMANAGED_LOOPBACK, "loopback"), + NM_UTILS_FLAGS2STR (NM_UNMANAGED_BY_TYPE, "by-type"), NM_UTILS_FLAGS2STR (NM_UNMANAGED_PLATFORM_INIT, "platform-init"), NM_UTILS_FLAGS2STR (NM_UNMANAGED_USER_EXPLICIT, "user-explicit"), NM_UTILS_FLAGS2STR (NM_UNMANAGED_BY_DEFAULT, "by-default"), diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 7d74e5b9..6342a657 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -583,7 +583,7 @@ void nm_device_copy_ip6_dns_config (NMDevice *self, NMDevice *from_device); * @NM_UNMANAGED_SLEEPING: %TRUE when unmanaged because NM is sleeping. * @NM_UNMANAGED_QUITTING: %TRUE when unmanaged because NM is shutting down. * @NM_UNMANAGED_PARENT: %TRUE when unmanaged due to parent device being unmanaged - * @NM_UNMANAGED_LOOPBACK: %TRUE for unmanaging loopback device + * @NM_UNMANAGED_BY_TYPE: %TRUE for unmanaging device by type, like loopback. * @NM_UNMANAGED_PLATFORM_INIT: %TRUE when unmanaged because platform link not * yet initialized. Unrealized device are also unmanaged for this reason. * @NM_UNMANAGED_USER_EXPLICIT: %TRUE when unmanaged by explicit user decision @@ -614,7 +614,7 @@ typedef enum { /*< skip >*/ NM_UNMANAGED_SLEEPING = (1LL << 0), NM_UNMANAGED_QUITTING = (1LL << 1), NM_UNMANAGED_PARENT = (1LL << 2), - NM_UNMANAGED_LOOPBACK = (1LL << 3), + NM_UNMANAGED_BY_TYPE = (1LL << 3), NM_UNMANAGED_PLATFORM_INIT = (1LL << 4), NM_UNMANAGED_USER_EXPLICIT = (1LL << 5), NM_UNMANAGED_USER_SETTINGS = (1LL << 6), diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index 56b1f853..32d49916 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -229,6 +229,85 @@ vardict_from_network_type (const char *type) } static void +insert_ap_from_network (GHashTable *aps, GDBusProxy *proxy, const char *path, int16_t signal, uint32_t ap_id) +{ + gs_unref_object GDBusProxy *network_proxy = NULL; + gs_unref_variant GVariant *name_value = NULL, *type_value = NULL; + const char *name, *type; + GVariantBuilder builder; + gs_unref_variant GVariant *props = NULL; + GVariant *rsn; + uint8_t bssid[6]; + NMWifiAP *ap; + GError *error; + + network_proxy = g_dbus_proxy_new_sync (g_dbus_proxy_get_connection (proxy), + G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, + NULL, + NM_IWD_SERVICE, + path, + NM_IWD_NETWORK_INTERFACE, + NULL, &error); + if (!network_proxy) { + g_clear_error (&error); + return; + } + + name_value = g_dbus_proxy_get_cached_property (network_proxy, "Name"); + type_value = g_dbus_proxy_get_cached_property (network_proxy, "Type"); + if ( !name_value + || !g_variant_is_of_type (name_value, G_VARIANT_TYPE_STRING) + || !type_value + || !g_variant_is_of_type (type_value, G_VARIANT_TYPE_STRING)) + return; + + name = g_variant_get_string (name_value, NULL); + type = g_variant_get_string (type_value, NULL); + + /* What we get from IWD are networks, or ESSs, that may contain + * multiple APs, or BSSs, each. We don't get information about any + * specific BSSs within an ESS but we can safely present each ESS + * as an individual BSS to NM, which will be seen as ESSs comprising + * a single BSS each. NM won't be able to handle roaming but IWD + * already does that. We fake the BSSIDs as they don't play any + * role either. + */ + bssid[0] = 0x00; + bssid[1] = 0x01; + bssid[2] = 0x02; + bssid[3] = ap_id >> 16; + bssid[4] = ap_id >> 8; + bssid[5] = ap_id; + + /* WEP not supported */ + if (nm_streq (type, "wep")) + return; + + g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); + g_variant_builder_add (&builder, "{sv}", "BSSID", + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, bssid, 6, 1)); + g_variant_builder_add (&builder, "{sv}", "Mode", + g_variant_new_string ("infrastructure")); + + rsn = vardict_from_network_type (type); + if (rsn) + g_variant_builder_add (&builder, "{sv}", "RSN", rsn); + + props = g_variant_new ("a{sv}", &builder); + + ap = nm_wifi_ap_new_from_properties (path, props); + + nm_wifi_ap_set_ssid_arr (ap, + (const guint8 *) name, + NM_MIN (32, strlen (name))); + + nm_wifi_ap_set_strength (ap, nm_wifi_utils_level_to_quality (signal / 100)); + nm_wifi_ap_set_freq (ap, 2417); + nm_wifi_ap_set_max_bitrate (ap, 65000); + g_hash_table_insert (aps, (gpointer) nm_wifi_ap_get_supplicant_path (ap), ap); +} + +static void get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data) { NMDeviceIwd *self = user_data; @@ -242,9 +321,16 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data) gboolean changed = FALSE; GHashTableIter ap_iter; gs_unref_hashtable GHashTable *new_aps = NULL; + /* Depending on whether we're using the Station interface or the Device + * interface for compatibility with IWD <= 0.7, the return signature of + * GetOrderedNetworks will be different. + */ + gboolean compat = priv->dbus_station_proxy == priv->dbus_device_proxy; + const char *return_sig = compat ? "(a(osns))" : "(a(on))"; + static uint32_t ap_id = 0; variant = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, - G_VARIANT_TYPE ("(a(osns))"), + G_VARIANT_TYPE (return_sig), &error); if (!variant) { _LOGE (LOGD_WIFI, "Station.GetOrderedNetworks failed: %s", @@ -254,60 +340,14 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data) new_aps = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref); - g_variant_get (variant, "(a(osns))", &networks); - - while (g_variant_iter_next (networks, "(&o&sn&s)", &path, &name, &signal, &type)) { - GVariantBuilder builder; - gs_unref_variant GVariant *props = NULL; - GVariant *rsn; - static uint32_t ap_id = 0; - uint8_t bssid[6]; + g_variant_get (variant, return_sig, &networks); - /* - * What we get from IWD are networks, or ESSs, that may - * contain multiple APs, or BSSs, each. We don't get - * information about any specific BSSs within an ESS but - * we can safely present each ESS as an individual BSS to - * NM, which will be seen as ESSs comprising a single BSS - * each. NM won't be able to handle roaming but IWD already - * does that. We fake the BSSIDs as they don't play any - * role either. - */ - bssid[0] = 0x00; - bssid[1] = 0x01; - bssid[2] = 0x02; - bssid[3] = ap_id >> 16; - bssid[4] = ap_id >> 8; - bssid[5] = ap_id++; - - /* WEP not supported */ - if (!strcmp (type, "wep")) - continue; - - g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); - g_variant_builder_add (&builder, "{sv}", "BSSID", - g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, bssid, 6, 1)); - g_variant_builder_add (&builder, "{sv}", "Mode", - g_variant_new_string ("infrastructure")); - - rsn = vardict_from_network_type (type); - if (rsn) - g_variant_builder_add (&builder, "{sv}", "RSN", rsn); - - props = g_variant_new ("a{sv}", &builder); - - ap = nm_wifi_ap_new_from_properties (path, props); - - nm_wifi_ap_set_ssid_arr (ap, - (const guint8 *) name, - NM_MIN (32, strlen (name))); - - nm_wifi_ap_set_strength (ap, nm_wifi_utils_level_to_quality (signal / 100)); - nm_wifi_ap_set_freq (ap, 2417); - nm_wifi_ap_set_max_bitrate (ap, 65000); - g_hash_table_insert (new_aps, - (gpointer) nm_wifi_ap_get_supplicant_path (ap), - ap); + if (compat) { + while (g_variant_iter_next (networks, "(&o&sn&s)", &path, &name, &signal, &type)) + insert_ap_from_network (new_aps, priv->dbus_station_proxy, path, signal, ap_id++); + } else { + while (g_variant_iter_next (networks, "(&on)", &path, &signal)) + insert_ap_from_network (new_aps, priv->dbus_station_proxy, path, signal, ap_id++); } g_variant_iter_free (networks); diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index 64ab82cb..ec1150bb 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -2593,6 +2593,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) set_current_ap (self, ap, FALSE); nm_active_connection_set_specific_object (NM_ACTIVE_CONNECTION (req), nm_dbus_object_get_path (NM_DBUS_OBJECT (ap))); + g_object_unref (ap); return NM_ACT_STAGE_RETURN_SUCCESS; done: |