diff options
| author | Michael Biebl <biebl@debian.org> | 2018-09-23 10:10:27 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2018-09-23 10:10:27 +0200 |
| commit | e126f3e804c35480c4f075777430419d6ece23da (patch) | |
| tree | 5d5821ebcda8cd6ac34d2483bb3354910e508930 /src | |
| parent | c240974325c552cad177c457d6ff04e381fd77a3 (diff) | |
New upstream version 1.12.4 upstream/1.12.4
Diffstat (limited to 'src')
277 files changed, 7349 insertions, 14607 deletions
diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 1404854d..a3bd6013 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -805,11 +805,9 @@ nm_utils_match_connection (NMConnection *const*connections, return NULL; for (; *connections; connections++) { - NMConnection *candidate = *connections; + NMConnection *candidate = NM_CONNECTION (*connections); GHashTable *diffs = NULL; - nm_assert (NM_IS_CONNECTION (candidate)); - if (match_filter_func) { if (!match_filter_func (candidate, match_filter_data)) continue; diff --git a/src/devices/adsl/meson.build b/src/devices/adsl/meson.build index 7ac0e123..ee804d23 100644 --- a/src/devices/adsl/meson.build +++ b/src/devices/adsl/meson.build @@ -20,10 +20,10 @@ libnm_device_plugin_adsl = shared_module( core_plugins += libnm_device_plugin_adsl -test( +run_target( 'check-local-devices-adsl', - check_exports, - args: [libnm_device_plugin_adsl.full_path(), linker_script_devices], + command: [check_exports, libnm_device_plugin_adsl.full_path(), linker_script_devices], + depends: libnm_device_plugin_adsl ) # FIXME: check_so_symbols replacement diff --git a/src/devices/adsl/nm-device-adsl.c b/src/devices/adsl/nm-device-adsl.c index c9984f51..1450a836 100644 --- a/src/devices/adsl/nm-device-adsl.c +++ b/src/devices/adsl/nm-device-adsl.c @@ -87,23 +87,25 @@ get_generic_capabilities (NMDevice *dev) } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMSettingAdsl *s_adsl; const char *protocol; - if (!NM_DEVICE_CLASS (nm_device_adsl_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_adsl_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_ADSL_SETTING_NAME)) return FALSE; s_adsl = nm_connection_get_setting_adsl (connection); + if (!s_adsl) + return FALSE; + /* FIXME: we don't yet support IPoATM */ protocol = nm_setting_adsl_get_protocol (s_adsl); - if (nm_streq0 (protocol, NM_SETTING_ADSL_PROTOCOL_IPOATM)) { - /* FIXME: we don't yet support IPoATM */ - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "IPoATM protocol is not yet supported"); + if (g_strcmp0 (protocol, NM_SETTING_ADSL_PROTOCOL_IPOATM) == 0) return FALSE; - } return TRUE; } @@ -667,7 +669,7 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); object_class->constructed = constructed; object_class->dispose = dispose; @@ -676,16 +678,14 @@ nm_device_adsl_class_init (NMDeviceAdslClass *klass) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_adsl); - device_class->connection_type_check_compatible = NM_SETTING_ADSL_SETTING_NAME; - - device_class->get_generic_capabilities = get_generic_capabilities; + parent_class->get_generic_capabilities = get_generic_capabilities; - device_class->check_connection_compatible = check_connection_compatible; - device_class->complete_connection = complete_connection; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->complete_connection = complete_connection; - device_class->act_stage2_config = act_stage2_config; - device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; - device_class->deactivate = deactivate; + parent_class->act_stage2_config = act_stage2_config; + parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; + parent_class->deactivate = deactivate; obj_properties[PROP_ATM_INDEX] = g_param_spec_int (NM_DEVICE_ADSL_ATM_INDEX, "", "", diff --git a/src/devices/bluetooth/meson.build b/src/devices/bluetooth/meson.build index 019f04f6..30284f9e 100644 --- a/src/devices/bluetooth/meson.build +++ b/src/devices/bluetooth/meson.build @@ -31,10 +31,10 @@ libnm_device_plugin_bluetooth = shared_module( core_plugins += libnm_device_plugin_bluetooth -test( +run_target( 'check-local-devices-bluetooth', - check_exports, - args: [libnm_device_plugin_bluetooth.full_path(), linker_script_devices], + command: [check_exports, libnm_device_plugin_bluetooth.full_path(), linker_script_devices], + depends: libnm_device_plugin_bluetooth ) # FIXME: check_so_symbols replacement diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c index b69b4320..d8e40d6f 100644 --- a/src/devices/bluetooth/nm-bluez-device.c +++ b/src/devices/bluetooth/nm-bluez-device.c @@ -94,7 +94,7 @@ typedef struct { NMSettings *settings; GSList *connections; - NMSettingsConnection *pan_connection; + NMConnection *pan_connection; gboolean pan_connection_no_autocreate; } NMBluezDevicePrivate; @@ -114,9 +114,8 @@ G_DEFINE_TYPE (NMBluezDevice, nm_bluez_device, G_TYPE_OBJECT) /*****************************************************************************/ static void cp_connection_added (NMSettings *settings, - NMSettingsConnection *sett_conn, - NMBluezDevice *self); -static gboolean connection_compatible (NMBluezDevice *self, NMSettingsConnection *sett_conn); + NMConnection *connection, NMBluezDevice *self); +static gboolean connection_compatible (NMBluezDevice *self, NMConnection *connection); /*****************************************************************************/ @@ -182,10 +181,10 @@ nm_bluez_device_get_connected (NMBluezDevice *self) static void pan_connection_check_create (NMBluezDevice *self) { - gs_unref_object NMConnection *connection = NULL; - NMSettingsConnection *added; + NMConnection *connection; + NMConnection *added; NMSetting *setting; - gs_free char *id = NULL; + char *id; char uuid[37]; GError *error = NULL; NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); @@ -247,14 +246,15 @@ pan_connection_check_create (NMBluezDevice *self) * which then already finds the suitable connection in priv->connections. This is confusing, * so block the signal. check_emit_usable will succeed after this function call returns. */ g_signal_handlers_block_by_func (priv->settings, cp_connection_added, self); - added = nm_settings_add_connection (priv->settings, connection, FALSE, &error); + added = NM_CONNECTION (nm_settings_add_connection (priv->settings, connection, FALSE, &error)); g_signal_handlers_unblock_by_func (priv->settings, cp_connection_added, self); if (added) { - nm_assert (!g_slist_find (priv->connections, added)); - nm_assert (connection_compatible (self, added)); + g_assert (!g_slist_find (priv->connections, added)); + g_assert (connection_compatible (self, added)); + g_assert (nm_connection_compare (added, connection, NM_SETTING_COMPARE_FLAG_EXACT)); - nm_settings_connection_set_flags (added, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, TRUE); + nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added), NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED, TRUE); priv->connections = g_slist_prepend (priv->connections, g_object_ref (added)); priv->pan_connection = added; @@ -263,7 +263,11 @@ pan_connection_check_create (NMBluezDevice *self) nm_log_warn (LOGD_BT, "bluez[%s] couldn't add new Bluetooth connection for NAP device: '%s' (%s): %s", priv->path, id, uuid, error->message); g_clear_error (&error); + } + g_object_unref (connection); + + g_free (id); } static gboolean @@ -317,10 +321,9 @@ check_emit_usable_schedule (NMBluezDevice *self) /*****************************************************************************/ static gboolean -connection_compatible (NMBluezDevice *self, NMSettingsConnection *sett_conn) +connection_compatible (NMBluezDevice *self, NMConnection *connection) { NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); - NMConnection *connection = nm_settings_connection_get_connection (sett_conn); NMSettingBluetooth *s_bt; const char *bt_type; const char *bdaddr; @@ -358,24 +361,22 @@ connection_compatible (NMBluezDevice *self, NMSettingsConnection *sett_conn) } static gboolean -_internal_track_connection (NMBluezDevice *self, - NMSettingsConnection *sett_conn, - gboolean tracked) +_internal_track_connection (NMBluezDevice *self, NMConnection *connection, gboolean tracked) { NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); gboolean was_tracked; - was_tracked = !!g_slist_find (priv->connections, sett_conn); + was_tracked = !!g_slist_find (priv->connections, connection); if (was_tracked == !!tracked) return FALSE; if (tracked) - priv->connections = g_slist_prepend (priv->connections, g_object_ref (sett_conn)); + priv->connections = g_slist_prepend (priv->connections, g_object_ref (connection)); else { - priv->connections = g_slist_remove (priv->connections, sett_conn); - if (priv->pan_connection == sett_conn) + priv->connections = g_slist_remove (priv->connections, connection); + if (priv->pan_connection == connection) priv->pan_connection = NULL; - g_object_unref (sett_conn); + g_object_unref (connection); } return TRUE; @@ -383,32 +384,32 @@ _internal_track_connection (NMBluezDevice *self, static void cp_connection_added (NMSettings *settings, - NMSettingsConnection *sett_conn, + NMConnection *connection, NMBluezDevice *self) { - if (connection_compatible (self, sett_conn)) { - if (_internal_track_connection (self, sett_conn, TRUE)) + if (connection_compatible (self, connection)) { + if (_internal_track_connection (self, connection, TRUE)) check_emit_usable (self); } } static void cp_connection_removed (NMSettings *settings, - NMSettingsConnection *sett_conn, + NMConnection *connection, NMBluezDevice *self) { - if (_internal_track_connection (self, sett_conn, FALSE)) + if (_internal_track_connection (self, connection, FALSE)) check_emit_usable (self); } static void cp_connection_updated (NMSettings *settings, - NMSettingsConnection *sett_conn, + NMConnection *connection, gboolean by_user, NMBluezDevice *self) { - if (_internal_track_connection (self, sett_conn, - connection_compatible (self, sett_conn))) + if (_internal_track_connection (self, connection, + connection_compatible (self, connection))) check_emit_usable_schedule (self); } @@ -422,8 +423,10 @@ load_connections (NMBluezDevice *self) connections = nm_settings_get_connections (priv->settings, NULL); for (i = 0; connections[i]; i++) { - if (connection_compatible (self, connections[i])) - changed |= _internal_track_connection (self, connections[i], TRUE); + NMConnection *connection = (NMConnection *) connections[i]; + + if (connection_compatible (self, connection)) + changed |= _internal_track_connection (self, connection, TRUE); } if (changed) check_emit_usable (self); @@ -1175,14 +1178,14 @@ dispose (GObject *object) { NMBluezDevice *self = NM_BLUEZ_DEVICE (object); NMBluezDevicePrivate *priv = NM_BLUEZ_DEVICE_GET_PRIVATE (self); - NMSettingsConnection *to_delete = NULL; + NMConnection *to_delete = NULL; nm_clear_g_source (&priv->check_emit_usable_id); if (priv->pan_connection) { /* Check whether we want to remove the created connection. If so, we take a reference * and delete it at the end of dispose(). */ - if (NM_FLAGS_HAS (nm_settings_connection_get_flags (priv->pan_connection), + if (NM_FLAGS_HAS (nm_settings_connection_get_flags (NM_SETTINGS_CONNECTION (priv->pan_connection)), NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) to_delete = g_object_ref (priv->pan_connection); @@ -1216,8 +1219,8 @@ dispose (GObject *object) if (to_delete) { nm_log_dbg (LOGD_BT, "bluez[%s] removing Bluetooth connection for NAP device: '%s' (%s)", priv->path, - nm_settings_connection_get_id (to_delete), nm_settings_connection_get_uuid (to_delete)); - nm_settings_connection_delete (to_delete, NULL); + nm_connection_get_id (to_delete), nm_connection_get_uuid (to_delete)); + nm_settings_connection_delete (NM_SETTINGS_CONNECTION (to_delete), NULL); g_object_unref (to_delete); } diff --git a/src/devices/bluetooth/nm-bluez-manager.c b/src/devices/bluetooth/nm-bluez-manager.c index 711f2e57..c74ecd81 100644 --- a/src/devices/bluetooth/nm-bluez-manager.c +++ b/src/devices/bluetooth/nm-bluez-manager.c @@ -244,8 +244,8 @@ setup_bluez5 (NMBluezManager *self) static void watch_name_on_appeared (GDBusConnection *connection, - const char *name, - const char *name_owner, + const gchar *name, + const gchar *name_owner, gpointer user_data) { check_bluez_and_try_setup (NM_BLUEZ_MANAGER (user_data)); diff --git a/src/devices/bluetooth/nm-bluez5-manager.c b/src/devices/bluetooth/nm-bluez5-manager.c index e984212b..5d3bd23a 100644 --- a/src/devices/bluetooth/nm-bluez5-manager.c +++ b/src/devices/bluetooth/nm-bluez5-manager.c @@ -224,7 +224,7 @@ network_server_unregister_bridge (const NMBtVTableNetworkServer *vtable, } static void -network_server_removed (GDBusProxy *proxy, const char *path, NMBluez5Manager *self) +network_server_removed (GDBusProxy *proxy, const gchar *path, NMBluez5Manager *self) { NetworkServer *network_server; @@ -241,7 +241,7 @@ network_server_removed (GDBusProxy *proxy, const char *path, NMBluez5Manager *se } static void -network_server_added (GDBusProxy *proxy, const char *path, const char *addr, NMBluez5Manager *self) +network_server_added (GDBusProxy *proxy, const gchar *path, const char *addr, NMBluez5Manager *self) { NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); NetworkServer *network_server; @@ -342,7 +342,7 @@ device_initialized (NMBluezDevice *device, gboolean success, NMBluez5Manager *se } static void -device_added (GDBusProxy *proxy, const char *path, NMBluez5Manager *self) +device_added (GDBusProxy *proxy, const gchar *path, NMBluez5Manager *self) { NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); NMBluezDevice *device; @@ -356,7 +356,7 @@ device_added (GDBusProxy *proxy, const char *path, NMBluez5Manager *self) } static void -device_removed (GDBusProxy *proxy, const char *path, NMBluez5Manager *self) +device_removed (GDBusProxy *proxy, const gchar *path, NMBluez5Manager *self) { NMBluez5ManagerPrivate *priv = NM_BLUEZ5_MANAGER_GET_PRIVATE (self); NMBluezDevice *device; diff --git a/src/devices/bluetooth/nm-device-bt.c b/src/devices/bluetooth/nm-device-bt.c index 1f650d33..92ad0b31 100644 --- a/src/devices/bluetooth/nm-device-bt.c +++ b/src/devices/bluetooth/nm-device-bt.c @@ -36,7 +36,6 @@ #include "nm-setting-serial.h" #include "nm-setting-ppp.h" #include "NetworkManagerUtils.h" -#include "settings/nm-settings-connection.h" #include "nm-utils.h" #include "nm-bt-error.h" #include "platform/nm-platform.h" @@ -138,7 +137,7 @@ get_generic_capabilities (NMDevice *device) static gboolean can_auto_connect (NMDevice *device, - NMSettingsConnection *sett_conn, + NMConnection *connection, char **specific_object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE ((NMDeviceBt *) device); @@ -146,11 +145,11 @@ can_auto_connect (NMDevice *device, nm_assert (!specific_object || !*specific_object); - if (!NM_DEVICE_CLASS (nm_device_bt_parent_class)->can_auto_connect (device, sett_conn, NULL)) + if (!NM_DEVICE_CLASS (nm_device_bt_parent_class)->can_auto_connect (device, connection, NULL)) return FALSE; /* Can't auto-activate a DUN connection without ModemManager */ - bt_type = get_connection_bt_type (nm_settings_connection_get_connection (sett_conn)); + bt_type = get_connection_bt_type (connection); if (bt_type == NM_BT_CAPABILITY_DUN && priv->mm_running == FALSE) return FALSE; @@ -158,36 +157,36 @@ can_auto_connect (NMDevice *device, } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE ((NMDeviceBt *) device); + NMSettingConnection *s_con; NMSettingBluetooth *s_bt; const char *bdaddr; guint32 bt_type; - if (!NM_DEVICE_CLASS (nm_device_bt_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_bt_parent_class)->check_connection_compatible (device, connection)) return FALSE; - bt_type = get_connection_bt_type (connection); - if (!NM_FLAGS_ALL (priv->capabilities, bt_type)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device does not support bluetooth type of profile"); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_BLUETOOTH_SETTING_NAME)) return FALSE; - } s_bt = nm_connection_get_setting_bluetooth (connection); + if (!s_bt) + return FALSE; + + bt_type = get_connection_bt_type (connection); + if (!(bt_type & priv->capabilities)) + return FALSE; bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); - if (!bdaddr) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "profile lacks bdaddr setting"); + if (!bdaddr) return FALSE; - } - if (!nm_utils_hwaddr_matches (priv->bdaddr, -1, bdaddr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "devices bdaddr setting mismatches"); + if (!nm_utils_hwaddr_matches (priv->bdaddr, -1, bdaddr, -1)) return FALSE; - } return TRUE; } @@ -196,25 +195,18 @@ static gboolean check_connection_available (NMDevice *device, NMConnection *connection, NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) + const char *specific_object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE ((NMDeviceBt *) device); guint32 bt_type; bt_type = get_connection_bt_type (connection); - if (!(bt_type & priv->capabilities)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device does not support bluetooth type"); + if (!(bt_type & priv->capabilities)) return FALSE; - } /* DUN connections aren't available without ModemManager */ - if (bt_type == NM_BT_CAPABILITY_DUN && priv->mm_running == FALSE) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "ModemManager missing for DUN profile"); + if (bt_type == NM_BT_CAPABILITY_DUN && priv->mm_running == FALSE) return FALSE; - } return TRUE; } @@ -1185,8 +1177,6 @@ nm_device_bt_class_init (NMDeviceBtClass *klass) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_bluetooth); - device_class->connection_type_check_compatible = NM_SETTING_BLUETOOTH_SETTING_NAME; - device_class->get_generic_capabilities = get_generic_capabilities; device_class->can_auto_connect = can_auto_connect; device_class->deactivate = deactivate; diff --git a/src/devices/nm-device-6lowpan.c b/src/devices/nm-device-6lowpan.c deleted file mode 100644 index b6b9157c..00000000 --- a/src/devices/nm-device-6lowpan.c +++ /dev/null @@ -1,345 +0,0 @@ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2018 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include "nm-device-6lowpan.h" - -#include "nm-device-private.h" -#include "settings/nm-settings.h" -#include "platform/nm-platform.h" -#include "nm-device-factory.h" -#include "nm-setting-6lowpan.h" -#include "nm-utils.h" - -#include "nm-device-logging.h" -_LOG_DECLARE_SELF(NMDevice6Lowpan); - -/*****************************************************************************/ - -typedef struct { - gulong parent_state_id; -} NMDevice6LowpanPrivate; - -struct _NMDevice6Lowpan { - NMDevice parent; - NMDevice6LowpanPrivate _priv; -}; - -struct _NMDevice6LowpanClass { - NMDeviceClass parent; -}; - -G_DEFINE_TYPE (NMDevice6Lowpan, nm_device_6lowpan, NM_TYPE_DEVICE) - -#define NM_DEVICE_6LOWPAN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDevice6Lowpan, NM_IS_DEVICE_6LOWPAN) - -/*****************************************************************************/ - -static void -parent_state_changed (NMDevice *parent, - NMDeviceState new_state, - NMDeviceState old_state, - NMDeviceStateReason reason, - gpointer user_data) -{ - NMDevice6Lowpan *self = NM_DEVICE_6LOWPAN (user_data); - - nm_device_set_unmanaged_by_flags (NM_DEVICE (self), NM_UNMANAGED_PARENT, !nm_device_get_managed (parent, FALSE), reason); -} - -static void -parent_changed_notify (NMDevice *device, - int old_ifindex, - NMDevice *old_parent, - int new_ifindex, - NMDevice *new_parent) -{ - NMDevice6Lowpan *self = NM_DEVICE_6LOWPAN (device); - NMDevice6LowpanPrivate *priv = NM_DEVICE_6LOWPAN_GET_PRIVATE (self); - - NM_DEVICE_CLASS (nm_device_6lowpan_parent_class)->parent_changed_notify (device, old_ifindex, old_parent, new_ifindex, new_parent); - - /* note that @self doesn't have to clear @parent_state_id on dispose, - * because NMDevice's dispose() will unset the parent, which in turn calls - * parent_changed_notify(). */ - nm_clear_g_signal_handler (old_parent, &priv->parent_state_id); - - if (new_parent) { - priv->parent_state_id = g_signal_connect (new_parent, - NM_DEVICE_STATE_CHANGED, - G_CALLBACK (parent_state_changed), - device); - - /* Set parent-dependent unmanaged flag */ - nm_device_set_unmanaged_by_flags (device, - NM_UNMANAGED_PARENT, - !nm_device_get_managed (new_parent, FALSE), - NM_DEVICE_STATE_REASON_PARENT_MANAGED_CHANGED); - } - - if (new_ifindex > 0) { - /* Recheck availability now that the parent has changed */ - nm_device_queue_recheck_available (device, - NM_DEVICE_STATE_REASON_PARENT_CHANGED, - NM_DEVICE_STATE_REASON_PARENT_CHANGED); - } -} - -static gboolean -create_and_realize (NMDevice *device, - NMConnection *connection, - NMDevice *parent, - const NMPlatformLink **out_plink, - GError **error) -{ - const char *iface = nm_device_get_iface (device); - NMPlatformError plerr; - NMSetting6Lowpan *s_6lowpan; - int parent_ifindex; - - 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; - - if (parent_ifindex <= 0) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES, - "6LoWPAN devices can not be created without a parent interface"); - g_return_val_if_fail (!parent, FALSE); - return FALSE; - } - - plerr = nm_platform_link_6lowpan_add (nm_device_get_platform (device), iface, parent_ifindex, out_plink); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) { - g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create 6lowpan interface '%s' for '%s': %s", - iface, - nm_connection_get_id (connection), - nm_platform_error_to_string_a (plerr)); - return FALSE; - } - - nm_device_parent_set_ifindex (device, parent_ifindex); - - return TRUE; -} - -static NMDeviceCapabilities -get_generic_capabilities (NMDevice *dev) -{ - return NM_DEVICE_CAP_CARRIER_DETECT | NM_DEVICE_CAP_IS_SOFTWARE; -} - -static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) -{ - NMDevice6Lowpan *self = NM_DEVICE_6LOWPAN (device); - int parent = 0; - int ifindex; - - NM_DEVICE_CLASS (nm_device_6lowpan_parent_class)->link_changed (device, pllink); - - ifindex = nm_device_get_ifindex (device); - if (!nm_platform_link_6lowpan_get_properties (nm_device_get_platform (device), ifindex, &parent)) { - _LOGW (LOGD_DEVICE, "could not get 6lowpan properties"); - return; - } - - nm_device_parent_set_ifindex (device, parent); -} - -static gboolean -is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) -{ - if (!nm_device_parent_get_device (device)) - return FALSE; - return NM_DEVICE_CLASS (nm_device_6lowpan_parent_class)->is_available (device, flags); -} - -static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) -{ - NMSetting6Lowpan *s_6lowpan; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_6LOWPAN_SETTING_NAME, - existing_connections, - NULL, - _("6LOWPAN connection"), - NULL, - TRUE); - - 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."); - return FALSE; - } - - /* If there's no 6LoWPAN interface, no parent, and no hardware address in the - * settings, then there's not enough information to complete the setting. - */ - if ( !nm_setting_6lowpan_get_parent (s_6lowpan) - && !nm_device_match_parent_hwaddr (device, connection, TRUE)) { - g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, - "The '6lowpan' setting had no interface name, parent, or hardware address."); - return FALSE; - } - - return TRUE; -} - -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); - } - - g_object_set (s_6lowpan, - NM_SETTING_6LOWPAN_PARENT, - nm_device_parent_find_for_connection (device, - nm_setting_6lowpan_get_parent (s_6lowpan)), - NULL); -} - -static NMActStageReturn -act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *out_failure_reason) -{ - NMActStageReturn ret; - - ret = NM_DEVICE_CLASS (nm_device_6lowpan_parent_class)->act_stage1_prepare (dev, out_failure_reason); - if (ret != NM_ACT_STAGE_RETURN_SUCCESS) - return ret; - - if (!nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE)) - return NM_ACT_STAGE_RETURN_FAILURE; - return NM_ACT_STAGE_RETURN_SUCCESS; -} - -/*****************************************************************************/ - -static void -nm_device_6lowpan_init (NMDevice6Lowpan *self) -{ -} - -static const NMDBusInterfaceInfoExtended interface_info_device_6lowpan = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_6LOWPAN, - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Parent", "o", NM_DEVICE_PARENT), - ), - ), -}; - -static void -nm_device_6lowpan_class_init (NMDevice6LowpanClass *klass) -{ - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_6lowpan); - - device_class->connection_type_supported = NM_SETTING_6LOWPAN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_6LOWPAN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_6LOWPAN); - - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->complete_connection = complete_connection; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; - device_class->link_changed = link_changed; - device_class->is_available = is_available; - device_class->parent_changed_notify = parent_changed_notify; - device_class->update_connection = update_connection; -} - -/*****************************************************************************/ - -#define NM_TYPE_6LOWPAN_DEVICE_FACTORY (nm_6lowpan_device_factory_get_type ()) -#define NM_6LOWPAN_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_6LOWPAN_DEVICE_FACTORY, NM6LowpanDeviceFactory)) - -static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) -{ - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_6LOWPAN, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "6LoWPAN", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_6LOWPAN, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_6LOWPAN, - NULL); -} - -static const char * -get_connection_parent (NMDeviceFactory *factory, NMConnection *connection) -{ - NMSetting6Lowpan *s_6lowpan; - - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL); - - 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); -} - -static char * -get_connection_iface (NMDeviceFactory *factory, - NMConnection *connection, - const char *parent_iface) -{ - NMSetting6Lowpan *s_6lowpan; - const char *ifname; - - g_return_val_if_fail (nm_connection_is_type (connection, NM_SETTING_6LOWPAN_SETTING_NAME), NULL); - - s_6lowpan = NM_SETTING_6LOWPAN (nm_connection_get_setting (connection, NM_TYPE_SETTING_6LOWPAN)); - g_assert (s_6lowpan); - - if (!parent_iface) - return NULL; - - ifname = nm_connection_get_interface_name (connection); - return g_strdup (ifname); -} - -NM_DEVICE_FACTORY_DEFINE_INTERNAL (6LOWPAN, 6Lowpan, 6lowpan, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_6LOWPAN) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_6LOWPAN_SETTING_NAME), - factory_class->create_device = create_device; - factory_class->get_connection_parent = get_connection_parent; - factory_class->get_connection_iface = get_connection_iface; -); diff --git a/src/devices/nm-device-6lowpan.h b/src/devices/nm-device-6lowpan.h deleted file mode 100644 index 86edf4af..00000000 --- a/src/devices/nm-device-6lowpan.h +++ /dev/null @@ -1,37 +0,0 @@ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2018 Red Hat, Inc. - */ - -#ifndef __NETWORKMANAGER_DEVICE_6LOWPAN_H__ -#define __NETWORKMANAGER_DEVICE_6LOWPAN_H__ - -#include "nm-device.h" - -#define NM_TYPE_DEVICE_6LOWPAN (nm_device_6lowpan_get_type ()) -#define NM_DEVICE_6LOWPAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_6LOWPAN, NMDevice6Lowpan)) -#define NM_DEVICE_6LOWPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_6LOWPAN, NMDevice6LowpanClass)) -#define NM_IS_DEVICE_6LOWPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_6LOWPAN)) -#define NM_IS_DEVICE_6LOWPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_6LOWPAN)) -#define NM_DEVICE_6LOWPAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_6LOWPAN, NMDevice6LowpanClass)) - -typedef struct _NMDevice6Lowpan NMDevice6Lowpan; -typedef struct _NMDevice6LowpanClass NMDevice6LowpanClass; - -GType nm_device_6lowpan_get_type (void); - -#endif /* __NETWORKMANAGER_DEVICE_6LOWPAN_H__ */ diff --git a/src/devices/nm-device-bond.c b/src/devices/nm-device-bond.c index 6e7e6ffc..f59ec9ff 100644 --- a/src/devices/nm-device-bond.c +++ b/src/devices/nm-device-bond.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright 2011 - 2018 Red Hat, Inc. + * Copyright 2011 - 2016 Red Hat, Inc. */ #include "nm-default.h" @@ -56,6 +56,23 @@ get_generic_capabilities (NMDevice *dev) } static gboolean +check_connection_compatible (NMDevice *device, NMConnection *connection) +{ + NMSettingBond *s_bond; + + if (!NM_DEVICE_CLASS (nm_device_bond_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + s_bond = nm_connection_get_setting_bond (connection); + if (!s_bond || !nm_connection_is_type (connection, NM_SETTING_BOND_SETTING_NAME)) + return FALSE; + + /* FIXME: match bond properties like mode, etc? */ + + return TRUE; +} + +static gboolean complete_connection (NMDevice *device, NMConnection *connection, const char *specific_object, @@ -346,6 +363,7 @@ static NMActStageReturn act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *out_failure_reason) { NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; + gboolean no_firmware = FALSE; ret = NM_DEVICE_CLASS (nm_device_bond_parent_class)->act_stage1_prepare (dev, out_failure_reason); if (ret != NM_ACT_STAGE_RETURN_SUCCESS) @@ -356,7 +374,7 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *out_failure_reason) ret = apply_bonding_config (dev); if (ret != NM_ACT_STAGE_RETURN_FAILURE) ret = nm_device_hw_addr_set_cloned (dev, nm_device_get_applied_connection (dev), FALSE); - nm_device_bring_up (dev, TRUE, NULL); + nm_device_bring_up (dev, TRUE, &no_firmware); return ret; } @@ -368,7 +386,7 @@ enslave_slave (NMDevice *device, gboolean configure) { NMDeviceBond *self = NM_DEVICE_BOND (device); - gboolean success = TRUE; + gboolean success = TRUE, no_firmware = FALSE; const char *slave_iface = nm_device_get_ip_iface (slave); NMConnection *master_con; @@ -379,7 +397,7 @@ enslave_slave (NMDevice *device, 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_bring_up (slave, TRUE, &no_firmware); if (!success) return FALSE; @@ -416,7 +434,7 @@ release_slave (NMDevice *device, gboolean configure) { NMDeviceBond *self = NM_DEVICE_BOND (device); - gboolean success; + gboolean success, no_firmware = FALSE; gs_free char *address = NULL; if (configure) { @@ -445,7 +463,7 @@ release_slave (NMDevice *device, * IFF_UP), so we must bring it back up here to ensure carrier changes and * other state is noticed by the now-released slave. */ - if (!nm_device_bring_up (slave, TRUE, NULL)) + if (!nm_device_bring_up (slave, TRUE, &no_firmware)) _LOGW (LOGD_BOND, "released bond slave could not be brought up."); } else { _LOGI (LOGD_BOND, "bond slave %s was released", @@ -614,28 +632,27 @@ static void nm_device_bond_class_init (NMDeviceBondClass *klass) { NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_bond); - - device_class->connection_type_supported = NM_SETTING_BOND_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_BOND_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_BOND); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_BOND_SETTING_NAME, NM_LINK_TYPE_BOND) - device_class->is_master = TRUE; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->complete_connection = complete_connection; - - device_class->update_connection = update_connection; - device_class->master_update_slave_connection = master_update_slave_connection; + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_bond); - device_class->create_and_realize = create_and_realize; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; - device_class->enslave_slave = enslave_slave; - device_class->release_slave = release_slave; - device_class->can_reapply_change = can_reapply_change; - device_class->reapply_connection = reapply_connection; + parent_class->is_master = TRUE; + parent_class->get_generic_capabilities = get_generic_capabilities; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->complete_connection = complete_connection; + + parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; + + parent_class->create_and_realize = create_and_realize; + parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + parent_class->enslave_slave = enslave_slave; + parent_class->release_slave = release_slave; + parent_class->can_reapply_change = can_reapply_change; + parent_class->reapply_connection = reapply_connection; } /*****************************************************************************/ diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index e79de95c..c81a0253 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -61,63 +61,41 @@ static gboolean check_connection_available (NMDevice *device, NMConnection *connection, NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) + const char *specific_object) { NMSettingBluetooth *s_bt; - if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->check_connection_available (device, connection, flags, specific_object, error)) + if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->check_connection_available (device, connection, flags, specific_object)) return FALSE; s_bt = _nm_connection_get_setting_bluetooth_for_nap (connection); if (s_bt) { - const char *bdaddr; - - if (!nm_bt_vtable_network_server) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "bluetooth plugin not available to activate NAP profile"); - return FALSE; - } - - bdaddr = nm_setting_bluetooth_get_bdaddr (s_bt); - if (!nm_bt_vtable_network_server->is_available (nm_bt_vtable_network_server, bdaddr)) { - if (bdaddr) - nm_utils_error_set (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "not suitable NAP device \"%s\" available", bdaddr); - else - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "not suitable NAP device available"); - return FALSE; - } + return nm_bt_vtable_network_server + && nm_bt_vtable_network_server->is_available (nm_bt_vtable_network_server, + nm_setting_bluetooth_get_bdaddr (s_bt)); } return TRUE; } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMSettingBridge *s_bridge; const char *mac_address; - if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_bridge_parent_class)->check_connection_compatible (device, connection)) return FALSE; - if ( nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME) - && _nm_connection_get_setting_bluetooth_for_nap (connection)) { - s_bridge = nm_connection_get_setting_bridge (connection); - if (!s_bridge) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "missing bridge setting for bluetooth NAP profile"); - return FALSE; - } + s_bridge = nm_connection_get_setting_bridge (connection); + if (!s_bridge) + return FALSE; - /* a bluetooth NAP connection is handled by the bridge. - * - * Proceed... */ - } else { - s_bridge = _nm_connection_check_main_setting (connection, NM_SETTING_BRIDGE_SETTING_NAME, error); - if (!s_bridge) + if (!nm_connection_is_type (connection, NM_SETTING_BRIDGE_SETTING_NAME)) { + if ( nm_connection_is_type (connection, NM_SETTING_BLUETOOTH_SETTING_NAME) + && _nm_connection_get_setting_bluetooth_for_nap (connection)) { + /* a bluetooth NAP connection is handled by the bridge */ + } else return FALSE; } @@ -126,11 +104,8 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError const char *hw_addr; hw_addr = nm_device_get_hw_address (device); - if (!hw_addr || !nm_utils_hwaddr_matches (hw_addr, -1, mac_address, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "mac address mismatches"); + if (!hw_addr || !nm_utils_hwaddr_matches (hw_addr, -1, mac_address, -1)) return FALSE; - } } return TRUE; @@ -530,29 +505,28 @@ static void nm_device_bridge_class_init (NMDeviceBridgeClass *klass) { NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_BRIDGE_SETTING_NAME, NM_LINK_TYPE_BRIDGE) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_bridge); - device_class->connection_type_supported = NM_SETTING_BRIDGE_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_BRIDGE); - - device_class->is_master = TRUE; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->check_connection_compatible = check_connection_compatible; - device_class->check_connection_available = check_connection_available; - device_class->complete_connection = complete_connection; - - device_class->update_connection = update_connection; - device_class->master_update_slave_connection = master_update_slave_connection; - - device_class->create_and_realize = create_and_realize; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->deactivate = deactivate; - device_class->enslave_slave = enslave_slave; - device_class->release_slave = release_slave; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + parent_class->is_master = TRUE; + parent_class->get_generic_capabilities = get_generic_capabilities; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->check_connection_available = check_connection_available; + parent_class->complete_connection = complete_connection; + + parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; + + parent_class->create_and_realize = create_and_realize; + parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->act_stage2_config = act_stage2_config; + parent_class->deactivate = deactivate; + parent_class->enslave_slave = enslave_slave; + parent_class->release_slave = release_slave; + parent_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; } /*****************************************************************************/ diff --git a/src/devices/nm-device-dummy.c b/src/devices/nm-device-dummy.c index a9059383..9be4d29f 100644 --- a/src/devices/nm-device-dummy.c +++ b/src/devices/nm-device-dummy.c @@ -117,6 +117,21 @@ create_and_realize (NMDevice *device, return TRUE; } +static gboolean +check_connection_compatible (NMDevice *device, NMConnection *connection) +{ + NMSettingDummy *s_dummy; + + if (!NM_DEVICE_CLASS (nm_device_dummy_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + s_dummy = nm_connection_get_setting_dummy (connection); + if (!s_dummy) + return FALSE; + + return TRUE; +} + static NMActStageReturn act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) { @@ -158,13 +173,13 @@ nm_device_dummy_class_init (NMDeviceDummyClass *klass) NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_dummy); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_DUMMY) - device_class->connection_type_supported = NM_SETTING_DUMMY_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_DUMMY_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_DUMMY); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_dummy); + device_class->connection_type = NM_SETTING_DUMMY_SETTING_NAME; device_class->complete_connection = complete_connection; + device_class->check_connection_compatible = check_connection_compatible; device_class->create_and_realize = create_and_realize; device_class->get_generic_capabilities = get_generic_capabilities; device_class->update_connection = update_connection; diff --git a/src/devices/nm-device-ethernet-utils.c b/src/devices/nm-device-ethernet-utils.c index 8bdb1991..298e6dff 100644 --- a/src/devices/nm-device-ethernet-utils.c +++ b/src/devices/nm-device-ethernet-utils.c @@ -18,24 +18,33 @@ #include "nm-default.h" -#include "nm-device-ethernet-utils.h" +#include <string.h> + +#include "nm-connection.h" -#include "settings/nm-settings-connection.h" +#include "nm-device-ethernet-utils.h" char * -nm_device_ethernet_utils_get_default_wired_name (GHashTable *existing_ids) +nm_device_ethernet_utils_get_default_wired_name (NMConnection *const *connections) { char *temp; + guint j; int i; /* Find the next available unique connection name */ - for (i = 1; i <= G_MAXINT; i++) { + for (i = 1; i <= 10000; i++) { temp = g_strdup_printf (_("Wired connection %d"), i); - if ( !existing_ids - || !g_hash_table_contains (existing_ids, temp)) - return temp; - g_free (temp); + for (j = 0; connections[j]; j++) { + if (nm_streq0 (nm_connection_get_id (connections[j]), temp)) { + g_free (temp); + goto next; + } + } + return temp; +next: + ; } + return NULL; } diff --git a/src/devices/nm-device-ethernet-utils.h b/src/devices/nm-device-ethernet-utils.h index 7e5c8b31..197d0a9e 100644 --- a/src/devices/nm-device-ethernet-utils.h +++ b/src/devices/nm-device-ethernet-utils.h @@ -19,6 +19,6 @@ #ifndef __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__ #define __NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H__ -char *nm_device_ethernet_utils_get_default_wired_name (GHashTable *existing_ids); +char *nm_device_ethernet_utils_get_default_wired_name (NMConnection *const *connections); #endif /* NETWORKMANAGER_DEVICE_ETHERNET_UTILS_H */ diff --git a/src/devices/nm-device-ethernet.c b/src/devices/nm-device-ethernet.c index 0fb8fea4..a9a9f968 100644 --- a/src/devices/nm-device-ethernet.c +++ b/src/devices/nm-device-ethernet.c @@ -343,21 +343,23 @@ match_subchans (NMDeviceEthernet *self, NMSettingWired *s_wired, gboolean *try_m } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device); NMSettingWired *s_wired; - if (!NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_ethernet_parent_class)->check_connection_compatible (device, connection)) return FALSE; + s_wired = nm_connection_get_setting_wired (connection); + if (nm_connection_is_type (connection, NM_SETTING_PPPOE_SETTING_NAME)) { - s_wired = nm_connection_get_setting_wired (connection); - } else { - s_wired = _nm_connection_check_main_setting (connection, NM_SETTING_WIRED_SETTING_NAME, error); + /* NOP */ + } else if (nm_connection_is_type (connection, NM_SETTING_WIRED_SETTING_NAME)) { if (!s_wired) return FALSE; - } + } else + return FALSE; if (s_wired) { const char *mac, *perm_hw_addr; @@ -365,43 +367,28 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError const char * const *mac_blacklist; int i; - if (!match_subchans (self, s_wired, &try_mac)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "s390 subchannels don't match"); + if (!match_subchans (self, s_wired, &try_mac)) return FALSE; - } perm_hw_addr = nm_device_get_permanent_hw_address (device); mac = nm_setting_wired_get_mac_address (s_wired); if (perm_hw_addr) { - if ( try_mac - && mac - && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "permanent MAC address doesn't match"); + if (try_mac && mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) return FALSE; - } /* Check for MAC address blacklist */ mac_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); for (i = 0; mac_blacklist[i]; i++) { if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "invalid MAC in blacklist"); + g_warn_if_reached (); return FALSE; } - if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, perm_hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "permanent MAC address of device blacklisted"); + if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, perm_hw_addr, -1)) return FALSE; - } } - } else if (mac) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has no permanent MAC address to match"); + } else if (mac) return FALSE; - } } return TRUE; @@ -1198,6 +1185,7 @@ wake_on_lan_enable (NMDevice *device) NMSettingWiredWakeOnLan wol; NMSettingWired *s_wired; const char *password = NULL; + gs_free char *value = NULL; s_wired = (NMSettingWired *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRED); if (s_wired) { @@ -1207,25 +1195,27 @@ wake_on_lan_enable (NMDevice *device) goto found; } - wol = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "ethernet.wake-on-lan", - device, - NM_SETTING_WIRED_WAKE_ON_LAN_NONE, - G_MAXINT32, - NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT); - - if ( NM_FLAGS_ANY (wol, NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS) - && !nm_utils_is_power_of_two (wol)) { - nm_log_dbg (LOGD_ETHER, "invalid default value %u for wake-on-lan", (guint) wol); - wol = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT; + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "ethernet.wake-on-lan", + device); + + if (value) { + wol = _nm_utils_ascii_str_to_int64 (value, 10, + NM_SETTING_WIRED_WAKE_ON_LAN_NONE, + G_MAXINT32, + NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT); + + if ( NM_FLAGS_ANY (wol, NM_SETTING_WIRED_WAKE_ON_LAN_EXCLUSIVE_FLAGS) + && !nm_utils_is_power_of_two (wol)) { + nm_log_dbg (LOGD_ETHER, "invalid default value %u for wake-on-lan", (guint) wol); + wol = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT; + } + if (wol != NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT) + goto found; } - if (wol != NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT) - goto found; wol = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; found: - return nm_platform_ethtool_set_wake_on_lan (nm_device_get_platform (device), - nm_device_get_ifindex (device), - wol, password); + return nm_platform_ethtool_set_wake_on_lan (nm_device_get_platform (device), nm_device_get_ifindex (device), wol, password); } /*****************************************************************************/ @@ -1440,14 +1430,12 @@ new_default_connection (NMDevice *self) NMConnection *connection; NMSettingsConnection *const*connections; NMSetting *setting; - gs_unref_hashtable GHashTable *existing_ids = NULL; struct udev_device *dev; const char *perm_hw_addr; const char *uprop = "0"; gs_free char *defname = NULL; gs_free char *uuid = NULL; gs_free char *machine_id = NULL; - guint i, n_connections; if (nm_config_get_no_auto_default_for_device (nm_config_get (), self)) return NULL; @@ -1460,13 +1448,8 @@ new_default_connection (NMDevice *self) setting = nm_setting_connection_new (); nm_connection_add_setting (connection, setting); - connections = nm_settings_get_connections (nm_device_get_settings (self), &n_connections); - if (n_connections > 0) { - existing_ids = g_hash_table_new (nm_str_hash, g_str_equal); - for (i = 0; i < n_connections; i++) - g_hash_table_add (existing_ids, (char *) nm_settings_connection_get_id (connections[i])); - } - defname = nm_device_ethernet_utils_get_default_wired_name (existing_ids); + connections = nm_settings_get_connections (nm_device_get_settings (self), NULL); + defname = nm_device_ethernet_utils_get_default_wired_name ((NMConnection *const*) connections); if (!defname) return NULL; @@ -1767,10 +1750,12 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); g_type_class_add_private (object_class, sizeof (NMDeviceEthernetPrivate)); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_WIRED_SETTING_NAME, NM_LINK_TYPE_ETHERNET) + object_class->dispose = dispose; object_class->finalize = finalize; object_class->get_property = get_property; @@ -1778,28 +1763,25 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_wired); - device_class->connection_type_supported = NM_SETTING_WIRED_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_ETHERNET); - - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->check_connection_compatible = check_connection_compatible; - device_class->complete_connection = complete_connection; - device_class->new_default_connection = new_default_connection; - - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; - device_class->get_configured_mtu = get_configured_mtu; - device_class->deactivate = deactivate; - device_class->get_s390_subchannels = get_s390_subchannels; - device_class->update_connection = update_connection; - device_class->carrier_changed_notify = carrier_changed_notify; - device_class->link_changed = link_changed; - device_class->is_available = is_available; - device_class->can_reapply_change = can_reapply_change; - device_class->reapply_connection = reapply_connection; - - device_class->state_changed = device_state_changed; + parent_class->get_generic_capabilities = get_generic_capabilities; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->complete_connection = complete_connection; + parent_class->new_default_connection = new_default_connection; + + parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->act_stage2_config = act_stage2_config; + parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; + parent_class->get_configured_mtu = get_configured_mtu; + parent_class->deactivate = deactivate; + parent_class->get_s390_subchannels = get_s390_subchannels; + parent_class->update_connection = update_connection; + parent_class->carrier_changed_notify = carrier_changed_notify; + parent_class->link_changed = link_changed; + parent_class->is_available = is_available; + parent_class->can_reapply_change = can_reapply_change; + parent_class->reapply_connection = reapply_connection; + + parent_class->state_changed = device_state_changed; obj_properties[PROP_SPEED] = g_param_spec_uint (NM_DEVICE_ETHERNET_SPEED, "", "", diff --git a/src/devices/nm-device-factory.c b/src/devices/nm-device-factory.c index a11ead6e..bc717bb3 100644 --- a/src/devices/nm-device-factory.c +++ b/src/devices/nm-device-factory.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2014 - 2018 Red Hat, Inc. + * Copyright (C) 2014 Red Hat, Inc. */ #include "nm-default.h" @@ -417,7 +417,6 @@ nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc call callback, user_data); \ } G_STMT_END - _ADD_INTERNAL (nm_6lowpan_device_factory_get_type); _ADD_INTERNAL (nm_bond_device_factory_get_type); _ADD_INTERNAL (nm_bridge_device_factory_get_type); _ADD_INTERNAL (nm_dummy_device_factory_get_type); @@ -431,8 +430,6 @@ nm_device_factory_manager_load_factories (NMDeviceFactoryManagerFactoryFunc call _ADD_INTERNAL (nm_veth_device_factory_get_type); _ADD_INTERNAL (nm_vlan_device_factory_get_type); _ADD_INTERNAL (nm_vxlan_device_factory_get_type); - _ADD_INTERNAL (nm_wireguard_device_factory_get_type); - _ADD_INTERNAL (nm_wpan_device_factory_get_type); load_factories_from_dir (NMPLUGINDIR, callback, user_data); } diff --git a/src/devices/nm-device-generic.c b/src/devices/nm-device-generic.c index d00aa93b..27eaf8d6 100644 --- a/src/devices/nm-device-generic.c +++ b/src/devices/nm-device-generic.c @@ -86,19 +86,19 @@ realize_start_notify (NMDevice *device, const NMPlatformLink *plink) } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMSettingConnection *s_con; - if (!NM_DEVICE_CLASS (nm_device_generic_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_generic_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_GENERIC_SETTING_NAME)) return FALSE; s_con = nm_connection_get_setting_connection (connection); - if (!nm_setting_connection_get_interface_name (s_con)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "generic profiles need an interface name"); + if (!nm_setting_connection_get_interface_name (s_con)) return FALSE; - } return TRUE; } @@ -220,7 +220,9 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_GENERIC_SETTING_NAME, NM_LINK_TYPE_ANY) object_class->constructor = constructor; object_class->dispose = dispose; @@ -229,15 +231,11 @@ nm_device_generic_class_init (NMDeviceGenericClass *klass) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_generic); - device_class->connection_type_supported = NM_SETTING_GENERIC_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_GENERIC_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_ANY); - - device_class->realize_start_notify = realize_start_notify; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->get_type_description = get_type_description; - device_class->check_connection_compatible = check_connection_compatible; - device_class->update_connection = update_connection; + parent_class->realize_start_notify = realize_start_notify; + parent_class->get_generic_capabilities = get_generic_capabilities; + parent_class->get_type_description = get_type_description; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->update_connection = update_connection; obj_properties[PROP_TYPE_DESCRIPTION] = g_param_spec_string (NM_DEVICE_GENERIC_TYPE_DESCRIPTION, "", "", diff --git a/src/devices/nm-device-infiniband.c b/src/devices/nm-device-infiniband.c index 41fac157..99bcef00 100644 --- a/src/devices/nm-device-infiniband.c +++ b/src/devices/nm-device-infiniband.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright 2011 - 2018 Red Hat, Inc. + * Copyright 2011 Red Hat, Inc. */ #include "nm-default.h" @@ -80,7 +80,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) NMSettingInfiniband *s_infiniband; char ifname_verified[IFNAMSIZ]; const char *transport_mode; - gboolean ok; + gboolean ok, no_firmware = FALSE; ret = NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->act_stage1_prepare (device, out_failure_reason); if (ret != NM_ACT_STAGE_RETURN_SUCCESS) @@ -104,7 +104,7 @@ act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) /* With some drivers the interface must be down to set transport mode */ nm_device_take_down (device, TRUE); ok = nm_platform_sysctl_set (nm_device_get_platform (device), NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname_verified, "mode"), transport_mode); - nm_device_bring_up (device, TRUE, NULL); + nm_device_bring_up (device, TRUE, &no_firmware); if (!ok) { NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_CONFIG_FAILED); @@ -123,28 +123,30 @@ get_configured_mtu (NMDevice *device, NMDeviceMtuSource *out_source) } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMSettingInfiniband *s_infiniband; - if (!NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_infiniband_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + if (!nm_connection_is_type (connection, NM_SETTING_INFINIBAND_SETTING_NAME)) + return FALSE; + + s_infiniband = nm_connection_get_setting_infiniband (connection); + if (!s_infiniband) return FALSE; if (nm_device_is_real (device)) { const char *mac; const char *hw_addr; - s_infiniband = nm_connection_get_setting_infiniband (connection); - mac = nm_setting_infiniband_get_mac_address (s_infiniband); if (mac) { hw_addr = nm_device_get_permanent_hw_address (device); if ( !hw_addr - || !nm_utils_hwaddr_matches (mac, -1, hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "MAC address mismatches"); + || !nm_utils_hwaddr_matches (mac, -1, hw_addr, -1)) return FALSE; - } } } @@ -365,26 +367,24 @@ nm_device_infiniband_class_init (NMDeviceInfinibandClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_INFINIBAND_SETTING_NAME, NM_LINK_TYPE_INFINIBAND) object_class->get_property = get_property; object_class->set_property = set_property; dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_infiniband); - device_class->connection_type_supported = NM_SETTING_INFINIBAND_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_INFINIBAND_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_INFINIBAND); - - device_class->create_and_realize = create_and_realize; - device_class->unrealize = unrealize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->check_connection_compatible = check_connection_compatible; - device_class->complete_connection = complete_connection; - device_class->update_connection = update_connection; + parent_class->create_and_realize = create_and_realize; + parent_class->unrealize = unrealize; + parent_class->get_generic_capabilities = get_generic_capabilities; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->complete_connection = complete_connection; + parent_class->update_connection = update_connection; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->get_configured_mtu = get_configured_mtu; + parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->get_configured_mtu = get_configured_mtu; obj_properties[PROP_IS_PARTITION] = g_param_spec_boolean (NM_DEVICE_INFINIBAND_IS_PARTITION, "", "", diff --git a/src/devices/nm-device-ip-tunnel.c b/src/devices/nm-device-ip-tunnel.c index 568403c6..2e266bb9 100644 --- a/src/devices/nm-device-ip-tunnel.c +++ b/src/devices/nm-device-ip-tunnel.c @@ -179,13 +179,10 @@ clear: goto out; } - if (NM_IN_SET (priv->mode, NM_IP_TUNNEL_MODE_GRE, NM_IP_TUNNEL_MODE_GRETAP)) { + if (priv->mode == NM_IP_TUNNEL_MODE_GRE) { const NMPlatformLnkGre *lnk; - if (priv->mode == NM_IP_TUNNEL_MODE_GRE) - lnk = nm_platform_link_get_lnk_gre (nm_device_get_platform (device), ifindex, NULL); - else - lnk = nm_platform_link_get_lnk_gretap (nm_device_get_platform (device), ifindex, NULL); + lnk = nm_platform_link_get_lnk_gre (nm_device_get_platform (device), ifindex, NULL); if (!lnk) { _LOGW (LOGD_PLATFORM, "could not read %s properties", "gre"); goto clear; @@ -257,21 +254,11 @@ clear: ttl = lnk->ttl; tos = lnk->tos; pmtud = lnk->path_mtu_discovery; - } else if (NM_IN_SET (priv->mode, - NM_IP_TUNNEL_MODE_IPIP6, - NM_IP_TUNNEL_MODE_IP6IP6, - NM_IP_TUNNEL_MODE_IP6GRE, - NM_IP_TUNNEL_MODE_IP6GRETAP)) { + } else if ( priv->mode == NM_IP_TUNNEL_MODE_IPIP6 + || priv->mode == NM_IP_TUNNEL_MODE_IP6IP6) { const NMPlatformLnkIp6Tnl *lnk; - NMPlatform *plat = nm_device_get_platform (device); - - if (priv->mode == NM_IP_TUNNEL_MODE_IP6GRE) - lnk = nm_platform_link_get_lnk_ip6gre (plat, ifindex, NULL); - else if (priv->mode == NM_IP_TUNNEL_MODE_IP6GRETAP) - lnk = nm_platform_link_get_lnk_ip6gretap (plat, ifindex, NULL); - else - lnk = nm_platform_link_get_lnk_ip6tnl (plat, ifindex, NULL); + lnk = nm_platform_link_get_lnk_ip6tnl (nm_device_get_platform (device), ifindex, NULL); if (!lnk) { _LOGW (LOGD_PLATFORM, "could not read %s properties", "ip6tnl"); goto clear; @@ -285,40 +272,6 @@ clear: encap_limit = lnk->encap_limit; flow_label = lnk->flow_label; flags = ip6tnl_flags_plat_to_setting (lnk->flags); - - if (NM_IN_SET (priv->mode, - NM_IP_TUNNEL_MODE_IP6GRE, - NM_IP_TUNNEL_MODE_IP6GRETAP)) { - if (NM_FLAGS_HAS (lnk->input_flags, NM_GRE_KEY)) { - key = g_strdup_printf ("%u", lnk->input_key); - if (g_strcmp0 (priv->input_key, key)) { - g_free (priv->input_key); - priv->input_key = key; - _notify (self, PROP_INPUT_KEY); - } else - g_free (key); - } else { - if (priv->input_key) { - g_clear_pointer (&priv->input_key, g_free); - _notify (self, PROP_INPUT_KEY); - } - } - - if (NM_FLAGS_HAS (lnk->output_flags, NM_GRE_KEY)) { - key = g_strdup_printf ("%u", lnk->output_key); - if (g_strcmp0 (priv->output_key, key)) { - g_free (priv->output_key); - priv->output_key = key; - _notify (self, PROP_OUTPUT_KEY); - } else - g_free (key); - } else { - if (priv->output_key) { - g_clear_pointer (&priv->output_key, g_free); - _notify (self, PROP_OUTPUT_KEY); - } - } - } } else g_return_if_reached (); @@ -435,6 +388,8 @@ 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); + NMDevice *parent = NULL; + const char *setting_parent, *new_parent; if (!s_ip_tunnel) { s_ip_tunnel = (NMSettingIPTunnel *) nm_setting_ip_tunnel_new (); @@ -444,11 +399,25 @@ update_connection (NMDevice *device, NMConnection *connection) 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); - g_object_set (s_ip_tunnel, - NM_SETTING_IP_TUNNEL_PARENT, - nm_device_parent_find_for_connection (device, - nm_setting_ip_tunnel_get_parent (s_ip_tunnel)), - NULL); + parent = nm_device_parent_get_device (device); + + /* Update parent in the connection; default to parent's interface name */ + if (parent) { + new_parent = nm_device_get_iface (parent); + setting_parent = nm_setting_ip_tunnel_get_parent (s_ip_tunnel); + if (setting_parent && nm_utils_is_uuid (setting_parent)) { + NMConnection *parent_connection; + + /* Don't change a parent specified by UUID if it's still valid */ + parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device), + setting_parent); + if (parent_connection && nm_device_check_connection_compatible (parent, parent_connection)) + new_parent = NULL; + } + if (new_parent) + g_object_set (s_ip_tunnel, NM_SETTING_IP_TUNNEL_PARENT, new_parent, NULL); + } else + g_object_set (s_ip_tunnel, NM_SETTING_IP_TUNNEL_PARENT, NULL, NULL); if (!address_equal_pp (priv->addr_family, nm_setting_ip_tunnel_get_local (s_ip_tunnel), @@ -487,11 +456,7 @@ update_connection (NMDevice *device, NMConnection *connection) NULL); } - if (NM_IN_SET (priv->mode, - NM_IP_TUNNEL_MODE_GRE, - NM_IP_TUNNEL_MODE_GRETAP, - NM_IP_TUNNEL_MODE_IP6GRE, - NM_IP_TUNNEL_MODE_IP6GRETAP)) { + if (priv->mode == NM_IP_TUNNEL_MODE_GRE || priv->mode == NM_IP_TUNNEL_MODE_IP6GRE) { if (g_strcmp0 (nm_setting_ip_tunnel_get_input_key (s_ip_tunnel), priv->input_key)) { g_object_set (G_OBJECT (s_ip_tunnel), NM_SETTING_IP_TUNNEL_INPUT_KEY, @@ -508,79 +473,54 @@ update_connection (NMDevice *device, NMConnection *connection) } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMDeviceIPTunnel *self = NM_DEVICE_IP_TUNNEL (device); NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE (self); NMSettingIPTunnel *s_ip_tunnel; const char *parent; - if (!NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->check_connection_compatible (device, connection)) return FALSE; s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection); + if (!s_ip_tunnel) + return FALSE; - if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "incompatible IP tunnel mode"); + if (nm_setting_ip_tunnel_get_mode (s_ip_tunnel) != priv->mode) return FALSE; - } if (nm_device_is_real (device)) { /* Check parent interface; could be an interface name or a UUID */ parent = nm_setting_ip_tunnel_get_parent (s_ip_tunnel); - if (parent && !nm_device_match_parent (device, parent)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "IP tunnel parent mismatches"); + if (parent && !nm_device_match_parent (device, parent)) return FALSE; - } if (!address_equal_pp (priv->addr_family, nm_setting_ip_tunnel_get_local (s_ip_tunnel), - priv->local)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "local IP tunnel address mismatches"); + priv->local)) return FALSE; - } if (!address_equal_pp (priv->addr_family, nm_setting_ip_tunnel_get_remote (s_ip_tunnel), - priv->remote)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "remote IP tunnel address mismatches"); + priv->remote)) return FALSE; - } - if (nm_setting_ip_tunnel_get_ttl (s_ip_tunnel) != priv->ttl) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "TTL of IP tunnel mismatches"); + if (nm_setting_ip_tunnel_get_ttl (s_ip_tunnel) != priv->ttl) return FALSE; - } - if (nm_setting_ip_tunnel_get_tos (s_ip_tunnel) != priv->tos) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "TOS of IP tunnel mismatches"); + if (nm_setting_ip_tunnel_get_tos (s_ip_tunnel) != priv->tos) return FALSE; - } if (priv->addr_family == AF_INET) { - if (nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel) != priv->path_mtu_discovery) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "MTU discovery setting of IP tunnel mismatches"); + if (nm_setting_ip_tunnel_get_path_mtu_discovery (s_ip_tunnel) != priv->path_mtu_discovery) return FALSE; - } } else { - if (nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel) != priv->encap_limit) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "encapsulation limit of IP tunnel mismatches"); + if (nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel) != priv->encap_limit) return FALSE; - } - if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "flow-label of IP tunnel mismatches"); + if (nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel) != priv->flow_label) return FALSE; - } } } @@ -595,8 +535,6 @@ platform_link_to_tunnel_mode (const NMPlatformLink *link) switch (link->type) { case NM_LINK_TYPE_GRE: return NM_IP_TUNNEL_MODE_GRE; - case NM_LINK_TYPE_GRETAP: - return NM_IP_TUNNEL_MODE_GRETAP; case NM_LINK_TYPE_IP6TNL: lnk = nm_platform_link_get_lnk_ip6tnl (NM_PLATFORM_GET, link->ifindex, NULL); if (lnk) { @@ -606,10 +544,6 @@ platform_link_to_tunnel_mode (const NMPlatformLink *link) return NM_IP_TUNNEL_MODE_IP6IP6; } return NM_IP_TUNNEL_MODE_UNKNOWN; - case NM_LINK_TYPE_IP6GRE: - return NM_IP_TUNNEL_MODE_IP6GRE; - case NM_LINK_TYPE_IP6GRETAP: - return NM_IP_TUNNEL_MODE_IP6GRETAP; case NM_LINK_TYPE_IPIP: return NM_IP_TUNNEL_MODE_IPIP; case NM_LINK_TYPE_SIT: @@ -625,20 +559,15 @@ tunnel_mode_to_link_type (NMIPTunnelMode tunnel_mode) switch (tunnel_mode) { case NM_IP_TUNNEL_MODE_GRE: return NM_LINK_TYPE_GRE; - case NM_IP_TUNNEL_MODE_GRETAP: - return NM_LINK_TYPE_GRETAP; case NM_IP_TUNNEL_MODE_IPIP6: case NM_IP_TUNNEL_MODE_IP6IP6: return NM_LINK_TYPE_IP6TNL; - case NM_IP_TUNNEL_MODE_IP6GRE: - return NM_LINK_TYPE_IP6GRE; - case NM_IP_TUNNEL_MODE_IP6GRETAP: - return NM_LINK_TYPE_IP6GRETAP; case NM_IP_TUNNEL_MODE_IPIP: return NM_LINK_TYPE_IPIP; case NM_IP_TUNNEL_MODE_SIT: return NM_LINK_TYPE_SIT; case NM_IP_TUNNEL_MODE_VTI: + case NM_IP_TUNNEL_MODE_IP6GRE: case NM_IP_TUNNEL_MODE_VTI6: case NM_IP_TUNNEL_MODE_ISATAP: return NM_LINK_TYPE_UNKNOWN; @@ -666,16 +595,11 @@ create_and_realize (NMDevice *device, NMPlatformLnkIp6Tnl lnk_ip6tnl = { }; const char *str; gint64 val; - NMIPTunnelMode mode; s_ip_tunnel = nm_connection_get_setting_ip_tunnel (connection); g_assert (s_ip_tunnel); - mode = nm_setting_ip_tunnel_get_mode (s_ip_tunnel); - switch (mode) { - case NM_IP_TUNNEL_MODE_GRETAP: - lnk_gre.is_tap = TRUE; - /* fall-through */ + switch (nm_setting_ip_tunnel_get_mode (s_ip_tunnel)) { case NM_IP_TUNNEL_MODE_GRE: if (parent) lnk_gre.parent_ifindex = nm_device_get_ifindex (parent); @@ -776,8 +700,6 @@ create_and_realize (NMDevice *device, break; case NM_IP_TUNNEL_MODE_IPIP6: case NM_IP_TUNNEL_MODE_IP6IP6: - case NM_IP_TUNNEL_MODE_IP6GRE: - case NM_IP_TUNNEL_MODE_IP6GRETAP: if (parent) lnk_ip6tnl.parent_ifindex = nm_device_get_ifindex (parent); @@ -793,44 +715,13 @@ create_and_realize (NMDevice *device, lnk_ip6tnl.tclass = nm_setting_ip_tunnel_get_tos (s_ip_tunnel); lnk_ip6tnl.encap_limit = nm_setting_ip_tunnel_get_encapsulation_limit (s_ip_tunnel); lnk_ip6tnl.flow_label = nm_setting_ip_tunnel_get_flow_label (s_ip_tunnel); + lnk_ip6tnl.proto = nm_setting_ip_tunnel_get_mode (s_ip_tunnel) == NM_IP_TUNNEL_MODE_IPIP6 ? IPPROTO_IPIP : IPPROTO_IPV6; lnk_ip6tnl.flags = ip6tnl_flags_setting_to_plat (nm_setting_ip_tunnel_get_flags (s_ip_tunnel)); - if (NM_IN_SET (mode, NM_IP_TUNNEL_MODE_IP6GRE, NM_IP_TUNNEL_MODE_IP6GRETAP)) { - val = _nm_utils_ascii_str_to_int64 (nm_setting_ip_tunnel_get_input_key (s_ip_tunnel), - 10, - 0, - G_MAXUINT32, - -1); - if (val != -1) { - lnk_ip6tnl.input_key = val; - lnk_ip6tnl.input_flags = NM_GRE_KEY; - } - - val = _nm_utils_ascii_str_to_int64 (nm_setting_ip_tunnel_get_output_key (s_ip_tunnel), - 10, - 0, - G_MAXUINT32, - -1); - if (val != -1) { - lnk_ip6tnl.output_key = val; - lnk_ip6tnl.output_flags = NM_GRE_KEY; - } - - lnk_ip6tnl.is_gre = TRUE; - lnk_ip6tnl.is_tap = (mode == NM_IP_TUNNEL_MODE_IP6GRETAP); - - plerr = nm_platform_link_ip6gre_add (nm_device_get_platform (device), - iface, &lnk_ip6tnl, out_plink); - } else { - lnk_ip6tnl.proto = nm_setting_ip_tunnel_get_mode (s_ip_tunnel) == NM_IP_TUNNEL_MODE_IPIP6 - ? IPPROTO_IPIP - : IPPROTO_IPV6; - plerr = nm_platform_link_ip6tnl_add (nm_device_get_platform (device), - iface, &lnk_ip6tnl, out_plink); - } + plerr = nm_platform_link_ip6tnl_add (nm_device_get_platform (device), iface, &lnk_ip6tnl, out_plink); if (plerr != NM_PLATFORM_ERROR_SUCCESS) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED, - "Failed to create IPv6 tunnel interface '%s' for '%s': %s", + "Failed to create IPIP interface '%s' for '%s': %s", iface, nm_connection_get_id (connection), nm_platform_error_to_string_a (plerr)); @@ -961,21 +852,6 @@ set_property (GObject *object, guint prop_id, } } -static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) -{ - NMActStageReturn ret; - - ret = NM_DEVICE_CLASS (nm_device_ip_tunnel_parent_class)->act_stage1_prepare (device, out_failure_reason); - if (ret != NM_ACT_STAGE_RETURN_SUCCESS) - return ret; - - if (!nm_device_hw_addr_set_cloned (device, nm_device_get_applied_connection (device), FALSE)) - return NM_ACT_STAGE_RETURN_FAILURE; - - return NM_ACT_STAGE_RETURN_SUCCESS; -} - /*****************************************************************************/ static void @@ -988,11 +864,8 @@ constructed (GObject *object) { NMDeviceIPTunnelPrivate *priv = NM_DEVICE_IP_TUNNEL_GET_PRIVATE ((NMDeviceIPTunnel *) object); - if (NM_IN_SET (priv->mode, - NM_IP_TUNNEL_MODE_IPIP6, - NM_IP_TUNNEL_MODE_IP6IP6, - NM_IP_TUNNEL_MODE_IP6GRE, - NM_IP_TUNNEL_MODE_IP6GRETAP)) + if ( priv->mode == NM_IP_TUNNEL_MODE_IPIP6 + || priv->mode == NM_IP_TUNNEL_MODE_IP6IP6) priv->addr_family = AF_INET6; else priv->addr_family = AF_INET; @@ -1052,17 +925,6 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ip_tunnel); - device_class->connection_type_supported = NM_SETTING_IP_TUNNEL_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_IP_TUNNEL_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_GRE, - NM_LINK_TYPE_GRETAP, - NM_LINK_TYPE_IP6TNL, - NM_LINK_TYPE_IP6GRE, - NM_LINK_TYPE_IP6GRETAP, - NM_LINK_TYPE_IPIP, - NM_LINK_TYPE_SIT); - - device_class->act_stage1_prepare = act_stage1_prepare; device_class->link_changed = link_changed; device_class->can_reapply_change = can_reapply_change; device_class->complete_connection = complete_connection; @@ -1073,6 +935,13 @@ nm_device_ip_tunnel_class_init (NMDeviceIPTunnelClass *klass) device_class->get_configured_mtu = get_configured_mtu; device_class->unrealize_notify = unrealize_notify; + NM_DEVICE_CLASS_DECLARE_TYPES (klass, + NM_SETTING_IP_TUNNEL_SETTING_NAME, + NM_LINK_TYPE_GRE, + NM_LINK_TYPE_IP6TNL, + NM_LINK_TYPE_IPIP, + NM_LINK_TYPE_SIT); + obj_properties[PROP_MODE] = g_param_spec_uint (NM_DEVICE_IP_TUNNEL_MODE, "", "", 0, G_MAXUINT, 0, @@ -1215,13 +1084,7 @@ get_connection_iface (NMDeviceFactory *factory, } NM_DEVICE_FACTORY_DEFINE_INTERNAL (IP_TUNNEL, IPTunnel, ip_tunnel, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_GRE, - NM_LINK_TYPE_GRETAP, - NM_LINK_TYPE_SIT, - NM_LINK_TYPE_IPIP, - NM_LINK_TYPE_IP6TNL, - NM_LINK_TYPE_IP6GRE, - NM_LINK_TYPE_IP6GRETAP) + NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_GRE, NM_LINK_TYPE_SIT, NM_LINK_TYPE_IPIP) NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_IP_TUNNEL_SETTING_NAME), factory_class->create_device = create_device; factory_class->get_connection_parent = get_connection_parent; diff --git a/src/devices/nm-device-macsec.c b/src/devices/nm-device-macsec.c index 8ea4c8b5..166bfb57 100644 --- a/src/devices/nm-device-macsec.c +++ b/src/devices/nm-device-macsec.c @@ -627,6 +627,21 @@ deactivate (NMDevice *device) supplicant_interface_release (self); } +static gboolean +check_connection_compatible (NMDevice *device, NMConnection *connection) +{ + NMSettingMacsec *s_macsec; + + if (!NM_DEVICE_CLASS (nm_device_macsec_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + s_macsec = nm_connection_get_setting_macsec (connection); + if (!s_macsec) + return FALSE; + + return TRUE; +} + /******************************************************************/ static NMDeviceCapabilities @@ -826,26 +841,27 @@ nm_device_macsec_class_init (NMDeviceMacsecClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_MACSEC) object_class->get_property = get_property; object_class->dispose = dispose; dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_macsec); - device_class->connection_type_supported = NM_SETTING_MACSEC_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_MACSEC_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_MACSEC); - - device_class->act_stage2_config = act_stage2_config; - device_class->create_and_realize = create_and_realize; - device_class->deactivate = deactivate; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->link_changed = link_changed; - device_class->is_available = is_available; - device_class->parent_changed_notify = parent_changed_notify; - device_class->state_changed = device_state_changed; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + parent_class->act_stage2_config = act_stage2_config; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->create_and_realize = create_and_realize; + parent_class->deactivate = deactivate; + parent_class->get_generic_capabilities = get_generic_capabilities; + parent_class->link_changed = link_changed; + parent_class->is_available = is_available; + parent_class->parent_changed_notify = parent_changed_notify; + parent_class->state_changed = device_state_changed; + parent_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + + parent_class->connection_type = NM_SETTING_MACSEC_SETTING_NAME; obj_properties[PROP_SCI] = g_param_spec_uint64 (NM_DEVICE_MACSEC_SCI, "", "", diff --git a/src/devices/nm-device-macvlan.c b/src/devices/nm-device-macvlan.c index ff386c82..dc4fb3e8 100644 --- a/src/devices/nm-device-macvlan.c +++ b/src/devices/nm-device-macvlan.c @@ -290,58 +290,40 @@ is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) /*****************************************************************************/ static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE ((NMDeviceMacvlan *) device); NMSettingMacvlan *s_macvlan; const char *parent = NULL; - if (!NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_macvlan_parent_class)->check_connection_compatible (device, connection)) return FALSE; s_macvlan = nm_connection_get_setting_macvlan (connection); + if (!s_macvlan) + return FALSE; - if (nm_setting_macvlan_get_tap (s_macvlan) != priv->props.tap) { - if (priv->props.tap) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvtap device does not match macvlan profile"); - } else { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvlan device does not match macvtap profile"); - } + if (nm_setting_macvlan_get_tap (s_macvlan) != priv->props.tap) return FALSE; - } /* Before the device is realized some properties will not be set */ if (nm_device_is_real (device)) { - if (setting_mode_to_platform (nm_setting_macvlan_get_mode (s_macvlan)) != priv->props.mode) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvlan mode setting differs"); + if (setting_mode_to_platform (nm_setting_macvlan_get_mode (s_macvlan)) != priv->props.mode) return FALSE; - } - if (nm_setting_macvlan_get_promiscuous (s_macvlan) == priv->props.no_promisc) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvlan promiscuous setting differs"); + if (nm_setting_macvlan_get_promiscuous (s_macvlan) == priv->props.no_promisc) return FALSE; - } /* Check parent interface; could be an interface name or a UUID */ parent = nm_setting_macvlan_get_parent (s_macvlan); if (parent) { - if (!nm_device_match_parent (device, parent)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvlan parent setting differs"); + if (!nm_device_match_parent (device, parent)) return FALSE; - } } else { /* Parent could be a MAC address in an NMSettingWired */ - if (!nm_device_match_parent_hwaddr (device, connection, TRUE)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "macvlan parent mac setting differs"); + if (!nm_device_match_hwaddr (device, connection, TRUE)) return FALSE; - } } } @@ -377,7 +359,7 @@ complete_connection (NMDevice *device, * settings, then there's not enough information to complete the setting. */ if ( !nm_setting_macvlan_get_parent (s_macvlan) - && !nm_device_match_parent_hwaddr (device, connection, TRUE)) { + && !nm_device_match_hwaddr (device, connection, TRUE)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "The 'macvlan' setting had no interface name, parent, or hardware address."); return FALSE; @@ -391,6 +373,8 @@ update_connection (NMDevice *device, NMConnection *connection) { NMDeviceMacvlanPrivate *priv = NM_DEVICE_MACVLAN_GET_PRIVATE ((NMDeviceMacvlan *) device); NMSettingMacvlan *s_macvlan = nm_connection_get_setting_macvlan (connection); + NMDevice *parent_device; + const char *setting_parent, *new_parent; int new_mode; if (!s_macvlan) { @@ -408,11 +392,24 @@ update_connection (NMDevice *device, NMConnection *connection) if (priv->props.tap != nm_setting_macvlan_get_tap (s_macvlan)) g_object_set (s_macvlan, NM_SETTING_MACVLAN_TAP, !!priv->props.tap, NULL); - g_object_set (s_macvlan, - NM_SETTING_MACVLAN_PARENT, - nm_device_parent_find_for_connection (device, - nm_setting_macvlan_get_parent (s_macvlan)), - NULL); + /* Update parent in the connection; default to parent's interface name */ + parent_device = nm_device_parent_get_device (device); + if (parent_device) { + new_parent = nm_device_get_iface (parent_device); + setting_parent = nm_setting_macvlan_get_parent (s_macvlan); + if (setting_parent && nm_utils_is_uuid (setting_parent)) { + NMConnection *parent_connection; + + /* Don't change a parent specified by UUID if it's still valid */ + parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device), setting_parent); + if (parent_connection && nm_device_check_connection_compatible (parent_device, parent_connection)) + new_parent = NULL; + } + if (new_parent) + g_object_set (s_macvlan, NM_SETTING_MACVLAN_PARENT, new_parent, NULL); + } else + g_object_set (s_macvlan, NM_SETTING_MACVLAN_PARENT, NULL, NULL); + } static NMActStageReturn @@ -498,18 +495,17 @@ nm_device_macvlan_class_init (NMDeviceMacvlanClass *klass) NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP) + object_class->get_property = get_property; object_class->set_property = set_property; dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_macvlan); - device_class->connection_type_supported = NM_SETTING_MACVLAN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_MACVLAN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVTAP); - device_class->act_stage1_prepare = act_stage1_prepare; device_class->check_connection_compatible = check_connection_compatible; device_class->complete_connection = complete_connection; + device_class->connection_type = NM_SETTING_MACVLAN_SETTING_NAME; device_class->create_and_realize = create_and_realize; device_class->get_generic_capabilities = get_generic_capabilities; device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; diff --git a/src/devices/nm-device-ppp.c b/src/devices/nm-device-ppp.c index 74b4d710..a6abb228 100644 --- a/src/devices/nm-device-ppp.c +++ b/src/devices/nm-device-ppp.c @@ -49,6 +49,24 @@ G_DEFINE_TYPE (NMDevicePpp, nm_device_ppp, NM_TYPE_DEVICE) #define NM_DEVICE_PPP_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMDevicePpp, NM_IS_DEVICE_PPP) +static gboolean +check_connection_compatible (NMDevice *device, NMConnection *connection) +{ + NMSettingPppoe *s_pppoe; + + if (!NM_DEVICE_CLASS (nm_device_ppp_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + if (!nm_streq0 (nm_connection_get_connection_type (connection), + NM_SETTING_PPPOE_SETTING_NAME)) + return FALSE; + + s_pppoe = nm_connection_get_setting_pppoe (connection); + nm_assert (s_pppoe); + + return !!nm_setting_pppoe_get_parent (s_pppoe); +} + static NMDeviceCapabilities get_generic_capabilities (NMDevice *device) { @@ -257,21 +275,20 @@ nm_device_ppp_class_init (NMDevicePppClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_PPPOE_SETTING_NAME, NM_LINK_TYPE_PPP) object_class->dispose = dispose; dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ppp); - device_class->connection_type_supported = NM_SETTING_PPPOE_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_PPPOE_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_PPP); - - device_class->act_stage2_config = act_stage2_config; - device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; - device_class->create_and_realize = create_and_realize; - device_class->deactivate = deactivate; - device_class->get_generic_capabilities = get_generic_capabilities; + parent_class->act_stage2_config = act_stage2_config; + parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->create_and_realize = create_and_realize; + parent_class->deactivate = deactivate; + parent_class->get_generic_capabilities = get_generic_capabilities; } /*****************************************************************************/ diff --git a/src/devices/nm-device-private.h b/src/devices/nm-device-private.h index 66c715de..ba28e9e4 100644 --- a/src/devices/nm-device-private.h +++ b/src/devices/nm-device-private.h @@ -130,21 +130,12 @@ void nm_device_commit_mtu (NMDevice *self); /*****************************************************************************/ -#define NM_DEVICE_DEFINE_LINK_TYPES(...) \ - ((NM_NARG (__VA_ARGS__) == 0) \ - ? NULL \ - : ({ \ - static const struct { \ - const NMLinkType types[NM_NARG (__VA_ARGS__)]; \ - const NMLinkType sentinel; \ - } _link_types = { \ - .types = { __VA_ARGS__ }, \ - .sentinel = NM_LINK_TYPE_NONE, \ - }; \ - \ - _link_types.types; \ - })\ - ) +#define NM_DEVICE_CLASS_DECLARE_TYPES(klass, conn_type, ...) \ + NM_DEVICE_CLASS (klass)->connection_type = conn_type; \ + { \ + static const NMLinkType link_types[] = { __VA_ARGS__, NM_LINK_TYPE_NONE }; \ + NM_DEVICE_CLASS (klass)->link_types = link_types; \ + } gboolean _nm_device_hash_check_invalid_keys (GHashTable *hash, const char *setting_name, GError **error, const char **whitelist); @@ -152,8 +143,8 @@ gboolean _nm_device_hash_check_invalid_keys (GHashTable *hash, const char *setti _nm_device_hash_check_invalid_keys (hash, setting_name, error, ((const char *[]) { __VA_ARGS__, NULL })) gboolean nm_device_match_parent (NMDevice *device, const char *parent); -gboolean nm_device_match_parent_hwaddr (NMDevice *device, - NMConnection *connection, - gboolean fail_if_no_hwaddr); +gboolean nm_device_match_hwaddr (NMDevice *device, + NMConnection *connection, + gboolean fail_if_no_hwaddr); #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/devices/nm-device-tun.c b/src/devices/nm-device-tun.c index 0f76b23a..3846676c 100644 --- a/src/devices/nm-device-tun.c +++ b/src/devices/nm-device-tun.c @@ -289,14 +289,18 @@ _same_og (const char *str, gboolean og_valid, guint32 og_num) } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMDeviceTun *self = NM_DEVICE_TUN (device); NMDeviceTunPrivate *priv = NM_DEVICE_TUN_GET_PRIVATE (self); NMSettingTunMode mode; NMSettingTun *s_tun; - if (!NM_DEVICE_CLASS (nm_device_tun_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_tun_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + s_tun = nm_connection_get_setting_tun (connection); + if (!s_tun) return FALSE; if (nm_device_is_real (device)) { @@ -304,43 +308,22 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError case IFF_TUN: mode = NM_SETTING_TUN_MODE_TUN; break; case IFF_TAP: mode = NM_SETTING_TUN_MODE_TAP; break; default: - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "invalid tun type on device"); + /* Huh? */ return FALSE; } - s_tun = nm_connection_get_setting_tun (connection); - - if (mode != nm_setting_tun_get_mode (s_tun)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun mode setting mismatches"); + if (mode != nm_setting_tun_get_mode (s_tun)) return FALSE; - } - if (!_same_og (nm_setting_tun_get_owner (s_tun), priv->props.owner_valid, priv->props.owner)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun owner setting mismatches"); + if (!_same_og (nm_setting_tun_get_owner (s_tun), priv->props.owner_valid, priv->props.owner)) return FALSE; - } - if (!_same_og (nm_setting_tun_get_group (s_tun), priv->props.group_valid, priv->props.group)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun group setting mismatches"); + if (!_same_og (nm_setting_tun_get_group (s_tun), priv->props.group_valid, priv->props.group)) return FALSE; - } - if (nm_setting_tun_get_pi (s_tun) != priv->props.pi) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun pi setting mismatches"); + if (nm_setting_tun_get_pi (s_tun) != priv->props.pi) return FALSE; - } - if (nm_setting_tun_get_vnet_hdr (s_tun) != priv->props.vnet_hdr) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun vnet-hdr setting mismatches"); + if (nm_setting_tun_get_vnet_hdr (s_tun) != priv->props.vnet_hdr) return FALSE; - } - if (nm_setting_tun_get_multi_queue (s_tun) != priv->props.multi_queue) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "tun multi-queue setting mismatches"); + if (nm_setting_tun_get_multi_queue (s_tun) != priv->props.multi_queue) return FALSE; - } } return TRUE; @@ -447,14 +430,13 @@ nm_device_tun_class_init (NMDeviceTunClass *klass) NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_TUN) + object_class->get_property = get_property; dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_tun); - device_class->connection_type_supported = NM_SETTING_TUN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_TUN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_TUN); - + device_class->connection_type = NM_SETTING_TUN_SETTING_NAME; device_class->link_changed = link_changed; device_class->complete_connection = complete_connection; device_class->check_connection_compatible = check_connection_compatible; diff --git a/src/devices/nm-device-veth.c b/src/devices/nm-device-veth.c index 6f90758c..186173eb 100644 --- a/src/devices/nm-device-veth.c +++ b/src/devices/nm-device-veth.c @@ -153,13 +153,12 @@ nm_device_veth_class_init (NMDeviceVethClass *klass) NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_VETH) + object_class->get_property = get_property; dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_veth); - device_class->connection_type_supported = NULL; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_VETH); - device_class->can_unmanaged_external_down = can_unmanaged_external_down; device_class->link_changed = link_changed; device_class->parent_changed_notify = parent_changed_notify; diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c index b7f0c4e7..b0e746a8 100644 --- a/src/devices/nm-device-vlan.c +++ b/src/devices/nm-device-vlan.c @@ -331,39 +331,33 @@ is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) /*****************************************************************************/ static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE ((NMDeviceVlan *) device); NMSettingVlan *s_vlan; - const char *parent; + const char *parent = NULL; - if (!NM_DEVICE_CLASS (nm_device_vlan_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_vlan_parent_class)->check_connection_compatible (device, connection)) return FALSE; - if (nm_device_is_real (device)) { - s_vlan = nm_connection_get_setting_vlan (connection); + s_vlan = nm_connection_get_setting_vlan (connection); + if (!s_vlan) + return FALSE; - if (nm_setting_vlan_get_id (s_vlan) != priv->vlan_id) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vlan id setting mismatches"); + /* Before the device is realized some properties will not be set */ + if (nm_device_is_real (device)) { + if (nm_setting_vlan_get_id (s_vlan) != priv->vlan_id) return FALSE; - } /* Check parent interface; could be an interface name or a UUID */ parent = nm_setting_vlan_get_parent (s_vlan); if (parent) { - if (!nm_device_match_parent (device, parent)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vlan parent setting differs"); + if (!nm_device_match_parent (device, parent)) return FALSE; - } } else { /* Parent could be a MAC address in an NMSettingWired */ - if (!nm_device_match_parent_hwaddr (device, connection, TRUE)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vlan parent mac setting differs"); + if (!nm_device_match_hwaddr (device, connection, TRUE)) return FALSE; - } } } @@ -374,13 +368,12 @@ static gboolean check_connection_available (NMDevice *device, NMConnection *connection, NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) + const char *specific_object) { if (!nm_device_is_real (device)) return TRUE; - return NM_DEVICE_CLASS (nm_device_vlan_parent_class)->check_connection_available (device, connection, flags, specific_object, error); + return NM_DEVICE_CLASS (nm_device_vlan_parent_class)->check_connection_available (device, connection, flags, specific_object); } static gboolean @@ -412,7 +405,7 @@ complete_connection (NMDevice *device, * settings, then there's not enough information to complete the setting. */ if ( !nm_setting_vlan_get_parent (s_vlan) - && !nm_device_match_parent_hwaddr (device, connection, TRUE)) { + && !nm_device_match_hwaddr (device, connection, TRUE)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "The 'vlan' setting had no interface name, parent, or hardware address."); return FALSE; @@ -427,8 +420,10 @@ update_connection (NMDevice *device, NMConnection *connection) NMDeviceVlanPrivate *priv = NM_DEVICE_VLAN_GET_PRIVATE (device); NMSettingVlan *s_vlan = nm_connection_get_setting_vlan (connection); int ifindex = nm_device_get_ifindex (device); + const char *setting_parent, *new_parent; const NMPlatformLink *plink; const NMPObject *polnk; + NMDevice *parent_device; guint vlan_id; guint vlan_flags; @@ -446,11 +441,26 @@ update_connection (NMDevice *device, NMConnection *connection) if (vlan_id != nm_setting_vlan_get_id (s_vlan)) g_object_set (s_vlan, NM_SETTING_VLAN_ID, vlan_id, NULL); - g_object_set (s_vlan, - NM_SETTING_VLAN_PARENT, - nm_device_parent_find_for_connection (device, - nm_setting_vlan_get_parent (s_vlan)), - NULL); + /* Update parent in the connection; default to parent's interface name */ + parent_device = nm_device_parent_get_device (device); + if ( parent_device + && polnk + && plink->parent > 0 + && nm_device_get_ifindex (parent_device) == plink->parent) { + new_parent = nm_device_get_iface (parent_device); + setting_parent = nm_setting_vlan_get_parent (s_vlan); + if (setting_parent && nm_utils_is_uuid (setting_parent)) { + NMConnection *parent_connection; + + /* Don't change a parent specified by UUID if it's still valid */ + parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device), setting_parent); + if (parent_connection && nm_device_check_connection_compatible (parent_device, parent_connection)) + new_parent = NULL; + } + if (new_parent) + g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, new_parent, NULL); + } else + g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, NULL, NULL); if (polnk) vlan_flags = polnk->lnk_vlan.flags; @@ -589,29 +599,27 @@ nm_device_vlan_class_init (NMDeviceVlanClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_VLAN_SETTING_NAME, NM_LINK_TYPE_VLAN) object_class->get_property = get_property; dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_vlan); - device_class->connection_type_supported = NM_SETTING_VLAN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_VLAN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_VLAN); - - device_class->create_and_realize = create_and_realize; - device_class->link_changed = link_changed; - device_class->unrealize_notify = unrealize_notify; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->get_configured_mtu = get_configured_mtu; - device_class->is_available = is_available; - device_class->parent_changed_notify = parent_changed_notify; - - device_class->check_connection_compatible = check_connection_compatible; - device_class->check_connection_available = check_connection_available; - device_class->complete_connection = complete_connection; - device_class->update_connection = update_connection; + parent_class->create_and_realize = create_and_realize; + parent_class->link_changed = link_changed; + parent_class->unrealize_notify = unrealize_notify; + parent_class->get_generic_capabilities = get_generic_capabilities; + parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->get_configured_mtu = get_configured_mtu; + parent_class->is_available = is_available; + parent_class->parent_changed_notify = parent_changed_notify; + + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->check_connection_available = check_connection_available; + parent_class->complete_connection = complete_connection; + parent_class->update_connection = update_connection; obj_properties[PROP_VLAN_ID] = g_param_spec_uint (NM_DEVICE_VLAN_ID, "", "", diff --git a/src/devices/nm-device-vxlan.c b/src/devices/nm-device-vxlan.c index c34f4142..e1252223 100644 --- a/src/devices/nm-device-vxlan.c +++ b/src/devices/nm-device-vxlan.c @@ -246,108 +246,65 @@ address_matches (const char *str, in_addr_t addr4, struct in6_addr *addr6) } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE ((NMDeviceVxlan *) device); NMSettingVxlan *s_vxlan; const char *parent; - if (!NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_vxlan_parent_class)->check_connection_compatible (device, connection)) return FALSE; - if (nm_device_is_real (device)) { - s_vxlan = nm_connection_get_setting_vxlan (connection); + s_vxlan = nm_connection_get_setting_vxlan (connection); + if (!s_vxlan) + return FALSE; + if (nm_device_is_real (device)) { parent = nm_setting_vxlan_get_parent (s_vxlan); - if (parent && !nm_device_match_parent (device, parent)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan parent mismatches"); + if (parent && !nm_device_match_parent (device, parent)) return FALSE; - } - if (priv->props.id != nm_setting_vxlan_get_id (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan id mismatches"); + if (priv->props.id != nm_setting_vxlan_get_id (s_vxlan)) return FALSE; - } - if (!address_matches (nm_setting_vxlan_get_local (s_vxlan), priv->props.local, &priv->props.local6)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan local address mismatches"); + if (!address_matches (nm_setting_vxlan_get_local (s_vxlan), priv->props.local, &priv->props.local6)) return FALSE; - } - if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan remote address mismatches"); + if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6)) return FALSE; - } - if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan source port min mismatches"); + if (priv->props.src_port_min != nm_setting_vxlan_get_source_port_min (s_vxlan)) return FALSE; - } - if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan source port max mismatches"); + if (priv->props.src_port_max != nm_setting_vxlan_get_source_port_max (s_vxlan)) return FALSE; - } - if (priv->props.dst_port != nm_setting_vxlan_get_destination_port (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan destination port mismatches"); + if (priv->props.dst_port != nm_setting_vxlan_get_destination_port (s_vxlan)) return FALSE; - } - if (priv->props.tos != nm_setting_vxlan_get_tos (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan TOS mismatches"); + if (priv->props.tos != nm_setting_vxlan_get_tos (s_vxlan)) return FALSE; - } - if (priv->props.ttl != nm_setting_vxlan_get_ttl (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan TTL mismatches"); + if (priv->props.ttl != nm_setting_vxlan_get_ttl (s_vxlan)) return FALSE; - } - if (priv->props.learning != nm_setting_vxlan_get_learning (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan learning mismatches"); + if (priv->props.learning != nm_setting_vxlan_get_learning (s_vxlan)) return FALSE; - } - if (priv->props.ageing != nm_setting_vxlan_get_ageing (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan ageing mismatches"); + if (priv->props.ageing != nm_setting_vxlan_get_ageing (s_vxlan)) return FALSE; - } - if (priv->props.proxy != nm_setting_vxlan_get_proxy (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan proxy mismatches"); + if (priv->props.proxy != nm_setting_vxlan_get_proxy (s_vxlan)) return FALSE; - } - if (priv->props.rsc != nm_setting_vxlan_get_rsc (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan rsc mismatches"); + if (priv->props.rsc != nm_setting_vxlan_get_rsc (s_vxlan)) return FALSE; - } - if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan l2miss mismatches"); + if (priv->props.l2miss != nm_setting_vxlan_get_l2_miss (s_vxlan)) return FALSE; - } - if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss (s_vxlan)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "vxlan l3miss mismatches"); + if (priv->props.l3miss != nm_setting_vxlan_get_l3_miss (s_vxlan)) return FALSE; - } } return TRUE; @@ -386,6 +343,9 @@ update_connection (NMDevice *device, NMConnection *connection) { NMDeviceVxlanPrivate *priv = NM_DEVICE_VXLAN_GET_PRIVATE ((NMDeviceVxlan *) device); NMSettingVxlan *s_vxlan = nm_connection_get_setting_vxlan (connection); + NMDevice *parent_device; + const char *setting_parent; + const char *new_parent = NULL; if (!s_vxlan) { s_vxlan = (NMSettingVxlan *) nm_setting_vxlan_new (); @@ -395,11 +355,23 @@ update_connection (NMDevice *device, NMConnection *connection) 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); - g_object_set (s_vxlan, - NM_SETTING_VXLAN_PARENT, - nm_device_parent_find_for_connection (device, - nm_setting_vxlan_get_parent (s_vxlan)), - NULL); + parent_device = nm_device_parent_get_device (device); + + /* Update parent in the connection; default to parent's interface name */ + if (parent_device) { + new_parent = nm_device_get_iface (parent_device); + setting_parent = nm_setting_vxlan_get_parent (s_vxlan); + if (setting_parent && nm_utils_is_uuid (setting_parent)) { + NMConnection *parent_connection; + + /* Don't change a parent specified by UUID if it's still valid */ + parent_connection = (NMConnection *) nm_settings_get_connection_by_uuid (nm_device_get_settings (device), + setting_parent); + if (parent_connection && nm_device_check_connection_compatible (parent_device, parent_connection)) + new_parent = NULL; + } + } + g_object_set (s_vxlan, NM_SETTING_VXLAN_PARENT, new_parent, NULL); if (!address_matches (nm_setting_vxlan_get_remote (s_vxlan), priv->props.group, &priv->props.group6)) { if (priv->props.group) { @@ -605,16 +577,15 @@ nm_device_vxlan_class_init (NMDeviceVxlanClass *klass) NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_VXLAN) + object_class->get_property = get_property; dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_vxlan); - device_class->connection_type_supported = NM_SETTING_VXLAN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_VXLAN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_VXLAN); - device_class->link_changed = link_changed; device_class->unrealize_notify = unrealize_notify; + device_class->connection_type = NM_SETTING_VXLAN_SETTING_NAME; device_class->create_and_realize = create_and_realize; device_class->check_connection_compatible = check_connection_compatible; device_class->complete_connection = complete_connection; diff --git a/src/devices/nm-device-wireguard.c b/src/devices/nm-device-wireguard.c deleted file mode 100644 index 62ec0274..00000000 --- a/src/devices/nm-device-wireguard.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright 2018 Javier Arteaga <jarteaga@jbeta.is> - */ - -#include "nm-default.h" - -#include "nm-device-wireguard.h" - -#include "nm-device-private.h" -#include "platform/nm-platform.h" -#include "nm-device-factory.h" - -#include "nm-device-logging.h" -_LOG_DECLARE_SELF(NMDeviceWireGuard); - -/*****************************************************************************/ - -NM_GOBJECT_PROPERTIES_DEFINE (NMDeviceWireGuard, - PROP_PUBLIC_KEY, - PROP_LISTEN_PORT, - PROP_FWMARK, -); - -struct _NMDeviceWireGuard { - NMDevice parent; - NMPlatformLnkWireGuard props; -}; - -struct _NMDeviceWireGuardClass { - NMDeviceClass parent; -}; - -G_DEFINE_TYPE (NMDeviceWireGuard, nm_device_wireguard, NM_TYPE_DEVICE) - -/******************************************************************/ - -static GVariant * -get_public_key_as_variant (const NMDeviceWireGuard *self) -{ - return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, - self->props.public_key, sizeof (self->props.public_key), 1); -} - -static void -update_properties (NMDevice *device) -{ - NMDeviceWireGuard *self; - const NMPlatformLink *plink; - const NMPlatformLnkWireGuard *props = NULL; - int ifindex; - - g_return_if_fail (NM_IS_DEVICE_WIREGUARD (device)); - self = NM_DEVICE_WIREGUARD (device); - - ifindex = nm_device_get_ifindex (device); - props = nm_platform_link_get_lnk_wireguard (nm_device_get_platform (device), ifindex, &plink); - if (!props) { - _LOGW (LOGD_PLATFORM, "could not get wireguard properties"); - return; - } - - g_object_freeze_notify (G_OBJECT (device)); - -#define CHECK_PROPERTY_CHANGED(field, prop) \ - G_STMT_START { \ - if (self->props.field != props->field) { \ - self->props.field = props->field; \ - _notify (self, prop); \ - } \ - } G_STMT_END - -#define CHECK_PROPERTY_CHANGED_ARRAY(field, prop) \ - G_STMT_START { \ - if (memcmp (&self->props.field, &props->field, sizeof (props->field)) != 0) { \ - memcpy (&self->props.field, &props->field, sizeof (props->field)); \ - _notify (self, prop); \ - } \ - } G_STMT_END - - CHECK_PROPERTY_CHANGED_ARRAY (public_key, PROP_PUBLIC_KEY); - CHECK_PROPERTY_CHANGED (listen_port, PROP_LISTEN_PORT); - CHECK_PROPERTY_CHANGED (fwmark, PROP_FWMARK); - - g_object_thaw_notify (G_OBJECT (device)); -} - -static void -link_changed (NMDevice *device, - const NMPlatformLink *pllink) -{ - NM_DEVICE_CLASS (nm_device_wireguard_parent_class)->link_changed (device, pllink); - update_properties (device); -} - - -/******************************************************************/ - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - NMDeviceWireGuard *self = NM_DEVICE_WIREGUARD (object); - - switch (prop_id) { - case PROP_PUBLIC_KEY: - g_value_take_variant (value, get_public_key_as_variant (self)); - break; - case PROP_LISTEN_PORT: - g_value_set_uint (value, self->props.listen_port); - break; - case PROP_FWMARK: - g_value_set_uint (value, self->props.fwmark); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -nm_device_wireguard_init (NMDeviceWireGuard *self) -{ -} - -static const NMDBusInterfaceInfoExtended interface_info_device_wireguard = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_WIREGUARD, - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("PublicKey", "ay", NM_DEVICE_WIREGUARD_PUBLIC_KEY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("ListenPort", "q", NM_DEVICE_WIREGUARD_LISTEN_PORT), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("FwMark", "u", NM_DEVICE_WIREGUARD_FWMARK), - ), - ), -}; - -static void -nm_device_wireguard_class_init (NMDeviceWireGuardClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - - object_class->get_property = get_property; - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_wireguard); - - device_class->connection_type_supported = NULL; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_WIREGUARD); - - device_class->link_changed = link_changed; - - obj_properties[PROP_PUBLIC_KEY] = - g_param_spec_variant (NM_DEVICE_WIREGUARD_PUBLIC_KEY, - "", "", - G_VARIANT_TYPE ("ay"), - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_LISTEN_PORT] = - g_param_spec_uint (NM_DEVICE_WIREGUARD_LISTEN_PORT, - "", "", - 0, G_MAXUINT16, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - obj_properties[PROP_FWMARK] = - g_param_spec_uint (NM_DEVICE_WIREGUARD_FWMARK, - "", "", - 0, G_MAXUINT32, 0, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); -} - -/*************************************************************/ - -#define NM_TYPE_WIREGUARD_DEVICE_FACTORY (nm_wireguard_device_factory_get_type ()) -#define NM_WIREGUARD_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIREGUARD_DEVICE_FACTORY, NMWireGuardDeviceFactory)) - -static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) -{ - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_WIREGUARD, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "WireGuard", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WIREGUARD, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WIREGUARD, - NULL); -} - -NM_DEVICE_FACTORY_DEFINE_INTERNAL (WIREGUARD, WireGuard, wireguard, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_WIREGUARD), - factory_class->create_device = create_device; -) diff --git a/src/devices/nm-device-wireguard.h b/src/devices/nm-device-wireguard.h deleted file mode 100644 index 3ad41f9b..00000000 --- a/src/devices/nm-device-wireguard.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA. - * - * Copyright 2018 Javier Arteaga <jarteaga@jbeta.is> - */ - -#ifndef __NM_DEVICE_WIREGUARD_H__ -#define __NM_DEVICE_WIREGUARD_H__ - -#include "nm-device.h" - -#define NM_TYPE_DEVICE_WIREGUARD (nm_device_wireguard_get_type ()) -#define NM_DEVICE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuard)) -#define NM_DEVICE_WIREGUARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass)) -#define NM_IS_DEVICE_WIREGUARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIREGUARD)) -#define NM_IS_DEVICE_WIREGUARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIREGUARD)) -#define NM_DEVICE_WIREGUARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIREGUARD, NMDeviceWireGuardClass)) - -#define NM_DEVICE_WIREGUARD_PUBLIC_KEY "public-key" -#define NM_DEVICE_WIREGUARD_LISTEN_PORT "listen-port" -#define NM_DEVICE_WIREGUARD_FWMARK "fwmark" - -typedef struct _NMDeviceWireGuard NMDeviceWireGuard; -typedef struct _NMDeviceWireGuardClass NMDeviceWireGuardClass; - -GType nm_device_wireguard_get_type (void); - -#endif /* __NM_DEVICE_WIREGUARD_H__ */ diff --git a/src/devices/nm-device-wpan.c b/src/devices/nm-device-wpan.c deleted file mode 100644 index f910b0b8..00000000 --- a/src/devices/nm-device-wpan.c +++ /dev/null @@ -1,253 +0,0 @@ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2018 Lubomir Rintel <lkundrak@v3.sk> - */ - -#include "nm-default.h" - -#include "nm-manager.h" -#include "nm-device-wpan.h" - -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> - -#include "nm-act-request.h" -#include "nm-device-private.h" -#include "nm-ip4-config.h" -#include "platform/nm-platform.h" -#include "nm-device-factory.h" -#include "nm-setting-wpan.h" -#include "nm-core-internal.h" - -#include "nm-device-logging.h" -_LOG_DECLARE_SELF(NMDeviceWpan); - -/*****************************************************************************/ - -struct _NMDeviceWpan { - NMDevice parent; -}; - -struct _NMDeviceWpanClass { - NMDeviceClass parent; -}; - -G_DEFINE_TYPE (NMDeviceWpan, nm_device_wpan, NM_TYPE_DEVICE) - -/*****************************************************************************/ - -static gboolean -complete_connection (NMDevice *device, - NMConnection *connection, - const char *specific_object, - NMConnection *const*existing_connections, - GError **error) -{ - NMSettingWpan *s_wpan; - - nm_utils_complete_generic (nm_device_get_platform (device), - connection, - NM_SETTING_WPAN_SETTING_NAME, - existing_connections, - NULL, - _("WPAN connection"), - NULL, - TRUE); - - 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."); - return FALSE; - } - - return TRUE; -} - -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); - } -} - -static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) -{ - NMSettingWpan *s_wpan; - const char *mac, *hw_addr; - - if (!NM_DEVICE_CLASS (nm_device_wpan_parent_class)->check_connection_compatible (device, connection, error)) - return FALSE; - - 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) { - hw_addr = nm_device_get_hw_address (device); - if (!nm_utils_hwaddr_matches (mac, -1, hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "MAC address mismatches"); - return FALSE; - } - } - - return TRUE; -} - -static NMActStageReturn -act_stage1_prepare (NMDevice *device, NMDeviceStateReason *out_failure_reason) -{ - NMDeviceWpan *self = NM_DEVICE_WPAN (device); - NMConnection *connection; - NMSettingWpan *s_wpan; - NMPlatform *platform; - guint16 pan_id; - guint16 short_address; - int ifindex; - const guint8 *hwaddr; - gsize hwaddr_len = 0; - const NMPlatformLink *lowpan_plink; - NMDevice *lowpan_device = NULL; - NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; - - ret = NM_DEVICE_CLASS (nm_device_wpan_parent_class)->act_stage1_prepare (device, out_failure_reason); - if (ret != NM_ACT_STAGE_RETURN_SUCCESS) - return ret; - - platform = nm_device_get_platform (device); - g_return_val_if_fail (platform, NM_ACT_STAGE_RETURN_FAILURE); - - ifindex = nm_device_get_ifindex (device); - g_return_val_if_fail (ifindex > 0, NM_ACT_STAGE_RETURN_FAILURE); - - connection = nm_device_get_applied_connection (device); - g_return_val_if_fail (connection, NM_ACT_STAGE_RETURN_FAILURE); - - 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); - g_return_val_if_fail (hwaddr, NM_ACT_STAGE_RETURN_FAILURE); - - /* As of kernel 4.16, the 6LoWPAN devices layered on top of WPANs - * need to be DOWN as well as the WPAN device itself in order to - * modify the WPAN properties. */ - lowpan_plink = nm_platform_link_get_by_address (platform, - NM_LINK_TYPE_6LOWPAN, - hwaddr, - hwaddr_len); - if (lowpan_plink && NM_FLAGS_HAS (lowpan_plink->n_ifi_flags, IFF_UP)) { - lowpan_device = nm_manager_get_device_by_ifindex (nm_manager_get (), - lowpan_plink->ifindex); - } - - if (lowpan_device) - nm_device_take_down (lowpan_device, TRUE); - - nm_device_take_down (device, TRUE); - - pan_id = nm_setting_wpan_get_pan_id (s_wpan); - if (pan_id != G_MAXUINT16) { - if (!nm_platform_wpan_set_pan_id (platform, ifindex, pan_id)) { - _LOGW (LOGD_DEVICE, "unable to set the PAN ID"); - goto out; - } - } - - short_address = nm_setting_wpan_get_short_address (s_wpan); - if (short_address != G_MAXUINT16) { - if (!nm_platform_wpan_set_short_addr (platform, ifindex, short_address)) { - _LOGW (LOGD_DEVICE, "unable to set the short address"); - goto out; - } - } - - ret = NM_ACT_STAGE_RETURN_SUCCESS; -out: - nm_device_bring_up (device, TRUE, NULL); - - if (lowpan_device) - nm_device_bring_up (lowpan_device, TRUE, NULL); - - return ret; -} - -/*****************************************************************************/ - -static void -nm_device_wpan_init (NMDeviceWpan *self) -{ -} - -static const NMDBusInterfaceInfoExtended interface_info_device_wpan = { - .parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT ( - NM_DBUS_INTERFACE_DEVICE_WPAN, - .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("HwAddress", "s", NM_DEVICE_HW_ADDRESS), - ), - ), -}; - -static void -nm_device_wpan_class_init (NMDeviceWpanClass *klass) -{ - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_wpan); - - device_class->connection_type_supported = NM_SETTING_WPAN_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_WPAN_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_WPAN); - - device_class->complete_connection = complete_connection; - device_class->check_connection_compatible = check_connection_compatible; - device_class->update_connection = update_connection; - device_class->act_stage1_prepare = act_stage1_prepare; -} - -/*****************************************************************************/ - -#define NM_TYPE_WPAN_DEVICE_FACTORY (nm_wpan_device_factory_get_type ()) -#define NM_WPAN_DEVICE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WPAN_DEVICE_FACTORY, NMWpanDeviceFactory)) - -static NMDevice * -create_device (NMDeviceFactory *factory, - const char *iface, - const NMPlatformLink *plink, - NMConnection *connection, - gboolean *out_ignore) -{ - return (NMDevice *) g_object_new (NM_TYPE_DEVICE_WPAN, - NM_DEVICE_IFACE, iface, - NM_DEVICE_TYPE_DESC, "WPAN", - NM_DEVICE_DEVICE_TYPE, NM_DEVICE_TYPE_WPAN, - NM_DEVICE_LINK_TYPE, NM_LINK_TYPE_WPAN, - NULL); -} - -NM_DEVICE_FACTORY_DEFINE_INTERNAL (WPAN, Wpan, wpan, - NM_DEVICE_FACTORY_DECLARE_LINK_TYPES (NM_LINK_TYPE_WPAN) - NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES (NM_SETTING_WPAN_SETTING_NAME), - factory_class->create_device = create_device; -); diff --git a/src/devices/nm-device-wpan.h b/src/devices/nm-device-wpan.h deleted file mode 100644 index 33f24776..00000000 --- a/src/devices/nm-device-wpan.h +++ /dev/null @@ -1,35 +0,0 @@ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright 2018 Lubomir Rintel <lkundrak@v3.sk> - */ - -#ifndef __NETWORKMANAGER_DEVICE_WPAN_H__ -#define __NETWORKMANAGER_DEVICE_WPAN_H__ - -#define NM_TYPE_DEVICE_WPAN (nm_device_wpan_get_type ()) -#define NM_DEVICE_WPAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WPAN, NMDeviceWpan)) -#define NM_DEVICE_WPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WPAN, NMDeviceWpanClass)) -#define NM_IS_DEVICE_WPAN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WPAN)) -#define NM_IS_DEVICE_WPAN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WPAN)) -#define NM_DEVICE_WPAN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WPAN, NMDeviceWpanClass)) - -typedef struct _NMDeviceWpan NMDeviceWpan; -typedef struct _NMDeviceWpanClass NMDeviceWpanClass; - -GType nm_device_wpan_get_type (void); - -#endif /* __NETWORKMANAGER_DEVICE_WPAN_H__ */ diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 8ca899a2..33dd5e50 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2018 Red Hat, Inc. + * Copyright (C) 2005 - 2017 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ @@ -43,7 +43,6 @@ #include "nm-utils/nm-random-utils.h" #include "nm-utils/unaligned.h" -#include "nm-ethtool-utils.h" #include "nm-common-macros.h" #include "nm-device-private.h" #include "NetworkManagerUtils.h" @@ -66,7 +65,6 @@ #include "nm-firewall-manager.h" #include "settings/nm-settings-connection.h" #include "settings/nm-settings.h" -#include "nm-setting-ethtool.h" #include "nm-auth-utils.h" #include "nm-netns.h" #include "nm-dispatcher.h" @@ -80,10 +78,7 @@ #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); @@ -177,12 +172,6 @@ struct _NMDeviceConnectivityHandle { bool is_periodic_bump_on_complete:1; }; -typedef struct { - int ifindex; - NMEthtoolFeatureStates *features; - NMTernary requested[_NM_ETHTOOL_ID_FEATURE_NUM]; -} EthtoolState; - /*****************************************************************************/ enum { @@ -519,8 +508,6 @@ typedef struct _NMDevicePrivate { GHashTable * ip6_saved_properties; - EthtoolState *ethtool_state; - struct { NMDhcpClient * client; NMNDiscDHCPLevel mode; @@ -627,7 +614,7 @@ static void _set_state_full (NMDevice *self, static void queued_state_clear (NMDevice *device); static gboolean queued_ip4_config_change (gpointer user_data); static gboolean queued_ip6_config_change (gpointer user_data); -static void ip_check_ping_watch_cb (GPid pid, int status, gpointer user_data); +static void ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data); static gboolean ip_config_valid (NMDeviceState state); static NMActStageReturn dhcp4_start (NMDevice *self); static gboolean dhcp6_start (NMDevice *self, gboolean wait_for_ll); @@ -737,7 +724,6 @@ NM_UTILS_LOOKUP_STR_DEFINE (nm_device_state_reason_to_str, NMDeviceStateReason, 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"), ); #define reason_to_string(reason) \ @@ -753,86 +739,6 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (mtu_source_to_str, NMDeviceMtuSource, /*****************************************************************************/ -static void -_ethtool_state_reset (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - if (priv->ethtool_state) { - gs_free NMEthtoolFeatureStates *features = priv->ethtool_state->features; - gs_free EthtoolState *ethtool_state = g_steal_pointer (&priv->ethtool_state); - - if (!nm_platform_ethtool_set_features (nm_device_get_platform (self), - ethtool_state->ifindex, - features, - ethtool_state->requested, - FALSE)) - _LOGW (LOGD_DEVICE, "ethtool: failure resetting one or more offload features"); - else - _LOGD (LOGD_DEVICE, "ethtool: offload features successfully reset"); - } -} - -static void -_ethtool_state_set (NMDevice *self) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - int ifindex; - NMConnection *connection; - NMSettingEthtool *s_ethtool; - NMPlatform *platform; - gs_free EthtoolState *ethtool_state = NULL; - gs_free NMEthtoolFeatureStates *features = NULL; - - _ethtool_state_reset (self); - - connection = nm_device_get_applied_connection (self); - if (!connection) - return; - - ifindex = nm_device_get_ip_ifindex (self); - if (ifindex <= 0) - return; - - s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (connection, NM_TYPE_SETTING_ETHTOOL)); - if (!s_ethtool) - return; - - ethtool_state = g_new (EthtoolState, 1); - if (nm_setting_ethtool_init_features (s_ethtool, ethtool_state->requested) == 0) - return; - - platform = nm_device_get_platform (self); - - features = nm_platform_ethtool_get_link_features (platform, ifindex); - if (!features) { - _LOGW (LOGD_DEVICE, "ethtool: failure setting offload features (cannot read features)"); - return; - } - - if (!nm_platform_ethtool_set_features (platform, - ifindex, - features, - ethtool_state->requested, - TRUE)) - _LOGW (LOGD_DEVICE, "ethtool: failure setting one or more offload features"); - else - _LOGD (LOGD_DEVICE, "ethtool: offload features successfully set"); - - ethtool_state->ifindex = ifindex; - ethtool_state->features = g_steal_pointer (&features); - priv->ethtool_state = g_steal_pointer (ðtool_state); -} - -/*****************************************************************************/ - -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) { @@ -1111,19 +1017,15 @@ nm_device_assume_state_reset (NMDevice *self) static void init_ip_config_dns_priority (NMDevice *self, NMIPConfig *config) { - const char *property; - int priority; - - property = (nm_ip_config_get_addr_family (config) == AF_INET) - ? "ipv4.dns-priority" - : "ipv6.dns-priority"; - - priority = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - property, - self, - G_MININT, - G_MAXINT, - 0); + gs_free char *value = NULL; + gint priority; + + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + (nm_ip_config_get_addr_family (config) == AF_INET) + ? "ipv4.dns-priority" + : "ipv6.dns-priority", + self); + priority = _nm_utils_ascii_str_to_int64 (value, 10, G_MININT, G_MAXINT, 0); nm_ip_config_set_dns_priority (config, priority ?: NM_DNS_PRIORITY_DEFAULT_NORMAL); } @@ -1725,41 +1627,6 @@ nm_device_parent_notify_changed (NMDevice *self, /*****************************************************************************/ -const char * -nm_device_parent_find_for_connection (NMDevice *self, - const char *current_setting_parent) -{ - const char *new_parent; - NMDevice *parent_device; - - parent_device = nm_device_parent_get_device (self); - if (!parent_device) - return NULL; - - new_parent = nm_device_get_iface (parent_device); - if (!new_parent) - return NULL; - - if ( current_setting_parent - && !nm_streq (current_setting_parent, new_parent) - && nm_utils_is_uuid (current_setting_parent)) { - NMSettingsConnection *parent_connection; - - /* Don't change a parent specified by UUID if it's still valid */ - parent_connection = nm_settings_get_connection_by_uuid (nm_device_get_settings (self), - current_setting_parent); - if ( parent_connection - && nm_device_check_connection_compatible (parent_device, - nm_settings_connection_get_connection (parent_connection), - NULL)) - return current_setting_parent; - } - - return new_parent; -} - -/*****************************************************************************/ - static void _stats_update_counters (NMDevice *self, guint64 tx_bytes, @@ -1864,11 +1731,7 @@ static gboolean get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMPlatform *platform = nm_device_get_platform (self); const NMPlatformLink *pllink; - const guint8 *hwaddr; - guint8 pseudo_hwaddr[ETH_ALEN]; - guint hwaddr_len; int ifindex; gboolean success; @@ -1876,7 +1739,7 @@ get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid) ifindex = nm_device_get_ip_ifindex (self); g_return_val_if_fail (ifindex > 0, FALSE); - pllink = nm_platform_link_get (platform, ifindex); + pllink = nm_platform_link_get (nm_device_get_platform (self), ifindex); if ( !pllink || NM_IN_SET (pllink->type, NM_LINK_TYPE_NONE, NM_LINK_TYPE_UNKNOWN)) return FALSE; @@ -1886,35 +1749,9 @@ get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid) if (pllink->addr.len > NM_UTILS_HWADDR_LEN_MAX) g_return_val_if_reached (FALSE); - hwaddr = pllink->addr.data; - hwaddr_len = pllink->addr.len; - - if (pllink->type == NM_LINK_TYPE_6LOWPAN) { - /* If the underlying IEEE 802.15.4 device has a short address we generate - * a "pseudo 48-bit address" that's to be used in the same fashion as a - * wired Ethernet address. The mechanism is specified in Section 6. of - * RFC 4944 */ - guint16 pan_id; - guint16 short_addr; - - short_addr = nm_platform_wpan_get_short_addr (platform, pllink->parent); - if (short_addr != G_MAXUINT16) { - pan_id = nm_platform_wpan_get_pan_id (platform, pllink->parent); - pseudo_hwaddr[0] = short_addr & 0xff; - pseudo_hwaddr[1] = (short_addr >> 8) & 0xff; - pseudo_hwaddr[2] = 0; - pseudo_hwaddr[3] = 0; - pseudo_hwaddr[4] = pan_id & 0xff; - pseudo_hwaddr[5] = (pan_id >> 8) & 0xff; - - hwaddr = pseudo_hwaddr; - hwaddr_len = G_N_ELEMENTS (pseudo_hwaddr); - } - } - success = nm_utils_get_ipv6_interface_identifier (pllink->type, - hwaddr, - hwaddr_len, + pllink->addr.data, + pllink->addr.len, priv->dev_id, out_iid); if (!success) { @@ -2028,9 +1865,7 @@ nm_device_get_route_metric_default (NMDeviceType device_type) */ switch (device_type) { - /* 50 is also used for VPN plugins (NM_VPN_ROUTE_METRIC_DEFAULT) */ - case NM_DEVICE_TYPE_WIREGUARD: - return 50; + /* 50 is reserved for VPN (NM_VPN_ROUTE_METRIC_DEFAULT) */ case NM_DEVICE_TYPE_ETHERNET: case NM_DEVICE_TYPE_VETH: return 100; @@ -2070,14 +1905,10 @@ nm_device_get_route_metric_default (NMDeviceType device_type) return 700; case NM_DEVICE_TYPE_BT: return 750; - case NM_DEVICE_TYPE_6LOWPAN: - return 775; case NM_DEVICE_TYPE_OVS_BRIDGE: case NM_DEVICE_TYPE_OVS_INTERFACE: case NM_DEVICE_TYPE_OVS_PORT: return 800; - case NM_DEVICE_TYPE_WPAN: - return 850; case NM_DEVICE_TYPE_GENERIC: return 950; case NM_DEVICE_TYPE_UNKNOWN: @@ -2122,10 +1953,10 @@ guint32 nm_device_get_route_metric (NMDevice *self, int addr_family) { + char *value; gint64 route_metric; NMSettingIPConfig *s_ip; NMConnection *connection; - const char *property; g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32); g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), G_MAXUINT32); @@ -2150,13 +1981,15 @@ nm_device_get_route_metric (NMDevice *self, /* use the current NMConfigData, which makes this configuration reloadable. * Note that that means that the route-metric might change between SIGHUP. * You must cache the returned value if that is a problem. */ - property = addr_family == AF_INET ? "ipv4.route-metric" : "ipv6.route-metric"; - route_metric = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - property, - self, - 0, G_MAXUINT32, -1); - if (route_metric >= 0) - goto out; + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + addr_family == AF_INET ? "ipv4.route-metric" : "ipv6.route-metric", self); + if (value) { + route_metric = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, -1); + g_free (value); + + if (route_metric >= 0) + goto out; + } route_metric = nm_manager_device_route_metric_reserve (nm_manager_get (), nm_device_get_ip_ifindex (self), @@ -2176,37 +2009,21 @@ _get_mdns (NMDevice *self) connection = nm_device_get_applied_connection (self); if (connection) mdns = nm_setting_connection_get_mdns (nm_connection_get_setting_connection (connection)); - if (mdns != NM_SETTING_CONNECTION_MDNS_DEFAULT) - return mdns; - return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "connection.mdns", - self, - NM_SETTING_CONNECTION_MDNS_NO, - NM_SETTING_CONNECTION_MDNS_YES, - NM_SETTING_CONNECTION_MDNS_DEFAULT); -} + if (mdns == NM_SETTING_CONNECTION_MDNS_DEFAULT) { + gs_free char *value = NULL; -static NMSettingConnectionLlmnr -_get_llmnr (NMDevice *self) -{ - NMConnection *connection; - NMSettingConnectionLlmnr llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT; - - g_return_val_if_fail (NM_IS_DEVICE (self), NM_SETTING_CONNECTION_LLMNR_DEFAULT); - - connection = nm_device_get_applied_connection (self); - if (connection) - llmnr = nm_setting_connection_get_llmnr (nm_connection_get_setting_connection (connection)); - if (llmnr != NM_SETTING_CONNECTION_LLMNR_DEFAULT) - return llmnr; + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "connection.mdns", + self); + mdns = _nm_utils_ascii_str_to_int64 (value, + 10, + NM_SETTING_CONNECTION_MDNS_NO, + NM_SETTING_CONNECTION_MDNS_YES, + NM_SETTING_CONNECTION_MDNS_DEFAULT); + } - return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "connection.llmnr", - self, - NM_SETTING_CONNECTION_LLMNR_NO, - NM_SETTING_CONNECTION_LLMNR_YES, - NM_SETTING_CONNECTION_LLMNR_DEFAULT); + return mdns; } guint32 @@ -2249,13 +2066,14 @@ nm_device_get_route_table (NMDevice *self, * connection. Otherwise, the connection is not active, and the * connection default doesn't matter. */ if (route_table == 0) { - const char *property; + gs_free char *value = NULL; - property = addr_family == AF_INET ? "ipv4.route-table" : "ipv6.route-table"; - route_table = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - property, - self, - 0, G_MAXUINT32, 0); + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + addr_family == AF_INET + ? "ipv4.route-table" + : "ipv6.route-table", + self); + route_table = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, 0); } } @@ -2373,22 +2191,6 @@ nm_device_get_settings_connection (NMDevice *self) } NMConnection * -nm_device_get_settings_connection_get_connection (NMDevice *self) -{ - NMSettingsConnection *sett_con; - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - - if (!priv->act_request.obj) - return NULL; - - sett_con = nm_act_request_get_settings_connection (priv->act_request.obj); - if (!sett_con) - return NULL; - - return nm_settings_connection_get_connection (sett_con); -} - -NMConnection * nm_device_get_applied_connection (NMDevice *self) { NMDevicePrivate *priv; @@ -2470,7 +2272,7 @@ concheck_is_possible (NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); if ( !nm_device_is_real (self) - || is_loopback (self)) + || NM_FLAGS_HAS (priv->unmanaged_flags, NM_UNMANAGED_LOOPBACK)) return FALSE; /* we enable periodic checks for every device state (except UNKNOWN). Especially with @@ -2813,7 +2615,6 @@ static void concheck_cb (NMConnectivity *connectivity, NMConnectivityCheckHandle *c_handle, NMConnectivityState state, - GError *error, gpointer user_data) { _nm_unused gs_unref_object NMDevice *self_keep_alive = NULL; @@ -2834,7 +2635,7 @@ concheck_cb (NMConnectivity *connectivity, handle->c_handle = NULL; self = handle->self; - if (nm_utils_error_is_cancelled (error, FALSE)) { + if (state == NM_CONNECTIVITY_CANCELLED) { /* the only place where we nm_connectivity_check_cancel(@c_handle), is * from inside concheck_handle_complete(). This is a recursive call, * nothing to do. */ @@ -2843,15 +2644,14 @@ concheck_cb (NMConnectivity *connectivity, return; } + /* we keep NMConnectivity instance alive. It cannot be disposing. */ + nm_assert (state != NM_CONNECTIVITY_DISPOSING); + self_keep_alive = g_object_ref (self); - _LOGT (LOGD_CONCHECK, "connectivity: complete check (seq:%llu, state:%s%s%s%s)", + _LOGT (LOGD_CONCHECK, "connectivity: complete check (seq:%llu, state:%s)", (long long unsigned) handle->seq, - nm_connectivity_state_to_string (state), - NM_PRINT_FMT_QUOTED (error, ", error: ", error->message, "", "")); - - /* we keep NMConnectivity instance alive. It cannot be disposing. */ - nm_assert (!nm_utils_error_is_cancelled (error, TRUE)); + nm_connectivity_state_to_string (state)); /* keep @self alive, while we invoke callbacks. */ priv = NM_DEVICE_GET_PRIVATE (self); @@ -4101,7 +3901,7 @@ nm_device_update_from_platform_link (NMDevice *self, const NMPlatformLink *plink } static void -device_init_static_sriov_num_vfs (NMDevice *self) +device_init_sriov_num_vfs (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gs_free char *value = NULL; @@ -4115,8 +3915,8 @@ device_init_static_sriov_num_vfs (NMDevice *self) NULL); num_vfs = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXINT32, -1); if (num_vfs >= 0) { - nm_platform_link_set_sriov_params (nm_device_get_platform (self), - priv->ifindex, num_vfs, -1); + nm_platform_link_set_sriov_num_vfs (nm_device_get_platform (self), + priv->ifindex, num_vfs); } } } @@ -4135,7 +3935,7 @@ config_changed (NMConfig *config, priv->ignore_carrier = nm_config_data_get_ignore_carrier (config_data, self); if (NM_FLAGS_HAS (changes, NM_CONFIG_CHANGE_VALUES)) - device_init_static_sriov_num_vfs (self); + device_init_sriov_num_vfs (self); } static void @@ -4279,7 +4079,7 @@ realize_start_setup (NMDevice *self, nm_device_set_carrier_from_platform (self); - device_init_static_sriov_num_vfs (self); + device_init_sriov_num_vfs (self); nm_assert (!priv->stats.timeout_id); real_rate = _stats_refresh_rate_real (priv->stats.refresh_rate_ms); @@ -4299,13 +4099,10 @@ realize_start_setup (NMDevice *self, NM_UNMANAGED_EXTERNAL_DOWN, is_unmanaged_external_down (self, TRUE)); - /* Unmanaged the loopback device with an explicit NM_UNMANAGED_BY_TYPE flag. + /* Unmanaged the loopback device with an explicit NM_UNMANAGED_LOOPBACK 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_BY_TYPE, - is_loopback (self) - || NM_IS_DEVICE_WIREGUARD (self)); + nm_device_set_unmanaged_flags (self, NM_UNMANAGED_LOOPBACK, priv->ifindex == 1); nm_device_set_unmanaged_by_user_udev (self); nm_device_set_unmanaged_by_user_conf (self); @@ -4501,7 +4298,7 @@ nm_device_unrealize (NMDevice *self, gboolean remove_resources, GError **error) nm_device_set_unmanaged_flags (self, NM_UNMANAGED_PARENT | - NM_UNMANAGED_BY_TYPE | + NM_UNMANAGED_LOOPBACK | NM_UNMANAGED_USER_UDEV | NM_UNMANAGED_USER_EXPLICIT | NM_UNMANAGED_EXTERNAL_DOWN | @@ -5242,7 +5039,7 @@ nm_device_autoconnect_allowed (NMDevice *self) static gboolean can_auto_connect (NMDevice *self, - NMSettingsConnection *sett_conn, + NMConnection *connection, char **specific_object) { nm_assert (!specific_object || !*specific_object); @@ -5252,27 +5049,27 @@ can_auto_connect (NMDevice *self, /** * nm_device_can_auto_connect: * @self: an #NMDevice - * @sett_conn: a #NMSettingsConnection + * @connection: a #NMConnection * @specific_object: (out) (transfer full): on output, the path of an * object associated with the returned connection, to be passed to * nm_manager_activate_connection(), or %NULL. * - * Checks if @sett_conn can be auto-activated on @self right now. + * Checks if @connection can be auto-activated on @self right now. * This requires, at a minimum, that the connection be compatible with * @self, and that it have the #NMSettingConnection:autoconnect property * set, and that the device allow auto connections. Some devices impose * additional requirements. (Eg, a Wi-Fi connection can only be activated * if its SSID was seen in the last scan.) * - * Returns: %TRUE, if the @sett_conn can be auto-activated. + * Returns: %TRUE, if the @connection can be auto-activated. **/ gboolean nm_device_can_auto_connect (NMDevice *self, - NMSettingsConnection *sett_conn, + NMConnection *connection, char **specific_object) { g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn), FALSE); + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); g_return_val_if_fail (!specific_object || !*specific_object, FALSE); /* the caller must ensure that nm_device_autoconnect_allowed() returns @@ -5284,14 +5081,10 @@ nm_device_can_auto_connect (NMDevice *self, * over and over again. The caller is supposed to do that. */ nm_assert (nm_device_autoconnect_allowed (self)); - if (!nm_device_check_connection_available (self, - nm_settings_connection_get_connection (sett_conn), - NM_DEVICE_CHECK_CON_AVAILABLE_NONE, - NULL, - NULL)) + if (!nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, NULL)) return FALSE; - if (!NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, sett_conn, specific_object)) + if (!NM_DEVICE_GET_CLASS (self)->can_auto_connect (self, connection, specific_object)) return FALSE; return TRUE; @@ -5412,10 +5205,8 @@ nm_device_generate_connection (NMDevice *self, NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), NULL); - - if (klass->connection_type_supported) - g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, klass->connection_type_supported, NULL); - + if (klass->connection_type) + g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, klass->connection_type, NULL); nm_connection_add_setting (connection, s_con); /* If the device is a slave, update various slave settings */ @@ -5567,9 +5358,9 @@ nm_device_match_parent (NMDevice *self, const char *parent) } gboolean -nm_device_match_parent_hwaddr (NMDevice *device, - NMConnection *connection, - gboolean fail_if_no_hwaddr) +nm_device_match_hwaddr (NMDevice *device, + NMConnection *connection, + gboolean fail_if_no_hwaddr) { NMSettingWired *s_wired; NMDevice *parent_device; @@ -5593,62 +5384,21 @@ nm_device_match_parent_hwaddr (NMDevice *device, } static gboolean -check_connection_compatible (NMDevice *self, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *self, NMConnection *connection) { const char *device_iface = nm_device_get_iface (self); - gs_free_error GError *local = NULL; - gs_free char *conn_iface = NULL; - NMDeviceClass *klass; - const char *const *patterns; - NMSettingMatch *s_match; - guint num_patterns; - - klass = NM_DEVICE_GET_CLASS (self); - if (klass->connection_type_check_compatible) { - if (!_nm_connection_check_main_setting (connection, - 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 (), - connection, - NULL, - &local); + gs_free char *conn_iface = nm_manager_get_connection_iface (nm_manager_get (), + connection, + NULL, NULL); /* We always need a interface name for virtual devices, but for * physical ones a connection without interface name is fine for * any device. */ - if (!conn_iface) { - if (nm_connection_is_virtual (connection)) { - nm_utils_error_set (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "cannot get interface name due to %s", local->message); - return FALSE; - } - } else if (!nm_streq0 (conn_iface, device_iface)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "mismatching interface name"); - return FALSE; - } + if (!conn_iface) + return !nm_connection_is_virtual (connection); - s_match = (NMSettingMatch *) nm_connection_get_setting (connection, - NM_TYPE_SETTING_MATCH); - if (s_match) { - patterns = nm_setting_match_get_interface_names (s_match, &num_patterns); - if (!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"); - return FALSE; - } - } + if (strcmp (conn_iface, device_iface) != 0) + return FALSE; return TRUE; } @@ -5657,11 +5407,6 @@ check_connection_compatible (NMDevice *self, NMConnection *connection, GError ** * nm_device_check_connection_compatible: * @self: an #NMDevice * @connection: an #NMConnection - * @error: optional reason why it is incompatible. Note that the - * error code is set to %NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, - * if the profile is fundamentally incompatible with the device - * (most commonly, because the device-type does not support the - * connection-type). * * Checks if @connection could potentially be activated on @self. * This means only that @self has the proper capabilities, and that @@ -5674,12 +5419,12 @@ check_connection_compatible (NMDevice *self, NMConnection *connection, GError ** * @self. */ gboolean -nm_device_check_connection_compatible (NMDevice *self, NMConnection *connection, GError **error) +nm_device_check_connection_compatible (NMDevice *self, NMConnection *connection) { g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); - return NM_DEVICE_GET_CLASS (self)->check_connection_compatible (self, connection, error); + return NM_DEVICE_GET_CLASS (self)->check_connection_compatible (self, connection); } gboolean @@ -5695,7 +5440,7 @@ nm_device_check_slave_connection_compatible (NMDevice *self, NMConnection *slave return FALSE; /* All masters should have connection type set */ - connection_type = NM_DEVICE_GET_CLASS (self)->connection_type_supported; + connection_type = NM_DEVICE_GET_CLASS (self)->connection_type; g_return_val_if_fail (connection_type, FALSE); s_con = nm_connection_get_setting_connection (slave); @@ -6066,151 +5811,24 @@ lldp_rx_enabled (NMDevice *self) lldp = nm_setting_connection_get_lldp (s_con); if (lldp == NM_SETTING_CONNECTION_LLDP_DEFAULT) { - lldp = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "connection.lldp", - self, - NM_SETTING_CONNECTION_LLDP_DEFAULT, - NM_SETTING_CONNECTION_LLDP_ENABLE_RX, - NM_SETTING_CONNECTION_LLDP_DEFAULT); + gs_free char *value = NULL; + + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "connection.lldp", + self); + lldp = _nm_utils_ascii_str_to_int64 (value, 10, + NM_SETTING_CONNECTION_LLDP_DEFAULT, + NM_SETTING_CONNECTION_LLDP_ENABLE_RX, + NM_SETTING_CONNECTION_LLDP_DEFAULT); if (lldp == NM_SETTING_CONNECTION_LLDP_DEFAULT) lldp = NM_SETTING_CONNECTION_LLDP_DISABLE; } return lldp == NM_SETTING_CONNECTION_LLDP_ENABLE_RX; } -static NMPlatformVF * -sriov_vf_config_to_platform (NMDevice *self, - NMSriovVF *vf, - GError **error) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - gs_free NMPlatformVF *plat_vf = NULL; - const guint *vlan_ids; - GVariant *variant; - guint i, num_vlans; - gsize length; - - g_return_val_if_fail (!error || !*error, FALSE); - - vlan_ids = nm_sriov_vf_get_vlan_ids (vf, &num_vlans); - plat_vf = g_malloc0 ( sizeof (NMPlatformVF) - + sizeof (NMPlatformVFVlan) * num_vlans); - - plat_vf->index = nm_sriov_vf_get_index (vf); - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK); - if (variant) - plat_vf->spoofchk = g_variant_get_boolean (variant); - else - plat_vf->spoofchk = -1; - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_TRUST); - if (variant) - plat_vf->trust = g_variant_get_boolean (variant); - else - plat_vf->trust = -1; - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MAC); - if (variant) { - if (!_nm_utils_hwaddr_aton (g_variant_get_string (variant, NULL), - plat_vf->mac.data, - sizeof (plat_vf->mac.data), - &length)) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "invalid MAC %s", - g_variant_get_string (variant, NULL)); - return NULL; - } - if (length != priv->hw_addr_len) { - g_set_error (error, - NM_DEVICE_ERROR, - NM_DEVICE_ERROR_FAILED, - "wrong MAC length %" G_GSIZE_FORMAT ", should be %u", - length, priv->hw_addr_len); - return NULL; - } - plat_vf->mac.len = length; - } - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MIN_TX_RATE); - if (variant) - plat_vf->min_tx_rate = g_variant_get_uint32 (variant); - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MAX_TX_RATE); - if (variant) - plat_vf->max_tx_rate = g_variant_get_uint32 (variant); - - plat_vf->num_vlans = num_vlans; - plat_vf->vlans = (NMPlatformVFVlan *) (&plat_vf[1]); - for (i = 0; i < num_vlans; i++) { - plat_vf->vlans[i].id = vlan_ids[i]; - plat_vf->vlans[i].qos = nm_sriov_vf_get_vlan_qos (vf, vlan_ids[i]); - plat_vf->vlans[i].proto_ad = nm_sriov_vf_get_vlan_protocol (vf, vlan_ids[i]) == NM_SRIOV_VF_VLAN_PROTOCOL_802_1AD; - } - - return g_steal_pointer (&plat_vf); -} - static NMActStageReturn act_stage1_prepare (NMDevice *self, NMDeviceStateReason *out_failure_reason) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMSettingSriov *s_sriov; - guint i, num; - - if ( priv->ifindex > 0 - && nm_device_has_capability (self, NM_DEVICE_CAP_SRIOV) - && (s_sriov = (NMSettingSriov *) nm_device_get_applied_setting (self, NM_TYPE_SETTING_SRIOV))) { - nm_auto_freev NMPlatformVF **plat_vfs = NULL; - gs_free_error GError *error = NULL; - NMSriovVF *vf; - int autoprobe; - - autoprobe = nm_setting_sriov_get_autoprobe_drivers (s_sriov); - if (autoprobe == NM_TERNARY_DEFAULT) { - autoprobe = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "sriov.autoprobe-drivers", - self, - NM_TERNARY_FALSE, - NM_TERNARY_TRUE, - NM_TERNARY_TRUE); - } - - num = nm_setting_sriov_get_num_vfs (s_sriov); - plat_vfs = g_new0 (NMPlatformVF *, num + 1); - for (i = 0; i < num; i++) { - vf = nm_setting_sriov_get_vf (s_sriov, i); - plat_vfs[i] = sriov_vf_config_to_platform (self, vf, &error); - if (!plat_vfs[i]) { - _LOGE (LOGD_DEVICE, - "failed to apply SR-IOV VF '%s': %s", - nm_utils_sriov_vf_to_str (vf, FALSE, NULL), - error->message); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - } - - if (!nm_platform_link_set_sriov_params (nm_device_get_platform (self), - priv->ifindex, - nm_setting_sriov_get_total_vfs (s_sriov), - autoprobe)) { - _LOGE (LOGD_DEVICE, "failed to apply SR-IOV parameters"); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - - if (!nm_platform_link_set_sriov_vfs (nm_device_get_platform (self), - priv->ifindex, - (const NMPlatformVF *const *) plat_vfs)) { - _LOGE (LOGD_DEVICE, "failed to apply SR-IOV VFs"); - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_SRIOV_CONFIGURATION_FAILED); - return NM_ACT_STAGE_RETURN_FAILURE; - } - } - return NM_ACT_STAGE_RETURN_SUCCESS; } @@ -6414,8 +6032,6 @@ activate_stage2_device_config (NMDevice *self) if (!nm_device_sys_iface_state_is_external_or_assume (self)) { NMDeviceStateReason failure_reason = NM_DEVICE_STATE_REASON_NONE; - _ethtool_state_set (self); - if (!tc_commit (self)) { _LOGW (LOGD_IP6, "failed applying traffic control rules"); nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED); @@ -6530,22 +6146,27 @@ get_ipv4_dad_timeout (NMDevice *self) { NMConnection *connection; NMSettingIPConfig *s_ip4 = NULL; - int timeout = -1; + gs_free char *value = NULL; + gint ret = 0; connection = nm_device_get_applied_connection (self); if (connection) s_ip4 = nm_connection_get_setting_ip4_config (connection); - if (s_ip4) - timeout = nm_setting_ip_config_get_dad_timeout (s_ip4); - if (timeout >= 0) - return timeout; - return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "ipv4.dad-timeout", - self, - 0, - NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, - 0); + if (s_ip4) { + ret = nm_setting_ip_config_get_dad_timeout (s_ip4); + + if (ret < 0) { + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "ipv4.dad-timeout", self); + ret = _nm_utils_ascii_str_to_int64 (value, 10, -1, + NM_SETTING_IP_CONFIG_DAD_TIMEOUT_MAX, + -1); + ret = ret < 0 ? 0 : ret; + } + } + + return ret; } static void @@ -6565,30 +6186,15 @@ acd_data_destroy (gpointer ptr, GClosure *closure) static void ipv4_manual_method_apply (NMDevice *self, NMIP4Config **configs, gboolean success) { - NMConnection *connection; - const char *method; NMIP4Config *empty; - connection = nm_device_get_applied_connection (self); - nm_assert (connection); - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - nm_assert (NM_IN_STRSET (method, - NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP4_CONFIG_METHOD_AUTO)); - - if (!success) { - nm_device_ip_method_failed (self, AF_INET, - NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE); - return; - } - - if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { + if (success) { empty = _ip4_config_new (self); nm_device_activate_schedule_ip4_config_result (self, empty); g_object_unref (empty); } else { - if (NM_DEVICE_GET_PRIVATE (self)->ip4_state != IP_DONE) - ip_config_merge_and_apply (self, AF_INET, TRUE); + nm_device_ip_method_failed (self, AF_INET, + NM_DEVICE_STATE_REASON_IP_ADDRESS_DUPLICATE); } } @@ -6926,7 +6532,6 @@ ensure_con_ip_config (NMDevice *self, int addr_family) nm_ip4_config_merge_setting (NM_IP4_CONFIG (con_ip_config), nm_connection_get_setting_ip4_config (connection), _get_mdns (self), - _get_llmnr (self), nm_device_get_route_table (self, addr_family, TRUE), nm_device_get_route_metric (self, addr_family)); } else { @@ -7339,7 +6944,6 @@ dhcp4_state_changed (NMDhcpClient *client, nm_ip4_config_merge_setting (manual, nm_connection_get_setting_ip4_config (connection), NM_SETTING_CONNECTION_MDNS_DEFAULT, - NM_SETTING_CONNECTION_LLMNR_DEFAULT, nm_device_get_route_table (self, AF_INET, TRUE), nm_device_get_route_metric (self, AF_INET)); @@ -7394,14 +6998,19 @@ get_dhcp_timeout (NMDevice *self, int addr_family) if (timeout) return timeout; - timeout = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - addr_family == AF_INET - ? "ipv4.dhcp-timeout" - : "ipv6.dhcp-timeout", - self, - 0, G_MAXINT32, 0); - if (timeout) - return timeout; + { + gs_free char *value = NULL; + + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + addr_family == AF_INET + ? "ipv4.dhcp-timeout" + : "ipv6.dhcp-timeout", + self); + timeout = _nm_utils_ascii_str_to_int64 (value, 10, + 0, G_MAXINT32, 0); + if (timeout) + return timeout; + } klass = NM_DEVICE_GET_CLASS (self); if (klass->get_dhcp_timeout) @@ -7561,7 +7170,6 @@ 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); @@ -7592,14 +7200,10 @@ dhcp4_start (NMDevice *self) client_id, get_dhcp_timeout (self, AF_INET), priv->dhcp_anycast_address, - NULL, - &error); + NULL); - if (!priv->dhcp4.client) { - _LOGW (LOGD_DHCP4, "failure to start DHCP: %s", error->message); - g_clear_error (&error); + if (!priv->dhcp4.client) return NM_ACT_STAGE_RETURN_FAILURE; - } priv->dhcp4.state_sigid = g_signal_connect (priv->dhcp4.client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, @@ -7840,45 +7444,30 @@ act_stage3_ip4_config_start (NMDevice *self, method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - if (NM_IN_STRSET (method, - NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NM_SETTING_IP4_CONFIG_METHOD_MANUAL)) { - NMSettingIPConfig *s_ip4; - NMIP4Config **configs, *config; - guint num_addresses; - - s_ip4 = nm_connection_get_setting_ip4_config (connection); - g_return_val_if_fail (s_ip4, NM_ACT_STAGE_RETURN_FAILURE); - num_addresses = nm_setting_ip_config_get_num_addresses (s_ip4); - - if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { - ret = dhcp4_start (self); - if (ret == NM_ACT_STAGE_RETURN_FAILURE) { - NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_DHCP_START_FAILED); - return ret; - } - } else { - g_return_val_if_fail (num_addresses != 0, NM_ACT_STAGE_RETURN_FAILURE); - ret = NM_ACT_STAGE_RETURN_POSTPONE; - } - - if (num_addresses) { - config = _ip4_config_new (self); - nm_ip4_config_merge_setting (config, - nm_connection_get_setting_ip4_config (connection), - NM_SETTING_CONNECTION_MDNS_DEFAULT, - NM_SETTING_CONNECTION_LLMNR_DEFAULT, - nm_device_get_route_table (self, AF_INET, TRUE), - nm_device_get_route_metric (self, AF_INET)); - configs = g_new0 (NMIP4Config *, 2); - configs[0] = config; - ipv4_dad_start (self, configs, ipv4_manual_method_apply); - } - } else if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { + /* Start IPv4 addressing based on the method requested */ + if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0) { + ret = dhcp4_start (self); + if (ret == NM_ACT_STAGE_RETURN_FAILURE) + NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_DHCP_START_FAILED); + } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL) == 0) { ret = ipv4ll_start (self); if (ret == NM_ACT_STAGE_RETURN_FAILURE) NM_SET_OUT (out_failure_reason, NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED); - } else if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) { + } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL) == 0) { + NMIP4Config **configs, *config; + + config = _ip4_config_new (self); + nm_ip4_config_merge_setting (config, + nm_connection_get_setting_ip4_config (connection), + NM_SETTING_CONNECTION_MDNS_DEFAULT, + nm_device_get_route_table (self, AF_INET, TRUE), + nm_device_get_route_metric (self, AF_INET)); + + configs = g_new0 (NMIP4Config *, 2); + configs[0] = config; + ipv4_dad_start (self, configs, ipv4_manual_method_apply); + ret = NM_ACT_STAGE_RETURN_POSTPONE; + } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) { if (out_config) { *out_config = shared4_new_config (self, connection); if (*out_config) { @@ -7890,7 +7479,7 @@ act_stage3_ip4_config_start (NMDevice *self, } } else g_return_val_if_reached (NM_ACT_STAGE_RETURN_FAILURE); - } else if (nm_streq (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) + } else if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0) ret = NM_ACT_STAGE_RETURN_SUCCESS; else _LOGW (LOGD_IP4, "unhandled IPv4 config method '%s'; will fail", method); @@ -8155,35 +7744,35 @@ static GBytes * generate_duid_llt (const guint8 *hwaddr /* ETH_ALEN bytes */, gint64 time) { - guint8 *arr; + GByteArray *duid_arr; const guint16 duid_type = htons (1); const guint16 hw_type = htons (ARPHRD_ETHER); const guint32 duid_time = htonl (NM_MAX (0, time - EPOCH_DATETIME_200001010000)); - arr = g_new (guint8, 2 + 2 + 4 + ETH_ALEN); + duid_arr = g_byte_array_sized_new (2 + 4 + 2 + ETH_ALEN); - memcpy (&arr[0], &duid_type, 2); - memcpy (&arr[2], &hw_type, 2); - memcpy (&arr[4], &duid_time, 4); - memcpy (&arr[8], hwaddr, ETH_ALEN); + g_byte_array_append (duid_arr, (const guint8 *) &duid_type, 2); + g_byte_array_append (duid_arr, (const guint8 *) &hw_type, 2); + g_byte_array_append (duid_arr, (const guint8 *) &duid_time, 4); + g_byte_array_append (duid_arr, hwaddr, ETH_ALEN); - return g_bytes_new_take (arr, 2 + 2 + 4 + ETH_ALEN); + return g_byte_array_free_to_bytes (duid_arr); } static GBytes * generate_duid_ll (const guint8 *hwaddr /* ETH_ALEN bytes */) { - guint8 *arr; + GByteArray *duid_arr; const guint16 duid_type = htons (3); const guint16 hw_type = htons (ARPHRD_ETHER); - arr = g_new (guint8, 2 + 2 + ETH_ALEN); + duid_arr = g_byte_array_sized_new (2 + 2 + ETH_ALEN); - memcpy (&arr[0], &duid_type, 2); - memcpy (&arr[2], &hw_type, 2); - memcpy (&arr[4], hwaddr, ETH_ALEN); + g_byte_array_append (duid_arr, (const guint8 *) &duid_type, 2); + g_byte_array_append (duid_arr, (const guint8 *) &hw_type, 2); + g_byte_array_append (duid_arr, hwaddr, ETH_ALEN); - return g_bytes_new_take (arr, 2 + 2 + ETH_ALEN); + return g_byte_array_free_to_bytes (duid_arr); } static GBytes * @@ -8401,7 +7990,6 @@ 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; @@ -8441,29 +8029,23 @@ 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, - &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.needed_prefixes); - 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 (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); + } if (nm_device_sys_iface_state_is_external_or_assume (self)) priv->dhcp6.was_active = TRUE; - return TRUE; + return !!priv->dhcp6.client; } static gboolean @@ -8786,10 +8368,10 @@ gint64 nm_device_get_configured_mtu_from_connection_default (NMDevice *self, const char *property_name) { - return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - property_name, - self, - 0, G_MAXUINT32, -1); + gs_free char *str = NULL; + + str = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, property_name, self); + return _nm_utils_ascii_str_to_int64 (str, 10, 0, G_MAXUINT32, -1); } guint32 @@ -9442,8 +9024,7 @@ set_nm_ipv6ll (NMDevice *self, gboolean enable) _LOGD (LOGD_IP6, "will %s userland IPv6LL", detail); plerr = nm_platform_link_set_user_ipv6ll_enabled (nm_device_get_platform (self), ifindex, enable); if (plerr != NM_PLATFORM_ERROR_SUCCESS) { - _NMLOG (( plerr == NM_PLATFORM_ERROR_NOT_FOUND - || plerr == NM_PLATFORM_ERROR_OPNOTSUPP) ? LOGL_DEBUG : LOGL_WARN, + _NMLOG (plerr == NM_PLATFORM_ERROR_NOT_FOUND ? LOGL_DEBUG : LOGL_WARN, LOGD_IP6, "failed to %s userspace IPv6LL address handling (%s)", detail, @@ -9486,6 +9067,7 @@ static NMSettingIP6ConfigPrivacy _ip6_privacy_get (NMDevice *self) { NMSettingIP6ConfigPrivacy ip6_privacy; + gs_free char *value = NULL; NMConnection *connection; g_return_val_if_fail (self, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); @@ -9504,13 +9086,14 @@ _ip6_privacy_get (NMDevice *self) } } + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "ipv6.ip6-privacy", self); + /* 2.) use the default value from the configuration. */ - ip6_privacy = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "ipv6.ip6-privacy", - self, - NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, - NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, - NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + ip6_privacy = _nm_utils_ascii_str_to_int64 (value, 10, + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN, + NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, + NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); if (ip6_privacy != NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN) return ip6_privacy; @@ -10740,7 +10323,6 @@ nm_device_reactivate_ip4_config (NMDevice *self, nm_ip4_config_merge_setting (priv->con_ip_config_4, s_ip4_new, _get_mdns (self), - _get_llmnr (self), nm_device_get_route_table (self, AF_INET, TRUE), nm_device_get_route_metric (self, AF_INET)); @@ -10912,9 +10494,7 @@ can_reapply_change (NMDevice *self, const char *setting_name, NM_SETTING_CONNECTION_AUTOCONNECT, NM_SETTING_CONNECTION_ZONE, NM_SETTING_CONNECTION_METERED, - NM_SETTING_CONNECTION_LLDP, - NM_SETTING_CONNECTION_MDNS, - NM_SETTING_CONNECTION_LLMNR); + NM_SETTING_CONNECTION_LLDP); } else if (NM_IN_STRSET (setting_name, NM_SETTING_PROXY_SETTING_NAME)) { return TRUE; @@ -11158,7 +10738,7 @@ reapply_cb (NMDevice *self, nm_device_sys_iface_state_set (self, NM_DEVICE_SYS_IFACE_STATE_MANAGED); if (!check_and_reapply_connection (self, - connection ?: nm_device_get_settings_connection_get_connection (self), + connection ? : (NMConnection *) nm_device_get_settings_connection (self), version_id, &audit_args, &local)) { @@ -11645,7 +11225,7 @@ _carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req) if (!connection_requires_carrier (connection)) return FALSE; - if (!nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL, NULL, NULL)) { + if (!nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL, NULL)) { /* We passed all @flags we have, and no @specific_object. * This equals maximal availability, if a connection is not available * in this case, it is not waiting for carrier. @@ -11656,9 +11236,7 @@ _carrier_wait_check_act_request_must_queue (NMDevice *self, NMActRequest *req) return FALSE; } - if (nm_device_check_connection_available (self, connection, - NM_DEVICE_CHECK_CON_AVAILABLE_ALL & ~_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER, - NULL, NULL)) { + if (nm_device_check_connection_available (self, connection, NM_DEVICE_CHECK_CON_AVAILABLE_ALL & ~_NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_WAITING_CARRIER, NULL)) { /* The connection was available with flags ALL, and it is still available * if we pretend not to wait for carrier. That means that the * connection is available now, and does not wait for carrier. @@ -11946,8 +11524,7 @@ nm_device_set_ip_config (NMDevice *self, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED) && nm_active_connection_get_activation_type (NM_ACTIVE_CONNECTION (priv->act_request.obj)) == NM_ACTIVATION_TYPE_EXTERNAL) { g_object_freeze_notify (G_OBJECT (settings_connection)); - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - nm_connection_add_setting (nm_settings_connection_get_connection (settings_connection), + nm_connection_add_setting (NM_CONNECTION (settings_connection), IS_IPv4 ? nm_ip4_config_create_setting (priv->ip_config_4) : nm_ip6_config_create_setting (priv->ip_config_6)); @@ -12156,11 +11733,11 @@ spawn_ping (NMDevice *self) gboolean ret; args[6] = str_timeout = g_strdup_printf ("%u", priv->gw_ping.deadline); - tmp_str = g_strjoinv (" ", (char **) args); + tmp_str = g_strjoinv (" ", (gchar **) args); _LOGD (priv->gw_ping.log_domain, "ping: running '%s'", tmp_str); ret = g_spawn_async ("/", - (char **) args, + (gchar **) args, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, @@ -12196,7 +11773,7 @@ respawn_ping_cb (gpointer user_data) } static void -ip_check_ping_watch_cb (GPid pid, int status, gpointer user_data) +ip_check_ping_watch_cb (GPid pid, gint status, gpointer user_data) { NMDevice *self = NM_DEVICE (user_data); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -12892,7 +12469,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_BY_TYPE, "by-type"), + NM_UTILS_FLAGS2STR (NM_UNMANAGED_LOOPBACK, "loopback"), 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"), @@ -13406,7 +12983,7 @@ nm_device_reapply_settings_immediately (NMDevice *self) NM_SETTING_COMPARE_FLAG_IGNORE_REAPPLY_IMMEDIATELY)) return; - s_con_settings = nm_connection_get_setting_connection (nm_settings_connection_get_connection (settings_connection)); + s_con_settings = nm_connection_get_setting_connection ((NMConnection *) settings_connection); s_con_applied = nm_connection_get_setting_connection (applied_connection); if (g_strcmp0 ((zone = nm_setting_connection_get_zone (s_con_settings)), @@ -13520,89 +13097,38 @@ static gboolean _nm_device_check_connection_available (NMDevice *self, NMConnection *connection, NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) + const char *specific_object) { NMDeviceState state; - GError *local = NULL; /* an unrealized software device is always available, hardware devices never. */ if (!nm_device_is_real (self)) { - if (nm_device_is_software (self)) { - if (!nm_device_check_connection_compatible (self, connection, - error ? &local : NULL)) { - if (error) { - g_return_val_if_fail (local, FALSE); - nm_utils_error_set (error, - local->domain == NM_UTILS_ERROR - ? local->code - : NM_UTILS_ERROR_UNKNOWN, - "profile is not compatible with software device (%s)", - local->message); - g_error_free (local); - } - return FALSE; - } - return TRUE; - } - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, - "hardware device is not realized"); + if (nm_device_is_software (self)) + return nm_device_check_connection_compatible (self, connection); return FALSE; } state = nm_device_get_state (self); - if (state < NM_DEVICE_STATE_UNMANAGED) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, - "device is in unknown state"); + if (state < NM_DEVICE_STATE_UNMANAGED) + return FALSE; + if ( state < NM_DEVICE_STATE_UNAVAILABLE + && ( ( !NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST) + && !nm_device_get_managed (self, FALSE)) + || ( NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST) + && !nm_device_get_managed (self, TRUE)))) return FALSE; - } - if (state < NM_DEVICE_STATE_UNAVAILABLE) { - if (NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)) { - if (!nm_device_get_managed (self, TRUE)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, - "device is unmanaged"); - return FALSE; - } - } else { - if (!nm_device_get_managed (self, FALSE)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_UNMANAGED_DEVICE, - "device is unmanaged for interal request"); - return FALSE; - } - } - } if ( state < NM_DEVICE_STATE_DISCONNECTED - && !nm_device_is_software (self)) { - if (NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST)) { - if (!nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device is not available"); - return FALSE; - } - } else { - if (!nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device is not available for internal request"); - return FALSE; - } - } - } + && !nm_device_is_software (self) + && ( ( !NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST) + && !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_NONE)) + || ( NM_FLAGS_ANY (flags, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST) + && !nm_device_is_available (self, NM_DEVICE_CHECK_DEV_AVAILABLE_FOR_USER_REQUEST)))) + return FALSE; - if (!nm_device_check_connection_compatible (self, connection, - error ? &local : NULL)) { - if (error) { - nm_utils_error_set (error, - local->domain == NM_UTILS_ERROR - ? local->code - : NM_UTILS_ERROR_UNKNOWN, - "profile is not compatible with device (%s)", - local->message); - g_error_free (local); - } + if (!nm_device_check_connection_compatible (self, connection)) return FALSE; - } - return NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, flags, specific_object, error); + return NM_DEVICE_GET_CLASS (self)->check_connection_available (self, connection, flags, specific_object); } /** @@ -13615,7 +13141,6 @@ _nm_device_check_connection_available (NMDevice *self, * @specific_object: a device type dependent argument to further * filter the result. Passing a non %NULL specific object can only reduce * the availability of a connection. - * @error: optionally give reason why not available. * * Check if @connection is available to be activated on @self. * @@ -13625,12 +13150,11 @@ gboolean nm_device_check_connection_available (NMDevice *self, NMConnection *connection, NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) + const char *specific_object) { gboolean available; - available = _nm_device_check_connection_available (self, connection, flags, specific_object, error); + available = _nm_device_check_connection_available (self, connection, flags, specific_object); #if NM_MORE_ASSERTS >= 2 { @@ -13640,7 +13164,7 @@ nm_device_check_connection_available (NMDevice *self, gboolean available_all[NM_DEVICE_CHECK_CON_AVAILABLE_ALL + 1] = { FALSE }; for (i = 0; i <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; i++) - available_all[i] = _nm_device_check_connection_available (self, connection, i, specific_object, NULL); + available_all[i] = _nm_device_check_connection_available (self, connection, i, specific_object); for (i = 0; i <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; i++) { for (j = 1; j <= NM_DEVICE_CHECK_CON_AVAILABLE_ALL; j <<= 1) { @@ -13667,23 +13191,22 @@ available_connections_del_all (NMDevice *self) } static gboolean -available_connections_add (NMDevice *self, NMSettingsConnection *sett_conn) +available_connections_add (NMDevice *self, NMConnection *connection) { - return g_hash_table_add (self->_priv->available_connections, g_object_ref (sett_conn)); + return g_hash_table_add (self->_priv->available_connections, g_object_ref (connection)); } static gboolean -available_connections_del (NMDevice *self, NMSettingsConnection *sett_conn) +available_connections_del (NMDevice *self, NMConnection *connection) { - return g_hash_table_remove (self->_priv->available_connections, sett_conn); + return g_hash_table_remove (self->_priv->available_connections, connection); } static gboolean check_connection_available (NMDevice *self, NMConnection *connection, NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) + const char *specific_object) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); @@ -13709,8 +13232,6 @@ check_connection_available (NMDevice *self, if (nm_device_is_master (self)) return TRUE; - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has no carrier"); return FALSE; } @@ -13721,7 +13242,7 @@ nm_device_recheck_available_connections (NMDevice *self) NMSettingsConnection *const*connections; gboolean changed = FALSE; GHashTableIter h_iter; - NMSettingsConnection *sett_conn; + NMConnection *connection; guint i; gs_unref_hashtable GHashTable *prune_list = NULL; @@ -13732,30 +13253,29 @@ nm_device_recheck_available_connections (NMDevice *self) if (g_hash_table_size (priv->available_connections) > 0) { prune_list = g_hash_table_new (nm_direct_hash, NULL); g_hash_table_iter_init (&h_iter, priv->available_connections); - while (g_hash_table_iter_next (&h_iter, (gpointer *) &sett_conn, NULL)) - g_hash_table_add (prune_list, sett_conn); + while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL)) + g_hash_table_add (prune_list, connection); } connections = nm_settings_get_connections (priv->settings, NULL); for (i = 0; connections[i]; i++) { - sett_conn = connections[i]; + connection = (NMConnection *) connections[i]; if (nm_device_check_connection_available (self, - nm_settings_connection_get_connection (sett_conn), + connection, NM_DEVICE_CHECK_CON_AVAILABLE_NONE, - NULL, NULL)) { - if (available_connections_add (self, sett_conn)) + if (available_connections_add (self, connection)) changed = TRUE; if (prune_list) - g_hash_table_remove (prune_list, sett_conn); + g_hash_table_remove (prune_list, connection); } } if (prune_list) { g_hash_table_iter_init (&h_iter, prune_list); - while (g_hash_table_iter_next (&h_iter, (gpointer *) &sett_conn, NULL)) { - if (available_connections_del (self, sett_conn)) + while (g_hash_table_iter_next (&h_iter, (gpointer *) &connection, NULL)) { + if (available_connections_del (self, connection)) changed = TRUE; } } @@ -13782,7 +13302,7 @@ nm_device_get_best_connection (NMDevice *self, GError **error) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMSettingsConnection *sett_conn = NULL; + NMSettingsConnection *connection = NULL; NMSettingsConnection *candidate; guint64 best_timestamp = 0; GHashTableIter iter; @@ -13796,44 +13316,42 @@ nm_device_get_best_connection (NMDevice *self, */ if ( specific_object /* << Optimization: we know that the connection is available without @specific_object. */ && !nm_device_check_connection_available (self, - nm_settings_connection_get_connection (candidate), + NM_CONNECTION (candidate), _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, - specific_object, - NULL)) + specific_object)) continue; nm_settings_connection_get_timestamp (candidate, &candidate_timestamp); - if (!sett_conn || (candidate_timestamp > best_timestamp)) { - sett_conn = candidate; + if (!connection || (candidate_timestamp > best_timestamp)) { + connection = candidate; best_timestamp = candidate_timestamp; } } - if (!sett_conn) { + if (!connection) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, "The device '%s' has no connections available for activation.", nm_device_get_iface (self)); } - return sett_conn; + return connection; } static void -cp_connection_added_or_updated (NMDevice *self, NMSettingsConnection *sett_conn) +cp_connection_added_or_updated (NMDevice *self, NMConnection *connection) { gboolean changed; g_return_if_fail (NM_IS_DEVICE (self)); - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn)); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); if (nm_device_check_connection_available (self, - nm_settings_connection_get_connection (sett_conn), + connection, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, - NULL, NULL)) - changed = available_connections_add (self, sett_conn); + changed = available_connections_add (self, connection); else - changed = available_connections_del (self, sett_conn); + changed = available_connections_del (self, connection); if (changed) { _notify (self, PROP_AVAILABLE_CONNECTIONS); @@ -13842,25 +13360,25 @@ cp_connection_added_or_updated (NMDevice *self, NMSettingsConnection *sett_conn) } static void -cp_connection_added (NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data) +cp_connection_added (NMSettings *settings, NMConnection *connection, gpointer user_data) { - cp_connection_added_or_updated (user_data, sett_conn); + cp_connection_added_or_updated (user_data, connection); } static void -cp_connection_updated (NMSettings *settings, NMSettingsConnection *sett_conn, gboolean by_user, gpointer user_data) +cp_connection_updated (NMSettings *settings, NMConnection *connection, gboolean by_user, gpointer user_data) { - cp_connection_added_or_updated (user_data, sett_conn); + cp_connection_added_or_updated (user_data, connection); } static void -cp_connection_removed (NMSettings *settings, NMSettingsConnection *sett_conn, gpointer user_data) +cp_connection_removed (NMSettings *settings, NMConnection *connection, gpointer user_data) { NMDevice *self = user_data; g_return_if_fail (NM_IS_DEVICE (self)); - if (available_connections_del (self, sett_conn)) { + if (available_connections_del (self, connection)) { _notify (self, PROP_AVAILABLE_CONNECTIONS); available_connections_check_delete_unrealized (self); } @@ -14219,8 +13737,6 @@ nm_device_cleanup (NMDevice *self, NMDeviceStateReason reason, CleanupType clean priv->ip6_mtu_initial = 0; } - _ethtool_state_reset (self); - _cleanup_generic_post (self, cleanup_type); } @@ -14500,7 +14016,7 @@ _set_state_full (NMDevice *self, NMDeviceState old_state; NMActRequest *req; gboolean no_firmware = FALSE; - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; g_return_if_fail (NM_IS_DEVICE (self)); @@ -14759,10 +14275,10 @@ _set_state_full (NMDevice *self, break; } - sett_conn = nm_device_get_settings_connection (self); + connection = nm_device_get_settings_connection (self); _LOGW (LOGD_DEVICE | LOGD_WIFI, "Activation: failed for connection '%s'", - sett_conn ? nm_settings_connection_get_id (sett_conn) : "<unknown>"); + connection ? nm_settings_connection_get_id (connection) : "<unknown>"); /* Notify any slaves of the unexpected failure */ nm_device_master_release_slaves (self); @@ -14772,8 +14288,8 @@ _set_state_full (NMDevice *self, * failed (zero timestamp), connections that succeeded (non-zero timestamp), * and those we haven't tried yet (no timestamp). */ - if (sett_conn && !nm_settings_connection_get_timestamp (sett_conn, NULL)) - nm_settings_connection_update_timestamp (sett_conn, (guint64) 0, TRUE); + if (connection && !nm_settings_connection_get_timestamp (connection, NULL)) + nm_settings_connection_update_timestamp (connection, (guint64) 0, TRUE); /* Schedule the transition to DISCONNECTED. The device can't transition * immediately because we can't change states again from the state @@ -15687,7 +15203,8 @@ nm_device_get_supplicant_timeout (NMDevice *self) { NMConnection *connection; NMSetting8021x *s_8021x; - int timeout; + gs_free char *value = NULL; + gint timeout; #define SUPPLICANT_DEFAULT_TIMEOUT 25 g_return_val_if_fail (NM_IS_DEVICE (self), SUPPLICANT_DEFAULT_TIMEOUT); @@ -15701,12 +15218,11 @@ nm_device_get_supplicant_timeout (NMDevice *self) return timeout; } - return nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "802-1x.auth-timeout", - self, - 1, - G_MAXINT32, - SUPPLICANT_DEFAULT_TIMEOUT); + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "802-1x.auth-timeout", + self); + return _nm_utils_ascii_str_to_int64 (value, 10, 1, G_MAXINT32, + SUPPLICANT_DEFAULT_TIMEOUT); } gboolean @@ -15729,10 +15245,12 @@ nm_device_auth_retries_try_next (NMDevice *self) auth_retries = nm_setting_connection_get_auth_retries (s_con); if (auth_retries == -1) { - auth_retries = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "connection.auth-retries", - self, - -1, G_MAXINT32, -1); + gs_free char *value = NULL; + + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "connection.auth-retries", + self); + auth_retries = _nm_utils_ascii_str_to_int64 (value, 10, -1, G_MAXINT32, -1); } if (auth_retries == 0) diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 6342a657..d145f8fc 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -202,12 +202,7 @@ typedef struct _NMDeviceClass { struct _NMDeviceClass *default_type_description_klass; const char *default_type_description; - const char *connection_type_supported; - - /* most device types, can only handle profiles of a particular type. This - * is the connection.type setting, as checked by nm_device_check_connection_compatible() */ - const char *connection_type_check_compatible; - + const char *connection_type; const NMLinkType *link_types; /* Whether the device type is a master-type. This depends purely on the @@ -297,7 +292,7 @@ typedef struct _NMDeviceClass { gboolean (* get_autoconnect_allowed) (NMDevice *self); gboolean (* can_auto_connect) (NMDevice *self, - NMSettingsConnection *sett_conn, + NMConnection *connection, char **specific_object); guint32 (*get_configured_mtu) (NMDevice *self, NMDeviceMtuSource *out_source); @@ -306,9 +301,7 @@ typedef struct _NMDeviceClass { * only the devices type and characteristics. Does not use any live * network information like WiFi scan lists etc. */ - gboolean (* check_connection_compatible) (NMDevice *self, - NMConnection *connection, - GError **error); + gboolean (* check_connection_compatible) (NMDevice *self, NMConnection *connection); /* Checks whether the connection is likely available to be activated, * including any live network information like scan lists. The connection @@ -324,8 +317,7 @@ typedef struct _NMDeviceClass { gboolean (* check_connection_available) (NMDevice *self, NMConnection *connection, NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error); + const char *specific_object); gboolean (* complete_connection) (NMDevice *self, NMConnection *connection, @@ -501,9 +493,6 @@ gboolean nm_device_parent_notify_changed (NMDevice *self, NMDevice *change_candidate, gboolean device_removed); -const char *nm_device_parent_find_for_connection (NMDevice *self, - const char *current_setting_parent); - /* Master */ gboolean nm_device_is_master (NMDevice *dev); @@ -512,7 +501,6 @@ NMDevice * nm_device_get_master (NMDevice *dev); NMActRequest * nm_device_get_act_request (NMDevice *dev); NMSettingsConnection *nm_device_get_settings_connection (NMDevice *dev); -NMConnection * nm_device_get_settings_connection_get_connection (NMDevice *self); NMConnection * nm_device_get_applied_connection (NMDevice *dev); gboolean nm_device_has_unmodified_applied_connection (NMDevice *self, NMSettingCompareFlags compare_flags); @@ -536,7 +524,7 @@ gboolean nm_device_master_update_slave_connection (NMDevice *master, GError **error); gboolean nm_device_can_auto_connect (NMDevice *self, - NMSettingsConnection *sett_conn, + NMConnection *connection, char **specific_object); gboolean nm_device_complete_connection (NMDevice *device, @@ -545,10 +533,7 @@ gboolean nm_device_complete_connection (NMDevice *device, NMConnection *const*existing_connections, GError **error); -gboolean nm_device_check_connection_compatible (NMDevice *device, - NMConnection *connection, - GError **error); - +gboolean nm_device_check_connection_compatible (NMDevice *device, NMConnection *connection); gboolean nm_device_check_slave_connection_compatible (NMDevice *device, NMConnection *connection); gboolean nm_device_unmanage_on_quit (NMDevice *self); @@ -583,7 +568,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_BY_TYPE: %TRUE for unmanaging device by type, like loopback. + * @NM_UNMANAGED_LOOPBACK: %TRUE for unmanaging loopback device * @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 +599,7 @@ typedef enum { /*< skip >*/ NM_UNMANAGED_SLEEPING = (1LL << 0), NM_UNMANAGED_QUITTING = (1LL << 1), NM_UNMANAGED_PARENT = (1LL << 2), - NM_UNMANAGED_BY_TYPE = (1LL << 3), + NM_UNMANAGED_LOOPBACK = (1LL << 3), NM_UNMANAGED_PLATFORM_INIT = (1LL << 4), NM_UNMANAGED_USER_EXPLICIT = (1LL << 5), NM_UNMANAGED_USER_SETTINGS = (1LL << 6), @@ -757,8 +742,7 @@ NMSettingsConnection *nm_device_get_best_connection (NMDevice *device, gboolean nm_device_check_connection_available (NMDevice *device, NMConnection *connection, NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error); + const char *specific_object); gboolean nm_device_notify_component_added (NMDevice *device, GObject *component); diff --git a/src/devices/ovs/meson.build b/src/devices/ovs/meson.build index 9d637fe9..f4edd57c 100644 --- a/src/devices/ovs/meson.build +++ b/src/devices/ovs/meson.build @@ -15,6 +15,7 @@ libnm_device_plugin_ovs = shared_module( 'nm-device-plugin-ovs', sources: sources, dependencies: deps, + c_args: '-DRUNSTATEDIR="@0@"'.format(nm_runstatedir), link_args: ldflags_linker_script_devices, link_depends: linker_script_devices, install: true, @@ -23,10 +24,10 @@ libnm_device_plugin_ovs = shared_module( core_plugins += libnm_device_plugin_ovs -test( +run_target( 'check-local-devices-ovs', - check_exports, - args: [libnm_device_plugin_ovs.full_path(), linker_script_devices], + command: [check_exports, libnm_device_plugin_ovs.full_path(), linker_script_devices], + depends: libnm_device_plugin_ovs ) # FIXME: check_so_symbols replacement diff --git a/src/devices/ovs/nm-device-ovs-bridge.c b/src/devices/ovs/nm-device-ovs-bridge.c index eff355a3..2e4d1cbd 100644 --- a/src/devices/ovs/nm-device-ovs-bridge.c +++ b/src/devices/ovs/nm-device-ovs-bridge.c @@ -76,6 +76,21 @@ get_generic_capabilities (NMDevice *device) return NM_DEVICE_CAP_IS_SOFTWARE; } +static gboolean +check_connection_compatible (NMDevice *device, NMConnection *connection) +{ + const char *connection_type; + + if (!NM_DEVICE_CLASS (nm_device_ovs_bridge_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + connection_type = nm_connection_get_connection_type (connection); + if (!nm_streq0 (connection_type, NM_SETTING_OVS_BRIDGE_SETTING_NAME)) + return FALSE; + + return TRUE; +} + static NMActStageReturn act_stage3_ip4_config_start (NMDevice *device, NMIP4Config **out_config, @@ -137,15 +152,13 @@ nm_device_ovs_bridge_class_init (NMDeviceOvsBridgeClass *klass) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ovs_bridge); - device_class->connection_type_supported = NM_SETTING_OVS_BRIDGE_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_OVS_BRIDGE_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (); - + device_class->connection_type = NM_SETTING_OVS_BRIDGE_SETTING_NAME; device_class->is_master = TRUE; device_class->get_type_description = get_type_description; device_class->create_and_realize = create_and_realize; device_class->unrealize = unrealize; device_class->get_generic_capabilities = get_generic_capabilities; + device_class->check_connection_compatible = check_connection_compatible; device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start; device_class->enslave_slave = enslave_slave; diff --git a/src/devices/ovs/nm-device-ovs-interface.c b/src/devices/ovs/nm-device-ovs-interface.c index 2b48fae6..c59af7a6 100644 --- a/src/devices/ovs/nm-device-ovs-interface.c +++ b/src/devices/ovs/nm-device-ovs-interface.c @@ -85,20 +85,25 @@ is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { + NMSettingConnection *s_con; NMSettingOvsInterface *s_ovs_iface; - if (!NM_DEVICE_CLASS (nm_device_ovs_interface_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_ovs_interface_parent_class)->check_connection_compatible (device, connection)) return FALSE; s_ovs_iface = nm_connection_get_setting_ovs_interface (connection); - + if (!s_ovs_iface) + return FALSE; if (!NM_IN_STRSET (nm_setting_ovs_interface_get_interface_type (s_ovs_iface), - "internal", - "patch")) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "unsupported OVS interface type in profile"); + "internal", "patch")) { + return FALSE; + } + + s_con = nm_connection_get_setting_connection (connection); + if (g_strcmp0 (nm_setting_connection_get_connection_type (s_con), + NM_SETTING_OVS_INTERFACE_SETTING_NAME) != 0) { return FALSE; } @@ -194,12 +199,11 @@ nm_device_ovs_interface_class_init (NMDeviceOvsInterfaceClass *klass) NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); - dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ovs_interface); + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NULL, NM_LINK_TYPE_OPENVSWITCH); - device_class->connection_type_supported = NM_SETTING_OVS_INTERFACE_SETTING_NAME; - 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); + dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ovs_interface); + device_class->connection_type = NM_SETTING_OVS_INTERFACE_SETTING_NAME; device_class->get_type_description = get_type_description; device_class->create_and_realize = create_and_realize; device_class->get_generic_capabilities = get_generic_capabilities; diff --git a/src/devices/ovs/nm-device-ovs-port.c b/src/devices/ovs/nm-device-ovs-port.c index 1f9afbab..a9a2b24a 100644 --- a/src/devices/ovs/nm-device-ovs-port.c +++ b/src/devices/ovs/nm-device-ovs-port.c @@ -70,6 +70,26 @@ get_generic_capabilities (NMDevice *device) return NM_DEVICE_CAP_IS_SOFTWARE; } +static gboolean +check_connection_compatible (NMDevice *device, NMConnection *connection) +{ + NMSettingConnection *s_con; + const char *connection_type; + + if (!NM_DEVICE_CLASS (nm_device_ovs_port_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + s_con = nm_connection_get_setting_connection (connection); + connection_type = nm_setting_connection_get_connection_type (s_con); + if (!connection_type) + return FALSE; + + if (strcmp (connection_type, NM_SETTING_OVS_PORT_SETTING_NAME) == 0) + return TRUE; + + return FALSE; +} + static NMActStageReturn act_stage3_ip4_config_start (NMDevice *device, NMIP4Config **out_config, @@ -178,14 +198,12 @@ nm_device_ovs_port_class_init (NMDeviceOvsPortClass *klass) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_ovs_port); - device_class->connection_type_supported = NM_SETTING_OVS_PORT_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_OVS_PORT_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (); - + device_class->connection_type = NM_SETTING_OVS_PORT_SETTING_NAME; device_class->is_master = TRUE; device_class->get_type_description = get_type_description; device_class->create_and_realize = create_and_realize; device_class->get_generic_capabilities = get_generic_capabilities; + device_class->check_connection_compatible = check_connection_compatible; device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start; device_class->enslave_slave = enslave_slave; diff --git a/src/devices/ovs/nm-ovsdb.c b/src/devices/ovs/nm-ovsdb.c index b00397cf..a9cb5703 100644 --- a/src/devices/ovs/nm-ovsdb.c +++ b/src/devices/ovs/nm-ovsdb.c @@ -139,7 +139,7 @@ typedef struct { static void _call_trace (const char *comment, OvsdbMethodCall *call, json_t *msg) { -#if NM_MORE_LOGGING +#ifdef NM_MORE_LOGGING char *str = NULL; if (msg) diff --git a/src/devices/team/meson.build b/src/devices/team/meson.build index 0f0763bd..159c182a 100644 --- a/src/devices/team/meson.build +++ b/src/devices/team/meson.build @@ -21,10 +21,10 @@ libnm_device_plugin_team = shared_module( core_plugins += libnm_device_plugin_team -test( +run_target( 'check-local-devices-team', - check_exports, - args: [libnm_device_plugin_team.full_path(), linker_script_devices], + command: [check_exports, libnm_device_plugin_team.full_path(), linker_script_devices], + depends: libnm_device_plugin_team ) # FIXME: check_so_symbols replacement diff --git a/src/devices/team/nm-device-team.c b/src/devices/team/nm-device-team.c index 899932fd..f83ba22b 100644 --- a/src/devices/team/nm-device-team.c +++ b/src/devices/team/nm-device-team.c @@ -1,6 +1,8 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager * + * Copyright (C) 2013 Jiri Pirko <jiri@resnulli.us> + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -14,9 +16,6 @@ * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2013 Jiri Pirko <jiri@resnulli.us> - * Copyright (C) 2018 Red Hat, Inc. */ #include "nm-default.h" @@ -85,6 +84,23 @@ get_generic_capabilities (NMDevice *device) } static gboolean +check_connection_compatible (NMDevice *device, NMConnection *connection) +{ + NMSettingTeam *s_team; + + if (!NM_DEVICE_CLASS (nm_device_team_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + s_team = nm_connection_get_setting_team (connection); + if (!s_team || !nm_connection_is_type (connection, NM_SETTING_TEAM_SETTING_NAME)) + return FALSE; + + /* FIXME: match team properties like mode, etc? */ + + return TRUE; +} + +static gboolean complete_connection (NMDevice *device, NMConnection *connection, const char *specific_object, @@ -351,8 +367,8 @@ teamd_timeout_cb (gpointer user_data) static void teamd_dbus_appeared (GDBusConnection *connection, - const char *name, - const char *name_owner, + const gchar *name, + const gchar *name_owner, gpointer user_data) { NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); @@ -414,7 +430,7 @@ teamd_dbus_appeared (GDBusConnection *connection, static void teamd_dbus_vanished (GDBusConnection *dbus_connection, - const char *name, + const gchar *name, gpointer user_data) { NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); @@ -447,7 +463,7 @@ teamd_dbus_vanished (GDBusConnection *dbus_connection, } static void -teamd_process_watch_cb (GPid pid, int status, gpointer user_data) +teamd_process_watch_cb (GPid pid, gint status, gpointer user_data) { NMDeviceTeam *self = NM_DEVICE_TEAM (user_data); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); @@ -500,7 +516,7 @@ teamd_kill (NMDeviceTeam *self, const char *teamd_binary, GError **error) g_ptr_array_add (argv, (gpointer) nm_device_get_iface (NM_DEVICE (self))); g_ptr_array_add (argv, NULL); - _LOGD (LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv (" ", (char **) argv->pdata))); + _LOGD (LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata))); return g_spawn_sync ("/", (char **) argv->pdata, NULL, 0, teamd_child_setup, NULL, NULL, NULL, NULL, error); } @@ -588,7 +604,7 @@ teamd_start (NMDevice *device, NMConnection *connection) g_ptr_array_add (argv, (gpointer) "-gg"); g_ptr_array_add (argv, NULL); - _LOGD (LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv (" ", (char **) argv->pdata))); + _LOGD (LOGD_TEAM, "running: %s", (tmp_str = g_strjoinv (" ", (gchar **) argv->pdata))); if (!g_spawn_async ("/", (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD, teamd_child_setup, NULL, &priv->teamd_pid, &error)) { _LOGW (LOGD_TEAM, "Activation: (team) failed to start teamd: %s", error->message); @@ -687,7 +703,7 @@ enslave_slave (NMDevice *device, { NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - gboolean success = TRUE; + gboolean success = TRUE, no_firmware = FALSE; const char *slave_iface = nm_device_get_ip_iface (slave); NMSettingTeamPort *s_team_port; @@ -722,7 +738,7 @@ enslave_slave (NMDevice *device, 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_bring_up (slave, TRUE, &no_firmware); if (!success) return FALSE; @@ -746,7 +762,7 @@ release_slave (NMDevice *device, { NMDeviceTeam *self = NM_DEVICE_TEAM (device); NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE (self); - gboolean success; + gboolean success, no_firmware = FALSE; if (configure) { success = nm_platform_link_release (nm_device_get_platform (device), @@ -762,7 +778,7 @@ release_slave (NMDevice *device, * IFF_UP), so we must bring it back up here to ensure carrier changes and * other state is noticed by the now-released port. */ - if (!nm_device_bring_up (slave, TRUE, NULL)) + if (!nm_device_bring_up (slave, TRUE, &no_firmware)) _LOGW (LOGD_TEAM, "released team port %s could not be brought up", nm_device_get_ip_iface (slave)); @@ -894,7 +910,9 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_TEAM_SETTING_NAME, NM_LINK_TYPE_TEAM) object_class->constructed = constructed; object_class->dispose = dispose; @@ -902,22 +920,19 @@ nm_device_team_class_init (NMDeviceTeamClass *klass) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_team); - device_class->connection_type_supported = NM_SETTING_TEAM_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_TEAM_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_TEAM); - - device_class->is_master = TRUE; - device_class->create_and_realize = create_and_realize; - device_class->get_generic_capabilities = get_generic_capabilities; - device_class->complete_connection = complete_connection; - device_class->update_connection = update_connection; - device_class->master_update_slave_connection = master_update_slave_connection; - - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; - device_class->deactivate = deactivate; - device_class->enslave_slave = enslave_slave; - device_class->release_slave = release_slave; + parent_class->is_master = TRUE; + parent_class->create_and_realize = create_and_realize; + parent_class->get_generic_capabilities = get_generic_capabilities; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->complete_connection = complete_connection; + parent_class->update_connection = update_connection; + parent_class->master_update_slave_connection = master_update_slave_connection; + + parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->get_configured_mtu = nm_device_get_configured_mtu_for_wired; + parent_class->deactivate = deactivate; + parent_class->enslave_slave = enslave_slave; + parent_class->release_slave = release_slave; obj_properties[PROP_CONFIG] = g_param_spec_string (NM_DEVICE_TEAM_CONFIG, "", "", diff --git a/src/devices/wifi/meson.build b/src/devices/wifi/meson.build index 2745040b..a27f8e6a 100644 --- a/src/devices/wifi/meson.build +++ b/src/devices/wifi/meson.build @@ -33,10 +33,10 @@ libnm_device_plugin_wifi = shared_module( core_plugins += libnm_device_plugin_wifi -test( +run_target( 'check-local-devices-wifi', - check_exports, - args: [libnm_device_plugin_wifi.full_path(), linker_script_devices], + command: [check_exports, libnm_device_plugin_wifi.full_path(), linker_script_devices], + depends: libnm_device_plugin_wifi ) # FIXME: check_so_symbols replacement diff --git a/src/devices/wifi/nm-device-iwd.c b/src/devices/wifi/nm-device-iwd.c index 32d49916..7667816a 100644 --- a/src/devices/wifi/nm-device-iwd.c +++ b/src/devices/wifi/nm-device-iwd.c @@ -67,8 +67,7 @@ static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { GDBusObject * dbus_obj; - GDBusProxy * dbus_device_proxy; - GDBusProxy * dbus_station_proxy; + GDBusProxy * dbus_proxy; CList aps_lst_head; NMWifiAP * current_ap; GCancellable * cancellable; @@ -205,11 +204,11 @@ remove_all_aps (NMDeviceIwd *self) } static GVariant * -vardict_from_network_type (const char *type) +vardict_from_network_type (const gchar *type) { GVariantBuilder builder; - const char *key_mgmt = ""; - const char *pairwise = "ccmp"; + const gchar *key_mgmt = ""; + const gchar *pairwise = "ccmp"; if (!strcmp (type, "psk")) key_mgmt = "wpa-psk"; @@ -229,85 +228,6 @@ 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; @@ -315,39 +235,75 @@ get_ordered_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data) gs_free_error GError *error = NULL; gs_unref_variant GVariant *variant = NULL; GVariantIter *networks; - const char *path, *name, *type; + const gchar *path, *name, *type; int16_t signal; NMWifiAP *ap, *ap_safe, *new_ap; 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 (return_sig), + G_VARIANT_TYPE ("(a(osns))"), &error); if (!variant) { - _LOGE (LOGD_WIFI, "Station.GetOrderedNetworks failed: %s", + _LOGE (LOGD_WIFI, "Device.GetOrderedNetworks failed: %s", error->message); return; } new_aps = g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_object_unref); - g_variant_get (variant, return_sig, &networks); + g_variant_get (variant, "(a(osns))", &networks); - 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++); + 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]; + + /* + * 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); + if (name[0] != '\0') + nm_wifi_ap_set_ssid (ap, (const guint8 *) name, 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); } g_variant_iter_free (networks); @@ -399,7 +355,7 @@ update_aps (NMDeviceIwd *self) if (!priv->cancellable) priv->cancellable = g_cancellable_new (); - g_dbus_proxy_call (priv->dbus_station_proxy, "GetOrderedNetworks", + g_dbus_proxy_call (priv->dbus_proxy, "GetOrderedNetworks", g_variant_new ("()"), G_DBUS_CALL_FLAGS_NONE, 2000, priv->cancellable, get_ordered_networks_cb, self); @@ -410,7 +366,7 @@ send_disconnect (NMDeviceIwd *self) { NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - g_dbus_proxy_call (priv->dbus_station_proxy, "Disconnect", g_variant_new ("()"), + g_dbus_proxy_call (priv->dbus_proxy, "Disconnect", g_variant_new ("()"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL); } @@ -449,7 +405,7 @@ deactivate_async_finish (NMDevice *device, GAsyncResult *res, GError **error) NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (NM_DEVICE_IWD (device)); gs_unref_variant GVariant *variant = NULL; - variant = g_dbus_proxy_call_finish (priv->dbus_station_proxy, res, error); + variant = g_dbus_proxy_call_finish (priv->dbus_proxy, res, error); return variant != NULL; } @@ -485,18 +441,39 @@ deactivate_async (NMDevice *device, ctx->callback = callback; ctx->user_data = user_data; - g_dbus_proxy_call (priv->dbus_station_proxy, "Disconnect", g_variant_new ("()"), + g_dbus_proxy_call (priv->dbus_proxy, "Disconnect", g_variant_new ("()"), G_DBUS_CALL_FLAGS_NONE, -1, cancellable, disconnect_cb, ctx); } +static NMIwdNetworkSecurity +get_connection_iwd_security (NMConnection *connection) +{ + NMSettingWirelessSecurity *s_wireless_sec; + const char *key_mgmt = NULL; + + s_wireless_sec = nm_connection_get_setting_wireless_security (connection); + if (!s_wireless_sec) + return NM_IWD_NETWORK_SECURITY_NONE; + + key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec); + nm_assert (key_mgmt); + + if (!strcmp (key_mgmt, "none") || !strcmp (key_mgmt, "ieee8021x")) + return NM_IWD_NETWORK_SECURITY_WEP; + + if (!strcmp (key_mgmt, "wpa-psk")) + return NM_IWD_NETWORK_SECURITY_PSK; + + nm_assert (!strcmp (key_mgmt, "wpa-eap")); + return NM_IWD_NETWORK_SECURITY_8021X; +} + static gboolean is_connection_known_network (NMConnection *connection) { NMSettingWireless *s_wireless; - NMIwdNetworkSecurity security; - gboolean security_ok; GBytes *ssid; - gs_free char *ssid_utf8 = NULL; + gs_free gchar *str_ssid = NULL; s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) @@ -506,73 +483,68 @@ is_connection_known_network (NMConnection *connection) if (!ssid) return FALSE; - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); - - security = nm_wifi_connection_get_iwd_security (connection, &security_ok); - if (!security_ok) - return FALSE; + str_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); return nm_iwd_manager_is_known_network (nm_iwd_manager_get (), - ssid_utf8, security); + str_ssid, + get_connection_iwd_security (connection)); } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { + NMSettingConnection *s_con; NMSettingWireless *s_wireless; const char *mac; const char * const *mac_blacklist; int i; + const char *mode; const char *perm_hw_addr; - if (!NM_DEVICE_CLASS (nm_device_iwd_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_iwd_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIRELESS_SETTING_NAME)) return FALSE; s_wireless = nm_connection_get_setting_wireless (connection); + if (!s_wireless) + return FALSE; perm_hw_addr = nm_device_get_permanent_hw_address (device); mac = nm_setting_wireless_get_mac_address (s_wireless); if (perm_hw_addr) { - if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device MAC address does not match the profile"); + if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) return FALSE; - } /* Check for MAC address blacklist */ mac_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless); for (i = 0; mac_blacklist[i]; i++) { - nm_assert (nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)); - - if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, perm_hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "MAC address blacklisted"); + if (!nm_utils_hwaddr_valid (mac_blacklist[i], ETH_ALEN)) { + g_warn_if_reached (); return FALSE; } + + if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, perm_hw_addr, -1)) + return FALSE; } - } else if (mac) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has no valid MAC address as required by profile"); + } else if (mac) return FALSE; - } - if (!NM_IN_STRSET (nm_setting_wireless_get_mode (s_wireless), - NULL, - NM_SETTING_WIRELESS_MODE_INFRA)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "IWD only support infrastructure type profiles"); + mode = nm_setting_wireless_get_mode (s_wireless); + if (mode && g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_INFRA) != 0) return FALSE; - } /* 8021x networks can only be used if they've been provisioned on the IWD side and * thus are Known Networks. */ - if (nm_wifi_connection_get_iwd_security (connection, NULL) == NM_IWD_NETWORK_SECURITY_8021X) { - if (!is_connection_known_network (connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "802.1x profile is not a known network"); + if (get_connection_iwd_security (connection) == NM_IWD_NETWORK_SECURITY_8021X) { + if (!is_connection_known_network (connection)) return FALSE; - } } return TRUE; @@ -582,8 +554,7 @@ static gboolean check_connection_available (NMDevice *device, NMConnection *connection, NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) + const char *specific_object) { NMDeviceIwd *self = NM_DEVICE_IWD (device); NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); @@ -595,28 +566,19 @@ check_connection_available (NMDevice *device, /* Only Infrastrusture mode at this time */ mode = nm_setting_wireless_get_mode (s_wifi); - if (!NM_IN_STRSET (mode, NULL, NM_SETTING_WIRELESS_MODE_INFRA)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "iwd only supports infrastructure mode connections"); + if (mode && g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_INFRA) != 0) return FALSE; - } /* Hidden SSIDs not supported yet */ - if (nm_setting_wireless_get_hidden (s_wifi)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "hidden networks not supported by iwd"); + if (nm_setting_wireless_get_hidden (s_wifi)) return FALSE; - } /* 8021x networks can only be used if they've been provisioned on the IWD side and * thus are Known Networks. */ - if (nm_wifi_connection_get_iwd_security (connection, NULL) == NM_IWD_NETWORK_SECURITY_8021X) { - if (!is_connection_known_network (connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "network is not known to iwd"); + if (get_connection_iwd_security (connection) == NM_IWD_NETWORK_SECURITY_8021X) { + if (!is_connection_known_network (connection)) return FALSE; - } } /* a connection that is available for a certain @specific_object, MUST @@ -626,29 +588,14 @@ check_connection_available (NMDevice *device, NMWifiAP *ap; ap = nm_wifi_ap_lookup_for_device (NM_DEVICE (self), specific_object); - if (!ap) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "requested access point not found"); - return FALSE; - } - if (!nm_wifi_ap_check_compatible (ap, connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "requested access point is not compatible with profile"); - return FALSE; - } - return TRUE; + return ap ? nm_wifi_ap_check_compatible (ap, connection) : FALSE; } if (NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP)) return TRUE; - if (!nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "no compatible access point found"); - return FALSE; - } - - return TRUE; + /* Check at least one AP is compatible with this connection */ + return !!nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection); } static gboolean @@ -662,9 +609,10 @@ complete_connection (NMDevice *device, NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); NMSettingWireless *s_wifi; const char *setting_mac; - gs_free char *ssid_utf8 = NULL; + char *str_ssid = NULL; NMWifiAP *ap; - GBytes *ssid; + const GByteArray *ssid = NULL; + GByteArray *tmp_ssid = NULL; GBytes *setting_ssid = NULL; const char *perm_hw_addr; const char *mode; @@ -728,7 +676,8 @@ complete_connection (NMDevice *device, } ssid = nm_wifi_ap_get_ssid (ap); - if (!ssid) { + + if (ssid == NULL) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, @@ -739,23 +688,30 @@ complete_connection (NMDevice *device, if (!nm_wifi_ap_complete_connection (ap, connection, nm_wifi_utils_is_manf_default_ssid (ssid), - error)) + error)) { + if (tmp_ssid) + g_byte_array_unref (tmp_ssid); return FALSE; + } + + str_ssid = nm_utils_ssid_to_utf8 (ssid->data, ssid->len); - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); nm_utils_complete_generic (nm_device_get_platform (device), connection, NM_SETTING_WIRELESS_SETTING_NAME, existing_connections, - ssid_utf8, - ssid_utf8, + str_ssid, + str_ssid, NULL, TRUE); + g_free (str_ssid); + if (tmp_ssid) + g_byte_array_unref (tmp_ssid); /* 8021x networks can only be used if they've been provisioned on the IWD side and * thus are Known Networks. */ - if (nm_wifi_connection_get_iwd_security (connection, NULL) == NM_IWD_NETWORK_SECURITY_8021X) { + if (get_connection_iwd_security (connection) == NM_IWD_NETWORK_SECURITY_8021X) { if (!is_connection_known_network (connection)) { g_set_error_literal (error, NM_CONNECTION_ERROR, @@ -797,32 +753,6 @@ complete_connection (NMDevice *device, } static gboolean -get_variant_boolean (GVariant *v, const char *property) -{ - if (!v || !g_variant_is_of_type (v, G_VARIANT_TYPE_BOOLEAN)) { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "Property %s not cached or not boolean type", property); - - return FALSE; - } - - return g_variant_get_boolean (v); -} - -static const char * -get_variant_state (GVariant *v) -{ - if (!v || !g_variant_is_of_type (v, G_VARIANT_TYPE_STRING)) { - nm_log_warn (LOGD_DEVICE | LOGD_WIFI, - "State property not cached or not a string"); - - return "unknown"; - } - - return g_variant_get_string (v, NULL); -} - -static gboolean is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) { NMDeviceIwd *self = NM_DEVICE_IWD (device); @@ -832,8 +762,8 @@ is_available (NMDevice *device, NMDeviceCheckDevAvailableFlags flags) if (!priv->enabled || !priv->dbus_obj) return FALSE; - value = g_dbus_proxy_get_cached_property (priv->dbus_device_proxy, "Powered"); - return get_variant_boolean (value, "Powered"); + value = g_dbus_proxy_get_cached_property (priv->dbus_proxy, "Powered"); + return g_variant_get_boolean (value); } static gboolean @@ -847,12 +777,11 @@ get_autoconnect_allowed (NMDevice *device) static gboolean can_auto_connect (NMDevice *device, - NMSettingsConnection *sett_conn, + NMConnection *connection, char **specific_object) { NMDeviceIwd *self = NM_DEVICE_IWD (device); NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - NMConnection *connection; NMSettingWireless *s_wifi; NMWifiAP *ap; const char *mode; @@ -860,11 +789,9 @@ can_auto_connect (NMDevice *device, nm_assert (!specific_object || !*specific_object); - if (!NM_DEVICE_CLASS (nm_device_iwd_parent_class)->can_auto_connect (device, sett_conn, NULL)) + if (!NM_DEVICE_CLASS (nm_device_iwd_parent_class)->can_auto_connect (device, connection, NULL)) return FALSE; - connection = nm_settings_connection_get_connection (sett_conn); - s_wifi = nm_connection_get_setting_wireless (connection); g_return_val_if_fail (s_wifi, FALSE); @@ -877,7 +804,7 @@ can_auto_connect (NMDevice *device, * but haven't been successful, since these are often accidental choices * from the menu and the user may not know the password. */ - if (nm_settings_connection_get_timestamp (sett_conn, ×tamp)) { + if (nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (connection), ×tamp)) { if (timestamp == 0) return FALSE; } @@ -885,7 +812,7 @@ can_auto_connect (NMDevice *device, /* 8021x networks can only be used if they've been provisioned on the IWD side and * thus are Known Networks. */ - if (nm_wifi_connection_get_iwd_security (connection, NULL) == NM_IWD_NETWORK_SECURITY_8021X) { + if (get_connection_iwd_security (connection) == NM_IWD_NETWORK_SECURITY_8021X) { if (!is_connection_known_network (connection)) return FALSE; } @@ -994,7 +921,7 @@ dbus_request_scan_cb (NMDevice *device, } if (!priv->scanning && !priv->scan_requested) { - g_dbus_proxy_call (priv->dbus_station_proxy, "Scan", + g_dbus_proxy_call (priv->dbus_proxy, "Scan", g_variant_new ("()"), G_DBUS_CALL_FLAGS_NONE, -1, priv->cancellable, scan_cb, self); @@ -1078,11 +1005,11 @@ static gboolean try_reply_agent_request (NMDeviceIwd *self, NMConnection *connection, GDBusMethodInvocation *invocation, - const char **setting_name, - const char **setting_key, + const gchar **setting_name, + const gchar **setting_key, gboolean *replied) { - const char *method_name = g_dbus_method_invocation_get_method_name (invocation); + const gchar *method_name = g_dbus_method_invocation_get_method_name (invocation); NMSettingWirelessSecurity *s_wireless_sec; NMSetting8021x *s_8021x; @@ -1092,7 +1019,7 @@ try_reply_agent_request (NMDeviceIwd *self, *replied = FALSE; if (!strcmp (method_name, "RequestPassphrase")) { - const char *psk; + const gchar *psk; if (!s_wireless_sec) return FALSE; @@ -1112,7 +1039,7 @@ try_reply_agent_request (NMDeviceIwd *self, *setting_key = NM_SETTING_WIRELESS_SECURITY_PSK; return TRUE; } else if (!strcmp (method_name, "RequestPrivateKeyPassphrase")) { - const char *password; + const gchar *password; if (!s_8021x) return FALSE; @@ -1132,7 +1059,7 @@ try_reply_agent_request (NMDeviceIwd *self, *setting_key = NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD; return TRUE; } else if (!strcmp (method_name, "RequestUserNameAndPassword")) { - const char *identity, *password; + const gchar *identity, *password; if (!s_8021x) return FALSE; @@ -1156,7 +1083,7 @@ try_reply_agent_request (NMDeviceIwd *self, *setting_key = NM_SETTING_802_1X_PASSWORD; return TRUE; } else if (!strcmp (method_name, "RequestUserPassword")) { - const char *password; + const gchar *password; if (!s_8021x) return FALSE; @@ -1197,8 +1124,8 @@ wifi_secrets_cb (NMActRequest *req, NMDeviceIwdPrivate *priv; NMDevice *device; GDBusMethodInvocation *invocation; - const char *setting_name; - const char *setting_key; + const gchar *setting_name; + const gchar *setting_key; gboolean replied; NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; @@ -1296,12 +1223,12 @@ network_connect_cb (GObject *source, GAsyncResult *res, gpointer user_data) NMConnection *connection; NMSettingWireless *s_wifi; GBytes *ssid; - gs_free char *ssid_utf8 = NULL; + gs_free gchar *str_ssid = NULL; if (!_nm_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, G_VARIANT_TYPE ("()"), &error)) { - gs_free char *dbus_error = NULL; + gs_free gchar *dbus_error = NULL; /* Connection failed; radio problems or if the network wasn't * open, the passwords or certificates may be wrong. @@ -1348,13 +1275,17 @@ network_connect_cb (GObject *source, GAsyncResult *res, gpointer user_data) if (!ssid) goto failed; - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); + str_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); _LOGI (LOGD_DEVICE | LOGD_WIFI, "Activation: (wifi) Stage 2 of 5 (Device Configure) successful. Connected to '%s'.", - ssid_utf8); + str_ssid); nm_device_activate_schedule_stage3_ip_config_start (device); + nm_iwd_manager_network_connected (nm_iwd_manager_get (), str_ssid, + get_connection_iwd_security (connection)); + return; failed: @@ -1368,7 +1299,7 @@ set_powered (NMDeviceIwd *self, gboolean powered) { NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); - g_dbus_proxy_call (priv->dbus_device_proxy, + g_dbus_proxy_call (priv->dbus_proxy, "org.freedesktop.DBus.Properties.Set", g_variant_new ("(ssv)", NM_IWD_DEVICE_INTERFACE, "Powered", @@ -1521,7 +1452,7 @@ periodic_scan_timeout_cb (gpointer user_data) if (priv->scanning || priv->scan_requested) return FALSE; - g_dbus_proxy_call (priv->dbus_station_proxy, "Scan", g_variant_new ("()"), + g_dbus_proxy_call (priv->dbus_proxy, "Scan", g_variant_new ("()"), G_DBUS_CALL_FLAGS_NONE, -1, priv->cancellable, scan_cb, self); priv->scan_requested = TRUE; @@ -1625,7 +1556,7 @@ set_enabled (NMDevice *device, gboolean enabled) return; } - if (priv->dbus_obj) + if (priv->dbus_proxy) set_powered (self, enabled); if (enabled) { @@ -1736,7 +1667,7 @@ set_property (GObject *object, guint prop_id, /*****************************************************************************/ static void -state_changed (NMDeviceIwd *self, const char *new_state) +state_changed (NMDeviceIwd *self, const gchar *new_state) { NMDeviceIwdPrivate *priv = NM_DEVICE_IWD_GET_PRIVATE (self); NMDevice *device = NM_DEVICE (self); @@ -1803,8 +1734,7 @@ state_changed (NMDeviceIwd *self, const char *new_state) NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT); return; - } else if (nm_streq (new_state, "unknown")) - return; + } _LOGE (LOGD_WIFI, "State %s unknown", new_state); } @@ -1831,29 +1761,6 @@ scanning_changed (NMDeviceIwd *self, gboolean new_scanning) } static void -station_properties_changed (GDBusProxy *proxy, GVariant *changed_properties, - GStrv invalidate_properties, gpointer user_data) -{ - NMDeviceIwd *self = user_data; - GVariantIter *iter; - const char *key; - GVariant *value; - - g_variant_get (changed_properties, "a{sv}", &iter); - while (g_variant_iter_next (iter, "{&sv}", &key, &value)) { - if (!strcmp (key, "State")) - state_changed (self, get_variant_state (value)); - - if (!strcmp (key, "Scanning")) - scanning_changed (self, get_variant_boolean (value, "Scanning")); - - g_variant_unref (value); - } - - g_variant_iter_free (iter); -} - -static void powered_changed (NMDeviceIwd *self, gboolean new_powered) { nm_device_queue_recheck_available (NM_DEVICE (self), @@ -1862,18 +1769,24 @@ powered_changed (NMDeviceIwd *self, gboolean new_powered) } static void -device_properties_changed (GDBusProxy *proxy, GVariant *changed_properties, - GStrv invalidate_properties, gpointer user_data) +properties_changed (GDBusProxy *proxy, GVariant *changed_properties, + GStrv invalidate_properties, gpointer user_data) { NMDeviceIwd *self = user_data; GVariantIter *iter; - const char *key; + const gchar *key; GVariant *value; g_variant_get (changed_properties, "a{sv}", &iter); while (g_variant_iter_next (iter, "{&sv}", &key, &value)) { + if (!strcmp (key, "State")) + state_changed (self, g_variant_get_string (value, NULL)); + + if (!strcmp (key, "Scanning")) + scanning_changed (self, g_variant_get_boolean (value)); + if (!strcmp (key, "Powered")) - powered_changed (self, get_variant_boolean (value, "Powered")); + powered_changed (self, g_variant_get_boolean (value)); g_variant_unref (value); } @@ -1891,13 +1804,11 @@ nm_device_iwd_set_dbus_object (NMDeviceIwd *self, GDBusObject *object) if (!nm_g_object_ref_set ((GObject **) &priv->dbus_obj, (GObject *) object)) return; - if (priv->dbus_device_proxy) { - g_signal_handlers_disconnect_by_func (priv->dbus_device_proxy, - device_properties_changed, self); - g_clear_object (&priv->dbus_device_proxy); - g_signal_handlers_disconnect_by_func (priv->dbus_station_proxy, - station_properties_changed, self); - g_clear_object (&priv->dbus_station_proxy); + if (priv->dbus_proxy) { + g_signal_handlers_disconnect_by_func (priv->dbus_proxy, + properties_changed, self); + + g_clear_object (&priv->dbus_proxy); } if (priv->enabled) @@ -1913,55 +1824,19 @@ nm_device_iwd_set_dbus_object (NMDeviceIwd *self, GDBusObject *object) } interface = g_dbus_object_get_interface (object, NM_IWD_DEVICE_INTERFACE); - if (!interface) { - _LOGE (LOGD_WIFI, "Interface %s not found on obj %s", - NM_IWD_DEVICE_INTERFACE, - g_dbus_object_get_object_path (object)); - goto error; - } - - priv->dbus_device_proxy = G_DBUS_PROXY (interface); - - g_signal_connect (priv->dbus_device_proxy, "g-properties-changed", - G_CALLBACK (device_properties_changed), self); - - interface = g_dbus_object_get_interface (object, NM_IWD_STATION_INTERFACE); - if (!interface) { - /* No Station interface on the device object. Check if the - * "State" property is present on the Device interface, that - * would mean we're dealing with an IWD version from before the - * Device/Station split (0.7 or earlier) and we can easily - * handle that by making priv->dbus_device_proxy and - * priv->dbus_station_proxy both point at the Device interface. - * - * TODO: handle device in a mode initially other than station - * -- also means the Station interface won't be there. - */ - value = g_dbus_proxy_get_cached_property (priv->dbus_device_proxy, "State"); - g_variant_unref (value); - if (!value) { - _LOGE (LOGD_WIFI, "Interface %s not found on obj %s", - NM_IWD_STATION_INTERFACE, - g_dbus_object_get_object_path (object)); - goto error; - } + priv->dbus_proxy = G_DBUS_PROXY (interface); - interface = g_object_ref (priv->dbus_device_proxy); - } - - priv->dbus_station_proxy = G_DBUS_PROXY (interface); - - value = g_dbus_proxy_get_cached_property (priv->dbus_station_proxy, "Scanning"); - priv->scanning = get_variant_boolean (value, "Scanning"); + value = g_dbus_proxy_get_cached_property (priv->dbus_proxy, "Scanning"); + priv->scanning = g_variant_get_boolean (value); g_variant_unref (value); priv->scan_requested = FALSE; - value = g_dbus_proxy_get_cached_property (priv->dbus_station_proxy, "State"); - state_changed (self, get_variant_state (value)); + value = g_dbus_proxy_get_cached_property (priv->dbus_proxy, "State"); + state_changed (self, g_variant_get_string (value, NULL)); g_variant_unref (value); - g_signal_connect (priv->dbus_station_proxy, "g-properties-changed", - G_CALLBACK (station_properties_changed), self); + g_signal_connect (priv->dbus_proxy, "g-properties-changed", + G_CALLBACK (properties_changed), self); set_powered (self, priv->enabled); @@ -1970,15 +1845,6 @@ nm_device_iwd_set_dbus_object (NMDeviceIwd *self, GDBusObject *object) */ if (priv->enabled) send_disconnect (self); - - return; -error: - g_clear_object (&priv->dbus_obj); - if (priv->dbus_device_proxy) { - g_signal_handlers_disconnect_by_func (priv->dbus_device_proxy, - device_properties_changed, self); - g_clear_object (&priv->dbus_device_proxy); - } } gboolean @@ -1986,8 +1852,8 @@ nm_device_iwd_agent_query (NMDeviceIwd *self, GDBusMethodInvocation *invocation) { NMActRequest *req; - const char *setting_name; - const char *setting_key; + const gchar *setting_name; + const gchar *setting_key; gboolean replied; NMSecretAgentGetSecretsFlags get_secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION; @@ -2071,8 +1937,7 @@ dispose (GObject *object) cleanup_association_attempt (self, TRUE); - g_clear_object (&priv->dbus_device_proxy); - g_clear_object (&priv->dbus_station_proxy); + g_clear_object (&priv->dbus_proxy); g_clear_object (&priv->dbus_obj); remove_all_aps (self); @@ -2087,7 +1952,9 @@ nm_device_iwd_class_init (NMDeviceIwdClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_WIRELESS_SETTING_NAME, NM_LINK_TYPE_WIFI) object_class->get_property = get_property; object_class->set_property = set_property; @@ -2095,29 +1962,25 @@ nm_device_iwd_class_init (NMDeviceIwdClass *klass) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&nm_interface_info_device_wireless); - device_class->connection_type_supported = NM_SETTING_WIRELESS_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_WIRELESS_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_WIFI); - - device_class->can_auto_connect = can_auto_connect; - device_class->is_available = is_available; - device_class->get_autoconnect_allowed = get_autoconnect_allowed; - device_class->check_connection_compatible = check_connection_compatible; - device_class->check_connection_available = check_connection_available; - device_class->complete_connection = complete_connection; - device_class->get_enabled = get_enabled; - device_class->set_enabled = set_enabled; - device_class->get_type_description = get_type_description; - - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->get_configured_mtu = get_configured_mtu; - device_class->deactivate = deactivate; - device_class->deactivate_async = deactivate_async; - device_class->deactivate_async_finish = deactivate_async_finish; - device_class->can_reapply_change = can_reapply_change; - - device_class->state_changed = device_state_changed; + parent_class->can_auto_connect = can_auto_connect; + parent_class->is_available = is_available; + parent_class->get_autoconnect_allowed = get_autoconnect_allowed; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->check_connection_available = check_connection_available; + parent_class->complete_connection = complete_connection; + parent_class->get_enabled = get_enabled; + parent_class->set_enabled = set_enabled; + parent_class->get_type_description = get_type_description; + + parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->act_stage2_config = act_stage2_config; + parent_class->get_configured_mtu = get_configured_mtu; + parent_class->deactivate = deactivate; + parent_class->deactivate_async = deactivate_async; + parent_class->deactivate_async_finish = deactivate_async_finish; + parent_class->can_reapply_change = can_reapply_change; + + parent_class->state_changed = device_state_changed; klass->scanning_prohibited = scanning_prohibited; diff --git a/src/devices/wifi/nm-device-olpc-mesh.c b/src/devices/wifi/nm-device-olpc-mesh.c index 6f833635..fd7bf3f7 100644 --- a/src/devices/wifi/nm-device-olpc-mesh.c +++ b/src/devices/wifi/nm-device-olpc-mesh.c @@ -80,6 +80,28 @@ G_DEFINE_TYPE (NMDeviceOlpcMesh, nm_device_olpc_mesh, NM_TYPE_DEVICE) /*****************************************************************************/ static gboolean +check_connection_compatible (NMDevice *device, NMConnection *connection) +{ + NMSettingConnection *s_con; + NMSettingOlpcMesh *s_mesh; + + if (!NM_DEVICE_CLASS (nm_device_olpc_mesh_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_OLPC_MESH_SETTING_NAME)) + return FALSE; + + s_mesh = nm_connection_get_setting_olpc_mesh (connection); + if (!s_mesh) + return FALSE; + + return TRUE; +} + +static gboolean get_autoconnect_allowed (NMDevice *device) { return FALSE; @@ -95,6 +117,7 @@ complete_connection (NMDevice *device, GError **error) { NMSettingOlpcMesh *s_mesh; + GByteArray *tmp; s_mesh = nm_connection_get_setting_olpc_mesh (connection); if (!s_mesh) { @@ -103,10 +126,10 @@ complete_connection (NMDevice *device, } if (!nm_setting_olpc_mesh_get_ssid (s_mesh)) { - gs_unref_bytes GBytes *ssid = NULL; - - ssid = g_bytes_new_static (DEFAULT_SSID, NM_STRLEN (DEFAULT_SSID)); - g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_SSID, ssid, NULL); + tmp = g_byte_array_sized_new (strlen (DEFAULT_SSID)); + g_byte_array_append (tmp, (const guint8 *) DEFAULT_SSID, strlen (DEFAULT_SSID)); + g_object_set (G_OBJECT (s_mesh), NM_SETTING_OLPC_MESH_SSID, tmp, NULL); + g_byte_array_free (tmp, TRUE); } if (!nm_setting_olpc_mesh_get_dhcp_anycast_address (s_mesh)) { @@ -492,7 +515,9 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_OLPC_MESH_SETTING_NAME, NM_LINK_TYPE_OLPC_MESH) object_class->constructed = constructed; object_class->get_property = get_property; @@ -500,17 +525,14 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&interface_info_device_olpc_mesh); - device_class->connection_type_supported = NM_SETTING_OLPC_MESH_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_OLPC_MESH_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_OLPC_MESH); - - device_class->get_autoconnect_allowed = get_autoconnect_allowed; - device_class->complete_connection = complete_connection; - device_class->is_available = is_available; - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->state_changed = state_changed; - device_class->get_dhcp_timeout = get_dhcp_timeout; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->get_autoconnect_allowed = get_autoconnect_allowed; + parent_class->complete_connection = complete_connection; + parent_class->is_available = is_available; + parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->act_stage2_config = act_stage2_config; + parent_class->state_changed = state_changed; + parent_class->get_dhcp_timeout = get_dhcp_timeout; obj_properties[PROP_COMPANION] = g_param_spec_string (NM_DEVICE_OLPC_MESH_COMPANION, "", "", diff --git a/src/devices/wifi/nm-device-wifi.c b/src/devices/wifi/nm-device-wifi.c index ec1150bb..0dd6fa74 100644 --- a/src/devices/wifi/nm-device-wifi.c +++ b/src/devices/wifi/nm-device-wifi.c @@ -121,8 +121,6 @@ typedef struct { gint32 hw_addr_scan_expire; guint wps_timeout_id; - - NMSettingWirelessWakeOnWLan wowlan_restore; } NMDeviceWifiPrivate; struct _NMDeviceWifi @@ -438,7 +436,7 @@ periodic_update (NMDeviceWifi *self) percent = nm_platform_wifi_get_quality (nm_device_get_platform (NM_DEVICE (self)), ifindex); if (percent >= 0 || ++priv->invalid_strength_counter > 3) { if (nm_wifi_ap_set_strength (priv->current_ap, (gint8) percent)) { -#if NM_MORE_LOGGING +#ifdef NM_MORE_LOGGING _ap_dump (self, LOGL_TRACE, priv->current_ap, "updated", 0); #endif } @@ -510,22 +508,6 @@ remove_all_aps (NMDeviceWifi *self) nm_device_recheck_available_connections (NM_DEVICE (self)); } -static gboolean -wake_on_wlan_restore (NMDeviceWifi *self) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMSettingWirelessWakeOnWLan w; - - w = priv->wowlan_restore; - if (w == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) - return TRUE; - - 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); -} - static void deactivate (NMDevice *device) { @@ -542,9 +524,6 @@ deactivate (NMDevice *device) set_current_ap (self, NULL, TRUE); - if (!wake_on_wlan_restore (self)) - _LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot unconfigure WoWLAN."); - /* Clear any critical protocol notification in the Wi-Fi stack */ nm_platform_wifi_indicate_addressing_running (nm_device_get_platform (device), ifindex, FALSE); @@ -604,10 +583,11 @@ is_adhoc_wpa (NMConnection *connection) } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); + NMSettingConnection *s_con; NMSettingWireless *s_wireless; const char *mac; const char * const *mac_blacklist; @@ -615,19 +595,24 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError const char *mode; const char *perm_hw_addr; - if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->check_connection_compatible (device, connection)) + return FALSE; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIRELESS_SETTING_NAME)) return FALSE; s_wireless = nm_connection_get_setting_wireless (connection); + if (!s_wireless) + return FALSE; perm_hw_addr = nm_device_get_permanent_hw_address (device); mac = nm_setting_wireless_get_mac_address (s_wireless); if (perm_hw_addr) { - if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device MAC address does not match the profile"); + if (mac && !nm_utils_hwaddr_matches (mac, -1, perm_hw_addr, -1)) return FALSE; - } /* Check for MAC address blacklist */ mac_blacklist = nm_setting_wireless_get_mac_address_blacklist (s_wireless); @@ -637,45 +622,27 @@ check_connection_compatible (NMDevice *device, NMConnection *connection, GError return FALSE; } - if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, perm_hw_addr, -1)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "MAC address blacklisted"); + if (nm_utils_hwaddr_matches (mac_blacklist[i], -1, perm_hw_addr, -1)) return FALSE; - } } - } else if (mac) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has no valid MAC address as required by profile"); + } else if (mac) return FALSE; - } - if (is_adhoc_wpa (connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "Ad-Hoc WPA networks are not supported"); + if (is_adhoc_wpa (connection)) return FALSE; - } /* 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)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "the device does not support Ad-Hoc networks"); + if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_ADHOC)) return FALSE; - } } else if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0) { - 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"); + if (!(priv->capabilities & NM_WIFI_DEVICE_CAP_AP)) return FALSE; - } if (priv->sup_iface) { - if (nm_supplicant_interface_get_ap_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_NO) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "wpa_supplicant does not support Access Point mode"); + if (nm_supplicant_interface_get_ap_support (priv->sup_iface) == NM_SUPPLICANT_FEATURE_NO) return FALSE; - } } } @@ -690,8 +657,7 @@ static gboolean check_connection_available (NMDevice *device, NMConnection *connection, NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) + const char *specific_object) { NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); @@ -708,17 +674,7 @@ check_connection_available (NMDevice *device, NMWifiAP *ap; ap = nm_wifi_ap_lookup_for_device (NM_DEVICE (self), specific_object); - if (!ap) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "requested access point not found"); - return FALSE; - } - if (!nm_wifi_ap_check_compatible (ap, connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "requested access point is not compatible with profile"); - return FALSE; - } - return TRUE; + return ap ? nm_wifi_ap_check_compatible (ap, connection) : FALSE; } /* Ad-Hoc and AP connections are always available because they may be @@ -737,17 +693,11 @@ check_connection_available (NMDevice *device, * activating but the network isn't available let the device recheck * availability. */ - if ( nm_setting_wireless_get_hidden (s_wifi) - || NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP)) + if (nm_setting_wireless_get_hidden (s_wifi) || NM_FLAGS_HAS (flags, _NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST_IGNORE_AP)) return TRUE; - if (!nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "no compatible access point found"); - return FALSE; - } - - return TRUE; + /* check at least one AP is compatible with this connection */ + return !!nm_wifi_aps_find_first_compatible (&priv->aps_lst_head, connection); } static gboolean @@ -761,9 +711,10 @@ complete_connection (NMDevice *device, NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMSettingWireless *s_wifi; const char *setting_mac; - gs_free char *ssid_utf8 = NULL; + char *str_ssid = NULL; NMWifiAP *ap; - GBytes *ssid = NULL; + const GByteArray *ssid = NULL; + GByteArray *tmp_ssid = NULL; GBytes *setting_ssid = NULL; gboolean hidden = FALSE; const char *perm_hw_addr; @@ -835,14 +786,19 @@ complete_connection (NMDevice *device, if (ap) ssid = nm_wifi_ap_get_ssid (ap); - if (ssid == NULL) { /* The AP must be hidden. Connecting to a WiFi AP requires the SSID * as part of the initial handshake, so check the connection details * for the SSID. The AP object will still be used for encryption * settings and such. */ - ssid = nm_setting_wireless_get_ssid (s_wifi); + setting_ssid = nm_setting_wireless_get_ssid (s_wifi); + if (setting_ssid) { + ssid = tmp_ssid = g_byte_array_new (); + g_byte_array_append (tmp_ssid, + g_bytes_get_data (setting_ssid, NULL), + g_bytes_get_size (setting_ssid)); + } } if (ssid == NULL) { @@ -865,8 +821,11 @@ complete_connection (NMDevice *device, if (!nm_wifi_ap_complete_connection (ap, connection, nm_wifi_utils_is_manf_default_ssid (ssid), - error)) + error)) { + if (tmp_ssid) + g_byte_array_unref (tmp_ssid); return FALSE; + } } /* The kernel doesn't support Ad-Hoc WPA connections well at this time, @@ -879,18 +838,24 @@ complete_connection (NMDevice *device, NM_CONNECTION_ERROR_INVALID_SETTING, _("WPA Ad-Hoc disabled due to kernel bugs")); g_prefix_error (error, "%s: ", NM_SETTING_WIRELESS_SECURITY_SETTING_NAME); + if (tmp_ssid) + g_byte_array_unref (tmp_ssid); return FALSE; } - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); + str_ssid = nm_utils_ssid_to_utf8 (ssid->data, ssid->len); + nm_utils_complete_generic (nm_device_get_platform (device), connection, NM_SETTING_WIRELESS_SETTING_NAME, existing_connections, - ssid_utf8, - ssid_utf8, + str_ssid, + str_ssid, NULL, TRUE); + g_free (str_ssid); + if (tmp_ssid) + g_byte_array_unref (tmp_ssid); if (hidden) g_object_set (s_wifi, NM_SETTING_WIRELESS_HIDDEN, TRUE, NULL); @@ -958,12 +923,11 @@ get_autoconnect_allowed (NMDevice *device) static gboolean can_auto_connect (NMDevice *device, - NMSettingsConnection *sett_conn, + NMConnection *connection, char **specific_object) { NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - NMConnection *connection; NMSettingWireless *s_wifi; NMWifiAP *ap; const char *method, *mode; @@ -971,28 +935,26 @@ can_auto_connect (NMDevice *device, nm_assert (!specific_object || !*specific_object); - if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->can_auto_connect (device, sett_conn, NULL)) + if (!NM_DEVICE_CLASS (nm_device_wifi_parent_class)->can_auto_connect (device, connection, NULL)) return FALSE; - connection = nm_settings_connection_get_connection (sett_conn); - s_wifi = nm_connection_get_setting_wireless (connection); g_return_val_if_fail (s_wifi, FALSE); /* Always allow autoconnect for AP and non-autoconf Ad-Hoc */ method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); mode = nm_setting_wireless_get_mode (s_wifi); - if (nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_AP)) + if (g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_AP) == 0) return TRUE; - else if ( nm_streq0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) - && !nm_streq0 (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) + else if ( g_strcmp0 (mode, NM_SETTING_WIRELESS_MODE_ADHOC) == 0 + && g_strcmp0 (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) != 0) return TRUE; /* Don't autoconnect to networks that have been tried at least once * but haven't been successful, since these are often accidental choices * from the menu and the user may not know the password. */ - if (nm_settings_connection_get_timestamp (sett_conn, ×tamp)) { + if (nm_settings_connection_get_timestamp (NM_SETTINGS_CONNECTION (connection), ×tamp)) { if (timestamp == 0) return FALSE; } @@ -1071,6 +1033,7 @@ static GPtrArray * ssids_options_to_ptrarray (GVariant *value, GError **error) { GPtrArray *ssids = NULL; + GByteArray *ssid_array; GVariant *v; const guint8 *bytes; gsize len; @@ -1086,7 +1049,7 @@ ssids_options_to_ptrarray (GVariant *value, GError **error) } if (num_ssids) { - ssids = g_ptr_array_new_full (num_ssids, (GDestroyNotify) g_bytes_unref); + ssids = g_ptr_array_new_full (num_ssids, (GDestroyNotify) g_byte_array_unref); for (i = 0; i < num_ssids; i++) { v = g_variant_get_child_value (value, i); bytes = g_variant_get_fixed_array (v, &len, sizeof (guint8)); @@ -1099,7 +1062,9 @@ ssids_options_to_ptrarray (GVariant *value, GError **error) return NULL; } - g_ptr_array_add (ssids, g_bytes_new (bytes, len)); + ssid_array = g_byte_array_new (); + g_byte_array_append (ssid_array, bytes, len); + g_ptr_array_add (ssids, ssid_array); } } return ssids; @@ -1267,15 +1232,14 @@ check_scanning_prohibited (NMDeviceWifi *self, gboolean periodic) static gboolean hidden_filter_func (NMSettings *settings, - NMSettingsConnection *set_con, + NMSettingsConnection *connection, gpointer user_data) { - NMConnection *connection = nm_settings_connection_get_connection (set_con); NMSettingWireless *s_wifi; - if (!nm_connection_is_type (connection, NM_SETTING_WIRELESS_SETTING_NAME)) + if (!nm_connection_is_type (NM_CONNECTION (connection), NM_SETTING_WIRELESS_SETTING_NAME)) return FALSE; - s_wifi = nm_connection_get_setting_wireless (connection); + s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (connection)); if (!s_wifi) return FALSE; if (nm_streq0 (nm_setting_wireless_get_mode (s_wifi), NM_SETTING_WIRELESS_MODE_AP)) @@ -1291,7 +1255,7 @@ build_hidden_probe_list (NMDeviceWifi *self) gs_free NMSettingsConnection **connections = NULL; guint i, len; GPtrArray *ssids = NULL; - static GBytes *nullssid = NULL; + static GByteArray *nullssid = NULL; /* Need at least two: wildcard SSID and one or more hidden SSIDs */ if (max_scan_ssids < 2) @@ -1306,23 +1270,30 @@ build_hidden_probe_list (NMDeviceWifi *self) g_qsort_with_data (connections, len, sizeof (NMSettingsConnection *), nm_settings_connection_cmp_timestamp_p_with_data, NULL); - ssids = g_ptr_array_new_full (max_scan_ssids, (GDestroyNotify) g_bytes_unref); + ssids = g_ptr_array_new_full (max_scan_ssids, (GDestroyNotify) g_byte_array_unref); /* Add wildcard SSID using a static wildcard SSID used for every scan */ if (G_UNLIKELY (nullssid == NULL)) - nullssid = g_bytes_new_static ("", 0); - g_ptr_array_add (ssids, g_bytes_ref (nullssid)); + nullssid = g_byte_array_new (); + g_ptr_array_add (ssids, g_byte_array_ref (nullssid)); for (i = 0; connections[i]; i++) { NMSettingWireless *s_wifi; GBytes *ssid; + GByteArray *ssid_array; if (i >= max_scan_ssids - 1) break; - s_wifi = (NMSettingWireless *) nm_connection_get_setting_wireless (nm_settings_connection_get_connection (connections[i])); + s_wifi = (NMSettingWireless *) nm_connection_get_setting_wireless (NM_CONNECTION (connections[i])); + g_assert (s_wifi); ssid = nm_setting_wireless_get_ssid (s_wifi); - g_ptr_array_add (ssids, g_bytes_ref (ssid)); + g_assert (ssid); + ssid_array = g_byte_array_new (); + g_byte_array_append (ssid_array, + g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); + g_ptr_array_add (ssids, ssid_array); } return ssids; @@ -1349,22 +1320,24 @@ request_wireless_scan (NMDeviceWifi *self, _LOGD (LOGD_WIFI, "wifi-scan: scanning requested"); - if (!ssids) + if (!ssids) { ssids = hidden_ssids = build_hidden_probe_list (self); + } if (_LOGD_ENABLED (LOGD_WIFI)) { if (ssids) { + const GByteArray *ssid; guint i; + char *foo; for (i = 0; i < ssids->len; i++) { - gs_free char *ssid_str = NULL; - GBytes *ssid = ssids->pdata[i]; - - ssid_str = g_bytes_get_size (ssid) > 0 - ? _nm_utils_ssid_to_string (ssid) - : NULL; - _LOGD (LOGD_WIFI, "wifi-scan: (%u) probe scanning SSID %s", - i, ssid_str ?: "*any*"); + ssid = g_ptr_array_index (ssids, i); + foo = ssid->len > 0 + ? nm_utils_ssid_to_utf8 (ssid->data, ssid->len) + : NULL; + _LOGD (LOGD_WIFI, "wifi-scan: (%u) probe scanning SSID %s%s%s", + i, NM_PRINT_FMT_QUOTED (foo, "\"", foo, "\"", "*any*")); + g_free (foo); } } else _LOGD (LOGD_WIFI, "wifi-scan: no SSIDs to probe scan"); @@ -1372,9 +1345,7 @@ request_wireless_scan (NMDeviceWifi *self, _hw_addr_set_scanning (self, FALSE); - nm_supplicant_interface_request_scan (priv->sup_iface, - ssids ? (GBytes *const*) ssids->pdata : NULL, - ssids ? ssids->len : 0u); + nm_supplicant_interface_request_scan (priv->sup_iface, ssids); request_started = TRUE; } else _LOGD (LOGD_WIFI, "wifi-scan: scanning requested but not allowed at this time"); @@ -1513,13 +1484,17 @@ try_fill_ssid_for_hidden_ap (NMDeviceWifi *self, * and if a match is found, copy over the SSID */ connections = nm_settings_get_connections (nm_device_get_settings ((NMDevice *) self), NULL); for (i = 0; connections[i]; i++) { - NMSettingsConnection *sett_conn = connections[i]; + NMConnection *connection = (NMConnection *) connections[i]; NMSettingWireless *s_wifi; - s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (sett_conn)); + s_wifi = nm_connection_get_setting_wireless (connection); if (s_wifi) { - if (nm_settings_connection_has_seen_bssid (sett_conn, bssid)) { - nm_wifi_ap_set_ssid (ap, nm_setting_wireless_get_ssid (s_wifi)); + if (nm_settings_connection_has_seen_bssid (NM_SETTINGS_CONNECTION (connection), bssid)) { + GBytes *ssid = nm_setting_wireless_get_ssid (s_wifi); + + nm_wifi_ap_set_ssid (ap, + g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); break; } } @@ -1535,7 +1510,7 @@ supplicant_iface_bss_updated_cb (NMSupplicantInterface *iface, NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMDeviceState state; NMWifiAP *found_ap = NULL; - GBytes *ssid; + const GByteArray *ssid; g_return_if_fail (self != NULL); g_return_if_fail (properties != NULL); @@ -1564,19 +1539,15 @@ supplicant_iface_bss_updated_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 (ssid->data, ssid->len)) { /* 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)) { - gs_free char *s = NULL; - + if (ssid && (nm_utils_is_empty_ssid (ssid->data, ssid->len) == FALSE)) { /* 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))); + _LOGD (LOGD_WIFI, "matched hidden AP %s => '%s'", + nm_wifi_ap_get_address (ap), nm_utils_escape_ssid (ssid->data, ssid->len)); } else { /* Didn't have an entry for this AP in the database */ _LOGD (LOGD_WIFI, "failed to match hidden AP %s", @@ -1888,7 +1859,7 @@ need_new_8021x_secrets (NMDeviceWifi *self, static gboolean need_new_wpa_psk (NMDeviceWifi *self, NMSupplicantInterfaceState old_state, - int disconnect_reason, + gint disconnect_reason, const char **setting_name) { NMSettingWirelessSecurity *s_wsec; @@ -2033,7 +2004,6 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, NMConnection *connection; NMSettingWireless *s_wifi; GBytes *ssid; - gs_free char *ssid_str = NULL; connection = nm_device_get_applied_connection (NM_DEVICE (self)); g_return_if_fail (connection); @@ -2045,11 +2015,11 @@ supplicant_iface_state_cb (NMSupplicantInterface *iface, g_return_if_fail (ssid); _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))); + "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 ? nm_utils_escape_ssid (g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)) : "(none)"); nm_device_activate_schedule_stage3_ip_config_start (device); } else if (devstate == NM_DEVICE_STATE_ACTIVATED) periodic_update (self); @@ -2157,11 +2127,9 @@ supplicant_iface_notify_current_bss (NMSupplicantInterface *iface, if (new_ap != priv->current_ap) { const char *new_bssid = NULL; - GBytes *new_ssid = NULL; + const GByteArray *new_ssid = NULL; const char *old_bssid = NULL; - GBytes *old_ssid = NULL; - gs_free char *new_ssid_s = NULL; - gs_free char *old_ssid_s = NULL; + const GByteArray *old_ssid = NULL; /* Don't ever replace a "fake" current AP if we don't know about the * supplicant's current BSS yet. It'll get replaced when we receive @@ -2182,9 +2150,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 ? nm_utils_escape_ssid (old_ssid->data, old_ssid->len) : "(none)", new_bssid ?: "(none)", - (new_ssid_s = _nm_utils_ssid_to_string (new_ssid))); + new_ssid ? nm_utils_escape_ssid (new_ssid->data, new_ssid->len) : "(none)"); set_current_ap (self, new_ap, TRUE); } @@ -2364,6 +2332,7 @@ build_supplicant_config (NMDeviceWifi *self, NMSettingWirelessSecurity *s_wireless_sec; NMSettingWirelessSecurityPmf pmf; NMSettingWirelessSecurityFils fils; + gs_free char *value = NULL; g_return_val_if_fail (priv->sup_iface, NULL); @@ -2405,23 +2374,25 @@ build_supplicant_config (NMDeviceWifi *self, /* Configure PMF (802.11w) */ pmf = nm_setting_wireless_security_get_pmf (s_wireless_sec); if (pmf == NM_SETTING_WIRELESS_SECURITY_PMF_DEFAULT) { - pmf = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "wifi-sec.pmf", - NM_DEVICE (self), - NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE, - NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED, - NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL); + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "wifi-sec.pmf", + NM_DEVICE (self)); + pmf = _nm_utils_ascii_str_to_int64 (value, 10, + NM_SETTING_WIRELESS_SECURITY_PMF_DISABLE, + NM_SETTING_WIRELESS_SECURITY_PMF_REQUIRED, + NM_SETTING_WIRELESS_SECURITY_PMF_OPTIONAL); } /* Configure FILS (802.11ai) */ fils = nm_setting_wireless_security_get_fils (s_wireless_sec); if (fils == NM_SETTING_WIRELESS_SECURITY_FILS_DEFAULT) { - fils = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "wifi-sec.fils", - NM_DEVICE (self), - NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE, - NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED, - NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL); + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "wifi-sec.fils", + NM_DEVICE (self)); + fils = _nm_utils_ascii_str_to_int64 (value, 10, + NM_SETTING_WIRELESS_SECURITY_FILS_DISABLE, + NM_SETTING_WIRELESS_SECURITY_FILS_REQUIRED, + NM_SETTING_WIRELESS_SECURITY_FILS_OPTIONAL); } s_8021x = nm_connection_get_setting_802_1x (connection); @@ -2455,9 +2426,9 @@ error: static gboolean wake_on_wlan_enable (NMDeviceWifi *self) { - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); NMSettingWirelessWakeOnWLan wowl; NMSettingWireless *s_wireless; + gs_free char *value = NULL; s_wireless = (NMSettingWireless *) nm_device_get_applied_setting (NM_DEVICE (self), NM_TYPE_SETTING_WIRELESS); if (s_wireless) { @@ -2466,39 +2437,32 @@ wake_on_wlan_enable (NMDeviceWifi *self) goto found; } - wowl = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "wifi.wake-on-wlan", - NM_DEVICE (self), - NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE, - G_MAXINT32, - NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT); + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "wifi.wake-on-wlan", + NM_DEVICE (self)); + + if (value) { + wowl = _nm_utils_ascii_str_to_int64 (value, 10, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE, + G_MAXINT32, + NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT); - if (NM_FLAGS_ANY (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS)) { - if (!nm_utils_is_power_of_two (wowl)) { - _LOGD (LOGD_WIFI, "invalid default value %u for wake-on-wlan: " - "'default' and 'ignore' are exclusive flags", (guint) wowl); + if (NM_FLAGS_ANY (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_EXCLUSIVE_FLAGS)) { + if (!nm_utils_is_power_of_two (wowl)) { + _LOGD (LOGD_WIFI, "invalid default value %u for wake-on-wlan: " + "'default' and 'ignore' are exclusive flags", (guint) wowl); + wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT; + } + } else if (NM_FLAGS_ANY (wowl, ~NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL)) { + _LOGD (LOGD_WIFI, "invalid default value %u for wake-on-wlan", (guint) wowl); wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT; } - } else if (NM_FLAGS_ANY (wowl, ~NM_SETTING_WIRELESS_WAKE_ON_WLAN_ALL)) { - _LOGD (LOGD_WIFI, "invalid default value %u for wake-on-wlan", (guint) wowl); - wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT; + if (wowl != NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT) + goto found; } - if (wowl != NM_SETTING_WIRELESS_WAKE_ON_WLAN_DEFAULT) - goto found; - wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; found: - if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) { - priv->wowlan_restore = wowl; - return TRUE; - } - - priv->wowlan_restore = nm_platform_wifi_get_wake_on_wlan (NM_PLATFORM_GET, - nm_device_get_ifindex (NM_DEVICE (self))); - - return nm_platform_wifi_set_wake_on_wlan (NM_PLATFORM_GET, - nm_device_get_ifindex (NM_DEVICE (self)), - wowl); + return nm_platform_wifi_set_wake_on_wlan (NM_PLATFORM_GET, nm_device_get_ifindex (NM_DEVICE (self)), wowl); } static NMActStageReturn @@ -2634,29 +2598,31 @@ set_powersave (NMDevice *device) { NMDeviceWifi *self = NM_DEVICE_WIFI (device); NMSettingWireless *s_wireless; - NMSettingWirelessPowersave val; + NMSettingWirelessPowersave powersave; + gs_free char *value = NULL; s_wireless = (NMSettingWireless *) nm_device_get_applied_setting (device, NM_TYPE_SETTING_WIRELESS); g_return_if_fail (s_wireless); - val = nm_setting_wireless_get_powersave (s_wireless); - if (val == NM_SETTING_WIRELESS_POWERSAVE_DEFAULT) { - val = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "wifi.powersave", - device, - NM_SETTING_WIRELESS_POWERSAVE_IGNORE, - NM_SETTING_WIRELESS_POWERSAVE_ENABLE, - NM_SETTING_WIRELESS_POWERSAVE_IGNORE); + powersave = nm_setting_wireless_get_powersave (s_wireless); + if (powersave == NM_SETTING_WIRELESS_POWERSAVE_DEFAULT) { + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "wifi.powersave", + device); + powersave = _nm_utils_ascii_str_to_int64 (value, 10, + NM_SETTING_WIRELESS_POWERSAVE_IGNORE, + NM_SETTING_WIRELESS_POWERSAVE_ENABLE, + NM_SETTING_WIRELESS_POWERSAVE_IGNORE); } - _LOGT (LOGD_WIFI, "powersave is set to %u", (unsigned) val); + _LOGT (LOGD_WIFI, "powersave is set to %u", (unsigned) powersave); - if (val == NM_SETTING_WIRELESS_POWERSAVE_IGNORE) + if (powersave == NM_SETTING_WIRELESS_POWERSAVE_IGNORE) return; nm_platform_wifi_set_powersave (nm_device_get_platform (device), nm_device_get_ifindex (device), - val == NM_SETTING_WIRELESS_POWERSAVE_ENABLE); + powersave == NM_SETTING_WIRELESS_POWERSAVE_ENABLE); } static NMActStageReturn @@ -2693,6 +2659,8 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) s_wireless = nm_connection_get_setting_wireless (connection); g_assert (s_wireless); + wake_on_wlan_enable (self); + /* If we need secrets, get them */ setting_name = nm_connection_need_secrets (connection, NULL); if (setting_name) { @@ -2709,9 +2677,6 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) goto out; } - if (!wake_on_wlan_enable (self)) - _LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot configure WoWLAN."); - /* have secrets, or no secrets required */ if (nm_connection_get_setting_wireless_security (connection)) { _LOGI (LOGD_DEVICE | LOGD_WIFI, @@ -2762,10 +2727,8 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *out_failure_reason) ret = NM_ACT_STAGE_RETURN_POSTPONE; out: - if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + if (ret == NM_ACT_STAGE_RETURN_FAILURE) cleanup_association_attempt (self, TRUE); - wake_on_wlan_restore (self); - } if (config) { /* Supplicant interface object refs the config; we no longer care about @@ -3171,8 +3134,7 @@ reapply_connection (NMDevice *device, NMConnection *con_old, NMConnection *con_n _LOGD (LOGD_DEVICE, "reapplying wireless settings"); - if (!wake_on_wlan_enable (self)) - _LOGW (LOGD_DEVICE | LOGD_WIFI, "Cannot configure WoWLAN."); + wake_on_wlan_enable (self); } /*****************************************************************************/ @@ -3245,7 +3207,6 @@ nm_device_wifi_init (NMDeviceWifi *self) c_list_init (&priv->aps_lst_head); priv->mode = NM_802_11_MODE_INFRA; - priv->wowlan_restore = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; } static void @@ -3313,7 +3274,9 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS (klass); - NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + + NM_DEVICE_CLASS_DECLARE_TYPES (klass, NM_SETTING_WIRELESS_SETTING_NAME, NM_LINK_TYPE_WIFI) object_class->constructed = constructed; object_class->get_property = get_property; @@ -3323,33 +3286,29 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass) dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS (&nm_interface_info_device_wireless); - device_class->connection_type_supported = NM_SETTING_WIRELESS_SETTING_NAME; - device_class->connection_type_check_compatible = NM_SETTING_WIRELESS_SETTING_NAME; - device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES (NM_LINK_TYPE_WIFI); - - device_class->can_auto_connect = can_auto_connect; - device_class->get_autoconnect_allowed = get_autoconnect_allowed; - device_class->is_available = is_available; - device_class->check_connection_compatible = check_connection_compatible; - device_class->check_connection_available = check_connection_available; - device_class->complete_connection = complete_connection; - device_class->get_enabled = get_enabled; - device_class->set_enabled = set_enabled; - - device_class->act_stage1_prepare = act_stage1_prepare; - device_class->act_stage2_config = act_stage2_config; - device_class->get_configured_mtu = get_configured_mtu; - device_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; - device_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start; - device_class->act_stage4_ip4_config_timeout = act_stage4_ip4_config_timeout; - device_class->act_stage4_ip6_config_timeout = act_stage4_ip6_config_timeout; - device_class->deactivate = deactivate; - device_class->deactivate_reset_hw_addr = deactivate_reset_hw_addr; - device_class->unmanaged_on_quit = unmanaged_on_quit; - device_class->can_reapply_change = can_reapply_change; - device_class->reapply_connection = reapply_connection; - - device_class->state_changed = device_state_changed; + parent_class->can_auto_connect = can_auto_connect; + parent_class->get_autoconnect_allowed = get_autoconnect_allowed; + parent_class->is_available = is_available; + parent_class->check_connection_compatible = check_connection_compatible; + parent_class->check_connection_available = check_connection_available; + parent_class->complete_connection = complete_connection; + parent_class->get_enabled = get_enabled; + parent_class->set_enabled = set_enabled; + + parent_class->act_stage1_prepare = act_stage1_prepare; + parent_class->act_stage2_config = act_stage2_config; + parent_class->get_configured_mtu = get_configured_mtu; + parent_class->act_stage3_ip4_config_start = act_stage3_ip4_config_start; + parent_class->act_stage3_ip6_config_start = act_stage3_ip6_config_start; + parent_class->act_stage4_ip4_config_timeout = act_stage4_ip4_config_timeout; + parent_class->act_stage4_ip6_config_timeout = act_stage4_ip6_config_timeout; + parent_class->deactivate = deactivate; + parent_class->deactivate_reset_hw_addr = deactivate_reset_hw_addr; + parent_class->unmanaged_on_quit = unmanaged_on_quit; + parent_class->can_reapply_change = can_reapply_change; + parent_class->reapply_connection = reapply_connection; + + parent_class->state_changed = device_state_changed; klass->scanning_prohibited = scanning_prohibited; diff --git a/src/devices/wifi/nm-iwd-manager.c b/src/devices/wifi/nm-iwd-manager.c index 1f28d263..d6511296 100644 --- a/src/devices/wifi/nm-iwd-manager.c +++ b/src/devices/wifi/nm-iwd-manager.c @@ -29,21 +29,13 @@ #include "nm-core-internal.h" #include "nm-manager.h" #include "nm-device-iwd.h" -#include "nm-wifi-utils.h" #include "nm-utils/nm-random-utils.h" -#include "settings/nm-settings.h" /*****************************************************************************/ typedef struct { - const char *name; + gchar *name; NMIwdNetworkSecurity security; - char buf[0]; -} KnownNetworkId; - -typedef struct { - GDBusProxy *known_network; - NMSettingsConnection *mirror_connection; } KnownNetworkData; typedef struct { @@ -52,8 +44,8 @@ typedef struct { gboolean running; GDBusObjectManager *object_manager; guint agent_id; - char *agent_path; - GHashTable *known_networks; + gchar *agent_path; + GSList *known_networks; } NMIwdManagerPrivate; struct _NMIwdManager { @@ -91,49 +83,20 @@ G_DEFINE_TYPE (NMIwdManager, nm_iwd_manager, G_TYPE_OBJECT) /*****************************************************************************/ -static void mirror_8021x_connection_take_and_delete (NMSettingsConnection *sett_conn); - -/*****************************************************************************/ - -static const char * -get_variant_string_or_null (GVariant *v) -{ - if (!v) - return NULL; - - if ( !g_variant_is_of_type (v, G_VARIANT_TYPE_STRING) - && !g_variant_is_of_type (v, G_VARIANT_TYPE_OBJECT_PATH)) - return NULL; - - return g_variant_get_string (v, NULL); -} - -static const char * -get_property_string_or_null (GDBusProxy *proxy, const char *property) -{ - gs_unref_variant GVariant *value = NULL; - - if (!proxy || !property) - return NULL; - - value = g_dbus_proxy_get_cached_property (proxy, property); - - return get_variant_string_or_null (value); -} - static void agent_dbus_method_cb (GDBusConnection *connection, - const char *sender, const char *object_path, - const char *interface_name, const char *method_name, + const gchar *sender, const gchar *object_path, + const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data) { NMIwdManager *self = user_data; NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - const char *network_path, *device_path, *ifname; + const gchar *network_path, *device_path, *ifname; gs_unref_object GDBusInterface *network = NULL, *device_obj = NULL; - int ifindex; + gs_unref_variant GVariant *value = NULL; + gint ifindex; NMDevice *device; gs_free char *name_owner = NULL; @@ -150,8 +113,9 @@ agent_dbus_method_cb (GDBusConnection *connection, network = g_dbus_object_manager_get_interface (priv->object_manager, network_path, NM_IWD_NETWORK_INTERFACE); + value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (network), "Device"); + device_path = g_variant_get_string (value, NULL); - device_path = get_property_string_or_null (G_DBUS_PROXY (network), "Device"); if (!device_path) { _LOGD ("agent-request: device not cached for network %s in IWD Agent request", network_path); @@ -161,8 +125,10 @@ agent_dbus_method_cb (GDBusConnection *connection, device_obj = g_dbus_object_manager_get_interface (priv->object_manager, device_path, NM_IWD_DEVICE_INTERFACE); + g_variant_unref (value); + value = g_dbus_proxy_get_cached_property (G_DBUS_PROXY (device_obj), "Name"); + ifname = g_variant_get_string (value, NULL); - ifname = get_property_string_or_null (G_DBUS_PROXY (device_obj), "Name"); if (!ifname) { _LOGD ("agent-request: name not cached for device %s in IWD Agent request", device_path); @@ -241,12 +207,12 @@ static const GDBusInterfaceInfo iwd_agent_iface_info = NM_DEFINE_GDBUS_INTERFACE static guint iwd_agent_export (GDBusConnection *connection, gpointer user_data, - char **agent_path, GError **error) + gchar **agent_path, GError **error) { static const GDBusInterfaceVTable vtable = { .method_call = agent_dbus_method_cb, }; - char path[50]; + gchar path[50]; unsigned int rnd; guint id; @@ -285,68 +251,38 @@ register_agent (NMIwdManager *self) /*****************************************************************************/ -static KnownNetworkId * -known_network_id_new (const char *name, NMIwdNetworkSecurity security) -{ - KnownNetworkId *id; - gsize strsize = strlen (name) + 1; - - id = g_malloc (sizeof (KnownNetworkId) + strsize); - id->name = id->buf; - id->security = security; - memcpy (id->buf, name, strsize); - - return id; -} - -static guint -known_network_id_hash (KnownNetworkId *id) -{ - NMHashState h; - - nm_hash_init (&h, 1947951703u); - nm_hash_update_val (&h, id->security); - nm_hash_update_str (&h, id->name); - return nm_hash_complete (&h); -} - -static gboolean -known_network_id_equal (KnownNetworkId *a, KnownNetworkId *b) -{ - return a->security == b->security - && nm_streq (a->name, b->name); -} - -static void -known_network_data_free (KnownNetworkData *network) -{ - if (!network) - return; - - g_object_unref (network->known_network); - mirror_8021x_connection_take_and_delete (network->mirror_connection); - g_slice_free (KnownNetworkData, network); -} - -/*****************************************************************************/ - static void -set_device_dbus_object (NMIwdManager *self, GDBusProxy *proxy, +set_device_dbus_object (NMIwdManager *self, GDBusInterface *interface, GDBusObject *object) { NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); + GDBusProxy *proxy; + GVariant *value; const char *ifname; - int ifindex; + gint ifindex; NMDevice *device; - ifname = get_property_string_or_null (proxy, "Name"); - if (!ifname) { + if (!priv->running) + return; + + g_return_if_fail (G_IS_DBUS_PROXY (interface)); + + proxy = G_DBUS_PROXY (interface); + + if (strcmp (g_dbus_proxy_get_interface_name (proxy), + NM_IWD_DEVICE_INTERFACE)) + return; + + value = g_dbus_proxy_get_cached_property (proxy, "Name"); + if (!value) { _LOGE ("Name not cached for Device at %s", g_dbus_proxy_get_object_path (proxy)); return; } + ifname = g_variant_get_string (value, NULL); ifindex = if_nametoindex (ifname); + g_variant_unref (value); if (!ifindex) { _LOGE ("if_nametoindex failed for Name %s for Device at %s: %i", @@ -363,183 +299,13 @@ set_device_dbus_object (NMIwdManager *self, GDBusProxy *proxy, nm_device_iwd_set_dbus_object (NM_DEVICE_IWD (device), object); } -/* Create an in-memory NMConnection for a WPA2-Enterprise network that - * has been preprovisioned with an IWD config file so that NM autoconnect - * mechanism and the clients know this networks needs no additional EAP - * configuration from the user. Only do this if no existing connection - * SSID and security type match that network yet. - */ -static NMSettingsConnection * -mirror_8021x_connection (NMIwdManager *self, - const char *name) -{ - NMSettings *settings = NM_SETTINGS_GET; - NMSettingsConnection *const*iter; - gs_unref_object NMConnection *connection = NULL; - NMSettingsConnection *settings_connection; - char uuid[37]; - NMSetting *setting; - GError *error = NULL; - gs_unref_bytes GBytes *new_ssid = NULL; - - for (iter = nm_settings_get_connections (settings, NULL); *iter; iter++) { - NMSettingsConnection *sett_conn = *iter; - NMConnection *conn = nm_settings_connection_get_connection (sett_conn); - NMIwdNetworkSecurity security; - gs_free char *ssid_name = NULL; - NMSettingWireless *s_wifi; - - security = nm_wifi_connection_get_iwd_security (conn, NULL); - if (security != NM_IWD_NETWORK_SECURITY_8021X) - continue; - - s_wifi = nm_connection_get_setting_wireless (conn); - if (!s_wifi) - continue; - - ssid_name = _nm_utils_ssid_to_utf8 (nm_setting_wireless_get_ssid (s_wifi)); - - /* We already have an NMSettingsConnection matching this - * KnownNetwork, whether it's saved or an in-memory connection - * potentially created by ourselves. Nothing to do here. - */ - if (nm_streq (ssid_name, name)) - return NULL; - } - - connection = nm_simple_connection_new (); - - setting = NM_SETTING (g_object_new (NM_TYPE_SETTING_CONNECTION, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRELESS_SETTING_NAME, - NM_SETTING_CONNECTION_ID, name, - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_buf (uuid), - NM_SETTING_CONNECTION_READ_ONLY, TRUE, - NULL)); - nm_connection_add_setting (connection, setting); - - new_ssid = g_bytes_new (name, strlen (name)); - setting = NM_SETTING (g_object_new (NM_TYPE_SETTING_WIRELESS, - NM_SETTING_WIRELESS_SSID, new_ssid, - NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA, - NULL)); - nm_connection_add_setting (connection, setting); - - setting = NM_SETTING (g_object_new (NM_TYPE_SETTING_WIRELESS_SECURITY, - NM_SETTING_WIRELESS_SECURITY_AUTH_ALG, "open", - NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", - NULL)); - nm_connection_add_setting (connection, setting); - - setting = NM_SETTING (g_object_new (NM_TYPE_SETTING_802_1X, NULL)); - nm_setting_802_1x_add_eap_method (NM_SETTING_802_1X (setting), "external"); - nm_connection_add_setting (connection, setting); - - if (!nm_connection_normalize (connection, NULL, NULL, NULL)) - return NULL; - - settings_connection = nm_settings_add_connection (settings, connection, - FALSE, &error); - if (!settings_connection) { - _LOGW ("failed to add a mirror NMConnection for IWD's Known Network '%s': %s", - name, error->message); - g_error_free (error); - return NULL; - } - - nm_settings_connection_set_flags (settings_connection, - NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED | - NM_SETTINGS_CONNECTION_INT_FLAGS_UNSAVED, - TRUE); - return settings_connection; -} - -static void -mirror_8021x_connection_take_and_delete (NMSettingsConnection *sett_conn) -{ - NMSettingsConnectionIntFlags flags; - - if (!sett_conn) - return; - - flags = nm_settings_connection_get_flags (sett_conn); - - /* If connection has not been saved since we created it - * in interface_added it too can be removed now. */ - if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED)) - nm_settings_connection_delete (sett_conn, NULL); - - g_object_unref (sett_conn); -} - static void interface_added (GDBusObjectManager *object_manager, GDBusObject *object, GDBusInterface *interface, gpointer user_data) { NMIwdManager *self = user_data; - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - GDBusProxy *proxy; - const char *iface_name; - - if (!priv->running) - return; - - g_return_if_fail (G_IS_DBUS_PROXY (interface)); - proxy = G_DBUS_PROXY (interface); - iface_name = g_dbus_proxy_get_interface_name (proxy); - - if (nm_streq (iface_name, NM_IWD_DEVICE_INTERFACE)) { - set_device_dbus_object (self, proxy, object); - return; - } - - if (nm_streq (iface_name, NM_IWD_KNOWN_NETWORK_INTERFACE)) { - KnownNetworkId *id; - KnownNetworkData *data; - NMIwdNetworkSecurity security; - const char *type_str, *name; - NMSettingsConnection *sett_conn = NULL; - - type_str = get_property_string_or_null (proxy, "Type"); - name = get_property_string_or_null (proxy, "Name"); - if (!type_str || !name) - return; - - if (nm_streq (type_str, "open")) - security = NM_IWD_NETWORK_SECURITY_NONE; - else if (nm_streq (type_str, "psk")) - security = NM_IWD_NETWORK_SECURITY_PSK; - else if (nm_streq (type_str, "8021x")) - security = NM_IWD_NETWORK_SECURITY_8021X; - else - return; - - id = known_network_id_new (name, security); - - data = g_hash_table_lookup (priv->known_networks, id); - if (data) - g_free (id); - else { - data = g_slice_new0 (KnownNetworkData); - data->known_network = g_object_ref (proxy); - g_hash_table_insert (priv->known_networks, id, data); - } - - if (security == NM_IWD_NETWORK_SECURITY_8021X) { - sett_conn = mirror_8021x_connection (self, name); - - if ( sett_conn - && sett_conn != data->mirror_connection) { - NMSettingsConnection *sett_conn_old = data->mirror_connection; - - data->mirror_connection = nm_g_object_ref (sett_conn); - mirror_8021x_connection_take_and_delete (sett_conn_old); - } - } else - mirror_8021x_connection_take_and_delete (g_steal_pointer (&data->mirror_connection)); - - return; - } + set_device_dbus_object (self, interface, object); } static void @@ -547,41 +313,15 @@ interface_removed (GDBusObjectManager *object_manager, GDBusObject *object, GDBusInterface *interface, gpointer user_data) { NMIwdManager *self = user_data; - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - GDBusProxy *proxy; - const char *iface_name; - g_return_if_fail (G_IS_DBUS_PROXY (interface)); - - proxy = G_DBUS_PROXY (interface); - iface_name = g_dbus_proxy_get_interface_name (proxy); - - if (nm_streq (iface_name, NM_IWD_DEVICE_INTERFACE)) { - set_device_dbus_object (self, proxy, NULL); - return; - } - - if (nm_streq (iface_name, NM_IWD_KNOWN_NETWORK_INTERFACE)) { - KnownNetworkId id; - const char *type_str; - - type_str = get_property_string_or_null (proxy, "Type"); - id.name = get_property_string_or_null (proxy, "Name"); - if (!type_str || !id.name) - return; - - if (nm_streq (type_str, "open")) - id.security = NM_IWD_NETWORK_SECURITY_NONE; - else if (nm_streq (type_str, "psk")) - id.security = NM_IWD_NETWORK_SECURITY_PSK; - else if (nm_streq (type_str, "8021x")) - id.security = NM_IWD_NETWORK_SECURITY_8021X; - else - return; + /* + * TODO: we may need to save the GDBusInterface or GDBusObject + * pointer in the hash table because we may be no longer able to + * access the Name property or map the name to ifindex with + * if_nametoindex at this point. + */ - g_hash_table_remove (priv->known_networks, &id); - return; - } + set_device_dbus_object (self, interface, NULL); } static gboolean @@ -601,42 +341,106 @@ object_added (NMIwdManager *self, GDBusObject *object) GList *interfaces, *iter; interfaces = g_dbus_object_get_interfaces (object); - for (iter = interfaces; iter; iter = iter->next) { GDBusInterface *interface = G_DBUS_INTERFACE (iter->data); - interface_added (NULL, object, interface, self); + set_device_dbus_object (self, interface, object); } g_list_free_full (interfaces, g_object_unref); } static void -release_object_manager (NMIwdManager *self) +known_network_free (KnownNetworkData *network) { - NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); + g_free (network->name); + g_free (network); +} - if (!priv->object_manager) +static void +list_known_networks_cb (GObject *source, GAsyncResult *res, gpointer user_data) +{ + NMIwdManager *self = user_data; + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); + gs_free_error GError *error = NULL; + gs_unref_variant GVariant *variant = NULL; + GVariantIter *networks, *props; + + variant = _nm_dbus_proxy_call_finish (G_DBUS_PROXY (source), res, + G_VARIANT_TYPE ("(aa{sv})"), + &error); + if (!variant) { + _LOGE ("ListKnownNetworks() failed: %s", error->message); return; + } - g_signal_handlers_disconnect_by_data (priv->object_manager, self); + g_slist_free_full (priv->known_networks, (GDestroyNotify) known_network_free); + priv->known_networks = NULL; - if (priv->agent_id) { - GDBusConnection *agent_connection; - GDBusObjectManagerClient *omc = G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager); + g_variant_get (variant, "(aa{sv})", &networks); - agent_connection = g_dbus_object_manager_client_get_connection (omc); + while (g_variant_iter_next (networks, "a{sv}", &props)) { + const gchar *key; + const gchar *name = NULL; + const gchar *type = NULL; + GVariant *val; + KnownNetworkData *network_data; - /* We're is called when we're shutting down (i.e. our DBus connection - * is being closed, and IWD will detect this) or IWD was stopped so - * in either case calling UnregisterAgent will not do anything. - */ - g_dbus_connection_unregister_object (agent_connection, priv->agent_id); - priv->agent_id = 0; - nm_clear_g_free (&priv->agent_path); + while (g_variant_iter_next (props, "{&sv}", &key, &val)) { + if (!strcmp (key, "Name")) + name = g_variant_get_string (val, NULL); + + if (!strcmp (key, "Type")) + type = g_variant_get_string (val, NULL); + + g_variant_unref (val); + } + + if (!name || !type) + goto next; + + network_data = g_new (KnownNetworkData, 1); + network_data->name = g_strdup (name); + if (!strcmp (type, "open")) + network_data->security = NM_IWD_NETWORK_SECURITY_NONE; + else if (!strcmp (type, "psk")) + network_data->security = NM_IWD_NETWORK_SECURITY_PSK; + else if (!strcmp (type, "8021x")) + network_data->security = NM_IWD_NETWORK_SECURITY_8021X; + + priv->known_networks = g_slist_append (priv->known_networks, + network_data); + +next: + g_variant_iter_free (props); } - g_clear_object (&priv->object_manager); + g_variant_iter_free (networks); + + /* For completness we may want to call nm_device_emit_recheck_auto_activate + * and nm_device_recheck_available_connections for all affected devices + * now but the ListKnownNetworks call should have been really fast, + * faster than any scan on any newly created devices could have happened. + */ +} + +static void +update_known_networks (NMIwdManager *self) +{ + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); + GDBusInterface *known_networks_if; + + known_networks_if = g_dbus_object_manager_get_interface (priv->object_manager, + "/", + NM_IWD_KNOWN_NETWORKS_INTERFACE); + + g_dbus_proxy_call (G_DBUS_PROXY (known_networks_if), + "ListKnownNetworks", + g_variant_new ("()"), + G_DBUS_CALL_FLAGS_NONE, -1, + priv->cancellable, list_known_networks_cb, self); + + g_object_unref (known_networks_if); } static void prepare_object_manager (NMIwdManager *self); @@ -651,7 +455,8 @@ name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data) nm_assert (object_manager == priv->object_manager); if (_om_has_name_owner (object_manager)) { - release_object_manager (self); + g_signal_handlers_disconnect_by_data (object_manager, self); + g_clear_object (&priv->object_manager); prepare_object_manager (self); } else { const CList *tmp_lst; @@ -687,14 +492,28 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data) objects = g_dbus_object_manager_get_objects (priv->object_manager); for (iter = objects; iter; iter = iter->next) { GDBusObject *object = G_DBUS_OBJECT (iter->data); - gs_unref_object GDBusInterface *interface = NULL; + GDBusInterface *interface; + GDBusProxy *proxy; + GVariant *value; const char *obj_ifname; interface = g_dbus_object_get_interface (object, NM_IWD_DEVICE_INTERFACE); - obj_ifname = get_property_string_or_null ((GDBusProxy *) interface, "Name"); + if (!interface) + continue; + + proxy = G_DBUS_PROXY (interface); + value = g_dbus_proxy_get_cached_property (proxy, "Name"); + if (!value) { + g_object_unref (interface); + continue; + } - if (!obj_ifname || strcmp (nm_device_get_iface (device), obj_ifname)) + obj_ifname = g_variant_get_string (value, NULL); + g_variant_unref (value); + g_object_unref (interface); + + if (strcmp (nm_device_get_iface (device), obj_ifname)) continue; nm_device_iwd_set_dbus_object (NM_DEVICE_IWD (device), object); @@ -716,7 +535,7 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) object_manager = g_dbus_object_manager_client_new_for_bus_finish (result, &error); if (object_manager == NULL) { _LOGE ("failed to acquire IWD Object Manager: Wi-Fi will not be available (%s)", - error->message); + NM_G_ERROR_MSG (error)); g_clear_error (&error); return; } @@ -730,13 +549,11 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) connection = g_dbus_object_manager_client_get_connection (G_DBUS_OBJECT_MANAGER_CLIENT (object_manager)); - priv->agent_id = iwd_agent_export (connection, - self, - &priv->agent_path, - &error); + priv->agent_id = iwd_agent_export (connection, self, + &priv->agent_path, &error); if (!priv->agent_id) { - _LOGE ("failed to export the IWD Agent: PSK/8021x WiFi networks may not work: %s", - error->message); + _LOGE ("failed to export the IWD Agent: PSK/8021x WiFi networks will not work: %s", + NM_G_ERROR_MSG (error)); g_clear_error (&error); } @@ -750,8 +567,6 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) g_signal_connect (priv->object_manager, "interface-removed", G_CALLBACK (interface_removed), self); - g_hash_table_remove_all (priv->known_networks); - objects = g_dbus_object_manager_get_objects (object_manager); for (iter = objects; iter; iter = iter->next) object_added (self, G_DBUS_OBJECT (iter->data)); @@ -760,6 +575,8 @@ got_object_manager (GObject *object, GAsyncResult *result, gpointer user_data) if (priv->agent_id) register_agent (self); + + update_known_networks (self); } } @@ -777,13 +594,36 @@ prepare_object_manager (NMIwdManager *self) } gboolean -nm_iwd_manager_is_known_network (NMIwdManager *self, const char *name, +nm_iwd_manager_is_known_network (NMIwdManager *self, const gchar *name, NMIwdNetworkSecurity security) { NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - KnownNetworkId kn_id = { name, security }; + const GSList *iter; + + for (iter = priv->known_networks; iter; iter = g_slist_next (iter)) { + const KnownNetworkData *network = iter->data; + + if (!strcmp (network->name, name) && network->security == security) + return true; + } - return g_hash_table_contains (priv->known_networks, &kn_id); + return false; +} + +void +nm_iwd_manager_network_connected (NMIwdManager *self, const gchar *name, + NMIwdNetworkSecurity security) +{ + NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); + KnownNetworkData *network_data; + + if (nm_iwd_manager_is_known_network (self, name, security)) + return; + + network_data = g_new (KnownNetworkData, 1); + network_data->name = g_strdup (name); + network_data->security = security; + priv->known_networks = g_slist_append (priv->known_networks, network_data); } /*****************************************************************************/ @@ -802,11 +642,6 @@ nm_iwd_manager_init (NMIwdManager *self) priv->cancellable = g_cancellable_new (); - priv->known_networks = g_hash_table_new_full ((GHashFunc) known_network_id_hash, - (GEqualFunc) known_network_id_equal, - g_free, - (GDestroyNotify) known_network_data_free); - prepare_object_manager (self); } @@ -816,11 +651,30 @@ dispose (GObject *object) NMIwdManager *self = (NMIwdManager *) object; NMIwdManagerPrivate *priv = NM_IWD_MANAGER_GET_PRIVATE (self); - release_object_manager (self); + if (priv->object_manager) { + if (priv->agent_id) { + GDBusConnection *connection; + GDBusObjectManagerClient *omc = G_DBUS_OBJECT_MANAGER_CLIENT (priv->object_manager); + + /* No need to unregister the agent as IWD will detect + * our DBus connection being closed. + */ + + connection = g_dbus_object_manager_client_get_connection (omc); + + g_dbus_connection_unregister_object (connection, priv->agent_id); + priv->agent_id = 0; + } + + g_clear_object (&priv->object_manager); + } + + nm_clear_g_free (&priv->agent_path); nm_clear_g_cancellable (&priv->cancellable); - nm_clear_pointer (&priv->known_networks, g_hash_table_destroy); + g_slist_free_full (priv->known_networks, (GDestroyNotify) known_network_free); + priv->known_networks = NULL; if (priv->manager) { g_signal_handlers_disconnect_by_data (priv->manager, self); diff --git a/src/devices/wifi/nm-iwd-manager.h b/src/devices/wifi/nm-iwd-manager.h index cf0e7262..8e6b66ff 100644 --- a/src/devices/wifi/nm-iwd-manager.h +++ b/src/devices/wifi/nm-iwd-manager.h @@ -22,7 +22,6 @@ #define __NETWORKMANAGER_IWD_MANAGER_H__ #include "devices/nm-device.h" -#include "nm-wifi-utils.h" #define NM_IWD_BUS_TYPE G_BUS_TYPE_SYSTEM #define NM_IWD_SERVICE "net.connman.iwd" @@ -34,11 +33,15 @@ #define NM_IWD_AGENT_INTERFACE "net.connman.iwd.Agent" #define NM_IWD_WSC_INTERFACE \ "net.connman.iwd.WiFiSimpleConfiguration" -#define NM_IWD_KNOWN_NETWORK_INTERFACE "net.connman.iwd.KnownNetwork" +#define NM_IWD_KNOWN_NETWORKS_INTERFACE "net.connman.iwd.KnownNetworks" #define NM_IWD_SIGNAL_AGENT_INTERFACE "net.connman.iwd.SignalLevelAgent" -#define NM_IWD_AP_INTERFACE "net.connman.iwd.AccessPoint" -#define NM_IWD_ADHOC_INTERFACE "net.connman.iwd.AdHoc" -#define NM_IWD_STATION_INTERFACE "net.connman.iwd.Station" + +typedef enum { + NM_IWD_NETWORK_SECURITY_NONE, + NM_IWD_NETWORK_SECURITY_WEP, + NM_IWD_NETWORK_SECURITY_PSK, + NM_IWD_NETWORK_SECURITY_8021X, +} NMIwdNetworkSecurity; #define NM_TYPE_IWD_MANAGER (nm_iwd_manager_get_type ()) #define NM_IWD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_IWD_MANAGER, NMIwdManager)) @@ -54,7 +57,9 @@ GType nm_iwd_manager_get_type (void); NMIwdManager *nm_iwd_manager_get (void); -gboolean nm_iwd_manager_is_known_network (NMIwdManager *self, const char *name, +gboolean nm_iwd_manager_is_known_network (NMIwdManager *self, const gchar *name, NMIwdNetworkSecurity security); +void nm_iwd_manager_network_connected (NMIwdManager *self, const gchar *name, + NMIwdNetworkSecurity security); #endif /* __NETWORKMANAGER_IWD_MANAGER_H__ */ diff --git a/src/devices/wifi/nm-wifi-ap.c b/src/devices/wifi/nm-wifi-ap.c index e5573383..dd6d1deb 100644 --- a/src/devices/wifi/nm-wifi-ap.c +++ b/src/devices/wifi/nm-wifi-ap.c @@ -58,7 +58,7 @@ struct _NMWifiAPPrivate { char *supplicant_path; /* D-Bus object path of this AP from wpa_supplicant */ /* Scanned or cached values */ - GBytes * ssid; + GByteArray * ssid; char * address; NM80211Mode mode; guint8 strength; @@ -95,7 +95,7 @@ nm_wifi_ap_get_supplicant_path (NMWifiAP *ap) return NM_WIFI_AP_GET_PRIVATE (ap)->supplicant_path; } -GBytes * +const GByteArray * nm_wifi_ap_get_ssid (const NMWifiAP *ap) { g_return_val_if_fail (NM_IS_WIFI_AP (ap), NULL); @@ -103,57 +103,43 @@ nm_wifi_ap_get_ssid (const NMWifiAP *ap) return NM_WIFI_AP_GET_PRIVATE (ap)->ssid; } -gboolean -nm_wifi_ap_set_ssid_arr (NMWifiAP *ap, - const guint8 *ssid, - gsize ssid_len) +static GVariant * +nm_wifi_ap_get_ssid_as_variant (const NMWifiAP *self) { - NMWifiAPPrivate *priv; - - g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE); - - if (ssid_len > 32) - g_return_val_if_reached (FALSE); - - priv = NM_WIFI_AP_GET_PRIVATE (ap); - - if (nm_utils_gbytes_equal_mem (priv->ssid, ssid, ssid_len)) - return FALSE; - - nm_clear_pointer (&priv->ssid, g_bytes_unref); - if (ssid_len > 0) - priv->ssid = g_bytes_new (ssid, ssid_len); + const NMWifiAPPrivate *priv = NM_WIFI_AP_GET_PRIVATE (self); - _notify (ap, PROP_SSID); - return TRUE; + if (priv->ssid) { + return g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + priv->ssid->data, priv->ssid->len, 1); + } else + return g_variant_new_array (G_VARIANT_TYPE_BYTE, NULL, 0); } gboolean -nm_wifi_ap_set_ssid (NMWifiAP *ap, GBytes *ssid) +nm_wifi_ap_set_ssid (NMWifiAP *ap, const guint8 *ssid, gsize len) { NMWifiAPPrivate *priv; - gsize l; g_return_val_if_fail (NM_IS_WIFI_AP (ap), FALSE); - - if (ssid) { - l = g_bytes_get_size (ssid); - if (l == 0 || l > 32) - g_return_val_if_reached (FALSE); - } + g_return_val_if_fail (ssid == NULL || len > 0, FALSE); priv = NM_WIFI_AP_GET_PRIVATE (ap); - if (ssid == priv->ssid) - return FALSE; - if ( ssid - && priv->ssid - && g_bytes_equal (ssid, priv->ssid)) - return FALSE; + /* same SSID */ + if ((ssid && priv->ssid) && (len == priv->ssid->len)) { + if (!memcmp (ssid, priv->ssid->data, len)) + return FALSE; + } - nm_clear_pointer (&priv->ssid, g_bytes_unref); - if (ssid) - priv->ssid = g_bytes_ref (ssid); + if (priv->ssid) { + g_byte_array_free (priv->ssid, TRUE); + priv->ssid = NULL; + } + + if (ssid) { + priv->ssid = g_byte_array_new (); + g_byte_array_append (priv->ssid, ssid, len); + } _notify (ap, PROP_SSID); return TRUE; @@ -828,16 +814,10 @@ nm_wifi_ap_update_from_properties (NMWifiAP *ap, len = MIN (32, len); /* Stupid ieee80211 layer uses <hidden> */ - if ( bytes - && len - && !( NM_IN_SET (len, 8, 9) - && memcmp (bytes, "<hidden>", len) == 0) - && !nm_utils_is_empty_ssid (bytes, len)) { - /* good */ - } else - len = 0; - - changed |= nm_wifi_ap_set_ssid_arr (ap, bytes, len); + if ( bytes && len + && !(((len == 8) || (len == 9)) && !memcmp (bytes, "<hidden>", 8)) + && !nm_utils_is_empty_ssid (bytes, len)) + changed |= nm_wifi_ap_set_ssid (ap, bytes, len); g_variant_unref (v); } @@ -981,7 +961,7 @@ nm_wifi_ap_to_string (const NMWifiAP *self, const char *supplicant_id = "-"; const char *export_path; guint32 chan; - gs_free char *ssid_to_free = NULL; + char b1[200]; g_return_val_if_fail (NM_IS_WIFI_AP (self), NULL); @@ -997,9 +977,10 @@ nm_wifi_ap_to_string (const NMWifiAP *self, export_path = "/"; g_snprintf (str_buf, buf_len, - "%17s %-35s [ %c %3u %3u%% %c W:%04X R:%04X ] %3us sup:%s [nm:%s]", + "%17s %-32s [ %c %3u %3u%% %c W:%04X R:%04X ] %3us sup:%s [nm:%s]", priv->address ?: "(none)", - (ssid_to_free = _nm_utils_ssid_to_string (priv->ssid)), + nm_sprintf_buf (b1, "%s%s%s", + NM_PRINT_FMT_QUOTED (priv->ssid, "\"", nm_utils_escape_ssid (priv->ssid->data, priv->ssid->len), "\"", "(none)")), (priv->mode == NM_802_11_MODE_ADHOC ? '*' : (priv->hotspot @@ -1051,12 +1032,15 @@ nm_wifi_ap_check_compatible (NMWifiAP *self, return FALSE; ssid = nm_setting_wireless_get_ssid (s_wireless); - if (ssid != priv->ssid) { - if (!ssid || !priv->ssid) - return FALSE; - if (!g_bytes_equal (ssid, priv->ssid)) - return FALSE; - } + if ( (ssid && !priv->ssid) + || (priv->ssid && !ssid)) + return FALSE; + + if ( ssid && priv->ssid && + !nm_utils_same_ssid (g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid), + priv->ssid->data, priv->ssid->len, + TRUE)) + return FALSE; bssid = nm_setting_wireless_get_bssid (s_wireless); if (bssid && (!priv->address || !nm_utils_hwaddr_matches (bssid, -1, priv->address, -1))) @@ -1142,8 +1126,7 @@ get_property (GObject *object, guint prop_id, 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_wifi_ap_get_ssid_as_variant (self)); break; case PROP_FREQUENCY: g_value_set_uint (value, priv->freq); @@ -1163,7 +1146,7 @@ get_property (GObject *object, guint prop_id, case PROP_LAST_SEEN: g_value_set_int (value, priv->last_seen > 0 - ? (int) nm_utils_monotonic_timestamp_as_boottime (priv->last_seen, NM_UTILS_NS_PER_SECOND) + ? (gint) nm_utils_monotonic_timestamp_as_boottime (priv->last_seen, NM_UTILS_NS_PER_SECOND) : -1); break; default: @@ -1219,6 +1202,7 @@ nm_wifi_ap_new_fake_from_connection (NMConnection *connection) NMWifiAPPrivate *priv; NMSettingWireless *s_wireless; NMSettingWirelessSecurity *s_wireless_sec; + GBytes *ssid; const char *mode, *band, *key_mgmt; guint32 channel; NM80211ApSecurityFlags flags; @@ -1229,12 +1213,14 @@ nm_wifi_ap_new_fake_from_connection (NMConnection *connection) s_wireless = nm_connection_get_setting_wireless (connection); g_return_val_if_fail (s_wireless != NULL, NULL); + ssid = nm_setting_wireless_get_ssid (s_wireless); + g_return_val_if_fail (ssid != NULL, NULL); + g_return_val_if_fail (g_bytes_get_size (ssid) > 0, NULL); + ap = (NMWifiAP *) g_object_new (NM_TYPE_WIFI_AP, NULL); priv = NM_WIFI_AP_GET_PRIVATE (ap); priv->fake = TRUE; - - nm_wifi_ap_set_ssid (ap, - nm_setting_wireless_get_ssid (s_wireless)); + nm_wifi_ap_set_ssid (ap, g_bytes_get_data (ssid, NULL), g_bytes_get_size (ssid)); // FIXME: bssid too? @@ -1348,7 +1334,7 @@ finalize (GObject *object) g_free (priv->supplicant_path); if (priv->ssid) - g_bytes_unref (priv->ssid); + g_byte_array_free (priv->ssid, TRUE); g_free (priv->address); G_OBJECT_CLASS (nm_wifi_ap_parent_class)->finalize (object); @@ -1534,8 +1520,8 @@ nm_wifi_ap_lookup_for_device (NMDevice *device, const char *exported_path) g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - ap = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (device)), - exported_path); + ap = (NMWifiAP *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (device)), + exported_path); if ( !ap || !NM_IS_WIFI_AP (ap) || ap->wifi_device != device) diff --git a/src/devices/wifi/nm-wifi-ap.h b/src/devices/wifi/nm-wifi-ap.h index 7462e9d1..4fdeee93 100644 --- a/src/devices/wifi/nm-wifi-ap.h +++ b/src/devices/wifi/nm-wifi-ap.h @@ -72,12 +72,10 @@ gboolean nm_wifi_ap_complete_connection (NMWifiAP *self, GError **error); const char * nm_wifi_ap_get_supplicant_path (NMWifiAP *ap); -GBytes *nm_wifi_ap_get_ssid (const NMWifiAP *ap); -gboolean nm_wifi_ap_set_ssid_arr (NMWifiAP *ap, - const guint8 *ssid, - gsize ssid_len); +const GByteArray *nm_wifi_ap_get_ssid (const NMWifiAP *ap); gboolean nm_wifi_ap_set_ssid (NMWifiAP *ap, - GBytes *ssid); + const guint8 *ssid, + gsize len); const char * nm_wifi_ap_get_address (const NMWifiAP *ap); gboolean nm_wifi_ap_set_address (NMWifiAP *ap, const char *addr); diff --git a/src/devices/wifi/nm-wifi-utils.c b/src/devices/wifi/nm-wifi-utils.c index 0f7836be..044bd392 100644 --- a/src/devices/wifi/nm-wifi-utils.c +++ b/src/devices/wifi/nm-wifi-utils.c @@ -525,7 +525,7 @@ verify_adhoc (NMSettingWirelessSecurity *s_wsec, } gboolean -nm_wifi_utils_complete_connection (GBytes *ap_ssid, +nm_wifi_utils_complete_connection (const GByteArray *ap_ssid, const char *bssid, NM80211Mode ap_mode, guint32 ap_flags, @@ -538,7 +538,7 @@ nm_wifi_utils_complete_connection (GBytes *ap_ssid, NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; NMSetting8021x *s_8021x; - GBytes *ssid; + GBytes *ssid, *ap_ssid_bytes; const char *mode, *key_mgmt, *auth_alg, *leap_username; gboolean adhoc = FALSE; @@ -548,17 +548,20 @@ nm_wifi_utils_complete_connection (GBytes *ap_ssid, s_8021x = nm_connection_get_setting_802_1x (connection); /* Fill in missing SSID */ + ap_ssid_bytes = ap_ssid ? g_bytes_new (ap_ssid->data, ap_ssid->len) : NULL; ssid = nm_setting_wireless_get_ssid (s_wifi); if (!ssid) - g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid, NULL); - else if (!ap_ssid || !g_bytes_equal (ssid, ap_ssid)) { + g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_SSID, ap_ssid_bytes, NULL); + else if (!ap_ssid_bytes || !g_bytes_equal (ssid, ap_ssid_bytes)) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("connection does not match access point")); g_prefix_error (error, "%s.%s: ", NM_SETTING_WIRELESS_SETTING_NAME, NM_SETTING_WIRELESS_SSID); + g_bytes_unref (ap_ssid_bytes); return FALSE; } + g_bytes_unref (ap_ssid_bytes); if (lock_bssid && !nm_setting_wireless_get_bssid (s_wifi)) g_object_set (G_OBJECT (s_wifi), NM_SETTING_WIRELESS_BSSID, bssid, NULL); @@ -761,7 +764,7 @@ nm_wifi_utils_complete_connection (GBytes *ap_ssid, } guint32 -nm_wifi_utils_level_to_quality (int val) +nm_wifi_utils_level_to_quality (gint val) { if (val < 0) { /* Assume dBm already; rough conversion: best = -40, worst = -100 */ @@ -780,10 +783,8 @@ nm_wifi_utils_level_to_quality (int val) } gboolean -nm_wifi_utils_is_manf_default_ssid (GBytes *ssid) +nm_wifi_utils_is_manf_default_ssid (const GByteArray *ssid) { - const guint8 *ssid_p; - gsize ssid_l; int i; /* * List of manufacturer default SSIDs that are often unchanged by users. @@ -805,46 +806,11 @@ nm_wifi_utils_is_manf_default_ssid (GBytes *ssid) "TURBONETT", }; - ssid_p = g_bytes_get_data (ssid, &ssid_l); - for (i = 0; i < G_N_ELEMENTS (manf_defaults); i++) { - if (ssid_l == strlen (manf_defaults[i])) { - if (memcmp (manf_defaults[i], ssid_p, ssid_l) == 0) + if (ssid->len == strlen (manf_defaults[i])) { + if (memcmp (manf_defaults[i], ssid->data, ssid->len) == 0) return TRUE; } } return FALSE; } - -NMIwdNetworkSecurity -nm_wifi_connection_get_iwd_security (NMConnection *connection, - gboolean *mapped) -{ - NMSettingWirelessSecurity *s_wireless_sec; - const char *key_mgmt = NULL; - - if (!nm_connection_get_setting_wireless (connection)) - goto error; - - NM_SET_OUT (mapped, TRUE); - - s_wireless_sec = nm_connection_get_setting_wireless_security (connection); - if (!s_wireless_sec) - return NM_IWD_NETWORK_SECURITY_NONE; - - key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec); - nm_assert (key_mgmt); - - if (NM_IN_STRSET (key_mgmt, "none", "ieee8021x")) - return NM_IWD_NETWORK_SECURITY_WEP; - - if (nm_streq (key_mgmt, "wpa-psk")) - return NM_IWD_NETWORK_SECURITY_PSK; - - if (nm_streq (key_mgmt, "wpa-eap")) - return NM_IWD_NETWORK_SECURITY_8021X; - -error: - NM_SET_OUT (mapped, FALSE); - return NM_IWD_NETWORK_SECURITY_NONE; -} diff --git a/src/devices/wifi/nm-wifi-utils.h b/src/devices/wifi/nm-wifi-utils.h index 03238c24..def64dd6 100644 --- a/src/devices/wifi/nm-wifi-utils.h +++ b/src/devices/wifi/nm-wifi-utils.h @@ -27,14 +27,7 @@ #include "nm-setting-wireless-security.h" #include "nm-setting-8021x.h" -typedef enum { - NM_IWD_NETWORK_SECURITY_NONE, - NM_IWD_NETWORK_SECURITY_WEP, - NM_IWD_NETWORK_SECURITY_PSK, - NM_IWD_NETWORK_SECURITY_8021X, -} NMIwdNetworkSecurity; - -gboolean nm_wifi_utils_complete_connection (GBytes *ssid, +gboolean nm_wifi_utils_complete_connection (const GByteArray *ssid, const char *bssid, NM80211Mode mode, guint32 flags, @@ -44,11 +37,8 @@ gboolean nm_wifi_utils_complete_connection (GBytes *ssid, gboolean lock_bssid, GError **error); -guint32 nm_wifi_utils_level_to_quality (int val); - -gboolean nm_wifi_utils_is_manf_default_ssid (GBytes *ssid); +guint32 nm_wifi_utils_level_to_quality (gint val); -NMIwdNetworkSecurity nm_wifi_connection_get_iwd_security (NMConnection *connection, - gboolean *mapped); +gboolean nm_wifi_utils_is_manf_default_ssid (const GByteArray *ssid); #endif /* __NM_WIFI_UTILS_H__ */ diff --git a/src/devices/wifi/tests/test-general.c b/src/devices/wifi/tests/test-general.c index f752bbfc..89eebb22 100644 --- a/src/devices/wifi/tests/test-general.c +++ b/src/devices/wifi/tests/test-general.c @@ -74,7 +74,8 @@ complete_connection (const char *ssid, NMConnection *src, GError **error) { - gs_unref_bytes GBytes *ssid_b = NULL; + GByteArray *tmp; + gboolean success; NMSettingWireless *s_wifi; /* Add a wifi setting if one doesn't exist */ @@ -84,17 +85,20 @@ complete_connection (const char *ssid, nm_connection_add_setting (src, NM_SETTING (s_wifi)); } - ssid_b = g_bytes_new (ssid, strlen (ssid)); - - return nm_wifi_utils_complete_connection (ssid_b, - bssid, - mode, - flags, - wpa_flags, - rsn_flags, - src, - lock_bssid, - error); + tmp = g_byte_array_sized_new (strlen (ssid)); + g_byte_array_append (tmp, (const guint8 *) ssid, strlen (ssid)); + + success = nm_wifi_utils_complete_connection (tmp, + bssid, + mode, + flags, + wpa_flags, + rsn_flags, + src, + lock_bssid, + error); + g_byte_array_free (tmp, TRUE); + return success; } typedef struct { @@ -123,7 +127,7 @@ set_items (NMSetting *setting, const KeyData *items) g_assert (item->str == NULL); g_object_set (G_OBJECT (setting), item->key, item->uint, NULL); } else if (pspec->value_type == G_TYPE_INT) { - int foo = (int) item->uint; + gint foo = (gint) item->uint; g_assert (item->str == NULL); g_object_set (G_OBJECT (setting), item->key, foo, NULL); @@ -1458,7 +1462,7 @@ main (int argc, char **argv) test_ap_wpa_eap_connection_5); #define ADD_FUNC(func) do { \ - char *name_idx = g_strdup_printf ("/wifi/wpa_psk/" G_STRINGIFY (func) "/%zd", i); \ + gchar *name_idx = g_strdup_printf ("/wifi/wpa_psk/" G_STRINGIFY (func) "/%zd", i); \ g_test_add_data_func (name_idx, (gconstpointer) i, func); \ g_free (name_idx); \ } while (0) @@ -1483,7 +1487,7 @@ main (int argc, char **argv) #undef ADD_FUNC #define ADD_FUNC(func) do { \ - char *name_idx = g_strdup_printf ("/wifi/rsn_psk/" G_STRINGIFY (func) "/%zd", i); \ + gchar *name_idx = g_strdup_printf ("/wifi/rsn_psk/" G_STRINGIFY (func) "/%zd", i); \ g_test_add_data_func (name_idx, (gconstpointer) i, func); \ g_free (name_idx); \ } while (0) diff --git a/src/devices/wwan/meson.build b/src/devices/wwan/meson.build index 2c0ea5a1..abf58594 100644 --- a/src/devices/wwan/meson.build +++ b/src/devices/wwan/meson.build @@ -35,10 +35,10 @@ libnm_wwan_dep = declare_dependency( core_plugins += libnm_wwan -test( +run_target( 'check-wwan', - check_exports, - args: [libnm_wwan.full_path(), linker_script], + command: [check_exports, libnm_wwan.full_path(), linker_script], + depends: libnm_wwan ) sources = files( diff --git a/src/devices/wwan/nm-device-modem.c b/src/devices/wwan/nm-device-modem.c index 4119d598..352b1c3e 100644 --- a/src/devices/wwan/nm-device-modem.c +++ b/src/devices/wwan/nm-device-modem.c @@ -397,67 +397,34 @@ get_type_description (NMDevice *device) } static gboolean -check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) +check_connection_compatible (NMDevice *device, NMConnection *connection) { - GError *local = NULL; - - if (!NM_DEVICE_CLASS (nm_device_modem_parent_class)->check_connection_compatible (device, connection, error)) + if (!NM_DEVICE_CLASS (nm_device_modem_parent_class)->check_connection_compatible (device, connection)) return FALSE; - if (!nm_modem_check_connection_compatible (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device)->modem, - connection, - error ? &local : NULL)) { - if (error) { - g_set_error (error, - NM_UTILS_ERROR, - g_error_matches (local, NM_UTILS_ERROR, NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE) - ? NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE - : NM_UTILS_ERROR_UNKNOWN, - "modem is incompatible with connection: %s", - local->message); - g_error_free (local); - } - return FALSE; - } - return TRUE; + return nm_modem_check_connection_compatible (NM_DEVICE_MODEM_GET_PRIVATE ((NMDeviceModem *) device)->modem, connection); } static gboolean check_connection_available (NMDevice *device, NMConnection *connection, NMDeviceCheckConAvailableFlags flags, - const char *specific_object, - GError **error) + const char *specific_object) { NMDeviceModem *self = NM_DEVICE_MODEM (device); NMDeviceModemPrivate *priv = NM_DEVICE_MODEM_GET_PRIVATE (self); NMModemState state; - if (!priv->rf_enabled) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "RFKILL for modem enabled"); + if (!priv->rf_enabled || !priv->modem) return FALSE; - } - - if (!priv->modem) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "modem not available"); - return FALSE; - } state = nm_modem_get_state (priv->modem); - if (state <= NM_MODEM_STATE_INITIALIZING) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "modem not initalized"); + if (state <= NM_MODEM_STATE_INITIALIZING) return FALSE; - } if (state == NM_MODEM_STATE_LOCKED) { - if (!nm_connection_get_setting_gsm (connection)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "modem is locked without pin available"); + if (!nm_connection_get_setting_gsm (connection)) return FALSE; - } } return TRUE; diff --git a/src/devices/wwan/nm-modem-broadband.c b/src/devices/wwan/nm-modem-broadband.c index 253574d5..e5678b96 100644 --- a/src/devices/wwan/nm-modem-broadband.c +++ b/src/devices/wwan/nm-modem-broadband.c @@ -256,7 +256,7 @@ create_cdma_connect_properties (NMConnection *connection) { NMSettingCdma *setting; MMSimpleConnectProperties *properties; - const char *str; + const gchar *str; setting = nm_connection_get_setting_cdma (connection); properties = mm_simple_connect_properties_new (); @@ -274,7 +274,7 @@ create_gsm_connect_properties (NMConnection *connection) NMSettingGsm *setting; NMSettingPpp *s_ppp; MMSimpleConnectProperties *properties; - const char *str; + const gchar *str; setting = nm_connection_get_setting_gsm (connection); properties = mm_simple_connect_properties_new (); @@ -617,40 +617,44 @@ act_stage1_prepare (NMModem *_self, /*****************************************************************************/ static gboolean -check_connection_compatible_with_modem (NMModem *_self, NMConnection *connection, GError **error) +check_connection_compatible (NMModem *_self, NMConnection *connection) { NMModemBroadband *self = NM_MODEM_BROADBAND (_self); MMModemCapability modem_caps; + NMSettingConnection *s_con; modem_caps = mm_modem_get_current_capabilities (self->_priv.modem_iface); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); if (MODEM_CAPS_3GPP (modem_caps)) { - if (!_nm_connection_check_main_setting (connection, NM_SETTING_GSM_SETTING_NAME, error)) + NMSettingGsm *s_gsm; + + if (!g_str_equal (nm_setting_connection_get_connection_type (s_con), + NM_SETTING_GSM_SETTING_NAME)) + return FALSE; + + s_gsm = nm_connection_get_setting_gsm (connection); + if (!s_gsm) return FALSE; return TRUE; } if (MODEM_CAPS_3GPP2 (modem_caps)) { - if (!_nm_connection_check_main_setting (connection, NM_SETTING_CDMA_SETTING_NAME, error)) + NMSettingCdma *s_cdma; + + if (!g_str_equal (nm_setting_connection_get_connection_type (s_con), + NM_SETTING_CDMA_SETTING_NAME)) return FALSE; - return TRUE; - } + s_cdma = nm_connection_get_setting_cdma (connection); + if (!s_cdma) + return FALSE; - if ( !_nm_connection_check_main_setting (connection, NM_SETTING_GSM_SETTING_NAME, NULL) - && !_nm_connection_check_main_setting (connection, NM_SETTING_CDMA_SETTING_NAME, NULL)) { - nm_utils_error_set (error, - NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, - "connection type %s is not supported by modem", - nm_connection_get_connection_type (connection)); - return FALSE; + return TRUE; } - nm_utils_error_set (error, - NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "modem lacks capabilities for %s profile", - nm_connection_get_connection_type (connection)); return FALSE; } @@ -864,12 +868,12 @@ static_stage3_ip4_done (NMModemBroadband *self) GError *error = NULL; gs_unref_object NMIP4Config *config = NULL; const char *data_port; - const char *address_string; - const char *gw_string; + const gchar *address_string; + const gchar *gw_string; guint32 address_network; guint32 gw = 0; NMPlatformIP4Address address; - const char **dns; + const gchar **dns; guint i; guint32 ip4_route_table, ip4_route_metric; NMPlatformIP4Route *r; @@ -975,10 +979,10 @@ stage3_ip6_done (NMModemBroadband *self) GError *error = NULL; NMIP6Config *config = NULL; const char *data_port; - const char *address_string; + const gchar *address_string; NMPlatformIP6Address address; NMModemIPMethod ip_method; - const char **dns; + const gchar **dns; guint i; g_assert (self->_priv.ipv6_config); @@ -1472,7 +1476,7 @@ nm_modem_broadband_class_init (NMModemBroadbandClass *klass) modem_class->deactivate_cleanup = deactivate_cleanup; modem_class->set_mm_enabled = set_mm_enabled; modem_class->get_user_pass = get_user_pass; - modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem; + modem_class->check_connection_compatible = check_connection_compatible; modem_class->complete_connection = complete_connection; modem_class->act_stage1_prepare = act_stage1_prepare; modem_class->owns_port = owns_port; diff --git a/src/devices/wwan/nm-modem-manager.c b/src/devices/wwan/nm-modem-manager.c index dfc102f3..59cd2bca 100644 --- a/src/devices/wwan/nm-modem-manager.c +++ b/src/devices/wwan/nm-modem-manager.c @@ -170,7 +170,7 @@ modm_handle_object_added (MMManager *modem_manager, NMModemManager *self) { NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - const char *path; + const gchar *path; MMModem *modem_iface; NMModem *modem; GError *error = NULL; @@ -211,7 +211,7 @@ modm_handle_object_removed (MMManager *manager, { NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); NMModem *modem; - const char *path; + const gchar *path; path = mm_object_get_path (modem_object); modem = (NMModem *) g_hash_table_lookup (priv->modems, path); @@ -246,7 +246,7 @@ modm_handle_name_owner_changed (MMManager *modem_manager, NMModemManager *self) { NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - char *name_owner; + gchar *name_owner; /* Quit poking, if any */ nm_clear_g_source (&priv->modm.relaunch_id); @@ -341,7 +341,7 @@ static void modm_manager_check_name_owner (NMModemManager *self) { NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - gs_free char *name_owner = NULL; + gs_free gchar *name_owner = NULL; name_owner = g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->modm.manager)); if (name_owner) { @@ -606,14 +606,14 @@ ofono_create_modem (NMModemManager *self, const char *path) static void ofono_signal_cb (GDBusProxy *proxy, - char *sender_name, - char *signal_name, + gchar *sender_name, + gchar *signal_name, GVariant *parameters, gpointer user_data) { NMModemManager *self = NM_MODEM_MANAGER (user_data); NMModemManagerPrivate *priv = NM_MODEM_MANAGER_GET_PRIVATE (self); - char *object_path; + gchar *object_path; NMModem *modem; if (g_strcmp0 (signal_name, "ModemAdded") == 0) { diff --git a/src/devices/wwan/nm-modem-ofono.c b/src/devices/wwan/nm-modem-ofono.c index ea668590..8b81ac41 100644 --- a/src/devices/wwan/nm-modem-ofono.c +++ b/src/devices/wwan/nm-modem-ofono.c @@ -279,42 +279,47 @@ deactivate_cleanup (NMModem *modem, NMDevice *device) } static gboolean -check_connection_compatible_with_modem (NMModem *modem, - NMConnection *connection, - GError **error) +check_connection_compatible (NMModem *modem, + NMConnection *connection) { NMModemOfono *self = NM_MODEM_OFONO (modem); NMModemOfonoPrivate *priv = NM_MODEM_OFONO_GET_PRIVATE (self); + NMSettingConnection *s_con; + NMSettingGsm *s_gsm; + const char *uuid; const char *id; - if (!_nm_connection_check_main_setting (connection, NM_SETTING_GSM_SETTING_NAME, NULL)) { - nm_utils_error_set (error, - NM_UTILS_ERROR_CONNECTION_AVAILABLE_INCOMPATIBLE, - "connection type %s is not supported by ofono modem", - nm_connection_get_connection_type (connection)); + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); + + uuid = nm_connection_get_uuid (connection); + id = nm_connection_get_id (connection); + + s_gsm = nm_connection_get_setting_gsm (connection); + if (!s_gsm) return FALSE; - } if (!priv->imsi) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "modem has no IMSI"); + _LOGW ("skipping %s/%s: no IMSI", uuid, id); return FALSE; } - id = nm_connection_get_id (connection); + if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_GSM_SETTING_NAME)) { + _LOGD ("skipping %s/%s: not GSM", uuid, id); + return FALSE; + } - if (!strstr (id, "/context")) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "the connection ID has no context"); + if (!g_strrstr (id, "/context")) { + _LOGD ("skipping %s/%s: unexpected ID", uuid, id); return FALSE; } - if (!strstr (id, priv->imsi)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "the connection ID does not contain the IMSI"); + if (!g_strrstr (id, priv->imsi)) { + _LOGD ("skipping %s/%s: ID doesn't contain IMSI", uuid, id); return FALSE; } + _LOGD ("%s/%s compatible with IMSI %s", uuid, id, priv->imsi); return TRUE; } @@ -825,8 +830,8 @@ context_property_changed (GDBusProxy *proxy, gboolean ret = FALSE; gs_unref_variant GVariant *v_dict = NULL; const char *interface; - const char *s; - const char **array, **iter; + const gchar *s; + const gchar **array, **iter; guint32 address_network, gateway_network; guint32 ip4_route_table, ip4_route_metric; int ifindex; @@ -1321,7 +1326,7 @@ nm_modem_ofono_class_init (NMModemOfonoClass *klass) modem_class->disconnect = disconnect; modem_class->disconnect_finish = disconnect_finish; modem_class->deactivate_cleanup = deactivate_cleanup; - modem_class->check_connection_compatible_with_modem = check_connection_compatible_with_modem; + modem_class->check_connection_compatible = check_connection_compatible; modem_class->act_stage1_prepare = act_stage1_prepare; modem_class->static_stage3_ip4_config_start = static_stage3_ip4_config_start; diff --git a/src/devices/wwan/nm-modem.c b/src/devices/wwan/nm-modem.c index 59b081e9..617d5c4a 100644 --- a/src/devices/wwan/nm-modem.c +++ b/src/devices/wwan/nm-modem.c @@ -291,7 +291,7 @@ nm_modem_get_supported_ip_types (NMModem *self) return NM_MODEM_GET_PRIVATE (self)->ip_types; } -const char * +const gchar * nm_modem_ip_type_to_string (NMModemIPType ip_type) { switch (ip_type) { @@ -1027,29 +1027,35 @@ nm_modem_act_stage2_config (NMModem *self, /*****************************************************************************/ gboolean -nm_modem_check_connection_compatible (NMModem *self, NMConnection *connection, GError **error) +nm_modem_check_connection_compatible (NMModem *self, NMConnection *connection) { NMModemPrivate *priv = NM_MODEM_GET_PRIVATE (self); + NMSettingConnection *s_con; + + s_con = nm_connection_get_setting_connection (connection); + g_assert (s_con); - if (nm_streq0 (nm_connection_get_connection_type (connection), - NM_SETTING_GSM_SETTING_NAME)) { + if (g_str_equal (nm_setting_connection_get_connection_type (s_con), + NM_SETTING_GSM_SETTING_NAME)) { NMSettingGsm *s_gsm; const char *str; - s_gsm = _nm_connection_check_main_setting (connection, NM_SETTING_GSM_SETTING_NAME, error); + s_gsm = nm_connection_get_setting_gsm (connection); if (!s_gsm) return FALSE; str = nm_setting_gsm_get_device_id (s_gsm); if (str) { if (!priv->device_id) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "GSM profile has device-id, device does not"); + _LOGD ("%s/%s has device-id, device does not", + nm_connection_get_uuid (connection), + nm_connection_get_id (connection)); return FALSE; } - if (!nm_streq (str, priv->device_id)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has differing device-id than GSM profile"); + if (strcmp (str, priv->device_id)) { + _LOGD ("%s/%s device-id mismatch", + nm_connection_get_uuid (connection), + nm_connection_get_id (connection)); return FALSE; } } @@ -1059,26 +1065,30 @@ nm_modem_check_connection_compatible (NMModem *self, NMConnection *connection, G * are only compared if present on the device. */ - if ( priv->sim_id - && (str = nm_setting_gsm_get_sim_id (s_gsm))) { - if (!nm_streq (str, priv->sim_id)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has differing sim-id than GSM profile"); + str = nm_setting_gsm_get_sim_id (s_gsm); + if (str && priv->sim_id) { + if (strcmp (str, priv->sim_id)) { + _LOGD ("%s/%s sim-id mismatch", + nm_connection_get_uuid (connection), + nm_connection_get_id (connection)); return FALSE; } } - if ( priv->sim_operator_id - && (str = nm_setting_gsm_get_sim_operator_id (s_gsm))) { - if (!nm_streq (str, priv->sim_operator_id)) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY, - "device has differing sim-operator-id than GSM profile"); + str = nm_setting_gsm_get_sim_operator_id (s_gsm); + if (str && priv->sim_operator_id) { + if (strcmp (str, priv->sim_operator_id)) { + _LOGD ("%s/%s sim-operator-id mismatch", + nm_connection_get_uuid (connection), + nm_connection_get_id (connection)); return FALSE; } } } - return NM_MODEM_GET_CLASS (self)->check_connection_compatible_with_modem (self, connection, error); + if (NM_MODEM_GET_CLASS (self)->check_connection_compatible) + return NM_MODEM_GET_CLASS (self)->check_connection_compatible (self, connection); + return FALSE; } /*****************************************************************************/ diff --git a/src/devices/wwan/nm-modem.h b/src/devices/wwan/nm-modem.h index c73745ce..cad9ece4 100644 --- a/src/devices/wwan/nm-modem.h +++ b/src/devices/wwan/nm-modem.h @@ -121,9 +121,8 @@ typedef struct { const char **user, const char **pass); - gboolean (*check_connection_compatible_with_modem) (NMModem *modem, - NMConnection *connection, - GError **error); + gboolean (*check_connection_compatible) (NMModem *modem, + NMConnection *connection); gboolean (*complete_connection) (NMModem *modem, NMConnection *connection, @@ -186,9 +185,7 @@ void nm_modem_get_capabilities (NMModem *self, NMDeviceModemCapabilities *modem_caps, NMDeviceModemCapabilities *current_caps); -gboolean nm_modem_check_connection_compatible (NMModem *self, - NMConnection *connection, - GError **error); +gboolean nm_modem_check_connection_compatible (NMModem *self, NMConnection *connection); gboolean nm_modem_complete_connection (NMModem *self, NMConnection *connection, @@ -276,7 +273,7 @@ void nm_modem_emit_ip6_config_result (NMModem *self, NMIP6Config *config, GError *error); -const char *nm_modem_ip_type_to_string (NMModemIPType ip_type); +const gchar *nm_modem_ip_type_to_string (NMModemIPType ip_type); guint32 nm_modem_get_configured_mtu (NMDevice *self, NMDeviceMtuSource *out_source); diff --git a/src/dhcp/meson.build b/src/dhcp/meson.build index 76707bca..289a16ca 100644 --- a/src/dhcp/meson.build +++ b/src/dhcp/meson.build @@ -3,6 +3,7 @@ name = 'nm-dhcp-helper' cflags = [ '-DG_LOG_DOMAIN="@0@"'.format(name), '-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_GLIB', + '-DNMRUNDIR="@0@"'.format(nm_pkgrundir), ] executable( diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c index 16db8306..e53c8d87 100644 --- a/src/dhcp/nm-dhcp-client.c +++ b/src/dhcp/nm-dhcp-client.c @@ -445,7 +445,7 @@ transaction_timeout (gpointer user_data) } static void -daemon_watch_cb (GPid pid, int status, gpointer user_data) +daemon_watch_cb (GPid pid, gint status, gpointer user_data) { NMDhcpClient *self = NM_DHCP_CLIENT (user_data); NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE (self); @@ -510,8 +510,7 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self, GBytes *client_id, const char *dhcp_anycast_addr, const char *hostname, - const char *last_ip4_address, - GError **error) + const char *last_ip4_address) { NMDhcpClientPrivate *priv; @@ -532,10 +531,7 @@ nm_dhcp_client_start_ip4 (NMDhcpClient *self, g_clear_pointer (&priv->hostname, g_free); priv->hostname = g_strdup (hostname); - return NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, - dhcp_anycast_addr, - last_ip4_address, - error); + return NM_DHCP_CLIENT_GET_CLASS (self)->ip4_start (self, dhcp_anycast_addr, last_ip4_address); } static GBytes * @@ -552,8 +548,7 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, const struct in6_addr *ll_addr, const char *hostname, NMSettingIP6ConfigPrivacy privacy, - guint needed_prefixes, - GError **error) + guint needed_prefixes) { NMDhcpClientPrivate *priv; gs_free char *str = NULL; @@ -589,8 +584,7 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, ll_addr, privacy, priv->duid, - needed_prefixes, - error); + needed_prefixes); } void @@ -740,7 +734,7 @@ maybe_add_option (NMDhcpClient *self, gboolean nm_dhcp_client_handle_event (gpointer unused, const char *iface, - int pid, + gint pid, GVariant *options, const char *reason, NMDhcpClient *self) diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h index 86d60e38..4c196045 100644 --- a/src/dhcp/nm-dhcp-client.h +++ b/src/dhcp/nm-dhcp-client.h @@ -76,18 +76,18 @@ typedef enum { typedef struct { GObjectClass parent; + /* Methods */ + gboolean (*ip4_start) (NMDhcpClient *self, const char *anycast_addr, - const char *last_ip4_address, - GError **error); + const char *last_ip4_address); gboolean (*ip6_start) (NMDhcpClient *self, const char *anycast_addr, const struct in6_addr *ll_addr, NMSettingIP6ConfigPrivacy privacy, GBytes *duid, - guint needed_prefixes, - GError **error); + guint needed_prefixes); void (*stop) (NMDhcpClient *self, gboolean release, @@ -151,8 +151,7 @@ gboolean nm_dhcp_client_start_ip4 (NMDhcpClient *self, GBytes *client_id, const char *dhcp_anycast_addr, const char *hostname, - const char *last_ip4_address, - GError **error); + const char *last_ip4_address); gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self, GBytes *client_id, @@ -161,8 +160,7 @@ gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self, const struct in6_addr *ll_addr, const char *hostname, NMSettingIP6ConfigPrivacy privacy, - guint needed_prefixes, - GError **error); + guint needed_prefixes); void nm_dhcp_client_stop (NMDhcpClient *self, gboolean release); @@ -182,7 +180,7 @@ void nm_dhcp_client_set_state (NMDhcpClient *self, gboolean nm_dhcp_client_handle_event (gpointer unused, const char *iface, - int pid, + gint pid, GVariant *options, const char *reason, NMDhcpClient *self); diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c index d8f8dd98..3290dd65 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/dhcp/nm-dhcp-dhclient-utils.c @@ -316,7 +316,6 @@ nm_dhcp_dhclient_create_config (const char *interface, if (orig_contents) { char **lines, **line; - int nest = 0; gboolean in_alsoreq = FALSE; gboolean in_req = FALSE; char intf[IFNAMSIZ]; @@ -331,23 +330,17 @@ nm_dhcp_dhclient_create_config (const char *interface, if (!strlen (g_strstrip (p))) continue; - if (in_req) { - /* pass */ - } else if (strchr (p, '{')) { - nest++; - if ( !intf[0] - && g_str_has_prefix (p, "interface")) - if (read_interface (p, intf, sizeof (intf))) - continue; - } else if (strchr (p, '}')) { - if (nest) - nest--; - intf[0] = '\0'; - continue; + if ( !intf[0] + && g_str_has_prefix (p, "interface") + && !in_req) { + if (read_interface (p, intf, sizeof (intf))) + continue; } - if (nest && !intf[0]) + if (intf[0] && strchr (p, '}')) { + intf[0] = '\0'; continue; + } if (intf[0] && !nm_streq (intf, interface)) continue; @@ -530,10 +523,6 @@ nm_dhcp_dhclient_unescape_duid (const char *duid) guint i, len; guint8 octal; - /* FIXME: it's wrong to have an "unescape-duid" function. dhclient - * defines a file format with escaping. So we need a general unescape - * function that can handle dhclient syntax. */ - len = strlen (duid); unescaped = g_byte_array_sized_new (len); for (i = 0; i < len; i++) { @@ -547,9 +536,6 @@ nm_dhcp_dhclient_unescape_duid (const char *duid) g_byte_array_append (unescaped, &octal, 1); i += 2; } else { - /* FIXME: don't warn on untrusted data. Either signal an error, or accept - * it silently. */ - /* One of ", ', $, `, \, |, or & */ g_warn_if_fail (p[i] == '"' || p[i] == '\'' || p[i] == '$' || p[i] == '`' || p[i] == '\\' || p[i] == '|' || diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c index 46d2339b..bf93c831 100644 --- a/src/dhcp/nm-dhcp-dhclient.c +++ b/src/dhcp/nm-dhcp-dhclient.c @@ -174,14 +174,13 @@ merge_dhclient_config (NMDhcpDhclient *self, GBytes **out_new_client_id, GError **error) { - gs_free char *orig = NULL; - gs_free char *new = NULL; + char *orig = NULL, *new; + gboolean success = FALSE; - g_return_val_if_fail (iface, FALSE); - g_return_val_if_fail (conf_file, FALSE); + g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (conf_file != NULL, FALSE); - if ( orig_path - && g_file_test (orig_path, G_FILE_TEST_EXISTS)) { + if (orig_path && g_file_test (orig_path, G_FILE_TEST_EXISTS)) { GError *read_error = NULL; if (!g_file_get_contents (orig_path, &orig, NULL, &read_error)) { @@ -191,22 +190,14 @@ merge_dhclient_config (NMDhcpDhclient *self, } } - new = nm_dhcp_dhclient_create_config (iface, - addr_family, - client_id, - anycast_addr, - hostname, - timeout, - use_fqdn, - orig_path, - orig, - out_new_client_id); + new = nm_dhcp_dhclient_create_config (iface, addr_family, client_id, anycast_addr, hostname, timeout, + use_fqdn, orig_path, orig, out_new_client_id); g_assert (new); + success = g_file_set_contents (conf_file, new, -1, error); + g_free (new); + g_free (orig); - return g_file_set_contents (conf_file, - new, - -1, - error); + return success; } static char * @@ -291,14 +282,13 @@ create_dhclient_config (NMDhcpDhclient *self, gboolean use_fqdn, GBytes **out_new_client_id) { - gs_free char *orig = NULL; - char *new = NULL; + char *orig = NULL, *new = NULL; GError *error = NULL; + gboolean success = FALSE; g_return_val_if_fail (iface != NULL, NULL); new = g_strdup_printf (NMSTATEDIR "/dhclient%s-%s.conf", _addr_family_to_path_part (addr_family), iface); - _LOGD ("creating composite dhclient config %s", new); orig = find_existing_config (self, addr_family, iface, uuid); @@ -307,12 +297,15 @@ create_dhclient_config (NMDhcpDhclient *self, else _LOGD ("no existing dhclient configuration to merge"); - if (!merge_dhclient_config (self, addr_family, iface, new, client_id, dhcp_anycast_addr, - hostname, timeout, use_fqdn, orig, out_new_client_id, &error)) { + error = NULL; + success = merge_dhclient_config (self, addr_family, iface, new, client_id, dhcp_anycast_addr, + hostname, timeout, use_fqdn, orig, out_new_client_id, &error); + if (!success) { _LOGW ("error creating dhclient configuration: %s", error->message); - g_clear_error (&error); + g_error_free (error); } + g_free (orig); return new; } @@ -322,14 +315,13 @@ dhclient_start (NMDhcpClient *client, GBytes *duid, gboolean release, pid_t *out_pid, - int prefixes, - GError **error) + int prefixes) { NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client); NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self); gs_unref_ptrarray GPtrArray *argv = NULL; pid_t pid; - gs_free_error GError *local = NULL; + GError *error = NULL; const char *iface; const char *uuid; const char *system_bus_address; @@ -347,7 +339,7 @@ dhclient_start (NMDhcpClient *client, dhclient_path = nm_dhcp_dhclient_get_path (); if (!dhclient_path) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "dhclient binary not found"); + _LOGW ("dhclient could not be found"); return FALSE; } @@ -379,7 +371,11 @@ dhclient_start (NMDhcpClient *client, gs_unref_object GFile *dst = g_file_new_for_path (preferred_leasefile_path); /* Try to copy the existing leasefile to the preferred location */ - if (!g_file_copy (src, dst, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &local)) { + if (g_file_copy (src, dst, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, &error)) { + /* Success; use the preferred leasefile path */ + g_free (priv->lease_file); + priv->lease_file = g_file_get_path (dst); + } else { gs_free char *s_path = NULL; gs_free char *d_path = NULL; @@ -387,12 +383,8 @@ dhclient_start (NMDhcpClient *client, _LOGW ("failed to copy leasefile %s to %s: %s", (s_path = g_file_get_path (src)), (d_path = g_file_get_path (dst)), - local->message); - g_clear_error (&local); - } else { - /* Success; use the preferred leasefile path */ - g_free (priv->lease_file); - priv->lease_file = g_file_get_path (dst); + error->message); + g_clear_error (&error); } } @@ -401,12 +393,9 @@ dhclient_start (NMDhcpClient *client, gs_free char *escaped = NULL; escaped = nm_dhcp_dhclient_escape_duid (duid); - if (!nm_dhcp_dhclient_save_duid (priv->lease_file, escaped, &local)) { - nm_utils_error_set (error, - NM_UTILS_ERROR_UNKNOWN, - "failed to save DUID to '%s': %s", - priv->lease_file, - local->message); + if (!nm_dhcp_dhclient_save_duid (priv->lease_file, escaped, &error)) { + _LOGW ("failed to save DUID to %s: %s", priv->lease_file, error->message); + g_clear_error (&error); return FALSE; } } @@ -462,15 +451,13 @@ dhclient_start (NMDhcpClient *client, g_ptr_array_add (argv, NULL); _LOGD ("running: %s", - (cmd_str = g_strjoinv (" ", (char **) argv->pdata))); + (cmd_str = g_strjoinv (" ", (gchar **) argv->pdata))); if (!g_spawn_async (NULL, (char **) argv->pdata, NULL, G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, - nm_utils_setpgid, NULL, &pid, &local)) { - nm_utils_error_set (error, - NM_UTILS_ERROR_UNKNOWN, - "dhclient failed to start: %s", - local->message); + nm_utils_setpgid, NULL, &pid, &error)) { + _LOGW ("dhclient failed to start: '%s'", error->message); + g_error_free (error); return FALSE; } @@ -486,46 +473,36 @@ dhclient_start (NMDhcpClient *client, } static gboolean -ip4_start (NMDhcpClient *client, - const char *dhcp_anycast_addr, - const char *last_ip4_address, - GError **error) +ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address) { NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client); NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self); GBytes *client_id; gs_unref_bytes GBytes *new_client_id = NULL; + const char *iface, *uuid, *hostname; + guint32 timeout; + gboolean success = FALSE; + gboolean use_fqdn; + iface = nm_dhcp_client_get_iface (client); + uuid = nm_dhcp_client_get_uuid (client); client_id = nm_dhcp_client_get_client_id (client); + hostname = nm_dhcp_client_get_hostname (client); + timeout = nm_dhcp_client_get_timeout (client); + use_fqdn = nm_dhcp_client_get_use_fqdn (client); - priv->conf_file = create_dhclient_config (self, - AF_INET, - nm_dhcp_client_get_iface (client), - nm_dhcp_client_get_uuid (client), - client_id, - dhcp_anycast_addr, - nm_dhcp_client_get_hostname (client), - nm_dhcp_client_get_timeout (client), - nm_dhcp_client_get_use_fqdn (client), - &new_client_id); - if (!priv->conf_file) { - nm_utils_error_set_literal (error, - NM_UTILS_ERROR_UNKNOWN, - "error creating dhclient configuration file"); - return FALSE; - } + priv->conf_file = create_dhclient_config (self, AF_INET, iface, uuid, client_id, dhcp_anycast_addr, + hostname, timeout, use_fqdn, &new_client_id); + if (priv->conf_file) { + if (new_client_id) { + nm_assert (!client_id); + nm_dhcp_client_set_client_id (client, new_client_id); + } + success = dhclient_start (client, NULL, NULL, FALSE, NULL, 0); + } else + _LOGW ("error creating dhclient configuration file"); - if (new_client_id) { - nm_assert (!client_id); - nm_dhcp_client_set_client_id (client, new_client_id); - } - return dhclient_start (client, - NULL, - NULL, - FALSE, - NULL, - 0, - error); + return success; } static gboolean @@ -534,26 +511,22 @@ ip6_start (NMDhcpClient *client, const struct in6_addr *ll_addr, NMSettingIP6ConfigPrivacy privacy, GBytes *duid, - guint needed_prefixes, - GError **error) + guint needed_prefixes) { NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client); NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self); + const char *iface, *uuid, *hostname; + guint32 timeout; + + iface = nm_dhcp_client_get_iface (client); + uuid = nm_dhcp_client_get_uuid (client); + hostname = nm_dhcp_client_get_hostname (client); + timeout = nm_dhcp_client_get_timeout (client); - priv->conf_file = create_dhclient_config (self, - AF_INET6, - nm_dhcp_client_get_iface (client), - nm_dhcp_client_get_uuid (client), - NULL, - dhcp_anycast_addr, - nm_dhcp_client_get_hostname (client), - nm_dhcp_client_get_timeout (client), - TRUE, - NULL); + priv->conf_file = create_dhclient_config (self, AF_INET6, iface, uuid, NULL, dhcp_anycast_addr, + hostname, timeout, TRUE, NULL); if (!priv->conf_file) { - nm_utils_error_set_literal (error, - NM_UTILS_ERROR_UNKNOWN, - "error creating dhclient configuration file"); + _LOGW ("error creating dhclient configuration file"); return FALSE; } @@ -561,11 +534,7 @@ ip6_start (NMDhcpClient *client, nm_dhcp_client_get_info_only (NM_DHCP_CLIENT (self)) ? "-S" : "-N", - duid, - FALSE, - NULL, - needed_prefixes, - error); + duid, FALSE, NULL, needed_prefixes); } static void @@ -591,13 +560,7 @@ stop (NMDhcpClient *client, gboolean release, GBytes *duid) if (release) { pid_t rpid = -1; - if (dhclient_start (client, - NULL, - duid, - TRUE, - &rpid, - 0, - NULL)) { + if (dhclient_start (client, NULL, duid, TRUE, &rpid, 0)) { /* Wait a few seconds for the release to happen */ nm_dhcp_client_stop_pid (rpid, nm_dhcp_client_get_iface (client)); } diff --git a/src/dhcp/nm-dhcp-dhcpcanon.c b/src/dhcp/nm-dhcp-dhcpcanon.c index de403020..12aa57aa 100644 --- a/src/dhcp/nm-dhcp-dhcpcanon.c +++ b/src/dhcp/nm-dhcp-dhcpcanon.c @@ -82,36 +82,28 @@ dhcpcanon_start (NMDhcpClient *client, GBytes *duid, gboolean release, pid_t *out_pid, - guint needed_prefixes, - GError **error) + int prefixes) { NMDhcpDhcpcanon *self = NM_DHCP_DHCPCANON (client); NMDhcpDhcpcanonPrivate *priv = NM_DHCP_DHCPCANON_GET_PRIVATE (self); - gs_unref_ptrarray GPtrArray *argv = NULL; + GPtrArray *argv = NULL; pid_t pid; - gs_free_error GError *local = NULL; - const char *iface; - const char *system_bus_address; - const char *dhcpcanon_path; - gs_free char *binary_name = NULL; - gs_free char *pid_file = NULL; - gs_free char *system_bus_address_env = NULL; + GError *error = NULL; + const char *iface, *system_bus_address, *dhcpcanon_path = NULL; + char *binary_name, *cmd_str, *pid_file = NULL, *system_bus_address_env = NULL; int addr_family; - g_return_val_if_fail (!priv->pid_file, FALSE); + g_return_val_if_fail (priv->pid_file == NULL, FALSE); iface = nm_dhcp_client_get_iface (client); - addr_family = nm_dhcp_client_get_addr_family (client); - dhcpcanon_path = nm_dhcp_dhcpcanon_get_path (); + _LOGD ("dhcpcanon_path: %s", dhcpcanon_path); if (!dhcpcanon_path) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "dhcpcanon binary not found"); + _LOGW ("dhcpcanon could not be found"); return FALSE; } - _LOGD ("dhcpcanon_path: %s", dhcpcanon_path); - pid_file = g_strdup_printf (RUNSTATEDIR "/dhcpcanon%c-%s.pid", nm_utils_addr_family_to_char (addr_family), iface); @@ -120,6 +112,7 @@ dhcpcanon_start (NMDhcpClient *client, /* Kill any existing dhcpcanon from the pidfile */ binary_name = g_path_get_basename (dhcpcanon_path); nm_dhcp_client_stop_existing (pid_file, binary_name); + g_free (binary_name); argv = g_ptr_array_new (); g_ptr_array_add (argv, (gpointer) dhcpcanon_path); @@ -127,8 +120,10 @@ dhcpcanon_start (NMDhcpClient *client, g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */ g_ptr_array_add (argv, (gpointer) nm_dhcp_helper_path); - g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ - g_ptr_array_add (argv, (gpointer) pid_file); + if (pid_file) { + g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ + g_ptr_array_add (argv, (gpointer) pid_file); + } if (priv->conf_file) { g_ptr_array_add (argv, (gpointer) "-cf"); /* Set interface config file */ @@ -149,43 +144,33 @@ dhcpcanon_start (NMDhcpClient *client, g_ptr_array_add (argv, (gpointer) iface); g_ptr_array_add (argv, NULL); - if (!g_spawn_async (NULL, - (char **) argv->pdata, - NULL, - G_SPAWN_DO_NOT_REAP_CHILD - | G_SPAWN_STDOUT_TO_DEV_NULL - | G_SPAWN_STDERR_TO_DEV_NULL, - nm_utils_setpgid, - NULL, - &pid, - &local)) { - nm_utils_error_set (error, - NM_UTILS_ERROR_UNKNOWN, - "dhcpcanon failed to start: %s", - local->message); - return FALSE; + cmd_str = g_strjoinv (" ", (gchar **) argv->pdata); + g_free (cmd_str); + + if (g_spawn_async (NULL, (char **) argv->pdata, NULL, + G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + nm_utils_setpgid, NULL, &pid, &error)) { + g_assert (pid > 0); + _LOGI ("dhcpcanon started with pid %d", pid); + nm_dhcp_client_watch_child (client, pid); + priv->pid_file = pid_file; + } else { + _LOGW ("dhcpcanon failed to start: '%s'", error->message); + g_error_free (error); + g_free (pid_file); } - nm_assert (pid > 0); - _LOGI ("dhcpcanon started with pid %d", pid); - nm_dhcp_client_watch_child (client, pid); - priv->pid_file = g_steal_pointer (&pid_file); - return TRUE; + g_ptr_array_free (argv, TRUE); + g_free (system_bus_address_env); + return pid > 0 ? TRUE : FALSE; } static gboolean -ip4_start (NMDhcpClient *client, - const char *dhcp_anycast_addr, - const char *last_ip4_address, - GError **error) +ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address) { - return dhcpcanon_start (client, - NULL, - NULL, - FALSE, - NULL, - 0, - error); + gboolean success = FALSE; + success = dhcpcanon_start (client, NULL, NULL, FALSE, NULL, 0); + return success; } static gboolean @@ -194,10 +179,11 @@ ip6_start (NMDhcpClient *client, const struct in6_addr *ll_addr, NMSettingIP6ConfigPrivacy privacy, GBytes *duid, - guint needed_prefixes, - GError **error) + guint needed_prefixes) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "dhcpcanon plugin does not support IPv6"); + NMDhcpDhcpcanon *self = NM_DHCP_DHCPCANON (client); + + _LOGW ("the dhcpcd backend does not support IPv6"); return FALSE; } static void diff --git a/src/dhcp/nm-dhcp-dhcpcd.c b/src/dhcp/nm-dhcp-dhcpcd.c index 98ab5342..c4bcb084 100644 --- a/src/dhcp/nm-dhcp-dhcpcd.c +++ b/src/dhcp/nm-dhcp-dhcpcd.c @@ -81,21 +81,15 @@ nm_dhcp_dhcpcd_get_path (void) } static gboolean -ip4_start (NMDhcpClient *client, - const char *dhcp_anycast_addr, - const char *last_ip4_address, - GError **error) +ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address) { NMDhcpDhcpcd *self = NM_DHCP_DHCPCD (client); NMDhcpDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (self); - gs_unref_ptrarray GPtrArray *argv = NULL; + GPtrArray *argv = NULL; pid_t pid = -1; - GError *local = NULL; - gs_free char *cmd_str = NULL; - gs_free char *binary_name = NULL; - const char *iface; - const char *dhcpcd_path; - const char *hostname; + GError *error = NULL; + char *pid_contents = NULL, *binary_name, *cmd_str; + const char *iface, *dhcpcd_path, *hostname; g_return_val_if_fail (priv->pid_file == NULL, FALSE); @@ -108,13 +102,14 @@ ip4_start (NMDhcpClient *client, dhcpcd_path = nm_dhcp_dhcpcd_get_path (); if (!dhcpcd_path) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "dhcpcd binary not found"); + _LOGW ("dhcpcd could not be found"); return FALSE; } /* Kill any existing dhcpcd from the pidfile */ binary_name = g_path_get_basename (dhcpcd_path); nm_dhcp_client_stop_existing (priv->pid_file, binary_name); + g_free (binary_name); argv = g_ptr_array_new (); g_ptr_array_add (argv, (gpointer) dhcpcd_path); @@ -133,11 +128,13 @@ ip4_start (NMDhcpClient *client, g_ptr_array_add (argv, (gpointer) "-c"); /* Set script file */ g_ptr_array_add (argv, (gpointer) nm_dhcp_helper_path); +#ifdef DHCPCD_SUPPORTS_IPV6 /* IPv4-only for now. NetworkManager knows better than dhcpcd when to * run IPv6, and dhcpcd's automatic Router Solicitations cause problems * with devices that don't expect them. */ g_ptr_array_add (argv, (gpointer) "-4"); +#endif hostname = nm_dhcp_client_get_hostname (client); @@ -156,30 +153,24 @@ ip4_start (NMDhcpClient *client, g_ptr_array_add (argv, (gpointer) iface); g_ptr_array_add (argv, NULL); - _LOGD ("running: %s", - (cmd_str = g_strjoinv (" ", (char **) argv->pdata))); - - if (!g_spawn_async (NULL, - (char **) argv->pdata, NULL, - G_SPAWN_DO_NOT_REAP_CHILD - | G_SPAWN_STDOUT_TO_DEV_NULL - | G_SPAWN_STDERR_TO_DEV_NULL, - nm_utils_setpgid, - NULL, - &pid, - &local)) { - nm_utils_error_set (error, - NM_UTILS_ERROR_UNKNOWN, - "dhcpcd failed to start: %s", - local->message); - g_error_free (local); - return FALSE; + cmd_str = g_strjoinv (" ", (gchar **) argv->pdata); + _LOGD ("running: %s", cmd_str); + g_free (cmd_str); + + if (g_spawn_async (NULL, (char **) argv->pdata, NULL, + G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, + nm_utils_setpgid, NULL, &pid, &error)) { + g_assert (pid > 0); + _LOGI ("dhcpcd started with pid %d", pid); + nm_dhcp_client_watch_child (client, pid); + } else { + _LOGW ("dhcpcd failed to start, error: '%s'", error->message); + g_error_free (error); } - nm_assert (pid > 0); - _LOGI ("dhcpcd started with pid %d", pid); - nm_dhcp_client_watch_child (client, pid); - return TRUE; + g_free (pid_contents); + g_ptr_array_free (argv, TRUE); + return pid > 0 ? TRUE : FALSE; } static gboolean @@ -188,10 +179,11 @@ ip6_start (NMDhcpClient *client, const struct in6_addr *ll_addr, NMSettingIP6ConfigPrivacy privacy, GBytes *duid, - guint needed_prefixes, - GError **error) + guint needed_prefixes) { - nm_utils_error_set_literal (error, NM_UTILS_ERROR_UNKNOWN, "dhcpcd plugin does not support IPv6"); + NMDhcpDhcpcd *self = NM_DHCP_DHCPCD (client); + + _LOGW ("the dhcpcd backend does not support IPv6"); return FALSE; } diff --git a/src/dhcp/nm-dhcp-helper.c b/src/dhcp/nm-dhcp-helper.c index 2b48d7a5..8ea55061 100644 --- a/src/dhcp/nm-dhcp-helper.c +++ b/src/dhcp/nm-dhcp-helper.c @@ -31,7 +31,7 @@ /*****************************************************************************/ -#if NM_MORE_LOGGING +#ifdef NM_MORE_LOGGING #define _NMLOG_ENABLED(level) TRUE #else #define _NMLOG_ENABLED(level) ((level) <= LOG_ERR) diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c index 6c71af9d..67254323 100644 --- a/src/dhcp/nm-dhcp-manager.c +++ b/src/dhcp/nm-dhcp-manager.c @@ -172,39 +172,22 @@ client_start (NMDhcpManager *self, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, const char *last_ip4_address, - guint needed_prefixes, - GError **error) + guint needed_prefixes) { NMDhcpManagerPrivate *priv; NMDhcpClient *client; gboolean success = FALSE; - gsize hwaddr_len; + g_return_val_if_fail (self, NULL); g_return_val_if_fail (NM_IS_DHCP_MANAGER (self), NULL); g_return_val_if_fail (ifindex > 0, NULL); g_return_val_if_fail (uuid != NULL, NULL); g_return_val_if_fail (!dhcp_client_id || g_bytes_get_size (dhcp_client_id) >= 2, NULL); - g_return_val_if_fail (!error || !*error, NULL); - - if (!hwaddr) { - nm_utils_error_set (error, - NM_UTILS_ERROR_UNKNOWN, - "missing MAC address"); - return NULL; - } - - hwaddr_len = g_bytes_get_size (hwaddr); - if ( hwaddr_len == 0 - || hwaddr_len > NM_UTILS_HWADDR_LEN_MAX) { - nm_utils_error_set (error, - NM_UTILS_ERROR_UNKNOWN, - "invalid MAC address"); - g_return_val_if_reached (NULL) ; - } priv = NM_DHCP_MANAGER_GET_PRIVATE (self); - nm_assert (priv->client_factory); + if (!priv->client_factory) + return NULL; /* Kill any old client instance */ client = get_client_for_ifindex (self, addr_family, ifindex); @@ -233,24 +216,10 @@ client_start (NMDhcpManager *self, c_list_link_tail (&priv->dhcp_client_lst_head, &client->dhcp_client_lst); g_signal_connect (client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (client_state_changed), self); - if (addr_family == AF_INET) { - success = nm_dhcp_client_start_ip4 (client, - dhcp_client_id, - dhcp_anycast_addr, - hostname, - last_ip4_address, - error); - } else { - success = nm_dhcp_client_start_ip6 (client, - dhcp_client_id, - enforce_duid, - dhcp_anycast_addr, - ipv6_ll_addr, - hostname, - privacy, - needed_prefixes, - error); - } + if (addr_family == AF_INET) + success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, last_ip4_address); + else + success = nm_dhcp_client_start_ip6 (client, dhcp_client_id, enforce_duid, dhcp_anycast_addr, ipv6_ll_addr, hostname, privacy, needed_prefixes); if (!success) { remove_client_unref (self, client); @@ -276,8 +245,7 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self, GBytes *dhcp_client_id, guint32 timeout, const char *dhcp_anycast_addr, - const char *last_ip_address, - GError **error) + const char *last_ip_address) { NMDhcpManagerPrivate *priv; const char *hostname = NULL; @@ -314,7 +282,7 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self, return client_start (self, AF_INET, multi_idx, iface, ifindex, hwaddr, uuid, route_table, route_metric, NULL, dhcp_client_id, 0, timeout, dhcp_anycast_addr, hostname, - use_fqdn, FALSE, 0, last_ip_address, 0, error); + use_fqdn, FALSE, 0, last_ip_address, 0); } /* Caller owns a reference to the NMDhcpClient on return */ @@ -336,8 +304,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, const char *dhcp_anycast_addr, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - guint needed_prefixes, - GError **error) + guint needed_prefixes) { NMDhcpManagerPrivate *priv; const char *hostname = NULL; @@ -352,7 +319,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, return client_start (self, AF_INET6, multi_idx, iface, ifindex, hwaddr, uuid, route_table, route_metric, ll_addr, duid, enforce_duid, timeout, dhcp_anycast_addr, hostname, TRUE, info_only, - privacy, NULL, needed_prefixes, error); + privacy, NULL, needed_prefixes); } void @@ -442,7 +409,7 @@ nm_dhcp_manager_init (NMDhcpManager *self) } } - g_return_if_fail (client_factory); + nm_assert (client_factory); nm_log_info (LOGD_DHCP, "dhcp-init: Using DHCP client '%s'", client_factory->name); diff --git a/src/dhcp/nm-dhcp-manager.h b/src/dhcp/nm-dhcp-manager.h index 1d9e5c21..7eb32c37 100644 --- a/src/dhcp/nm-dhcp-manager.h +++ b/src/dhcp/nm-dhcp-manager.h @@ -59,8 +59,7 @@ NMDhcpClient * nm_dhcp_manager_start_ip4 (NMDhcpManager *manager, GBytes *dhcp_client_id, guint32 timeout, const char *dhcp_anycast_addr, - const char *last_ip_address, - GError **error); + const char *last_ip_address); NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager, struct _NMDedupMultiIndex *multi_idx, @@ -79,8 +78,7 @@ NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager, const char *dhcp_anycast_addr, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - guint needed_prefixes, - GError **error); + guint needed_prefixes); /* For testing only */ extern const char* nm_dhcp_helper_path; diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index b51c6e7b..2d0202bb 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -567,10 +567,7 @@ get_arp_type (GBytes *hwaddr) } static gboolean -ip4_start (NMDhcpClient *client, - const char *dhcp_anycast_addr, - const char *last_ip4_address, - GError **error) +ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last_ip4_address) { NMDhcpSystemd *self = NM_DHCP_SYSTEMD (client); NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); @@ -593,7 +590,7 @@ ip4_start (NMDhcpClient *client, r = sd_dhcp_client_new (&priv->client4, FALSE); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to create dhcp-client: %s"); + _LOGW ("failed to create client (%d)", r); return FALSE; } @@ -601,8 +598,8 @@ ip4_start (NMDhcpClient *client, r = sd_dhcp_client_attach_event (priv->client4, NULL, 0); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to attach event: %s"); - goto errout; + _LOGW ("failed to attach event (%d)", r); + goto error; } hwaddr = nm_dhcp_client_get_hw_addr (client); @@ -616,21 +613,21 @@ ip4_start (NMDhcpClient *client, len, get_arp_type (hwaddr)); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to set MAC address: %s"); - goto errout; + _LOGW ("failed to set MAC address (%d)", r); + goto error; } } r = sd_dhcp_client_set_ifindex (priv->client4, nm_dhcp_client_get_ifindex (client)); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to set ifindex: %s"); - goto errout; + _LOGW ("failed to set ififindex (%d)", r); + goto error; } r = sd_dhcp_client_set_callback (priv->client4, dhcp_event_cb, client); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to set callback: %s"); - goto errout; + _LOGW ("failed to set callback (%d)", r); + goto error; } dhcp_lease_load (&lease, priv->lease_file); @@ -643,8 +640,8 @@ ip4_start (NMDhcpClient *client, if (last_addr.s_addr) { r = sd_dhcp_client_set_request_address (priv->client4, &last_addr); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to set last IPv4 address: %s"); - goto errout; + _LOGW ("failed to set last IPv4 address (%d)", r); + goto error; } } @@ -684,25 +681,25 @@ ip4_start (NMDhcpClient *client, */ r = sd_dhcp_client_set_hostname (priv->client4, hostname); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to set DHCP hostname: %s"); - goto errout; + _LOGW ("failed to set DHCP hostname to '%s' (%d)", hostname, r); + goto error; } } r = sd_dhcp_client_start (priv->client4); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to start DHCP client: %s"); - goto errout; + _LOGW ("failed to start client (%d)", r); + goto error; } nm_dhcp_client_start_timeout (client); success = TRUE; -errout: +error: sd_dhcp_lease_unref (lease); if (!success) - sd_dhcp_client_unref (g_steal_pointer (&priv->client4)); + priv->client4 = sd_dhcp_client_unref (priv->client4); return success; } @@ -867,8 +864,7 @@ ip6_start (NMDhcpClient *client, const struct in6_addr *ll_addr, NMSettingIP6ConfigPrivacy privacy, GBytes *duid, - guint needed_prefixes, - GError **error) + guint needed_prefixes) { NMDhcpSystemd *self = NM_DHCP_SYSTEMD (client); NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); @@ -892,7 +888,7 @@ ip6_start (NMDhcpClient *client, r = sd_dhcp6_client_new (&priv->client6); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to create dhcp-client: %s"); + _LOGW ("failed to create client (%d)", r); return FALSE; } @@ -911,14 +907,14 @@ ip6_start (NMDhcpClient *client, &duid_arr[2], duid_len - 2); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to set DUID: %s"); + _LOGW ("failed to set DUID (%d)", r); return FALSE; } r = sd_dhcp6_client_attach_event (priv->client6, NULL, 0); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to attach event: %s"); - goto errout; + _LOGW ("failed to attach event (%d)", r); + goto error; } hwaddr = nm_dhcp_client_get_hw_addr (client); @@ -932,21 +928,21 @@ ip6_start (NMDhcpClient *client, len, get_arp_type (hwaddr)); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to set MAC address: %s"); - goto errout; + _LOGW ("failed to set MAC address (%d)", r); + goto error; } } r = sd_dhcp6_client_set_ifindex (priv->client6, nm_dhcp_client_get_ifindex (client)); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to set ifindex: %s"); - goto errout; + _LOGW ("failed to set ifindex (%d)", r); + goto error; } r = sd_dhcp6_client_set_callback (priv->client6, dhcp6_event_cb, client); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to set callback: %s"); - goto errout; + _LOGW ("failed to set callback (%d)", r); + goto error; } /* Add requested options */ @@ -957,29 +953,30 @@ ip6_start (NMDhcpClient *client, r = sd_dhcp6_client_set_local_address (priv->client6, ll_addr); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to set local address: %s"); - goto errout; + _LOGW ("failed to set local address (%d)", r); + goto error; } hostname = nm_dhcp_client_get_hostname (client); r = sd_dhcp6_client_set_fqdn (priv->client6, hostname); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to set DHCP hostname: %s"); - goto errout; + _LOGW ("failed to set DHCP hostname to '%s' (%d)", hostname, r); + goto error; } r = sd_dhcp6_client_start (priv->client6); if (r < 0) { - nm_utils_error_set_errno (error, r, "failed to start client: %s"); - goto errout; + _LOGW ("failed to start client (%d)", r); + goto error; } nm_dhcp_client_start_timeout (client); return TRUE; -errout: - sd_dhcp6_client_unref (g_steal_pointer (&priv->client6)); +error: + sd_dhcp6_client_unref (priv->client6); + priv->client6 = NULL; return FALSE; } diff --git a/src/dhcp/nm-dhcp-utils.c b/src/dhcp/nm-dhcp-utils.c index 6bbc670b..9185a135 100644 --- a/src/dhcp/nm-dhcp-utils.c +++ b/src/dhcp/nm-dhcp-utils.c @@ -594,7 +594,7 @@ ip6_add_domain_search (gpointer data, gpointer user_data) NMPlatformIP6Address nm_dhcp_utils_ip6_prefix_from_options (GHashTable *options) { - gs_strfreev char **split_addr = NULL; + gs_strfreev gchar **split_addr = NULL; NMPlatformIP6Address address = { 0, }; struct in6_addr tmp_addr; char *str = NULL; diff --git a/src/dhcp/tests/meson.build b/src/dhcp/tests/meson.build index 0fee26b2..9d8be427 100644 --- a/src/dhcp/tests/meson.build +++ b/src/dhcp/tests/meson.build @@ -8,6 +8,7 @@ foreach test_unit: test_units test_unit, test_unit + '.c', dependencies: test_nm_dep, + c_args: nm_build_cflags, ) test( diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c index 14a1c786..2f369aac 100644 --- a/src/dhcp/tests/test-dhcp-dhclient.c +++ b/src/dhcp/tests/test-dhcp-dhclient.c @@ -86,7 +86,7 @@ test_config (const char *orig, if (expected_new_client_id) { g_assert (new_client_id); g_assert (g_bytes_equal (new_client_id, expected_new_client_id)); - } else + } else g_assert (new_client_id == NULL); } @@ -675,18 +675,27 @@ test_existing_multiline_alsoreq (void) static void test_one_duid (const char *escaped, const guint8 *unescaped, guint len) { - gs_unref_bytes GBytes *t1 = NULL; - gs_unref_bytes GBytes *t2 = NULL; - gs_free char *w = NULL; - - t1 = nm_dhcp_dhclient_unescape_duid (escaped); - g_assert (t1); - g_assert (nm_utils_gbytes_equal_mem (t1, unescaped, len)); - - t2 = g_bytes_new (unescaped, len); - w = nm_dhcp_dhclient_escape_duid (t2); + GBytes *t; + char *w; + gsize t_len; + gconstpointer t_arr; + + t = nm_dhcp_dhclient_unescape_duid (escaped); + g_assert (t); + t_arr = g_bytes_get_data (t, &t_len); + g_assert (t_arr); + g_assert_cmpint (t_len, ==, len); + g_assert_cmpint (memcmp (t_arr, unescaped, len), ==, 0); + g_bytes_unref (t); + + t = g_bytes_new_static (unescaped, len); + w = nm_dhcp_dhclient_escape_duid (t); g_assert (w); + g_assert_cmpint (strlen (escaped), ==, strlen (w)); g_assert_cmpstr (escaped, ==, w); + + g_bytes_unref (t); + g_free (w); } static void @@ -726,11 +735,15 @@ test_read_duid_from_leasefile (void) 0x13, 0x60, 0x67, 0x20, 0xec, 0x4c, 0x70 }; gs_unref_bytes GBytes *duid = NULL; GError *error = NULL; + gconstpointer duid_arr; + gsize duid_len; duid = nm_dhcp_dhclient_read_duid (TEST_DIR"/test-dhclient-duid.leases", &error); - nmtst_assert_success (duid, error); - - g_assert (nm_utils_gbytes_equal_mem (duid, expected, G_N_ELEMENTS (expected))); + g_assert_no_error (error); + g_assert (duid); + duid_arr = g_bytes_get_data (duid, &duid_len); + g_assert_cmpint (duid_len, ==, sizeof (expected)); + g_assert_cmpint (memcmp (duid_arr, expected, duid_len), ==, 0); } static void @@ -949,99 +962,6 @@ test_interface2 (void) } static void -test_structured (void) -{ - gs_unref_bytes GBytes *new_client_id = NULL; - const guint8 bytes[] = "sad-and-useless"; - - static const char *const orig = \ - "interface \"eth0\" { \n" - " send host-name \"useless.example.com\";\n" - " hardware ethernet de:ad:80:86:ba:be;\n" - " send dhcp-client-identifier \"sad-and-useless\";\n" - " script \"/bin/useless\";\n" - " send dhcp-lease-time 8086;\n" - " request subnet-mask, broadcast-address, time-offset, routers,\n" - " domain-search, domain-name, host-name;\n" - " require subnet-mask;\n" - "} \n" - "\n" - " interface \"eth1\" { \n" - " send host-name \"sad.example.com\";\n" - " hardware ethernet de:ca:f6:66:ca:fe;\n" - " send dhcp-client-identifier \"useless-and-miserable\";\n" - " script \"/bin/miserable\";\n" - " send dhcp-lease-time 1337;\n" - " request subnet-mask, broadcast-address, time-offset, routers,\n" - " domain-search, domain-name, domain-name-servers, host-name;\n" - " require subnet-mask, domain-name-servers;\n" - " } \n" - "\n" - "pseudo \"secondary\" \"eth0\" { \n" - " send dhcp-client-identifier \"sad-useless-and-secondary\";\n" - " script \"/bin/secondary\";\n" - " send host-name \"secondary.useless.example.com\";\n" - " send dhcp-lease-time 666;\n" - " request routers;\n" - " require routers;\n" - " } \n" - "\n" - " pseudo \"tertiary\" \"eth0\" { \n" - " send dhcp-client-identifier \"sad-useless-and-tertiary\";\n" - " script \"/bin/tertiary\";\n" - " send host-name \"tertiary.useless.example.com\";\n" - "} \n" - "\n" - " alias{ \n" - " interface \"eth0\";\n" - " fixed-address 192.0.2.1;\n" - " option subnet-mask 255.255.255.0;\n" - " } \n" - " lease { \n" - " interface \"eth0\";\n" - " fixed-address 192.0.2.2;\n" - " option subnet-mask 255.255.255.0;\n" - " } \n"; - - static const char *const expected = \ - "# Created by NetworkManager\n" - "# Merged from /path/to/dhclient.conf\n" - "\n" - "send host-name \"useless.example.com\";\n" - "hardware ethernet de:ad:80:86:ba:be;\n" - "send dhcp-client-identifier \"sad-and-useless\";\n" - "send dhcp-lease-time 8086;\n" - "require subnet-mask;\n" - "\n" - "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" - "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" - "option wpad code 252 = string;\n" - "\n" - "request; # override dhclient defaults\n" - "also request subnet-mask;\n" - "also request broadcast-address;\n" - "also request time-offset;\n" - "also request routers;\n" - "also request domain-search;\n" - "also request domain-name;\n" - "also request host-name;\n" - "also request rfc3442-classless-static-routes;\n" - "also request ms-classless-static-routes;\n" - "also request static-routes;\n" - "also request wpad;\n" - "also request ntp-servers;\n" - "\n"; - - new_client_id = g_bytes_new (bytes, sizeof (bytes) - 1); - test_config (orig, expected, - AF_INET, NULL, 0, FALSE, - NULL, - new_client_id, - "eth0", - NULL); -} - -static void test_config_req_intf (void) { static const char *const orig = \ @@ -1126,7 +1046,6 @@ main (int argc, char **argv) g_test_add_func ("/dhcp/dhclient/interface/1", test_interface1); g_test_add_func ("/dhcp/dhclient/interface/2", test_interface2); g_test_add_func ("/dhcp/dhclient/config/req_intf", test_config_req_intf); - g_test_add_func ("/dhcp/dhclient/structured", test_structured); g_test_add_func ("/dhcp/dhclient/read_duid_from_leasefile", test_read_duid_from_leasefile); g_test_add_func ("/dhcp/dhclient/read_commented_duid_from_leasefile", test_read_commented_duid_from_leasefile); diff --git a/src/dns/nm-dns-dnsmasq.c b/src/dns/nm-dns-dnsmasq.c index cb7a626c..91f4c55b 100644 --- a/src/dns/nm-dns-dnsmasq.c +++ b/src/dns/nm-dns-dnsmasq.c @@ -409,7 +409,7 @@ update (NMDnsPlugin *plugin, /*****************************************************************************/ static void -child_quit (NMDnsPlugin *plugin, int status) +child_quit (NMDnsPlugin *plugin, gint status) { NMDnsDnsmasq *self = NM_DNS_DNSMASQ (plugin); NMDnsDnsmasqPrivate *priv = NM_DNS_DNSMASQ_GET_PRIVATE (self); diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index 6a59b41c..a29fd81f 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -310,7 +310,7 @@ _config_data_free (NMDnsConfigData *data) g_slice_free (NMDnsConfigData, data); } -static int +static gint _ip_config_data_cmp (const NMDnsIPConfigData *a, const NMDnsIPConfigData *b) { int a_prio, b_prio; @@ -333,7 +333,7 @@ _ip_config_data_cmp (const NMDnsIPConfigData *a, const NMDnsIPConfigData *b) return 0; } -static int +static gint _ip_config_lst_cmp (const CList *a, const CList *b, const void *user_data) @@ -482,7 +482,7 @@ merge_one_ip_config (NMResolvConfData *rc, } static GPid -run_netconfig (NMDnsManager *self, GError **error, int *stdin_fd) +run_netconfig (NMDnsManager *self, GError **error, gint *stdin_fd) { char *argv[5]; gs_free char *tmp = NULL; @@ -533,7 +533,7 @@ dispatch_netconfig (NMDnsManager *self, GError **error) { GPid pid; - int fd; + gint fd; int status; gssize l; nm_auto_free_gstring GString *str = NULL; @@ -970,8 +970,6 @@ compute_hash (NMDnsManager *self, const NMGlobalDnsConfig *global, guint8 buffer else { const CList *head; - /* FIXME(ip-config-checksum): this relies on the fact that an IP - * configuration without DNS parameters gives a zero checksum. */ head = _ip_config_lst_head (self); c_list_for_each_entry (ip_data, head, ip_config_lst) nm_ip_config_hash (ip_data->ip_config, sum, TRUE); diff --git a/src/dns/nm-dns-plugin.c b/src/dns/nm-dns-plugin.c index 48f04b00..d9400e3e 100644 --- a/src/dns/nm-dns-plugin.c +++ b/src/dns/nm-dns-plugin.c @@ -124,7 +124,7 @@ _clear_pidfile (NMDnsPlugin *self) static void kill_existing (const char *progname, const char *pidfile, const char *kill_match) { - long pid; + glong pid; gs_free char *contents = NULL; gs_free char *cmdline_contents = NULL; guint64 start_time; @@ -167,7 +167,7 @@ out: } static void -watch_cb (GPid pid, int status, gpointer user_data) +watch_cb (GPid pid, gint status, gpointer user_data) { NMDnsPlugin *self = NM_DNS_PLUGIN (user_data); NMDnsPluginPrivate *priv = NM_DNS_PLUGIN_GET_PRIVATE (self); diff --git a/src/dns/nm-dns-plugin.h b/src/dns/nm-dns-plugin.h index 8a55921d..80b77d95 100644 --- a/src/dns/nm-dns-plugin.h +++ b/src/dns/nm-dns-plugin.h @@ -70,7 +70,7 @@ typedef struct { * by NMDnsManager. If the subclass decides the exit status (as returned * by waitpid(2)) is fatal it should then emit the 'failed' signal. */ - void (*child_quit) (NMDnsPlugin *self, int status); + void (*child_quit) (NMDnsPlugin *self, gint status); } NMDnsPluginClass; GType nm_dns_plugin_get_type (void); diff --git a/src/dns/nm-dns-systemd-resolved.c b/src/dns/nm-dns-systemd-resolved.c index 544f19c1..1a73aae1 100644 --- a/src/dns/nm-dns-systemd-resolved.c +++ b/src/dns/nm-dns-systemd-resolved.c @@ -65,6 +65,7 @@ typedef struct { GDBusProxy *resolve; GCancellable *init_cancellable; GCancellable *update_cancellable; + GCancellable *mdns_cancellable; CList request_queue_lst_head; } NMDnsSystemdResolvedPrivate; @@ -191,8 +192,7 @@ prepare_one_interface (NMDnsSystemdResolved *self, InterfaceConfig *ic) GVariantBuilder dns, domains; NMCListElem *elem; NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT; - NMSettingConnectionLlmnr llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT; - const char *mdns_arg = NULL, *llmnr_arg = NULL; + const char *mdns_arg = NULL; g_variant_builder_init (&dns, G_VARIANT_TYPE ("(ia(iay))")); g_variant_builder_add (&dns, "i", ic->ifindex); @@ -208,10 +208,8 @@ prepare_one_interface (NMDnsSystemdResolved *self, InterfaceConfig *ic) update_add_ip_config (self, &dns, &domains, data); - if (NM_IS_IP4_CONFIG (ip_config)) { + if (NM_IS_IP4_CONFIG (ip_config)) mdns = NM_MAX (mdns, nm_ip4_config_mdns_get (NM_IP4_CONFIG (ip_config))); - llmnr = NM_MAX (llmnr, nm_ip4_config_llmnr_get (NM_IP4_CONFIG (ip_config))); - } } g_variant_builder_close (&dns); @@ -233,22 +231,6 @@ prepare_one_interface (NMDnsSystemdResolved *self, InterfaceConfig *ic) } nm_assert (mdns_arg); - switch (llmnr) { - case NM_SETTING_CONNECTION_LLMNR_NO: - llmnr_arg = "no"; - break; - case NM_SETTING_CONNECTION_LLMNR_RESOLVE: - llmnr_arg = "resolve"; - break; - case NM_SETTING_CONNECTION_LLMNR_YES: - llmnr_arg = "yes"; - break; - case NM_SETTING_CONNECTION_LLMNR_DEFAULT: - llmnr_arg = ""; - break; - } - nm_assert (llmnr_arg); - _request_item_append (&priv->request_queue_lst_head, "SetLinkDNS", g_variant_builder_end (&dns)); @@ -258,9 +240,6 @@ prepare_one_interface (NMDnsSystemdResolved *self, InterfaceConfig *ic) _request_item_append (&priv->request_queue_lst_head, "SetLinkMulticastDNS", g_variant_new ("(is)", ic->ifindex, mdns_arg ?: "")); - _request_item_append (&priv->request_queue_lst_head, - "SetLinkLLMNR", - g_variant_new ("(is)", ic->ifindex, llmnr_arg ?: "")); } static void @@ -431,6 +410,7 @@ dispose (GObject *object) g_clear_object (&priv->resolve); nm_clear_g_cancellable (&priv->init_cancellable); nm_clear_g_cancellable (&priv->update_cancellable); + nm_clear_g_cancellable (&priv->mdns_cancellable); G_OBJECT_CLASS (nm_dns_systemd_resolved_parent_class)->dispose (object); } diff --git a/src/dns/nm-dns-unbound.c b/src/dns/nm-dns-unbound.c index b900f29e..e06128aa 100644 --- a/src/dns/nm-dns-unbound.c +++ b/src/dns/nm-dns-unbound.c @@ -43,7 +43,7 @@ update (NMDnsPlugin *plugin, const CList *ip_config_lst_head, const char *hostname) { - char *argv[] = { DNSSEC_TRIGGER_PATH, "--async", "--update", NULL }; + char *argv[] = { DNSSEC_TRIGGER_SCRIPT, "--async", "--update", NULL }; int status; /* TODO: We currently call a script installed with the dnssec-trigger diff --git a/src/dnsmasq/nm-dnsmasq-manager.c b/src/dnsmasq/nm-dnsmasq-manager.c index 09889441..041e75ea 100644 --- a/src/dnsmasq/nm-dnsmasq-manager.c +++ b/src/dnsmasq/nm-dnsmasq-manager.c @@ -104,7 +104,7 @@ nm_cmd_line_to_str (NMCmdLine *cmd) char *str; g_ptr_array_add (cmd->array, NULL); - str = g_strjoinv (" ", (char **) cmd->array->pdata); + str = g_strjoinv (" ", (gchar **) cmd->array->pdata); g_ptr_array_remove_index (cmd->array, cmd->array->len - 1); return str; @@ -119,7 +119,7 @@ nm_cmd_line_add_string (NMCmdLine *cmd, const char *str) /*****************************************************************************/ static void -dm_watch_cb (GPid pid, int status, gpointer user_data) +dm_watch_cb (GPid pid, gint status, gpointer user_data) { NMDnsMasqManager *manager = NM_DNSMASQ_MANAGER (user_data); NMDnsMasqManagerPrivate *priv = NM_DNSMASQ_MANAGER_GET_PRIVATE (manager); @@ -187,7 +187,7 @@ create_dm_cmd_line (const char *iface, * as the gateway or whatever. So tell dnsmasq not to use any config file * at all. */ - nm_cmd_line_add_string (cmd, "--conf-file=/dev/null"); + nm_cmd_line_add_string (cmd, "--conf-file"); nm_cmd_line_add_string (cmd, "--no-hosts"); nm_cmd_line_add_string (cmd, "--keep-in-foreground"); @@ -249,11 +249,6 @@ create_dm_cmd_line (const char *iface, nm_cmd_line_add_string (cmd, "--dhcp-lease-max=50"); - g_string_append (s, "--dhcp-leasefile=" NMSTATEDIR); - g_string_append_printf (s, "/dnsmasq-%s.leases", iface); - nm_cmd_line_add_string (cmd, s->str); - g_string_truncate (s, 0); - g_string_append (s, "--pid-file="); g_string_append (s, pidfile); nm_cmd_line_add_string (cmd, s->str); diff --git a/src/main-utils.c b/src/main-utils.c index a597ede7..0f790536 100644 --- a/src/main-utils.c +++ b/src/main-utils.c @@ -177,7 +177,7 @@ nm_main_utils_ensure_not_running_pidfile (const char *pidfile) gs_free char *contents = NULL; gs_free char *proc_cmdline = NULL; gsize len = 0; - long pid; + glong pid; const char *process_name; const char *prgname = g_get_prgname (); diff --git a/src/main.c b/src/main.c index a5bfb6af..7da0c3c2 100644 --- a/src/main.c +++ b/src/main.c @@ -59,6 +59,7 @@ #endif #define NM_DEFAULT_PID_FILE NMRUNDIR "/NetworkManager.pid" +#define NM_DEFAULT_SYSTEM_STATE_FILE NMSTATEDIR "/NetworkManager.state" #define CONFIG_ATOMIC_SECTION_PREFIXES ((char **) NULL) @@ -443,7 +444,7 @@ done: * state here. We don't bother updating the state as devices * change during regular operation. If NM is killed with SIGKILL, * it misses to update the state. */ - nm_manager_write_device_state_all (manager); + nm_manager_write_device_state (manager); nm_manager_stop (manager); diff --git a/src/meson.build b/src/meson.build index f46366a9..e60ab93f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -17,7 +17,35 @@ nm_dep = declare_dependency( compile_args: nm_cflags ) -cflags = nm_cflags +cflags = nm_cflags + [ + '-DPREFIX="@0@"'.format(nm_prefix), + '-DBINDIR="@0@"'.format(nm_bindir), + '-DDATADIR="@0@"'.format(nm_datadir), + '-DLIBEXECDIR="@0@"'.format(nm_libexecdir), + '-DLOCALSTATEDIR="@0@"'.format(nm_localstatedir), + '-DRUNSTATEDIR="@0@"'.format(nm_runstatedir), + '-DSBINDIR="@0@"'.format(nm_sbindir), + '-DSYSCONFDIR="@0@"'.format(nm_sysconfdir), + '-DRUNDIR="@0@"'.format(nm_pkgrundir), + '-DNMCONFDIR="@0@"'.format(nm_pkgconfdir), + '-DNMLOCALEDIR="@0@"'.format(nm_localedir), + '-DNMPLUGINDIR="@0@"'.format(nm_plugindir), + '-DNMRUNDIR="@0@"'.format(nm_pkgrundir), + '-DNMSTATEDIR="@0@"'.format(nm_pkgstatedir), + '-DNMLIBDIR="@0@"'.format(nm_pkglibdir) +] + +if enable_dhcpcanon + cflags += '-DDHCPCANON_PATH="@0@"'.format(dhcpcanon.path()) +endif + +if enable_dhclient + cflags += '-DDHCLIENT_PATH="@0@"'.format(dhclient.path()) +endif + +if enable_dhcpcd + cflags += '-DDHCPCD_PATH="@0@"'.format(dhcpcd.path()) +endif sources = files( 'dhcp/nm-dhcp-client.c', @@ -27,9 +55,8 @@ sources = files( 'ndisc/nm-lndp-ndisc.c', 'ndisc/nm-ndisc.c', 'platform/nm-netlink.c', - 'platform/wifi/nm-wifi-utils-nl80211.c', - 'platform/wifi/nm-wifi-utils.c', - 'platform/wpan/nm-wpan-utils.c', + 'platform/wifi/wifi-utils-nl80211.c', + 'platform/wifi/wifi-utils.c', 'platform/nm-linux-platform.c', 'platform/nm-platform.c', 'platform/nm-platform-utils.c', @@ -52,7 +79,7 @@ deps = [ ] if enable_wext - sources += files('platform/wifi/nm-wifi-utils-wext.c') + sources += files('platform/wifi/wifi-utils-wext.c') endif libnetwork_manager_base = static_library( @@ -65,7 +92,6 @@ libnetwork_manager_base = static_library( sources = files( 'devices/nm-acd-manager.c', - 'devices/nm-device-6lowpan.c', 'devices/nm-device-bond.c', 'devices/nm-device-bridge.c', 'devices/nm-device.c', @@ -83,8 +109,6 @@ sources = files( 'devices/nm-device-veth.c', 'devices/nm-device-vlan.c', 'devices/nm-device-vxlan.c', - 'devices/nm-device-wireguard.c', - 'devices/nm-device-wpan.c', 'devices/nm-lldp-listener.c', 'dhcp/nm-dhcp-dhclient.c', 'dhcp/nm-dhcp-dhclient-utils.c', @@ -143,39 +167,86 @@ sources = files( 'nm-sleep-monitor.c' ) -nm_deps = [ +deps = [ dl_dep, libndp_dep, + # FIXME: Some files use introspection/dbus* headers, so + # this dependency might be needed + #libnmdbus_dep, libudev_dep, nm_core_dep, - shared_n_acd_dep, - logind_dep, + shared_n_acd_dep ] if enable_concheck - nm_deps += libcurl_dep + deps += libcurl_dep endif if enable_libaudit - nm_deps += libaudit_dep + deps += libaudit_dep endif if enable_libpsl - nm_deps += libpsl_dep + deps += libpsl_dep endif if enable_selinux - nm_deps += selinux_dep + deps += selinux_dep +endif + +if enable_session_tracking + deps += logind_dep endif libnetwork_manager = static_library( nm_name, sources: sources, - dependencies: nm_deps, + dependencies: deps, c_args: cflags, link_with: [libnetwork_manager_base, libsystemd_nm] ) +ldflags = ['-rdynamic'] + +# FIXME: this doesn't work and it depends on libtool +''' +src/NetworkManager.ver: src/libNetworkManager.la $(core_plugins) + $(AM_V_GEN) NM="$(NM)" "$(srcdir)/tools/create-exports-NetworkManager.sh" --called-from-make "$(srcdir)" + +src_NetworkManager_LDFLAGS = \ + -rdynamic \ + -Wl,--version-script="src/NetworkManager.ver" + +nm = find_program('gcc-nm', 'nm') +create_exports_networkmanager = join_paths(meson.source_root(), 'tools', 'create-exports-NetworkManager.sh') + +symbol_map_name = 'NetworkManager.ver' + +linker_script = custom_target( + symbol_map_name, + input: meson.source_root(), + output: symbol_map_name, + capture: true, + #command: ['NM=' + nm.path(), create_exports_networkmanager, '--called-from-make', '@INPUT@'] + command: [create_exports_networkmanager, '--called-from-make', '@INPUT@'] +) + +ldflags += '-Wl,--version-script,@0@'.format(linker_script) +''' + +network_manager = executable( + nm_name, + 'main.c', + dependencies: deps, + c_args: cflags, + link_with: libnetwork_manager, + link_args: ldflags, + #FIXME + #link_depends: linker_script, + install: true, + install_dir: nm_sbindir +) + deps = [ dl_dep, libndp_dep, @@ -246,30 +317,3 @@ endif subdir('devices') subdir('settings/plugins') - -# NetworkManager binary - -create_exports_networkmanager = join_paths(meson.source_root(), 'tools', 'create-exports-NetworkManager.sh') -symbol_map_name = 'NetworkManager.ver' - -ver_script = custom_target( - symbol_map_name, - input: meson.source_root(), - output: symbol_map_name, - depends: [ libnetwork_manager, core_plugins ], - command: [create_exports_networkmanager, '--called-from-build', '@INPUT@'] -) - -ldflags = ['-rdynamic', '-Wl,--version-script,@0@'.format(ver_script.full_path())] - -network_manager = executable( - nm_name, - 'main.c', - dependencies: nm_deps, - c_args: nm_cflags, - link_with: libnetwork_manager, - link_args: ldflags, - link_depends: ver_script, - install: true, - install_dir: nm_sbindir -) diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index 879eec67..04f86312 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -1192,7 +1192,7 @@ set_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_PLATFORM: /* construct-only */ - priv->platform = g_value_get_object (value) ?: NM_PLATFORM_GET; + priv->platform = g_value_get_object (value) ? : NM_PLATFORM_GET; if (!priv->platform) g_return_if_reached (); diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c index a2f9ae4a..aa83d6d5 100644 --- a/src/nm-active-connection.c +++ b/src/nm-active-connection.c @@ -174,7 +174,7 @@ NM_UTILS_FLAGS2STR_DEFINE_STATIC (_state_flags_to_string, NMActivationStateFlags /*****************************************************************************/ static void -_settings_connection_updated (NMSettingsConnection *sett_conn, +_settings_connection_updated (NMSettingsConnection *connection, gboolean by_user, gpointer user_data) { @@ -196,24 +196,24 @@ _settings_connection_updated (NMSettingsConnection *sett_conn, } static void -_set_settings_connection (NMActiveConnection *self, NMSettingsConnection *sett_conn) +_set_settings_connection (NMActiveConnection *self, NMSettingsConnection *connection) { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); - if (priv->settings_connection.obj == sett_conn) + if (priv->settings_connection.obj == connection) return; if (priv->settings_connection.obj) { g_signal_handlers_disconnect_by_func (priv->settings_connection.obj, _settings_connection_updated, self); g_signal_handlers_disconnect_by_func (priv->settings_connection.obj, _settings_connection_flags_changed, self); } - if (sett_conn) { - g_signal_connect (sett_conn, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, (GCallback) _settings_connection_updated, self); + if (connection) { + g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, (GCallback) _settings_connection_updated, self); if (nm_active_connection_get_activation_type (self) == NM_ACTIVATION_TYPE_EXTERNAL) - g_signal_connect (sett_conn, NM_SETTINGS_CONNECTION_FLAGS_CHANGED, (GCallback) _settings_connection_flags_changed, self); + g_signal_connect (connection, NM_SETTINGS_CONNECTION_FLAGS_CHANGED, (GCallback) _settings_connection_flags_changed, self); } - nm_dbus_track_obj_path_set (&priv->settings_connection, sett_conn, TRUE); + nm_dbus_track_obj_path_set (&priv->settings_connection, connection, TRUE); } NMActiveConnectionState @@ -367,13 +367,13 @@ nm_active_connection_set_state_flags_full (NMActiveConnection *self, const char * nm_active_connection_get_settings_connection_id (NMActiveConnection *self) { - NMSettingsConnection *sett_conn; + NMSettingsConnection *con; g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL); - sett_conn = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection.obj; - return sett_conn - ? nm_settings_connection_get_id (sett_conn) + con = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->settings_connection.obj; + return con + ? nm_connection_get_id (NM_CONNECTION (con)) : NULL; } @@ -388,31 +388,31 @@ _nm_active_connection_get_settings_connection (NMActiveConnection *self) NMSettingsConnection * nm_active_connection_get_settings_connection (NMActiveConnection *self) { - NMSettingsConnection *sett_conn; + NMSettingsConnection *con; - sett_conn = _nm_active_connection_get_settings_connection (self); + con = _nm_active_connection_get_settings_connection (self); /* Only call this function on an active-connection that is already * fully set-up (i.e. that has a settings-connection). Other uses * indicate a bug. */ - g_return_val_if_fail (sett_conn, NULL); - return sett_conn; + g_return_val_if_fail (con, NULL); + return con; } NMConnection * nm_active_connection_get_applied_connection (NMActiveConnection *self) { - NMConnection *connection; + NMConnection *con; g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (self), NULL); - connection = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->applied_connection; + con = NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->applied_connection; /* Only call this function on an active-connection that is already * fully set-up (i.e. that has a settings-connection). Other uses * indicate a bug. */ - g_return_val_if_fail (connection, NULL); - return connection; + g_return_val_if_fail (con, NULL); + return con; } static void @@ -447,7 +447,7 @@ _set_applied_connection_take (NMActiveConnection *self, void nm_active_connection_set_settings_connection (NMActiveConnection *self, - NMSettingsConnection *sett_conn) + NMSettingsConnection *connection) { NMActiveConnectionPrivate *priv; @@ -455,7 +455,7 @@ nm_active_connection_set_settings_connection (NMActiveConnection *self, priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn)); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); g_return_if_fail (!priv->settings_connection.obj); g_return_if_fail (!priv->applied_connection); @@ -468,10 +468,10 @@ nm_active_connection_set_settings_connection (NMActiveConnection *self, * For example, we'd have to cancel all pending seret requests. */ g_return_if_fail (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (self))); - _set_settings_connection (self, sett_conn); + _set_settings_connection (self, connection); _set_applied_connection_take (self, - nm_simple_connection_new_clone (nm_settings_connection_get_connection (priv->settings_connection.obj))); + nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection.obj))); } gboolean @@ -503,10 +503,8 @@ nm_active_connection_clear_secrets (NMActiveConnection *self) if (nm_settings_connection_has_unmodified_applied_connection (priv->settings_connection.obj, priv->applied_connection, - NM_SETTING_COMPARE_FLAG_NONE)) { - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - nm_connection_clear_secrets (nm_settings_connection_get_connection (priv->settings_connection.obj)); - } + NM_SETTING_COMPARE_FLAG_NONE)) + nm_connection_clear_secrets ((NMConnection *) priv->settings_connection.obj); nm_connection_clear_secrets (priv->applied_connection); } @@ -923,7 +921,7 @@ _settings_connection_flags_changed (NMSettingsConnection *settings_connection, _set_activation_type_managed (self); if (!nm_device_reapply (nm_active_connection_get_device (self), - nm_settings_connection_get_connection ((nm_active_connection_get_settings_connection (self))), + NM_CONNECTION (nm_active_connection_get_settings_connection (self)), &error)) { _LOGW ("failed to reapply new device settings on previously externally managed device: %s", error->message); @@ -1114,7 +1112,7 @@ nm_active_connection_authorize (NMActiveConnection *self, { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); const char *wifi_permission = NULL; - NMConnection *connection; + NMConnection *con; g_return_if_fail (result_func); g_return_if_fail (!priv->auth.call_id_network_control); @@ -1124,11 +1122,11 @@ nm_active_connection_authorize (NMActiveConnection *self, g_return_if_fail (NM_IS_CONNECTION (initial_connection)); g_return_if_fail (!priv->settings_connection.obj); g_return_if_fail (!priv->applied_connection); - connection = initial_connection; + con = initial_connection; } else { g_return_if_fail (NM_IS_SETTINGS_CONNECTION (priv->settings_connection.obj)); g_return_if_fail (NM_IS_CONNECTION (priv->applied_connection)); - connection = priv->applied_connection; + con = priv->applied_connection; } priv->auth.call_id_network_control = nm_auth_manager_check_authorization (nm_auth_manager_get (), @@ -1139,7 +1137,7 @@ nm_active_connection_authorize (NMActiveConnection *self, self); /* Shared wifi connections require special permissions too */ - wifi_permission = nm_utils_get_shared_wifi_permission (connection); + wifi_permission = nm_utils_get_shared_wifi_permission (con); if (wifi_permission) { priv->auth.call_id_wifi_shared_permission = nm_auth_manager_check_authorization (nm_auth_manager_get (), priv->subject, @@ -1229,13 +1227,13 @@ get_property (GObject *object, guint prop_id, g_value_set_string (value, nm_dbus_track_obj_path_get (&priv->settings_connection)); break; case PROP_ID: - g_value_set_string (value, nm_settings_connection_get_id (priv->settings_connection.obj)); + g_value_set_string (value, nm_connection_get_id (NM_CONNECTION (priv->settings_connection.obj))); break; case PROP_UUID: - g_value_set_string (value, nm_settings_connection_get_uuid (priv->settings_connection.obj)); + g_value_set_string (value, nm_connection_get_uuid (NM_CONNECTION (priv->settings_connection.obj))); break; case PROP_TYPE: - g_value_set_string (value, nm_settings_connection_get_connection_type (priv->settings_connection.obj)); + g_value_set_string (value, nm_connection_get_connection_type (NM_CONNECTION (priv->settings_connection.obj))); break; case PROP_SPECIFIC_OBJECT: @@ -1306,16 +1304,16 @@ set_property (GObject *object, guint prop_id, NMActiveConnection *self = (NMActiveConnection *) object; NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self); const char *tmp; - NMSettingsConnection *sett_conn; + NMSettingsConnection *con; NMConnection *acon; int i; switch (prop_id) { case PROP_INT_SETTINGS_CONNECTION: /* construct-only */ - sett_conn = g_value_get_object (value); - if (sett_conn) - _set_settings_connection (self, sett_conn); + con = g_value_get_object (value); + if (con) + _set_settings_connection (self, con); break; case PROP_INT_APPLIED_CONNECTION: /* construct-only */ @@ -1412,7 +1410,7 @@ constructed (GObject *object) if ( !priv->applied_connection && priv->settings_connection.obj) - priv->applied_connection = nm_simple_connection_new_clone (nm_settings_connection_get_connection (priv->settings_connection.obj)); + priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection.obj)); _LOGD ("constructed (%s, version-id %llu, type %s)", G_OBJECT_TYPE_NAME (self), diff --git a/src/nm-auth-subject.c b/src/nm-auth-subject.c index 9ed65e2d..117a3815 100644 --- a/src/nm-auth-subject.c +++ b/src/nm-auth-subject.c @@ -200,7 +200,7 @@ _new_unix_process (GDBusMethodInvocation *context, return NULL; g_return_val_if_fail (dbus_sender && *dbus_sender, NULL); - /* polkit glib library stores uid and pid as int. There might be some + /* polkit glib library stores uid and pid as gint. There might be some * pitfalls if the id ever happens to be larger then that. Just assert against * it here. */ g_return_val_if_fail (uid <= MIN (G_MAXINT, G_MAXINT32), NULL); @@ -356,7 +356,7 @@ constructed (GObject *object) return; case NM_AUTH_SUBJECT_TYPE_UNIX_PROCESS: /* Ensure pid and uid to be representable as int32. - * DBUS treats them as uint32, polkit library as int. */ + * DBUS treats them as uint32, polkit library as gint. */ if (priv->unix_process.pid > MIN (G_MAXINT, G_MAXINT32)) break; if (priv->unix_process.uid > MIN (G_MAXINT, G_MAXINT32)) { diff --git a/src/nm-checkpoint-manager.c b/src/nm-checkpoint-manager.c index 0c2af831..7e8c8aea 100644 --- a/src/nm-checkpoint-manager.c +++ b/src/nm-checkpoint-manager.c @@ -265,8 +265,8 @@ nm_checkpoint_manager_lookup_by_path (NMCheckpointManager *self, const char *pat g_return_val_if_fail (self, NULL); - checkpoint = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (GET_MANAGER (self))), - path); + checkpoint = (NMCheckpoint *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (GET_MANAGER (self))), + path); if ( !checkpoint || !NM_IS_CHECKPOINT (checkpoint)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_INVALID_ARGUMENTS, diff --git a/src/nm-checkpoint.c b/src/nm-checkpoint.c index b0cf1f51..a17f7eda 100644 --- a/src/nm-checkpoint.c +++ b/src/nm-checkpoint.c @@ -159,7 +159,7 @@ find_settings_connection (NMCheckpoint *self, { NMCheckpointPrivate *priv = NM_CHECKPOINT_GET_PRIVATE (self); NMActiveConnection *active; - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; const char *uuid, *ac_uuid; const CList *tmp_clist; @@ -167,14 +167,14 @@ find_settings_connection (NMCheckpoint *self, *need_update = FALSE; uuid = nm_connection_get_uuid (dev_checkpoint->settings_connection); - sett_conn = nm_settings_get_connection_by_uuid (nm_settings_get (), uuid); + connection = nm_settings_get_connection_by_uuid (nm_settings_get (), uuid); - if (!sett_conn) + if (!connection) return NULL; /* Now check if the connection changed, ... */ if (!nm_connection_compare (dev_checkpoint->settings_connection, - nm_settings_connection_get_connection (sett_conn), + NM_CONNECTION (connection), NM_SETTING_COMPARE_FLAG_EXACT)) { _LOGT ("rollback: settings connection %s changed", uuid); *need_update = TRUE; @@ -193,7 +193,7 @@ find_settings_connection (NMCheckpoint *self, if (!active) { _LOGT ("rollback: connection %s is not active", uuid); *need_activation = TRUE; - return sett_conn; + return connection; } /* ... or if the connection was reactivated/reapplied */ @@ -202,7 +202,7 @@ find_settings_connection (NMCheckpoint *self, *need_activation = TRUE; } - return sett_conn; + return connection; } GVariant * @@ -337,8 +337,8 @@ activate: dev_checkpoint->activation_reason, &local_error)) { _LOGW ("rollback: reactivation of connection %s/%s failed: %s", - nm_settings_connection_get_id (connection), - nm_settings_connection_get_uuid (connection), + nm_connection_get_id ((NMConnection *) connection), + nm_connection_get_uuid ((NMConnection *) connection), local_error->message); g_clear_error (&local_error); result = NM_ROLLBACK_RESULT_ERR_FAILED; @@ -436,9 +436,12 @@ device_checkpoint_create (NMDevice *device) applied_connection = nm_act_request_get_applied_connection (act_request); dev_checkpoint->applied_connection = nm_simple_connection_new_clone (applied_connection); - dev_checkpoint->settings_connection = nm_simple_connection_new_clone (nm_settings_connection_get_connection (settings_connection)); - dev_checkpoint->ac_version_id = nm_active_connection_version_id_get (NM_ACTIVE_CONNECTION (act_request)); - dev_checkpoint->activation_reason = nm_active_connection_get_activation_reason (NM_ACTIVE_CONNECTION (act_request)); + dev_checkpoint->settings_connection = + nm_simple_connection_new_clone (NM_CONNECTION (settings_connection)); + dev_checkpoint->ac_version_id = + nm_active_connection_version_id_get (NM_ACTIVE_CONNECTION (act_request)); + dev_checkpoint->activation_reason = + nm_active_connection_get_activation_reason (NM_ACTIVE_CONNECTION (act_request)); } return dev_checkpoint; diff --git a/src/nm-config-data.c b/src/nm-config-data.c index 8d84e74a..813ef9c8 100644 --- a/src/nm-config-data.c +++ b/src/nm-config-data.c @@ -183,11 +183,11 @@ nm_config_data_has_value (const NMConfigData *self, const char *group, const cha return !!value; } -int -nm_config_data_get_value_boolean (const NMConfigData *self, const char *group, const char *key, int default_value) +gint +nm_config_data_get_value_boolean (const NMConfigData *self, const char *group, const char *key, gint default_value) { char *str; - int value = default_value; + gint value = default_value; g_return_val_if_fail (NM_IS_CONFIG_DATA (self), default_value); g_return_val_if_fail (group && *group, default_value); @@ -655,12 +655,12 @@ nm_config_data_log (const NMConfigData *self, const char *group = default_values[g].group; gssize idx; - idx = nm_utils_array_find_binary_search ((gconstpointer *) groups_full->pdata, - sizeof (char *), - groups_full->len, - &group, - (GCompareDataFunc) _nm_config_data_log_sort, - NULL); + idx = _nm_utils_array_find_binary_search ((gconstpointer *) groups_full->pdata, + sizeof (char *), + groups_full->len, + &group, + (GCompareDataFunc) _nm_config_data_log_sort, + NULL); if (idx < 0) g_ptr_array_insert (groups_full, (~idx), (gpointer) group); } @@ -1335,8 +1335,8 @@ gboolean nm_config_data_get_device_config_boolean (const NMConfigData *self, const char *property, NMDevice *device, - int val_no_match, - int val_invalid) + gint val_no_match, + gint val_invalid) { gs_free char *value = NULL; gboolean has_match; @@ -1371,20 +1371,6 @@ nm_config_data_get_connection_default (const NMConfigData *self, return value; } -gint64 -nm_config_data_get_connection_default_int64 (const NMConfigData *self, - const char *property, - NMDevice *device, - gint64 min, - gint64 max, - gint64 fallback) -{ - gs_free char *value = NULL; - - value = nm_config_data_get_connection_default (self, property, device); - return _nm_utils_ascii_str_to_int64 (value, 10, min, max, fallback); -} - static void _get_connection_info_init (MatchSectionInfo *connection_info, GKeyFile *keyfile, char *group) { diff --git a/src/nm-config-data.h b/src/nm-config-data.h index b52ddcc4..650fbe14 100644 --- a/src/nm-config-data.h +++ b/src/nm-config-data.h @@ -154,7 +154,7 @@ const char *nm_config_data_get_config_description (const NMConfigData *config_da gboolean nm_config_data_has_group (const NMConfigData *self, const char *group); gboolean nm_config_data_has_value (const NMConfigData *self, const char *group, const char *key, NMConfigGetValueFlags flags); char *nm_config_data_get_value (const NMConfigData *config_data, const char *group, const char *key, NMConfigGetValueFlags flags); -int nm_config_data_get_value_boolean (const NMConfigData *self, const char *group, const char *key, int default_value); +gint nm_config_data_get_value_boolean (const NMConfigData *self, const char *group, const char *key, gint default_value); gint64 nm_config_data_get_value_int64 (const NMConfigData *self, const char *group, const char *key, guint base, gint64 min, gint64 max, gint64 fallback); char **nm_config_data_get_plugins (const NMConfigData *config_data, gboolean allow_default); @@ -181,13 +181,6 @@ char *nm_config_data_get_connection_default (const NMConfigData *self, const char *property, NMDevice *device); -gint64 nm_config_data_get_connection_default_int64 (const NMConfigData *self, - const char *property, - NMDevice *device, - gint64 min, - gint64 max, - gint64 fallback); - char *nm_config_data_get_device_config (const NMConfigData *self, const char *property, NMDevice *device, @@ -202,8 +195,8 @@ char *nm_config_data_get_device_config_by_pllink (const NMConfigData *self, gboolean nm_config_data_get_device_config_boolean (const NMConfigData *self, const char *property, NMDevice *device, - int val_no_match, - int val_invalid); + gint val_no_match, + gint val_invalid); char **nm_config_data_get_groups (const NMConfigData *self); char **nm_config_data_get_keys (const NMConfigData *self, const char *group); diff --git a/src/nm-config.c b/src/nm-config.c index 102070e9..d4682ed6 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -167,18 +167,18 @@ static void _set_config_data (NMConfig *self, NMConfigData *new_data, NMConfigCh /*****************************************************************************/ -int +gint nm_config_parse_boolean (const char *str, - int default_value) + gint default_value) { return _nm_utils_ascii_str_to_bool (str, default_value); } -int +gint nm_config_keyfile_get_boolean (const GKeyFile *keyfile, const char *section, const char *key, - int default_value) + gint default_value) { gs_free char *str = NULL; @@ -1690,7 +1690,7 @@ nm_config_set_values (NMConfig *self, GError *local = NULL; NMConfigData *new_data = NULL; gs_strfreev char **groups = NULL; - int g; + gint g; g_return_if_fail (NM_IS_CONFIG (self)); @@ -1948,7 +1948,7 @@ _config_device_state_data_new (int ifindex, GKeyFile *kf) gs_free char *perm_hw_addr_fake = NULL; gsize connection_uuid_len; gsize perm_hw_addr_fake_len; - int nm_owned = -1; + gint nm_owned = -1; char *p; guint32 route_metric_default_effective; guint32 route_metric_default_aspired; @@ -2126,7 +2126,7 @@ nm_config_device_state_write (int ifindex, NMConfigDeviceStateManagedType managed, const char *perm_hw_addr_fake, const char *connection_uuid, - int nm_owned, + gint nm_owned, guint32 route_metric_default_aspired, guint32 route_metric_default_effective) { diff --git a/src/nm-config.h b/src/nm-config.h index 1b013ff3..5d027ce0 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -159,13 +159,13 @@ void _nm_config_state_set (NMConfig *config, #define nm_config_state_set(config, allow_persist, force_persist, ...) \ _nm_config_state_set (config, allow_persist, force_persist, ##__VA_ARGS__, 0) -int nm_config_parse_boolean (const char *str, int default_value); +gint nm_config_parse_boolean (const char *str, gint default_value); GKeyFile *nm_config_create_keyfile (void); -int nm_config_keyfile_get_boolean (const GKeyFile *keyfile, +gint nm_config_keyfile_get_boolean (const GKeyFile *keyfile, const char *section, const char *key, - int default_value); + gint default_value); gint64 nm_config_keyfile_get_int64 (const GKeyFile *keyfile, const char *section, const char *key, @@ -234,7 +234,7 @@ gboolean nm_config_device_state_write (int ifindex, NMConfigDeviceStateManagedType managed, const char *perm_hw_addr_fake, const char *connection_uuid, - int nm_owned, + gint nm_owned, guint32 route_metric_default_aspired, guint32 route_metric_default_effective); diff --git a/src/nm-connectivity.c b/src/nm-connectivity.c index 3b779677..db26218b 100644 --- a/src/nm-connectivity.c +++ b/src/nm-connectivity.c @@ -46,8 +46,10 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_state_to_string, int /*NMConnectivityState*/ NM_UTILS_LOOKUP_STR_ITEM (NM_CONNECTIVITY_PORTAL, "PORTAL"), NM_UTILS_LOOKUP_STR_ITEM (NM_CONNECTIVITY_FULL, "FULL"), - NM_UTILS_LOOKUP_STR_ITEM (NM_CONNECTIVITY_ERROR, "ERROR"), - NM_UTILS_LOOKUP_STR_ITEM (NM_CONNECTIVITY_FAKE, "FAKE"), + NM_UTILS_LOOKUP_STR_ITEM (NM_CONNECTIVITY_ERROR, "ERROR"), + NM_UTILS_LOOKUP_STR_ITEM (NM_CONNECTIVITY_FAKE, "FAKE"), + NM_UTILS_LOOKUP_STR_ITEM (NM_CONNECTIVITY_CANCELLED, "CANCELLED"), + NM_UTILS_LOOKUP_STR_ITEM (NM_CONNECTIVITY_DISPOSING, "DISPOSING"), ); const char * @@ -77,6 +79,10 @@ struct _NMConnectivityCheckHandle { } concheck; #endif + const char *completed_log_message; + char *completed_log_message_free; + NMConnectivityState completed_state; + guint timeout_id; }; @@ -90,6 +96,7 @@ static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { CList handles_lst_head; + CList completed_handles_lst_head; char *uri; char *response; gboolean enabled; @@ -142,60 +149,37 @@ NM_DEFINE_SINGLETON_GETTER (NMConnectivity, nm_connectivity_get, NM_TYPE_CONNECT /*****************************************************************************/ static void -cb_data_invoke_callback (NMConnectivityCheckHandle *cb_data, - NMConnectivityState state, - GError *error, - const char *log_message) +cb_data_complete (NMConnectivityCheckHandle *cb_data, + NMConnectivityState state, + const char *log_message) { - NMConnectivityCheckCallback callback; + NMConnectivity *self; nm_assert (cb_data); nm_assert (NM_IS_CONNECTIVITY (cb_data->self)); - - callback = cb_data->callback; - if (!callback) - return; - - cb_data->callback = NULL; - + nm_assert (cb_data->callback); + nm_assert (state != NM_CONNECTIVITY_UNKNOWN); nm_assert (log_message); - _LOG2D ("check completed: %s; %s", - nm_connectivity_state_to_string (state), - log_message); - - callback (cb_data->self, - cb_data, - state, - error, - cb_data->user_data); -} - -static void -cb_data_free (NMConnectivityCheckHandle *cb_data, - NMConnectivityState state, - GError *error, - const char *log_message) -{ - NMConnectivity *self; - - nm_assert (cb_data); - self = cb_data->self; - nm_assert (NM_IS_CONNECTIVITY (self)); + /* mark the handle as completing. After this point, nm_connectivity_check_cancel() + * is no longer possible. */ + cb_data->self = NULL; - c_list_unlink (&cb_data->handles_lst); + c_list_unlink_stale (&cb_data->handles_lst); #if WITH_CONCHECK if (cb_data->concheck.curl_ehandle) { NMConnectivityPrivate *priv; /* Contrary to what cURL manual claim it is *not* safe to remove - * the easy handle "at any moment"; specifically not from the - * write function. Thus here we just dissociate the cb_data from - * the easy handle and the easy handle will be cleaned up when the - * message goes to CURLMSG_DONE in _con_curl_check_connectivity(). */ + * the easy handle "at any moment"; specifically it's not safe to + * remove *any* handle from within a libcurl callback. That is + * why we queue completed handles in this case. + * + * cb_data_complete() is however only called *not* from within a + * libcurl callback. So, this is fine. */ curl_easy_setopt (cb_data->concheck.curl_ehandle, CURLOPT_WRITEFUNCTION, NULL); curl_easy_setopt (cb_data->concheck.curl_ehandle, CURLOPT_WRITEDATA, NULL); curl_easy_setopt (cb_data->concheck.curl_ehandle, CURLOPT_HEADERFUNCTION, NULL); @@ -214,7 +198,18 @@ cb_data_free (NMConnectivityCheckHandle *cb_data, nm_clear_g_source (&cb_data->timeout_id); - cb_data_invoke_callback (cb_data, state, error, log_message); + _LOG2D ("check completed: %s; %s", + nm_connectivity_state_to_string (state), + log_message); + + cb_data->callback (self, + cb_data, + state, + cb_data->user_data); + + /* Note: self might be a danling pointer at this point. It must not be used + * after this point, and all callers must either take a reference first, or + * not use the self pointer too. */ #if WITH_CONCHECK g_free (cb_data->concheck.response); @@ -222,12 +217,54 @@ cb_data_free (NMConnectivityCheckHandle *cb_data, g_string_free (cb_data->concheck.recv_msg, TRUE); #endif g_free (cb_data->ifspec); + if (cb_data->completed_log_message_free) + g_free (cb_data->completed_log_message_free); g_slice_free (NMConnectivityCheckHandle, cb_data); } /*****************************************************************************/ #if WITH_CONCHECK + +static void +cb_data_queue_completed (NMConnectivityCheckHandle *cb_data, + NMConnectivityState state, + const char *log_message_static, + char *log_message_take /* take */) +{ + nm_assert (cb_data); + nm_assert (NM_IS_CONNECTIVITY (cb_data->self)); + nm_assert (state != NM_CONNECTIVITY_UNKNOWN); + nm_assert (log_message_static || log_message_take); + nm_assert (cb_data->completed_state == NM_CONNECTIVITY_UNKNOWN); + nm_assert (!cb_data->completed_log_message); + nm_assert (c_list_contains (&NM_CONNECTIVITY_GET_PRIVATE (cb_data->self)->handles_lst_head, &cb_data->handles_lst)); + + cb_data->completed_state = state; + cb_data->completed_log_message = log_message_static ?: log_message_take; + cb_data->completed_log_message_free = log_message_take; + + c_list_unlink_stale (&cb_data->handles_lst); + c_list_link_tail (&NM_CONNECTIVITY_GET_PRIVATE (cb_data->self)->completed_handles_lst_head, &cb_data->handles_lst); +} + +static void +_complete_queued (NMConnectivity *self) +{ + NMConnectivity *self_keep_alive = NULL; + NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); + NMConnectivityCheckHandle *cb_data; + + while ((cb_data = c_list_first_entry (&priv->completed_handles_lst_head, NMConnectivityCheckHandle, handles_lst))) { + if (!self_keep_alive) + self_keep_alive = g_object_ref (self); + cb_data_complete (cb_data, + cb_data->completed_state, + cb_data->completed_log_message); + } + nm_g_object_unref (self_keep_alive); +} + static const char * _check_handle_get_response (NMConnectivityCheckHandle *cb_data) { @@ -240,7 +277,7 @@ _con_curl_check_connectivity (CURLM *mhandle, int sockfd, int ev_bitmask) NMConnectivityCheckHandle *cb_data; CURLMsg *msg; CURLcode eret; - int m_left; + gint m_left; long response_code; CURLMcode ret; int running_handles; @@ -265,29 +302,37 @@ _con_curl_check_connectivity (CURLM *mhandle, int sockfd, int ev_bitmask) continue; } - if (!cb_data->callback) { - /* callback was already invoked earlier. */ - cb_data_free (cb_data, NM_CONNECTIVITY_UNKNOWN, NULL, NULL); - } else if (msg->data.result != CURLE_OK) { - gs_free char *log_message = NULL; + nm_assert (cb_data); + nm_assert (NM_IS_CONNECTIVITY (cb_data->self)); - log_message = g_strdup_printf ("check failed with curl status %d", msg->data.result); - cb_data_free (cb_data, NM_CONNECTIVITY_LIMITED, NULL, - log_message); + if (cb_data->completed_state != NM_CONNECTIVITY_UNKNOWN) { + /* callback was already invoked earlier. Nothing to do. */ + continue; + } + + if (msg->data.result != CURLE_OK) { + cb_data_queue_completed (cb_data, + NM_CONNECTIVITY_LIMITED, + NULL, + g_strdup_printf ("check failed with curl status %d", msg->data.result)); } else if ( !((_check_handle_get_response (cb_data))[0]) && (curl_easy_getinfo (msg->easy_handle, CURLINFO_RESPONSE_CODE, &response_code) == CURLE_OK) && response_code == 204) { /* If we got a 204 response code (no content) and we actually * requested no content, report full connectivity. */ - cb_data_free (cb_data, NM_CONNECTIVITY_FULL, NULL, - "no content, as expected"); + cb_data_queue_completed (cb_data, + NM_CONNECTIVITY_FULL, + "no content, as expected", + NULL); } else { /* If we get here, it means that easy_write_cb() didn't read enough * bytes to be able to do a match, or that we were asking for no content * (204 response code) and we actually got some. Either way, that is * an indication of a captive portal */ - cb_data_free (cb_data, NM_CONNECTIVITY_PORTAL, NULL, - "unexpected short response"); + cb_data_queue_completed (cb_data, + NM_CONNECTIVITY_PORTAL, + "unexpected short response", + NULL); } } @@ -306,6 +351,7 @@ _con_curl_timeout_cb (gpointer user_data) priv->concheck.curl_timer = 0; _con_curl_check_connectivity (priv->concheck.curl_mhandle, CURL_SOCKET_TIMEOUT, 0); + _complete_queued (self); return G_SOURCE_REMOVE; } @@ -368,6 +414,8 @@ _con_curl_socketevent_cb (GIOChannel *ch, GIOCondition condition, gpointer user_ fdp->ev = 0; } + _complete_queued (self); + return success ? G_SOURCE_CONTINUE : G_SOURCE_REMOVE; } @@ -419,10 +467,17 @@ easy_header_cb (char *buffer, size_t size, size_t nitems, void *userdata) NMConnectivityCheckHandle *cb_data = userdata; size_t len = size * nitems; + if (cb_data->completed_state != NM_CONNECTIVITY_UNKNOWN) { + /* already completed. */ + return 0; + } + if ( len >= sizeof (HEADER_STATUS_ONLINE) - 1 && !g_ascii_strncasecmp (buffer, HEADER_STATUS_ONLINE, sizeof (HEADER_STATUS_ONLINE) - 1)) { - cb_data_invoke_callback (cb_data, NM_CONNECTIVITY_FULL, - NULL, "status header found"); + cb_data_queue_completed (cb_data, + NM_CONNECTIVITY_FULL, + "status header found", + NULL); return 0; } @@ -434,24 +489,33 @@ easy_write_cb (void *buffer, size_t size, size_t nmemb, void *userdata) { NMConnectivityCheckHandle *cb_data = userdata; size_t len = size * nmemb; - const char *response = _check_handle_get_response (cb_data);; + const char *response; + + if (cb_data->completed_state != NM_CONNECTIVITY_UNKNOWN) { + /* already completed. */ + return 0; + } if (!cb_data->concheck.recv_msg) cb_data->concheck.recv_msg = g_string_sized_new (len + 10); g_string_append_len (cb_data->concheck.recv_msg, buffer, len); + response = _check_handle_get_response (cb_data);; if ( response && cb_data->concheck.recv_msg->len >= strlen (response)) { /* We already have enough data -- check response */ if (g_str_has_prefix (cb_data->concheck.recv_msg->str, response)) { - cb_data_invoke_callback (cb_data, NM_CONNECTIVITY_FULL, NULL, - "expected response"); + cb_data_queue_completed (cb_data, + NM_CONNECTIVITY_FULL, + "expected response", + NULL); } else { - cb_data_invoke_callback (cb_data, NM_CONNECTIVITY_PORTAL, NULL, - "unexpected response"); + cb_data_queue_completed (cb_data, + NM_CONNECTIVITY_PORTAL, + "unexpected response", + NULL); } - return 0; } @@ -462,15 +526,11 @@ static gboolean _timeout_cb (gpointer user_data) { NMConnectivityCheckHandle *cb_data = user_data; - NMConnectivity *self; nm_assert (NM_IS_CONNECTIVITY (cb_data->self)); + nm_assert (c_list_contains (&NM_CONNECTIVITY_GET_PRIVATE (cb_data->self)->handles_lst_head, &cb_data->handles_lst)); - self = cb_data->self; - - nm_assert (c_list_contains (&NM_CONNECTIVITY_GET_PRIVATE (self)->handles_lst_head, &cb_data->handles_lst)); - - cb_data_free (cb_data, NM_CONNECTIVITY_LIMITED, NULL, "timeout"); + cb_data_complete (cb_data, NM_CONNECTIVITY_LIMITED, "timeout"); return G_SOURCE_REMOVE; } #endif @@ -490,9 +550,9 @@ _idle_cb (gpointer user_data) /* the invocation was with an invalid ifname. It is a fail. */ g_set_error (&error, NM_UTILS_ERROR, NM_UTILS_ERROR_INVALID_ARGUMENT, "no interface specified for connectivity check"); - cb_data_free (cb_data, NM_CONNECTIVITY_ERROR, NULL, "missing interface"); + cb_data_complete (cb_data, NM_CONNECTIVITY_ERROR, "missing interface"); } else - cb_data_free (cb_data, NM_CONNECTIVITY_FAKE, NULL, "fake result"); + cb_data_complete (cb_data, NM_CONNECTIVITY_FAKE, "fake result"); return G_SOURCE_REMOVE; } @@ -516,6 +576,7 @@ nm_connectivity_check_start (NMConnectivity *self, c_list_link_tail (&priv->handles_lst_head, &cb_data->handles_lst); cb_data->callback = callback; cb_data->user_data = user_data; + cb_data->completed_state = NM_CONNECTIVITY_UNKNOWN; if (iface) cb_data->ifspec = g_strdup_printf ("if!%s", iface); @@ -556,22 +617,13 @@ nm_connectivity_check_start (NMConnectivity *self, void nm_connectivity_check_cancel (NMConnectivityCheckHandle *cb_data) { - NMConnectivity *self; - gs_free_error GError *error = NULL; - g_return_if_fail (cb_data); + g_return_if_fail (NM_IS_CONNECTIVITY (cb_data->self)); - self = cb_data->self; - - g_return_if_fail (NM_IS_CONNECTIVITY (self)); - g_return_if_fail (!c_list_is_empty (&cb_data->handles_lst)); - g_return_if_fail (cb_data->callback); - - nm_assert (c_list_contains (&NM_CONNECTIVITY_GET_PRIVATE (self)->handles_lst_head, &cb_data->handles_lst)); + nm_assert ( c_list_contains (&NM_CONNECTIVITY_GET_PRIVATE (cb_data->self)->handles_lst_head, &cb_data->handles_lst) + || c_list_contains (&NM_CONNECTIVITY_GET_PRIVATE (cb_data->self)->completed_handles_lst_head, &cb_data->handles_lst)); - nm_utils_error_set_cancelled (&error, FALSE, "NMConnectivity"); - - cb_data_free (cb_data, NM_CONNECTIVITY_ERROR, error, "cancelled"); + cb_data_complete (cb_data, NM_CONNECTIVITY_CANCELLED, "cancelled"); } /*****************************************************************************/ @@ -684,6 +736,7 @@ nm_connectivity_init (NMConnectivity *self) NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); c_list_init (&priv->handles_lst_head); + c_list_init (&priv->completed_handles_lst_head); priv->config = g_object_ref (nm_config_get ()); g_signal_connect (G_OBJECT (priv->config), @@ -715,16 +768,13 @@ dispose (GObject *object) NMConnectivity *self = NM_CONNECTIVITY (object); NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self); NMConnectivityCheckHandle *cb_data; - GError *error = NULL; - -again: - c_list_for_each_entry (cb_data, &priv->handles_lst_head, handles_lst) { - if (!error) - nm_utils_error_set_cancelled (&error, TRUE, "NMConnectivity"); - cb_data_free (cb_data, NM_CONNECTIVITY_ERROR, error, "shutting down"); - goto again; - } - g_clear_error (&error); + + nm_assert (c_list_is_empty (&priv->completed_handles_lst_head)); + + while ((cb_data = c_list_first_entry (&priv->handles_lst_head, + NMConnectivityCheckHandle, + handles_lst))) + cb_data_complete (cb_data, NM_CONNECTIVITY_DISPOSING, "shutting down"); g_clear_pointer (&priv->uri, g_free); g_clear_pointer (&priv->response, g_free); diff --git a/src/nm-connectivity.h b/src/nm-connectivity.h index df9295e0..178f27ad 100644 --- a/src/nm-connectivity.h +++ b/src/nm-connectivity.h @@ -24,8 +24,10 @@ #include "nm-dbus-interface.h" -#define NM_CONNECTIVITY_ERROR ((NMConnectivityState) -1) -#define NM_CONNECTIVITY_FAKE ((NMConnectivityState) -2) +#define NM_CONNECTIVITY_ERROR ((NMConnectivityState) -1) +#define NM_CONNECTIVITY_FAKE ((NMConnectivityState) -2) +#define NM_CONNECTIVITY_CANCELLED ((NMConnectivityState) -3) +#define NM_CONNECTIVITY_DISPOSING ((NMConnectivityState) -4) #define NM_TYPE_CONNECTIVITY (nm_connectivity_get_type ()) #define NM_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTIVITY, NMConnectivity)) @@ -53,7 +55,6 @@ typedef struct _NMConnectivityCheckHandle NMConnectivityCheckHandle; typedef void (*NMConnectivityCheckCallback) (NMConnectivity *self, NMConnectivityCheckHandle *handle, NMConnectivityState state, - GError *error, gpointer user_data); NMConnectivityCheckHandle *nm_connectivity_check_start (NMConnectivity *self, diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index ca8c9526..54ccdb83 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright 2004 - 2018 Red Hat, Inc. + * Copyright 2004 - 2014 Red Hat, Inc. * Copyright 2005 - 2008 Novell, Inc. */ @@ -25,7 +25,6 @@ #include <errno.h> #include <fcntl.h> -#include <fnmatch.h> #include <string.h> #include <unistd.h> #include <stdlib.h> @@ -38,7 +37,6 @@ #include <net/ethernet.h> #include "nm-utils/nm-random-utils.h" -#include "nm-utils/nm-io-utils.h" #include "nm-utils.h" #include "nm-core-internal.h" #include "nm-setting-connection.h" @@ -47,6 +45,15 @@ #include "nm-setting-wireless.h" #include "nm-setting-wireless-security.h" +/* + * Some toolchains (E.G. uClibc 0.9.33 and earlier) don't export + * CLOCK_BOOTTIME even though the kernel supports it, so provide a + * local definition + */ +#ifndef CLOCK_BOOTTIME +#define CLOCK_BOOTTIME 7 +#endif + G_STATIC_ASSERT (sizeof (NMUtilsTestFlags) <= sizeof (int)); static int _nm_utils_testing = 0; @@ -525,7 +532,7 @@ _kc_waited_to_string (char *buf, gint64 wait_start_us) } static void -_kc_cb_watch_child (GPid pid, int status, gpointer user_data) +_kc_cb_watch_child (GPid pid, gint status, gpointer user_data) { KillChildAsyncData *data = user_data; char buf_exit[KC_EXIT_TO_STRING_BUF_SIZE], buf_wait[KC_WAITED_TO_STRING]; @@ -1448,7 +1455,7 @@ match_config_eval (const char *str, const char *tag, guint cur_nm_version) { gs_free char *s_ver = NULL; gs_strfreev char **s_ver_tokens = NULL; - int v_maj = -1, v_min = -1, v_mic = -1; + gint v_maj = -1, v_min = -1, v_mic = -1; guint c_maj = -1, c_min = -1, c_mic = -1; guint n_tokens; @@ -1580,9 +1587,9 @@ nm_match_spec_split (const char *value) /* Copied from glibs g_key_file_parse_value_as_string() function * and adjusted. */ - string_value = g_new (char, strlen (value) + 1); + string_value = g_new (gchar, strlen (value) + 1); - p = (char *) value; + p = (gchar *) value; /* skip over leading whitespace */ while (g_ascii_isspace (*p)) @@ -1732,33 +1739,6 @@ nm_match_spec_join (GSList *specs) return g_string_free (str, FALSE); } -gboolean -nm_wildcard_match_check (const char *str, - const char *const *patterns, - guint num_patterns) -{ - guint i, neg = 0; - - for (i = 0; i < num_patterns; i++) { - if (patterns[i][0] == '!') { - neg++; - if (!fnmatch (patterns[i] + 1, str, 0)) - return FALSE; - } - } - - if (neg == num_patterns) - return TRUE; - - for (i = 0; i < num_patterns; i++) { - if ( patterns[i][0] != '!' - && !fnmatch (patterns[i], str, 0)) - return TRUE; - } - - return FALSE; -} - /*****************************************************************************/ char * @@ -2056,7 +2036,7 @@ typedef struct NMSettingDiffResult diff_result; } LogConnectionSettingItem; -static int +static gint _log_connection_sort_hashes_fcn (gconstpointer a, gconstpointer b) { const LogConnectionSettingData *v1 = a; @@ -2099,7 +2079,7 @@ _log_connection_sort_hashes (NMConnection *connection, NMConnection *diff_base, return sorted_hashes; } -static int +static gint _log_connection_sort_names_fcn (gconstpointer a, gconstpointer b) { const LogConnectionSettingItem *v1 = a; @@ -2561,6 +2541,262 @@ nm_utils_machine_id_read (void) /*****************************************************************************/ +_nm_printf (3, 4) +static int +_get_contents_error (GError **error, int errsv, const char *format, ...) +{ + if (errsv < 0) + errsv = -errsv; + else if (!errsv) + errsv = errno; + + if (error) { + char *msg; + va_list args; + + va_start (args, format); + msg = g_strdup_vprintf (format, args); + va_end (args); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errsv), + "%s: %s", + msg, g_strerror (errsv)); + g_free (msg); + } + return -errsv; +} + +/** + * nm_utils_fd_get_contents: + * @fd: open file descriptor to read. The fd will not be closed, + * but don't rely on its state afterwards. + * @close_fd: if %TRUE, @fd will be closed by the function. + * Passing %TRUE here might safe a syscall for dup(). + * @max_length: allocate at most @max_length bytes. If the + * file is larger, reading will fail. Set to zero to use + * a very large default. + * + * WARNING: @max_length is here to avoid a crash for huge/unlimited files. + * For example, stat(/sys/class/net/enp0s25/ifindex) gives a filesize of + * 4K, although the actual real is small. @max_length is the memory + * allocated in the process of reading the file, thus it must be at least + * the size reported by fstat. + * If you set it to 1K, read will fail because fstat() claims the + * file is larger. + * + * @contents: the output buffer with the file read. It is always + * NUL terminated. The buffer is at most @max_length long, including + * the NUL byte. That is, it reads only files up to a length of + * @max_length - 1 bytes. + * @length: optional output argument of the read file size. + * + * A reimplementation of g_file_get_contents() with a few differences: + * - accepts an open fd, instead of a path name. This allows you to + * use openat(). + * - limits the maxium filesize to max_length. + * + * Returns: a negative error code on failure. + */ +int +nm_utils_fd_get_contents (int fd, + gboolean close_fd, + gsize max_length, + char **contents, + gsize *length, + GError **error) +{ + nm_auto_close int fd_keeper = close_fd ? fd : -1; + struct stat stat_buf; + gs_free char *str = NULL; + + g_return_val_if_fail (fd >= 0, -EINVAL); + g_return_val_if_fail (contents, -EINVAL); + g_return_val_if_fail (!error || !*error, -EINVAL); + + if (fstat (fd, &stat_buf) < 0) + return _get_contents_error (error, 0, "failure during fstat"); + + if (!max_length) { + /* default to a very large size, but not extreme */ + max_length = 2 * 1024 * 1024; + } + + if ( stat_buf.st_size > 0 + && S_ISREG (stat_buf.st_mode)) { + const gsize n_stat = stat_buf.st_size; + ssize_t n_read; + + if (n_stat > max_length - 1) + return _get_contents_error (error, EMSGSIZE, "file too large (%zu+1 bytes with maximum %zu bytes)", n_stat, max_length); + + str = g_try_malloc (n_stat + 1); + if (!str) + return _get_contents_error (error, ENOMEM, "failure to allocate buffer of %zu+1 bytes", n_stat); + + n_read = nm_utils_fd_read_loop (fd, str, n_stat, TRUE); + if (n_read < 0) + return _get_contents_error (error, n_read, "error reading %zu bytes from file descriptor", n_stat); + str[n_read] = '\0'; + + if (n_read < n_stat) { + char *tmp; + + tmp = g_try_realloc (str, n_read + 1); + if (!tmp) + return _get_contents_error (error, ENOMEM, "failure to reallocate buffer with %zu bytes", n_read + 1); + str = tmp; + } + NM_SET_OUT (length, n_read); + } else { + nm_auto_fclose FILE *f = NULL; + char buf[4096]; + gsize n_have, n_alloc; + int fd2; + + if (fd_keeper >= 0) + fd2 = nm_steal_fd (&fd_keeper); + else { + fd2 = fcntl (fd, F_DUPFD_CLOEXEC, 0); + if (fd2 < 0) + return _get_contents_error (error, 0, "error during dup"); + } + + if (!(f = fdopen (fd2, "r"))) { + nm_close (fd2); + return _get_contents_error (error, 0, "failure during fdopen"); + } + + n_have = 0; + n_alloc = 0; + + while (!feof (f)) { + int errsv; + gsize n_read; + + n_read = fread (buf, 1, sizeof (buf), f); + errsv = errno; + if (ferror (f)) + return _get_contents_error (error, errsv, "error during fread"); + + if ( n_have > G_MAXSIZE - 1 - n_read + || n_have + n_read + 1 > max_length) { + return _get_contents_error (error, EMSGSIZE, "file stream too large (%zu+1 bytes with maximum %zu bytes)", + (n_have > G_MAXSIZE - 1 - n_read) ? G_MAXSIZE : n_have + n_read, + max_length); + } + + if (n_have + n_read + 1 >= n_alloc) { + char *tmp; + + if (str) { + if (n_alloc >= max_length / 2) + n_alloc = max_length; + else + n_alloc *= 2; + } else + n_alloc = NM_MIN (n_read + 1, sizeof (buf)); + + tmp = g_try_realloc (str, n_alloc); + if (!tmp) + return _get_contents_error (error, ENOMEM, "failure to allocate buffer of %zu bytes", n_alloc); + str = tmp; + } + + memcpy (str + n_have, buf, n_read); + n_have += n_read; + } + + if (n_alloc == 0) + str = g_new0 (gchar, 1); + else { + str[n_have] = '\0'; + if (n_have + 1 < n_alloc) { + char *tmp; + + tmp = g_try_realloc (str, n_have + 1); + if (!tmp) + return _get_contents_error (error, ENOMEM, "failure to truncate buffer to %zu bytes", n_have + 1); + str = tmp; + } + } + + NM_SET_OUT (length, n_have); + } + + *contents = g_steal_pointer (&str); + return 0; +} + +/** + * nm_utils_file_get_contents: + * @dirfd: optional file descriptor to use openat(). If negative, use plain open(). + * @filename: the filename to open. Possibly relative to @dirfd. + * @max_length: allocate at most @max_length bytes. + * WARNING: see nm_utils_fd_get_contents() hint about @max_length. + * @contents: the output buffer with the file read. It is always + * NUL terminated. The buffer is at most @max_length long, including + * the NUL byte. That is, it reads only files up to a length of + * @max_length - 1 bytes. + * @length: optional output argument of the read file size. + * + * A reimplementation of g_file_get_contents() with a few differences: + * - accepts an @dirfd to open @filename relative to that path via openat(). + * - limits the maxium filesize to max_length. + * - uses O_CLOEXEC on internal file descriptor + * + * Returns: a negative error code on failure. + */ +int +nm_utils_file_get_contents (int dirfd, + const char *filename, + gsize max_length, + char **contents, + gsize *length, + GError **error) +{ + int fd; + int errsv; + + g_return_val_if_fail (filename && filename[0], -EINVAL); + + if (dirfd >= 0) { + fd = openat (dirfd, filename, O_RDONLY | O_CLOEXEC); + if (fd < 0) { + errsv = errno; + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errsv), + "Failed to open file \"%s\" with openat: %s", + filename, + g_strerror (errsv)); + return -errsv; + } + } else { + fd = open (filename, O_RDONLY | O_CLOEXEC); + if (fd < 0) { + errsv = errno; + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errsv), + "Failed to open file \"%s\": %s", + filename, + g_strerror (errsv)); + return -errsv; + } + } + return nm_utils_fd_get_contents (fd, + TRUE, + max_length, + contents, + length, + error); +} + +/*****************************************************************************/ + static gboolean _secret_key_read (guint8 **out_secret_key, gsize *out_key_len) @@ -2687,7 +2923,6 @@ nm_utils_get_boot_id (void) gs_free char *contents = NULL; nm_utils_file_get_contents (-1, "/proc/sys/kernel/random/boot_id", 0, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, &contents, NULL, NULL); if (contents) { g_strstrip (contents); @@ -2782,6 +3017,7 @@ nm_utils_get_ipv6_interface_identifier (NMLinkType link_type, out_iid->id_u8[0] |= 0x02; return TRUE; case NM_LINK_TYPE_GRE: + case NM_LINK_TYPE_GRETAP: /* Hardware address is the network-endian IPv4 address */ g_return_val_if_fail (hwaddr_len == 4, FALSE); addr = * (guint32 *) hwaddr; @@ -2791,11 +3027,6 @@ nm_utils_get_ipv6_interface_identifier (NMLinkType link_type, out_iid->id_u8[3] = 0xFE; memcpy (out_iid->id_u8 + 4, &addr, 4); return TRUE; - case NM_LINK_TYPE_6LOWPAN: - /* The hardware address is already 64-bit. This is the case for - * IEEE 802.15.4 networks. */ - memcpy (out_iid->id_u8, hwaddr, sizeof (out_iid->id_u8)); - return TRUE; default: if (hwaddr_len == ETH_ALEN) { /* Translate 48-bit MAC address to a 64-bit Modified EUI-64. See @@ -3430,8 +3661,8 @@ nm_utils_g_value_set_strv (GValue *value, GPtrArray *strings) /*****************************************************************************/ static gboolean -debug_key_matches (const char *key, - const char *token, +debug_key_matches (const gchar *key, + const gchar *token, guint length) { /* may not call GLib functions: see note in g_parse_debug_string() */ @@ -3733,12 +3964,116 @@ nm_utils_get_reverse_dns_domains_ip6 (const struct in6_addr *ip, guint8 plen, GP #undef N_SHIFT } +/** + * Copied from GLib's g_file_set_contents() et al., but allows + * specifying a mode for the new file. + */ +gboolean +nm_utils_file_set_contents (const gchar *filename, + const gchar *contents, + gssize length, + mode_t mode, + GError **error) +{ + gs_free char *tmp_name = NULL; + struct stat statbuf; + int errsv; + gssize s; + int fd; + + g_return_val_if_fail (filename, FALSE); + g_return_val_if_fail (contents || !length, FALSE); + g_return_val_if_fail (!error || !*error, FALSE); + g_return_val_if_fail (length >= -1, FALSE); + + if (length == -1) + length = strlen (contents); + + tmp_name = g_strdup_printf ("%s.XXXXXX", filename); + fd = g_mkstemp_full (tmp_name, O_RDWR, mode); + if (fd < 0) { + errsv = errno; + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errsv), + "failed to create file %s: %s", + tmp_name, + g_strerror (errsv)); + return FALSE; + } + + while (length > 0) { + s = write (fd, contents, length); + if (s < 0) { + errsv = errno; + if (errsv == EINTR) + continue; + + nm_close (fd); + unlink (tmp_name); + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errsv), + "failed to write to file %s: %s", + tmp_name, + g_strerror (errsv)); + return FALSE; + } + + g_assert (s <= length); + + contents += s; + length -= s; + } + + /* If the final destination exists and is > 0 bytes, we want to sync the + * newly written file to ensure the data is on disk when we rename over + * the destination. Otherwise if we get a system crash we can lose both + * the new and the old file on some filesystems. (I.E. those that don't + * guarantee the data is written to the disk before the metadata.) + */ + if ( lstat (filename, &statbuf) == 0 + && statbuf.st_size > 0 + && fsync (fd) != 0) { + errsv = errno; + + nm_close (fd); + unlink (tmp_name); + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errsv), + "failed to fsync %s: %s", + tmp_name, + g_strerror (errsv)); + return FALSE; + } + + nm_close (fd); + + if (rename (tmp_name, filename)) { + errsv = errno; + unlink (tmp_name); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errsv), + "failed to rename %s to %s: %s", + tmp_name, + filename, + g_strerror (errsv)); + return FALSE; + } + + return TRUE; +} + struct plugin_info { char *path; struct stat st; }; -static int +static gint read_device_factory_paths_sort_fcn (gconstpointer a, gconstpointer b) { const struct plugin_info *da = a; diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 30d1360a..08530400 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -204,9 +204,9 @@ typedef enum { NMMatchSpecMatchType nm_match_spec_device (const GSList *specs, const char *interface_name, - const char *device_type, const char *driver, const char *driver_version, + const char *device_type, const char *hwaddr, const char *s390_subchannels); NMMatchSpecMatchType nm_match_spec_config (const GSList *specs, @@ -215,10 +215,6 @@ NMMatchSpecMatchType nm_match_spec_config (const GSList *specs, GSList *nm_match_spec_split (const char *value); char *nm_match_spec_join (GSList *specs); -gboolean nm_wildcard_match_check (const char *str, - const char *const *patterns, - guint num_patterns); - /*****************************************************************************/ const char *nm_utils_get_ip_config_method (NMConnection *connection, @@ -264,6 +260,26 @@ gboolean nm_utils_sysctl_ip_conf_is_path (int addr_family, const char *path, con gboolean nm_utils_is_specific_hostname (const char *name); +int nm_utils_fd_get_contents (int fd, + gboolean close_fd, + gsize max_length, + char **contents, + gsize *length, + GError **error); + +int nm_utils_file_get_contents (int dirfd, + const char *filename, + gsize max_length, + char **contents, + gsize *length, + GError **error); + +gboolean nm_utils_file_set_contents (const gchar *filename, + const gchar *contents, + gssize length, + mode_t mode, + GError **error); + char *nm_utils_machine_id_read (void); gboolean nm_utils_machine_id_parse (const char *id_str, /*uuid_t*/ guchar *out_uuid); diff --git a/src/nm-dbus-manager.c b/src/nm-dbus-manager.c index 0a421aa9..7f1121f6 100644 --- a/src/nm-dbus-manager.c +++ b/src/nm-dbus-manager.c @@ -1084,7 +1084,7 @@ _obj_unregister (NMDBusManager *self, NULL); } -gpointer +NMDBusObject * nm_dbus_manager_lookup_object (NMDBusManager *self, const char *path) { NMDBusManagerPrivate *priv; diff --git a/src/nm-dbus-manager.h b/src/nm-dbus-manager.h index 04c42bb0..a0741316 100644 --- a/src/nm-dbus-manager.h +++ b/src/nm-dbus-manager.h @@ -61,7 +61,7 @@ gboolean nm_dbus_manager_is_stopping (NMDBusManager *self); GDBusConnection *nm_dbus_manager_get_connection (NMDBusManager *self); -gpointer nm_dbus_manager_lookup_object (NMDBusManager *self, const char *path); +NMDBusObject *nm_dbus_manager_lookup_object (NMDBusManager *self, const char *path); void _nm_dbus_manager_obj_export (NMDBusObject *obj); void _nm_dbus_manager_obj_unexport (NMDBusObject *obj); diff --git a/src/nm-dcb.c b/src/nm-dcb.c index 5a46fa00..140e7c36 100644 --- a/src/nm-dcb.c +++ b/src/nm-dcb.c @@ -104,7 +104,7 @@ G_STMT_START { \ #define SET_APP(f, s, tag) \ G_STMT_START { \ - int prio = nm_setting_dcb_get_app_##tag##_priority (s); \ + gint prio = nm_setting_dcb_get_app_##tag##_priority (s); \ \ SET_FLAGS (f, "app:" #tag); \ if ((f & NM_SETTING_DCB_FLAG_ENABLE) && (prio >= 0)) { \ diff --git a/src/nm-hostname-manager.c b/src/nm-hostname-manager.c index 88ff1604..f569ab86 100644 --- a/src/nm-hostname-manager.c +++ b/src/nm-hostname-manager.c @@ -48,7 +48,8 @@ #define HOSTNAME_FILE_UCASE_HOSTNAME "/etc/HOSTNAME" #define HOSTNAME_FILE_GENTOO "/etc/conf.d/hostname" -#define CONF_DHCP SYSCONFDIR "/sysconfig/network/dhcp" +#define IFCFG_DIR SYSCONFDIR "/sysconfig/network" +#define CONF_DHCP IFCFG_DIR "/dhcp" #if (defined(HOSTNAME_PERSIST_SUSE) + defined(HOSTNAME_PERSIST_SLACKWARE) + defined(HOSTNAME_PERSIST_GENTOO)) > 1 #error "Can only define one of HOSTNAME_PERSIST_*" @@ -102,7 +103,7 @@ NM_DEFINE_SINGLETON_GETTER (NMHostnameManager, nm_hostname_manager_get, NM_TYPE_ /*****************************************************************************/ #if defined(HOSTNAME_PERSIST_GENTOO) -static char * +static gchar * read_hostname_gentoo (const char *path) { gs_free char *contents = NULL; @@ -128,7 +129,7 @@ read_hostname_gentoo (const char *path) #endif #if defined(HOSTNAME_PERSIST_SLACKWARE) -static char * +static gchar * read_hostname_slackware (const char *path) { gs_free char *contents = NULL; diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index 805c6e4f..308c9e1f 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -380,7 +380,7 @@ int main (int argc, char *argv[]) { char *bad_domains = NULL; - gs_free_error GError *error = NULL; + GError *error = NULL; gboolean wrote_pidfile = FALSE; gs_free char *pidfile = NULL; gs_unref_object NMDhcpClient *dhcp4_client = NULL; @@ -516,11 +516,8 @@ main (int argc, char *argv[]) client_id, NM_DHCP_TIMEOUT_DEFAULT, NULL, - global_opt.dhcp4_address, - &error); - if (!dhcp4_client) - g_error ("failure to start DHCP: %s", error->message); - + global_opt.dhcp4_address); + g_assert (dhcp4_client); g_signal_connect (dhcp4_client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (dhcp4_state_changed), diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 573c479a..657ebfc0 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -278,12 +278,10 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMIP4Config, PROP_ROUTE_DATA, PROP_ROUTES, PROP_GATEWAY, - PROP_NAMESERVER_DATA, PROP_NAMESERVERS, PROP_DOMAINS, PROP_SEARCHES, PROP_DNS_OPTIONS, - PROP_WINS_SERVER_DATA, PROP_WINS_SERVERS, PROP_DNS_PRIORITY, ); @@ -293,9 +291,8 @@ typedef struct { guint32 mtu; int ifindex; NMIPConfigSource mtu_source; - int dns_priority; + gint dns_priority; NMSettingConnectionMdns mdns; - NMSettingConnectionLlmnr llmnr; GArray *nameservers; GPtrArray *domains; GPtrArray *searches; @@ -512,8 +509,8 @@ _notify_addresses (NMIP4Config *self) nm_clear_g_variant (&priv->address_data_variant); nm_clear_g_variant (&priv->addresses_variant); - nm_gobject_notify_together (self, PROP_ADDRESS_DATA, - PROP_ADDRESSES); + _notify (self, PROP_ADDRESS_DATA); + _notify (self, PROP_ADDRESSES); } static void @@ -524,13 +521,13 @@ _notify_routes (NMIP4Config *self) nm_assert (priv->best_default_route == _nm_ip4_config_best_default_route_find (self)); nm_clear_g_variant (&priv->route_data_variant); nm_clear_g_variant (&priv->routes_variant); - nm_gobject_notify_together (self, PROP_ROUTE_DATA, - PROP_ROUTES); + _notify (self, PROP_ROUTE_DATA); + _notify (self, PROP_ROUTES); } /*****************************************************************************/ -static int +static gint _addresses_sort_cmp_get_prio (in_addr_t addr) { if (nm_utils_ip4_address_is_link_local (addr)) @@ -541,7 +538,7 @@ _addresses_sort_cmp_get_prio (in_addr_t addr) static int _addresses_sort_cmp (gconstpointer a, gconstpointer b, gpointer user_data) { - int p1, p2; + gint p1, p2; const NMPlatformIP4Address *a1 = NMP_OBJECT_CAST_IP4_ADDRESS (*((const NMPObject **) a)); const NMPlatformIP4Address *a2 = NMP_OBJECT_CAST_IP4_ADDRESS (*((const NMPObject **) b)); guint32 n1, n2; @@ -917,7 +914,6 @@ void nm_ip4_config_merge_setting (NMIP4Config *self, NMSettingIPConfig *setting, NMSettingConnectionMdns mdns, - NMSettingConnectionLlmnr llmnr, guint32 route_table, guint32 route_metric) { @@ -1035,7 +1031,6 @@ nm_ip4_config_merge_setting (NMIP4Config *self, nm_ip4_config_set_dns_priority (self, priority); nm_ip4_config_mdns_set (self, mdns); - nm_ip4_config_llmnr_set (self, llmnr); g_object_thaw_notify (G_OBJECT (self)); } @@ -1256,10 +1251,6 @@ nm_ip4_config_merge (NMIP4Config *dst, nm_ip4_config_mdns_set (dst, NM_MAX (nm_ip4_config_mdns_get (src), nm_ip4_config_mdns_get (dst))); - /* LLMNR */ - nm_ip4_config_llmnr_set (dst, - NM_MAX (nm_ip4_config_llmnr_get (src), - nm_ip4_config_llmnr_get (dst))); g_object_thaw_notify (G_OBJECT (dst)); } @@ -1376,7 +1367,7 @@ nm_ip4_config_subtract (NMIP4Config *dst, { NMIP4ConfigPrivate *dst_priv; guint i; - int idx; + gint idx; const NMPlatformIP4Address *a; const NMPlatformIP4Route *r; NMDedupMultiIter ipconf_iter; @@ -1501,10 +1492,6 @@ nm_ip4_config_subtract (NMIP4Config *dst, if (nm_ip4_config_mdns_get (src) == nm_ip4_config_mdns_get (dst)) nm_ip4_config_mdns_set (dst, NM_SETTING_CONNECTION_MDNS_DEFAULT); - /* LLMNR */ - if (nm_ip4_config_llmnr_get (src) == nm_ip4_config_llmnr_get (dst)) - nm_ip4_config_llmnr_set (dst, NM_SETTING_CONNECTION_LLMNR_DEFAULT); - g_object_thaw_notify (G_OBJECT (dst)); } @@ -1606,7 +1593,6 @@ _nm_ip4_config_intersect_helper (NMIP4Config *dst, /* ignore NIS */ /* ignore WINS */ /* ignore mdns */ - /* ignore LLMNR */ if (update_dst) g_object_thaw_notify (G_OBJECT (dst)); @@ -1885,15 +1871,7 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev has_relevant_changes = TRUE; } - if (src_priv->mdns != dst_priv->mdns) { - dst_priv->mdns = src_priv->mdns; - has_relevant_changes = TRUE; - } - - if (src_priv->llmnr != dst_priv->llmnr) { - dst_priv->llmnr = src_priv->llmnr; - has_relevant_changes = TRUE; - } + dst_priv->mdns = src_priv->mdns; /* DNS priority */ if (src_priv->dns_priority != dst_priv->dns_priority) { @@ -2329,8 +2307,7 @@ nm_ip4_config_reset_nameservers (NMIP4Config *self) if (priv->nameservers->len != 0) { g_array_set_size (priv->nameservers, 0); - nm_gobject_notify_together (self, PROP_NAMESERVER_DATA, - PROP_NAMESERVERS); + _notify (self, PROP_NAMESERVERS); } } @@ -2347,8 +2324,7 @@ nm_ip4_config_add_nameserver (NMIP4Config *self, guint32 new) return; g_array_append_val (priv->nameservers, new); - nm_gobject_notify_together (self, PROP_NAMESERVER_DATA, - PROP_NAMESERVERS); + _notify (self, PROP_NAMESERVERS); } void @@ -2359,8 +2335,7 @@ nm_ip4_config_del_nameserver (NMIP4Config *self, guint i) g_return_if_fail (i < priv->nameservers->len); g_array_remove_index (priv->nameservers, i); - nm_gobject_notify_together (self, PROP_NAMESERVER_DATA, - PROP_NAMESERVERS); + _notify (self, PROP_NAMESERVERS); } guint @@ -2582,23 +2557,10 @@ nm_ip4_config_mdns_set (NMIP4Config *self, NM_IP4_CONFIG_GET_PRIVATE (self)->mdns = mdns; } -NMSettingConnectionLlmnr -nm_ip4_config_llmnr_get (const NMIP4Config *self) -{ - return NM_IP4_CONFIG_GET_PRIVATE (self)->llmnr; -} - -void -nm_ip4_config_llmnr_set (NMIP4Config *self, - NMSettingConnectionLlmnr llmnr) -{ - NM_IP4_CONFIG_GET_PRIVATE (self)->llmnr = llmnr; -} - /*****************************************************************************/ void -nm_ip4_config_set_dns_priority (NMIP4Config *self, int priority) +nm_ip4_config_set_dns_priority (NMIP4Config *self, gint priority) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); @@ -2608,7 +2570,7 @@ nm_ip4_config_set_dns_priority (NMIP4Config *self, int priority) } } -int +gint nm_ip4_config_get_dns_priority (const NMIP4Config *self) { const NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); @@ -2691,8 +2653,7 @@ nm_ip4_config_reset_wins (NMIP4Config *self) if (priv->wins->len != 0) { g_array_set_size (priv->wins, 0); - nm_gobject_notify_together (self, PROP_WINS_SERVER_DATA, - PROP_WINS_SERVERS); + _notify (self, PROP_WINS_SERVERS); } } @@ -2709,8 +2670,7 @@ nm_ip4_config_add_wins (NMIP4Config *self, guint32 wins) return; g_array_append_val (priv->wins, wins); - nm_gobject_notify_together (self, PROP_WINS_SERVER_DATA, - PROP_WINS_SERVERS); + _notify (self, PROP_WINS_SERVERS); } void @@ -2721,8 +2681,7 @@ nm_ip4_config_del_wins (NMIP4Config *self, guint i) g_return_if_fail (i < priv->wins->len); g_array_remove_index (priv->wins, i); - nm_gobject_notify_together (self, PROP_WINS_SERVER_DATA, - PROP_WINS_SERVERS); + _notify (self, PROP_WINS_SERVERS); } guint @@ -2884,7 +2843,6 @@ nm_ip4_config_hash (const NMIP4Config *self, GChecksum *sum, gboolean dns_only) NMDedupMultiIter ipconf_iter; const NMPlatformIP4Address *address; const NMPlatformIP4Route *route; - int val; g_return_if_fail (self); g_return_if_fail (sum); @@ -2931,25 +2889,6 @@ nm_ip4_config_hash (const NMIP4Config *self, GChecksum *sum, gboolean dns_only) s = nm_ip4_config_get_dns_option (self, i); g_checksum_update (sum, (const guint8 *) s, strlen (s)); } - - val = nm_ip4_config_mdns_get (self); - if (val != NM_SETTING_CONNECTION_MDNS_DEFAULT) - g_checksum_update (sum, (const guint8 *) &val, sizeof (val)); - - val = nm_ip4_config_llmnr_get (self); - if (val != NM_SETTING_CONNECTION_LLMNR_DEFAULT) - g_checksum_update (sum, (const guint8 *) &val, sizeof (val)); - - /* FIXME(ip-config-checksum): the DNS priority should be considered relevant - * and added into the checksum as well, but this can't be done right now - * because in the DNS manager we rely on the fact that an empty - * configuration (i.e. just created) has a zero checksum. This is needed to - * avoid rewriting resolv.conf when there is no change. - * - * The DNS priority initial value depends on the connection type (VPN or - * not), so it's a bit difficult to add it to checksum maintaining the - * assumption of checksum(empty)=0 - */ } /** @@ -3005,7 +2944,6 @@ get_property (GObject *object, guint prop_id, NMDedupMultiIter ipconf_iter; const NMPlatformIP4Route *route; GVariantBuilder builder_data, builder_legacy; - guint i; switch (prop_id) { case PROP_IFINDEX: @@ -3024,7 +2962,7 @@ get_property (GObject *object, guint prop_id, head_entry = nm_ip4_config_lookup_addresses (self); if (head_entry) { gs_free const NMPObject **addresses = NULL; - guint naddr; + guint naddr, i; addresses = (const NMPObject **) nm_dedup_multi_objs_to_array_head (head_entry, NULL, NULL, &naddr); nm_assert (addresses && naddr); @@ -3160,26 +3098,6 @@ out_routes_cached: } else g_value_set_string (value, NULL); break; - case PROP_NAMESERVER_DATA: - g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("aa{sv}")); - - for (i = 0; i < priv->nameservers->len; i++) { - GVariantBuilder nested_builder; - char addr_str[NM_UTILS_INET_ADDRSTRLEN]; - - nm_utils_inet4_ntop (g_array_index (priv->nameservers, in_addr_t, i), - addr_str); - - g_variant_builder_init (&nested_builder, G_VARIANT_TYPE ("a{sv}")); - g_variant_builder_add (&nested_builder, "{sv}", - "address", - g_variant_new_string (addr_str)); - g_variant_builder_add (&builder_data, "a{sv}", &nested_builder); - } - - g_value_take_variant (value, - g_variant_builder_end (&builder_data)); - break; case PROP_NAMESERVERS: g_value_take_variant (value, g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, @@ -3199,19 +3117,6 @@ out_routes_cached: case PROP_DNS_PRIORITY: g_value_set_int (value, priv->dns_priority); break; - case PROP_WINS_SERVER_DATA: - g_variant_builder_init (&builder_data, G_VARIANT_TYPE ("as")); - for (i = 0; i < priv->wins->len; i++) { - char addr_str[NM_UTILS_INET_ADDRSTRLEN]; - - g_variant_builder_add (&builder_data, - "s", - nm_utils_inet4_ntop (g_array_index (priv->wins, in_addr_t, i), - addr_str)); - } - g_value_take_variant (value, - g_variant_builder_end (&builder_data)); - break; case PROP_WINS_SERVERS: g_value_take_variant (value, g_variant_new_fixed_array (G_VARIANT_TYPE_UINT32, @@ -3265,7 +3170,6 @@ nm_ip4_config_init (NMIP4Config *self) NMP_OBJECT_TYPE_IP4_ROUTE); priv->mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT; - priv->llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT; priv->nameservers = g_array_new (FALSE, FALSE, sizeof (guint32)); priv->domains = g_ptr_array_new_with_free_func (g_free); priv->searches = g_ptr_array_new_with_free_func (g_free); @@ -3320,19 +3224,17 @@ static const NMDBusInterfaceInfoExtended interface_info_ip4_config = { &nm_signal_info_property_changed_legacy, ), .properties = NM_DEFINE_GDBUS_PROPERTY_INFOS ( - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Addresses", "aau", NM_IP4_CONFIG_ADDRESSES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("AddressData", "aa{sv}", NM_IP4_CONFIG_ADDRESS_DATA), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Gateway", "s", NM_IP4_CONFIG_GATEWAY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Routes", "aau", NM_IP4_CONFIG_ROUTES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("RouteData", "aa{sv}", NM_IP4_CONFIG_ROUTE_DATA), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("NameserverData", "aa{sv}", NM_IP4_CONFIG_NAMESERVER_DATA), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Nameservers", "au", NM_IP4_CONFIG_NAMESERVERS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Domains", "as", NM_IP4_CONFIG_DOMAINS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Searches", "as", NM_IP4_CONFIG_SEARCHES), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DnsOptions", "as", NM_IP4_CONFIG_DNS_OPTIONS), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DnsPriority", "i", NM_IP4_CONFIG_DNS_PRIORITY), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("WinsServerData", "as", NM_IP4_CONFIG_WINS_SERVER_DATA), - NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("WinsServers", "au", NM_IP4_CONFIG_WINS_SERVERS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Addresses", "aau", NM_IP4_CONFIG_ADDRESSES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("AddressData", "aa{sv}", NM_IP4_CONFIG_ADDRESS_DATA), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Gateway", "s", NM_IP4_CONFIG_GATEWAY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Routes", "aau", NM_IP4_CONFIG_ROUTES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("RouteData", "aa{sv}", NM_IP4_CONFIG_ROUTE_DATA), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Nameservers", "au", NM_IP4_CONFIG_NAMESERVERS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Domains", "as", NM_IP4_CONFIG_DOMAINS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Searches", "as", NM_IP4_CONFIG_SEARCHES), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DnsOptions", "as", NM_IP4_CONFIG_DNS_OPTIONS), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("DnsPriority", "i", NM_IP4_CONFIG_DNS_PRIORITY), + NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("WinsServers", "au", NM_IP4_CONFIG_WINS_SERVERS), ), ), .legacy_property_changed = TRUE, @@ -3391,12 +3293,6 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_NAMESERVER_DATA] = - g_param_spec_variant (NM_IP4_CONFIG_NAMESERVER_DATA, "", "", - G_VARIANT_TYPE ("aa{sv}"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); obj_properties[PROP_NAMESERVERS] = g_param_spec_variant (NM_IP4_CONFIG_NAMESERVERS, "", "", G_VARIANT_TYPE ("au"), @@ -3423,12 +3319,6 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) G_MININT32, G_MAXINT32, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_WINS_SERVER_DATA] = - g_param_spec_variant (NM_IP4_CONFIG_WINS_SERVER_DATA, "", "", - G_VARIANT_TYPE ("as"), - NULL, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); obj_properties[PROP_WINS_SERVERS] = g_param_spec_variant (NM_IP4_CONFIG_WINS_SERVERS, "", "", G_VARIANT_TYPE ("au"), diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index d9ac969c..45c1fa3f 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -138,18 +138,16 @@ typedef struct _NMIP4ConfigClass NMIP4ConfigClass; #define NM_IP4_CONFIG_ADDRESS_DATA "address-data" #define NM_IP4_CONFIG_ROUTE_DATA "route-data" #define NM_IP4_CONFIG_GATEWAY "gateway" -#define NM_IP4_CONFIG_NAMESERVER_DATA "nameserver-data" +#define NM_IP4_CONFIG_NAMESERVERS "nameservers" #define NM_IP4_CONFIG_DOMAINS "domains" #define NM_IP4_CONFIG_SEARCHES "searches" #define NM_IP4_CONFIG_DNS_OPTIONS "dns-options" #define NM_IP4_CONFIG_DNS_PRIORITY "dns-priority" -#define NM_IP4_CONFIG_WINS_SERVER_DATA "wins-server-data" +#define NM_IP4_CONFIG_WINS_SERVERS "wins-servers" /* deprecated */ #define NM_IP4_CONFIG_ADDRESSES "addresses" #define NM_IP4_CONFIG_ROUTES "routes" -#define NM_IP4_CONFIG_NAMESERVERS "nameservers" -#define NM_IP4_CONFIG_WINS_SERVERS "wins-servers" GType nm_ip4_config_get_type (void); @@ -175,7 +173,6 @@ gboolean nm_ip4_config_commit (const NMIP4Config *self, void nm_ip4_config_merge_setting (NMIP4Config *self, NMSettingIPConfig *setting, NMSettingConnectionMdns mdns, - NMSettingConnectionLlmnr llmnr, guint32 route_table, guint32 route_metric); NMSetting *nm_ip4_config_create_setting (const NMIP4Config *self); @@ -204,9 +201,6 @@ in_addr_t nmtst_ip4_config_get_gateway (NMIP4Config *config); NMSettingConnectionMdns nm_ip4_config_mdns_get (const NMIP4Config *self); void nm_ip4_config_mdns_set (NMIP4Config *self, NMSettingConnectionMdns mdns); -NMSettingConnectionLlmnr nm_ip4_config_llmnr_get (const NMIP4Config *self); -void nm_ip4_config_llmnr_set (NMIP4Config *self, - NMSettingConnectionLlmnr llmnr); const NMDedupMultiHeadEntry *nm_ip4_config_lookup_addresses (const NMIP4Config *self); void nm_ip4_config_reset_addresses (NMIP4Config *self); @@ -263,8 +257,8 @@ void nm_ip4_config_del_dns_option (NMIP4Config *self, guint i); guint nm_ip4_config_get_num_dns_options (const NMIP4Config *self); const char * nm_ip4_config_get_dns_option (const NMIP4Config *self, guint i); -void nm_ip4_config_set_dns_priority (NMIP4Config *self, int priority); -int nm_ip4_config_get_dns_priority (const NMIP4Config *self); +void nm_ip4_config_set_dns_priority (NMIP4Config *self, gint priority); +gint nm_ip4_config_get_dns_priority (const NMIP4Config *self); void nm_ip4_config_reset_nis_servers (NMIP4Config *self); void nm_ip4_config_add_nis_server (NMIP4Config *self, guint32 nis); @@ -437,7 +431,7 @@ nm_ip_config_get_dns_priority (const NMIPConfig *self) } static inline void -nm_ip_config_set_dns_priority (NMIPConfig *self, int priority) +nm_ip_config_set_dns_priority (NMIPConfig *self, gint priority) { _NM_IP_CONFIG_DISPATCH_VOID (self, nm_ip4_config_set_dns_priority, nm_ip6_config_set_dns_priority, priority); } diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 378b76d6..3869fee8 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -208,8 +208,8 @@ _notify_addresses (NMIP6Config *self) nm_clear_g_variant (&priv->address_data_variant); nm_clear_g_variant (&priv->addresses_variant); - nm_gobject_notify_together (self, PROP_ADDRESS_DATA, - PROP_ADDRESSES); + _notify (self, PROP_ADDRESS_DATA); + _notify (self, PROP_ADDRESSES); } static void @@ -220,13 +220,13 @@ _notify_routes (NMIP6Config *self) nm_assert (priv->best_default_route == _nm_ip6_config_best_default_route_find (self)); nm_clear_g_variant (&priv->route_data_variant); nm_clear_g_variant (&priv->routes_variant); - nm_gobject_notify_together (self, PROP_ROUTE_DATA, - PROP_ROUTES); + _notify (self, PROP_ROUTE_DATA); + _notify (self, PROP_ROUTES); } /*****************************************************************************/ -static int +static gint _addresses_sort_cmp_get_prio (const struct in6_addr *addr) { if (IN6_IS_ADDR_V4MAPPED (addr)) @@ -249,7 +249,7 @@ _addresses_sort_cmp (const NMPlatformIP6Address *a1, const NMPlatformIP6Address *a2, gboolean prefer_temp) { - int p1, p2, c; + gint p1, p2, c; gboolean perm1, perm2, tent1, tent2; gboolean ipv6_privacy1, ipv6_privacy2; @@ -979,7 +979,7 @@ nm_ip6_config_subtract (NMIP6Config *dst, { NMIP6ConfigPrivate *dst_priv; guint i; - int idx; + gint idx; const NMPlatformIP6Address *a; const NMPlatformIP6Route *r; NMDedupMultiIter ipconf_iter; @@ -2289,7 +2289,7 @@ nm_ip6_config_get_dns_option (const NMIP6Config *self, guint i) /*****************************************************************************/ void -nm_ip6_config_set_dns_priority (NMIP6Config *self, int priority) +nm_ip6_config_set_dns_priority (NMIP6Config *self, gint priority) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); @@ -2299,7 +2299,7 @@ nm_ip6_config_set_dns_priority (NMIP6Config *self, int priority) } } -int +gint nm_ip6_config_get_dns_priority (const NMIP6Config *self) { const NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index 425b2049..b8e80410 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -194,8 +194,8 @@ void nm_ip6_config_del_dns_option (NMIP6Config *self, guint i); guint nm_ip6_config_get_num_dns_options (const NMIP6Config *self); const char * nm_ip6_config_get_dns_option (const NMIP6Config *self, guint i); -void nm_ip6_config_set_dns_priority (NMIP6Config *self, int priority); -int nm_ip6_config_get_dns_priority (const NMIP6Config *self); +void nm_ip6_config_set_dns_priority (NMIP6Config *self, gint priority); +gint nm_ip6_config_get_dns_priority (const NMIP6Config *self); const NMPObject *nm_ip6_config_nmpobj_lookup (const NMIP6Config *self, const NMPObject *needle); diff --git a/src/nm-logging.c b/src/nm-logging.c index 9e7d3892..c5553791 100644 --- a/src/nm-logging.c +++ b/src/nm-logging.c @@ -54,9 +54,9 @@ void (*_nm_logging_clear_platform_logging_cache) (void); static void -nm_log_handler (const char *log_domain, +nm_log_handler (const gchar *log_domain, GLogLevelFlags level, - const char *message, + const gchar *message, gpointer ignored); typedef struct { @@ -745,9 +745,9 @@ _nm_log_impl (const char *file, /*****************************************************************************/ static void -nm_log_handler (const char *log_domain, +nm_log_handler (const gchar *log_domain, GLogLevelFlags level, - const char *message, + const gchar *message, gpointer ignored) { int syslog_priority; diff --git a/src/nm-logging.h b/src/nm-logging.h index 0737bbd6..70c14a5e 100644 --- a/src/nm-logging.h +++ b/src/nm-logging.h @@ -271,7 +271,7 @@ gboolean nm_logging_syslog_enabled (void); /* _LOGT() and _LOGt() both log with level TRACE, but the latter is disabled by default, * unless building with --with-more-logging. */ -#if NM_MORE_LOGGING +#ifdef NM_MORE_LOGGING #define _LOGt_ENABLED(...) _NMLOG_ENABLED (LOGL_TRACE, ##__VA_ARGS__) #define _LOGt(...) _NMLOG (LOGL_TRACE, __VA_ARGS__) #define _LOGt_err(errsv, ...) _NMLOG_err (errsv, LOGL_TRACE, __VA_ARGS__) @@ -311,7 +311,7 @@ gboolean nm_logging_syslog_enabled (void); #define _LOG2W_err(errsv, ...) _NMLOG2_err (errsv, LOGL_WARN , __VA_ARGS__) #define _LOG2E_err(errsv, ...) _NMLOG2_err (errsv, LOGL_ERR , __VA_ARGS__) -#if NM_MORE_LOGGING +#ifdef NM_MORE_LOGGING #define _LOG2t_ENABLED(...) _NMLOG2_ENABLED (LOGL_TRACE, ##__VA_ARGS__) #define _LOG2t(...) _NMLOG2 (LOGL_TRACE, __VA_ARGS__) #define _LOG2t_err(errsv, ...) _NMLOG2_err (errsv, LOGL_TRACE, __VA_ARGS__) @@ -342,7 +342,7 @@ gboolean nm_logging_syslog_enabled (void); #define _LOG3W_err(errsv, ...) _NMLOG3_err (errsv, LOGL_WARN , __VA_ARGS__) #define _LOG3E_err(errsv, ...) _NMLOG3_err (errsv, LOGL_ERR , __VA_ARGS__) -#if NM_MORE_LOGGING +#ifdef NM_MORE_LOGGING #define _LOG3t_ENABLED(...) _NMLOG3_ENABLED (LOGL_TRACE, ##__VA_ARGS__) #define _LOG3t(...) _NMLOG3 (LOGL_TRACE, __VA_ARGS__) #define _LOG3t_err(errsv, ...) _NMLOG3_err (errsv, LOGL_TRACE, __VA_ARGS__) diff --git a/src/nm-manager.c b/src/nm-manager.c index f8be6d37..ad906169 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -310,8 +310,7 @@ static void _emit_device_added_removed (NMManager *self, static NMActiveConnection *_new_active_connection (NMManager *self, gboolean is_vpn, - NMSettingsConnection *sett_conn, - NMConnection *incompl_conn, + NMConnection *connection, NMConnection *applied, const char *specific_object, NMDevice *device, @@ -320,7 +319,7 @@ static NMActiveConnection *_new_active_connection (NMManager *self, NMActivationReason activation_reason, GError **error); -static void policy_activating_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data); +static void policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data); static gboolean find_master (NMManager *self, NMConnection *connection, @@ -332,8 +331,7 @@ static gboolean find_master (NMManager *self, static void nm_manager_update_state (NMManager *manager); -static void connection_changed (NMManager *self, - NMSettingsConnection *sett_conn); +static void connection_changed (NMManager *self, NMConnection *connection); static void device_sleep_cb (NMDevice *device, GParamSpec *pspec, NMManager *self); @@ -355,7 +353,7 @@ static void active_connection_parent_active (NMActiveConnection *active, NMManager *self); static NMActiveConnection *active_connection_find (NMManager *self, - NMSettingsConnection *sett_conn, + NMSettingsConnection *settings_connection, const char *uuid, NMActiveConnectionState max_state, GPtrArray **out_all_matching); @@ -949,7 +947,7 @@ nm_manager_get_active_connections (NMManager *manager) static NMActiveConnection * active_connection_find (NMManager *self, - NMSettingsConnection *sett_conn, + NMSettingsConnection *settings_connection, const char *uuid, NMActiveConnectionState max_state /* candidates in state @max_state will be found */, GPtrArray **out_all_matching) @@ -959,18 +957,16 @@ active_connection_find (NMManager *self, NMActiveConnection *best_ac = NULL; GPtrArray *all = NULL; - nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn)); + nm_assert (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection)); nm_assert (!out_all_matching || !*out_all_matching); c_list_for_each_entry (ac, &priv->active_connections_lst_head, active_connections_lst) { - NMSettingsConnection *ac_conn; + NMSettingsConnection *con; - ac_conn = nm_active_connection_get_settings_connection (ac); - if ( sett_conn - && sett_conn != ac_conn) + con = nm_active_connection_get_settings_connection (ac); + if (settings_connection && con != settings_connection) continue; - if ( uuid - && !nm_streq0 (uuid, nm_settings_connection_get_uuid (ac_conn))) + if (uuid && !nm_streq0 (uuid, nm_connection_get_uuid (NM_CONNECTION (con)))) continue; if (nm_active_connection_get_state (ac) > max_state) continue; @@ -1009,73 +1005,47 @@ active_connection_find (NMManager *self, static NMActiveConnection * active_connection_find_by_connection (NMManager *self, - NMSettingsConnection *sett_conn, NMConnection *connection, NMActiveConnectionState max_state, GPtrArray **out_all_matching) { + gboolean is_settings_connection; + nm_assert (NM_IS_MANAGER (self)); - nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn)); - nm_assert (!connection || NM_IS_CONNECTION (connection)); - nm_assert (sett_conn || connection); - nm_assert (!connection || !sett_conn || connection == nm_settings_connection_get_connection (sett_conn)); + nm_assert (NM_IS_CONNECTION (connection)); + is_settings_connection = NM_IS_SETTINGS_CONNECTION (connection); /* Depending on whether connection is a settings connection, * either lookup by object-identity of @connection, or compare the UUID */ return active_connection_find (self, - sett_conn, - sett_conn ? NULL : nm_connection_get_uuid (connection), + is_settings_connection ? NM_SETTINGS_CONNECTION (connection) : NULL, + is_settings_connection ? NULL : nm_connection_get_uuid (connection), max_state, out_all_matching); } -typedef struct { - NMManager *self; - gboolean for_auto_activation; -} GetActivatableConnectionsFilterData; - static gboolean _get_activatable_connections_filter (NMSettings *settings, - NMSettingsConnection *sett_conn, + NMSettingsConnection *connection, gpointer user_data) { - const GetActivatableConnectionsFilterData *d = user_data; - NMConnectionMultiConnect multi_connect; - - if (NM_FLAGS_HAS (nm_settings_connection_get_flags (sett_conn), + if (NM_FLAGS_HAS (nm_settings_connection_get_flags (connection), NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)) return FALSE; - multi_connect = _nm_connection_get_multi_connect (nm_settings_connection_get_connection (sett_conn)); - if ( multi_connect == NM_CONNECTION_MULTI_CONNECT_MULTIPLE - || ( multi_connect == NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE - && !d->for_auto_activation)) - return TRUE; - /* the connection is activatable, if it has no active-connections that are in state * activated, activating, or waiting to be activated. */ - return !active_connection_find (d->self, - sett_conn, - NULL, - NM_ACTIVE_CONNECTION_STATE_ACTIVATED, - NULL); + return !active_connection_find (user_data, connection, NULL, NM_ACTIVE_CONNECTION_STATE_ACTIVATED, NULL); } NMSettingsConnection ** -nm_manager_get_activatable_connections (NMManager *manager, - gboolean for_auto_activation, - gboolean sort, - guint *out_len) +nm_manager_get_activatable_connections (NMManager *manager, guint *out_len, gboolean sort) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); - const GetActivatableConnectionsFilterData d = { - .self = manager, - .for_auto_activation = for_auto_activation, - }; return nm_settings_get_connections_clone (priv->settings, out_len, _get_activatable_connections_filter, - (gpointer) &d, + manager, sort ? nm_settings_connection_cmp_autoconnect_priority_p_with_data : NULL, NULL); } @@ -1086,8 +1056,8 @@ active_connection_get_by_path (NMManager *self, const char *path) NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMActiveConnection *ac; - ac = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), - path); + ac = (NMActiveConnection *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), + path); if ( !ac || !NM_IS_ACTIVE_CONNECTION (ac) || c_list_is_empty (&ac->active_connections_lst)) @@ -1223,8 +1193,8 @@ nm_manager_get_device_by_path (NMManager *self, const char *path) g_return_val_if_fail (path, NULL); - device = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), - path); + device = (NMDevice *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), + path); if ( !device || !NM_IS_DEVICE (device) || c_list_is_empty (&device->devices_lst)) @@ -1274,7 +1244,7 @@ find_device_by_permanent_hw_addr (NMManager *self, const char *hwaddr) } static NMDevice * -find_device_by_ip_iface (NMManager *self, const char *iface) +find_device_by_ip_iface (NMManager *self, const gchar *iface) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMDevice *device; @@ -1320,7 +1290,7 @@ find_device_by_iface (NMManager *self, if (strcmp (nm_device_get_iface (candidate), iface)) continue; - if (connection && !nm_device_check_connection_compatible (candidate, connection, NULL)) + if (connection && !nm_device_check_connection_compatible (candidate, connection)) continue; if (slave) { if (!nm_device_is_master (candidate)) @@ -1489,23 +1459,20 @@ manager_device_state_changed (NMDevice *device, && new_state > NM_DEVICE_STATE_UNMANAGED) retry_connections_for_parent_device (self, device); - if (NM_IN_SET (new_state, - NM_DEVICE_STATE_UNMANAGED, - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_PREPARE, - NM_DEVICE_STATE_FAILED)) + switch (new_state) { + case NM_DEVICE_STATE_UNMANAGED: + case NM_DEVICE_STATE_UNAVAILABLE: + case NM_DEVICE_STATE_DISCONNECTED: + case NM_DEVICE_STATE_PREPARE: + case NM_DEVICE_STATE_FAILED: _notify (self, PROP_ACTIVE_CONNECTIONS); + break; + default: + break; + } - if (NM_IN_SET (new_state, - NM_DEVICE_STATE_UNMANAGED, - NM_DEVICE_STATE_DISCONNECTED, - NM_DEVICE_STATE_ACTIVATED)) - nm_manager_write_device_state (self, device); - - if (NM_IN_SET (new_state, - NM_DEVICE_STATE_UNAVAILABLE, - NM_DEVICE_STATE_DISCONNECTED)) + if ( new_state == NM_DEVICE_STATE_UNAVAILABLE + || new_state == NM_DEVICE_STATE_DISCONNECTED) nm_settings_device_added (priv->settings, device); } @@ -1740,9 +1707,7 @@ find_parent_device_for_connection (NMManager *self, NMConnection *connection, NM return candidate; if ( !first_compatible - && nm_device_check_connection_compatible (candidate, - nm_settings_connection_get_connection (parent_connection), - NULL)) + && nm_device_check_connection_compatible (candidate, NM_CONNECTION (parent_connection))) first_compatible = candidate; } @@ -1836,13 +1801,13 @@ const char * nm_manager_iface_for_uuid (NMManager *self, const char *uuid) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; - sett_conn = nm_settings_get_connection_by_uuid (priv->settings, uuid); - if (!sett_conn) + connection = nm_settings_get_connection_by_uuid (priv->settings, uuid); + if (!connection) return NULL; - return nm_connection_get_interface_name (nm_settings_connection_get_connection (sett_conn)); + return nm_connection_get_interface_name (NM_CONNECTION (connection)); } NMDevice * @@ -1912,7 +1877,7 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) /* See if there's a device that is already compatible with this connection */ c_list_for_each_entry (dev_candidate, &priv->devices_lst_head, devices_lst) { - if (nm_device_check_connection_compatible (dev_candidate, connection, NULL)) { + if (nm_device_check_connection_compatible (dev_candidate, connection)) { if (nm_device_is_real (dev_candidate)) { _LOG3D (LOGD_DEVICE, connection, "already created virtual interface name %s", iface); @@ -1965,10 +1930,10 @@ system_create_virtual_device (NMManager *self, NMConnection *connection) NULL, NULL, nm_settings_connection_cmp_autoconnect_priority_p_with_data, NULL); for (i = 0; connections[i]; i++) { - NMConnection *candidate = nm_settings_connection_get_connection (connections[i]); + NMConnection *candidate = NM_CONNECTION (connections[i]); NMSettingConnection *s_con; - if (!nm_device_check_connection_compatible (device, candidate, NULL)) + if (!nm_device_check_connection_compatible (device, candidate)) continue; s_con = nm_connection_get_setting_connection (candidate); @@ -2011,19 +1976,18 @@ retry_connections_for_parent_device (NMManager *self, NMDevice *device) NULL, NULL, nm_settings_connection_cmp_autoconnect_priority_p_with_data, NULL); for (i = 0; connections[i]; i++) { - NMSettingsConnection *sett_conn = connections[i]; - NMConnection *connection = nm_settings_connection_get_connection (sett_conn); + NMConnection *candidate = NM_CONNECTION (connections[i]); gs_free_error GError *error = NULL; gs_free char *ifname = NULL; NMDevice *parent; - parent = find_parent_device_for_connection (self, connection, NULL); + parent = find_parent_device_for_connection (self, candidate, NULL); if (parent == device) { /* Only try to activate devices that don't already exist */ - ifname = nm_manager_get_connection_iface (self, connection, &parent, &error); + ifname = nm_manager_get_connection_iface (self, candidate, &parent, &error); if (ifname) { if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, ifname)) - connection_changed (self, sett_conn); + connection_changed (self, candidate); } } } @@ -2031,10 +1995,9 @@ retry_connections_for_parent_device (NMManager *self, NMDevice *device) static void connection_changed (NMManager *self, - NMSettingsConnection *sett_conn) + NMConnection *connection) { NMDevice *device; - NMConnection *connection = nm_settings_connection_get_connection (sett_conn); if (!nm_connection_is_virtual (connection)) return; @@ -2051,20 +2014,20 @@ connection_changed (NMManager *self, static void connection_added_cb (NMSettings *settings, - NMSettingsConnection *sett_conn, + NMConnection *connection, NMManager *self) { - connection_changed (self, sett_conn); + connection_changed (self, connection); } static void connection_updated_cb (NMSettings *settings, - NMSettingsConnection *sett_conn, + NMConnection *connection, gboolean by_user, NMManager *self) { if (by_user) - connection_changed (self, sett_conn); + connection_changed (self, connection); } /*****************************************************************************/ @@ -2407,20 +2370,6 @@ done: g_clear_error (&error); } -static gboolean -new_activation_allowed_for_connection (NMManager *self, - NMSettingsConnection *connection) -{ - if (NM_IN_SET (_nm_connection_get_multi_connect (nm_settings_connection_get_connection (connection)), - NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE, - NM_CONNECTION_MULTI_CONNECT_MULTIPLE)) - return TRUE; - - return !active_connection_find (self, connection, NULL, - NM_ACTIVE_CONNECTION_STATE_ACTIVATED, - NULL); -} - /** * get_existing_connection: * @manager: #NMManager instance @@ -2437,12 +2386,12 @@ get_existing_connection (NMManager *self, { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); gs_unref_object NMConnection *connection = NULL; - NMSettingsConnection *added; + NMSettingsConnection *added = NULL; GError *error = NULL; gs_free_error GError *gen_error = NULL; NMDevice *master = NULL; int ifindex = nm_device_get_ifindex (device); - NMSettingsConnection *matched = NULL; + NMSettingsConnection *matched; NMSettingsConnection *connection_checked = NULL; gboolean assume_state_guess_assume = FALSE; const char *assume_state_connection_uuid = NULL; @@ -2508,25 +2457,28 @@ get_existing_connection (NMManager *self, */ if ( assume_state_connection_uuid && (connection_checked = nm_settings_get_connection_by_uuid (priv->settings, assume_state_connection_uuid)) - && new_activation_allowed_for_connection (self, connection_checked) - && nm_device_check_connection_compatible (device, - nm_settings_connection_get_connection (connection_checked), - NULL)) { + && !active_connection_find (self, connection_checked, NULL, + NM_ACTIVE_CONNECTION_STATE_ACTIVATED, + NULL) + && nm_device_check_connection_compatible (device, NM_CONNECTION (connection_checked))) { if (connection) { - NMConnection *con = nm_settings_connection_get_connection (connection_checked); - - if (nm_utils_match_connection ((NMConnection *[]) { con, NULL }, - connection, - TRUE, - nm_device_has_carrier (device), - nm_device_get_route_metric (device, AF_INET), - nm_device_get_route_metric (device, AF_INET6), - NULL, NULL)) - matched = connection_checked; + NMConnection *const connections[] = { + NM_CONNECTION (connection_checked), + NULL, + }; + + matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection (connections, + connection, + TRUE, + nm_device_has_carrier (device), + nm_device_get_route_metric (device, AF_INET), + nm_device_get_route_metric (device, AF_INET6), + NULL, NULL)); } else matched = connection_checked; - } + } else + matched = NULL; if (!matched && only_by_uuid) { _LOG2D (LOGD_DEVICE, device, "assume: cannot generate connection: %s", @@ -2535,51 +2487,32 @@ get_existing_connection (NMManager *self, } if (!matched && assume_state_guess_assume) { - gs_free NMSettingsConnection **sett_conns = NULL; + gs_free NMSettingsConnection **connections = NULL; guint len, i, j; /* the state file doesn't indicate a connection UUID to assume. Search the * persistent connections for a matching candidate. */ - sett_conns = nm_manager_get_activatable_connections (self, FALSE, FALSE, &len); + connections = nm_manager_get_activatable_connections (self, &len, FALSE); if (len > 0) { for (i = 0, j = 0; i < len; i++) { - NMSettingsConnection *sett_conn = sett_conns[i]; + NMConnection *con = NM_CONNECTION (connections[i]); - if ( sett_conn != connection_checked - && nm_device_check_connection_compatible (device, - nm_settings_connection_get_connection (sett_conn), - NULL)) - sett_conns[j++] = sett_conn; + if ( con != NM_CONNECTION (connection_checked) + && nm_device_check_connection_compatible (device, con)) + connections[j++] = connections[i]; } - sett_conns[j] = NULL; + connections[j] = NULL; len = j; - if (len > 0) { - gs_free NMConnection **conns = NULL; - NMConnection *con; - - g_qsort_with_data (sett_conns, len, sizeof (sett_conns[0]), - nm_settings_connection_cmp_timestamp_p_with_data, NULL); - - conns = nm_settings_connections_array_to_connections (sett_conns, len); - - con = nm_utils_match_connection (conns, - connection, - FALSE, - nm_device_has_carrier (device), - nm_device_get_route_metric (device, AF_INET), - nm_device_get_route_metric (device, AF_INET6), - NULL, - NULL); - if (con) { - for (i = 0; i < len; i++) { - if (conns[i] == con) { - matched = sett_conns[i]; - break; - } - } - nm_assert (matched); - } - } + g_qsort_with_data (connections, len, sizeof (connections[0]), + nm_settings_connection_cmp_timestamp_p_with_data, NULL); + + matched = NM_SETTINGS_CONNECTION (nm_utils_match_connection ((NMConnection *const*) connections, + connection, + FALSE, + nm_device_has_carrier (device), + nm_device_get_route_metric (device, AF_INET), + nm_device_get_route_metric (device, AF_INET6), + NULL, NULL)); } } @@ -2608,7 +2541,7 @@ get_existing_connection (NMManager *self, return NULL; } - nm_settings_connection_set_flags (added, + nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added), NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE, TRUE); @@ -2620,7 +2553,7 @@ static gboolean recheck_assume_connection (NMManager *self, NMDevice *device) { - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; gboolean was_unmanaged = FALSE; gboolean generated = FALSE; NMDeviceState state; @@ -2642,9 +2575,9 @@ recheck_assume_connection (NMManager *self, return FALSE; } - sett_conn = get_existing_connection (self, device, &generated); + connection = get_existing_connection (self, device, &generated); /* log no reason. get_existing_connection() already does it. */ - if (!sett_conn) + if (!connection) return FALSE; nm_device_sys_iface_state_set (device, @@ -2676,8 +2609,7 @@ recheck_assume_connection (NMManager *self, subject = nm_auth_subject_new_internal (); active = _new_active_connection (self, FALSE, - sett_conn, - NULL, + NM_CONNECTION (connection), NULL, NULL, device, @@ -2688,7 +2620,7 @@ recheck_assume_connection (NMManager *self, if (!active) { _LOGW (LOGD_DEVICE, "assume: assumed connection %s failed to activate: %s", - nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)), error->message); g_error_free (error); @@ -2700,7 +2632,7 @@ recheck_assume_connection (NMManager *self, if (generated) { _LOG2D (LOGD_DEVICE, device, "assume: deleting generated connection after assuming failed"); - nm_settings_connection_delete (sett_conn, NULL); + nm_settings_connection_delete (connection, NULL); } else { if (nm_device_sys_iface_state_get (device) == NM_DEVICE_SYS_IFACE_STATE_ASSUME) nm_device_sys_iface_state_set (device, NM_DEVICE_SYS_IFACE_STATE_EXTERNAL); @@ -2710,14 +2642,7 @@ recheck_assume_connection (NMManager *self, /* If the device is a slave or VLAN, find the master ActiveConnection */ master_ac = NULL; - if ( find_master (self, - nm_settings_connection_get_connection (sett_conn), - device, - NULL, - NULL, - &master_ac, - NULL) - && master_ac) + if (find_master (self, NM_CONNECTION (connection), device, NULL, NULL, &master_ac, NULL) && master_ac) nm_active_connection_set_master (active, master_ac); active_connection_add (self, active); @@ -3321,11 +3246,9 @@ nm_manager_get_devices (NMManager *manager) static NMDevice * nm_manager_get_best_device_for_connection (NMManager *self, - NMSettingsConnection *sett_conn, NMConnection *connection, gboolean for_user_request, - GHashTable *unavailable_devices, - GError **error) + GHashTable *unavailable_devices) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMActiveConnectionState ac_state; @@ -3334,25 +3257,16 @@ nm_manager_get_best_device_for_connection (NMManager *self, NMDevice *device; NMDeviceCheckConAvailableFlags flags; gs_unref_ptrarray GPtrArray *all_ac_arr = NULL; - gs_free_error GError *local_best = NULL; - - nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn)); - nm_assert (!connection || NM_IS_CONNECTION (connection)); - nm_assert (sett_conn || connection); - nm_assert (!connection || !sett_conn || connection == nm_settings_connection_get_connection (sett_conn)); - - if (!connection) - connection = nm_settings_connection_get_connection (sett_conn); flags = for_user_request ? NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST : NM_DEVICE_CHECK_CON_AVAILABLE_NONE; - ac = active_connection_find_by_connection (self, sett_conn, connection, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, &all_ac_arr); + ac = active_connection_find_by_connection (self, connection, NM_ACTIVE_CONNECTION_STATE_DEACTIVATING, &all_ac_arr); if (ac) { ac_device = nm_active_connection_get_device (ac); if ( ac_device && ( (unavailable_devices && g_hash_table_contains (unavailable_devices, ac_device)) - || !nm_device_check_connection_available (ac_device, connection, flags, NULL, NULL))) + || !nm_device_check_connection_available (ac_device, connection, flags, NULL))) ac_device = NULL; if (all_ac_arr) { @@ -3369,7 +3283,7 @@ nm_manager_get_best_device_for_connection (NMManager *self, if ( !ac_device2 || (unavailable_devices && g_hash_table_contains (unavailable_devices, ac_device2)) - || !nm_device_check_connection_available (ac_device2, connection, flags, NULL, NULL)) + || !nm_device_check_connection_available (ac_device2, connection, flags, NULL)) continue; ac_state2 = nm_active_connection_get_state (ac2); @@ -3417,53 +3331,15 @@ found_better: /* Pick the first device that's compatible with the connection. */ c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { - GError *local = NULL; - if ( unavailable_devices - && g_hash_table_contains (unavailable_devices, device)) + if (unavailable_devices && g_hash_table_contains (unavailable_devices, device)) continue; - if (nm_device_check_connection_available (device, - connection, - flags, - NULL, - error ? &local : NULL)) + if (nm_device_check_connection_available (device, connection, flags, NULL)) return device; - - if (error) { - gboolean reset_error; - - if (!local_best) - reset_error = TRUE; - else if (local_best->domain != NM_UTILS_ERROR) - reset_error = (local->domain == NM_UTILS_ERROR); - else { - reset_error = ( local->domain == NM_UTILS_ERROR - && local_best->code < local->code); - } - - if (reset_error) { - g_clear_error (&local_best); - g_set_error (&local_best, - local->domain, - local->code, - "device %s not available because %s", - nm_device_get_iface (device), - local->message); - } - g_error_free (local); - } } - if (error) { - if (local_best) - g_propagate_error (error, g_steal_pointer (&local_best)); - else { - nm_utils_error_set_literal (error, - NM_UTILS_ERROR_UNKNOWN, - "no suitable device found"); - } - } + /* No luck. :( */ return NULL; } @@ -3632,7 +3508,7 @@ find_master (NMManager *self, NMSettingConnection *s_con; const char *master; NMDevice *master_device = NULL; - NMSettingsConnection *master_connection; + NMSettingsConnection *master_connection = NULL; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); @@ -3651,9 +3527,7 @@ find_master (NMManager *self, } master_connection = nm_device_get_settings_connection (master_device); - if ( master_connection - && !is_compatible_with_slave (nm_settings_connection_get_connection (master_connection), - connection)) { + if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), connection)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED, "The active connection on %s is not compatible", nm_device_get_iface (master_device)); @@ -3753,9 +3627,7 @@ ensure_master_active_connection (NMManager *self, * be already activated on the device, eg returned from find_master(). */ g_assert (!master_connection || master_connection == device_connection); - if ( device_connection - && !is_compatible_with_slave (nm_settings_connection_get_connection (device_connection), - connection)) { + if (device_connection && !is_compatible_with_slave (NM_CONNECTION (device_connection), connection)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED, "The active connection %s is not compatible", nm_connection_get_id (connection)); @@ -3780,22 +3652,17 @@ ensure_master_active_connection (NMManager *self, g_assert (master_connection == NULL); /* Find a compatible connection and activate this device using it */ - connections = nm_manager_get_activatable_connections (self, FALSE, TRUE, NULL); + connections = nm_manager_get_activatable_connections (self, NULL, TRUE); for (i = 0; connections[i]; i++) { NMSettingsConnection *candidate = connections[i]; - NMConnection *cand_conn = nm_settings_connection_get_connection (candidate); /* Ensure eg bond/team slave and the candidate master is a * bond/team master */ - if (!is_compatible_with_slave (cand_conn, connection)) + if (!is_compatible_with_slave (NM_CONNECTION (candidate), connection)) continue; - if (nm_device_check_connection_available (master_device, - cand_conn, - NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, - NULL, - NULL)) { + if (nm_device_check_connection_available (master_device, NM_CONNECTION (candidate), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) { master_ac = nm_manager_activate_connection (self, candidate, NULL, @@ -3831,11 +3698,7 @@ ensure_master_active_connection (NMManager *self, continue; } - if (!nm_device_check_connection_available (candidate, - nm_settings_connection_get_connection (master_connection), - NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, - NULL, - NULL)) + if (!nm_device_check_connection_available (candidate, NM_CONNECTION (master_connection), NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) continue; if (!nm_device_is_software (candidate)) { @@ -3874,18 +3737,18 @@ typedef struct { /** * find_slaves: * @manager: #NMManager object - * @sett_conn: the master #NMSettingsConnection to find slave connections for - * @device: the master #NMDevice for the @sett_conn + * @connection: the master #NMSettingsConnection to find slave connections for + * @device: the master #NMDevice for the @connection * @out_n_slaves: on return, the number of slaves found * - * Given an #NMSettingsConnection, attempts to find its slaves. If @sett_conn is not + * Given an #NMSettingsConnection, attempts to find its slaves. If @connection is not * master, or has not any slaves, this will return %NULL. * - * Returns: an array of #SlaveConnectionInfo for given master @sett_conn, or %NULL + * Returns: an array of #SlaveConnectionInfo for given master @connection, or %NULL **/ static SlaveConnectionInfo * find_slaves (NMManager *manager, - NMSettingsConnection *sett_conn, + NMSettingsConnection *connection, NMDevice *device, guint *out_n_slaves) { @@ -3900,7 +3763,7 @@ find_slaves (NMManager *manager, nm_assert (out_n_slaves); - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (sett_conn)); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); g_return_val_if_fail (s_con, NULL); devices = g_hash_table_new (nm_direct_hash, NULL); @@ -3915,23 +3778,15 @@ find_slaves (NMManager *manager, for (i = 0; i < n_all_connections; i++) { NMSettingsConnection *master_connection = NULL; NMDevice *master_device = NULL, *slave_device; - NMSettingsConnection *candidate = all_connections[i]; - - find_master (manager, - nm_settings_connection_get_connection (candidate), - NULL, - &master_connection, - &master_device, - NULL, - NULL); - if ( (master_connection && master_connection == sett_conn) + NMConnection *candidate = NM_CONNECTION (all_connections[i]); + + find_master (manager, candidate, NULL, &master_connection, &master_device, NULL, NULL); + if ( (master_connection && master_connection == connection) || (master_device && master_device == device)) { slave_device = nm_manager_get_best_device_for_connection (manager, candidate, - NULL, FALSE, - devices, - NULL); + devices); if (!slaves) { /* what we allocate is quite likely much too large. Don't bother, it is only @@ -3940,7 +3795,7 @@ find_slaves (NMManager *manager, } nm_assert (n_slaves < n_all_connections); - slaves[n_slaves].connection = candidate, + slaves[n_slaves].connection = NM_SETTINGS_CONNECTION (candidate), slaves[n_slaves].device = slave_device, n_slaves++; @@ -3959,29 +3814,32 @@ static gboolean should_connect_slaves (NMConnection *connection, NMDevice *device) { NMSettingConnection *s_con; - NMSettingConnectionAutoconnectSlaves val; + NMSettingConnectionAutoconnectSlaves autoconnect_slaves; + gs_free char *value = NULL; s_con = nm_connection_get_setting_connection (connection); g_assert (s_con); - val = nm_setting_connection_get_autoconnect_slaves (s_con); - if (val != NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT) + /* Check autoconnect-slaves property */ + autoconnect_slaves = nm_setting_connection_get_autoconnect_slaves (s_con); + if (autoconnect_slaves != NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT) goto out; - val = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "connection.autoconnect-slaves", - device, - 0, 1, -1); + /* Check configuration default for autoconnect-slaves property */ + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "connection.autoconnect-slaves", device); + if (value) + autoconnect_slaves = _nm_utils_ascii_str_to_int64 (value, 10, 0, 1, -1); out: - if (val == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO) + if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_NO) return FALSE; - if (val == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES) + if (autoconnect_slaves == NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_YES) return TRUE; return FALSE; } -static int +static gint compare_slaves (gconstpointer a, gconstpointer b, gpointer sort_by_name) { const SlaveConnectionInfo *a_info = a; @@ -4009,8 +3867,7 @@ autoconnect_slaves (NMManager *self, { GError *local_err = NULL; - if (should_connect_slaves (nm_settings_connection_get_connection (master_connection), - master_device)) { + if (should_connect_slaves (NM_CONNECTION (master_connection), master_device)) { gs_free SlaveConnectionInfo *slaves = NULL; guint i, n_slaves = 0; @@ -4151,7 +4008,7 @@ active_connection_parent_active (NMActiveConnection *active, { NMDevice *device = nm_active_connection_get_device (active); GError *error = NULL; - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; NMDevice *parent; g_signal_handlers_disconnect_by_func (active, @@ -4167,13 +4024,10 @@ active_connection_parent_active (NMActiveConnection *active, return; } - sett_conn = nm_active_connection_get_settings_connection (active); + connection = nm_active_connection_get_settings_connection (active); parent = nm_active_connection_get_device (parent_ac); - if (!nm_device_create_and_realize (device, - nm_settings_connection_get_connection (sett_conn), - parent, - &error)) { + if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, &error)) { _LOGW (LOGD_CORE, "Could not realize device '%s': %s", nm_device_get_iface (device), error->message); nm_active_connection_set_state_fail (active, @@ -4191,13 +4045,11 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * { NMDevice *device, *master_device = NULL; NMConnection *applied; - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; NMSettingsConnection *master_connection = NULL; NMConnection *existing_connection = NULL; NMActiveConnection *master_ac = NULL; NMAuthSubject *subject; - GError *local = NULL; - NMConnectionMultiConnect multi_connect; g_return_val_if_fail (NM_IS_MANAGER (self), FALSE); g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (active), FALSE); @@ -4208,8 +4060,8 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * device = nm_active_connection_get_device (active); g_return_val_if_fail (device != NULL, FALSE); - sett_conn = nm_active_connection_get_settings_connection (active); - nm_assert (sett_conn); + connection = nm_active_connection_get_settings_connection (active); + nm_assert (connection); applied = nm_active_connection_get_applied_connection (active); @@ -4231,13 +4083,10 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * } /* Final connection must be available on device */ - if (!nm_device_check_connection_available (device, applied, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL, &local)) { + if (!nm_device_check_connection_available (device, applied, NM_DEVICE_CHECK_CON_AVAILABLE_FOR_USER_REQUEST, NULL)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, - "Connection '%s' is not available on device %s because %s", - nm_settings_connection_get_id (sett_conn), - nm_device_get_iface (device), - local->message); - g_error_free (local); + "Connection '%s' is not available on the device %s at this time.", + nm_settings_connection_get_id (connection), nm_device_get_iface (device)); return FALSE; } @@ -4248,9 +4097,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * if (!nm_device_is_real (device)) { NMDevice *parent; - parent = find_parent_device_for_connection (self, - nm_settings_connection_get_connection (sett_conn), - NULL); + parent = find_parent_device_for_connection (self, (NMConnection *) connection, NULL); if (parent && !nm_device_is_real (parent)) { NMSettingsConnection *parent_con; @@ -4262,11 +4109,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * return FALSE; } - parent_ac = nm_manager_activate_connection (self, - parent_con, - NULL, - NULL, - parent, + parent_ac = nm_manager_activate_connection (self, parent_con, NULL, NULL, parent, subject, NM_ACTIVATION_TYPE_MANAGED, nm_active_connection_get_activation_reason (active), @@ -4284,10 +4127,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * nm_active_connection_set_parent (active, parent_ac); } else { /* We can realize now; no need to wait for a parent device. */ - if (!nm_device_create_and_realize (device, - nm_settings_connection_get_connection (sett_conn), - parent, - error)) { + if (!nm_device_create_and_realize (device, (NMConnection *) connection, parent, error)) { g_prefix_error (error, "%s failed to create resources: ", nm_device_get_iface (device)); return FALSE; } @@ -4295,15 +4135,11 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * } /* Try to find the master connection/device if the connection has a dependency */ - if (!find_master (self, - applied, - device, - &master_connection, - &master_device, - &master_ac, + if (!find_master (self, applied, device, + &master_connection, &master_device, &master_ac, error)) { g_prefix_error (error, "Can not find a master for %s: ", - nm_settings_connection_get_id (sett_conn)); + nm_settings_connection_get_id (connection)); return FALSE; } @@ -4313,23 +4149,21 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * if (master_connection || master_device) { if (master_connection) { _LOGD (LOGD_CORE, "Activation of '%s' requires master connection '%s'", - nm_settings_connection_get_id (sett_conn), + nm_settings_connection_get_id (connection), nm_settings_connection_get_id (master_connection)); } if (master_device) { _LOGD (LOGD_CORE, "Activation of '%s' requires master device '%s'", - nm_settings_connection_get_id (sett_conn), + nm_settings_connection_get_id (connection), nm_device_get_ip_iface (master_device)); } /* Ensure eg bond slave and the candidate master is a bond master */ - if ( master_connection - && !is_compatible_with_slave (nm_settings_connection_get_connection (master_connection), - applied)) { + if (master_connection && !is_compatible_with_slave (NM_CONNECTION (master_connection), applied)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_DEPENDENCY_FAILED, "The master connection '%s' is not compatible with '%s'", nm_settings_connection_get_id (master_connection), - nm_settings_connection_get_id (sett_conn)); + nm_settings_connection_get_id (connection)); return FALSE; } @@ -4348,7 +4182,7 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * nm_device_get_ip_iface (device)); } else { g_prefix_error (error, "Master connection '%s' can't be activated: ", - nm_settings_connection_get_id (sett_conn)); + nm_settings_connection_get_id (connection)); } return FALSE; } @@ -4365,30 +4199,22 @@ _internal_activate_device (NMManager *self, NMActiveConnection *active, GError * nm_active_connection_set_master (active, master_ac); _LOGD (LOGD_CORE, "Activation of '%s' depends on active connection %p %s", - nm_settings_connection_get_id (sett_conn), + nm_settings_connection_get_id (connection), master_ac, nm_dbus_object_get_path (NM_DBUS_OBJECT (master_ac)) ?: ""); } /* Check slaves for master connection and possibly activate them */ - autoconnect_slaves (self, sett_conn, device, nm_active_connection_get_subject (active)); - - multi_connect = _nm_connection_get_multi_connect (nm_settings_connection_get_connection (sett_conn)); - if ( multi_connect == NM_CONNECTION_MULTI_CONNECT_MULTIPLE - || ( multi_connect == NM_CONNECTION_MULTI_CONNECT_MANUAL_MULTIPLE - && NM_IN_SET (nm_active_connection_get_activation_reason (active), - NM_ACTIVATION_REASON_ASSUME, - NM_ACTIVATION_REASON_AUTOCONNECT_SLAVES, - NM_ACTIVATION_REASON_USER_REQUEST))) { - /* the profile can be activated multiple times. Proceed. */ - } else { + autoconnect_slaves (self, connection, device, nm_active_connection_get_subject (active)); + + { gs_unref_ptrarray GPtrArray *all_ac_arr = NULL; NMActiveConnection *ac; guint i, n_all; /* Disconnect the connection if already connected or queued for activation. * The connection cannot be active multiple times (at the same time). */ - ac = active_connection_find (self, sett_conn, NULL, NM_ACTIVE_CONNECTION_STATE_ACTIVATED, + ac = active_connection_find (self, connection, NULL, NM_ACTIVE_CONNECTION_STATE_ACTIVATED, &all_ac_arr); if (ac) { n_all = all_ac_arr ? all_ac_arr->len : ((guint) 1); @@ -4451,7 +4277,7 @@ _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError * is exported, make sure the manager's activating-connection property * is up-to-date. */ - policy_activating_ac_changed (G_OBJECT (priv->policy), NULL, self); + policy_activating_device_changed (G_OBJECT (priv->policy), NULL, self); } return success; @@ -4460,8 +4286,7 @@ _internal_activate_generic (NMManager *self, NMActiveConnection *active, GError static NMActiveConnection * _new_active_connection (NMManager *self, gboolean is_vpn, - NMSettingsConnection *sett_conn, - NMConnection *incompl_conn, + NMConnection *connection, NMConnection *applied, const char *specific_object, NMDevice *device, @@ -4471,19 +4296,18 @@ _new_active_connection (NMManager *self, GError **error) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMSettingsConnection *settings_connection = NULL; NMDevice *parent_device; - nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn)); - nm_assert (!incompl_conn || NM_IS_CONNECTION (incompl_conn)); - nm_assert ((!incompl_conn) ^ (!sett_conn)); - nm_assert (NM_IS_AUTH_SUBJECT (subject)); - nm_assert (is_vpn == _connection_is_vpn (sett_conn - ? nm_settings_connection_get_connection (sett_conn) - : incompl_conn)); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (NM_IS_AUTH_SUBJECT (subject), NULL); + + nm_assert (is_vpn == _connection_is_vpn (connection)); nm_assert (is_vpn || NM_IS_DEVICE (device)); nm_assert (!nm_streq0 (specific_object, "/")); - nm_assert (!applied || NM_IS_CONNECTION (applied)); - nm_assert (!is_vpn || !applied); + + if (NM_IS_SETTINGS_CONNECTION (connection)) + settings_connection = (NMSettingsConnection *) connection; if (is_vpn) { NMActiveConnection *parent; @@ -4491,20 +4315,21 @@ _new_active_connection (NMManager *self, /* FIXME: for VPN connections, we don't allow re-activating an * already active connection. It's a bug, and should be fixed together * when reworking VPN handling. */ - if (active_connection_find_by_connection (self, - sett_conn, - incompl_conn, - NM_ACTIVE_CONNECTION_STATE_ACTIVATED, - NULL)) { + if (active_connection_find_by_connection (self, connection, NM_ACTIVE_CONNECTION_STATE_ACTIVATED, NULL)) { g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_ALREADY_ACTIVE, "Connection '%s' is already active", - sett_conn ? nm_settings_connection_get_id (sett_conn) : nm_connection_get_id (incompl_conn)); + nm_connection_get_id (connection)); return NULL; } + /* FIXME: apparently, activation here only works if @connection is + * a settings-connection. Which is not the case during AddAndActivatate. + * Probably, AddAndActivate is broken for VPN. */ if (activation_type != NM_ACTIVATION_TYPE_MANAGED) g_return_val_if_reached (NULL); + g_return_val_if_fail (!settings_connection || NM_IS_SETTINGS_CONNECTION (settings_connection), NULL); + if (specific_object) { /* Find the specific connection the client requested we use */ parent = active_connection_get_by_path (self, specific_object); @@ -4535,14 +4360,14 @@ _new_active_connection (NMManager *self, return NULL; } - return (NMActiveConnection *) nm_vpn_connection_new (sett_conn, + return (NMActiveConnection *) nm_vpn_connection_new (settings_connection, parent_device, nm_dbus_object_get_path (NM_DBUS_OBJECT (parent)), activation_reason, subject); } - return (NMActiveConnection *) nm_act_request_new (sett_conn, + return (NMActiveConnection *) nm_act_request_new (settings_connection, applied, specific_object, subject, @@ -4603,17 +4428,17 @@ fail: /** * nm_manager_activate_connection(): * @self: the #NMManager - * @sett_conn: the #NMSettingsConnection to activate on @device + * @connection: the #NMSettingsConnection to activate on @device * @applied: (allow-none): the applied connection to activate on @device * @specific_object: the specific object path, if any, for the activation - * @device: the #NMDevice to activate @sett_conn on. Can be %NULL for VPNs. + * @device: the #NMDevice to activate @connection on. Can be %NULL for VPNs. * @subject: the subject which requested activation * @activation_type: whether to assume the connection. That is, take over gracefully, * non-destructible. * @activation_reason: the reason for activation * @error: return location for an error * - * Begins a new internally-initiated activation of @sett_conn on @device. + * Begins a new internally-initiated activation of @connection on @device. * @subject should be the subject of the activation that triggered this * one, or if this is an autoconnect request, a new internal subject. * The returned #NMActiveConnection is owned by the Manager and should be @@ -4621,11 +4446,11 @@ fail: * is supplied, it shall not be modified by the caller afterwards. * * Returns: (transfer none): the new #NMActiveConnection that tracks - * activation of @sett_conn on @device + * activation of @connection on @device */ NMActiveConnection * nm_manager_activate_connection (NMManager *self, - NMSettingsConnection *sett_conn, + NMSettingsConnection *connection, NMConnection *applied, const char *specific_object, NMDevice *device, @@ -4640,15 +4465,15 @@ nm_manager_activate_connection (NMManager *self, gboolean is_vpn; g_return_val_if_fail (NM_IS_MANAGER (self), NULL); - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn), NULL); - is_vpn = _connection_is_vpn (nm_settings_connection_get_connection (sett_conn)); + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (connection), NULL); + is_vpn = _connection_is_vpn (NM_CONNECTION (connection)); g_return_val_if_fail (is_vpn || NM_IS_DEVICE (device), NULL); g_return_val_if_fail (!error || !*error, NULL); nm_assert (!nm_streq0 (specific_object, "/")); priv = NM_MANAGER_GET_PRIVATE (self); - if (!nm_auth_is_subject_in_acl_set_error (nm_settings_connection_get_connection (sett_conn), + if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (connection), subject, NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -4666,7 +4491,7 @@ nm_manager_activate_connection (NMManager *self, continue; active = async_op_data->ac_auth.active; - if ( sett_conn == nm_active_connection_get_settings_connection (active) + if ( connection == nm_active_connection_get_settings_connection (active) && nm_streq0 (nm_active_connection_get_specific_object (active), specific_object) && (!device || nm_active_connection_get_device (active) == device) && nm_auth_subject_is_internal (nm_active_connection_get_subject (active)) @@ -4677,8 +4502,7 @@ nm_manager_activate_connection (NMManager *self, active = _new_active_connection (self, is_vpn, - sett_conn, - NULL, + NM_CONNECTION (connection), applied, specific_object, device, @@ -4701,9 +4525,7 @@ nm_manager_activate_connection (NMManager *self, * validate_activation_request: * @self: the #NMManager * @context: the D-Bus context of the requestor - * @sett_conn: the #NMSettingsConnection to be activated, or %NULL if there - * is only a partial activation. - * @connection: the partial #NMConnection to be activated (if @sett_conn is unspecified) + * @connection: the partial or complete #NMConnection to be activated * @device_path: the object path of the device to be activated, or NULL * @out_device: on successful reutrn, the #NMDevice to be activated with @connection * The caller may pass in a device which shortcuts the lookup by path. @@ -4722,7 +4544,6 @@ nm_manager_activate_connection (NMManager *self, static NMAuthSubject * validate_activation_request (NMManager *self, GDBusMethodInvocation *context, - NMSettingsConnection *sett_conn, NMConnection *connection, const char *device_path, NMDevice **out_device, @@ -4733,16 +4554,10 @@ validate_activation_request (NMManager *self, gboolean is_vpn = FALSE; gs_unref_object NMAuthSubject *subject = NULL; - nm_assert (!sett_conn || NM_IS_SETTINGS_CONNECTION (sett_conn)); - nm_assert (!connection || NM_IS_CONNECTION (connection)); - nm_assert (sett_conn || connection); - nm_assert (!connection || !sett_conn || connection == nm_settings_connection_get_connection (sett_conn)); + nm_assert (NM_IS_CONNECTION (connection)); nm_assert (out_device); nm_assert (out_is_vpn); - if (!connection) - connection = nm_settings_connection_get_connection (sett_conn); - /* Validate the caller */ subject = nm_auth_subject_new_unix_process_from_context (context); if (!subject) { @@ -4778,20 +4593,17 @@ validate_activation_request (NMManager *self, return NULL; } } else if (!is_vpn) { - gs_free_error GError *local = NULL; - - device = nm_manager_get_best_device_for_connection (self, sett_conn, connection, TRUE, NULL, &local); + device = nm_manager_get_best_device_for_connection (self, connection, TRUE, NULL); if (!device) { gs_free char *iface = NULL; /* VPN and software-device connections don't need a device yet, * but non-virtual connections do ... */ if (!nm_connection_is_virtual (connection)) { - g_set_error (error, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_UNKNOWN_DEVICE, - "No suitable device found for this connection (%s).", - local->message); + g_set_error_literal (error, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "No suitable device found for this connection."); return NULL; } @@ -4877,7 +4689,7 @@ impl_manager_activate_connection (NMDBusObject *obj, NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); gs_unref_object NMActiveConnection *active = NULL; gs_unref_object NMAuthSubject *subject = NULL; - NMSettingsConnection *sett_conn = NULL; + NMSettingsConnection *connection = NULL; NMDevice *device = NULL; gboolean is_vpn = FALSE; GError *error = NULL; @@ -4897,8 +4709,8 @@ impl_manager_activate_connection (NMDBusObject *obj, * (since this is an explicit request, not an auto-activation request). */ if (connection_path) { - sett_conn = nm_settings_get_connection_by_path (priv->settings, connection_path); - if (!sett_conn) { + connection = nm_settings_get_connection_by_path (priv->settings, connection_path); + if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, "Connection could not be found."); @@ -4918,15 +4730,14 @@ impl_manager_activate_connection (NMDBusObject *obj, goto error; } - sett_conn = nm_device_get_best_connection (device, specific_object_path, &error); - if (!sett_conn) + connection = nm_device_get_best_connection (device, specific_object_path, &error); + if (!connection) goto error; } subject = validate_activation_request (self, invocation, - sett_conn, - NULL, + NM_CONNECTION (connection), device_path, &device, &is_vpn, @@ -4936,8 +4747,7 @@ impl_manager_activate_connection (NMDBusObject *obj, active = _new_active_connection (self, is_vpn, - sett_conn, - NULL, + NM_CONNECTION (connection), NULL, specific_object_path, device, @@ -4961,8 +4771,8 @@ impl_manager_activate_connection (NMDBusObject *obj, return; error: - if (sett_conn) { - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, sett_conn, FALSE, NULL, + if (connection) { + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, NULL, subject, error->message); } g_dbus_method_invocation_take_error (invocation, error); @@ -5077,7 +4887,7 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, { NMManager *self = NM_MANAGER (obj); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - gs_unref_object NMConnection *incompl_conn = NULL; + gs_unref_object NMConnection *connection = NULL; NMActiveConnection *active = NULL; gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; @@ -5086,7 +4896,6 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, gs_unref_variant GVariant *settings = NULL; const char *device_path; const char *specific_object_path; - gs_free NMConnection **conns = NULL; g_variant_get (parameters, "(@a{sa{sv}}&o&o)", &settings, &device_path, &specific_object_path); @@ -5100,14 +4909,13 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, * specific data being in the connection till then (especially in * validate_activation_request()). */ - incompl_conn = nm_simple_connection_new (); + connection = nm_simple_connection_new (); if (settings && g_variant_n_children (settings)) - _nm_connection_replace_settings (incompl_conn, settings, NM_SETTING_PARSE_FLAGS_STRICT, NULL); + _nm_connection_replace_settings (connection, settings, NM_SETTING_PARSE_FLAGS_STRICT, NULL); subject = validate_activation_request (self, invocation, - NULL, - incompl_conn, + connection, device_path, &device, &is_vpn, @@ -5117,7 +4925,7 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, if (is_vpn) { /* Try to fill the VPN's connection setting and name at least */ - if (!nm_connection_get_setting_vpn (incompl_conn)) { + if (!nm_connection_get_setting_vpn (connection)) { error = g_error_new_literal (NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_MISSING_SETTING, "VPN connections require a 'vpn' setting"); @@ -5125,31 +4933,27 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, goto error; } - conns = nm_settings_connections_array_to_connections (nm_settings_get_connections (priv->settings, NULL), -1); - nm_utils_complete_generic (priv->platform, - incompl_conn, + connection, NM_SETTING_VPN_SETTING_NAME, - conns, + (NMConnection *const*) nm_settings_get_connections (priv->settings, NULL), NULL, _("VPN connection"), NULL, FALSE); /* No IPv6 by default for now */ } else { - conns = nm_settings_connections_array_to_connections (nm_settings_get_connections (priv->settings, NULL), -1); /* Let each device subclass complete the connection */ if (!nm_device_complete_connection (device, - incompl_conn, + connection, specific_object_path, - conns, + (NMConnection *const*) nm_settings_get_connections (priv->settings, NULL), &error)) goto error; } active = _new_active_connection (self, is_vpn, - NULL, - incompl_conn, + connection, NULL, specific_object_path, device, @@ -5160,16 +4964,15 @@ impl_manager_add_and_activate_connection (NMDBusObject *obj, if (!active) goto error; - nm_active_connection_authorize (active, - incompl_conn, + nm_active_connection_authorize (active, connection, _async_op_complete_ac_auth_cb, _async_op_data_new_ac_auth_add_and_activate (self, active, invocation, - incompl_conn)); + connection)); /* we passed the pointers on to _async_op_data_new_ac_auth_add_and_activate() */ - g_steal_pointer (&incompl_conn); + g_steal_pointer (&connection); g_steal_pointer (&active); return; @@ -5286,7 +5089,7 @@ impl_manager_deactivate_connection (NMDBusObject *obj, NMManager *self = NM_MANAGER (obj); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); NMActiveConnection *ac; - NMSettingsConnection *sett_conn = NULL; + NMSettingsConnection *connection = NULL; GError *error = NULL; NMAuthSubject *subject = NULL; NMAuthChain *chain; @@ -5297,9 +5100,9 @@ impl_manager_deactivate_connection (NMDBusObject *obj, /* Find the connection by its object path */ ac = active_connection_get_by_path (self, active_path); if (ac) - sett_conn = nm_active_connection_get_settings_connection (ac); + connection = nm_active_connection_get_settings_connection (ac); - if (!sett_conn) { + if (!connection) { error = g_error_new_literal (NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, "The connection was not active."); @@ -5315,7 +5118,7 @@ impl_manager_deactivate_connection (NMDBusObject *obj, goto done; } - if (!nm_auth_is_subject_in_acl_set_error (nm_settings_connection_get_connection (sett_conn), + if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (connection), subject, NM_MANAGER_ERROR, NM_MANAGER_ERROR_PERMISSION_DENIED, @@ -5337,9 +5140,8 @@ impl_manager_deactivate_connection (NMDBusObject *obj, done: if (error) { - if (sett_conn) { - nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, - sett_conn, FALSE, NULL, + if (connection) { + nm_audit_log_connection_op (NM_AUDIT_OP_CONN_DEACTIVATE, connection, FALSE, NULL, subject, error->message); } g_dbus_method_invocation_take_error (invocation, error); @@ -6088,76 +5890,66 @@ start_factory (NMDeviceFactory *factory, gpointer user_data) nm_device_factory_start (factory); } -gboolean -nm_manager_write_device_state (NMManager *self, NMDevice *device) +void +nm_manager_write_device_state (NMManager *self) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - int ifindex; - gboolean managed; - NMConfigDeviceStateManagedType managed_type; - const char *uuid = NULL; - const char *perm_hw_addr_fake = NULL; - gboolean perm_hw_addr_is_fake; - guint32 route_metric_default_aspired; - guint32 route_metric_default_effective; - int nm_owned; - - ifindex = nm_device_get_ip_ifindex (device); - if (ifindex <= 0) - return FALSE; - if (ifindex == 1) { - /* ignore loopback */ - return FALSE; - } + NMDevice *device; + gs_unref_hashtable GHashTable *seen_ifindexes = NULL; + gint nm_owned; - if (!nm_platform_link_get (priv->platform, ifindex)) - return FALSE; + seen_ifindexes = g_hash_table_new (nm_direct_hash, NULL); - managed = nm_device_get_managed (device, FALSE); - if (managed) { - NMSettingsConnection *sett_conn; + c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { + int ifindex; + gboolean managed; + NMConfigDeviceStateManagedType managed_type; + NMConnection *settings_connection; + const char *uuid = NULL; + const char *perm_hw_addr_fake = NULL; + gboolean perm_hw_addr_is_fake; + guint32 route_metric_default_aspired; + guint32 route_metric_default_effective; + + ifindex = nm_device_get_ip_ifindex (device); + if (ifindex <= 0) + continue; + if (ifindex == 1) { + /* ignore loopback */ + continue; + } - sett_conn = nm_device_get_settings_connection (device); - if (sett_conn) - uuid = nm_settings_connection_get_uuid (sett_conn); - managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_MANAGED; - } else if (nm_device_get_unmanaged_flags (device, NM_UNMANAGED_USER_EXPLICIT)) - managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNMANAGED; - else - managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNKNOWN; + if (!nm_platform_link_get (priv->platform, ifindex)) + continue; - perm_hw_addr_fake = nm_device_get_permanent_hw_address_full (device, FALSE, &perm_hw_addr_is_fake); - if (perm_hw_addr_fake && !perm_hw_addr_is_fake) - perm_hw_addr_fake = NULL; + managed = nm_device_get_managed (device, FALSE); + if (managed) { + settings_connection = NM_CONNECTION (nm_device_get_settings_connection (device)); + if (settings_connection) + uuid = nm_connection_get_uuid (settings_connection); + managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_MANAGED; + } else if (nm_device_get_unmanaged_flags (device, NM_UNMANAGED_USER_EXPLICIT)) + managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNMANAGED; + else + managed_type = NM_CONFIG_DEVICE_STATE_MANAGED_TYPE_UNKNOWN; - nm_owned = nm_device_is_software (device) ? nm_device_is_nm_owned (device) : -1; + perm_hw_addr_fake = nm_device_get_permanent_hw_address_full (device, FALSE, &perm_hw_addr_is_fake); + if (perm_hw_addr_fake && !perm_hw_addr_is_fake) + perm_hw_addr_fake = NULL; - route_metric_default_effective = _device_route_metric_get (self, ifindex, NM_DEVICE_TYPE_UNKNOWN, - TRUE, &route_metric_default_aspired); + nm_owned = nm_device_is_software (device) ? nm_device_is_nm_owned (device) : -1; - return nm_config_device_state_write (ifindex, - managed_type, - perm_hw_addr_fake, - uuid, - nm_owned, - route_metric_default_aspired, - route_metric_default_effective); -} + route_metric_default_effective = _device_route_metric_get (self, ifindex, NM_DEVICE_TYPE_UNKNOWN, + TRUE, &route_metric_default_aspired); -void -nm_manager_write_device_state_all (NMManager *self) -{ - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - gs_unref_hashtable GHashTable *seen_ifindexes = NULL; - NMDevice *device; - - seen_ifindexes = g_hash_table_new (nm_direct_hash, NULL); - - c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) { - if (nm_manager_write_device_state (self, device)) { - g_hash_table_add (seen_ifindexes, - GINT_TO_POINTER (nm_device_get_ip_ifindex (device))); - } + if (nm_config_device_state_write (ifindex, + managed_type, + perm_hw_addr_fake, + uuid, + nm_owned, + route_metric_default_aspired, + route_metric_default_effective)) + g_hash_table_add (seen_ifindexes, GINT_TO_POINTER (ifindex)); } nm_config_device_state_prune_unseen (seen_ifindexes); @@ -6237,7 +6029,7 @@ nm_manager_start (NMManager *self, GError **error) NULL, NULL, nm_settings_connection_cmp_autoconnect_priority_p_with_data, NULL); for (i = 0; connections[i]; i++) - connection_changed (self, connections[i]); + connection_changed (self, NM_CONNECTION (connections[i])); nm_clear_g_source (&priv->devices_inited_id); priv->devices_inited_id = g_idle_add_full (G_PRIORITY_LOW + 10, devices_inited_cb, self, NULL); @@ -6337,19 +6129,25 @@ connection_metered_changed (GObject *object, } static void -policy_default_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data) +policy_default_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data) { NMManager *self = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); + NMDevice *best; NMActiveConnection *ac; /* Note: this assumes that it's not possible for the IP4 default * route to be going over the default-ip6-device. If that changes, * we need something more complicated here. */ - ac = nm_policy_get_default_ip4_ac (priv->policy); - if (!ac) - ac = nm_policy_get_default_ip6_ac (priv->policy); + best = nm_policy_get_default_ip4_device (priv->policy); + if (!best) + best = nm_policy_get_default_ip6_device (priv->policy); + + if (best) + ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (best)); + else + ac = NULL; if (ac != priv->primary_connection) { if (priv->primary_connection) { @@ -6362,12 +6160,10 @@ policy_default_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_dat priv->primary_connection = ac ? g_object_ref (ac) : NULL; if (priv->primary_connection) { - g_signal_connect (priv->primary_connection, - NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED, + g_signal_connect (priv->primary_connection, NM_ACTIVE_CONNECTION_DEVICE_METERED_CHANGED, G_CALLBACK (connection_metered_changed), self); } - _LOGD (LOGD_CORE, "PrimaryConnection now %s", - ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)"); + _LOGD (LOGD_CORE, "PrimaryConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)"); _notify (self, PROP_PRIMARY_CONNECTION); _notify (self, PROP_PRIMARY_CONNECTION_TYPE); nm_manager_update_metered (self); @@ -6375,29 +6171,34 @@ policy_default_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_dat } static void -policy_activating_ac_changed (GObject *object, GParamSpec *pspec, gpointer user_data) +policy_activating_device_changed (GObject *object, GParamSpec *pspec, gpointer user_data) { NMManager *self = NM_MANAGER (user_data); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - NMActiveConnection *activating, *best; + NMDevice *activating, *best; + NMActiveConnection *ac; - /* We only look at activating-ip6-ac if activating-ip4-ac - * AND default-ip4-ac are NULL; if default-ip4-ac is - * non-NULL, then activating-ip6-ac is irrelevant, since while - * that AC might become the new default-ip6-ac, it can't - * become primary-connection while default-ip4-ac is set to + /* We only look at activating-ip6-device if activating-ip4-device + * AND default-ip4-device are NULL; if default-ip4-device is + * non-NULL, then activating-ip6-device is irrelevant, since while + * that device might become the new default-ip6-device, it can't + * become primary-connection while default-ip4-device is set to * something else. */ - activating = nm_policy_get_activating_ip4_ac (priv->policy); - best = nm_policy_get_default_ip4_ac (priv->policy); + activating = nm_policy_get_activating_ip4_device (priv->policy); + best = nm_policy_get_default_ip4_device (priv->policy); if (!activating && !best) - activating = nm_policy_get_activating_ip6_ac (priv->policy); + activating = nm_policy_get_activating_ip6_device (priv->policy); - if (nm_g_object_ref_set (&priv->activating_connection, activating)) { - _LOGD (LOGD_CORE, "ActivatingConnection now %s", - activating - ? nm_active_connection_get_settings_connection_id (activating) - : "(none)"); + if (activating) + ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (activating)); + else + ac = NULL; + + if (ac != priv->activating_connection) { + g_clear_object (&priv->activating_connection); + priv->activating_connection = ac ? g_object_ref (ac) : NULL; + _LOGD (LOGD_CORE, "ActivatingConnection now %s", ac ? nm_active_connection_get_settings_connection_id (ac) : "(none)"); _notify (self, PROP_ACTIVATING_CONNECTION); } } @@ -6902,12 +6703,12 @@ nm_manager_set_capability (NMManager *self, priv = NM_MANAGER_GET_PRIVATE (self); - idx = nm_utils_array_find_binary_search (&g_array_index (priv->capabilities, guint32, 0), - sizeof (guint32), - priv->capabilities->len, - &cap_i, - nm_cmp_uint32_p_with_data, - NULL); + idx = _nm_utils_array_find_binary_search (&g_array_index (priv->capabilities, guint32, 0), + sizeof (guint32), + priv->capabilities->len, + &cap_i, + nm_cmp_uint32_p_with_data, + NULL); if (idx >= 0) return; @@ -6988,14 +6789,14 @@ constructed (GObject *object) */ priv->policy = nm_policy_new (self, priv->settings); - g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_AC, - G_CALLBACK (policy_default_ac_changed), self); - g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_AC, - G_CALLBACK (policy_default_ac_changed), self); - g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_AC, - G_CALLBACK (policy_activating_ac_changed), self); - g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_AC, - G_CALLBACK (policy_activating_ac_changed), self); + g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP4_DEVICE, + G_CALLBACK (policy_default_device_changed), self); + g_signal_connect (priv->policy, "notify::" NM_POLICY_DEFAULT_IP6_DEVICE, + G_CALLBACK (policy_default_device_changed), self); + g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP4_DEVICE, + G_CALLBACK (policy_activating_device_changed), self); + g_signal_connect (priv->policy, "notify::" NM_POLICY_ACTIVATING_IP6_DEVICE, + G_CALLBACK (policy_activating_device_changed), self); priv->config = g_object_ref (nm_config_get ()); g_signal_connect (G_OBJECT (priv->config), @@ -7333,8 +7134,8 @@ dispose (GObject *object) } if (priv->policy) { - g_signal_handlers_disconnect_by_func (priv->policy, policy_default_ac_changed, self); - g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_ac_changed, self); + g_signal_handlers_disconnect_by_func (priv->policy, policy_default_device_changed, self); + g_signal_handlers_disconnect_by_func (priv->policy, policy_activating_device_changed, self); g_clear_object (&priv->policy); } diff --git a/src/nm-manager.h b/src/nm-manager.h index 11cba1a5..5a462846 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -98,12 +98,10 @@ const CList * nm_manager_get_active_connections (NMManager *manager); iter = c_list_entry (iter->active_connections_lst.next, NMActiveConnection, active_connections_lst)) NMSettingsConnection **nm_manager_get_activatable_connections (NMManager *manager, - gboolean for_auto_activation, - gboolean sort, - guint *out_len); + guint *out_len, + gboolean sort); -void nm_manager_write_device_state_all (NMManager *manager); -gboolean nm_manager_write_device_state (NMManager *manager, NMDevice *device); +void nm_manager_write_device_state (NMManager *manager); /* Device handling */ diff --git a/src/nm-policy.c b/src/nm-policy.c index 7f8c665c..125f2704 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -56,10 +56,10 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMPolicy, PROP_MANAGER, PROP_SETTINGS, - PROP_DEFAULT_IP4_AC, - PROP_DEFAULT_IP6_AC, - PROP_ACTIVATING_IP4_AC, - PROP_ACTIVATING_IP6_AC, + PROP_DEFAULT_IP4_DEVICE, + PROP_DEFAULT_IP6_DEVICE, + PROP_ACTIVATING_IP4_DEVICE, + PROP_ACTIVATING_IP6_DEVICE, ); typedef struct { @@ -79,8 +79,8 @@ typedef struct { NMHostnameManager *hostname_manager; - NMActiveConnection *default_ac4, *activating_ac4; - NMActiveConnection *default_ac6, *activating_ac6; + NMDevice *default_device4, *activating_device4; + NMDevice *default_device6, *activating_device6; struct { GInetAddress *addr; @@ -146,7 +146,6 @@ _PRIV_TO_SELF (NMPolicyPrivate *priv) static void schedule_activate_all (NMPolicy *self); static void schedule_activate_check (NMPolicy *self, NMDevice *device); -static NMDevice *get_default_device (NMPolicy *self, int addr_family); /*****************************************************************************/ @@ -368,56 +367,43 @@ device_ip6_subnet_needed (NMDevice *device, _LOGD (LOGD_IP6, "ipv6-pd: %s needs a subnet", nm_device_get_iface (device)); - if (!priv->default_ac6) { + if (!priv->default_device6) { /* We request the prefixes when the default IPv6 device is set. */ _LOGI (LOGD_IP6, "ipv6-pd: no device to obtain a subnet to share on %s from", nm_device_get_iface (device)); return; } - ip6_subnet_from_device (self, get_default_device (self, AF_INET6), device); - nm_device_copy_ip6_dns_config (device, get_default_device (self, AF_INET6)); + ip6_subnet_from_device (self, priv->default_device6, device); + nm_device_copy_ip6_dns_config (device, priv->default_device6); } /*****************************************************************************/ static NMDevice * -get_default_device (NMPolicy *self, int addr_family) -{ - NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMActiveConnection *ac; - - nm_assert_addr_family (addr_family); - - ac = (addr_family == AF_INET) ? priv->default_ac4 : priv->default_ac6; - - return ac ? nm_active_connection_get_device (ac) : NULL; -} - -static NMActiveConnection * -get_best_active_connection (NMPolicy *self, - int addr_family, - gboolean fully_activated) +get_best_ip_device (NMPolicy *self, + int addr_family, + gboolean fully_activated) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); const CList *tmp_lst; NMDevice *device; + NMDevice *best_device; + NMDevice *prev_device; guint32 best_metric = G_MAXUINT32; gboolean best_is_fully_activated = FALSE; - NMActiveConnection *best_ac, *prev_ac; nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); - /* we prefer the current AC in case of identical metric. - * Hence, try that one first. */ - prev_ac = addr_family == AF_INET - ? (fully_activated ? priv->default_ac4 : priv->activating_ac4) - : (fully_activated ? priv->default_ac6 : priv->activating_ac6); - best_ac = NULL; + /* we prefer the current device in case of identical metric. + * Hence, try that one first.*/ + best_device = NULL; + prev_device = addr_family == AF_INET + ? (fully_activated ? priv->default_device4 : priv->activating_device4) + : (fully_activated ? priv->default_device6 : priv->activating_device6); nm_manager_for_each_device (priv->manager, device, tmp_lst) { NMDeviceState state; const NMPObject *r; - NMActiveConnection *ac; NMConnection *connection; guint32 metric; gboolean is_fully_activated; @@ -449,29 +435,26 @@ get_best_active_connection (NMPolicy *self, } else continue; - ac = (NMActiveConnection *) nm_device_get_act_request (device); - nm_assert (ac); - - if ( !best_ac + if ( !best_device || (!best_is_fully_activated && is_fully_activated) || ( metric < best_metric - || (metric == best_metric && ac == prev_ac))) { - best_ac = ac; + || (metric == best_metric && device == prev_device))) { + best_device = device; best_metric = metric; best_is_fully_activated = is_fully_activated; } } if ( !fully_activated - && best_ac + && best_device && best_is_fully_activated) { - /* There's a best activating AC only if the best device + /* There's only a best activating device if the best device * among all activating and already-activated devices is a * still-activating one. */ return NULL; } - return best_ac; + return best_device; } static gboolean @@ -685,7 +668,6 @@ update_system_hostname (NMPolicy *self, const char *msg) gboolean external_hostname = FALSE; const NMPlatformIP4Address *addr4; const NMPlatformIP6Address *addr6; - NMDevice *device; g_return_if_fail (self != NULL); @@ -738,11 +720,11 @@ update_system_hostname (NMPolicy *self, const char *msg) return; } - if (priv->default_ac4) { + if (priv->default_device4) { NMDhcp4Config *dhcp4_config; /* Grab a hostname out of the device's DHCP4 config */ - dhcp4_config = nm_device_get_dhcp4_config (get_default_device (self, AF_INET)); + dhcp4_config = nm_device_get_dhcp4_config (priv->default_device4); if (dhcp4_config) { dhcp_hostname = nm_dhcp4_config_get_option (dhcp4_config, "host_name"); if (dhcp_hostname && dhcp_hostname[0]) { @@ -758,11 +740,11 @@ update_system_hostname (NMPolicy *self, const char *msg) } } - if (priv->default_ac6) { + if (priv->default_device6) { NMDhcp6Config *dhcp6_config; /* Grab a hostname out of the device's DHCP6 config */ - dhcp6_config = nm_device_get_dhcp6_config (get_default_device (self, AF_INET6)); + dhcp6_config = nm_device_get_dhcp6_config (priv->default_device6); if (dhcp6_config) { dhcp_hostname = nm_dhcp6_config_get_option (dhcp6_config, "host_name"); if (dhcp_hostname && dhcp_hostname[0]) { @@ -797,7 +779,7 @@ update_system_hostname (NMPolicy *self, const char *msg) priv->dhcp_hostname = FALSE; - if (!priv->default_ac4 && !priv->default_ac6) { + if (!priv->default_device4 && !priv->default_device6) { /* No best device; fall back to the last hostname set externally * to NM or if there wasn't one, 'localhost.localdomain' */ @@ -816,11 +798,8 @@ update_system_hostname (NMPolicy *self, const char *msg) /* No configured hostname, no automatically determined hostname, and no * bootup hostname. Start reverse DNS of the current IPv4 or IPv6 address. */ - device = get_default_device (self, AF_INET); - ip4_config = device ? nm_device_get_ip4_config (device) : NULL; - - device = get_default_device (self, AF_INET6); - ip6_config = device ? nm_device_get_ip6_config (device) : NULL; + ip4_config = priv->default_device4 ? nm_device_get_ip4_config (priv->default_device4) : NULL; + ip6_config = priv->default_device6 ? nm_device_get_ip6_config (priv->default_device6) : NULL; if ( ip4_config && (addr4 = nm_ip4_config_get_first_address (ip4_config))) { @@ -873,19 +852,16 @@ get_best_ip_config (NMPolicy *self, NMVpnConnection **out_vpn) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - gpointer conf, best_conf = NULL; + NMDevice *device; + gpointer conf; const CList *tmp_list; NMActiveConnection *ac; - guint64 best_metric = G_MAXUINT64; - NMVpnConnection *best_vpn = NULL; nm_assert (NM_IN_SET (addr_family, AF_INET, AF_INET6)); nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { NMVpnConnection *candidate; NMVpnConnectionState vpn_state; - const NMPObject *obj; - guint32 metric; if (!NM_IS_VPN_CONNECTION (ac)) continue; @@ -903,45 +879,40 @@ get_best_ip_config (NMPolicy *self, if (!conf) continue; - if (addr_family == AF_INET) - obj = nm_ip4_config_best_default_route_get (conf); - else - obj = nm_ip6_config_best_default_route_get (conf); - if (!obj) - continue; - - metric = NMP_OBJECT_CAST_IPX_ROUTE (obj)->rx.metric; - if (metric <= best_metric) { - best_metric = metric; - best_conf = conf; - best_vpn = candidate; + if (addr_family == AF_INET) { + if (!nm_ip4_config_best_default_route_get (conf)) + continue; + } else { + if (!nm_ip6_config_best_default_route_get (conf)) + continue; } - } - if (best_metric != G_MAXUINT64) { + /* FIXME: in case of multiple VPN candidates, choose the one with the + * best metric. */ NM_SET_OUT (out_device, NULL); - NM_SET_OUT (out_vpn, best_vpn); - NM_SET_OUT (out_ac, NM_ACTIVE_CONNECTION (best_vpn)); - NM_SET_OUT (out_ip_iface, nm_vpn_connection_get_ip_iface (best_vpn, TRUE)); - return best_conf; + NM_SET_OUT (out_vpn, candidate); + NM_SET_OUT (out_ac, ac); + NM_SET_OUT (out_ip_iface, nm_vpn_connection_get_ip_iface (candidate, TRUE)); + return conf; } - ac = get_best_active_connection (self, addr_family, TRUE); - if (ac) { - NMDevice *device = nm_active_connection_get_device (ac); - - nm_assert (device); + device = get_best_ip_device (self, addr_family, TRUE); + if (device) { + NMActRequest *req; if (addr_family == AF_INET) conf = nm_device_get_ip4_config (device); else conf = nm_device_get_ip6_config (device); + req = nm_device_get_act_request (device); - NM_SET_OUT (out_device, device); - NM_SET_OUT (out_vpn, NULL); - NM_SET_OUT (out_ac, ac); - NM_SET_OUT (out_ip_iface, nm_device_get_ip_iface (device)); - return conf; + if (conf && req) { + NM_SET_OUT (out_device, device); + NM_SET_OUT (out_vpn, NULL); + NM_SET_OUT (out_ac, NM_ACTIVE_CONNECTION (req)); + NM_SET_OUT (out_ip_iface, nm_device_get_ip_iface (device)); + return conf; + } } NM_SET_OUT (out_device, NULL); @@ -966,17 +937,17 @@ update_ip4_routing (NMPolicy *self, gboolean force_update) * so we can get (vpn != NULL && best == NULL). */ if (!get_best_ip_config (self, AF_INET, &ip_iface, &best_ac, &best, &vpn)) { - if (nm_clear_g_object (&priv->default_ac4)) { - _LOGt (LOGD_DNS, "set-default-ac-4: %p", NULL); - _notify (self, PROP_DEFAULT_IP4_AC); + if (nm_clear_g_object (&priv->default_device4)) { + _LOGt (LOGD_DNS, "set-default-device-4: %p", NULL); + _notify (self, PROP_DEFAULT_IP4_DEVICE); } return; } g_assert ((best || vpn) && best_ac); if ( !force_update - && best_ac - && best_ac == priv->default_ac4) + && best + && best == priv->default_device4) return; if (best) { @@ -988,16 +959,19 @@ update_ip4_routing (NMPolicy *self, gboolean force_update) } } + if (vpn) + best = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); + update_default_ac (self, AF_INET, best_ac); - if (!nm_g_object_ref_set (&priv->default_ac4, best_ac)) + if (!nm_g_object_ref_set (&priv->default_device4, best)) return; - _LOGt (LOGD_DNS, "set-default-ac-4: %p", priv->default_ac4); + _LOGt (LOGD_DNS, "set-default-device-4: %p", priv->default_device4); _LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv4 routing and DNS", nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)), ip_iface); - _notify (self, PROP_DEFAULT_IP4_AC); + _notify (self, PROP_DEFAULT_IP4_DEVICE); } static void @@ -1011,7 +985,7 @@ update_ip6_dns_delegation (NMPolicy *self) nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { device = nm_active_connection_get_device (ac); if (device && nm_device_needs_ip6_subnet (device)) - nm_device_copy_ip6_dns_config (device, get_default_device (self, AF_INET6)); + nm_device_copy_ip6_dns_config (device, priv->default_device6); } } @@ -1027,7 +1001,7 @@ update_ip6_prefix_delegation (NMPolicy *self) nm_manager_for_each_active_connection (priv->manager, ac, tmp_list) { device = nm_active_connection_get_device (ac); if (device && nm_device_needs_ip6_subnet (device)) - ip6_subnet_from_device (self, get_default_device (self, AF_INET6), device); + ip6_subnet_from_device (self, priv->default_device6, device); } } @@ -1046,17 +1020,17 @@ update_ip6_routing (NMPolicy *self, gboolean force_update) * so we can get (vpn != NULL && best == NULL). */ if (!get_best_ip_config (self, AF_INET6, &ip_iface, &best_ac, &best, &vpn)) { - if (nm_clear_g_object (&priv->default_ac6)) { - _LOGt (LOGD_DNS, "set-default-ac-6: %p", NULL); - _notify (self, PROP_DEFAULT_IP6_AC); + if (nm_clear_g_object (&priv->default_device6)) { + _LOGt (LOGD_DNS, "set-default-device-6: %p", NULL); + _notify (self, PROP_DEFAULT_IP6_DEVICE); } return; } g_assert ((best || vpn) && best_ac); if ( !force_update - && best_ac - && best_ac == priv->default_ac6) + && best + && best == priv->default_device6) return; if (best) { @@ -1068,18 +1042,21 @@ update_ip6_routing (NMPolicy *self, gboolean force_update) } } + if (vpn) + best = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); + update_default_ac (self, AF_INET6, best_ac); - if (!nm_g_object_ref_set (&priv->default_ac6, best_ac)) + if (!nm_g_object_ref_set (&priv->default_device6, best)) return; - _LOGt (LOGD_DNS, "set-default-ac-6: %p", priv->default_ac6); + _LOGt (LOGD_DNS, "set-default-device-6: %p", priv->default_device6); update_ip6_prefix_delegation (self); _LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv6 routing and DNS", nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)), ip_iface); - _notify (self, PROP_DEFAULT_IP6_AC); + _notify (self, PROP_DEFAULT_IP6_DEVICE); } static void @@ -1127,23 +1104,23 @@ update_routing_and_dns (NMPolicy *self, gboolean force_update) } static void -check_activating_active_connections (NMPolicy *self) +check_activating_devices (NMPolicy *self) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMActiveConnection *best4, *best6 = NULL; + NMDevice *best4, *best6 = NULL; - best4 = get_best_active_connection (self, AF_INET, FALSE); - best6 = get_best_active_connection (self, AF_INET6, FALSE); + best4 = get_best_ip_device (self, AF_INET, FALSE); + best6 = get_best_ip_device (self, AF_INET6, FALSE); g_object_freeze_notify (G_OBJECT (self)); - if (nm_g_object_ref_set (&priv->activating_ac4, best4)) { - _LOGt (LOGD_DNS, "set-activating-ac-4: %p", priv->activating_ac4); - _notify (self, PROP_ACTIVATING_IP4_AC); + if (nm_g_object_ref_set (&priv->activating_device4, best4)) { + _LOGt (LOGD_DNS, "set-activating-device-4: %p", priv->activating_device4); + _notify (self, PROP_ACTIVATING_IP4_DEVICE); } - if (nm_g_object_ref_set (&priv->activating_ac6, best6)) { - _LOGt (LOGD_DNS, "set-activating-ac-6: %p", priv->activating_ac6); - _notify (self, PROP_ACTIVATING_IP6_AC); + if (nm_g_object_ref_set (&priv->activating_device6, best6)) { + _LOGt (LOGD_DNS, "set-activating-device-6: %p", priv->activating_device6); + _notify (self, PROP_ACTIVATING_IP6_DEVICE); } g_object_thaw_notify (G_OBJECT (self)); @@ -1235,33 +1212,30 @@ auto_activate_device (NMPolicy *self, if (!nm_device_autoconnect_allowed (device)) return; - connections = nm_manager_get_activatable_connections (priv->manager, TRUE, TRUE, &len); + connections = nm_manager_get_activatable_connections (priv->manager, &len, TRUE); if (!connections[0]) return; /* Find the first connection that should be auto-activated */ best_connection = NULL; for (i = 0; i < len; i++) { - NMSettingsConnection *candidate = connections[i]; - NMConnection *cand_conn; + NMSettingsConnection *candidate = NM_SETTINGS_CONNECTION (connections[i]); NMSettingConnection *s_con; const char *permission; if (nm_settings_connection_autoconnect_is_blocked (candidate)) continue; - cand_conn = nm_settings_connection_get_connection (candidate); - - s_con = nm_connection_get_setting_connection (cand_conn); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (candidate)); if (!nm_setting_connection_get_autoconnect (s_con)) continue; - permission = nm_utils_get_shared_wifi_permission (cand_conn); + permission = nm_utils_get_shared_wifi_permission (NM_CONNECTION (candidate)); if ( permission && !nm_settings_connection_check_permission (candidate, permission)) continue; - if (nm_device_can_auto_connect (device, candidate, &specific_object)) { + if (nm_device_can_auto_connect (device, (NMConnection *) candidate, &specific_object)) { best_connection = candidate; break; } @@ -1444,36 +1418,34 @@ reset_autoconnect_all (NMPolicy *self, connections = nm_settings_get_connections (priv->settings, NULL); for (i = 0; connections[i]; i++) { - NMSettingsConnection *sett_conn = connections[i]; + NMSettingsConnection *connection = connections[i]; if ( device - && !nm_device_check_connection_compatible (device, - nm_settings_connection_get_connection (sett_conn), - NULL)) + && !nm_device_check_connection_compatible (device, NM_CONNECTION (connection))) continue; if (only_no_secrets) { /* we only reset the no-secrets blocked flag. */ - if (nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, + if (nm_settings_connection_autoconnect_blocked_reason_set (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, FALSE)) { /* maybe the connection is still blocked afterwards for other reasons * and in the larger picture nothing changed. But it's too complicated * to find out exactly. Just assume, something changed to be sure. */ - if (!nm_settings_connection_autoconnect_is_blocked (sett_conn)) + if (!nm_settings_connection_autoconnect_is_blocked (connection)) changed = TRUE; } } else { /* we reset the tries-count and any blocked-reason */ - if (nm_settings_connection_autoconnect_retries_get (sett_conn) == 0) + if (nm_settings_connection_autoconnect_retries_get (connection) == 0) changed = TRUE; - nm_settings_connection_autoconnect_retries_reset (sett_conn); + nm_settings_connection_autoconnect_retries_reset (connection); - if (nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, + if (nm_settings_connection_autoconnect_blocked_reason_set (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL & ~NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST, FALSE)) { - if (!nm_settings_connection_autoconnect_is_blocked (sett_conn)) + if (!nm_settings_connection_autoconnect_is_blocked (connection)) changed = TRUE; } } @@ -1594,9 +1566,7 @@ static void activate_slave_connections (NMPolicy *self, NMDevice *device) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - const char *master_device; - const char *master_uuid_settings = NULL; - const char *master_uuid_applied = NULL; + const char *master_device, *master_uuid_settings = NULL, *master_uuid_applied = NULL; guint i; NMActRequest *req; gboolean internal_activation = FALSE; @@ -1608,18 +1578,16 @@ activate_slave_connections (NMPolicy *self, NMDevice *device) req = nm_device_get_act_request (device); if (req) { - NMConnection *connection; - NMSettingsConnection *sett_conn; + NMConnection *con; NMAuthSubject *subject; - connection = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (req)); - if (connection) - master_uuid_applied = nm_connection_get_uuid (connection); - - sett_conn = nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (req)); - if (sett_conn) { - master_uuid_settings = nm_settings_connection_get_uuid (sett_conn); - if (nm_streq0 (master_uuid_settings, master_uuid_applied)) + con = nm_active_connection_get_applied_connection (NM_ACTIVE_CONNECTION (req)); + if (con) + master_uuid_applied = nm_connection_get_uuid (con); + con = NM_CONNECTION (nm_active_connection_get_settings_connection (NM_ACTIVE_CONNECTION (req))); + if (con) { + master_uuid_settings = nm_connection_get_uuid (con); + if (!g_strcmp0 (master_uuid_settings, master_uuid_applied)) master_uuid_settings = NULL; } @@ -1630,11 +1598,11 @@ activate_slave_connections (NMPolicy *self, NMDevice *device) changed = FALSE; connections = nm_settings_get_connections (priv->settings, NULL); for (i = 0; connections[i]; i++) { - NMSettingsConnection *sett_conn = connections[i]; + NMSettingsConnection *connection = connections[i]; NMSettingConnection *s_slave_con; const char *slave_master; - s_slave_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (sett_conn)); + s_slave_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); slave_master = nm_setting_connection_get_master (s_slave_con); if (!slave_master) continue; @@ -1644,14 +1612,14 @@ activate_slave_connections (NMPolicy *self, NMDevice *device) continue; if (!internal_activation) { - if (nm_settings_connection_autoconnect_retries_get (sett_conn) == 0) + if (nm_settings_connection_autoconnect_retries_get (connection) == 0) changed = TRUE; - nm_settings_connection_autoconnect_retries_reset (sett_conn); + nm_settings_connection_autoconnect_retries_reset (connection); } - if (nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, + if (nm_settings_connection_autoconnect_blocked_reason_set (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, FALSE)) { - if (!nm_settings_connection_autoconnect_is_blocked (sett_conn)) + if (!nm_settings_connection_autoconnect_is_blocked (connection)) changed = TRUE; } } @@ -1667,6 +1635,7 @@ activate_secondary_connections (NMPolicy *self, { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); NMSettingConnection *s_con; + NMSettingsConnection *settings_con; NMActiveConnection *ac; PendingSecondaryData *secondary_data; GSList *secondary_ac_list = NULL; @@ -1675,25 +1644,22 @@ activate_secondary_connections (NMPolicy *self, gboolean success = TRUE; s_con = nm_connection_get_setting_connection (connection); - nm_assert (s_con); + g_assert (s_con); for (i = 0; i < nm_setting_connection_get_num_secondaries (s_con); i++) { - NMSettingsConnection *sett_conn; const char *sec_uuid = nm_setting_connection_get_secondary (s_con, i); NMActRequest *req; - sett_conn = nm_settings_get_connection_by_uuid (priv->settings, sec_uuid); - if (!sett_conn) { + settings_con = nm_settings_get_connection_by_uuid (priv->settings, sec_uuid); + if (!settings_con) { _LOGW (LOGD_DEVICE, "secondary connection '%s' auto-activation failed: The connection doesn't exist.", sec_uuid); success = FALSE; break; } - - if (!nm_connection_is_type (nm_settings_connection_get_connection (sett_conn), - NM_SETTING_VPN_SETTING_NAME)) { + if (!nm_connection_is_type (NM_CONNECTION (settings_con), NM_SETTING_VPN_SETTING_NAME)) { _LOGW (LOGD_DEVICE, "secondary connection '%s (%s)' auto-activation failed: The connection is not a VPN.", - nm_settings_connection_get_id (sett_conn), sec_uuid); + nm_settings_connection_get_id (settings_con), sec_uuid); success = FALSE; break; } @@ -1702,10 +1668,10 @@ activate_secondary_connections (NMPolicy *self, g_assert (req); _LOGD (LOGD_DEVICE, "activating secondary connection '%s (%s)' for base connection '%s (%s)'", - nm_settings_connection_get_id (sett_conn), sec_uuid, + nm_settings_connection_get_id (settings_con), sec_uuid, nm_connection_get_id (connection), nm_connection_get_uuid (connection)); ac = nm_manager_activate_connection (priv->manager, - sett_conn, + settings_con, NULL, nm_dbus_object_get_path (NM_DBUS_OBJECT (req)), device, @@ -1717,7 +1683,7 @@ activate_secondary_connections (NMPolicy *self, secondary_ac_list = g_slist_append (secondary_ac_list, g_object_ref (ac)); else { _LOGW (LOGD_DEVICE, "secondary connection '%s (%s)' auto-activation failed: (%d) %s", - nm_settings_connection_get_id (sett_conn), sec_uuid, + nm_settings_connection_get_id (settings_con), sec_uuid, error->code, error->message); g_clear_error (&error); @@ -1745,7 +1711,7 @@ device_state_changed (NMDevice *device, NMPolicyPrivate *priv = user_data; NMPolicy *self = _PRIV_TO_SELF (priv); NMActiveConnection *ac; - NMSettingsConnection *sett_conn = nm_device_get_settings_connection (device); + NMSettingsConnection *connection = nm_device_get_settings_connection (device); NMIP4Config *ip4_config; NMIP6Config *ip6_config; NMSettingConnection *s_con = NULL; @@ -1763,8 +1729,8 @@ device_state_changed (NMDevice *device, /* Block autoconnect of the just-failed connection for situations * where a retry attempt would just fail again. */ - if (sett_conn) { - nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, + if (connection) { + nm_settings_connection_autoconnect_blocked_reason_set (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_FAILED, TRUE); } @@ -1778,7 +1744,7 @@ device_state_changed (NMDevice *device, /* Mark the connection invalid if it failed during activation so that * it doesn't get automatically chosen over and over and over again. */ - if ( sett_conn + if ( connection && old_state >= NM_DEVICE_STATE_PREPARE && old_state <= NM_DEVICE_STATE_ACTIVATED) { gboolean block_no_secrets = FALSE; @@ -1799,7 +1765,7 @@ device_state_changed (NMDevice *device, * That can happen when nm_settings_connection_get_secrets() fails early without actually * consulting any agents. */ - con_v = nm_settings_connection_get_last_secret_agent_version_id (sett_conn); + con_v = nm_settings_connection_get_last_secret_agent_version_id (connection); if ( con_v == 0 || con_v == nm_agent_manager_get_agent_version_id (priv->agent_mgr)) block_no_secrets = TRUE; @@ -1807,35 +1773,33 @@ device_state_changed (NMDevice *device, if (block_no_secrets) { _LOGD (LOGD_DEVICE, "connection '%s' now blocked from autoconnect due to no secrets", - nm_settings_connection_get_id (sett_conn)); - nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, TRUE); + nm_settings_connection_get_id (connection)); + nm_settings_connection_autoconnect_blocked_reason_set (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, TRUE); } else { - tries = nm_settings_connection_autoconnect_retries_get (sett_conn); + tries = nm_settings_connection_autoconnect_retries_get (connection); if (tries > 0) { _LOGD (LOGD_DEVICE, "connection '%s' failed to autoconnect; %d tries left", - nm_settings_connection_get_id (sett_conn), tries - 1); - _connection_autoconnect_retries_set (self, sett_conn, tries - 1); + nm_settings_connection_get_id (connection), tries - 1); + _connection_autoconnect_retries_set (self, connection, tries - 1); } else if (tries != 0) { _LOGD (LOGD_DEVICE, "connection '%s' failed to autoconnect; infinite tries left", - nm_settings_connection_get_id (sett_conn)); + nm_settings_connection_get_id (connection)); } } - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - nm_connection_clear_secrets (nm_settings_connection_get_connection (sett_conn)); + nm_connection_clear_secrets (NM_CONNECTION (connection)); } break; case NM_DEVICE_STATE_ACTIVATED: - if (sett_conn) { + if (connection) { /* Reset auto retries back to default since connection was successful */ - nm_settings_connection_autoconnect_retries_reset (sett_conn); + nm_settings_connection_autoconnect_retries_reset (connection); /* And clear secrets so they will always be requested from the * settings service when the next connection is made. */ - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - nm_connection_clear_secrets (nm_settings_connection_get_connection (sett_conn)); + nm_connection_clear_secrets (NM_CONNECTION (connection)); } /* Add device's new IPv4 and IPv6 configs to DNS */ @@ -1859,7 +1823,7 @@ device_state_changed (NMDevice *device, update_routing_and_dns (self, FALSE); break; case NM_DEVICE_STATE_DEACTIVATING: - if (sett_conn) { + if (connection) { NMSettingsAutoconnectBlockedReason blocked_reason = NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE; switch (nm_device_state_reason_check (reason)) { @@ -1874,10 +1838,10 @@ device_state_changed (NMDevice *device, } if (blocked_reason != NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NONE) { _LOGD (LOGD_DEVICE, "blocking autoconnect of connection '%s': %s", - nm_settings_connection_get_id (sett_conn), + nm_settings_connection_get_id (connection), NM_UTILS_LOOKUP_STR (nm_device_state_reason_to_str, nm_device_state_reason_check (reason))); - nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, blocked_reason, TRUE); + nm_settings_connection_autoconnect_blocked_reason_set (connection, blocked_reason, TRUE); } } ip6_remove_device_prefix_delegations (self, device); @@ -1913,25 +1877,20 @@ device_state_changed (NMDevice *device, break; case NM_DEVICE_STATE_IP_CONFIG: /* We must have secrets if we got here. */ - if (sett_conn) - nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL, FALSE); + if (connection) + nm_settings_connection_autoconnect_blocked_reason_set (connection, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_ALL, FALSE); break; case NM_DEVICE_STATE_SECONDARIES: - if (sett_conn) - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (sett_conn)); - if ( s_con - && nm_setting_connection_get_num_secondaries (s_con) > 0) { + if (connection) + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); + if (s_con && nm_setting_connection_get_num_secondaries (s_con) > 0) { /* Make routes and DNS up-to-date before activating dependent connections */ update_routing_and_dns (self, FALSE); /* Activate secondary (VPN) connections */ - if (!activate_secondary_connections (self, - nm_settings_connection_get_connection (sett_conn), - device)) { - nm_device_queue_state (device, - NM_DEVICE_STATE_FAILED, + if (!activate_secondary_connections (self, NM_CONNECTION (connection), device)) + nm_device_queue_state (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED); - } } else nm_device_queue_state (device, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_NONE); @@ -1941,7 +1900,7 @@ device_state_changed (NMDevice *device, break; } - check_activating_active_connections (self); + check_activating_devices (self); } static void @@ -2423,28 +2382,28 @@ secret_agent_registered (NMSettings *settings, schedule_activate_all (self); } -NMActiveConnection * -nm_policy_get_default_ip4_ac (NMPolicy *self) +NMDevice * +nm_policy_get_default_ip4_device (NMPolicy *self) { - return NM_POLICY_GET_PRIVATE (self)->default_ac4; + return NM_POLICY_GET_PRIVATE (self)->default_device4; } -NMActiveConnection * -nm_policy_get_default_ip6_ac (NMPolicy *self) +NMDevice * +nm_policy_get_default_ip6_device (NMPolicy *self) { - return NM_POLICY_GET_PRIVATE (self)->default_ac6; + return NM_POLICY_GET_PRIVATE (self)->default_device6; } -NMActiveConnection * -nm_policy_get_activating_ip4_ac (NMPolicy *self) +NMDevice * +nm_policy_get_activating_ip4_device (NMPolicy *self) { - return NM_POLICY_GET_PRIVATE (self)->activating_ac4; + return NM_POLICY_GET_PRIVATE (self)->activating_device4; } -NMActiveConnection * -nm_policy_get_activating_ip6_ac (NMPolicy *self) +NMDevice * +nm_policy_get_activating_ip6_device (NMPolicy *self) { - return NM_POLICY_GET_PRIVATE (self)->activating_ac6; + return NM_POLICY_GET_PRIVATE (self)->activating_device6; } /*****************************************************************************/ @@ -2466,17 +2425,17 @@ get_property (GObject *object, guint prop_id, NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); switch (prop_id) { - case PROP_DEFAULT_IP4_AC: - g_value_set_object (value, priv->default_ac4); + case PROP_DEFAULT_IP4_DEVICE: + g_value_set_object (value, priv->default_device4); break; - case PROP_DEFAULT_IP6_AC: - g_value_set_object (value, priv->default_ac6); + case PROP_DEFAULT_IP6_DEVICE: + g_value_set_object (value, priv->default_device6); break; - case PROP_ACTIVATING_IP4_AC: - g_value_set_object (value, priv->activating_ac4); + case PROP_ACTIVATING_IP4_DEVICE: + g_value_set_object (value, priv->activating_device4); break; - case PROP_ACTIVATING_IP6_AC: - g_value_set_object (value, priv->activating_ac6); + case PROP_ACTIVATING_IP6_DEVICE: + g_value_set_object (value, priv->activating_device6); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -2617,10 +2576,10 @@ dispose (GObject *object) g_clear_object (&priv->lookup.addr); g_clear_object (&priv->lookup.resolver); - nm_clear_g_object (&priv->default_ac4); - nm_clear_g_object (&priv->default_ac6); - nm_clear_g_object (&priv->activating_ac4); - nm_clear_g_object (&priv->activating_ac6); + nm_clear_g_object (&priv->default_device4); + nm_clear_g_object (&priv->default_device6); + nm_clear_g_object (&priv->activating_device4); + nm_clear_g_object (&priv->activating_device6); g_clear_pointer (&priv->pending_active_connections, g_hash_table_unref); c_list_for_each_entry_safe (data, data_safe, &priv->pending_activation_checks, pending_lst) @@ -2726,23 +2685,23 @@ nm_policy_class_init (NMPolicyClass *policy_class) G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_DEFAULT_IP4_AC] = - g_param_spec_object (NM_POLICY_DEFAULT_IP4_AC, "", "", - NM_TYPE_ACTIVE_CONNECTION, + obj_properties[PROP_DEFAULT_IP4_DEVICE] = + g_param_spec_object (NM_POLICY_DEFAULT_IP4_DEVICE, "", "", + NM_TYPE_DEVICE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_DEFAULT_IP6_AC] = - g_param_spec_object (NM_POLICY_DEFAULT_IP6_AC, "", "", + obj_properties[PROP_DEFAULT_IP6_DEVICE] = + g_param_spec_object (NM_POLICY_DEFAULT_IP6_DEVICE, "", "", NM_TYPE_DEVICE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_ACTIVATING_IP4_AC] = - g_param_spec_object (NM_POLICY_ACTIVATING_IP4_AC, "", "", + obj_properties[PROP_ACTIVATING_IP4_DEVICE] = + g_param_spec_object (NM_POLICY_ACTIVATING_IP4_DEVICE, "", "", NM_TYPE_DEVICE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); - obj_properties[PROP_ACTIVATING_IP6_AC] = - g_param_spec_object (NM_POLICY_ACTIVATING_IP6_AC, "", "", + obj_properties[PROP_ACTIVATING_IP6_DEVICE] = + g_param_spec_object (NM_POLICY_ACTIVATING_IP6_DEVICE, "", "", NM_TYPE_DEVICE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); diff --git a/src/nm-policy.h b/src/nm-policy.h index 916ede00..2c96e6d0 100644 --- a/src/nm-policy.h +++ b/src/nm-policy.h @@ -31,10 +31,10 @@ #define NM_POLICY_MANAGER "manager" #define NM_POLICY_SETTINGS "settings" -#define NM_POLICY_DEFAULT_IP4_AC "default-ip4-ac" -#define NM_POLICY_DEFAULT_IP6_AC "default-ip6-ac" -#define NM_POLICY_ACTIVATING_IP4_AC "activating-ip4-ac" -#define NM_POLICY_ACTIVATING_IP6_AC "activating-ip6-ac" +#define NM_POLICY_DEFAULT_IP4_DEVICE "default-ip4-device" +#define NM_POLICY_DEFAULT_IP6_DEVICE "default-ip6-device" +#define NM_POLICY_ACTIVATING_IP4_DEVICE "activating-ip4-device" +#define NM_POLICY_ACTIVATING_IP6_DEVICE "activating-ip6-device" typedef struct _NMPolicyClass NMPolicyClass; @@ -42,10 +42,10 @@ GType nm_policy_get_type (void); NMPolicy *nm_policy_new (NMManager *manager, NMSettings *settings); -NMActiveConnection *nm_policy_get_default_ip4_ac (NMPolicy *policy); -NMActiveConnection *nm_policy_get_default_ip6_ac (NMPolicy *policy); -NMActiveConnection *nm_policy_get_activating_ip4_ac (NMPolicy *policy); -NMActiveConnection *nm_policy_get_activating_ip6_ac (NMPolicy *policy); +NMDevice *nm_policy_get_default_ip4_device (NMPolicy *policy); +NMDevice *nm_policy_get_default_ip6_device (NMPolicy *policy); +NMDevice *nm_policy_get_activating_ip4_device (NMPolicy *policy); +NMDevice *nm_policy_get_activating_ip6_device (NMPolicy *policy); /** * NMPolicyHostnameMode diff --git a/src/nm-rfkill-manager.c b/src/nm-rfkill-manager.c index a7bc694a..b2909e9d 100644 --- a/src/nm-rfkill-manager.c +++ b/src/nm-rfkill-manager.c @@ -65,7 +65,7 @@ typedef struct { char *path; char *driver; RfKillType rtype; - int state; + gint state; gboolean platform; } Killswitch; @@ -158,7 +158,7 @@ killswitch_destroy (Killswitch *ks) } static RfKillState -sysfs_state_to_nm_state (int sysfs_state) +sysfs_state_to_nm_state (gint sysfs_state) { switch (sysfs_state) { case 0: diff --git a/src/nm-session-monitor.c b/src/nm-session-monitor.c index b67c537c..23d41d7e 100644 --- a/src/nm-session-monitor.c +++ b/src/nm-session-monitor.c @@ -28,26 +28,24 @@ #include <string.h> #include <sys/stat.h> -#if SESSION_TRACKING_SYSTEMD && SESSION_TRACKING_ELOGIND +#if defined (SESSION_TRACKING_SYSTEMD) && defined (SESSION_TRACKING_ELOGIND) #error Cannot build both systemd-logind and elogind support #endif -#if SESSION_TRACKING_SYSTEMD +#ifdef SESSION_TRACKING_SYSTEMD #include <systemd/sd-login.h> #define LOGIND_NAME "systemd-logind" #endif -#if SESSION_TRACKING_ELOGIND +#ifdef SESSION_TRACKING_ELOGIND #include <elogind/sd-login.h> #define LOGIND_NAME "elogind" +/* Re-Use SESSION_TRACKING_SYSTEMD as elogind substitutes systemd-login */ +#define SESSION_TRACKING_SYSTEMD 1 #endif #include "NetworkManagerUtils.h" -#define SESSION_TRACKING_XLOGIND (SESSION_TRACKING_SYSTEMD || SESSION_TRACKING_ELOGIND) - -#define CKDB_PATH "/var/run/ConsoleKit/database" - /*****************************************************************************/ enum { @@ -60,14 +58,14 @@ static guint signals[LAST_SIGNAL] = { 0 }; struct _NMSessionMonitor { GObject parent; -#if SESSION_TRACKING_XLOGIND +#ifdef SESSION_TRACKING_SYSTEMD struct { sd_login_monitor *monitor; guint watch; } sd; #endif -#if SESSION_TRACKING_CONSOLEKIT +#ifdef SESSION_TRACKING_CONSOLEKIT struct { GFileMonitor *monitor; GHashTable *cache; @@ -87,7 +85,7 @@ G_DEFINE_TYPE (NMSessionMonitor, nm_session_monitor, G_TYPE_OBJECT); /*****************************************************************************/ -#if SESSION_TRACKING_XLOGIND +#ifdef SESSION_TRACKING_SYSTEMD static gboolean st_sd_session_exists (NMSessionMonitor *monitor, uid_t uid, gboolean active) { @@ -145,11 +143,11 @@ st_sd_finalize (NMSessionMonitor *monitor) } nm_clear_g_source (&monitor->sd.watch); } -#endif /* SESSION_TRACKING_XLOGIND */ +#endif /* SESSION_TRACKING_SYSTEMD */ /*****************************************************************************/ -#if SESSION_TRACKING_CONSOLEKIT +#ifdef SESSION_TRACKING_CONSOLEKIT typedef struct { gboolean active; } CkSession; @@ -188,7 +186,7 @@ ck_load_cache (GHashTable *cache) if (error) goto out; - g_hash_table_insert (cache, GUINT_TO_POINTER (uid), nm_memdup (&session, sizeof session)); + g_hash_table_insert (cache, GUINT_TO_POINTER (uid), g_memdup (&session, sizeof session)); } finished = TRUE; @@ -354,12 +352,12 @@ nm_session_monitor_session_exists (NMSessionMonitor *self, { g_return_val_if_fail (NM_IS_SESSION_MONITOR (self), FALSE); -#if SESSION_TRACKING_XLOGIND +#ifdef SESSION_TRACKING_SYSTEMD if (st_sd_session_exists (self, uid, active)) return TRUE; #endif -#if SESSION_TRACKING_CONSOLEKIT +#ifdef SESSION_TRACKING_CONSOLEKIT if (ck_session_exists (self, uid, active)) return TRUE; #endif @@ -372,12 +370,12 @@ nm_session_monitor_session_exists (NMSessionMonitor *self, static void nm_session_monitor_init (NMSessionMonitor *monitor) { -#if SESSION_TRACKING_XLOGIND +#ifdef SESSION_TRACKING_SYSTEMD st_sd_init (monitor); _LOGD ("using "LOGIND_NAME" session tracking"); #endif -#if SESSION_TRACKING_CONSOLEKIT +#ifdef SESSION_TRACKING_CONSOLEKIT ck_init (monitor); _LOGD ("using ConsoleKit session tracking"); #endif @@ -386,11 +384,11 @@ nm_session_monitor_init (NMSessionMonitor *monitor) static void finalize (GObject *object) { -#if SESSION_TRACKING_XLOGIND +#ifdef SESSION_TRACKING_SYSTEMD st_sd_finalize (NM_SESSION_MONITOR (object)); #endif -#if SESSION_TRACKING_CONSOLEKIT +#ifdef SESSION_TRACKING_CONSOLEKIT ck_finalize (NM_SESSION_MONITOR (object)); #endif diff --git a/src/nm-sleep-monitor.c b/src/nm-sleep-monitor.c index 54d75773..a7e3a7c3 100644 --- a/src/nm-sleep-monitor.c +++ b/src/nm-sleep-monitor.c @@ -84,7 +84,7 @@ struct _NMSleepMonitor { /* used both during construction of proxy and during Inhibit call. */ GCancellable *cancellable; - int inhibit_fd; + gint inhibit_fd; GSList *handles_active; GSList *handles_stale; diff --git a/src/nm-test-utils-core.h b/src/nm-test-utils-core.h index 5e89cb39..c76f510f 100644 --- a/src/nm-test-utils-core.h +++ b/src/nm-test-utils-core.h @@ -216,8 +216,8 @@ nmtst_platform_ip4_routes_equal (const NMPlatformIP4Route *a, const NMPlatformIP g_assert (b); if (ignore_order) { - a = c_a = nm_memdup (a, sizeof (NMPlatformIP4Route) * len); - b = c_b = nm_memdup (b, sizeof (NMPlatformIP4Route) * len); + a = c_a = g_memdup (a, sizeof (NMPlatformIP4Route) * len); + b = c_b = g_memdup (b, sizeof (NMPlatformIP4Route) * len); g_qsort_with_data (c_a, len, sizeof (NMPlatformIP4Route), _nmtst_platform_ip4_routes_equal_sort, NULL); g_qsort_with_data (c_b, len, sizeof (NMPlatformIP4Route), _nmtst_platform_ip4_routes_equal_sort, NULL); } @@ -269,8 +269,8 @@ nmtst_platform_ip6_routes_equal (const NMPlatformIP6Route *a, const NMPlatformIP g_assert (b); if (ignore_order) { - a = c_a = nm_memdup (a, sizeof (NMPlatformIP6Route) * len); - b = c_b = nm_memdup (b, sizeof (NMPlatformIP6Route) * len); + a = c_a = g_memdup (a, sizeof (NMPlatformIP6Route) * len); + b = c_b = g_memdup (b, sizeof (NMPlatformIP6Route) * len); g_qsort_with_data (c_a, len, sizeof (NMPlatformIP6Route), _nmtst_platform_ip6_routes_equal_sort, NULL); g_qsort_with_data (c_b, len, sizeof (NMPlatformIP6Route), _nmtst_platform_ip6_routes_equal_sort, NULL); } diff --git a/src/nm-types.h b/src/nm-types.h index a0a7f620..1477d226 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 - 2018 Red Hat, Inc. + * Copyright (C) 2012 - 2017 Red Hat, Inc. */ #ifndef __NETWORKMANAGER_TYPES_H__ @@ -150,8 +150,6 @@ typedef enum { NM_LINK_TYPE_WIFI, NM_LINK_TYPE_WWAN_NET, /* WWAN kernel netdevice */ NM_LINK_TYPE_WIMAX, - NM_LINK_TYPE_WPAN, - NM_LINK_TYPE_6LOWPAN, /* Software types */ NM_LINK_TYPE_BNEP = 0x10000, /* Bluetooth Ethernet emulation */ @@ -160,8 +158,6 @@ typedef enum { NM_LINK_TYPE_GRETAP, NM_LINK_TYPE_IFB, NM_LINK_TYPE_IP6TNL, - NM_LINK_TYPE_IP6GRE, - NM_LINK_TYPE_IP6GRETAP, NM_LINK_TYPE_IPIP, NM_LINK_TYPE_LOOPBACK, NM_LINK_TYPE_MACSEC, @@ -174,7 +170,6 @@ typedef enum { NM_LINK_TYPE_VETH, NM_LINK_TYPE_VLAN, NM_LINK_TYPE_VXLAN, - NM_LINK_TYPE_WIREGUARD, /* Software types with slaves */ NM_LINK_TYPE_BRIDGE = 0x10000 | 0x20000, @@ -197,11 +192,8 @@ typedef enum { NMP_OBJECT_TYPE_TFILTER, NMP_OBJECT_TYPE_LNK_GRE, - NMP_OBJECT_TYPE_LNK_GRETAP, NMP_OBJECT_TYPE_LNK_INFINIBAND, NMP_OBJECT_TYPE_LNK_IP6TNL, - NMP_OBJECT_TYPE_LNK_IP6GRE, - NMP_OBJECT_TYPE_LNK_IP6GRETAP, NMP_OBJECT_TYPE_LNK_IPIP, NMP_OBJECT_TYPE_LNK_MACSEC, NMP_OBJECT_TYPE_LNK_MACVLAN, @@ -210,7 +202,6 @@ typedef enum { NMP_OBJECT_TYPE_LNK_TUN, NMP_OBJECT_TYPE_LNK_VLAN, NMP_OBJECT_TYPE_LNK_VXLAN, - NMP_OBJECT_TYPE_LNK_WIREGUARD, __NMP_OBJECT_TYPE_LAST, NMP_OBJECT_TYPE_MAX = __NMP_OBJECT_TYPE_LAST - 1, diff --git a/src/platform/linux/nl802154.h b/src/platform/linux/nl802154.h deleted file mode 100644 index ddcee128..00000000 --- a/src/platform/linux/nl802154.h +++ /dev/null @@ -1,452 +0,0 @@ -#ifndef __NL802154_H -#define __NL802154_H -/* - * 802.15.4 netlink interface public header - * - * Copyright 2014 Alexander Aring <aar@pengutronix.de> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#define NL802154_GENL_NAME "nl802154" - -enum nl802154_commands { -/* don't change the order or add anything between, this is ABI! */ -/* currently we don't shipping this file via uapi, ignore the above one */ - NL802154_CMD_UNSPEC, - - NL802154_CMD_GET_WPAN_PHY, /* can dump */ - NL802154_CMD_SET_WPAN_PHY, - NL802154_CMD_NEW_WPAN_PHY, - NL802154_CMD_DEL_WPAN_PHY, - - NL802154_CMD_GET_INTERFACE, /* can dump */ - NL802154_CMD_SET_INTERFACE, - NL802154_CMD_NEW_INTERFACE, - NL802154_CMD_DEL_INTERFACE, - - NL802154_CMD_SET_CHANNEL, - - NL802154_CMD_SET_PAN_ID, - NL802154_CMD_SET_SHORT_ADDR, - - NL802154_CMD_SET_TX_POWER, - NL802154_CMD_SET_CCA_MODE, - NL802154_CMD_SET_CCA_ED_LEVEL, - - NL802154_CMD_SET_MAX_FRAME_RETRIES, - - NL802154_CMD_SET_BACKOFF_EXPONENT, - NL802154_CMD_SET_MAX_CSMA_BACKOFFS, - - NL802154_CMD_SET_LBT_MODE, - - NL802154_CMD_SET_ACKREQ_DEFAULT, - - NL802154_CMD_SET_WPAN_PHY_NETNS, - - /* add new commands above here */ - -#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL - NL802154_CMD_SET_SEC_PARAMS, - NL802154_CMD_GET_SEC_KEY, /* can dump */ - NL802154_CMD_NEW_SEC_KEY, - NL802154_CMD_DEL_SEC_KEY, - NL802154_CMD_GET_SEC_DEV, /* can dump */ - NL802154_CMD_NEW_SEC_DEV, - NL802154_CMD_DEL_SEC_DEV, - NL802154_CMD_GET_SEC_DEVKEY, /* can dump */ - NL802154_CMD_NEW_SEC_DEVKEY, - NL802154_CMD_DEL_SEC_DEVKEY, - NL802154_CMD_GET_SEC_LEVEL, /* can dump */ - NL802154_CMD_NEW_SEC_LEVEL, - NL802154_CMD_DEL_SEC_LEVEL, -#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ - - /* used to define NL802154_CMD_MAX below */ - __NL802154_CMD_AFTER_LAST, - NL802154_CMD_MAX = __NL802154_CMD_AFTER_LAST - 1 -}; - -enum nl802154_attrs { -/* don't change the order or add anything between, this is ABI! */ -/* currently we don't shipping this file via uapi, ignore the above one */ - NL802154_ATTR_UNSPEC, - - NL802154_ATTR_WPAN_PHY, - NL802154_ATTR_WPAN_PHY_NAME, - - NL802154_ATTR_IFINDEX, - NL802154_ATTR_IFNAME, - NL802154_ATTR_IFTYPE, - - NL802154_ATTR_WPAN_DEV, - - NL802154_ATTR_PAGE, - NL802154_ATTR_CHANNEL, - - NL802154_ATTR_PAN_ID, - NL802154_ATTR_SHORT_ADDR, - - NL802154_ATTR_TX_POWER, - - NL802154_ATTR_CCA_MODE, - NL802154_ATTR_CCA_OPT, - NL802154_ATTR_CCA_ED_LEVEL, - - NL802154_ATTR_MAX_FRAME_RETRIES, - - NL802154_ATTR_MAX_BE, - NL802154_ATTR_MIN_BE, - NL802154_ATTR_MAX_CSMA_BACKOFFS, - - NL802154_ATTR_LBT_MODE, - - NL802154_ATTR_GENERATION, - - NL802154_ATTR_CHANNELS_SUPPORTED, - NL802154_ATTR_SUPPORTED_CHANNEL, - - NL802154_ATTR_EXTENDED_ADDR, - - NL802154_ATTR_WPAN_PHY_CAPS, - - NL802154_ATTR_SUPPORTED_COMMANDS, - - NL802154_ATTR_ACKREQ_DEFAULT, - - NL802154_ATTR_PAD, - - NL802154_ATTR_PID, - NL802154_ATTR_NETNS_FD, - - /* add attributes here, update the policy in nl802154.c */ - -#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL - NL802154_ATTR_SEC_ENABLED, - NL802154_ATTR_SEC_OUT_LEVEL, - NL802154_ATTR_SEC_OUT_KEY_ID, - NL802154_ATTR_SEC_FRAME_COUNTER, - - NL802154_ATTR_SEC_LEVEL, - NL802154_ATTR_SEC_DEVICE, - NL802154_ATTR_SEC_DEVKEY, - NL802154_ATTR_SEC_KEY, -#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ - - __NL802154_ATTR_AFTER_LAST, - NL802154_ATTR_MAX = __NL802154_ATTR_AFTER_LAST - 1 -}; - -enum nl802154_iftype { - /* for backwards compatibility TODO */ - NL802154_IFTYPE_UNSPEC = -1, - - NL802154_IFTYPE_NODE, - NL802154_IFTYPE_MONITOR, - NL802154_IFTYPE_COORD, - - /* keep last */ - NUM_NL802154_IFTYPES, - NL802154_IFTYPE_MAX = NUM_NL802154_IFTYPES - 1 -}; - -/** - * enum nl802154_wpan_phy_capability_attr - wpan phy capability attributes - * - * @__NL802154_CAP_ATTR_INVALID: attribute number 0 is reserved - * @NL802154_CAP_ATTR_CHANNELS: a nested attribute for nl802154_channel_attr - * @NL802154_CAP_ATTR_TX_POWERS: a nested attribute for - * nl802154_wpan_phy_tx_power - * @NL802154_CAP_ATTR_MIN_CCA_ED_LEVEL: minimum value for cca_ed_level - * @NL802154_CAP_ATTR_MAX_CCA_ED_LEVEL: maxmimum value for cca_ed_level - * @NL802154_CAP_ATTR_CCA_MODES: nl802154_cca_modes flags - * @NL802154_CAP_ATTR_CCA_OPTS: nl802154_cca_opts flags - * @NL802154_CAP_ATTR_MIN_MINBE: minimum of minbe value - * @NL802154_CAP_ATTR_MAX_MINBE: maximum of minbe value - * @NL802154_CAP_ATTR_MIN_MAXBE: minimum of maxbe value - * @NL802154_CAP_ATTR_MAX_MINBE: maximum of maxbe value - * @NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS: minimum of csma backoff value - * @NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS: maximum of csma backoffs value - * @NL802154_CAP_ATTR_MIN_FRAME_RETRIES: minimum of frame retries value - * @NL802154_CAP_ATTR_MAX_FRAME_RETRIES: maximum of frame retries value - * @NL802154_CAP_ATTR_IFTYPES: nl802154_iftype flags - * @NL802154_CAP_ATTR_LBT: nl802154_supported_bool_states flags - * @NL802154_CAP_ATTR_MAX: highest cap attribute currently defined - * @__NL802154_CAP_ATTR_AFTER_LAST: internal use - */ -enum nl802154_wpan_phy_capability_attr { - __NL802154_CAP_ATTR_INVALID, - - NL802154_CAP_ATTR_IFTYPES, - - NL802154_CAP_ATTR_CHANNELS, - NL802154_CAP_ATTR_TX_POWERS, - - NL802154_CAP_ATTR_CCA_ED_LEVELS, - NL802154_CAP_ATTR_CCA_MODES, - NL802154_CAP_ATTR_CCA_OPTS, - - NL802154_CAP_ATTR_MIN_MINBE, - NL802154_CAP_ATTR_MAX_MINBE, - - NL802154_CAP_ATTR_MIN_MAXBE, - NL802154_CAP_ATTR_MAX_MAXBE, - - NL802154_CAP_ATTR_MIN_CSMA_BACKOFFS, - NL802154_CAP_ATTR_MAX_CSMA_BACKOFFS, - - NL802154_CAP_ATTR_MIN_FRAME_RETRIES, - NL802154_CAP_ATTR_MAX_FRAME_RETRIES, - - NL802154_CAP_ATTR_LBT, - - /* keep last */ - __NL802154_CAP_ATTR_AFTER_LAST, - NL802154_CAP_ATTR_MAX = __NL802154_CAP_ATTR_AFTER_LAST - 1 -}; - -/** - * enum nl802154_cca_modes - cca modes - * - * @__NL802154_CCA_INVALID: cca mode number 0 is reserved - * @NL802154_CCA_ENERGY: Energy above threshold - * @NL802154_CCA_CARRIER: Carrier sense only - * @NL802154_CCA_ENERGY_CARRIER: Carrier sense with energy above threshold - * @NL802154_CCA_ALOHA: CCA shall always report an idle medium - * @NL802154_CCA_UWB_SHR: UWB preamble sense based on the SHR of a frame - * @NL802154_CCA_UWB_MULTIPLEXED: UWB preamble sense based on the packet with - * the multiplexed preamble - * @__NL802154_CCA_ATTR_AFTER_LAST: Internal - * @NL802154_CCA_ATTR_MAX: Maximum CCA attribute number - */ -enum nl802154_cca_modes { - __NL802154_CCA_INVALID, - NL802154_CCA_ENERGY, - NL802154_CCA_CARRIER, - NL802154_CCA_ENERGY_CARRIER, - NL802154_CCA_ALOHA, - NL802154_CCA_UWB_SHR, - NL802154_CCA_UWB_MULTIPLEXED, - - /* keep last */ - __NL802154_CCA_ATTR_AFTER_LAST, - NL802154_CCA_ATTR_MAX = __NL802154_CCA_ATTR_AFTER_LAST - 1 -}; - -/** - * enum nl802154_cca_opts - additional options for cca modes - * - * @NL802154_CCA_OPT_ENERGY_CARRIER_OR: NL802154_CCA_ENERGY_CARRIER with OR - * @NL802154_CCA_OPT_ENERGY_CARRIER_AND: NL802154_CCA_ENERGY_CARRIER with AND - */ -enum nl802154_cca_opts { - NL802154_CCA_OPT_ENERGY_CARRIER_AND, - NL802154_CCA_OPT_ENERGY_CARRIER_OR, - - /* keep last */ - __NL802154_CCA_OPT_ATTR_AFTER_LAST, - NL802154_CCA_OPT_ATTR_MAX = __NL802154_CCA_OPT_ATTR_AFTER_LAST - 1 -}; - -/** - * enum nl802154_supported_bool_states - bool states for bool capability entry - * - * @NL802154_SUPPORTED_BOOL_FALSE: indicates to set false - * @NL802154_SUPPORTED_BOOL_TRUE: indicates to set true - * @__NL802154_SUPPORTED_BOOL_INVALD: reserved - * @NL802154_SUPPORTED_BOOL_BOTH: indicates to set true and false - * @__NL802154_SUPPORTED_BOOL_AFTER_LAST: Internal - * @NL802154_SUPPORTED_BOOL_MAX: highest value for bool states - */ -enum nl802154_supported_bool_states { - NL802154_SUPPORTED_BOOL_FALSE, - NL802154_SUPPORTED_BOOL_TRUE, - /* to handle them in a mask */ - __NL802154_SUPPORTED_BOOL_INVALD, - NL802154_SUPPORTED_BOOL_BOTH, - - /* keep last */ - __NL802154_SUPPORTED_BOOL_AFTER_LAST, - NL802154_SUPPORTED_BOOL_MAX = __NL802154_SUPPORTED_BOOL_AFTER_LAST - 1 -}; - -#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL - -enum nl802154_dev_addr_modes { - NL802154_DEV_ADDR_NONE, - __NL802154_DEV_ADDR_INVALID, - NL802154_DEV_ADDR_SHORT, - NL802154_DEV_ADDR_EXTENDED, - - /* keep last */ - __NL802154_DEV_ADDR_AFTER_LAST, - NL802154_DEV_ADDR_MAX = __NL802154_DEV_ADDR_AFTER_LAST - 1 -}; - -enum nl802154_dev_addr_attrs { - NL802154_DEV_ADDR_ATTR_UNSPEC, - - NL802154_DEV_ADDR_ATTR_PAN_ID, - NL802154_DEV_ADDR_ATTR_MODE, - NL802154_DEV_ADDR_ATTR_SHORT, - NL802154_DEV_ADDR_ATTR_EXTENDED, - NL802154_DEV_ADDR_ATTR_PAD, - - /* keep last */ - __NL802154_DEV_ADDR_ATTR_AFTER_LAST, - NL802154_DEV_ADDR_ATTR_MAX = __NL802154_DEV_ADDR_ATTR_AFTER_LAST - 1 -}; - -enum nl802154_key_id_modes { - NL802154_KEY_ID_MODE_IMPLICIT, - NL802154_KEY_ID_MODE_INDEX, - NL802154_KEY_ID_MODE_INDEX_SHORT, - NL802154_KEY_ID_MODE_INDEX_EXTENDED, - - /* keep last */ - __NL802154_KEY_ID_MODE_AFTER_LAST, - NL802154_KEY_ID_MODE_MAX = __NL802154_KEY_ID_MODE_AFTER_LAST - 1 -}; - -enum nl802154_key_id_attrs { - NL802154_KEY_ID_ATTR_UNSPEC, - - NL802154_KEY_ID_ATTR_MODE, - NL802154_KEY_ID_ATTR_INDEX, - NL802154_KEY_ID_ATTR_IMPLICIT, - NL802154_KEY_ID_ATTR_SOURCE_SHORT, - NL802154_KEY_ID_ATTR_SOURCE_EXTENDED, - NL802154_KEY_ID_ATTR_PAD, - - /* keep last */ - __NL802154_KEY_ID_ATTR_AFTER_LAST, - NL802154_KEY_ID_ATTR_MAX = __NL802154_KEY_ID_ATTR_AFTER_LAST - 1 -}; - -enum nl802154_seclevels { - NL802154_SECLEVEL_NONE, - NL802154_SECLEVEL_MIC32, - NL802154_SECLEVEL_MIC64, - NL802154_SECLEVEL_MIC128, - NL802154_SECLEVEL_ENC, - NL802154_SECLEVEL_ENC_MIC32, - NL802154_SECLEVEL_ENC_MIC64, - NL802154_SECLEVEL_ENC_MIC128, - - /* keep last */ - __NL802154_SECLEVEL_AFTER_LAST, - NL802154_SECLEVEL_MAX = __NL802154_SECLEVEL_AFTER_LAST - 1 -}; - -enum nl802154_frames { - NL802154_FRAME_BEACON, - NL802154_FRAME_DATA, - NL802154_FRAME_ACK, - NL802154_FRAME_CMD, - - /* keep last */ - __NL802154_FRAME_AFTER_LAST, - NL802154_FRAME_MAX = __NL802154_FRAME_AFTER_LAST - 1 -}; - -enum nl802154_cmd_frames { - __NL802154_CMD_FRAME_INVALID, - NL802154_CMD_FRAME_ASSOC_REQUEST, - NL802154_CMD_FRAME_ASSOC_RESPONSE, - NL802154_CMD_FRAME_DISASSOC_NOTIFY, - NL802154_CMD_FRAME_DATA_REQUEST, - NL802154_CMD_FRAME_PAN_ID_CONFLICT_NOTIFY, - NL802154_CMD_FRAME_ORPHAN_NOTIFY, - NL802154_CMD_FRAME_BEACON_REQUEST, - NL802154_CMD_FRAME_COORD_REALIGNMENT, - NL802154_CMD_FRAME_GTS_REQUEST, - - /* keep last */ - __NL802154_CMD_FRAME_AFTER_LAST, - NL802154_CMD_FRAME_MAX = __NL802154_CMD_FRAME_AFTER_LAST - 1 -}; - -enum nl802154_seclevel_attrs { - NL802154_SECLEVEL_ATTR_UNSPEC, - - NL802154_SECLEVEL_ATTR_LEVELS, - NL802154_SECLEVEL_ATTR_FRAME, - NL802154_SECLEVEL_ATTR_CMD_FRAME, - NL802154_SECLEVEL_ATTR_DEV_OVERRIDE, - - /* keep last */ - __NL802154_SECLEVEL_ATTR_AFTER_LAST, - NL802154_SECLEVEL_ATTR_MAX = __NL802154_SECLEVEL_ATTR_AFTER_LAST - 1 -}; - -/* TODO what is this? couldn't find in mib */ -enum { - NL802154_DEVKEY_IGNORE, - NL802154_DEVKEY_RESTRICT, - NL802154_DEVKEY_RECORD, - - /* keep last */ - __NL802154_DEVKEY_AFTER_LAST, - NL802154_DEVKEY_MAX = __NL802154_DEVKEY_AFTER_LAST - 1 -}; - -enum nl802154_dev { - NL802154_DEV_ATTR_UNSPEC, - - NL802154_DEV_ATTR_FRAME_COUNTER, - NL802154_DEV_ATTR_PAN_ID, - NL802154_DEV_ATTR_SHORT_ADDR, - NL802154_DEV_ATTR_EXTENDED_ADDR, - NL802154_DEV_ATTR_SECLEVEL_EXEMPT, - NL802154_DEV_ATTR_KEY_MODE, - NL802154_DEV_ATTR_PAD, - - /* keep last */ - __NL802154_DEV_ATTR_AFTER_LAST, - NL802154_DEV_ATTR_MAX = __NL802154_DEV_ATTR_AFTER_LAST - 1 -}; - -enum nl802154_devkey { - NL802154_DEVKEY_ATTR_UNSPEC, - - NL802154_DEVKEY_ATTR_FRAME_COUNTER, - NL802154_DEVKEY_ATTR_EXTENDED_ADDR, - NL802154_DEVKEY_ATTR_ID, - NL802154_DEVKEY_ATTR_PAD, - - /* keep last */ - __NL802154_DEVKEY_ATTR_AFTER_LAST, - NL802154_DEVKEY_ATTR_MAX = __NL802154_DEVKEY_ATTR_AFTER_LAST - 1 -}; - -enum nl802154_key { - NL802154_KEY_ATTR_UNSPEC, - - NL802154_KEY_ATTR_ID, - NL802154_KEY_ATTR_USAGE_FRAMES, - NL802154_KEY_ATTR_USAGE_CMDS, - NL802154_KEY_ATTR_BYTES, - - /* keep last */ - __NL802154_KEY_ATTR_AFTER_LAST, - NL802154_KEY_ATTR_MAX = __NL802154_KEY_ATTR_AFTER_LAST - 1 -}; - -#define NL802154_KEY_SIZE 16 -#define NL802154_CMD_FRAME_NR_IDS 256 - -#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ - -#endif /* __NL802154_H */ diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index 82f9e2fb..f8f4627e 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -602,6 +602,12 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu) return NM_PLATFORM_ERROR_SUCCESS; } +static gboolean +link_set_sriov_num_vfs (NMPlatform *platform, int ifindex, guint num_vfs) +{ + return TRUE; +} + static const char * link_get_udi (NMPlatform *platform, int ifindex) { @@ -887,6 +893,12 @@ wifi_get_bssid (NMPlatform *platform, int ifindex, guint8 *bssid) return FALSE; } +static GByteArray * +wifi_get_ssid (NMPlatform *platform, int ifindex) +{ + return NULL; +} + static guint32 wifi_get_frequency (NMPlatform *platform, int ifindex) { @@ -1410,6 +1422,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass) platform_class->link_set_address = link_set_address; platform_class->link_set_mtu = link_set_mtu; + platform_class->link_set_sriov_num_vfs = link_set_sriov_num_vfs; platform_class->link_get_driver_info = link_get_driver_info; @@ -1429,6 +1442,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass) platform_class->wifi_get_capabilities = wifi_get_capabilities; platform_class->wifi_get_bssid = wifi_get_bssid; + platform_class->wifi_get_ssid = wifi_get_ssid; platform_class->wifi_get_frequency = wifi_get_frequency; platform_class->wifi_get_quality = wifi_get_quality; platform_class->wifi_get_rate = wifi_get_rate; diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index e73d5d8c..9bd662a1 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 - 2018 Red Hat, Inc. + * Copyright (C) 2012 - 2017 Red Hat, Inc. */ #include "nm-default.h" @@ -44,18 +44,15 @@ #include "nm-core-internal.h" #include "nm-setting-vlan.h" -#include "nm-utils/nm-secret-utils.h" #include "nm-netlink.h" #include "nm-core-utils.h" #include "nmp-object.h" #include "nmp-netns.h" #include "nm-platform-utils.h" #include "nm-platform-private.h" -#include "wifi/nm-wifi-utils.h" -#include "wifi/nm-wifi-utils-wext.h" -#include "wpan/nm-wpan-utils.h" +#include "wifi/wifi-utils.h" +#include "wifi/wifi-utils-wext.h" #include "nm-utils/unaligned.h" -#include "nm-utils/nm-io-utils.h" #include "nm-utils/nm-udev-utils.h" /*****************************************************************************/ @@ -157,13 +154,6 @@ G_STATIC_ASSERT (RTA_MAX == (__RTA_MAX - 1)); /*****************************************************************************/ -/* Appeared in in kernel prior to 3.13 dated 19 January, 2014 */ -#ifndef ARPHRD_6LOWPAN -#define ARPHRD_6LOWPAN 825 -#endif - -/*****************************************************************************/ - #define IFLA_MACSEC_UNSPEC 0 #define IFLA_MACSEC_SCI 1 #define IFLA_MACSEC_PORT 2 @@ -183,79 +173,63 @@ G_STATIC_ASSERT (RTA_MAX == (__RTA_MAX - 1)); /*****************************************************************************/ -#define WG_CMD_GET_DEVICE 0 -#define WG_CMD_SET_DEVICE 1 - -#define WGDEVICE_A_UNSPEC 0 -#define WGDEVICE_A_IFINDEX 1 -#define WGDEVICE_A_IFNAME 2 -#define WGDEVICE_A_PRIVATE_KEY 3 -#define WGDEVICE_A_PUBLIC_KEY 4 -#define WGDEVICE_A_FLAGS 5 -#define WGDEVICE_A_LISTEN_PORT 6 -#define WGDEVICE_A_FWMARK 7 -#define WGDEVICE_A_PEERS 8 -#define WGDEVICE_A_MAX 8 - -#define WGPEER_A_UNSPEC 0 -#define WGPEER_A_PUBLIC_KEY 1 -#define WGPEER_A_PRESHARED_KEY 2 -#define WGPEER_A_FLAGS 3 -#define WGPEER_A_ENDPOINT 4 -#define WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL 5 -#define WGPEER_A_LAST_HANDSHAKE_TIME 6 -#define WGPEER_A_RX_BYTES 7 -#define WGPEER_A_TX_BYTES 8 -#define WGPEER_A_ALLOWEDIPS 9 -#define WGPEER_A_MAX 9 - -#define WGALLOWEDIP_A_UNSPEC 0 -#define WGALLOWEDIP_A_FAMILY 1 -#define WGALLOWEDIP_A_IPADDR 2 -#define WGALLOWEDIP_A_CIDR_MASK 3 -#define WGALLOWEDIP_A_MAX 3 +#define _NMLOG_PREFIX_NAME "platform-linux" +#define _NMLOG_DOMAIN LOGD_PLATFORM +#define _NMLOG2_DOMAIN LOGD_PLATFORM +#define _NMLOG(level, ...) _LOG ( level, _NMLOG_DOMAIN, platform, __VA_ARGS__) +#define _NMLOG_err(errsv, level, ...) _LOG_err (errsv, level, _NMLOG_DOMAIN, platform, __VA_ARGS__) +#define _NMLOG2(level, ...) _LOG ( level, _NMLOG2_DOMAIN, NULL, __VA_ARGS__) +#define _NMLOG2_err(errsv, level, ...) _LOG_err (errsv, level, _NMLOG2_DOMAIN, NULL, __VA_ARGS__) -/*****************************************************************************/ +#define _LOG_print(__level, __domain, __errsv, self, ...) \ + G_STMT_START { \ + char __prefix[32]; \ + const char *__p_prefix = _NMLOG_PREFIX_NAME; \ + NMPlatform *const __self = (self); \ + \ + if (__self && nm_platform_get_log_with_ptr (__self)) { \ + g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ + __p_prefix = __prefix; \ + } \ + _nm_log (__level, __domain, __errsv, NULL, NULL, \ + "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ + __p_prefix _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ + } G_STMT_END -/* Redefine VF enums and structures that are not available on older kernels. */ - -#define IFLA_VF_UNSPEC 0 -#define IFLA_VF_MAC 1 -#define IFLA_VF_VLAN 2 -#define IFLA_VF_TX_RATE 3 -#define IFLA_VF_SPOOFCHK 4 -#define IFLA_VF_LINK_STATE 5 -#define IFLA_VF_RATE 6 -#define IFLA_VF_RSS_QUERY_EN 7 -#define IFLA_VF_STATS 8 -#define IFLA_VF_TRUST 9 -#define IFLA_VF_IB_NODE_GUID 10 -#define IFLA_VF_IB_PORT_GUID 11 -#define IFLA_VF_VLAN_LIST 12 - -#define IFLA_VF_VLAN_INFO_UNSPEC 0 -#define IFLA_VF_VLAN_INFO 1 - -/* valid for TRUST, SPOOFCHK, LINK_STATE, RSS_QUERY_EN */ -struct _ifla_vf_setting { - guint32 vf; - guint32 setting; -}; +#define _LOG(level, domain, self, ...) \ + G_STMT_START { \ + const NMLogLevel __level = (level); \ + const NMLogDomain __domain = (domain); \ + \ + if (nm_logging_enabled (__level, __domain)) { \ + _LOG_print (__level, __domain, 0, self, __VA_ARGS__); \ + } \ + } G_STMT_END -struct _ifla_vf_rate { - guint32 vf; - guint32 min_tx_rate; - guint32 max_tx_rate; -}; +#define _LOG_err(errsv, level, domain, self, ...) \ + G_STMT_START { \ + const NMLogLevel __level = (level); \ + const NMLogDomain __domain = (domain); \ + \ + if (nm_logging_enabled (__level, __domain)) { \ + int __errsv = (errsv); \ + \ + /* The %m format specifier (GNU extension) would alread allow you to specify the error + * message conveniently (and nm_log would get that right too). But we don't want to depend + * on that, so instead append the message at the end. + * Currently users are expected not to use %m in the format string. */ \ + _LOG_print (__level, __domain, __errsv, self, \ + _NM_UTILS_MACRO_FIRST (__VA_ARGS__) ": %s (%d)" \ + _NM_UTILS_MACRO_REST (__VA_ARGS__), \ + g_strerror (__errsv), __errsv); \ + } \ + } G_STMT_END -struct _ifla_vf_vlan_info { - guint32 vf; - guint32 vlan; /* 0 - 4095, 0 disables VLAN filter */ - guint32 qos; - guint16 vlan_proto; /* VLAN protocol, either 802.1Q or 802.1ad */ -}; +#define LOG_FMT_IP_TUNNEL "adding %s '%s' parent %u local %s remote %s" -/*****************************************************************************/ +/****************************************************************** + * Forward declarations and enums + ******************************************************************/ typedef enum { INFINIBAND_ACTION_CREATE_CHILD, @@ -333,133 +307,6 @@ typedef enum { WAIT_FOR_NL_RESPONSE_RESULT_FAILED_SETNS, } WaitForNlResponseResult; -typedef enum { - DELAYED_ACTION_RESPONSE_TYPE_VOID = 0, - DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS = 1, - DELAYED_ACTION_RESPONSE_TYPE_ROUTE_GET = 2, -} DelayedActionWaitForNlResponseType; - -typedef struct { - guint32 seq_number; - WaitForNlResponseResult seq_result; - DelayedActionWaitForNlResponseType response_type; - gint64 timeout_abs_ns; - WaitForNlResponseResult *out_seq_result; - char **out_errmsg; - union { - int *out_refresh_all_in_progress; - NMPObject **out_route_get; - gpointer out_data; - } response; -} DelayedActionWaitForNlResponseData; - -/*****************************************************************************/ - -typedef struct { - struct nl_sock *genl; - - struct nl_sock *nlh; - guint32 nlh_seq_next; -#if NM_MORE_LOGGING - guint32 nlh_seq_last_handled; -#endif - guint32 nlh_seq_last_seen; - GIOChannel *event_channel; - guint event_id; - - bool pruning[_DELAYED_ACTION_IDX_REFRESH_ALL_NUM]; - - bool sysctl_get_warned; - GHashTable *sysctl_get_prev_values; - - NMUdevClient *udev_client; - - struct { - /* which delayed actions are scheduled, as marked in @flags. - * Some types have additional arguments in the fields below. */ - DelayedActionType flags; - - /* counter that a refresh all action is in progress, separated - * by type. */ - int refresh_all_in_progress[_DELAYED_ACTION_IDX_REFRESH_ALL_NUM]; - - GPtrArray *list_master_connected; - GPtrArray *list_refresh_link; - GArray *list_wait_for_nl_response; - - int is_handling; - } delayed_action; -} NMLinuxPlatformPrivate; - -struct _NMLinuxPlatform { - NMPlatform parent; - NMLinuxPlatformPrivate _priv; -}; - -struct _NMLinuxPlatformClass { - NMPlatformClass parent; -}; - -G_DEFINE_TYPE (NMLinuxPlatform, nm_linux_platform, NM_TYPE_PLATFORM) - -#define NM_LINUX_PLATFORM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMLinuxPlatform, NM_IS_LINUX_PLATFORM, NMPlatform) - -/*****************************************************************************/ - -#define _NMLOG_PREFIX_NAME "platform-linux" -#define _NMLOG_DOMAIN LOGD_PLATFORM -#define _NMLOG2_DOMAIN LOGD_PLATFORM -#define _NMLOG(level, ...) _LOG ( level, _NMLOG_DOMAIN, platform, __VA_ARGS__) -#define _NMLOG_err(errsv, level, ...) _LOG_err (errsv, level, _NMLOG_DOMAIN, platform, __VA_ARGS__) -#define _NMLOG2(level, ...) _LOG ( level, _NMLOG2_DOMAIN, NULL, __VA_ARGS__) -#define _NMLOG2_err(errsv, level, ...) _LOG_err (errsv, level, _NMLOG2_DOMAIN, NULL, __VA_ARGS__) - -#define _LOG_print(__level, __domain, __errsv, self, ...) \ - G_STMT_START { \ - char __prefix[32]; \ - const char *__p_prefix = _NMLOG_PREFIX_NAME; \ - NMPlatform *const __self = (self); \ - \ - if (__self && nm_platform_get_log_with_ptr (__self)) { \ - g_snprintf (__prefix, sizeof (__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ - __p_prefix = __prefix; \ - } \ - _nm_log (__level, __domain, __errsv, NULL, NULL, \ - "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - __p_prefix _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ - } G_STMT_END - -#define _LOG(level, domain, self, ...) \ - G_STMT_START { \ - const NMLogLevel __level = (level); \ - const NMLogDomain __domain = (domain); \ - \ - if (nm_logging_enabled (__level, __domain)) { \ - _LOG_print (__level, __domain, 0, self, __VA_ARGS__); \ - } \ - } G_STMT_END - -#define _LOG_err(errsv, level, domain, self, ...) \ - G_STMT_START { \ - const NMLogLevel __level = (level); \ - const NMLogDomain __domain = (domain); \ - \ - if (nm_logging_enabled (__level, __domain)) { \ - int __errsv = (errsv); \ - \ - /* The %m format specifier (GNU extension) would alread allow you to specify the error - * message conveniently (and nm_log would get that right too). But we don't want to depend - * on that, so instead append the message at the end. - * Currently users are expected not to use %m in the format string. */ \ - _LOG_print (__level, __domain, __errsv, self, \ - _NM_UTILS_MACRO_FIRST (__VA_ARGS__) ": %s (%d)" \ - _NM_UTILS_MACRO_REST (__VA_ARGS__), \ - g_strerror (__errsv), __errsv); \ - } \ - } G_STMT_END - -/*****************************************************************************/ - static void delayed_action_schedule (NMPlatform *platform, DelayedActionType action_type, gpointer user_data); static gboolean delayed_action_handle_all (NMPlatform *platform, gboolean read_netlink); static void do_request_link_no_delayed_actions (NMPlatform *platform, int ifindex, const char *name); @@ -470,7 +317,6 @@ static void cache_on_change (NMPlatform *platform, const NMPObject *obj_new); static void cache_prune_all (NMPlatform *platform); static gboolean event_handler_read_netlink (NMPlatform *platform, gboolean wait_for_acks); -static struct nl_sock *_genl_sock (NMLinuxPlatform *platform); /*****************************************************************************/ @@ -687,8 +533,6 @@ static const LinkDesc linktypes[] = { { NM_LINK_TYPE_WIFI, "wifi", NULL, "wlan" }, { NM_LINK_TYPE_WWAN_NET, "wwan", NULL, "wwan" }, { NM_LINK_TYPE_WIMAX, "wimax", "wimax", "wimax" }, - { NM_LINK_TYPE_WPAN, "wpan", NULL, NULL }, - { NM_LINK_TYPE_6LOWPAN, "6lowpan", NULL, NULL }, { NM_LINK_TYPE_BNEP, "bluetooth", NULL, "bluetooth" }, { NM_LINK_TYPE_DUMMY, "dummy", "dummy", NULL }, @@ -696,8 +540,6 @@ static const LinkDesc linktypes[] = { { NM_LINK_TYPE_GRETAP, "gretap", "gretap", NULL }, { NM_LINK_TYPE_IFB, "ifb", "ifb", NULL }, { NM_LINK_TYPE_IP6TNL, "ip6tnl", "ip6tnl", NULL }, - { NM_LINK_TYPE_IP6GRE, "ip6gre", "ip6gre", NULL }, - { NM_LINK_TYPE_IP6GRETAP, "ip6gretap", "ip6gretap", NULL }, { NM_LINK_TYPE_IPIP, "ipip", "ipip", NULL }, { NM_LINK_TYPE_LOOPBACK, "loopback", NULL, NULL }, { NM_LINK_TYPE_MACSEC, "macsec", "macsec", NULL }, @@ -710,7 +552,6 @@ static const LinkDesc linktypes[] = { { NM_LINK_TYPE_VETH, "veth", "veth", NULL }, { NM_LINK_TYPE_VLAN, "vlan", "vlan", "vlan" }, { NM_LINK_TYPE_VXLAN, "vxlan", "vxlan", "vxlan" }, - { NM_LINK_TYPE_WIREGUARD, "wireguard", "wireguard", "wireguard" }, { NM_LINK_TYPE_BRIDGE, "bridge", "bridge", "bridge" }, { NM_LINK_TYPE_BOND, "bond", "bond", "bond" }, @@ -884,21 +725,19 @@ _addrtime_get_lifetimes (guint32 timestamp, /*****************************************************************************/ static const NMPObject * -_lookup_cached_link (const NMPCache *cache, - int ifindex, - gboolean *completed_from_cache, - const NMPObject **link_cached) +_lookup_cached_link (const NMPCache *cache, int ifindex, gboolean *completed_from_cache, const NMPObject **link_cached) { const NMPObject *obj; nm_assert (completed_from_cache && link_cached); if (!*completed_from_cache) { - obj = ifindex > 0 && cache - ? nmp_cache_lookup_link (cache, ifindex) - : NULL; + obj = ifindex > 0 && cache ? nmp_cache_lookup_link (cache, ifindex) : NULL; - *link_cached = obj; + if (obj && obj->_link.netlink.is_in_netlink) + *link_cached = obj; + else + *link_cached = NULL; *completed_from_cache = TRUE; } return *link_cached; @@ -916,9 +755,7 @@ _linktype_read_devtype (int dirfd) nm_assert (dirfd >= 0); - if (nm_utils_file_get_contents (dirfd, "uevent", 1*1024*1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &contents, NULL, NULL) < 0) + if (nm_utils_file_get_contents (dirfd, "uevent", 1*1024*1024, &contents, NULL, NULL) < 0) return NULL; for (cont = contents; cont; cont = end) { end = strpbrk (cont, "\r\n"); @@ -969,7 +806,6 @@ _linktype_get_type (NMPlatform *platform, * when moving interfce to other netns). Thus here there is a tiny potential * of messing stuff up. */ if ( obj - && obj->_link.netlink.is_in_netlink && !NM_IN_SET (obj->link.type, NM_LINK_TYPE_UNKNOWN, NM_LINK_TYPE_NONE) && nm_streq (ifname, obj->link.name) && ( !kind @@ -1005,10 +841,6 @@ _linktype_get_type (NMPlatform *platform, return NM_LINK_TYPE_IP6TNL; else if (arptype == ARPHRD_PPP) return NM_LINK_TYPE_PPP; - else if (arptype == ARPHRD_IEEE802154) - return NM_LINK_TYPE_WPAN; - else if (arptype == ARPHRD_6LOWPAN) - return NM_LINK_TYPE_6LOWPAN; { NMPUtilsEthtoolDriverInfo driver_info; @@ -1053,7 +885,7 @@ _linktype_get_type (NMPlatform *platform, } /* Fallback for drivers that don't call SET_NETDEV_DEVTYPE() */ - if (nm_wifi_utils_is_wifi (dirfd, ifname_verified)) + if (wifi_utils_is_wifi (dirfd, ifname_verified)) return NM_LINK_TYPE_WIFI; } @@ -1121,21 +953,18 @@ _nl_addattr_l (struct nlmsghdr *n, * NMPObject/netlink functions ******************************************************************/ -#define _check_addr_or_return_val(tb, attr, addr_len, ret_val) \ +#define _check_addr_or_errout(tb, attr, addr_len) \ ({ \ const struct nlattr *__t = (tb)[(attr)]; \ \ if (__t) { \ if (nla_len (__t) != (addr_len)) { \ - return ret_val; \ + goto errout; \ } \ } \ !!__t; \ }) -#define _check_addr_or_return_null(tb, attr, addr_len) \ - _check_addr_or_return_val (tb, attr, addr_len, NULL) - /*****************************************************************************/ /* Copied and heavily modified from libnl3's inet6_parse_protinfo(). */ @@ -1162,19 +991,20 @@ _parse_af_inet6 (NMPlatform *platform, gboolean token_valid = FALSE; gboolean addr_gen_mode_valid = FALSE; guint8 i6_addr_gen_mode_inv = 0; + gboolean success = FALSE; err = nla_parse_nested (tb, IFLA_INET6_MAX, attr, policy); if (err < 0) - return FALSE; + goto errout; if (tb[IFLA_INET6_CONF] && nla_len(tb[IFLA_INET6_CONF]) % 4) - return FALSE; + goto errout; if (tb[IFLA_INET6_STATS] && nla_len(tb[IFLA_INET6_STATS]) % 8) - return FALSE; + goto errout; if (tb[IFLA_INET6_ICMP6STATS] && nla_len(tb[IFLA_INET6_ICMP6STATS]) % 8) - return FALSE; + goto errout; - if (_check_addr_or_return_val (tb, IFLA_INET6_TOKEN, sizeof (struct in6_addr), FALSE)) { + if (_check_addr_or_errout (tb, IFLA_INET6_TOKEN, sizeof (struct in6_addr))) { nla_memcpy (&i6_token, tb[IFLA_INET6_TOKEN], sizeof (struct in6_addr)); token_valid = TRUE; } @@ -1190,11 +1020,12 @@ _parse_af_inet6 (NMPlatform *platform, if (i6_addr_gen_mode_inv == 0) { /* an inverse addrgenmode of zero is unexpected. We need to reserve zero * to signal "unset". */ - return FALSE; + goto errout; } addr_gen_mode_valid = TRUE; } + success = TRUE; if (token_valid) { *out_token_valid = token_valid; nm_utils_ipv6_interface_identifier_get_from_addr (out_token, &i6_token); @@ -1203,7 +1034,8 @@ _parse_af_inet6 (NMPlatform *platform, *out_addr_gen_mode_valid = addr_gen_mode_valid; *out_addr_gen_mode_inv = i6_addr_gen_mode_inv; } - return TRUE; +errout: + return success; } /*****************************************************************************/ @@ -1227,23 +1059,15 @@ _parse_lnk_gre (const char *kind, struct nlattr *info_data) int err; NMPObject *obj; NMPlatformLnkGre *props; - gboolean is_tap; - - if (!info_data || !kind) - return NULL; - if (nm_streq (kind, "gretap")) - is_tap = TRUE; - else if (nm_streq (kind, "gre")) - is_tap = FALSE; - else + if (!info_data || g_strcmp0 (kind, "gre")) return NULL; err = nla_parse_nested (tb, IFLA_GRE_MAX, info_data, policy); if (err < 0) return NULL; - obj = nmp_object_new (is_tap ? NMP_OBJECT_TYPE_LNK_GRETAP : NMP_OBJECT_TYPE_LNK_GRE, NULL); + obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_GRE, NULL); props = &obj->lnk_gre; props->parent_ifindex = tb[IFLA_GRE_LINK] ? nla_get_u32 (tb[IFLA_GRE_LINK]) : 0; @@ -1256,7 +1080,6 @@ _parse_lnk_gre (const char *kind, struct nlattr *info_data) props->tos = tb[IFLA_GRE_TOS] ? nla_get_u8 (tb[IFLA_GRE_TOS]) : 0; props->ttl = tb[IFLA_GRE_TTL] ? nla_get_u8 (tb[IFLA_GRE_TTL]) : 0; props->path_mtu_discovery = !tb[IFLA_GRE_PMTUDISC] || !!nla_get_u8 (tb[IFLA_GRE_PMTUDISC]); - props->is_tap = is_tap; return obj; } @@ -1377,79 +1200,6 @@ _parse_lnk_ip6tnl (const char *kind, struct nlattr *info_data) return obj; } -static NMPObject * -_parse_lnk_ip6gre (const char *kind, struct nlattr *info_data) -{ - static const struct nla_policy policy[IFLA_GRE_MAX + 1] = { - [IFLA_GRE_LINK] = { .type = NLA_U32 }, - [IFLA_GRE_IFLAGS] = { .type = NLA_U16 }, - [IFLA_GRE_OFLAGS] = { .type = NLA_U16 }, - [IFLA_GRE_IKEY] = { .type = NLA_U32 }, - [IFLA_GRE_OKEY] = { .type = NLA_U32 }, - [IFLA_GRE_LOCAL] = { .type = NLA_UNSPEC, - .minlen = sizeof (struct in6_addr)}, - [IFLA_GRE_REMOTE] = { .type = NLA_UNSPEC, - .minlen = sizeof (struct in6_addr)}, - [IFLA_GRE_TTL] = { .type = NLA_U8 }, - [IFLA_GRE_ENCAP_LIMIT] = { .type = NLA_U8 }, - [IFLA_GRE_FLOWINFO] = { .type = NLA_U32 }, - [IFLA_GRE_FLAGS] = { .type = NLA_U32 }, - }; - struct nlattr *tb[IFLA_GRE_MAX + 1]; - int err; - NMPObject *obj; - NMPlatformLnkIp6Tnl *props; - guint32 flowinfo; - gboolean is_tap; - - if (!info_data || !kind) - return NULL; - - if (nm_streq (kind, "ip6gre")) - is_tap = FALSE; - else if (nm_streq (kind, "ip6gretap")) - is_tap = TRUE; - else - return NULL; - - err = nla_parse_nested (tb, IFLA_GRE_MAX, info_data, policy); - if (err < 0) - return NULL; - - obj = nmp_object_new (is_tap ? NMP_OBJECT_TYPE_LNK_IP6GRETAP : NMP_OBJECT_TYPE_LNK_IP6GRE, NULL); - props = &obj->lnk_ip6tnl; - props->is_gre = TRUE; - props->is_tap = is_tap; - - if (tb[IFLA_GRE_LINK]) - props->parent_ifindex = nla_get_u32 (tb[IFLA_GRE_LINK]); - if (tb[IFLA_GRE_IFLAGS]) - props->input_flags = ntohs (nla_get_u16 (tb[IFLA_GRE_IFLAGS])); - if (tb[IFLA_GRE_OFLAGS]) - props->output_flags = ntohs (nla_get_u16 (tb[IFLA_GRE_OFLAGS])); - if (tb[IFLA_GRE_IKEY]) - props->input_key = ntohl (nla_get_u32 (tb[IFLA_GRE_IKEY])); - if (tb[IFLA_GRE_OKEY]) - props->output_key = ntohl (nla_get_u32 (tb[IFLA_GRE_OKEY])); - if (tb[IFLA_GRE_LOCAL]) - memcpy (&props->local, nla_data (tb[IFLA_GRE_LOCAL]), sizeof (props->local)); - if (tb[IFLA_GRE_REMOTE]) - memcpy (&props->remote, nla_data (tb[IFLA_GRE_REMOTE]), sizeof (props->remote)); - if (tb[IFLA_GRE_TTL]) - props->ttl = nla_get_u8 (tb[IFLA_GRE_TTL]); - if (tb[IFLA_GRE_ENCAP_LIMIT]) - props->encap_limit = nla_get_u8 (tb[IFLA_GRE_ENCAP_LIMIT]); - if (tb[IFLA_GRE_FLOWINFO]) { - flowinfo = ntohl (nla_get_u32 (tb[IFLA_GRE_FLOWINFO])); - props->flow_label = flowinfo & IP6_FLOWINFO_FLOWLABEL_MASK; - props->tclass = (flowinfo & IP6_FLOWINFO_TCLASS_MASK) >> IP6_FLOWINFO_TCLASS_SHIFT; - } - if (tb[IFLA_GRE_FLAGS]) - props->flags = nla_get_u32 (tb[IFLA_GRE_FLAGS]); - - return obj; -} - /*****************************************************************************/ static NMPObject * @@ -1913,378 +1663,6 @@ _parse_lnk_vxlan (const char *kind, struct nlattr *info_data) /*****************************************************************************/ -static gboolean -_wireguard_update_from_allowed_ips_nla (NMPWireGuardAllowedIP *allowed_ip, - struct nlattr *nlattr) -{ - static const struct nla_policy policy[WGALLOWEDIP_A_MAX + 1] = { - [WGALLOWEDIP_A_FAMILY] = { .type = NLA_U16 }, - [WGALLOWEDIP_A_IPADDR] = { .minlen = sizeof (struct in_addr) }, - [WGALLOWEDIP_A_CIDR_MASK] = { .type = NLA_U8 }, - }; - struct nlattr *tb[WGALLOWEDIP_A_MAX + 1]; - int family; - int addr_len; - - if (nla_parse_nested (tb, WGALLOWEDIP_A_MAX, nlattr, policy) < 0) - return FALSE; - - if (!tb[WGALLOWEDIP_A_FAMILY]) - return FALSE; - - family = nla_get_u16 (tb[WGALLOWEDIP_A_FAMILY]); - if (family == AF_INET) - addr_len = sizeof (in_addr_t); - else if (family == AF_INET6) - addr_len = sizeof (struct in6_addr); - else - return FALSE; - - _check_addr_or_return_val (tb, WGALLOWEDIP_A_IPADDR, addr_len, FALSE); - - memset (allowed_ip, 0, sizeof (NMPWireGuardAllowedIP)); - - allowed_ip->family = family; - nm_assert ((int) allowed_ip->family == family); - - if (tb[WGALLOWEDIP_A_IPADDR]) - nla_memcpy (&allowed_ip->addr, tb[WGALLOWEDIP_A_IPADDR], addr_len); - if (tb[WGALLOWEDIP_A_CIDR_MASK]) - allowed_ip->mask = nla_get_u8 (tb[WGALLOWEDIP_A_CIDR_MASK]); - - return TRUE; -} - -typedef struct { - CList lst; - NMPWireGuardPeer data; -} WireGuardPeerConstruct; - -static gboolean -_wireguard_update_from_peers_nla (CList *peers, - GArray **p_allowed_ips, - struct nlattr *peer_attr) -{ - static const struct nla_policy policy[WGPEER_A_MAX + 1] = { - [WGPEER_A_PUBLIC_KEY] = { .minlen = NMP_WIREGUARD_PUBLIC_KEY_LEN }, - [WGPEER_A_PRESHARED_KEY] = { }, - [WGPEER_A_FLAGS] = { .type = NLA_U32 }, - [WGPEER_A_ENDPOINT] = { }, - [WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL] = { .type = NLA_U16 }, - [WGPEER_A_LAST_HANDSHAKE_TIME] = { }, - [WGPEER_A_RX_BYTES] = { .type = NLA_U64 }, - [WGPEER_A_TX_BYTES] = { .type = NLA_U64 }, - [WGPEER_A_ALLOWEDIPS] = { .type = NLA_NESTED }, - }; - WireGuardPeerConstruct *peer_c; - struct nlattr *tb[WGPEER_A_MAX + 1]; - - if (nla_parse_nested (tb, WGPEER_A_MAX, peer_attr, policy) < 0) - return FALSE; - - if (!tb[WGPEER_A_PUBLIC_KEY]) - return FALSE; - - /* a peer with the same public key as last peer is just a continuation for extra AllowedIPs */ - peer_c = c_list_last_entry (peers, WireGuardPeerConstruct, lst); - if ( peer_c - && !memcmp (nla_data (tb[WGPEER_A_PUBLIC_KEY]), peer_c->data.public_key, NMP_WIREGUARD_PUBLIC_KEY_LEN)) { - G_STATIC_ASSERT_EXPR (NMP_WIREGUARD_PUBLIC_KEY_LEN == sizeof (peer_c->data.public_key)); - /* this message is a continuation of the previous peer. - * Only parse WGPEER_A_ALLOWEDIPS below. */ - } - else { - /* otherwise, start a new peer */ - peer_c = g_slice_new0 (WireGuardPeerConstruct); - c_list_link_tail (peers, &peer_c->lst); - - nla_memcpy (&peer_c->data.public_key, tb[WGPEER_A_PUBLIC_KEY], sizeof (peer_c->data.public_key)); - - if (tb[WGPEER_A_PRESHARED_KEY]) { - nla_memcpy (&peer_c->data.preshared_key, tb[WGPEER_A_PRESHARED_KEY], sizeof (peer_c->data.preshared_key)); - /* FIXME(netlink-bzero-secret) */ - nm_explicit_bzero (nla_data (tb[WGPEER_A_PRESHARED_KEY]), - nla_len (tb[WGPEER_A_PRESHARED_KEY])); - } - if (tb[WGPEER_A_ENDPOINT]) { - const struct sockaddr *addr = nla_data (tb[WGPEER_A_ENDPOINT]); - unsigned short family; - - G_STATIC_ASSERT (sizeof (addr->sa_family) == sizeof (family)); - memcpy (&family, &addr->sa_family, sizeof (addr->sa_family)); - - if ( family == AF_INET - && nla_len (tb[WGPEER_A_ENDPOINT]) == sizeof (struct sockaddr_in)) { - const struct sockaddr_in *addr4 = (const struct sockaddr_in *) addr; - - peer_c->data.endpoint_family = AF_INET; - peer_c->data.endpoint_port = unaligned_read_be16 (&addr4->sin_port); - peer_c->data.endpoint_addr.addr4 = unaligned_read_ne32 (&addr4->sin_addr.s_addr); - memcpy (&peer_c->data.endpoint_addr.addr4, &addr4->sin_addr.s_addr, 4); - } else if ( family == AF_INET6 - && nla_len (tb[WGPEER_A_ENDPOINT]) == sizeof (struct sockaddr_in6)) { - const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6 *) addr; - - peer_c->data.endpoint_family = AF_INET6; - peer_c->data.endpoint_port = unaligned_read_be16 (&addr6->sin6_port); - memcpy (&peer_c->data.endpoint_addr.addr6, &addr6->sin6_addr, 16); - } - } - if (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]) - peer_c->data.persistent_keepalive_interval = nla_get_u64 (tb[WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL]); - if (tb[WGPEER_A_LAST_HANDSHAKE_TIME]) - nla_memcpy (&peer_c->data.last_handshake_time, tb[WGPEER_A_LAST_HANDSHAKE_TIME], sizeof (peer_c->data.last_handshake_time)); - if (tb[WGPEER_A_RX_BYTES]) - peer_c->data.rx_bytes = nla_get_u64 (tb[WGPEER_A_RX_BYTES]); - if (tb[WGPEER_A_TX_BYTES]) - peer_c->data.tx_bytes = nla_get_u64 (tb[WGPEER_A_TX_BYTES]); - } - - if (tb[WGPEER_A_ALLOWEDIPS]) { - struct nlattr *attr; - int rem; - GArray *allowed_ips = *p_allowed_ips; - - nla_for_each_nested (attr, tb[WGPEER_A_ALLOWEDIPS], rem) { - if (!allowed_ips) { - allowed_ips = g_array_new (FALSE, FALSE, sizeof (NMPWireGuardAllowedIP)); - *p_allowed_ips = allowed_ips; - g_array_set_size (allowed_ips, 1); - } else - g_array_set_size (allowed_ips, allowed_ips->len + 1); - - if (!_wireguard_update_from_allowed_ips_nla (&g_array_index (allowed_ips, - NMPWireGuardAllowedIP, - allowed_ips->len - 1), - attr)) { - /* we ignore the error of parsing one allowed-ip. */ - g_array_set_size (allowed_ips, allowed_ips->len - 1); - continue; - } - - if (!peer_c->data._construct_idx_end) - peer_c->data._construct_idx_start = allowed_ips->len - 1; - peer_c->data._construct_idx_end = allowed_ips->len; - } - } - - return TRUE; -} - -typedef struct { - const int ifindex; - NMPObject *obj; - CList peers; - GArray *allowed_ips; -} WireGuardParseData; - -static int -_wireguard_get_device_cb (struct nl_msg *msg, void *arg) -{ - static const struct nla_policy policy[WGDEVICE_A_MAX + 1] = { - [WGDEVICE_A_IFINDEX] = { .type = NLA_U32 }, - [WGDEVICE_A_IFNAME] = { .type = NLA_NUL_STRING, .maxlen = IFNAMSIZ }, - [WGDEVICE_A_PRIVATE_KEY] = { }, - [WGDEVICE_A_PUBLIC_KEY] = { }, - [WGDEVICE_A_FLAGS] = { .type = NLA_U32 }, - [WGDEVICE_A_LISTEN_PORT] = { .type = NLA_U16 }, - [WGDEVICE_A_FWMARK] = { .type = NLA_U32 }, - [WGDEVICE_A_PEERS] = { .type = NLA_NESTED }, - }; - WireGuardParseData *parse_data = arg; - struct nlattr *tb[WGDEVICE_A_MAX + 1]; - int nlerr; - - nlerr = genlmsg_parse (nlmsg_hdr (msg), 0, tb, WGDEVICE_A_MAX, policy); - if (nlerr < 0) - return NL_SKIP; - - if (tb[WGDEVICE_A_IFINDEX]) { - int ifindex; - - ifindex = (int) nla_get_u32 (tb[WGDEVICE_A_IFINDEX]); - if ( ifindex <= 0 - || parse_data->ifindex != ifindex) - return NL_SKIP; - } else { - if (!parse_data->obj) - return NL_SKIP; - } - - if (parse_data->obj) { - /* we already have an object instance. This means the netlink message - * is a continuation, only providing more WGDEVICE_A_PEERS data below. */ - } else { - NMPObject *obj; - NMPlatformLnkWireGuard *props; - - obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_WIREGUARD, NULL); - props = &obj->lnk_wireguard; - - if (tb[WGDEVICE_A_PRIVATE_KEY]) { - nla_memcpy (props->private_key, tb[WGDEVICE_A_PRIVATE_KEY], sizeof (props->private_key)); - /* FIXME(netlink-bzero-secret): extend netlink library to wipe memory. For now, - * just hack it here (yes, this does not cover all places where the - * private key was copied). */ - nm_explicit_bzero (nla_data (tb[WGDEVICE_A_PRIVATE_KEY]), - nla_len (tb[WGDEVICE_A_PRIVATE_KEY])); - } - if (tb[WGDEVICE_A_PUBLIC_KEY]) - nla_memcpy (props->public_key, tb[WGDEVICE_A_PUBLIC_KEY], sizeof (props->public_key)); - if (tb[WGDEVICE_A_LISTEN_PORT]) - props->listen_port = nla_get_u16 (tb[WGDEVICE_A_LISTEN_PORT]); - if (tb[WGDEVICE_A_FWMARK]) - props->fwmark = nla_get_u32 (tb[WGDEVICE_A_FWMARK]); - - parse_data->obj = obj; - } - - if (tb[WGDEVICE_A_PEERS]) { - struct nlattr *attr; - int rem; - - nla_for_each_nested (attr, tb[WGDEVICE_A_PEERS], rem) { - if (!_wireguard_update_from_peers_nla (&parse_data->peers, &parse_data->allowed_ips, attr)) { - /* we ignore the error of parsing one peer. - * _wireguard_update_from_peers_nla() leaves the @peers array in the - * desired state. */ - } - } - } - - return NL_OK; -} - -static const NMPObject * -_wireguard_read_info (NMPlatform *platform /* used only as logging context */, - struct nl_sock *genl, - int wireguard_family_id, - int ifindex) -{ - nm_auto_nlmsg struct nl_msg *msg = NULL; - NMPObject *obj = NULL; - WireGuardPeerConstruct *peer_c; - WireGuardPeerConstruct *peer_c_safe; - gs_unref_array GArray *allowed_ips = NULL; - WireGuardParseData parse_data = { - .ifindex = ifindex, - }; - guint i; - - nm_assert (genl); - nm_assert (wireguard_family_id >= 0); - nm_assert (ifindex > 0); - - msg = nlmsg_alloc (); - - if (!genlmsg_put (msg, - NL_AUTO_PORT, - NL_AUTO_SEQ, - wireguard_family_id, - 0, - NLM_F_DUMP, - WG_CMD_GET_DEVICE, - 1)) - return NULL; - - NLA_PUT_U32 (msg, WGDEVICE_A_IFINDEX, (guint32) ifindex); - - if (nl_send_auto (genl, msg) < 0) - return NULL; - - c_list_init (&parse_data.peers); - - /* we ignore errors, and return whatever we could successfully - * parse. */ - nl_recvmsgs (genl, - &((const struct nl_cb) { - .valid_cb = _wireguard_get_device_cb, - .valid_arg = (gpointer) &parse_data, - })); - - /* unpack: transfer ownership */ - obj = parse_data.obj; - allowed_ips = parse_data.allowed_ips; - - if (!obj) { - while ((peer_c = c_list_first_entry (&parse_data.peers, WireGuardPeerConstruct, lst))) { - c_list_unlink_stale (&peer_c->lst); - nm_explicit_bzero (&peer_c->data.preshared_key, sizeof (peer_c->data.preshared_key)); - g_slice_free (WireGuardPeerConstruct, peer_c); - } - return NULL; - } - - /* we receive peers/allowed-ips possibly in separate netlink messages. Hence, while - * parsing the dump, we don't know upfront how many peers/allowed-ips we will receive. - * - * We solve that, by collecting all peers with a CList. It's done this way, - * because a GArray would require growing the array, but we want to bzero() - * the preshared-key of each peer while reallocating. The CList apprach avoids - * that. - * - * For allowed-ips, we instead track one GArray, which are all appended - * there. The realloc/resize of the GArray is fine there. However, - * while we build the GArray, we don't yet have the final pointers. - * Hence, while constructing, we track the indexes with peer->_construct_idx_* - * fields. These indexes must be convered to actual pointers blow. - * - * This is all done during parsing. In the final NMPObjectLnkWireGuard we - * don't want the CList anymore and repackage the NMPObject tightly. The - * reason is, that NMPObject instances are immutable and long-living. Spend - * a bit effort below during construction to obtain a most suitable representation - * in this regard. */ - obj->_lnk_wireguard.peers_len = c_list_length (&parse_data.peers); - obj->_lnk_wireguard.peers = obj->_lnk_wireguard.peers_len > 0 - ? g_new (NMPWireGuardPeer, obj->_lnk_wireguard.peers_len) - : NULL; - - /* duplicate allowed_ips instead of using the pointer. The GArray possibly has more - * space allocated then we need, and we want to get rid of this excess buffer. - * Note that NMPObject instance is possibly put into the cache and long-living. */ - obj->_lnk_wireguard._allowed_ips_buf_len = allowed_ips ? allowed_ips->len : 0u; - obj->_lnk_wireguard._allowed_ips_buf = obj->_lnk_wireguard._allowed_ips_buf_len > 0 - ? (NMPWireGuardAllowedIP *) nm_memdup (allowed_ips->data, - sizeof (NMPWireGuardAllowedIP) * allowed_ips->len) - : NULL; - - i = 0; - c_list_for_each_entry_safe (peer_c, peer_c_safe, &parse_data.peers, lst) { - NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &obj->_lnk_wireguard.peers[i++]; - - *peer = peer_c->data; - - c_list_unlink_stale (&peer_c->lst); - nm_explicit_bzero (&peer_c->data.preshared_key, sizeof (peer_c->data.preshared_key)); - g_slice_free (WireGuardPeerConstruct, peer_c); - - if (peer->_construct_idx_end != 0) { - guint len; - - nm_assert (obj->_lnk_wireguard._allowed_ips_buf); - nm_assert (peer->_construct_idx_end > peer->_construct_idx_start); - nm_assert (peer->_construct_idx_start < obj->_lnk_wireguard._allowed_ips_buf_len); - nm_assert (peer->_construct_idx_end <= obj->_lnk_wireguard._allowed_ips_buf_len); - - len = peer->_construct_idx_end - peer->_construct_idx_start; - peer->allowed_ips = &obj->_lnk_wireguard._allowed_ips_buf[peer->_construct_idx_start]; - peer->allowed_ips_len = len; - } else { - nm_assert (!peer->_construct_idx_start); - nm_assert (!peer->_construct_idx_end); - peer->allowed_ips = NULL; - peer->allowed_ips_len = 0; - } - } - - return obj; - -nla_put_failure: - g_return_val_if_reached (NULL); -} - -/*****************************************************************************/ - /* Copied and heavily modified from libnl3's link_msg_parser(). */ static NMPObject * _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr *nlh, gboolean id_only) @@ -2329,39 +1707,37 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr const char *nl_info_kind = NULL; int err; nm_auto_nmpobj NMPObject *obj = NULL; + NMPObject *obj_result = NULL; gboolean completed_from_cache_val = FALSE; gboolean *completed_from_cache = cache ? &completed_from_cache_val : NULL; const NMPObject *link_cached = NULL; - const NMPObject *lnk_data = NULL; + NMPObject *lnk_data = NULL; gboolean address_complete_from_cache = TRUE; gboolean lnk_data_complete_from_cache = TRUE; - gboolean need_ext_data = FALSE; gboolean af_inet6_token_valid = FALSE; gboolean af_inet6_addr_gen_mode_valid = FALSE; if (!nlmsg_valid_hdr (nlh, sizeof (*ifi))) return NULL; - ifi = nlmsg_data (nlh); + ifi = nlmsg_data(nlh); if (ifi->ifi_family != AF_UNSPEC) return NULL; - if (ifi->ifi_index <= 0) - return NULL; obj = nmp_object_new_link (ifi->ifi_index); if (id_only) - return g_steal_pointer (&obj); + goto id_only_handled; err = nlmsg_parse (nlh, sizeof (*ifi), tb, IFLA_MAX, policy); if (err < 0) - return NULL; + goto errout; if (!tb[IFLA_IFNAME]) - return NULL; + goto errout; nla_strlcpy(obj->link.name, tb[IFLA_IFNAME], IFNAMSIZ); if (!obj->link.name[0]) - return NULL; + goto errout; if (!tb[IFLA_MTU]) { /* Kernel has two places that send RTM_GETLINK messages: @@ -2376,14 +1752,14 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr * To some extent this is a hack and correct approach is to * merge objects per-field. */ - return NULL; + goto errout; } obj->link.mtu = nla_get_u32 (tb[IFLA_MTU]); if (tb[IFLA_LINKINFO]) { err = nla_parse_nested (li, IFLA_INFO_MAX, tb[IFLA_LINKINFO], policy_link_info); if (err < 0) - return NULL; + goto errout; if (li[IFLA_INFO_KIND]) nl_info_kind = nla_get_string (li[IFLA_INFO_KIND]); @@ -2462,7 +1838,6 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr switch (obj->link.type) { case NM_LINK_TYPE_GRE: - case NM_LINK_TYPE_GRETAP: lnk_data = _parse_lnk_gre (nl_info_kind, nl_info_data); break; case NM_LINK_TYPE_INFINIBAND: @@ -2471,10 +1846,6 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr case NM_LINK_TYPE_IP6TNL: lnk_data = _parse_lnk_ip6tnl (nl_info_kind, nl_info_data); break; - case NM_LINK_TYPE_IP6GRE: - case NM_LINK_TYPE_IP6GRETAP: - lnk_data = _parse_lnk_ip6gre (nl_info_kind, nl_info_data); - break; case NM_LINK_TYPE_IPIP: lnk_data = _parse_lnk_ipip (nl_info_kind, nl_info_data); break; @@ -2497,15 +1868,6 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr case NM_LINK_TYPE_VXLAN: lnk_data = _parse_lnk_vxlan (nl_info_kind, nl_info_data); break; - case NM_LINK_TYPE_WIFI: - case NM_LINK_TYPE_OLPC_MESH: - case NM_LINK_TYPE_WPAN: - need_ext_data = TRUE; - lnk_data_complete_from_cache = FALSE; - break; - case NM_LINK_TYPE_WIREGUARD: - lnk_data_complete_from_cache = TRUE; - break; default: lnk_data_complete_from_cache = FALSE; break; @@ -2513,14 +1875,12 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr if ( completed_from_cache && ( lnk_data_complete_from_cache - || need_ext_data || address_complete_from_cache || !af_inet6_token_valid || !af_inet6_addr_gen_mode_valid || !tb[IFLA_STATS64])) { _lookup_cached_link (cache, obj->link.ifindex, completed_from_cache, &link_cached); - if ( link_cached - && link_cached->_link.netlink.is_in_netlink) { + if (link_cached) { if ( lnk_data_complete_from_cache && link_cached->link.type == obj->link.type && link_cached->_link.netlink.lnk @@ -2533,16 +1893,8 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr * Also, sometimes the info-data is missing for updates. In this case * we want to keep the previously received lnk_data. */ nmp_object_unref (lnk_data); - lnk_data = nmp_object_ref (link_cached->_link.netlink.lnk); + lnk_data = (NMPObject *) nmp_object_ref (link_cached->_link.netlink.lnk); } - - if ( need_ext_data - && link_cached->link.type == obj->link.type - && link_cached->_link.ext_data) { - /* Prefer reuse of existing ext_data object */ - obj->_link.ext_data = g_object_ref (link_cached->_link.ext_data); - } - if (address_complete_from_cache) obj->link.addr = link_cached->link.addr; if (!af_inet6_token_valid) @@ -2560,71 +1912,12 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr obj->_link.netlink.lnk = lnk_data; - if ( need_ext_data - && obj->_link.ext_data == NULL) { - switch (obj->link.type) { - case NM_LINK_TYPE_WIFI: - obj->_link.ext_data = (GObject *) nm_wifi_utils_new (ifi->ifi_index, - _genl_sock (NM_LINUX_PLATFORM (platform)), - TRUE); - break; - case NM_LINK_TYPE_OLPC_MESH: -#if HAVE_WEXT - /* The kernel driver now uses nl80211, but we force use of WEXT because - * the cfg80211 interactions are not quite ready to support access to - * mesh control through nl80211 just yet. - */ - obj->_link.ext_data = (GObject *) nm_wifi_utils_wext_new (ifi->ifi_index, FALSE); -#endif - break; - case NM_LINK_TYPE_WPAN: - obj->_link.ext_data = (GObject *) nm_wpan_utils_new (ifi->ifi_index, - _genl_sock (NM_LINUX_PLATFORM (platform)), - TRUE); - break; - default: - g_assert_not_reached (); - } - } - - if (obj->link.type == NM_LINK_TYPE_WIREGUARD) { - const NMPObject *lnk_data_new = NULL; - struct nl_sock *genl = NM_LINUX_PLATFORM_GET_PRIVATE (platform)->genl; - - /* The WireGuard kernel module does not yet send link update - * notifications, so we don't actually update the cache. For - * now, always refetch link data here. */ - - _lookup_cached_link (cache, obj->link.ifindex, completed_from_cache, &link_cached); - if ( link_cached - && link_cached->_link.netlink.is_in_netlink - && link_cached->link.type == NM_LINK_TYPE_WIREGUARD) - obj->_link.wireguard_family_id = link_cached->_link.wireguard_family_id; - else - obj->_link.wireguard_family_id = -1; - - if (obj->_link.wireguard_family_id < 0) - obj->_link.wireguard_family_id = genl_ctrl_resolve (genl, "wireguard"); - - if (obj->_link.wireguard_family_id >= 0) { - lnk_data_new = _wireguard_read_info (platform, - genl, - obj->_link.wireguard_family_id, - obj->link.ifindex); - } - - if ( lnk_data_new - && obj->_link.netlink.lnk - && nmp_object_equal (obj->_link.netlink.lnk, lnk_data_new)) - nmp_object_unref (lnk_data_new); - else { - nmp_object_unref (obj->_link.netlink.lnk); - obj->_link.netlink.lnk = lnk_data_new; - } - } - obj->_link.netlink.is_in_netlink = TRUE; - return g_steal_pointer (&obj); +id_only_handled: + obj_result = obj; + obj = NULL; +errout: + return obj_result; } /* Copied and heavily modified from libnl3's addr_msg_parser(). */ @@ -2641,6 +1934,7 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) int err; gboolean is_v4; nm_auto_nmpobj NMPObject *obj = NULL; + NMPObject *obj_result = NULL; int addr_len; guint32 lifetime, preferred, timestamp; @@ -2649,19 +1943,19 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) ifa = nlmsg_data(nlh); if (!NM_IN_SET (ifa->ifa_family, AF_INET, AF_INET6)) - return NULL; + goto errout; is_v4 = ifa->ifa_family == AF_INET; err = nlmsg_parse (nlh, sizeof(*ifa), tb, IFA_MAX, policy); if (err < 0) - return NULL; + goto errout; addr_len = is_v4 ? sizeof (in_addr_t) : sizeof (struct in6_addr); if (ifa->ifa_prefixlen > (is_v4 ? 32 : 128)) - return NULL; + goto errout; /*****************************************************************/ @@ -2670,8 +1964,8 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) obj->ip_address.ifindex = ifa->ifa_index; obj->ip_address.plen = ifa->ifa_prefixlen; - _check_addr_or_return_null (tb, IFA_ADDRESS, addr_len); - _check_addr_or_return_null (tb, IFA_LOCAL, addr_len); + _check_addr_or_errout (tb, IFA_ADDRESS, addr_len); + _check_addr_or_errout (tb, IFA_LOCAL, addr_len); if (is_v4) { /* For IPv4, kernel omits IFA_LOCAL/IFA_ADDRESS if (and only if) they * are effectively 0.0.0.0 (all-zero). */ @@ -2735,7 +2029,10 @@ _new_from_nl_addr (struct nlmsghdr *nlh, gboolean id_only) &obj->ip_address.lifetime, &obj->ip_address.preferred); - return g_steal_pointer (&obj); + obj_result = obj; + obj = NULL; +errout: + return obj_result; } /* Copied and heavily modified from libnl3's rtnl_route_parse() and parse_multipath(). */ @@ -2758,6 +2055,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) int err; gboolean is_v4; nm_auto_nmpobj NMPObject *obj = NULL; + NMPObject *obj_result = NULL; int addr_len; struct { gboolean is_present; @@ -2776,14 +2074,14 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) *****************************************************************/ if (!NM_IN_SET (rtm->rtm_family, AF_INET, AF_INET6)) - return NULL; + goto errout; if (rtm->rtm_type != RTN_UNICAST) - return NULL; + goto errout; err = nlmsg_parse (nlh, sizeof (struct rtmsg), tb, RTA_MAX, policy); if (err < 0) - return NULL; + goto errout; /*****************************************************************/ @@ -2793,7 +2091,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) : sizeof (struct in6_addr); if (rtm->rtm_dst_len > (is_v4 ? 32 : 128)) - return NULL; + goto errout; /***************************************************************** * parse nexthops. Only handle routes with one nh. @@ -2809,7 +2107,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) if (nh.is_present) { /* we don't support multipath routes. */ - return NULL; + goto errout; } nh.is_present = TRUE; @@ -2823,9 +2121,9 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) rtnh->rtnh_len - sizeof (*rtnh), policy); if (err < 0) - return NULL; + goto errout; - if (_check_addr_or_return_null (ntb, RTA_GATEWAY, addr_len)) + if (_check_addr_or_errout (ntb, RTA_GATEWAY, addr_len)) memcpy (&nh.gateway, nla_data (ntb[RTA_GATEWAY]), addr_len); } @@ -2842,7 +2140,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) if (tb[RTA_OIF]) ifindex = nla_get_u32 (tb[RTA_OIF]); - if (_check_addr_or_return_null (tb, RTA_GATEWAY, addr_len)) + if (_check_addr_or_errout (tb, RTA_GATEWAY, addr_len)) memcpy (&gateway, nla_data (tb[RTA_GATEWAY]), addr_len); if (!nh.is_present) { @@ -2856,10 +2154,10 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) * verify that it is a duplicate and ignore old-style nexthop. */ if ( nh.ifindex != ifindex || memcmp (&nh.gateway, &gateway, addr_len) != 0) - return NULL; + goto errout; } } else if (!nh.is_present) - return NULL; + goto errout; /*****************************************************************/ @@ -2878,7 +2176,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) err = nla_parse_nested (mtb, RTAX_MAX, tb[RTA_METRICS], rtax_policy); if (err < 0) - return NULL; + goto errout; if (mtb[RTAX_LOCK]) lock = nla_get_u32 (mtb[RTAX_LOCK]); @@ -2906,7 +2204,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) obj->ip_route.ifindex = nh.ifindex; - if (_check_addr_or_return_null (tb, RTA_DST, addr_len)) + if (_check_addr_or_errout (tb, RTA_DST, addr_len)) memcpy (obj->ip_route.network_ptr, nla_data (tb[RTA_DST]), addr_len); obj->ip_route.plen = rtm->rtm_dst_len; @@ -2922,7 +2220,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) if (is_v4) obj->ip4_route.scope_inv = nm_platform_route_scope_inv (rtm->rtm_scope); - if (_check_addr_or_return_null (tb, RTA_PREFSRC, addr_len)) { + if (_check_addr_or_errout (tb, RTA_PREFSRC, addr_len)) { if (is_v4) memcpy (&obj->ip4_route.pref_src, nla_data (tb[RTA_PREFSRC]), addr_len); else @@ -2933,7 +2231,7 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) obj->ip4_route.tos = rtm->rtm_tos; else { if (tb[RTA_SRC]) { - _check_addr_or_return_null (tb, RTA_SRC, addr_len); + _check_addr_or_errout (tb, RTA_SRC, addr_len); memcpy (&obj->ip6_route.src, nla_data (tb[RTA_SRC]), addr_len); } obj->ip6_route.src_plen = rtm->rtm_src_len; @@ -2963,7 +2261,10 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only) obj->ip_route.r_rtm_flags = rtm->rtm_flags; obj->ip_route.rt_source = nmp_utils_ip_config_source_from_rtprot (rtm->rtm_protocol); - return g_steal_pointer (&obj); + obj_result = obj; + obj = NULL; +errout: + return obj_result; } static NMPObject * @@ -3640,16 +2941,103 @@ nla_put_failure: g_return_val_if_reached (NULL); } -/*****************************************************************************/ +/****************************************************************** + * NMPlatform types and functions + ******************************************************************/ + +typedef enum { + DELAYED_ACTION_RESPONSE_TYPE_VOID = 0, + DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS = 1, + DELAYED_ACTION_RESPONSE_TYPE_ROUTE_GET = 2, +} DelayedActionWaitForNlResponseType; + +typedef struct { + guint32 seq_number; + WaitForNlResponseResult seq_result; + DelayedActionWaitForNlResponseType response_type; + gint64 timeout_abs_ns; + WaitForNlResponseResult *out_seq_result; + char **out_errmsg; + union { + gint *out_refresh_all_in_progess; + NMPObject **out_route_get; + gpointer out_data; + } response; +} DelayedActionWaitForNlResponseData; + +typedef struct { + struct nl_sock *nlh; + guint32 nlh_seq_next; +#ifdef NM_MORE_LOGGING + guint32 nlh_seq_last_handled; +#endif + guint32 nlh_seq_last_seen; + GIOChannel *event_channel; + guint event_id; + + bool pruning[_DELAYED_ACTION_IDX_REFRESH_ALL_NUM]; + + bool sysctl_get_warned; + GHashTable *sysctl_get_prev_values; + + NMUdevClient *udev_client; + + struct { + /* which delayed actions are scheduled, as marked in @flags. + * Some types have additional arguments in the fields below. */ + DelayedActionType flags; + + /* counter that a refresh all action is in progress, separated + * by type. */ + gint refresh_all_in_progess[_DELAYED_ACTION_IDX_REFRESH_ALL_NUM]; + + GPtrArray *list_master_connected; + GPtrArray *list_refresh_link; + GArray *list_wait_for_nl_response; + + gint is_handling; + } delayed_action; + + GHashTable *wifi_data; +} NMLinuxPlatformPrivate; + +struct _NMLinuxPlatform { + NMPlatform parent; + NMLinuxPlatformPrivate _priv; +}; + +struct _NMLinuxPlatformClass { + NMPlatformClass parent; +}; -static struct nl_sock * -_genl_sock (NMLinuxPlatform *platform) +G_DEFINE_TYPE (NMLinuxPlatform, nm_linux_platform, NM_TYPE_PLATFORM) + +#define NM_LINUX_PLATFORM_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMLinuxPlatform, NM_IS_LINUX_PLATFORM, NMPlatform) + +NMPlatform * +nm_linux_platform_new (gboolean log_with_ptr, gboolean netns_support) { - NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + gboolean use_udev = FALSE; + + if ( nmp_netns_is_initial () + && access ("/sys", W_OK) == 0) + use_udev = TRUE; - return priv->genl; + return g_object_new (NM_TYPE_LINUX_PLATFORM, + NM_PLATFORM_LOG_WITH_PTR, log_with_ptr, + NM_PLATFORM_USE_UDEV, use_udev, + NM_PLATFORM_NETNS_SUPPORT, netns_support, + NULL); +} + +void +nm_linux_platform_setup (void) +{ + nm_platform_setup (nm_linux_platform_new (FALSE, FALSE)); } +/*****************************************************************************/ + #define ASSERT_SYSCTL_ARGS(pathid, dirfd, path) \ G_STMT_START { \ const char *const _pathid = (pathid); \ @@ -3676,9 +3064,7 @@ _log_dbg_sysctl_set_impl (NMPlatform *platform, const char *pathid, int dirfd, c char *contents; gs_free char *value_escaped = g_strescape (value, NULL); - if (nm_utils_file_get_contents (dirfd, path, 1*1024*1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &contents, NULL, &error) < 0) { + if (nm_utils_file_get_contents (dirfd, path, 1*1024*1024, &contents, NULL, &error) < 0) { _LOGD ("sysctl: setting '%s' to '%s' (current value cannot be read: %s)", pathid, value_escaped, error->message); g_clear_error (&error); return; @@ -3895,9 +3281,7 @@ sysctl_get (NMPlatform *platform, const char *pathid, int dirfd, const char *pat pathid = path; } - if (nm_utils_file_get_contents (dirfd, path, 1*1024*1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &contents, NULL, &error) < 0) { + if (nm_utils_file_get_contents (dirfd, path, 1*1024*1024, &contents, NULL, &error) < 0) { /* We assume FAILED means EOPNOTSUP */ if ( g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT) || g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NODEV) @@ -4068,7 +3452,7 @@ delayed_action_refresh_all_in_progress (NMPlatform *platform, DelayedActionType if (NM_FLAGS_ANY (priv->delayed_action.flags, action_type)) return TRUE; - if (priv->delayed_action.refresh_all_in_progress[delayed_action_refresh_all_to_idx (action_type)] > 0) + if (priv->delayed_action.refresh_all_in_progess[delayed_action_refresh_all_to_idx (action_type)] > 0) return TRUE; return FALSE; @@ -4098,10 +3482,10 @@ delayed_action_wait_for_nl_response_complete (NMPlatform *platform, case DELAYED_ACTION_RESPONSE_TYPE_VOID: break; case DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS: - if (data->response.out_refresh_all_in_progress) { - nm_assert (*data->response.out_refresh_all_in_progress > 0); - *data->response.out_refresh_all_in_progress -= 1; - data->response.out_refresh_all_in_progress = NULL; + if (data->response.out_refresh_all_in_progess) { + nm_assert (*data->response.out_refresh_all_in_progess > 0); + *data->response.out_refresh_all_in_progess -= 1; + data->response.out_refresh_all_in_progess = NULL; } break; case DELAYED_ACTION_RESPONSE_TYPE_ROUTE_GET: @@ -4126,7 +3510,7 @@ delayed_action_wait_for_nl_response_complete_check (NMPlatform *platform, guint i; guint32 next_seq_number = 0; gint64 next_timeout_abs_ns = 0; - int now_ns = 0; + gint now_ns = 0; for (i = 0; i < priv->delayed_action.list_wait_for_nl_response->len; ) { const DelayedActionWaitForNlResponseData *data = &g_array_index (priv->delayed_action.list_wait_for_nl_response, DelayedActionWaitForNlResponseData, i); @@ -4548,10 +3932,7 @@ cache_on_change (NMPlatform *platform, if ( !obj_new->_link.netlink.lnk && NM_IN_SET (obj_new->link.type, NM_LINK_TYPE_GRE, - NM_LINK_TYPE_GRETAP, NM_LINK_TYPE_IP6TNL, - NM_LINK_TYPE_IP6GRE, - NM_LINK_TYPE_IP6GRETAP, NM_LINK_TYPE_INFINIBAND, NM_LINK_TYPE_MACVLAN, NM_LINK_TYPE_MACVLAN, @@ -4824,11 +4205,11 @@ do_request_all_no_delayed_actions (NMPlatform *platform, DelayedActionType actio const NMPClass *klass = nmp_class_from_type (obj_type); nm_auto_nlmsg struct nl_msg *nlmsg = NULL; int nle; - int *out_refresh_all_in_progress; + gint *out_refresh_all_in_progess; - out_refresh_all_in_progress = &priv->delayed_action.refresh_all_in_progress[delayed_action_refresh_all_to_idx (iflags)]; - nm_assert (*out_refresh_all_in_progress >= 0); - *out_refresh_all_in_progress += 1; + out_refresh_all_in_progess = &priv->delayed_action.refresh_all_in_progess[delayed_action_refresh_all_to_idx (iflags)]; + nm_assert (*out_refresh_all_in_progess >= 0); + *out_refresh_all_in_progess += 1; /* clear any delayed action that request a refresh of this object type. */ priv->delayed_action.flags &= ~iflags; @@ -4862,9 +4243,9 @@ do_request_all_no_delayed_actions (NMPlatform *platform, DelayedActionType actio if (nle < 0) continue; - if (_nl_send_nlmsg (platform, nlmsg, NULL, NULL, DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS, out_refresh_all_in_progress) < 0) { - nm_assert (*out_refresh_all_in_progress > 0); - *out_refresh_all_in_progress -= 1; + if (_nl_send_nlmsg (platform, nlmsg, NULL, NULL, DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS, out_refresh_all_in_progess) < 0) { + nm_assert (*out_refresh_all_in_progess > 0); + *out_refresh_all_in_progess -= 1; } } } @@ -4893,10 +4274,10 @@ event_seq_check_refresh_all (NMPlatform *platform, guint32 seq_number) data = &g_array_index (priv->delayed_action.list_wait_for_nl_response, DelayedActionWaitForNlResponseData, i); if ( data->response_type == DELAYED_ACTION_RESPONSE_TYPE_REFRESH_ALL_IN_PROGRESS - && data->response.out_refresh_all_in_progress + && data->response.out_refresh_all_in_progess && data->seq_number == priv->nlh_seq_last_seen) { - *data->response.out_refresh_all_in_progress -= 1; - data->response.out_refresh_all_in_progress = NULL; + *data->response.out_refresh_all_in_progess -= 1; + data->response.out_refresh_all_in_progess = NULL; break; } } @@ -4937,7 +4318,7 @@ event_seq_check (NMPlatform *platform, guint32 seq_number, WaitForNlResponseResu } } -#if NM_MORE_LOGGING +#ifdef NM_MORE_LOGGING if (seq_number != priv->nlh_seq_last_handled) _LOGt ("netlink: recvmsg: unwaited sequence number %u", seq_number); priv->nlh_seq_last_handled = seq_number; @@ -5360,9 +4741,6 @@ retry: } else if (NM_IN_SET (-((int) seq_result), ENODEV)) { log_level = LOGL_DEBUG; result = NM_PLATFORM_ERROR_NOT_FOUND; - } else if (-((int) seq_result) == EAFNOSUPPORT) { - log_level = LOGL_DEBUG; - result = NM_PLATFORM_ERROR_OPNOTSUPP; } else { log_level = LOGL_WARN; result = NM_PLATFORM_ERROR_UNSPECIFIED; @@ -5463,6 +4841,8 @@ link_set_netns (NMPlatform *platform, { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + _LOGD ("link: move link %d to network namespace with fd %d", ifindex, netns_fd); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -5651,6 +5031,7 @@ static NMPlatformError link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size_t length) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + gs_free char *mac = NULL; const ChangeLinkData d = { .set_address = { .address = address, @@ -5661,6 +5042,10 @@ link_set_address (NMPlatform *platform, int ifindex, gconstpointer address, size if (!address || !length) g_return_val_if_reached (NM_PLATFORM_ERROR_BUG); + _LOGD ("link: change %d: address: %s (%lu bytes)", ifindex, + (mac = nm_utils_hwaddr_ntoa (address, length)), + (unsigned long) length); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -5682,6 +5067,8 @@ link_set_name (NMPlatform *platform, int ifindex, const char *name) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + _LOGD ("link: change %d: name: %s", ifindex, name); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -5717,6 +5104,8 @@ link_set_mtu (NMPlatform *platform, int ifindex, guint32 mtu) { nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + _LOGD ("link: change %d: mtu: %u", ifindex, (unsigned) mtu); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -5734,18 +5123,16 @@ nla_put_failure: } static gboolean -link_set_sriov_params (NMPlatform *platform, - int ifindex, - guint num_vfs, - int autoprobe) +link_set_sriov_num_vfs (NMPlatform *platform, int ifindex, guint num_vfs) { nm_auto_pop_netns NMPNetns *netns = NULL; nm_auto_close int dirfd = -1; - gboolean current_autoprobe; - guint total, current_num; + int total, current; char ifname[IFNAMSIZ]; char buf[64]; + _LOGD ("link: change %d: num VFs: %u", ifindex, num_vfs); + if (!nm_platform_netns_push (platform, &netns)) return FALSE; @@ -5753,69 +5140,46 @@ link_set_sriov_params (NMPlatform *platform, if (!dirfd) return FALSE; - total = nm_platform_sysctl_get_int_checked (platform, - NMP_SYSCTL_PATHID_NETDIR (dirfd, - ifname, - "device/sriov_totalvfs"), - 10, 0, G_MAXUINT, 0); - if (errno) + total = nm_platform_sysctl_get_int32 (platform, + NMP_SYSCTL_PATHID_NETDIR (dirfd, + ifname, + "device/sriov_totalvfs"), + -1); + if (total < 1) return FALSE; if (num_vfs > total) { _LOGW ("link: %d only supports %u VFs (requested %u)", ifindex, total, num_vfs); num_vfs = total; } - /* - * Take special care when setting new values: - * - don't touch anything if the right values are already set - * - to change the number of VFs or autoprobe we need to destroy existing VFs - * - the autoprobe setting is irrelevant when numvfs is zero - */ - current_num = nm_platform_sysctl_get_int_checked (platform, - NMP_SYSCTL_PATHID_NETDIR (dirfd, - ifname, - "device/sriov_numvfs"), - 10, 0, G_MAXUINT, 0); - current_autoprobe = nm_platform_sysctl_get_int_checked (platform, - NMP_SYSCTL_PATHID_NETDIR (dirfd, - ifname, - "device/sriov_drivers_autoprobe"), - 10, 0, G_MAXUINT, 0); - if ( current_num == num_vfs - && (autoprobe == -1 || current_autoprobe == autoprobe)) + current = nm_platform_sysctl_get_int32 (platform, + NMP_SYSCTL_PATHID_NETDIR (dirfd, + ifname, + "device/sriov_numvfs"), + -1); + if (current == num_vfs) return TRUE; - if (current_num != 0) { - /* We need to destroy all other VFs before changing any value */ + if (current != 0) { + /* We need to destroy all other VFs before changing the value */ if (!nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "device/sriov_numvfs"), "0")) { - _LOGW ("link: couldn't reset SR-IOV num_vfs: %s", strerror (errno)); + _LOGW ("link: couldn't set SR-IOV num_vfs to %d: %s", 0, strerror (errno)); return FALSE; } + if (num_vfs == 0) + return TRUE; } - if (num_vfs == 0) - return TRUE; - - if ( autoprobe >= 0 - && current_autoprobe != autoprobe - && !nm_platform_sysctl_set (NM_PLATFORM_GET, - NMP_SYSCTL_PATHID_NETDIR (dirfd, - ifname, - "device/sriov_drivers_autoprobe"), - nm_sprintf_buf (buf, "%d", autoprobe))) { - _LOGW ("link: couldn't set SR-IOV drivers-autoprobe to %d: %s", autoprobe, strerror (errno)); - return FALSE; - } - + /* Finally, set the desired value */ if (!nm_platform_sysctl_set (NM_PLATFORM_GET, NMP_SYSCTL_PATHID_NETDIR (dirfd, ifname, "device/sriov_numvfs"), - nm_sprintf_buf (buf, "%u", num_vfs))) { + nm_sprintf_buf (buf, "%d", num_vfs))) { _LOGW ("link: couldn't set SR-IOV num_vfs to %d: %s", num_vfs, strerror (errno)); return FALSE; } @@ -5823,101 +5187,6 @@ link_set_sriov_params (NMPlatform *platform, return TRUE; } -static gboolean -link_set_sriov_vfs (NMPlatform *platform, int ifindex, const NMPlatformVF *const *vfs) -{ - nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - struct nlattr *list, *info, *vlan_list; - guint i; - - nlmsg = _nl_msg_new_link (RTM_NEWLINK, - 0, - ifindex, - NULL, - 0, - 0); - if (!nlmsg) - g_return_val_if_reached (NM_PLATFORM_ERROR_UNSPECIFIED); - - if (!(list = nla_nest_start (nlmsg, IFLA_VFINFO_LIST))) - goto nla_put_failure; - - for (i = 0; vfs[i]; i++) { - const NMPlatformVF *vf = vfs[i]; - - if (!(info = nla_nest_start (nlmsg, IFLA_VF_INFO))) - goto nla_put_failure; - - if (vf->spoofchk >= 0) { - struct _ifla_vf_setting ivs = { 0 }; - - ivs.vf = vf->index; - ivs.setting = vf->spoofchk; - NLA_PUT (nlmsg, IFLA_VF_SPOOFCHK, sizeof (ivs), &ivs); - } - - if (vf->trust >= 0) { - struct _ifla_vf_setting ivs = { 0 }; - - ivs.vf = vf->index; - ivs.setting = vf->trust; - NLA_PUT (nlmsg, IFLA_VF_TRUST, sizeof (ivs), &ivs); - } - - if (vf->mac.len) { - struct ifla_vf_mac ivm = { 0 }; - - ivm.vf = vf->index; - memcpy (ivm.mac, vf->mac.data, vf->mac.len); - NLA_PUT (nlmsg, IFLA_VF_MAC, sizeof (ivm), &ivm); - } - - if (vf->min_tx_rate || vf->max_tx_rate) { - struct _ifla_vf_rate ivr = { 0 }; - - ivr.vf = vf->index; - ivr.min_tx_rate = vf->min_tx_rate; - ivr.max_tx_rate = vf->max_tx_rate; - NLA_PUT (nlmsg, IFLA_VF_RATE, sizeof (ivr), &ivr); - } - - /* Kernel only supports one VLAN per VF now. If this - * changes in the future, we need to figure out how to - * clear existing VLANs and set new ones in one message - * with the new API.*/ - if (vf->num_vlans > 1) { - _LOGW ("multiple VLANs per VF are not supported at the moment"); - return FALSE; - } else { - struct _ifla_vf_vlan_info ivvi = { 0 }; - - if (!(vlan_list = nla_nest_start (nlmsg, IFLA_VF_VLAN_LIST))) - goto nla_put_failure; - - ivvi.vf = vf->index; - if (vf->num_vlans == 1) { - ivvi.vlan = vf->vlans[0].id; - ivvi.qos = vf->vlans[0].qos; - ivvi.vlan_proto = htons (vf->vlans[0].proto_ad ? ETH_P_8021AD : ETH_P_8021Q); - } else { - /* Clear existing VLAN */ - ivvi.vlan = 0; - ivvi.qos = 0; - ivvi.vlan_proto = htons (ETH_P_8021Q); - } - - NLA_PUT (nlmsg, IFLA_VF_VLAN_INFO, sizeof (ivvi), &ivvi); - nla_nest_end (nlmsg, vlan_list); - } - nla_nest_end (nlmsg, info); - } - nla_nest_end (nlmsg, list); - - return do_change_link (platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == NM_PLATFORM_ERROR_SUCCESS; -nla_put_failure: - g_return_val_if_reached (FALSE); -} - static char * link_get_physical_port_id (NMPlatform *platform, int ifindex) { @@ -5944,7 +5213,7 @@ link_get_dev_id (NMPlatform *platform, int ifindex) 16, 0, G_MAXUINT16, 0); } -static gboolean +static int vlan_add (NMPlatform *platform, const char *name, int parent, @@ -5960,6 +5229,10 @@ vlan_add (NMPlatform *platform, G_STATIC_ASSERT (NM_VLAN_FLAG_MVRP == (guint32) VLAN_FLAG_MVRP); vlan_flags &= (guint32) NM_VLAN_FLAGS_ALL; + + _LOGD ("link: add vlan '%s', parent %d, vlan id %d, flags %X", + name, parent, vlan_id, (unsigned) vlan_flags); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, 0, @@ -5986,7 +5259,7 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean +static int link_gre_add (NMPlatform *platform, const char *name, const NMPlatformLnkGre *props, @@ -5995,6 +5268,14 @@ link_gre_add (NMPlatform *platform, nm_auto_nlmsg struct nl_msg *nlmsg = NULL; struct nlattr *info; struct nlattr *data; + char buffer[INET_ADDRSTRLEN]; + + _LOGD (LOG_FMT_IP_TUNNEL, + "gre", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, @@ -6008,7 +5289,7 @@ link_gre_add (NMPlatform *platform, if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO))) goto nla_put_failure; - NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, props->is_tap ? "gretap" : "gre"); + NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, "gre"); if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA))) goto nla_put_failure; @@ -6022,20 +5303,18 @@ link_gre_add (NMPlatform *platform, NLA_PUT_U8 (nlmsg, IFLA_GRE_PMTUDISC, !!props->path_mtu_discovery); NLA_PUT_U32 (nlmsg, IFLA_GRE_IKEY, htonl (props->input_key)); NLA_PUT_U32 (nlmsg, IFLA_GRE_OKEY, htonl (props->output_key)); - NLA_PUT_U16 (nlmsg, IFLA_GRE_IFLAGS, htons (props->input_flags)); - NLA_PUT_U16 (nlmsg, IFLA_GRE_OFLAGS, htons (props->output_flags)); + NLA_PUT_U32 (nlmsg, IFLA_GRE_IFLAGS, htons (props->input_flags)); + NLA_PUT_U32 (nlmsg, IFLA_GRE_OFLAGS, htons (props->output_flags)); nla_nest_end (nlmsg, data); nla_nest_end (nlmsg, info); - return do_add_link_with_lookup (platform, - props->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE, - name, nlmsg, out_link); + return do_add_link_with_lookup (platform, NM_LINK_TYPE_GRE, name, nlmsg, out_link); nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean +static int link_ip6tnl_add (NMPlatform *platform, const char *name, const NMPlatformLnkIp6Tnl *props, @@ -6044,9 +5323,15 @@ link_ip6tnl_add (NMPlatform *platform, nm_auto_nlmsg struct nl_msg *nlmsg = NULL; struct nlattr *info; struct nlattr *data; + char buffer[INET_ADDRSTRLEN]; guint32 flowinfo; - g_return_val_if_fail (!props->is_gre, FALSE); + _LOGD (LOG_FMT_IP_TUNNEL, + "ip6tnl", + name, + props->parent_ifindex, + nm_utils_inet6_ntop (&props->local, NULL), + nm_utils_inet6_ntop (&props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, @@ -6091,69 +5376,7 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean -link_ip6gre_add (NMPlatform *platform, - const char *name, - const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink **out_link) -{ - nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - struct nlattr *info; - struct nlattr *data; - guint32 flowinfo; - - g_return_val_if_fail (props->is_gre, FALSE); - - nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE | NLM_F_EXCL, - 0, - name, - 0, - 0); - if (!nlmsg) - return FALSE; - - if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO))) - goto nla_put_failure; - - NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, props->is_tap ? "ip6gretap" : "ip6gre"); - - if (!(data = nla_nest_start (nlmsg, IFLA_INFO_DATA))) - goto nla_put_failure; - - if (props->parent_ifindex) - NLA_PUT_U32 (nlmsg, IFLA_GRE_LINK, props->parent_ifindex); - - NLA_PUT_U32 (nlmsg, IFLA_GRE_IKEY, htonl (props->input_key)); - NLA_PUT_U32 (nlmsg, IFLA_GRE_OKEY, htonl (props->output_key)); - NLA_PUT_U16 (nlmsg, IFLA_GRE_IFLAGS, htons (props->input_flags)); - NLA_PUT_U16 (nlmsg, IFLA_GRE_OFLAGS, htons (props->output_flags)); - - if (memcmp (&props->local, &in6addr_any, sizeof (in6addr_any))) - NLA_PUT (nlmsg, IFLA_GRE_LOCAL, sizeof (props->local), &props->local); - if (memcmp (&props->remote, &in6addr_any, sizeof (in6addr_any))) - NLA_PUT (nlmsg, IFLA_GRE_REMOTE, sizeof (props->remote), &props->remote); - - NLA_PUT_U8 (nlmsg, IFLA_GRE_TTL, props->ttl); - NLA_PUT_U8 (nlmsg, IFLA_GRE_ENCAP_LIMIT, props->encap_limit); - - flowinfo = props->flow_label & IP6_FLOWINFO_FLOWLABEL_MASK; - flowinfo |= (props->tclass << IP6_FLOWINFO_TCLASS_SHIFT) - & IP6_FLOWINFO_TCLASS_MASK; - NLA_PUT_U32 (nlmsg, IFLA_GRE_FLOWINFO, htonl (flowinfo)); - NLA_PUT_U32 (nlmsg, IFLA_GRE_FLAGS, props->flags); - - nla_nest_end (nlmsg, data); - nla_nest_end (nlmsg, info); - - return do_add_link_with_lookup (platform, - props->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE, - name, nlmsg, out_link); -nla_put_failure: - g_return_val_if_reached (FALSE); -} - -static gboolean +static int link_ipip_add (NMPlatform *platform, const char *name, const NMPlatformLnkIpIp *props, @@ -6162,6 +5385,14 @@ link_ipip_add (NMPlatform *platform, nm_auto_nlmsg struct nl_msg *nlmsg = NULL; struct nlattr *info; struct nlattr *data; + char buffer[INET_ADDRSTRLEN]; + + _LOGD (LOG_FMT_IP_TUNNEL, + "ipip", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, @@ -6196,7 +5427,7 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean +static int link_macsec_add (NMPlatform *platform, const char *name, int parent, @@ -6207,6 +5438,11 @@ link_macsec_add (NMPlatform *platform, struct nlattr *info; struct nlattr *data; + _LOGD ("adding macsec '%s' parent %u sci %llx", + name, + parent, + (unsigned long long) props->sci); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, 0, @@ -6253,7 +5489,7 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean +static int link_macvlan_add (NMPlatform *platform, const char *name, int parent, @@ -6264,6 +5500,12 @@ link_macvlan_add (NMPlatform *platform, struct nlattr *info; struct nlattr *data; + _LOGD ("adding %s '%s' parent %u mode %u", + props->tap ? "macvtap" : "macvlan", + name, + parent, + props->mode); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, 0, @@ -6296,7 +5538,7 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean +static int link_sit_add (NMPlatform *platform, const char *name, const NMPlatformLnkSit *props, @@ -6305,6 +5547,14 @@ link_sit_add (NMPlatform *platform, nm_auto_nlmsg struct nl_msg *nlmsg = NULL; struct nlattr *info; struct nlattr *data; + char buffer[INET_ADDRSTRLEN]; + + _LOGD (LOG_FMT_IP_TUNNEL, + "sit", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, @@ -6408,6 +5658,9 @@ link_vxlan_add (NMPlatform *platform, g_return_val_if_fail (props, FALSE); + _LOGD ("link: add vxlan '%s', parent %d, vxlan id %d", + name, props->parent_ifindex, props->id); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, NLM_F_CREATE | NLM_F_EXCL, 0, @@ -6465,41 +5718,6 @@ nla_put_failure: g_return_val_if_reached (FALSE); } -static gboolean -link_6lowpan_add (NMPlatform *platform, - const char *name, - int parent, - const NMPlatformLink **out_link) -{ - nm_auto_nlmsg struct nl_msg *nlmsg = NULL; - struct nlattr *info; - - nlmsg = _nl_msg_new_link (RTM_NEWLINK, - NLM_F_CREATE | NLM_F_EXCL, - 0, - name, - 0, - 0); - if (!nlmsg) - return FALSE; - - NLA_PUT_U32 (nlmsg, IFLA_LINK, parent); - - if (!(info = nla_nest_start (nlmsg, IFLA_LINKINFO))) - goto nla_put_failure; - - NLA_PUT_STRING (nlmsg, IFLA_INFO_KIND, "lowpan"); - - nla_nest_end (nlmsg, info); - - return do_add_link_with_lookup (platform, - NM_LINK_TYPE_6LOWPAN, - name, nlmsg, out_link); -nla_put_failure: - g_return_val_if_reached (FALSE); -} - - static void _vlan_change_vlan_qos_mapping_create (gboolean is_ingress_map, gboolean reset_all, @@ -6594,6 +5812,9 @@ link_vlan_change (NMPlatform *platform, guint new_n_egress_map = 0; gs_free NMVlanQosMapping *new_ingress_map = NULL; gs_free NMVlanQosMapping *new_egress_map = NULL; + char s_flags[64]; + char s_ingress[256]; + char s_egress[256]; obj_cache = nmp_cache_lookup_link (nm_platform_get_cache (platform), ifindex); if ( !obj_cache @@ -6624,6 +5845,26 @@ link_vlan_change (NMPlatform *platform, &new_egress_map, &new_n_egress_map); + _LOGD ("link: change %d: vlan:%s%s%s", + ifindex, + flags_mask + ? nm_sprintf_buf (s_flags, " flags 0x%x/0x%x", (unsigned) flags_set, (unsigned) flags_mask) + : "", + new_n_ingress_map + ? nm_platform_vlan_qos_mapping_to_string (" ingress-qos-map", + new_ingress_map, + new_n_ingress_map, + s_ingress, + sizeof (s_ingress)) + : "", + new_n_egress_map + ? nm_platform_vlan_qos_mapping_to_string (" egress-qos-map", + new_egress_map, + new_n_egress_map, + s_egress, + sizeof (s_egress)) + : ""); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -6650,6 +5891,8 @@ link_enslave (NMPlatform *platform, int master, int slave) nm_auto_nlmsg struct nl_msg *nlmsg = NULL; int ifindex = slave; + _LOGD ("link: change %d: enslave: master %d", slave, master); + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, @@ -6737,26 +5980,43 @@ infiniband_partition_delete (NMPlatform *platform, int parent, int p_key) /*****************************************************************************/ -static GObject * -get_ext_data (NMPlatform *platform, int ifindex) +static WifiData * +wifi_get_wifi_data (NMPlatform *platform, int ifindex) { - const NMPObject *obj; + NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform); + const NMPlatformLink *pllink; + WifiData *wifi_data; + + wifi_data = g_hash_table_lookup (priv->wifi_data, GINT_TO_POINTER (ifindex)); + pllink = nm_platform_link_get (platform, ifindex); + + if (!wifi_data) { + if (pllink) { + if (pllink->type == NM_LINK_TYPE_WIFI) + wifi_data = wifi_utils_init (ifindex, TRUE); + else if (pllink->type == NM_LINK_TYPE_OLPC_MESH) { + /* The kernel driver now uses nl80211, but we force use of WEXT because + * the cfg80211 interactions are not quite ready to support access to + * mesh control through nl80211 just yet. + */ +#if HAVE_WEXT + wifi_data = wifi_wext_init (ifindex, FALSE); +#endif + } - obj = nmp_cache_lookup_link (nm_platform_get_cache (platform), ifindex); - if (!obj) - return NULL; + if (wifi_data) + g_hash_table_insert (priv->wifi_data, GINT_TO_POINTER (ifindex), wifi_data); + } + } - return obj->_link.ext_data; + return wifi_data; } - -/*****************************************************************************/ - #define WIFI_GET_WIFI_DATA_NETNS(wifi_data, platform, ifindex, retval) \ nm_auto_pop_netns NMPNetns *netns = NULL; \ - NMWifiUtils *wifi_data; \ + WifiData *wifi_data; \ if (!nm_platform_netns_push (platform, &netns)) \ return retval; \ - wifi_data = NM_WIFI_UTILS (get_ext_data (platform, ifindex)); \ + wifi_data = wifi_get_wifi_data (platform, ifindex); \ if (!wifi_data) \ return retval; @@ -6765,7 +6025,7 @@ wifi_get_capabilities (NMPlatform *platform, int ifindex, NMDeviceWifiCapabiliti { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); if (caps) - *caps = nm_wifi_utils_get_caps (wifi_data); + *caps = wifi_utils_get_caps (wifi_data); return TRUE; } @@ -6773,70 +6033,63 @@ static gboolean wifi_get_bssid (NMPlatform *platform, int ifindex, guint8 *bssid) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_get_bssid (wifi_data, bssid); + return wifi_utils_get_bssid (wifi_data, bssid); } static guint32 wifi_get_frequency (NMPlatform *platform, int ifindex) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, 0); - return nm_wifi_utils_get_freq (wifi_data); + return wifi_utils_get_freq (wifi_data); } static gboolean wifi_get_quality (NMPlatform *platform, int ifindex) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_get_qual (wifi_data); + return wifi_utils_get_qual (wifi_data); } static guint32 wifi_get_rate (NMPlatform *platform, int ifindex) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_get_rate (wifi_data); + return wifi_utils_get_rate (wifi_data); } static NM80211Mode wifi_get_mode (NMPlatform *platform, int ifindex) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, NM_802_11_MODE_UNKNOWN); - return nm_wifi_utils_get_mode (wifi_data); + return wifi_utils_get_mode (wifi_data); } static void wifi_set_mode (NMPlatform *platform, int ifindex, NM80211Mode mode) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, ); - nm_wifi_utils_set_mode (wifi_data, mode); + wifi_utils_set_mode (wifi_data, mode); } static void wifi_set_powersave (NMPlatform *platform, int ifindex, guint32 powersave) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, ); - nm_wifi_utils_set_powersave (wifi_data, powersave); + wifi_utils_set_powersave (wifi_data, powersave); } static guint32 wifi_find_frequency (NMPlatform *platform, int ifindex, const guint32 *freqs) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, 0); - return nm_wifi_utils_find_freq (wifi_data, freqs); + return wifi_utils_find_freq (wifi_data, freqs); } static void wifi_indicate_addressing_running (NMPlatform *platform, int ifindex, gboolean running) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, ); - nm_wifi_utils_indicate_addressing_running (wifi_data, running); -} - -static NMSettingWirelessWakeOnWLan -wifi_get_wake_on_wlan (NMPlatform *platform, int ifindex) -{ - WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_get_wake_on_wlan (wifi_data); + wifi_utils_indicate_addressing_running (wifi_data, running); } static gboolean @@ -6844,7 +6097,7 @@ wifi_set_wake_on_wlan (NMPlatform *platform, int ifindex, NMSettingWirelessWakeOnWLan wowl) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_set_wake_on_wlan (wifi_data, wowl); + return wifi_utils_set_wake_on_wlan (wifi_data, wowl); } /*****************************************************************************/ @@ -6895,56 +6148,21 @@ static guint32 mesh_get_channel (NMPlatform *platform, int ifindex) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, 0); - return nm_wifi_utils_get_mesh_channel (wifi_data); + return wifi_utils_get_mesh_channel (wifi_data); } static gboolean mesh_set_channel (NMPlatform *platform, int ifindex, guint32 channel) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_set_mesh_channel (wifi_data, channel); + return wifi_utils_set_mesh_channel (wifi_data, channel); } static gboolean mesh_set_ssid (NMPlatform *platform, int ifindex, const guint8 *ssid, gsize len) { WIFI_GET_WIFI_DATA_NETNS (wifi_data, platform, ifindex, FALSE); - return nm_wifi_utils_set_mesh_ssid (wifi_data, ssid, len); -} - -/*****************************************************************************/ - -#define WPAN_GET_WPAN_DATA(wpan_data, platform, ifindex, retval) \ - NMWpanUtils *wpan_data = NM_WPAN_UTILS (get_ext_data (platform, ifindex)); \ - if (!wpan_data) \ - return retval; - -static guint16 -wpan_get_pan_id (NMPlatform *platform, int ifindex) -{ - WPAN_GET_WPAN_DATA (wpan_data, platform, ifindex, G_MAXINT16); - return nm_wpan_utils_get_pan_id (wpan_data); -} - -static gboolean -wpan_set_pan_id (NMPlatform *platform, int ifindex, guint16 pan_id) -{ - WPAN_GET_WPAN_DATA (wpan_data, platform, ifindex, FALSE); - return nm_wpan_utils_set_pan_id (wpan_data, pan_id); -} - -static guint16 -wpan_get_short_addr (NMPlatform *platform, int ifindex) -{ - WPAN_GET_WPAN_DATA (wpan_data, platform, ifindex, G_MAXINT16); - return nm_wpan_utils_get_short_addr (wpan_data); -} - -static gboolean -wpan_set_short_addr (NMPlatform *platform, int ifindex, guint16 short_addr) -{ - WPAN_GET_WPAN_DATA (wpan_data, platform, ifindex, FALSE); - return nm_wpan_utils_set_short_addr (wpan_data, short_addr); + return wifi_utils_set_mesh_ssid (wifi_data, ssid, len); } /*****************************************************************************/ @@ -6961,12 +6179,12 @@ link_get_wake_on_lan (NMPlatform *platform, int ifindex) if (type == NM_LINK_TYPE_ETHERNET) return nmp_utils_ethtool_get_wake_on_lan (ifindex); else if (type == NM_LINK_TYPE_WIFI) { - NMWifiUtils *wifi_data = NM_WIFI_UTILS (get_ext_data (platform, ifindex)); + WifiData *wifi_data = wifi_get_wifi_data (platform, ifindex); if (!wifi_data) return FALSE; - return nm_wifi_utils_get_wake_on_wlan (wifi_data) != NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE; + return wifi_utils_get_wowlan (wifi_data); } else return FALSE; } @@ -7780,14 +6998,6 @@ handle_udev_event (NMUdevClient *udev_client, /*****************************************************************************/ -void -nm_linux_platform_setup (void) -{ - nm_platform_setup (nm_linux_platform_new (FALSE, FALSE)); -} - -/*****************************************************************************/ - static void nm_linux_platform_init (NMLinuxPlatform *self) { @@ -7796,6 +7006,7 @@ nm_linux_platform_init (NMLinuxPlatform *self) priv->delayed_action.list_master_connected = g_ptr_array_new (); priv->delayed_action.list_refresh_link = g_ptr_array_new (); priv->delayed_action.list_wait_for_nl_response = g_array_new (FALSE, TRUE, sizeof (DelayedActionWaitForNlResponseData)); + priv->wifi_data = g_hash_table_new_full (nm_direct_hash, NULL, NULL, (GDestroyNotify) wifi_utils_unref); } static void @@ -7825,18 +7036,6 @@ constructed (GObject *_object) nmp_netns_get_current () == nmp_netns_get_initial () ? "/main" : "")), nm_platform_get_use_udev (platform) ? "use" : "no"); - - priv->genl = nl_socket_alloc (); - g_assert (priv->genl); - - nle = nl_connect (priv->genl, NETLINK_GENERIC); - if (nle) { - _LOGE ("unable to connect the generic netlink socket \"%s\" (%d)", - nl_geterror (nle), -nle); - nl_socket_free (priv->genl); - priv->genl = NULL; - } - priv->nlh = nl_socket_alloc (); g_assert (priv->nlh); @@ -7928,22 +7127,6 @@ constructed (GObject *_object) } } -NMPlatform * -nm_linux_platform_new (gboolean log_with_ptr, gboolean netns_support) -{ - gboolean use_udev = FALSE; - - if ( nmp_netns_is_initial () - && access ("/sys", W_OK) == 0) - use_udev = TRUE; - - return g_object_new (NM_TYPE_LINUX_PLATFORM, - NM_PLATFORM_LOG_WITH_PTR, log_with_ptr, - NM_PLATFORM_USE_UDEV, use_udev, - NM_PLATFORM_NETNS_SUPPORT, netns_support, - NULL); -} - static void dispose (GObject *object) { @@ -7971,12 +7154,12 @@ finalize (GObject *object) g_ptr_array_unref (priv->delayed_action.list_refresh_link); g_array_unref (priv->delayed_action.list_wait_for_nl_response); - nl_socket_free (priv->genl); - g_source_remove (priv->event_id); g_io_channel_unref (priv->event_channel); nl_socket_free (priv->nlh); + g_hash_table_unref (priv->wifi_data); + if (priv->sysctl_get_prev_values) { sysctl_clear_cache_list = g_slist_remove (sysctl_clear_cache_list, object); g_hash_table_destroy (priv->sysctl_get_prev_values); @@ -8022,8 +7205,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->link_get_permanent_address = link_get_permanent_address; platform_class->link_set_mtu = link_set_mtu; platform_class->link_set_name = link_set_name; - platform_class->link_set_sriov_params = link_set_sriov_params; - platform_class->link_set_sriov_vfs = link_set_sriov_vfs; + platform_class->link_set_sriov_num_vfs = link_set_sriov_num_vfs; platform_class->link_get_physical_port_id = link_get_physical_port_id; platform_class->link_get_dev_id = link_get_dev_id; @@ -8056,27 +7238,19 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->wifi_set_powersave = wifi_set_powersave; platform_class->wifi_find_frequency = wifi_find_frequency; platform_class->wifi_indicate_addressing_running = wifi_indicate_addressing_running; - platform_class->wifi_get_wake_on_wlan = wifi_get_wake_on_wlan; platform_class->wifi_set_wake_on_wlan = wifi_set_wake_on_wlan; platform_class->mesh_get_channel = mesh_get_channel; platform_class->mesh_set_channel = mesh_set_channel; platform_class->mesh_set_ssid = mesh_set_ssid; - platform_class->wpan_get_pan_id = wpan_get_pan_id; - platform_class->wpan_set_pan_id = wpan_set_pan_id; - platform_class->wpan_get_short_addr = wpan_get_short_addr; - platform_class->wpan_set_short_addr = wpan_set_short_addr; - platform_class->link_gre_add = link_gre_add; platform_class->link_ip6tnl_add = link_ip6tnl_add; - platform_class->link_ip6gre_add = link_ip6gre_add; platform_class->link_macsec_add = link_macsec_add; platform_class->link_macvlan_add = link_macvlan_add; platform_class->link_ipip_add = link_ipip_add; platform_class->link_sit_add = link_sit_add; platform_class->link_tun_add = link_tun_add; - platform_class->link_6lowpan_add = link_6lowpan_add; platform_class->object_delete = object_delete; platform_class->ip4_address_add = ip4_address_add; diff --git a/src/platform/nm-netlink.c b/src/platform/nm-netlink.c index 3e2ad911..4cb19780 100644 --- a/src/platform/nm-netlink.c +++ b/src/platform/nm-netlink.c @@ -52,6 +52,7 @@ struct nl_msg { struct ucred nm_creds; struct nlmsghdr * nm_nlh; size_t nm_size; + int nm_refcnt; }; struct nl_sock { @@ -83,18 +84,18 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_geterror, int, ) const char * -nl_geterror (int nlerr) +nl_geterror (int err) { const char *s; - nlerr = nl_errno (nlerr); + err = nl_errno (err); - if (nlerr >= _NLE_BASE) { - s = _geterror (nlerr); + if (err >= _NLE_BASE) { + s = _geterror (err); if (s) return s; } - return g_strerror (nlerr); + return g_strerror (err); } /*****************************************************************************/ @@ -251,13 +252,27 @@ nlmsg_reserve (struct nl_msg *n, size_t len, int pad) n->nm_nlh->nlmsg_len += tlen; if (tlen > len) - memset (buf + len, 0, tlen - len); + memset(buf + len, 0, tlen - len); return buf; } /*****************************************************************************/ +static int + get_default_page_size (void) +{ + static int val = 0; + int v; + + if (G_UNLIKELY (val == 0)) { + v = getpagesize (); + g_assert (v > 0); + val = v; + } + return val; +} + struct nlattr * nla_reserve (struct nl_msg *msg, int attrtype, int attrlen) { @@ -267,38 +282,22 @@ nla_reserve (struct nl_msg *msg, int attrtype, int attrlen) if (attrlen < 0) return NULL; - tlen = NLMSG_ALIGN (msg->nm_nlh->nlmsg_len) + nla_total_size (attrlen); + tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) + nla_total_size(attrlen); if (tlen > msg->nm_size) return NULL; - nla = (struct nlattr *) nlmsg_tail (msg->nm_nlh); + nla = (struct nlattr *) nlmsg_tail(msg->nm_nlh); nla->nla_type = attrtype; - nla->nla_len = nla_attr_size (attrlen); + nla->nla_len = nla_attr_size(attrlen); if (attrlen) - memset ((unsigned char *) nla + nla->nla_len, 0, nla_padlen (attrlen)); + memset((unsigned char *) nla + nla->nla_len, 0, nla_padlen(attrlen)); msg->nm_nlh->nlmsg_len = tlen; return nla; } -/*****************************************************************************/ - -static int -get_default_page_size (void) -{ - static int val = 0; - int v; - - if (G_UNLIKELY (val == 0)) { - v = getpagesize (); - g_assert (v > 0); - val = v; - } - return val; -} - struct nl_msg * nlmsg_alloc_size (size_t len) { @@ -309,6 +308,7 @@ nlmsg_alloc_size (size_t len) nm = g_slice_new0 (struct nl_msg); + nm->nm_refcnt = 1; nm->nm_protocol = -1; nm->nm_size = len; nm->nm_nlh = g_malloc0 (len); @@ -331,40 +331,48 @@ nlmsg_alloc (void) return nlmsg_alloc_size (get_default_page_size ()); } +/** + * Allocate a new netlink message with maximum payload size specified. + */ struct nl_msg * -nlmsg_alloc_convert (struct nlmsghdr *hdr) +nlmsg_alloc_inherit (struct nlmsghdr *hdr) { struct nl_msg *nm; - nm = nlmsg_alloc_size (NLMSG_ALIGN (hdr->nlmsg_len)); - memcpy (nm->nm_nlh, hdr, hdr->nlmsg_len); + nm = nlmsg_alloc (); + if (hdr) { + struct nlmsghdr *new = nm->nm_nlh; + + new->nlmsg_type = hdr->nlmsg_type; + new->nlmsg_flags = hdr->nlmsg_flags; + new->nlmsg_seq = hdr->nlmsg_seq; + new->nlmsg_pid = hdr->nlmsg_pid; + } + return nm; } struct nl_msg * -nlmsg_alloc_simple (int nlmsgtype, int flags) +nlmsg_alloc_convert (struct nlmsghdr *hdr) { struct nl_msg *nm; - struct nlmsghdr *new; - nm = nlmsg_alloc (); - new = nm->nm_nlh; - new->nlmsg_type = nlmsgtype; - new->nlmsg_flags = flags; + nm = nlmsg_alloc_size (NLMSG_ALIGN (hdr->nlmsg_len)); + memcpy(nm->nm_nlh, hdr, hdr->nlmsg_len); return nm; } -void nlmsg_free (struct nl_msg *msg) +struct nl_msg * +nlmsg_alloc_simple (int nlmsgtype, int flags) { - if (!msg) - return; + struct nlmsghdr nlh = { + .nlmsg_type = nlmsgtype, + .nlmsg_flags = flags, + }; - g_free (msg->nm_nlh); - g_slice_free (struct nl_msg, msg); + return nlmsg_alloc_inherit (&nlh); } -/*****************************************************************************/ - int nlmsg_append (struct nl_msg *n, void *data, size_t len, int pad) { @@ -374,21 +382,19 @@ nlmsg_append (struct nl_msg *n, void *data, size_t len, int pad) if (tmp == NULL) return -ENOMEM; - memcpy (tmp, data, len); + memcpy(tmp, data, len); return 0; } -/*****************************************************************************/ - int nlmsg_parse (struct nlmsghdr *nlh, int hdrlen, struct nlattr *tb[], int maxtype, const struct nla_policy *policy) { - if (!nlmsg_valid_hdr (nlh, hdrlen)) + if (!nlmsg_valid_hdr(nlh, hdrlen)) return -NLE_MSG_TOOSHORT; - return nla_parse (tb, maxtype, nlmsg_attrdata (nlh, hdrlen), - nlmsg_attrlen (nlh, hdrlen), policy); + return nla_parse (tb, maxtype, nlmsg_attrdata(nlh, hdrlen), + nlmsg_attrlen(nlh, hdrlen), policy); } struct nlmsghdr * @@ -406,8 +412,8 @@ nlmsg_put (struct nl_msg *n, uint32_t pid, uint32_t seq, nlh->nlmsg_pid = pid; nlh->nlmsg_seq = seq; - if ( payload > 0 - && nlmsg_reserve (n, payload, NLMSG_ALIGNTO) == NULL) + if (payload > 0 && + nlmsg_reserve(n, payload, NLMSG_ALIGNTO) == NULL) return NULL; return nlh; @@ -418,8 +424,8 @@ nla_get_u64 (const struct nlattr *nla) { uint64_t tmp = 0; - if (nla && nla_len (nla) >= sizeof (tmp)) - memcpy (&tmp, nla_data (nla), sizeof (tmp)); + if (nla && nla_len(nla) >= sizeof (tmp)) + memcpy(&tmp, nla_data(nla), sizeof (tmp)); return tmp; } @@ -427,8 +433,8 @@ nla_get_u64 (const struct nlattr *nla) size_t nla_strlcpy (char *dst, const struct nlattr *nla, size_t dstsize) { - size_t srclen = nla_len (nla); - const char *src = nla_data (nla); + size_t srclen = nla_len(nla); + const char *src = nla_data(nla); if (srclen > 0 && src[srclen - 1] == '\0') srclen--; @@ -436,8 +442,8 @@ nla_strlcpy (char *dst, const struct nlattr *nla, size_t dstsize) if (dstsize > 0) { size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen; - memset (dst, 0, dstsize); - memcpy (dst, src, len); + memset(dst, 0, dstsize); + memcpy(dst, src, len); } return srclen; @@ -452,7 +458,7 @@ nla_memcpy (void *dest, const struct nlattr *src, int count) return 0; minlen = NM_MIN (count, (int) nla_len (src)); - memcpy (dest, nla_data (src), minlen); + memcpy(dest, nla_data(src), minlen); return minlen; } @@ -462,7 +468,7 @@ nla_put (struct nl_msg *msg, int attrtype, int datalen, const void *data) { struct nlattr *nla; - nla = nla_reserve (msg, attrtype, datalen); + nla = nla_reserve(msg, attrtype, datalen); if (!nla) { if (datalen < 0) g_return_val_if_reached (-NLE_BUG); @@ -471,7 +477,7 @@ nla_put (struct nl_msg *msg, int attrtype, int datalen, const void *data) } if (datalen > 0) - memcpy (nla_data (nla), data, datalen); + memcpy (nla_data(nla), data, datalen); return 0; } @@ -495,21 +501,21 @@ nla_nest_cancel (struct nl_msg *msg, const struct nlattr *attr) { ssize_t len; - len = (char *) nlmsg_tail (msg->nm_nlh) - (char *) attr; + len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) attr; if (len < 0) g_return_if_reached (); else if (len > 0) { msg->nm_nlh->nlmsg_len -= len; - memset (nlmsg_tail (msg->nm_nlh), 0, len); + memset(nlmsg_tail(msg->nm_nlh), 0, len); } } struct nlattr * nla_nest_start (struct nl_msg *msg, int attrtype) { - struct nlattr *start = (struct nlattr *) nlmsg_tail (msg->nm_nlh); + struct nlattr *start = (struct nlattr *) nlmsg_tail(msg->nm_nlh); - if (nla_put (msg, attrtype, 0, NULL) < 0) + if (nla_put(msg, attrtype, 0, NULL) < 0) return NULL; return start; @@ -520,7 +526,7 @@ _nest_end (struct nl_msg *msg, struct nlattr *start, int keep_empty) { size_t pad, len; - len = (char *) nlmsg_tail (msg->nm_nlh) - (char *) start; + len = (char *) nlmsg_tail(msg->nm_nlh) - (char *) start; if ( len > USHRT_MAX || (!keep_empty && len == NLA_HDRLEN)) { @@ -528,7 +534,7 @@ _nest_end (struct nl_msg *msg, struct nlattr *start, int keep_empty) * Max nlattr size exceeded or empty nested attribute, trim the * attribute header again */ - nla_nest_cancel (msg, start); + nla_nest_cancel(msg, start); /* Return error only if nlattr size was exceeded */ return (len == NLA_HDRLEN) ? 0 : -NLE_ATTRSIZE; @@ -536,7 +542,7 @@ _nest_end (struct nl_msg *msg, struct nlattr *start, int keep_empty) start->nla_len = len; - pad = NLMSG_ALIGN (msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len; + pad = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len; if (pad > 0) { /* * Data inside attribute does not end at a alignment boundry. @@ -544,7 +550,7 @@ _nest_end (struct nl_msg *msg, struct nlattr *start, int keep_empty) * the message. nlmsg_reserve() may never fail in this situation, * the allocate message buffer must be a multiple of NLMSG_ALIGNTO. */ - if (!nlmsg_reserve (msg, pad, 0)) + if (!nlmsg_reserve(msg, pad, 0)) g_return_val_if_reached (-NLE_BUG); } @@ -572,7 +578,7 @@ validate_nla (const struct nlattr *nla, int maxtype, { const struct nla_policy *pt; unsigned int minlen = 0; - int type = nla_type (nla); + int type = nla_type(nla); if (type < 0 || type > maxtype) return 0; @@ -587,15 +593,15 @@ validate_nla (const struct nlattr *nla, int maxtype, else if (pt->type != NLA_UNSPEC) minlen = nla_attr_minlen[pt->type]; - if (nla_len (nla) < minlen) + if (nla_len(nla) < minlen) return -NLE_UNSPEC; - if (pt->maxlen && nla_len (nla) > pt->maxlen) + if (pt->maxlen && nla_len(nla) > pt->maxlen) return -NLE_UNSPEC; if (pt->type == NLA_STRING) { - const char *data = nla_data (nla); - if (data[nla_len (nla) - 1] != '\0') + const char *data = nla_data(nla); + if (data[nla_len(nla) - 1] != '\0') return -NLE_UNSPEC; } @@ -607,32 +613,48 @@ nla_parse (struct nlattr *tb[], int maxtype, struct nlattr *head, int len, const struct nla_policy *policy) { struct nlattr *nla; - int rem, nlerr; + int rem, err; - memset (tb, 0, sizeof (struct nlattr *) * (maxtype + 1)); + memset(tb, 0, sizeof (struct nlattr *) * (maxtype + 1)); - nla_for_each_attr (nla, head, len, rem) { - int type = nla_type (nla); + nla_for_each_attr(nla, head, len, rem) { + int type = nla_type(nla); if (type > maxtype) continue; if (policy) { - nlerr = validate_nla (nla, maxtype, policy); - if (nlerr < 0) + err = validate_nla(nla, maxtype, policy); + if (err < 0) goto errout; } tb[type] = nla; } - nlerr = 0; + err = 0; errout: - return nlerr; + return err; } /*****************************************************************************/ +void nlmsg_free (struct nl_msg *msg) +{ + if (!msg) + return; + + if (msg->nm_refcnt < 1) + g_return_if_reached (); + + msg->nm_refcnt--; + + if (msg->nm_refcnt <= 0) { + g_free (msg->nm_nlh); + g_slice_free (struct nl_msg, msg); + } +} + int nlmsg_get_proto (struct nl_msg *msg) { @@ -791,7 +813,7 @@ int genl_ctrl_resolve (struct nl_sock *sk, const char *name) { nm_auto_nlmsg struct nl_msg *msg = NULL; - int nlerr; + int result = -ENOMEM; gint32 response_data = -1; const struct nl_cb cb = { .valid_cb = _genl_parse_getfamily, @@ -802,29 +824,31 @@ genl_ctrl_resolve (struct nl_sock *sk, const char *name) if (!genlmsg_put (msg, NL_AUTO_PORT, NL_AUTO_SEQ, GENL_ID_CTRL, 0, 0, CTRL_CMD_GETFAMILY, 1)) - return -ENOMEM; + goto out; - nlerr = nla_put_string (msg, CTRL_ATTR_FAMILY_NAME, name); - if (nlerr < 0) - return nlerr; + if (nla_put_string (msg, CTRL_ATTR_FAMILY_NAME, name) < 0) + goto out; - nlerr = nl_send_auto (sk, msg); - if (nlerr < 0) - return nlerr; + result = nl_send_auto (sk, msg); + if (result < 0) + goto out; - nlerr = nl_recvmsgs (sk, &cb); - if (nlerr < 0) - return nlerr; + result = nl_recvmsgs (sk, &cb); + if (result < 0) + goto out; /* If search was successful, request may be ACKed after data */ - nlerr = nl_wait_for_ack (sk, NULL); - if (nlerr < 0) - return nlerr; + result = nl_wait_for_ack (sk, NULL); + if (result < 0) + goto out; - if (response_data < 0) - return -NLE_UNSPEC; + if (response_data > 0) + result = response_data; + else + result = -ENOENT; - return response_data; +out: + return result; } /*****************************************************************************/ @@ -839,7 +863,7 @@ nl_socket_alloc (void) sk->s_fd = -1; sk->s_local.nl_family = AF_NETLINK; sk->s_peer.nl_family = AF_NETLINK; - sk->s_seq_expect = sk->s_seq_next = time (NULL); + sk->s_seq_expect = sk->s_seq_next = time(NULL); return sk; } @@ -914,7 +938,7 @@ nl_socket_set_nonblocking (const struct nl_sock *sk) if (sk->s_fd == -1) return -NLE_BAD_SOCK; - if (fcntl (sk->s_fd, F_SETFL, O_NONBLOCK) < 0) + if (fcntl(sk->s_fd, F_SETFL, O_NONBLOCK) < 0) return -nl_syserr2nlerr (errno); return 0; @@ -958,27 +982,25 @@ nl_socket_add_memberships (struct nl_sock *sk, int group, ...) if (sk->s_fd == -1) return -NLE_BAD_SOCK; - va_start (ap, group); + va_start(ap, group); while (group != 0) { if (group < 0) { - va_end (ap); + va_end(ap); g_return_val_if_reached (-NLE_BUG); } err = setsockopt (sk->s_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof (group)); if (err < 0) { - int errsv = errno; - - va_end (ap); - return -nl_syserr2nlerr (errsv); + va_end(ap); + return -nl_syserr2nlerr (errno); } - group = va_arg (ap, int); + group = va_arg(ap, int); } - va_end (ap); + va_end(ap); return 0; } @@ -1008,7 +1030,7 @@ void nl_socket_disable_msg_peek (struct nl_sock *sk) int nl_connect (struct nl_sock *sk, int protocol) { - int err, nlerr; + int err; socklen_t addrlen; struct sockaddr_nl local = { 0 }; @@ -1017,12 +1039,12 @@ nl_connect (struct nl_sock *sk, int protocol) sk->s_fd = socket (AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, protocol); if (sk->s_fd < 0) { - nlerr = -nl_syserr2nlerr (errno); + err = -nl_syserr2nlerr (errno); goto errout; } - nlerr = nl_socket_set_buffer_size (sk, 0, 0); - if (nlerr < 0) + err = nl_socket_set_buffer_size(sk, 0, 0); + if (err < 0) goto errout; nm_assert (sk->s_local.nl_pid == 0); @@ -1030,7 +1052,7 @@ nl_connect (struct nl_sock *sk, int protocol) err = bind (sk->s_fd, (struct sockaddr*) &sk->s_local, sizeof (sk->s_local)); if (err != 0) { - nlerr = -nl_syserr2nlerr (errno); + err = -nl_syserr2nlerr (errno); goto errout; } @@ -1038,17 +1060,17 @@ nl_connect (struct nl_sock *sk, int protocol) err = getsockname (sk->s_fd, (struct sockaddr *) &local, &addrlen); if (err < 0) { - nlerr = -nl_syserr2nlerr (errno); + err = -nl_syserr2nlerr (errno); goto errout; } if (addrlen != sizeof (local)) { - nlerr = -NLE_UNSPEC; + err = -NLE_UNSPEC; goto errout; } if (local.nl_family != AF_NETLINK) { - nlerr = -NLE_UNSPEC; + err = -NLE_UNSPEC; goto errout; } @@ -1059,10 +1081,10 @@ nl_connect (struct nl_sock *sk, int protocol) errout: if (sk->s_fd != -1) { - close (sk->s_fd); + close(sk->s_fd); sk->s_fd = -1; } - return nlerr; + return err; } /*****************************************************************************/ @@ -1078,7 +1100,7 @@ _cb_init (struct nl_cb *dst, const struct nl_cb *src) memset (dst, 0, sizeof (*dst)); } -static int ack_wait_handler (struct nl_msg *msg, void *arg) +static int ack_wait_handler(struct nl_msg *msg, void *arg) { return NL_STOP; } @@ -1099,22 +1121,16 @@ do { \ const struct nl_cb *_cb = (cb); \ \ if (_cb->type##_cb) { \ - /* the returned value here must be either a negative - * netlink error number, or one of NL_SKIP, NL_STOP, NL_OK. */ \ - nlerr = _cb->type##_cb ((msg), _cb->type##_arg); \ - switch (nlerr) { \ + err = _cb->type##_cb ((msg), _cb->type##_arg); \ + switch (err) { \ case NL_OK: \ - nlerr = 0; \ + err = 0; \ break; \ case NL_SKIP: \ goto skip; \ case NL_STOP: \ goto stop; \ default: \ - if (nlerr >= 0) { \ - nm_assert_not_reached (); \ - nlerr = -NLE_BUG; \ - } \ goto out; \ } \ } \ @@ -1123,7 +1139,7 @@ do { \ int nl_recvmsgs (struct nl_sock *sk, const struct nl_cb *cb) { - int n, nlerr = 0, multipart = 0, interrupted = 0, nrecv = 0; + int n, err = 0, multipart = 0, interrupted = 0, nrecv = 0; gs_free unsigned char *buf = NULL; struct nlmsghdr *hdr; struct sockaddr_nl nla = { 0 }; @@ -1148,9 +1164,9 @@ continue_reading: nrecv++; /* Only do sequence checking if auto-ack mode is enabled */ - if (! (sk->s_flags & NL_NO_AUTO_ACK)) { + if (!(sk->s_flags & NL_NO_AUTO_ACK)) { if (hdr->nlmsg_seq != sk->s_seq_expect) { - nlerr = -NLE_SEQ_MISMATCH; + err = -NLE_SEQ_MISMATCH; goto out; } } @@ -1182,7 +1198,7 @@ continue_reading: * this action by skipping this packet. */ if (hdr->nlmsg_type == NLMSG_DONE) { multipart = 0; - NL_CB_CALL (cb, finish, msg); + NL_CB_CALL(cb, finish, msg); } /* Message to be ignored, the default action is to @@ -1196,53 +1212,50 @@ continue_reading: * quit parsing. The user may overrule this action by retuning * NL_SKIP or NL_PROCEED (dangerous) */ else if (hdr->nlmsg_type == NLMSG_OVERRUN) { - nlerr = -NLE_MSG_OVERFLOW; + err = -NLE_MSG_OVERFLOW; goto out; } /* Message carries a nlmsgerr */ else if (hdr->nlmsg_type == NLMSG_ERROR) { - struct nlmsgerr *e = nlmsg_data (hdr); + struct nlmsgerr *e = nlmsg_data(hdr); - if (hdr->nlmsg_len < nlmsg_size (sizeof (*e))) { + if (hdr->nlmsg_len < nlmsg_size(sizeof (*e))) { /* Truncated error message, the default action * is to stop parsing. The user may overrule * this action by returning NL_SKIP or * NL_PROCEED (dangerous) */ - nlerr = -NLE_MSG_TRUNC; + err = -NLE_MSG_TRUNC; goto out; } if (e->error) { /* Error message reported back from kernel. */ if (cb->err_cb) { - /* the returned value here must be either a negative - * netlink error number, or one of NL_SKIP, NL_STOP, NL_OK. */ - nlerr = cb->err_cb (&nla, e, - cb->err_arg); - if (nlerr < 0) + err = cb->err_cb (&nla, e, + cb->err_arg); + if (err < 0) goto out; - else if (nlerr == NL_SKIP) + else if (err == NL_SKIP) goto skip; - else if (nlerr == NL_STOP) { - nlerr = -nl_syserr2nlerr (e->error); + else if (err == NL_STOP) { + err = -e->error; goto out; } - nm_assert (nlerr == NL_OK); } else { - nlerr = -nl_syserr2nlerr (e->error); + err = -e->error; goto out; } } else - NL_CB_CALL (cb, ack, msg); + NL_CB_CALL(cb, ack, msg); } else { /* Valid message (not checking for MULTIPART bit to * get along with broken kernels. NL_SKIP has no * effect on this. */ - NL_CB_CALL (cb, valid, msg); + NL_CB_CALL(cb, valid, msg); } skip: - nlerr = 0; - hdr = nlmsg_next (hdr, &n); + err = 0; + hdr = nlmsg_next(hdr, &n); } if (multipart) { @@ -1254,14 +1267,13 @@ skip: } stop: - nlerr = 0; + err = 0; out: if (interrupted) - nlerr = -NLE_DUMP_INTR; + err = -NLE_DUMP_INTR; - nm_assert (nlerr <= 0); - return nlerr ?: nrecv; + return err ?: nrecv; } int @@ -1274,7 +1286,7 @@ nl_sendmsg (struct nl_sock *sk, struct nl_msg *msg, struct msghdr *hdr) nlmsg_set_src (msg, &sk->s_local); - ret = sendmsg (sk->s_fd, hdr, 0); + ret = sendmsg(sk->s_fd, hdr, 0); if (ret < 0) return -nl_syserr2nlerr (errno); @@ -1292,31 +1304,31 @@ nl_send_iovec (struct nl_sock *sk, struct nl_msg *msg, struct iovec *iov, unsign .msg_iov = iov, .msg_iovlen = iovlen, }; - char buf[CMSG_SPACE (sizeof (struct ucred))]; + char buf[CMSG_SPACE(sizeof (struct ucred))]; /* Overwrite destination if specified in the message itself, defaults * to the peer address of the socket. */ - dst = nlmsg_get_dst (msg); + dst = nlmsg_get_dst(msg); if (dst->nl_family == AF_NETLINK) hdr.msg_name = dst; /* Add credentials if present. */ - creds = nlmsg_get_creds (msg); + creds = nlmsg_get_creds(msg); if (creds != NULL) { struct cmsghdr *cmsg; hdr.msg_control = buf; hdr.msg_controllen = sizeof (buf); - cmsg = CMSG_FIRSTHDR (&hdr); + cmsg = CMSG_FIRSTHDR(&hdr); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_CREDENTIALS; - cmsg->cmsg_len = CMSG_LEN (sizeof (struct ucred)); - memcpy (CMSG_DATA (cmsg), creds, sizeof (struct ucred)); + cmsg->cmsg_len = CMSG_LEN(sizeof (struct ucred)); + memcpy(CMSG_DATA(cmsg), creds, sizeof (struct ucred)); } - return nl_sendmsg (sk, msg, &hdr); + return nl_sendmsg(sk, msg, &hdr); } void @@ -1324,9 +1336,9 @@ nl_complete_msg (struct nl_sock *sk, struct nl_msg *msg) { struct nlmsghdr *nlh; - nlh = nlmsg_hdr (msg); + nlh = nlmsg_hdr(msg); if (nlh->nlmsg_pid == NL_AUTO_PORT) - nlh->nlmsg_pid = nl_socket_get_local_port (sk); + nlh->nlmsg_pid = nl_socket_get_local_port(sk); if (nlh->nlmsg_seq == NL_AUTO_SEQ) nlh->nlmsg_seq = sk->s_seq_next++; @@ -1344,18 +1356,18 @@ int nl_send (struct nl_sock *sk, struct nl_msg *msg) { struct iovec iov = { - .iov_base = (void *) nlmsg_hdr (msg), - .iov_len = nlmsg_hdr (msg)->nlmsg_len, + .iov_base = (void *) nlmsg_hdr(msg), + .iov_len = nlmsg_hdr(msg)->nlmsg_len, }; - return nl_send_iovec (sk, msg, &iov, 1); + return nl_send_iovec(sk, msg, &iov, 1); } -int nl_send_auto (struct nl_sock *sk, struct nl_msg *msg) +int nl_send_auto(struct nl_sock *sk, struct nl_msg *msg) { - nl_complete_msg (sk, msg); + nl_complete_msg(sk, msg); - return nl_send (sk, msg); + return nl_send(sk, msg); } int @@ -1385,9 +1397,9 @@ nl_recv (struct nl_sock *sk, struct sockaddr_nl *nla, flags |= MSG_PEEK | MSG_TRUNC; if (page_size == 0) - page_size = getpagesize () * 4; + page_size = getpagesize() * 4; - iov.iov_len = sk->s_bufsize ?: page_size; + iov.iov_len = sk->s_bufsize ? : page_size; iov.iov_base = g_malloc (iov.iov_len); if ( creds @@ -1397,7 +1409,7 @@ nl_recv (struct nl_sock *sk, struct sockaddr_nl *nla, } retry: - n = recvmsg (sk->s_fd, &msg, flags); + n = recvmsg(sk->s_fd, &msg, flags); if (!n) { retval = 0; goto abort; @@ -1453,12 +1465,12 @@ retry: if (creds && (sk->s_flags & NL_SOCK_PASSCRED)) { struct cmsghdr *cmsg; - for (cmsg = CMSG_FIRSTHDR (&msg); cmsg; cmsg = CMSG_NXTHDR (&msg, cmsg)) { + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET) continue; if (cmsg->cmsg_type != SCM_CREDENTIALS) continue; - tmpcreds = nm_memdup (CMSG_DATA (cmsg), sizeof (*tmpcreds)); + tmpcreds = g_memdup (CMSG_DATA(cmsg), sizeof (*tmpcreds)); break; } } diff --git a/src/platform/nm-netlink.h b/src/platform/nm-netlink.h index 1fccddb9..185269ba 100644 --- a/src/platform/nm-netlink.h +++ b/src/platform/nm-netlink.h @@ -52,48 +52,32 @@ #endif static inline int -nl_errno (int nlerr) +nl_errno (int err) { - /* Normalizes an netlink error to be positive. Various API returns negative - * error codes, and this function converts the negative value to its - * positive. + /* the error codes from our netlink implementation are plain errno + * extended with our own error in a particular range starting from + * _NLE_BASE. * - * It's very similar to nm_errno(), but not exactly. The difference is that - * nm_errno() is for plain errno, while nl_errno() is for netlink error numbers. - * Yes, netlink error number are ~almost~ the same as errno, except that a particular - * range (_NLE_BASE, _NLE_BASE_END) is reserved. The difference between the two - * functions is only how G_MININT is mapped. - * - * See also nl_syserr2nlerr() below. */ - return nlerr >= 0 - ? nlerr - : ((nlerr == G_MININT) ? NLE_BUG : -nlerr); + * However, often we encode errors as negative values. This function + * normalizes the error and returns its positive value. */ + return err >= 0 + ? err + : ((err == G_MININT) ? NLE_BUG : -errno); } static inline int -nl_syserr2nlerr (int errsv) +nl_syserr2nlerr (int err) { - /* this maps a native errno to a (always non-negative) netlink error number. - * - * Note that netlink error numbers are embedded into the range of regular - * errno. The only difference is, that netlink error numbers reserve a - * range (_NLE_BASE, _NLE_BASE_END) for their own purpose. - * - * That means, converting an errno to netlink error number means in - * most cases just returning itself (negative values are normalized - * to be positive). Only values G_MININT and [_NLE_BASE, _NLE_BASE_END] - * are coerced to the special value NLE_NATIVE_ERRNO, as they cannot - * otherwise be represented in netlink error number domain. */ - if (errsv == G_MININT) + if (err == G_MININT) return NLE_NATIVE_ERRNO; - if (errsv < 0) - errsv = -errsv; - return (errsv >= _NLE_BASE && errsv < _NLE_BASE_END) + if (err < 0) + err = -err; + return (err >= _NLE_BASE && err < _NLE_BASE_END) ? NLE_NATIVE_ERRNO - : errsv; + : err; } -const char *nl_geterror (int nlerr); +const char *nl_geterror (int err); /*****************************************************************************/ @@ -193,12 +177,6 @@ nla_get_u8 (const struct nlattr *nla) } static inline uint8_t -nla_get_s8 (const struct nlattr *nla) -{ - return *(const int8_t *) nla_data (nla); -} - -static inline uint8_t nla_get_u8_cond (/*const*/ struct nlattr *const*tb, int attr, uint8_t default_val) { nm_assert (tb); @@ -219,12 +197,6 @@ nla_get_u32(const struct nlattr *nla) return *(const uint32_t *) nla_data (nla); } -static inline int32_t -nla_get_s32(const struct nlattr *nla) -{ - return *(const int32_t *) nla_data (nla); -} - uint64_t nla_get_u64 (const struct nlattr *nla); static inline char * @@ -260,18 +232,12 @@ nla_put_string (struct nl_msg *msg, int attrtype, const char *str) #define NLA_PUT_U8(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint8_t, attrtype, value) -#define NLA_PUT_S8(msg, attrtype, value) \ - NLA_PUT_TYPE(msg, int8_t, attrtype, value) - #define NLA_PUT_U16(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint16_t, attrtype, value) #define NLA_PUT_U32(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint32_t, attrtype, value) -#define NLA_PUT_S32(msg, attrtype, value) \ - NLA_PUT_TYPE(msg, int32_t, attrtype, value) - #define NLA_PUT_U64(msg, attrtype, value) \ NLA_PUT_TYPE(msg, uint64_t, attrtype, value) @@ -330,6 +296,8 @@ struct nl_msg *nlmsg_alloc (void); struct nl_msg *nlmsg_alloc_size (size_t max); +struct nl_msg *nlmsg_alloc_inherit (struct nlmsghdr *hdr); + struct nl_msg *nlmsg_alloc_convert (struct nlmsghdr *hdr); struct nl_msg *nlmsg_alloc_simple (int nlmsgtype, int flags); diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 216b1547..0d224443 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -36,15 +36,12 @@ #include "nm-utils.h" #include "nm-setting-wired.h" -#include "nm-ethtool-utils.h" #include "nm-core-utils.h" -#define ONOFF(bool_val) ((bool_val) ? "on" : "off") - -/****************************************************************************** +/****************************************************************** * utils - *****************************************************************************/ + ******************************************************************/ extern char *if_indextoname (unsigned __ifindex, char *__ifname); unsigned if_nametoindex (const char *__ifname); @@ -66,45 +63,9 @@ nmp_utils_if_nametoindex (const char *ifname) return if_nametoindex (ifname); } -/*****************************************************************************/ - -typedef struct { - int fd; - int ifindex; - char ifname[IFNAMSIZ]; -} SocketHandle; - -static int -socket_handle_init (SocketHandle *shandle, int ifindex) -{ - if (!nmp_utils_if_indextoname (ifindex, shandle->ifname)) { - shandle->ifindex = 0; - return -ENODEV; - } - - shandle->fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - if (shandle->fd < 0) { - shandle->ifindex = 0; - return -errno; - } - - shandle->ifindex = ifindex; - return 0; -} - -static void -socket_handle_destroy (SocketHandle *shandle) -{ - if (shandle->ifindex) { - shandle->ifindex = 0; - nm_close (shandle->fd); - } -} -#define nm_auto_socket_handle nm_auto(socket_handle_destroy) - -/****************************************************************************** +/****************************************************************** * ethtool - *****************************************************************************/ + ******************************************************************/ NM_UTILS_ENUM2STR_DEFINE_STATIC (_ethtool_cmd_to_string, guint32, NM_UTILS_ENUM2STR (ETHTOOL_GDRVINFO, "ETHTOOL_GDRVINFO"), @@ -116,7 +77,6 @@ NM_UTILS_ENUM2STR_DEFINE_STATIC (_ethtool_cmd_to_string, guint32, NM_UTILS_ENUM2STR (ETHTOOL_GSTATS, "ETHTOOL_GSTATS"), NM_UTILS_ENUM2STR (ETHTOOL_GSTRINGS, "ETHTOOL_GSTRINGS"), NM_UTILS_ENUM2STR (ETHTOOL_GWOL, "ETHTOOL_GWOL"), - NM_UTILS_ENUM2STR (ETHTOOL_SFEATURES, "ETHTOOL_SFEATURES"), NM_UTILS_ENUM2STR (ETHTOOL_SSET, "ETHTOOL_SSET"), NM_UTILS_ENUM2STR (ETHTOOL_SWOL, "ETHTOOL_SWOL"), ); @@ -127,8 +87,6 @@ _ethtool_data_to_string (gconstpointer edata, char *buf, gsize len) return _ethtool_cmd_to_string (*((guint32 *) edata), buf, len); } -/*****************************************************************************/ - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) #define ethtool_cmd_speed(pedata) ((pedata)->speed) @@ -136,553 +94,117 @@ _ethtool_data_to_string (gconstpointer edata, char *buf, gsize len) G_STMT_START { (pedata)->speed = (guint16) (speed); } G_STMT_END #endif -static int -ethtool_call_handle (SocketHandle *shandle, gpointer edata) +static gboolean +ethtool_get (int ifindex, gpointer edata) { - struct ifreq ifr = { - .ifr_data = edata, - }; + char ifname[IFNAMSIZ]; char sbuf[50]; - int errsv; - - nm_assert (shandle); - nm_assert (shandle->ifindex); - nm_assert (shandle->ifname[0]); - nm_assert (strlen (shandle->ifname) < IFNAMSIZ); - nm_assert (edata); - - memcpy (ifr.ifr_name, shandle->ifname, IFNAMSIZ); - if (ioctl (shandle->fd, SIOCETHTOOL, &ifr) < 0) { - errsv = errno; - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: failed: %s", - shandle->ifindex, - _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), - shandle->ifname, - strerror (errsv)); - return -errsv; - } - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: success", - shandle->ifindex, - _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), - shandle->ifname); - return 0; -} + nm_assert (ifindex > 0); -static int -ethtool_call_ifindex (int ifindex, gpointer edata) -{ - nm_auto_socket_handle SocketHandle shandle = { }; - int r; - char sbuf[50]; - - nm_assert (edata); + /* ethtool ioctl API uses the ifname to refer to an interface. That is racy + * as interfaces can be renamed *sigh*. + * + * Note that we anyway have to verify whether the interface exists, before + * calling ioctl for a non-existing ifname. This is to prevent autoloading + * of kernel modules *sigh*. + * Thus, as we anyway verify the existence of ifname before doing the call, + * go one step further and lookup the ifname everytime anew. + * + * This does not solve the renaming race, but it minimizes the time for + * the race to happen as much as possible. */ - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", + if (!nmp_utils_if_indextoname (ifindex, ifname)) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: request fails resolving ifindex: %s", ifindex, _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), - g_strerror (-r)); - return r; - } - - return ethtool_call_handle (&shandle, edata); -} - -/*****************************************************************************/ - -static struct ethtool_gstrings * -ethtool_get_stringset (SocketHandle *shandle, int stringset_id) -{ - struct { - struct ethtool_sset_info info; - guint32 sentinel; - } sset_info = { }; - gs_free struct ethtool_gstrings *gstrings = NULL; - guint32 i, len; - - sset_info.info.cmd = ETHTOOL_GSSET_INFO; - sset_info.info.reserved = 0; - sset_info.info.sset_mask = (1ULL << stringset_id); - - if (ethtool_call_handle (shandle, &sset_info) < 0) - return NULL; - if (!sset_info.info.sset_mask) - return NULL; - - len = sset_info.info.data[0]; - - gstrings = g_malloc0 (sizeof (*gstrings) + (len * ETH_GSTRING_LEN)); - gstrings->cmd = ETHTOOL_GSTRINGS; - gstrings->string_set = stringset_id; - gstrings->len = len; - if (gstrings->len > 0) { - if (ethtool_call_handle (shandle, gstrings) < 0) - return NULL; - for (i = 0; i < gstrings->len; i++) { - /* ensure NUL terminated */ - gstrings->data[i * ETH_GSTRING_LEN + (ETH_GSTRING_LEN - 1)] = '\0'; - } - } - - return g_steal_pointer (&gstrings); -} - -static int -ethtool_gstrings_find (const struct ethtool_gstrings *gstrings, const char *needle) -{ - guint32 i; - - /* ethtool_get_stringset() always ensures NUL terminated strings at ETH_GSTRING_LEN. - * that means, we cannot possibly request longer names. */ - nm_assert (needle && strlen (needle) < ETH_GSTRING_LEN); - - for (i = 0; i < gstrings->len; i++) { - if (nm_streq ((char *) &gstrings->data[i * ETH_GSTRING_LEN], needle)) - return i; - } - return -1; -} - -static int -ethtool_get_stringset_index (SocketHandle *shandle, int stringset_id, const char *needle) -{ - gs_free struct ethtool_gstrings *gstrings = NULL; - - /* ethtool_get_stringset() always ensures NUL terminated strings at ETH_GSTRING_LEN. - * that means, we cannot possibly request longer names. */ - nm_assert (needle && strlen (needle) < ETH_GSTRING_LEN); - - gstrings = ethtool_get_stringset (shandle, stringset_id); - if (gstrings) - return ethtool_gstrings_find (gstrings, needle); - return -1; -} - -/*****************************************************************************/ - -static const NMEthtoolFeatureInfo _ethtool_feature_infos[_NM_ETHTOOL_ID_FEATURE_NUM] = { -#define ETHT_FEAT(eid, ...) \ - { \ - .ethtool_id = eid, \ - .n_kernel_names = NM_NARG (__VA_ARGS__), \ - .kernel_names = ((const char *const[]) { __VA_ARGS__ }), \ - } - - /* the order does only matter for one thing: if it happens that more than one NMEthtoolID - * reference the same kernel-name, then the one that is mentioned *later* will win in - * case these NMEthtoolIDs are set. That mostly only makes sense for ethtool-ids which - * refer to multiple features ("feature-tso"), while also having more specific ids - * ("feature-tx-tcp-segmentation"). */ - - /* names from ethtool utility, which are aliases for multiple features. */ - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_SG, "tx-scatter-gather", - "tx-scatter-gather-fraglist"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TSO, "tx-tcp-segmentation", - "tx-tcp-ecn-segmentation", - "tx-tcp-mangleid-segmentation", - "tx-tcp6-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX, "tx-checksum-ipv4", - "tx-checksum-ip-generic", - "tx-checksum-ipv6", - "tx-checksum-fcoe-crc", - "tx-checksum-sctp"), - - /* names from ethtool utility, which are aliases for one feature. */ - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert"), - - /* names of features, as known by kernel. */ - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD, "esp-hw-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, "esp-tx-csum-hw-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_FCOE_MTU, "fcoe-mtu"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_HIGHDMA, "highdma"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, "hw-tc-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, "l2-fwd-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_LOOPBACK, "loopback"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_ALL, "rx-all"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_FCS, "rx-fcs"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, "rx-gro-hw"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, "rx-udp_tunnel-port-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, "rx-vlan-filter"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, "rx-vlan-stag-filter"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, "rx-vlan-stag-hw-parse"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, "tls-hw-record"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, "tls-hw-tx-offload"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, "tx-checksum-fcoe-crc"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, "tx-checksum-ipv4"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, "tx-checksum-ipv6"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, "tx-checksum-ip-generic"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, "tx-checksum-sctp"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, "tx-esp-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, "tx-fcoe-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, "tx-gre-csum-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, "tx-gre-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, "tx-gso-partial"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, "tx-gso-robust"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, "tx-ipxip4-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, "tx-ipxip6-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, "tx-nocache-copy"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, "tx-scatter-gather"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, "tx-scatter-gather-fraglist"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, "tx-sctp-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, "tx-tcp-ecn-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, "tx-tcp-mangleid-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, "tx-udp-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, "tx-udp_tnl-csum-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, "tx-udp_tnl-segmentation"), - ETHT_FEAT (NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, "tx-vlan-stag-hw-insert"), -}; - -/* the number of kernel features that we handle. It essentially is the sum of all - * kernel_names. So, all ethtool-ids that reference exactly one kernel-name - * (_NM_ETHTOOL_ID_FEATURE_NUM) + some extra, for ethtool-ids that are aliases - * for multiple kernel-names. */ -#define N_ETHTOOL_KERNEL_FEATURES (((guint) _NM_ETHTOOL_ID_FEATURE_NUM) + 8u) - -static void -_ASSERT_ethtool_feature_infos (void) -{ -#if NM_MORE_ASSERTS > 10 - guint i, k, n; - bool found[_NM_ETHTOOL_ID_FEATURE_NUM] = { }; - - G_STATIC_ASSERT_EXPR (G_N_ELEMENTS (_ethtool_feature_infos) == _NM_ETHTOOL_ID_FEATURE_NUM); - - n = 0; - for (i = 0; i < G_N_ELEMENTS (_ethtool_feature_infos); i++) { - NMEthtoolFeatureState kstate; - const NMEthtoolFeatureInfo *inf = &_ethtool_feature_infos[i]; - - g_assert (inf->ethtool_id >= _NM_ETHTOOL_ID_FEATURE_FIRST); - g_assert (inf->ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST); - g_assert (inf->n_kernel_names > 0); - - for (k = 0; k < i; k++) - g_assert (inf->ethtool_id != _ethtool_feature_infos[k].ethtool_id); - - g_assert (!found[inf->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]); - found[inf->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST] = TRUE; - - kstate.idx_kernel_name = inf->n_kernel_names - 1; - g_assert ((guint) kstate.idx_kernel_name == (guint) (inf->n_kernel_names - 1)); - - n += inf->n_kernel_names; - for (k = 0; k < inf->n_kernel_names; k++) { - g_assert (nm_utils_strv_find_first ((char **) inf->kernel_names, - k, - inf->kernel_names[k]) < 0); - } - } - - for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) - g_assert (found[i]); - - g_assert (n == N_ETHTOOL_KERNEL_FEATURES); -#endif -} - -static NMEthtoolFeatureStates * -ethtool_get_features (SocketHandle *shandle) -{ - gs_free NMEthtoolFeatureStates *states = NULL; - gs_free struct ethtool_gstrings *ss_features = NULL; - - _ASSERT_ethtool_feature_infos (); - - ss_features = ethtool_get_stringset (shandle, ETH_SS_FEATURES); - if (!ss_features) - return NULL; - - if (ss_features->len > 0) { - gs_free struct ethtool_gfeatures *gfeatures = NULL; - guint idx; - const NMEthtoolFeatureState *states_list0 = NULL; - const NMEthtoolFeatureState *const*states_plist0 = NULL; - guint states_plist_n = 0; - - gfeatures = g_malloc0 ( sizeof (struct ethtool_gfeatures) - + (NM_DIV_ROUND_UP (ss_features->len, 32u) * sizeof(gfeatures->features[0]))); - - gfeatures->cmd = ETHTOOL_GFEATURES; - gfeatures->size = NM_DIV_ROUND_UP (ss_features->len, 32u); - if (ethtool_call_handle (shandle, gfeatures) < 0) - return NULL; - - for (idx = 0; idx < G_N_ELEMENTS (_ethtool_feature_infos); idx++) { - const NMEthtoolFeatureInfo *info = &_ethtool_feature_infos[idx]; - guint idx_kernel_name; - - for (idx_kernel_name = 0; idx_kernel_name < info->n_kernel_names; idx_kernel_name++) { - NMEthtoolFeatureState *kstate; - const char *kernel_name = info->kernel_names[idx_kernel_name]; - int i_feature; - guint i_block; - guint32 i_flag; - - i_feature = ethtool_gstrings_find (ss_features, kernel_name); - if (i_feature < 0) - continue; - - i_block = ((guint) i_feature) / 32u; - i_flag = (guint32) (1u << (((guint) i_feature) % 32u)); - - if (!states) { - states = g_malloc0 (sizeof (NMEthtoolFeatureStates) - + (N_ETHTOOL_KERNEL_FEATURES * sizeof (NMEthtoolFeatureState)) - + ((N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS (_ethtool_feature_infos)) * sizeof (NMEthtoolFeatureState *))); - states_list0 = &states->states_list[0]; - states_plist0 = (gpointer) &states_list0[N_ETHTOOL_KERNEL_FEATURES]; - states->n_ss_features = ss_features->len; - } - - nm_assert (states->n_states < N_ETHTOOL_KERNEL_FEATURES); - kstate = (NMEthtoolFeatureState *) &states_list0[states->n_states]; - states->n_states++; - - kstate->info = info; - kstate->idx_ss_features = i_feature; - kstate->idx_kernel_name = idx_kernel_name; - kstate->available = !!(gfeatures->features[i_block].available & i_flag); - kstate->requested = !!(gfeatures->features[i_block].requested & i_flag); - kstate->active = !!(gfeatures->features[i_block].active & i_flag); - kstate->never_changed = !!(gfeatures->features[i_block].never_changed & i_flag); - - nm_assert (states_plist_n < N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS (_ethtool_feature_infos)); - - if (!states->states_indexed[info->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]) - states->states_indexed[info->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST] = &states_plist0[states_plist_n]; - ((const NMEthtoolFeatureState **) states_plist0)[states_plist_n] = kstate; - states_plist_n++; - } - - if (states && states->states_indexed[info->ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]) { - nm_assert (states_plist_n < N_ETHTOOL_KERNEL_FEATURES + G_N_ELEMENTS (_ethtool_feature_infos)); - nm_assert (!states_plist0[states_plist_n]); - states_plist_n++; - } - } - } - - return g_steal_pointer (&states); -} - -NMEthtoolFeatureStates * -nmp_utils_ethtool_get_features (int ifindex) -{ - nm_auto_socket_handle SocketHandle shandle = { }; - NMEthtoolFeatureStates *features; - int r; - - g_return_val_if_fail (ifindex > 0, 0); - - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", - ifindex, - "get-features", - g_strerror (-r)); + g_strerror (errno)); return FALSE; } - features = ethtool_get_features (&shandle); + { + nm_auto_close int fd = -1; + struct ifreq ifr = { + .ifr_data = edata, + }; - if (!features) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failure getting features", - ifindex, - "get-features"); - return NULL; - } - - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: retrieved kernel features", - ifindex, - "get-features"); - return features; -} - -static const char * -_ethtool_feature_state_to_string (char *buf, gsize buf_size, const NMEthtoolFeatureState *s, const char *prefix) -{ - int l; - - l = g_snprintf (buf, buf_size, - "%s %s%s", - prefix ?: "", - ONOFF (s->active), - (!s->available || s->never_changed) - ? ", [fixed]" - : ((s->requested != s->active) - ? (s->requested ? ", [requested on]" : ", [requested off]") - : "")); - nm_assert (l < buf_size); - return buf; -} + memcpy (ifr.ifr_name, ifname, sizeof (ifname)); -gboolean -nmp_utils_ethtool_set_features (int ifindex, - const NMEthtoolFeatureStates *features, - const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, - gboolean do_set /* or reset */) -{ - nm_auto_socket_handle SocketHandle shandle = { }; - gs_free struct ethtool_sfeatures *sfeatures = NULL; - int r; - guint i, j; - struct { - const NMEthtoolFeatureState *f_state; - NMTernary requested; - } set_states[N_ETHTOOL_KERNEL_FEATURES]; - guint set_states_n = 0; - gboolean success = TRUE; - - g_return_val_if_fail (ifindex > 0, 0); - g_return_val_if_fail (features, 0); - g_return_val_if_fail (requested, 0); - - nm_assert (features->n_states <= N_ETHTOOL_KERNEL_FEATURES); - - for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) { - const NMEthtoolFeatureState *const*states_indexed; - - if (requested[i] == NM_TERNARY_DEFAULT) - continue; - - if (!(states_indexed = features->states_indexed[i])) { - if (do_set) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: set feature %s: skip (not found)", - ifindex, - "set-features", - nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname); - success = FALSE; - } - continue; + fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: failed creating socket for ioctl: %s", + ifindex, + _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), + ifname, + g_strerror (errno)); + return FALSE; } - for (j = 0; states_indexed[j]; j++) { - const NMEthtoolFeatureState *s = states_indexed[j]; - char sbuf[255]; - - if (set_states_n >= G_N_ELEMENTS (set_states)) - g_return_val_if_reached (FALSE); - - if (s->never_changed) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: %s feature %s (%s): %s, %s (skip feature marked as never changed)", - ifindex, - "set-features", - do_set ? "set" : "reset", - nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, - s->info->kernel_names[s->idx_kernel_name], - ONOFF (do_set ? requested[i] == NM_TERNARY_TRUE : s->active), - _ethtool_feature_state_to_string (sbuf, sizeof (sbuf), s, do_set ? " currently:" : " before:")); - continue; - } - - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: %s feature %s (%s): %s, %s", + if (ioctl (fd, SIOCETHTOOL, &ifr) < 0) { + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: failed: %s", ifindex, - "set-features", - do_set ? "set" : "reset", - nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, - s->info->kernel_names[s->idx_kernel_name], - ONOFF (do_set ? requested[i] == NM_TERNARY_TRUE : s->active), - _ethtool_feature_state_to_string (sbuf, sizeof (sbuf), s, do_set ? " currently:" : " before:")); - - if ( do_set - && (!s->available || s->never_changed) - && (s->active != (requested[i] == NM_TERNARY_TRUE))) { - /* we request to change a flag which kernel reported as fixed. - * While the ethtool operation will silently succeed, mark the request - * as failure. */ - success = FALSE; - } - - set_states[set_states_n].f_state = s; - set_states[set_states_n].requested = requested[i]; - set_states_n++; + _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), + ifname, + strerror (errno)); + return FALSE; } - } - if (set_states_n == 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: no feature requested", + nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s, %s: success", ifindex, - "set-features"); + _ethtool_data_to_string (edata, sbuf, sizeof (sbuf)), + ifname); return TRUE; } +} - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", - ifindex, - "set-features", - g_strerror (-r)); - return FALSE; - } +static int +ethtool_get_stringset_index (int ifindex, int stringset_id, const char *string) +{ + gs_free struct ethtool_sset_info *info = NULL; + gs_free struct ethtool_gstrings *strings = NULL; + guint32 len, i; - sfeatures = g_malloc0 (sizeof (struct ethtool_sfeatures) - + (NM_DIV_ROUND_UP (features->n_ss_features, 32U) * sizeof(sfeatures->features[0]))); - sfeatures->cmd = ETHTOOL_SFEATURES; - sfeatures->size = NM_DIV_ROUND_UP (features->n_ss_features, 32U); + g_return_val_if_fail (ifindex > 0, -1); - for (i = 0; i < set_states_n; i++) { - const NMEthtoolFeatureState *s = set_states[i].f_state; - guint i_block; - guint32 i_flag; - gboolean is_requested; + info = g_malloc0 (sizeof (*info) + sizeof (guint32)); + info->cmd = ETHTOOL_GSSET_INFO; + info->reserved = 0; + info->sset_mask = 1ULL << stringset_id; - i_block = s->idx_ss_features / 32u; - i_flag = (guint32) (1u << (s->idx_ss_features % 32u)); + if (!ethtool_get (ifindex, info)) + return -1; + if (!info->sset_mask) + return -1; - sfeatures->features[i_block].valid |= i_flag; + len = info->data[0]; - if (do_set) - is_requested = (set_states[i].requested == NM_TERNARY_TRUE); - else - is_requested = s->active; + strings = g_malloc0 (sizeof (*strings) + len * ETH_GSTRING_LEN); + strings->cmd = ETHTOOL_GSTRINGS; + strings->string_set = stringset_id; + strings->len = len; + if (!ethtool_get (ifindex, strings)) + return -1; - if (is_requested) - sfeatures->features[i_block].requested |= i_flag; - else - sfeatures->features[i_block].requested &= ~i_flag; - } - - if ((r = ethtool_call_handle (&shandle, sfeatures)) < 0) { - success = FALSE; - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failure setting features (%s)", - ifindex, - "set-features", - g_strerror (-r)); - return FALSE; + for (i = 0; i < len; i++) { + if (!strcmp ((char *) &strings->data[i * ETH_GSTRING_LEN], string)) + return i; } - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: %s", - ifindex, - "set-features", - success - ? "successfully setting features" - : "at least some of the features were not successfuly set"); - return success; + return -1; } -/*****************************************************************************/ - gboolean nmp_utils_ethtool_get_driver_info (int ifindex, NMPUtilsEthtoolDriverInfo *data) { struct ethtool_drvinfo *drvinfo; - - G_STATIC_ASSERT_EXPR (sizeof (*data) == sizeof (*drvinfo)); - G_STATIC_ASSERT_EXPR (offsetof (NMPUtilsEthtoolDriverInfo, driver) == offsetof (struct ethtool_drvinfo, driver)); - G_STATIC_ASSERT_EXPR (offsetof (NMPUtilsEthtoolDriverInfo, version) == offsetof (struct ethtool_drvinfo, version)); - G_STATIC_ASSERT_EXPR (offsetof (NMPUtilsEthtoolDriverInfo, fw_version) == offsetof (struct ethtool_drvinfo, fw_version)); - G_STATIC_ASSERT_EXPR (sizeof (data->driver) == sizeof (drvinfo->driver)); - G_STATIC_ASSERT_EXPR (sizeof (data->version) == sizeof (drvinfo->version)); - G_STATIC_ASSERT_EXPR (sizeof (data->fw_version) == sizeof (drvinfo->fw_version)); + G_STATIC_ASSERT (sizeof (*data) == sizeof (*drvinfo)); + G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, driver) == offsetof (struct ethtool_drvinfo, driver)); + G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, version) == offsetof (struct ethtool_drvinfo, version)); + G_STATIC_ASSERT (offsetof (NMPUtilsEthtoolDriverInfo, fw_version) == offsetof (struct ethtool_drvinfo, fw_version)); + G_STATIC_ASSERT (sizeof (data->driver) == sizeof (drvinfo->driver)); + G_STATIC_ASSERT (sizeof (data->version) == sizeof (drvinfo->version)); + G_STATIC_ASSERT (sizeof (data->fw_version) == sizeof (drvinfo->fw_version)); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (data, FALSE); @@ -691,7 +213,7 @@ nmp_utils_ethtool_get_driver_info (int ifindex, memset (drvinfo, 0, sizeof (*drvinfo)); drvinfo->cmd = ETHTOOL_GDRVINFO; - return ethtool_call_ifindex (ifindex, drvinfo) >= 0; + return ethtool_get (ifindex, drvinfo); } gboolean @@ -711,7 +233,7 @@ nmp_utils_ethtool_get_permanent_address (int ifindex, edata.e.cmd = ETHTOOL_GPERMADDR; edata.e.size = NM_UTILS_HWADDR_LEN_MAX; - if (ethtool_call_ifindex (ifindex, &edata.e) < 0) + if (!ethtool_get (ifindex, &edata.e)) return FALSE; if (edata.e.size > NM_UTILS_HWADDR_LEN_MAX) @@ -730,8 +252,8 @@ nmp_utils_ethtool_get_permanent_address (int ifindex, } return FALSE; } - not_all_0or1: + memcpy (buf, edata.e.data, edata.e.size); *length = edata.e.size; return TRUE; @@ -748,30 +270,20 @@ nmp_utils_ethtool_supports_carrier_detect (int ifindex) * assume the device supports carrier-detect, otherwise we assume it * doesn't. */ - return ethtool_call_ifindex (ifindex, &edata) >= 0; + return ethtool_get (ifindex, &edata); } gboolean nmp_utils_ethtool_supports_vlans (int ifindex) { - nm_auto_socket_handle SocketHandle shandle = { }; - int r; gs_free struct ethtool_gfeatures *features = NULL; int idx, block, bit, size; g_return_val_if_fail (ifindex > 0, FALSE); - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", - ifindex, - "support-vlans", - g_strerror (-r)); - return FALSE; - } - - idx = ethtool_get_stringset_index (&shandle, ETH_SS_FEATURES, "vlan-challenged"); - if (idx < 0) { - nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: vlan-challenged ethtool feature does not exist?", ifindex); + idx = ethtool_get_stringset_index (ifindex, ETH_SS_FEATURES, "vlan-challenged"); + if (idx == -1) { + nm_log_dbg (LOGD_PLATFORM, "ethtool: vlan-challenged ethtool feature does not exist for %d?", ifindex); return FALSE; } @@ -783,7 +295,7 @@ nmp_utils_ethtool_supports_vlans (int ifindex) features->cmd = ETHTOOL_GFEATURES; features->size = size; - if (ethtool_call_handle (&shandle, features) < 0) + if (!ethtool_get (ifindex, features)) return FALSE; return !(features->features[block].active & (1 << bit)); @@ -792,32 +304,21 @@ nmp_utils_ethtool_supports_vlans (int ifindex) int nmp_utils_ethtool_get_peer_ifindex (int ifindex) { - nm_auto_socket_handle SocketHandle shandle = { }; - int r; - gs_free struct ethtool_stats *stats = NULL; int peer_ifindex_stat; g_return_val_if_fail (ifindex > 0, 0); - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "ethtool[%d]: %s: failed creating ethtool socket: %s", - ifindex, - "get-peer-ifindex", - g_strerror (-r)); - return FALSE; - } - - peer_ifindex_stat = ethtool_get_stringset_index (&shandle, ETH_SS_STATS, "peer_ifindex"); - if (peer_ifindex_stat < 0) { - nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: peer_ifindex stat does not exist?", ifindex); + peer_ifindex_stat = ethtool_get_stringset_index (ifindex, ETH_SS_STATS, "peer_ifindex"); + if (peer_ifindex_stat == -1) { + nm_log_dbg (LOGD_PLATFORM, "ethtool: peer_ifindex stat for %d does not exist?", ifindex); return FALSE; } stats = g_malloc0 (sizeof (*stats) + (peer_ifindex_stat + 1) * sizeof (guint64)); stats->cmd = ETHTOOL_GSTATS; stats->n_stats = peer_ifindex_stat + 1; - if (ethtool_call_ifindex (ifindex, stats) < 0) + if (!ethtool_get (ifindex, stats)) return 0; return stats->data[peer_ifindex_stat]; @@ -832,7 +333,7 @@ nmp_utils_ethtool_get_wake_on_lan (int ifindex) memset (&wol, 0, sizeof (wol)); wol.cmd = ETHTOOL_GWOL; - if (ethtool_call_ifindex (ifindex, &wol) < 0) + if (!ethtool_get (ifindex, &wol)) return FALSE; return wol.wolopts != 0; @@ -850,7 +351,7 @@ nmp_utils_ethtool_get_link_settings (int ifindex, g_return_val_if_fail (ifindex > 0, FALSE); - if (ethtool_call_ifindex (ifindex, &edata) < 0) + if (!ethtool_get (ifindex, &edata)) return FALSE; if (out_autoneg) @@ -932,13 +433,9 @@ nmp_utils_ethtool_set_link_settings (int ifindex, || (!speed && duplex == NM_PLATFORM_LINK_DUPLEX_UNKNOWN), FALSE); /* retrieve first current settings */ - if (ethtool_call_ifindex (ifindex, &edata) < 0) + if (!ethtool_get (ifindex, &edata)) return FALSE; - /* FIXME: try first new ETHTOOL_GLINKSETTINGS/SLINKSETTINGS API - * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=3f1ac7a700d039c61d8d8b99f28d605d489a60cf - */ - /* then change the needed ones */ edata.cmd = ETHTOOL_SSET; if (autoneg) { @@ -988,7 +485,7 @@ nmp_utils_ethtool_set_link_settings (int ifindex, } } - return ethtool_call_ifindex (ifindex, &edata) >= 0; + return ethtool_get (ifindex, &edata); } gboolean @@ -1003,8 +500,8 @@ nmp_utils_ethtool_set_wake_on_lan (int ifindex, if (wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE) return TRUE; - nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: setting Wake-on-LAN options 0x%x, password '%s'", - ifindex, (unsigned) wol, wol_password); + nm_log_dbg (LOGD_PLATFORM, "setting Wake-on-LAN options 0x%x, password '%s'", + (unsigned) wol, wol_password); wol_info.cmd = ETHTOOL_SWOL; wol_info.wolopts = 0; @@ -1024,41 +521,45 @@ nmp_utils_ethtool_set_wake_on_lan (int ifindex, if (wol_password) { if (!nm_utils_hwaddr_aton (wol_password, wol_info.sopass, ETH_ALEN)) { - nm_log_dbg (LOGD_PLATFORM, "ethtool[%d]: couldn't parse Wake-on-LAN password '%s'", ifindex, wol_password); + nm_log_dbg (LOGD_PLATFORM, "couldn't parse Wake-on-LAN password '%s'", wol_password); return FALSE; } wol_info.wolopts |= WAKE_MAGICSECURE; } - return ethtool_call_ifindex (ifindex, &wol_info) >= 0; + return ethtool_get (ifindex, &wol_info); } -/****************************************************************************** +/****************************************************************** * mii - *****************************************************************************/ + ******************************************************************/ gboolean nmp_utils_mii_supports_carrier_detect (int ifindex) { - nm_auto_socket_handle SocketHandle shandle = { }; - int r; + char ifname[IFNAMSIZ]; + nm_auto_close int fd = -1; struct ifreq ifr; struct mii_ioctl_data *mii; g_return_val_if_fail (ifindex > 0, FALSE); - if ((r = socket_handle_init (&shandle, ifindex)) < 0) { - nm_log_trace (LOGD_PLATFORM, "mii[%d]: carrier-detect no: failed creating ethtool socket: %s", - ifindex, - g_strerror (-r)); + if (!nmp_utils_if_indextoname (ifindex, ifname)) { + nm_log_trace (LOGD_PLATFORM, "mii[%d]: carrier-detect no: request fails resolving ifindex: %s", ifindex, g_strerror (errno)); + return FALSE; + } + + fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: couldn't open control socket: %s", ifindex, ifname, g_strerror (errno)); return FALSE; } memset (&ifr, 0, sizeof (struct ifreq)); - memcpy (ifr.ifr_name, shandle.ifname, IFNAMSIZ); + memcpy (ifr.ifr_name, ifname, IFNAMSIZ); - if (ioctl (shandle.fd, SIOCGMIIPHY, &ifr) < 0) { - nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIPHY failed: %s", ifindex, shandle.ifname, strerror (errno)); + if (ioctl (fd, SIOCGMIIPHY, &ifr) < 0) { + nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIPHY failed: %s", ifindex, ifname, strerror (errno)); return FALSE; } @@ -1066,18 +567,18 @@ nmp_utils_mii_supports_carrier_detect (int ifindex) mii = (struct mii_ioctl_data *) &ifr.ifr_ifru; mii->reg_num = MII_BMSR; - if (ioctl (shandle.fd, SIOCGMIIREG, &ifr) != 0) { - nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIREG failed: %s", ifindex, shandle.ifname, strerror (errno)); + if (ioctl (fd, SIOCGMIIREG, &ifr) != 0) { + nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect no: SIOCGMIIREG failed: %s", ifindex, ifname, strerror (errno)); return FALSE; } - nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect yes: SIOCGMIIREG result 0x%X", ifindex, shandle.ifname, mii->val_out); + nm_log_trace (LOGD_PLATFORM, "mii[%d,%s]: carrier-detect yes: SIOCGMIIREG result 0x%X", ifindex, ifname, mii->val_out); return TRUE; } -/****************************************************************************** +/****************************************************************** * udev - *****************************************************************************/ + ******************************************************************/ const char * nmp_utils_udev_get_driver (struct udev_device *udevice) diff --git a/src/platform/nm-platform-utils.h b/src/platform/nm-platform-utils.h index bad77aee..97f5630a 100644 --- a/src/platform/nm-platform-utils.h +++ b/src/platform/nm-platform-utils.h @@ -23,9 +23,6 @@ #include "nm-platform.h" #include "nm-setting-wired.h" -#include "nm-ethtool-utils.h" - -/*****************************************************************************/ const char *nmp_utils_ethtool_get_driver (int ifindex); gboolean nmp_utils_ethtool_supports_carrier_detect (int ifindex); @@ -38,10 +35,6 @@ gboolean nmp_utils_ethtool_set_wake_on_lan (int ifindex, NMSettingWiredWakeOnLan gboolean nmp_utils_ethtool_get_link_settings (int ifindex, gboolean *out_autoneg, guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex); gboolean nmp_utils_ethtool_set_link_settings (int ifindex, gboolean autoneg, guint32 speed, NMPlatformLinkDuplexType duplex); -gboolean nmp_utils_ethtool_get_permanent_address (int ifindex, - guint8 *buf, - size_t *length); - typedef struct { /* We don't want to include <linux/ethtool.h> in header files, * thus create a ABI compatible version of struct ethtool_drvinfo.*/ @@ -62,52 +55,9 @@ typedef struct { gboolean nmp_utils_ethtool_get_driver_info (int ifindex, NMPUtilsEthtoolDriverInfo *data); -typedef struct { - NMEthtoolID ethtool_id; - - guint8 n_kernel_names; - - /* one NMEthtoolID refers to one or more kernel_names. The reason for supporting this complexity - * (where one NMSettingEthtool option refers to multiple kernel features) is to follow what - * ethtool does, where "tx" is an alias for multiple features. */ - const char *const*kernel_names; -} NMEthtoolFeatureInfo; - -typedef struct { - const NMEthtoolFeatureInfo *info; - - guint idx_ss_features; - - /* one NMEthtoolFeatureInfo references one or more kernel_names. This is the index - * of the matching info->kernel_names */ - guint8 idx_kernel_name; - - bool available:1; - bool requested:1; - bool active:1; - bool never_changed:1; -} NMEthtoolFeatureState; - -struct _NMEthtoolFeatureStates { - guint n_states; - - guint n_ss_features; - - /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */ - const NMEthtoolFeatureState *const*states_indexed[_NM_ETHTOOL_ID_FEATURE_NUM]; - - /* the same content, here as a list of n_states entries. */ - const NMEthtoolFeatureState states_list[]; -}; - -NMEthtoolFeatureStates *nmp_utils_ethtool_get_features (int ifindex); - -gboolean nmp_utils_ethtool_set_features (int ifindex, - const NMEthtoolFeatureStates *features, - const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, - gboolean do_set /* or reset */); - -/*****************************************************************************/ +gboolean nmp_utils_ethtool_get_permanent_address (int ifindex, + guint8 *buf, + size_t *length); gboolean nmp_utils_mii_supports_carrier_detect (int ifindex); diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 7ddcf41a..f75019e8 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2012 - 2018 Red Hat, Inc. + * Copyright (C) 2012 - 2017 Red Hat, Inc. */ #include "nm-default.h" @@ -27,8 +27,6 @@ #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> -#include <sys/socket.h> -#include <netdb.h> #include <string.h> #include <linux/ip.h> #include <linux/if_tun.h> @@ -76,6 +74,8 @@ G_STATIC_ASSERT (G_STRUCT_OFFSET (NMPlatformIPRoute, network_ptr) == G_STRUCT_OF } \ } G_STMT_END +#define LOG_FMT_IP_TUNNEL "adding %s '%s' parent %u local %s remote %s" + /*****************************************************************************/ static guint signals[_NM_PLATFORM_SIGNAL_ID_LAST] = { 0 }; @@ -807,7 +807,6 @@ _nm_platform_link_get_by_address_match_link (const NMPObject *obj, struct _nm_pl **/ const NMPlatformLink * nm_platform_link_get_by_address (NMPlatform *self, - NMLinkType link_type, gconstpointer address, size_t length) { @@ -828,7 +827,7 @@ nm_platform_link_get_by_address (NMPlatform *self, g_return_val_if_reached (NULL); obj = nmp_cache_lookup_link_full (nm_platform_get_cache (self), - 0, NULL, TRUE, link_type, + 0, NULL, TRUE, NM_LINK_TYPE_NONE, (NMPObjectMatchFn) _nm_platform_link_get_by_address_match_link, &d); return NMP_OBJECT_CAST_LINK (obj); } @@ -902,7 +901,7 @@ nm_platform_link_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("link: adding link '%s': %s (%d)" + _LOGD ("link: adding link '%s' of type '%s' (%d)" "%s%s" /* address */ "%s%s" /* veth peer */ "", @@ -986,7 +985,7 @@ nm_platform_link_set_netns (NMPlatform *self, int ifindex, int netns_fd) if (!pllink) return FALSE; - _LOGD ("link: move link %d to network namespace with fd %d", ifindex, netns_fd); + _LOGD ("link: ifindex %d changing network namespace to %d", ifindex, netns_fd); return klass->link_set_netns (self, ifindex, netns_fd); } @@ -1355,18 +1354,15 @@ nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolea NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, gconstpointer address, size_t length) { - gs_free char *mac = NULL; - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (ifindex > 0, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (address, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (length > 0, NM_PLATFORM_ERROR_BUG); - _LOGD ("link: setting %s (%d) hardware address to %s", + _LOGD ("link: setting %s (%d) hardware address", nm_strquote_a (20, nm_platform_link_get_name (self, ifindex)), - ifindex, - (mac = nm_utils_hwaddr_ntoa (address, length))); + ifindex); return klass->link_set_address (self, ifindex, address, length); } @@ -1463,52 +1459,18 @@ nm_platform_link_supports_sriov (NMPlatform *self, int ifindex) return klass->link_supports_sriov (self, ifindex); } -/** - * nm_platform_link_set_sriov_params: - * @self: platform instance - * @ifindex: the index of the interface to change - * @num_vfs: the number of VFs to create - * @autoprobe: -1 to keep the current autoprobe-drivers value, - * or {0,1} to set a new value - */ gboolean -nm_platform_link_set_sriov_params (NMPlatform *self, - int ifindex, - guint num_vfs, - int autoprobe) +nm_platform_link_set_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs) { _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (NM_IN_SET (autoprobe, -1, 0, 1), FALSE); - _LOGD ("link: setting %u total VFs and autoprobe %d for %s (%d)", + _LOGD ("link: setting %u VFs for %s (%d)", num_vfs, - autoprobe, nm_strquote_a (25, nm_platform_link_get_name (self, ifindex)), ifindex); - return klass->link_set_sriov_params (self, ifindex, num_vfs, autoprobe); -} - -gboolean -nm_platform_link_set_sriov_vfs (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs) -{ - guint i; - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - _LOGD ("link: setting VFs for \"%s\" (%d):", - nm_platform_link_get_name (self, ifindex), - ifindex); - - for (i = 0; vfs[i]; i++) { - const NMPlatformVF *vf = vfs[i]; - - _LOGD ("link: VF %s", nm_platform_vf_to_string (vf, NULL, 0)); - } - - return klass->link_set_sriov_vfs (self, ifindex, vfs); + return klass->link_set_sriov_num_vfs (self, ifindex, num_vfs); } /** @@ -1890,12 +1852,6 @@ nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLin return _link_get_lnk (self, ifindex, NM_LINK_TYPE_GRE, out_link); } -const NMPlatformLnkGre * -nm_platform_link_get_lnk_gretap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) -{ - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_GRETAP, out_link); -} - const NMPlatformLnkInfiniband * nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { @@ -1908,18 +1864,6 @@ nm_platform_link_get_lnk_ip6tnl (NMPlatform *self, int ifindex, const NMPlatform return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IP6TNL, out_link); } -const NMPlatformLnkIp6Tnl * -nm_platform_link_get_lnk_ip6gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) -{ - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IP6GRE, out_link); -} - -const NMPlatformLnkIp6Tnl * -nm_platform_link_get_lnk_ip6gretap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) -{ - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_IP6GRETAP, out_link); -} - const NMPlatformLnkIpIp * nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { @@ -1968,12 +1912,6 @@ nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformL return _link_get_lnk (self, ifindex, NM_LINK_TYPE_VXLAN, out_link); } -const NMPlatformLnkWireGuard * -nm_platform_link_get_lnk_wireguard (NMPlatform *self, int ifindex, const NMPlatformLink **out_link) -{ - return _link_get_lnk (self, ifindex, NM_LINK_TYPE_WIREGUARD, out_link); -} - /*****************************************************************************/ /** @@ -2058,9 +1996,8 @@ nm_platform_link_vlan_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("link: adding link '%s': vlan parent %d vlanid %d vlanflags %x", + _LOGD ("link: adding vlan '%s' parent %d vlanid %d vlanflags %x", name, parent, vlanid, vlanflags); - if (!klass->vlan_add (self, name, parent, vlanid, vlanflags, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; return NM_PLATFORM_ERROR_SUCCESS; @@ -2091,9 +2028,8 @@ nm_platform_link_vxlan_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("link: adding link '%s': %s", - name, nm_platform_lnk_vxlan_to_string (props, NULL, 0)); - + _LOGD ("link: adding vxlan '%s' parent %d id %d", + name, props->parent_ifindex, props->id); if (!klass->link_vxlan_add (self, name, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; return NM_PLATFORM_ERROR_SUCCESS; @@ -2144,78 +2080,13 @@ nm_platform_link_tun_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("link: adding link '%s': %s", + _LOGD ("link: adding tun '%s' %s", name, nm_platform_lnk_tun_to_string (props, b, sizeof (b))); - if (!klass->link_tun_add (self, name, props, out_link, out_fd)) return NM_PLATFORM_ERROR_UNSPECIFIED; return NM_PLATFORM_ERROR_SUCCESS; } -/** - * nm_platform_6lowpan_add: - * @self: platform instance - * @parent: parent link - * @name: name of the new interface - * @out_link: on success, the link object - * - * Create a 6LoWPAN interface. - */ -NMPlatformError -nm_platform_link_6lowpan_add (NMPlatform *self, - const char *name, - int parent, - const NMPlatformLink **out_link) -{ - NMPlatformError plerr; - - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); - - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - - plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_6LOWPAN, out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; - - _LOGD ("adding link '%s': 6lowpan parent %u", name, parent); - - if (!klass->link_6lowpan_add (self, name, parent, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; -} - -gboolean -nm_platform_link_6lowpan_get_properties (NMPlatform *self, int ifindex, int *out_parent) -{ - const NMPlatformLink *plink; - _CHECK_SELF (self, klass, FALSE); - - plink = nm_platform_link_get (self, ifindex); - - if (!plink) - return FALSE; - if (plink->type != NM_LINK_TYPE_6LOWPAN) - return FALSE; - - if (plink->parent != 0) { - NM_SET_OUT (out_parent, plink->parent); - return TRUE; - } - - /* As of 4.16 kernel does not expose the peer_ifindex as IFA_LINK. - * Find the WPAN device with the same MAC address. */ - if (out_parent) { - const NMPlatformLink *parent_plink; - - parent_plink = nm_platform_link_get_by_address (self, NM_LINK_TYPE_WPAN, - plink->addr.data, - plink->addr.len); - NM_SET_OUT (out_parent, parent_plink ? parent_plink->ifindex : -1); - } - - return TRUE; -} - /*****************************************************************************/ static gboolean @@ -2439,18 +2310,23 @@ nm_platform_link_gre_add (NMPlatform *self, const NMPlatformLink **out_link) { NMPlatformError plerr; + char buffer[INET_ADDRSTRLEN]; _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - plerr = _link_add_check_existing (self, name, props->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE, out_link); + plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_GRE, out_link); if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_gre_to_string (props, NULL, 0)); + _LOGD (LOG_FMT_IP_TUNNEL, + "gre", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); if (!klass->link_gre_add (self, name, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -2496,9 +2372,6 @@ _infiniband_add_add_or_delete (NMPlatform *self, if (!klass->infiniband_partition_add (self, parent, p_key, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; } else { - _LOGD ("link: deleting infiniband partition %s for parent '%s' (%d), key %d", - name, parent_link->name, parent, p_key); - if (!klass->infiniband_partition_delete (self, parent, p_key)) return NM_PLATFORM_ERROR_UNSPECIFIED; } @@ -2599,19 +2472,23 @@ nm_platform_link_ip6tnl_add (NMPlatform *self, const NMPlatformLink **out_link) { NMPlatformError plerr; + char buffer[INET6_ADDRSTRLEN]; _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (!props->is_gre, NM_PLATFORM_ERROR_BUG); plerr = _link_add_check_existing (self, name, NM_LINK_TYPE_IP6TNL, out_link); if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_ip6tnl_to_string (props, NULL, 0)); + _LOGD (LOG_FMT_IP_TUNNEL, + "ip6tnl", + name, + props->parent_ifindex, + nm_utils_inet6_ntop (&props->local, NULL), + nm_utils_inet6_ntop (&props->remote, buffer)); if (!klass->link_ip6tnl_add (self, name, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -2619,46 +2496,6 @@ nm_platform_link_ip6tnl_add (NMPlatform *self, } /** - * nm_platform_ip6gre_add: - * @self: platform instance - * @name: name of the new interface - * @props: interface properties - * @out_link: on success, the link object - * - * Create an IPv6 GRE/GRETAP tunnel. - */ -NMPlatformError -nm_platform_link_ip6gre_add (NMPlatform *self, - const char *name, - const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink **out_link) -{ - NMPlatformError plerr; - - _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); - - g_return_val_if_fail (props, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (name, NM_PLATFORM_ERROR_BUG); - g_return_val_if_fail (props->is_gre, NM_PLATFORM_ERROR_BUG); - - plerr = _link_add_check_existing (self, - name, - props->is_tap - ? NM_LINK_TYPE_IP6GRETAP - : NM_LINK_TYPE_IP6GRE, - out_link); - if (plerr != NM_PLATFORM_ERROR_SUCCESS) - return plerr; - - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_ip6tnl_to_string (props, NULL, 0)); - - if (!klass->link_ip6gre_add (self, name, props, out_link)) - return NM_PLATFORM_ERROR_UNSPECIFIED; - return NM_PLATFORM_ERROR_SUCCESS; -} - -/** * nm_platform_ipip_add: * @self: platform instance * @name: name of the new interface @@ -2674,6 +2511,7 @@ nm_platform_link_ipip_add (NMPlatform *self, const NMPlatformLink **out_link) { NMPlatformError plerr; + char buffer[INET_ADDRSTRLEN]; _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); @@ -2684,8 +2522,12 @@ nm_platform_link_ipip_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_ipip_to_string (props, NULL, 0)); + _LOGD (LOG_FMT_IP_TUNNEL, + "ipip", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); if (!klass->link_ipip_add (self, name, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -2696,7 +2538,6 @@ nm_platform_link_ipip_add (NMPlatform *self, * nm_platform_macsec_add: * @self: platform instance * @name: name of the new interface - * @parent: parent link * @props: interface properties * @out_link: on success, the link object * @@ -2720,8 +2561,10 @@ nm_platform_link_macsec_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_macsec_to_string (props, NULL, 0)); + _LOGD ("adding macsec '%s' parent %u sci %llx", + name, + parent, + (unsigned long long) props->sci); if (!klass->link_macsec_add (self, name, parent, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -2758,8 +2601,11 @@ nm_platform_link_macvlan_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_macvlan_to_string (props, NULL, 0)); + _LOGD ("adding %s '%s' parent %u mode %u", + props->tap ? "macvtap" : "macvlan", + name, + parent, + props->mode); if (!klass->link_macvlan_add (self, name, parent, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -2782,6 +2628,7 @@ nm_platform_link_sit_add (NMPlatform *self, const NMPlatformLink **out_link) { NMPlatformError plerr; + char buffer[INET_ADDRSTRLEN]; _CHECK_SELF (self, klass, NM_PLATFORM_ERROR_BUG); @@ -2792,8 +2639,12 @@ nm_platform_link_sit_add (NMPlatform *self, if (plerr != NM_PLATFORM_ERROR_SUCCESS) return plerr; - _LOGD ("adding link '%s': %s", - name, nm_platform_lnk_sit_to_string (props, NULL, 0)); + _LOGD (LOG_FMT_IP_TUNNEL, + "sit", + name, + props->parent_ifindex, + nm_utils_inet4_ntop (props->local, NULL), + nm_utils_inet4_ntop (props->remote, buffer)); if (!klass->link_sit_add (self, name, props, out_link)) return NM_PLATFORM_ERROR_UNSPECIFIED; @@ -3037,16 +2888,6 @@ nm_platform_wifi_indicate_addressing_running (NMPlatform *self, int ifindex, gbo klass->wifi_indicate_addressing_running (self, ifindex, running); } -NMSettingWirelessWakeOnWLan -nm_platform_wifi_get_wake_on_wlan (NMPlatform *self, int ifindex) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return klass->wifi_get_wake_on_wlan (self, ifindex); -} - gboolean nm_platform_wifi_set_wake_on_wlan (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl) { @@ -3088,46 +2929,6 @@ nm_platform_mesh_set_ssid (NMPlatform *self, int ifindex, const guint8 *ssid, gs return klass->mesh_set_ssid (self, ifindex, ssid, len); } -guint16 -nm_platform_wpan_get_pan_id (NMPlatform *self, int ifindex) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return klass->wpan_get_pan_id (self, ifindex); -} - -gboolean -nm_platform_wpan_set_pan_id (NMPlatform *self, int ifindex, guint16 pan_id) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return klass->wpan_set_pan_id (self, ifindex, pan_id); -} - -guint16 -nm_platform_wpan_get_short_addr (NMPlatform *self, int ifindex) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return klass->wpan_get_short_addr (self, ifindex); -} - -gboolean -nm_platform_wpan_set_short_addr (NMPlatform *self, int ifindex, guint16 short_addr) -{ - _CHECK_SELF (self, klass, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return klass->wpan_set_short_addr (self, ifindex, short_addr); -} - #define TO_STRING_DEV_BUF_SIZE (5+15+1) static const char * _to_string_dev (NMPlatform *self, int ifindex, char *buf, size_t size) @@ -3213,32 +3014,6 @@ NM_UTILS_LOOKUP_STR_DEFINE (nm_platform_link_duplex_type_to_string, NMPlatformLi /*****************************************************************************/ -NMEthtoolFeatureStates * -nm_platform_ethtool_get_link_features (NMPlatform *self, int ifindex) -{ - _CHECK_SELF_NETNS (self, klass, netns, NULL); - - g_return_val_if_fail (ifindex > 0, NULL); - - return nmp_utils_ethtool_get_features (ifindex); -} - -gboolean -nm_platform_ethtool_set_features (NMPlatform *self, - int ifindex, - const NMEthtoolFeatureStates *features, - const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, - gboolean do_set /* or reset */) -{ - _CHECK_SELF_NETNS (self, klass, netns, FALSE); - - g_return_val_if_fail (ifindex > 0, FALSE); - - return nmp_utils_ethtool_set_features (ifindex, features, requested, do_set); -} - -/*****************************************************************************/ - const NMDedupMultiHeadEntry * nm_platform_lookup_all (NMPlatform *platform, NMPCacheIdType cache_id_type, @@ -3847,7 +3622,7 @@ ip6_address_scope_priority (const struct in6_addr *addr) return 3; } -static int +static gint ip6_address_scope_cmp (gconstpointer a, gconstpointer b) { const NMPlatformIP6Address *x = NMP_OBJECT_CAST_IP6_ADDRESS (*(const void **) a); @@ -5182,7 +4957,7 @@ nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len return buf; g_snprintf (buf, len, - lnk->is_tap ? "gretap" : "gre" + "gre" "%s" /* remote */ "%s" /* local */ "%s" /* parent_ifindex */ @@ -5239,18 +5014,12 @@ nm_platform_lnk_ip6tnl_to_string (const NMPlatformLnkIp6Tnl *lnk, char *buf, gsi char str_encap[30]; char str_proto[30]; char str_parent_ifindex[30]; - char *str_type; if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) return buf; - if (lnk->is_gre) - str_type = lnk->is_tap ? "ip6gretap" : "ip6gre"; - else - str_type = "ip6tnl"; - g_snprintf (buf, len, - "%s" /* type */ + "ip6tnl" "%s" /* remote */ "%s" /* local */ "%s" /* parent_ifindex */ @@ -5261,7 +5030,6 @@ nm_platform_lnk_ip6tnl_to_string (const NMPlatformLnkIp6Tnl *lnk, char *buf, gsi "%s" /* proto */ " flags 0x%x" "", - str_type, nm_sprintf_buf (str_remote, " remote %s", nm_utils_inet6_ntop (&lnk->remote, str_remote1)), nm_sprintf_buf (str_local, " local %s", nm_utils_inet6_ntop (&lnk->local, str_local1)), lnk->parent_ifindex ? nm_sprintf_buf (str_parent_ifindex, " dev %d", lnk->parent_ifindex) : "", @@ -5346,8 +5114,7 @@ nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk, char *buf, g return buf; g_snprintf (buf, len, - "%s mode %u %s", - lnk->tap ? "macvtap" : "macvlan", + "macvlan mode %u %s", lnk->mode, lnk->no_promisc ? "not-promisc" : "promisc"); return buf; @@ -5531,91 +5298,6 @@ nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize return buf; } -const char * -nm_platform_wireguard_peer_to_string (const NMPWireGuardPeer *peer, char *buf, gsize len) -{ - gs_free char *public_key_b64 = NULL; - char s_endpoint[NM_UTILS_INET_ADDRSTRLEN + 100]; - char s_addr[NM_UTILS_INET_ADDRSTRLEN]; - guint i; - - nm_utils_to_string_buffer_init (&buf, &len); - - if (peer->endpoint_family == AF_INET) { - nm_sprintf_buf (s_endpoint, - " endpoint %s:%u", - nm_utils_inet4_ntop (peer->endpoint_addr.addr4, s_addr), - (guint) peer->endpoint_port); - } else if (peer->endpoint_family == AF_INET6) { - nm_sprintf_buf (s_endpoint, - " endpoint [%s]:%u", - nm_utils_inet6_ntop (&peer->endpoint_addr.addr6, s_addr), - (guint) peer->endpoint_port); - } else - s_endpoint[0] = '\0'; - - public_key_b64 = g_base64_encode (peer->public_key, sizeof (peer->public_key)); - - nm_utils_strbuf_append (&buf, &len, - "public-key %s" - "%s" /* preshared-key */ - "%s" /* endpoint */ - " rx %"G_GUINT64_FORMAT - " tx %"G_GUINT64_FORMAT - "%s", /* allowed-ips */ - public_key_b64, - nm_utils_mem_all_zero (peer->preshared_key, sizeof (peer->preshared_key)) - ? "" - : " preshared-key (hidden)", - s_endpoint, - peer->rx_bytes, - peer->tx_bytes, - peer->allowed_ips_len > 0 - ? " allowed-ips" - : ""); - - for (i = 0; i < peer->allowed_ips_len; i++) { - const NMPWireGuardAllowedIP *allowed_ip = &peer->allowed_ips[i]; - - nm_utils_strbuf_append (&buf, &len, - " %s/%u", - nm_utils_inet_ntop (allowed_ip->family, &allowed_ip->addr, s_addr), - allowed_ip->mask); - } - - return buf; -} - -const char * -nm_platform_lnk_wireguard_to_string (const NMPlatformLnkWireGuard *lnk, char *buf, gsize len) -{ - gs_free char *public_b64 = NULL; - - if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len)) - return buf; - - if (!nm_utils_mem_all_zero (lnk->public_key, sizeof (lnk->public_key))) - public_b64 = g_base64_encode (lnk->public_key, sizeof (lnk->public_key)); - - g_snprintf (buf, len, - "wireguard" - "%s%s" /* public-key */ - "%s" /* private-key */ - " listen-port %u" - " fwmark 0x%x", - public_b64 - ? " public-key " - : "", - public_b64 ?: "", - nm_utils_mem_all_zero (lnk->private_key, sizeof (lnk->private_key)) - ? "" - : " private-key (hidden)", - lnk->listen_port, - lnk->fwmark); - - return buf; -} - /** * nm_platform_ip4_address_to_string: * @route: pointer to NMPlatformIP4Address address structure @@ -6093,56 +5775,6 @@ nm_platform_tfilter_cmp (const NMPlatformTfilter *a, const NMPlatformTfilter *b) return 0; } -const char * -nm_platform_vf_to_string (const NMPlatformVF *vf, char *buf, gsize len) -{ - char str_mac[128], mac[128]; - char str_spoof_check[64]; - char str_trust[64]; - char str_min_tx_rate[64]; - char str_max_tx_rate[64]; - nm_auto_free_gstring GString *gstr_vlans = NULL; - guint i; - - if (!nm_utils_to_string_buffer_init_null (vf, &buf, &len)) - return buf; - - if (vf->mac.len) { - nm_utils_hwaddr_ntoa_buf (vf->mac.data, vf->mac.len, TRUE, mac, sizeof (mac)); - nm_sprintf_buf (str_mac, " mac %s", mac); - } else - str_mac[0] = '\0'; - - if (vf->num_vlans) { - gstr_vlans = g_string_new (""); - for (i = 0; i < vf->num_vlans; i++) { - g_string_append_printf (gstr_vlans, " vlan %u", (unsigned) vf->vlans[i].id); - if (vf->vlans[i].qos) - g_string_append_printf (gstr_vlans, " qos %u", (unsigned) vf->vlans[i].qos); - if (vf->vlans[i].proto_ad) - g_string_append (gstr_vlans, " proto 802.1ad"); - } - } - - g_snprintf (buf, len, - "%u" /* index */ - "%s" /* MAC */ - "%s" /* spoof check */ - "%s" /* trust */ - "%s" /* min tx rate */ - "%s" /* max tx rate */ - "%s", /* VLANs */ - vf->index, - str_mac, - vf->spoofchk >= 0 ? nm_sprintf_buf (str_spoof_check, " spoofchk %d", vf->spoofchk) : "", - vf->trust >= 0 ? nm_sprintf_buf (str_trust, " trust %d", vf->trust) : "", - vf->min_tx_rate ? nm_sprintf_buf (str_min_tx_rate, " min_tx_rate %u", (unsigned) vf->min_tx_rate) : "", - vf->max_tx_rate ? nm_sprintf_buf (str_max_tx_rate, " max_tx_rate %u", (unsigned) vf->max_tx_rate) : "", - gstr_vlans ? gstr_vlans->str : ""); - - return buf; -} - void nm_platform_link_hash_update (const NMPlatformLink *obj, NMHashState *h) { @@ -6211,8 +5843,7 @@ nm_platform_lnk_gre_hash_update (const NMPlatformLnkGre *obj, NMHashState *h) obj->output_key, obj->ttl, obj->tos, - (bool) obj->path_mtu_discovery, - (bool) obj->is_tap); + (bool) obj->path_mtu_discovery); } int @@ -6229,7 +5860,6 @@ nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b) NM_CMP_FIELD (a, b, ttl); NM_CMP_FIELD (a, b, tos); NM_CMP_FIELD_BOOL (a, b, path_mtu_discovery); - NM_CMP_FIELD_BOOL (a, b, is_tap); return 0; } @@ -6261,13 +5891,7 @@ nm_platform_lnk_ip6tnl_hash_update (const NMPlatformLnkIp6Tnl *obj, NMHashState obj->encap_limit, obj->proto, obj->flow_label, - obj->flags, - obj->input_flags, - obj->output_flags, - obj->input_key, - obj->output_key, - (bool) obj->is_gre, - (bool) obj->is_tap); + obj->flags); } int @@ -6283,12 +5907,6 @@ nm_platform_lnk_ip6tnl_cmp (const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6 NM_CMP_FIELD (a, b, flow_label); NM_CMP_FIELD (a, b, proto); NM_CMP_FIELD (a, b, flags); - NM_CMP_FIELD (a, b, input_flags); - NM_CMP_FIELD (a, b, output_flags); - NM_CMP_FIELD (a, b, input_key); - NM_CMP_FIELD (a, b, output_key); - NM_CMP_FIELD_BOOL (a, b, is_gre); - NM_CMP_FIELD_BOOL (a, b, is_tap); return 0; } @@ -6506,27 +6124,6 @@ nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan } void -nm_platform_lnk_wireguard_hash_update (const NMPlatformLnkWireGuard *obj, NMHashState *h) -{ - nm_hash_update_vals (h, - obj->listen_port, - obj->fwmark); - nm_hash_update (h, obj->private_key, sizeof (obj->private_key)); - nm_hash_update (h, obj->public_key, sizeof (obj->public_key)); -} - -int -nm_platform_lnk_wireguard_cmp (const NMPlatformLnkWireGuard *a, const NMPlatformLnkWireGuard *b) -{ - NM_CMP_SELF (a, b); - NM_CMP_FIELD (a, b, listen_port); - NM_CMP_FIELD (a, b, fwmark); - NM_CMP_FIELD_MEMCMP (a, b, private_key); - NM_CMP_FIELD_MEMCMP (a, b, public_key); - return 0; -} - -void nm_platform_ip4_address_hash_update (const NMPlatformIP4Address *obj, NMHashState *h) { nm_hash_update_vals (h, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 11495aff..866df736 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2009 - 2018 Red Hat, Inc. + * Copyright (C) 2009 - 2017 Red Hat, Inc. */ #ifndef __NETWORKMANAGER_PLATFORM_H__ @@ -608,26 +608,6 @@ extern const NMPlatformVTableRoute nm_platform_vtable_route_v4; extern const NMPlatformVTableRoute nm_platform_vtable_route_v6; typedef struct { - guint16 id; - guint32 qos; - bool proto_ad:1; -} NMPlatformVFVlan; - -typedef struct { - guint32 index; - guint32 min_tx_rate; - guint32 max_tx_rate; - guint num_vlans; - NMPlatformVFVlan *vlans; - struct { - guint8 data[20]; /* NM_UTILS_HWADDR_LEN_MAX */ - guint8 len; - } mac; - gint8 spoofchk; - gint8 trust; -} NMPlatformVF; - -typedef struct { in_addr_t local; in_addr_t remote; int parent_ifindex; @@ -638,7 +618,6 @@ typedef struct { guint8 ttl; guint8 tos; bool path_mtu_discovery:1; - bool is_tap:1; } NMPlatformLnkGre; typedef struct { @@ -656,14 +635,6 @@ typedef struct { guint8 proto; guint flow_label; guint32 flags; - - /* IP6GRE only */ - guint32 input_key; - guint32 output_key; - guint16 input_flags; - guint16 output_flags; - bool is_tap:1; - bool is_gre:1; } NMPlatformLnkIp6Tnl; typedef struct { @@ -752,16 +723,6 @@ typedef struct { bool l3miss:1; } NMPlatformLnkVxlan; -#define NMP_WIREGUARD_PUBLIC_KEY_LEN 32 -#define NMP_WIREGUARD_SYMMETRIC_KEY_LEN 32 - -typedef struct { - guint32 fwmark; - guint16 listen_port; - guint8 private_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; - guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; -} NMPlatformLnkWireGuard; - typedef enum { NM_PLATFORM_LINK_DUPLEX_UNKNOWN, NM_PLATFORM_LINK_DUPLEX_HALF, @@ -825,8 +786,7 @@ typedef struct { NMPlatformError (*link_set_address) (NMPlatform *, int ifindex, gconstpointer address, size_t length); NMPlatformError (*link_set_mtu) (NMPlatform *, int ifindex, guint32 mtu); gboolean (*link_set_name) (NMPlatform *, int ifindex, const char *name); - gboolean (*link_set_sriov_params) (NMPlatform *, int ifindex, guint num_vfs, int autoprobe); - gboolean (*link_set_sriov_vfs) (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs); + gboolean (*link_set_sriov_num_vfs) (NMPlatform *, int ifindex, guint num_vfs); char * (*link_get_physical_port_id) (NMPlatform *, int ifindex); guint (*link_get_dev_id) (NMPlatform *, int ifindex); @@ -869,10 +829,6 @@ typedef struct { const char *name, const NMPlatformLnkIp6Tnl *props, const NMPlatformLink **out_link); - gboolean (*link_ip6gre_add) (NMPlatform *, - const char *name, - const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink **out_link); gboolean (*link_ipip_add) (NMPlatform *, const char *name, const NMPlatformLnkIpIp *props, @@ -898,16 +854,12 @@ typedef struct { const NMPlatformLink **out_link, int *out_fd); - gboolean (*link_6lowpan_add) (NMPlatform *platform, - const char *name, - int parent, - const NMPlatformLink **out_link); - gboolean (*infiniband_partition_add) (NMPlatform *, int parent, int p_key, const NMPlatformLink **out_link); gboolean (*infiniband_partition_delete) (NMPlatform *, int parent, int p_key); gboolean (*wifi_get_capabilities) (NMPlatform *, int ifindex, NMDeviceWifiCapabilities *caps); gboolean (*wifi_get_bssid) (NMPlatform *, int ifindex, guint8 *bssid); + GByteArray *(*wifi_get_ssid) (NMPlatform *, int ifindex); guint32 (*wifi_get_frequency) (NMPlatform *, int ifindex); int (*wifi_get_quality) (NMPlatform *, int ifindex); guint32 (*wifi_get_rate) (NMPlatform *, int ifindex); @@ -916,18 +868,12 @@ typedef struct { void (*wifi_set_powersave) (NMPlatform *, int ifindex, guint32 powersave); guint32 (*wifi_find_frequency) (NMPlatform *, int ifindex, const guint32 *freqs); void (*wifi_indicate_addressing_running) (NMPlatform *, int ifindex, gboolean running); - NMSettingWirelessWakeOnWLan (*wifi_get_wake_on_wlan) (NMPlatform *, int ifindex); gboolean (*wifi_set_wake_on_wlan) (NMPlatform *, int ifindex, NMSettingWirelessWakeOnWLan wowl); guint32 (*mesh_get_channel) (NMPlatform *, int ifindex); gboolean (*mesh_set_channel) (NMPlatform *, int ifindex, guint32 channel); gboolean (*mesh_set_ssid) (NMPlatform *, int ifindex, const guint8 *ssid, gsize len); - guint16 (*wpan_get_pan_id) (NMPlatform *, int ifindex); - gboolean (*wpan_set_pan_id) (NMPlatform *, int ifindex, guint16 pan_id); - guint16 (*wpan_get_short_addr) (NMPlatform *, int ifindex); - gboolean (*wpan_set_short_addr) (NMPlatform *, int ifindex, guint16 short_addr); - gboolean (*object_delete) (NMPlatform *, const NMPObject *obj); gboolean (*ip4_address_add) (NMPlatform *, @@ -1132,7 +1078,7 @@ const NMPObject *nm_platform_link_get_obj (NMPlatform *self, gboolean visible_only); const NMPlatformLink *nm_platform_link_get (NMPlatform *self, int ifindex); const NMPlatformLink *nm_platform_link_get_by_ifname (NMPlatform *self, const char *ifname); -const NMPlatformLink *nm_platform_link_get_by_address (NMPlatform *self, NMLinkType link_type, gconstpointer address, size_t length); +const NMPlatformLink *nm_platform_link_get_by_address (NMPlatform *self, gconstpointer address, size_t length); GPtrArray *nm_platform_link_get_all (NMPlatform *self, gboolean sort_by_name); NMPlatformError nm_platform_link_dummy_add (NMPlatform *self, const char *name, const NMPlatformLink **out_link); @@ -1216,8 +1162,7 @@ gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, NMPlatformError nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length); NMPlatformError nm_platform_link_set_mtu (NMPlatform *self, int ifindex, guint32 mtu); gboolean nm_platform_link_set_name (NMPlatform *self, int ifindex, const char *name); -gboolean nm_platform_link_set_sriov_params (NMPlatform *self, int ifindex, guint num_vfs, int autoprobe); -gboolean nm_platform_link_set_sriov_vfs (NMPlatform *self, int ifindex, const NMPlatformVF *const *vfs); +gboolean nm_platform_link_set_sriov_num_vfs (NMPlatform *self, int ifindex, guint num_vfs); char *nm_platform_link_get_physical_port_id (NMPlatform *self, int ifindex); guint nm_platform_link_get_dev_id (NMPlatform *self, int ifindex); @@ -1242,10 +1187,7 @@ char *nm_platform_sysctl_slave_get_option (NMPlatform *self, int ifindex, const const NMPObject *nm_platform_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link); const NMPlatformLnkGre *nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); -const NMPlatformLnkGre *nm_platform_link_get_lnk_gretap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkIp6Tnl *nm_platform_link_get_lnk_ip6tnl (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); -const NMPlatformLnkIp6Tnl *nm_platform_link_get_lnk_ip6gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); -const NMPlatformLnkIp6Tnl *nm_platform_link_get_lnk_ip6gretap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkInfiniband *nm_platform_link_get_lnk_infiniband (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkIpIp *nm_platform_link_get_lnk_ipip (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); @@ -1256,7 +1198,6 @@ const NMPlatformLnkSit *nm_platform_link_get_lnk_sit (NMPlatform *self, int ifin const NMPlatformLnkTun *nm_platform_link_get_lnk_tun (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkVlan *nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); const NMPlatformLnkVxlan *nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); -const NMPlatformLnkWireGuard *nm_platform_link_get_lnk_wireguard (NMPlatform *self, int ifindex, const NMPlatformLink **out_link); NMPlatformError nm_platform_link_vlan_add (NMPlatform *self, const char *name, @@ -1306,18 +1247,12 @@ void nm_platform_wifi_set_mode (NMPlatform *self, int ifindex, NM void nm_platform_wifi_set_powersave (NMPlatform *self, int ifindex, guint32 powersave); guint32 nm_platform_wifi_find_frequency (NMPlatform *self, int ifindex, const guint32 *freqs); void nm_platform_wifi_indicate_addressing_running (NMPlatform *self, int ifindex, gboolean running); -NMSettingWirelessWakeOnWLan nm_platform_wifi_get_wake_on_wlan (NMPlatform *self, int ifindex); gboolean nm_platform_wifi_set_wake_on_wlan (NMPlatform *self, int ifindex, NMSettingWirelessWakeOnWLan wowl); guint32 nm_platform_mesh_get_channel (NMPlatform *self, int ifindex); gboolean nm_platform_mesh_set_channel (NMPlatform *self, int ifindex, guint32 channel); gboolean nm_platform_mesh_set_ssid (NMPlatform *self, int ifindex, const guint8 *ssid, gsize len); -guint16 nm_platform_wpan_get_pan_id (NMPlatform *platform, int ifindex); -gboolean nm_platform_wpan_set_pan_id (NMPlatform *platform, int ifindex, guint16 pan_id); -guint16 nm_platform_wpan_get_short_addr (NMPlatform *platform, int ifindex); -gboolean nm_platform_wpan_set_short_addr (NMPlatform *platform, int ifindex, guint16 short_addr); - void nm_platform_ip4_address_set_addr (NMPlatformIP4Address *addr, in_addr_t address, guint8 plen); const struct in6_addr *nm_platform_ip6_address_get_peer (const NMPlatformIP6Address *addr); @@ -1331,10 +1266,6 @@ NMPlatformError nm_platform_link_ip6tnl_add (NMPlatform *self, const char *name, const NMPlatformLnkIp6Tnl *props, const NMPlatformLink **out_link); -NMPlatformError nm_platform_link_ip6gre_add (NMPlatform *self, - const char *name, - const NMPlatformLnkIp6Tnl *props, - const NMPlatformLink **out_link); NMPlatformError nm_platform_link_ipip_add (NMPlatform *self, const char *name, const NMPlatformLnkIpIp *props, @@ -1358,13 +1289,6 @@ NMPlatformError nm_platform_link_tun_add (NMPlatform *self, const NMPlatformLnkTun *props, const NMPlatformLink **out_link, int *out_fd); -NMPlatformError nm_platform_link_6lowpan_add (NMPlatform *self, - const char *name, - int parent, - const NMPlatformLink **out_link); -gboolean nm_platform_link_6lowpan_get_properties (NMPlatform *self, - int ifindex, - int *out_parent); const NMPlatformIP6Address *nm_platform_ip6_address_get (NMPlatform *self, int ifindex, struct in6_addr address); @@ -1451,14 +1375,12 @@ const char *nm_platform_lnk_sit_to_string (const NMPlatformLnkSit *lnk, char *bu const char *nm_platform_lnk_tun_to_string (const NMPlatformLnkTun *lnk, char *buf, gsize len); const char *nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len); const char *nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize len); -const char *nm_platform_lnk_wireguard_to_string (const NMPlatformLnkWireGuard *lnk, char *buf, gsize len); const char *nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *buf, gsize len); const char *nm_platform_ip6_address_to_string (const NMPlatformIP6Address *address, char *buf, gsize len); const char *nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsize len); const char *nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsize len); const char *nm_platform_qdisc_to_string (const NMPlatformQdisc *qdisc, char *buf, gsize len); const char *nm_platform_tfilter_to_string (const NMPlatformTfilter *tfilter, char *buf, gsize len); -const char *nm_platform_vf_to_string (const NMPlatformVF *vf, char *buf, gsize len); const char *nm_platform_vlan_qos_mapping_to_string (const char *name, const NMVlanQosMapping *map, @@ -1466,11 +1388,6 @@ const char *nm_platform_vlan_qos_mapping_to_string (const char *name, char *buf, gsize len); -struct _NMPWireGuardPeer; -const char *nm_platform_wireguard_peer_to_string (const struct _NMPWireGuardPeer *peer, - char *buf, - gsize len); - int nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b); int nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b); int nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b); @@ -1482,7 +1399,6 @@ int nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit * int nm_platform_lnk_tun_cmp (const NMPlatformLnkTun *a, const NMPlatformLnkTun *b); int nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b); int nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b); -int nm_platform_lnk_wireguard_cmp (const NMPlatformLnkWireGuard *a, const NMPlatformLnkWireGuard *b); int nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b); int nm_platform_ip6_address_cmp (const NMPlatformIP6Address *a, const NMPlatformIP6Address *b); @@ -1519,7 +1435,6 @@ void nm_platform_lnk_sit_hash_update (const NMPlatformLnkSit *obj, NMHashState * void nm_platform_lnk_tun_hash_update (const NMPlatformLnkTun *obj, NMHashState *h); void nm_platform_lnk_vlan_hash_update (const NMPlatformLnkVlan *obj, NMHashState *h); void nm_platform_lnk_vxlan_hash_update (const NMPlatformLnkVxlan *obj, NMHashState *h); -void nm_platform_lnk_wireguard_hash_update (const NMPlatformLnkWireGuard *obj, NMHashState *h); void nm_platform_qdisc_hash_update (const NMPlatformQdisc *obj, NMHashState *h); void nm_platform_tfilter_hash_update (const NMPlatformTfilter *obj, NMHashState *h); @@ -1537,17 +1452,6 @@ int nm_platform_ip_address_cmp_expiry (const NMPlatformIPAddress *a, const NMPla gboolean nm_platform_ethtool_set_wake_on_lan (NMPlatform *self, int ifindex, NMSettingWiredWakeOnLan wol, const char *wol_password); gboolean nm_platform_ethtool_set_link_settings (NMPlatform *self, int ifindex, gboolean autoneg, guint32 speed, NMPlatformLinkDuplexType duplex); gboolean nm_platform_ethtool_get_link_settings (NMPlatform *self, int ifindex, gboolean *out_autoneg, guint32 *out_speed, NMPlatformLinkDuplexType *out_duplex); - -typedef struct _NMEthtoolFeatureStates NMEthtoolFeatureStates; - -NMEthtoolFeatureStates *nm_platform_ethtool_get_link_features (NMPlatform *self, - int ifindex); -gboolean nm_platform_ethtool_set_features (NMPlatform *self, - int ifindex, - const NMEthtoolFeatureStates *features, - const NMTernary *requested /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */, - gboolean do_set /* or reset */); - const char * nm_platform_link_duplex_type_to_string (NMPlatformLinkDuplexType duplex); void nm_platform_ip4_dev_route_blacklist_set (NMPlatform *self, diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index fdc27440..50e6825b 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2015 - 2018 Red Hat, Inc. + * Copyright (C) 2015 - 2017 Red Hat, Inc. */ #include "nm-default.h" @@ -27,14 +27,10 @@ #include <libudev.h> #include "nm-utils.h" -#include "nm-utils/nm-secret-utils.h" #include "nm-core-utils.h" #include "nm-platform-utils.h" -#include "wifi/nm-wifi-utils.h" -#include "wpan/nm-wpan-utils.h" - /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_PLATFORM @@ -341,103 +337,12 @@ _vlan_xgress_qos_mappings_cpy (guint *dst_n_map, g_clear_pointer (dst_map, g_free); *dst_n_map = src_n_map; if (src_n_map > 0) - *dst_map = nm_memdup (src_map, sizeof (*src_map) * src_n_map); + *dst_map = g_memdup (src_map, sizeof (*src_map) * src_n_map); } } /*****************************************************************************/ -static void -_wireguard_allowed_ip_hash_update (const NMPWireGuardAllowedIP *ip, - NMHashState *h) -{ - nm_hash_update_vals (h, ip->family, - ip->mask); - - if (ip->family == AF_INET) - nm_hash_update_val (h, ip->addr.addr4); - else if (ip->family == AF_INET6) - nm_hash_update_val (h, ip->addr.addr6); -} - -static int -_wireguard_allowed_ip_cmp (const NMPWireGuardAllowedIP *a, - const NMPWireGuardAllowedIP *b) -{ - NM_CMP_SELF (a, b); - - NM_CMP_FIELD (a, b, family); - NM_CMP_FIELD (a, b, mask); - - if (a->family == AF_INET) - NM_CMP_FIELD (a, b, addr.addr4); - else if (a->family == AF_INET6) - NM_CMP_FIELD_IN6ADDR (a, b, addr.addr6); - - return 0; -} - -static void -_wireguard_peer_hash_update (const NMPWireGuardPeer *peer, - NMHashState *h) -{ - guint i; - - nm_hash_update (h, peer->public_key, sizeof (peer->public_key)); - nm_hash_update (h, peer->preshared_key, sizeof (peer->preshared_key)); - nm_hash_update_vals (h, - peer->persistent_keepalive_interval, - peer->allowed_ips_len, - peer->rx_bytes, - peer->tx_bytes, - peer->last_handshake_time.tv_sec, - peer->last_handshake_time.tv_nsec, - peer->endpoint_port, - peer->endpoint_family); - - if (peer->endpoint_family == AF_INET) - nm_hash_update_val (h, peer->endpoint_addr.addr4); - else if (peer->endpoint_family == AF_INET6) - nm_hash_update_val (h, peer->endpoint_addr.addr6); - - for (i = 0; i < peer->allowed_ips_len; i++) - _wireguard_allowed_ip_hash_update (&peer->allowed_ips[i], h); -} - -static int -_wireguard_peer_cmp (const NMPWireGuardPeer *a, - const NMPWireGuardPeer *b) -{ - guint i; - - NM_CMP_SELF (a, b); - - NM_CMP_FIELD (a, b, last_handshake_time.tv_sec); - NM_CMP_FIELD (a, b, last_handshake_time.tv_nsec); - NM_CMP_FIELD (a, b, rx_bytes); - NM_CMP_FIELD (a, b, tx_bytes); - NM_CMP_FIELD (a, b, allowed_ips_len); - NM_CMP_FIELD (a, b, persistent_keepalive_interval); - NM_CMP_FIELD (a, b, endpoint_port); - NM_CMP_FIELD (a, b, endpoint_family); - NM_CMP_FIELD_MEMCMP (a, b, public_key); - NM_CMP_FIELD_MEMCMP (a, b, preshared_key); - - if (a->endpoint_family == AF_INET) - NM_CMP_FIELD (a, b, endpoint_addr.addr4); - else if (a->endpoint_family == AF_INET6) - NM_CMP_FIELD_IN6ADDR (a, b, endpoint_addr.addr6); - - for (i = 0; i < a->allowed_ips_len; i++) { - NM_CMP_RETURN (_wireguard_allowed_ip_cmp (&a->allowed_ips[i], - &b->allowed_ips[i])); - } - - return 0; -} - -/*****************************************************************************/ - static const char * _link_get_driver (struct udev_device *udevice, const char *kind, int ifindex) { @@ -551,7 +456,6 @@ _vt_cmd_obj_dispose_link (NMPObject *obj) udev_device_unref (obj->_link.udev.device); obj->_link.udev.device = NULL; } - g_clear_object (&obj->_link.ext_data); nmp_object_unref (obj->_link.netlink.lnk); } @@ -562,28 +466,6 @@ _vt_cmd_obj_dispose_lnk_vlan (NMPObject *obj) g_free ((gpointer) obj->_lnk_vlan.egress_qos_map); } -static void -_wireguard_clear (NMPObjectLnkWireGuard *lnk) -{ - guint i; - - nm_explicit_bzero (lnk->_public.private_key, - sizeof (lnk->_public.private_key)); - for (i = 0; i < lnk->peers_len; i++) { - NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &lnk->peers[i]; - - nm_explicit_bzero (peer->preshared_key, sizeof (peer->preshared_key)); - } - g_free ((gpointer) lnk->peers); - g_free ((gpointer) lnk->_allowed_ips_buf); -} - -static void -_vt_cmd_obj_dispose_lnk_wireguard (NMPObject *obj) -{ - _wireguard_clear (&obj->_lnk_wireguard); -} - static NMPObject * _nmp_object_new_from_class (const NMPClass *klass) { @@ -749,35 +631,31 @@ static const char * _vt_cmd_obj_to_string_link (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size) { const NMPClass *klass = NMP_OBJECT_GET_CLASS (obj); - char *b = buf; + char buf2[sizeof (_nm_utils_to_string_buffer)]; + char buf3[sizeof (_nm_utils_to_string_buffer)]; switch (to_string_mode) { case NMP_OBJECT_TO_STRING_ID: return klass->cmd_plobj_to_string_id (&obj->object, buf, buf_size); case NMP_OBJECT_TO_STRING_ALL: - nm_utils_strbuf_append (&b, &buf_size, - "[%s,%p,%u,%calive,%cvisible,%cin-nl,%p; ", - klass->obj_type_name, obj, obj->parent._ref_count, - nmp_object_is_alive (obj) ? '+' : '-', - nmp_object_is_visible (obj) ? '+' : '-', - obj->_link.netlink.is_in_netlink ? '+' : '-', - obj->_link.udev.device); - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, b, buf_size); - nm_utils_strbuf_seek_end (&b, &buf_size); - if (obj->_link.netlink.lnk) { - nm_utils_strbuf_append_str (&b, &buf_size, "; "); - nmp_object_to_string (obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_ALL, b, buf_size); - nm_utils_strbuf_seek_end (&b, &buf_size); - } - nm_utils_strbuf_append_c (&b, &buf_size, ']'); + g_snprintf (buf, buf_size, + "[%s,%p,%u,%calive,%cvisible,%cin-nl,%p; %s]", + klass->obj_type_name, obj, obj->parent._ref_count, + nmp_object_is_alive (obj) ? '+' : '-', + nmp_object_is_visible (obj) ? '+' : '-', + obj->_link.netlink.is_in_netlink ? '+' : '-', + obj->_link.udev.device, + nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof (buf2))); return buf; case NMP_OBJECT_TO_STRING_PUBLIC: - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, b, buf_size); if (obj->_link.netlink.lnk) { - nm_utils_strbuf_seek_end (&b, &buf_size); - nm_utils_strbuf_append_str (&b, &buf_size, "; "); - nmp_object_to_string (obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_PUBLIC, b, buf_size); - } + NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, buf2, sizeof (buf2)); + nmp_object_to_string (obj->_link.netlink.lnk, NMP_OBJECT_TO_STRING_PUBLIC, buf3, sizeof (buf3)); + g_snprintf (buf, buf_size, + "%s; %s", + buf2, buf3); + } else + NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, buf, buf_size); return buf; default: g_return_val_if_reached ("ERROR"); @@ -842,55 +720,6 @@ _vt_cmd_obj_to_string_lnk_vlan (const NMPObject *obj, NMPObjectToStringMode to_s } } -static const char * -_vt_cmd_obj_to_string_lnk_wireguard (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size) -{ - const NMPClass *klass; - char buf2[sizeof (_nm_utils_to_string_buffer)]; - char *b; - guint i; - - klass = NMP_OBJECT_GET_CLASS (obj); - - switch (to_string_mode) { - case NMP_OBJECT_TO_STRING_ID: - g_snprintf (buf, buf_size, "%p", obj); - return buf; - case NMP_OBJECT_TO_STRING_ALL: - b = buf; - - nm_utils_strbuf_append (&b, &buf_size, - "[%s,%p,%u,%calive,%cvisible; %s" - "%s", - klass->obj_type_name, obj, obj->parent._ref_count, - nmp_object_is_alive (obj) ? '+' : '-', - nmp_object_is_visible (obj) ? '+' : '-', - nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof (buf2)), - obj->_lnk_wireguard.peers_len > 0 - ? " peers {" - : ""); - - for (i = 0; i < obj->_lnk_wireguard.peers_len; i++) { - const NMPWireGuardPeer *peer = &obj->_lnk_wireguard.peers[i]; - - nm_utils_strbuf_append_str (&b, &buf_size, " { "); - nm_platform_wireguard_peer_to_string (peer, b, buf_size); - nm_utils_strbuf_seek_end (&b, &buf_size); - nm_utils_strbuf_append_str (&b, &buf_size, " }"); - } - if (obj->_lnk_wireguard.peers_len) - nm_utils_strbuf_append_str (&b, &buf_size, " }"); - - return buf; - case NMP_OBJECT_TO_STRING_PUBLIC: - NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, buf, buf_size); - - return buf; - default: - g_return_val_if_reached ("ERROR"); - } -} - #define _vt_cmd_plobj_to_string_id(type, plat_type, ...) \ static const char * \ _vt_cmd_plobj_to_string_id_##type (const NMPlatformObject *_obj, char *buf, gsize buf_len) \ @@ -939,7 +768,6 @@ _vt_cmd_obj_hash_update_link (const NMPObject *obj, NMHashState *h) nm_platform_link_hash_update (&obj->link, h); nm_hash_update_vals (h, obj->_link.netlink.is_in_netlink, - obj->_link.wireguard_family_id, obj->_link.udev.device); if (obj->_link.netlink.lnk) nmp_object_hash_update (obj->_link.netlink.lnk, h); @@ -959,26 +787,17 @@ _vt_cmd_obj_hash_update_lnk_vlan (const NMPObject *obj, NMHashState *h) h); } -static void -_vt_cmd_obj_hash_update_lnk_wireguard (const NMPObject *obj, NMHashState *h) -{ - guint i; - - nm_assert (NMP_OBJECT_GET_TYPE (obj) == NMP_OBJECT_TYPE_LNK_WIREGUARD); - - nm_platform_lnk_wireguard_hash_update (&obj->lnk_wireguard, h); - - nm_hash_update_val (h, obj->_lnk_wireguard.peers_len); - for (i = 0; i < obj->_lnk_wireguard.peers_len; i++) - _wireguard_peer_hash_update (&obj->_lnk_wireguard.peers[i], h); -} - int nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2) { const NMPClass *klass1, *klass2; - NM_CMP_SELF (obj1, obj2); + if (obj1 == obj2) + return 0; + if (!obj1) + return -1; + if (!obj2) + return 1; g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj1), -1); g_return_val_if_fail (NMP_OBJECT_IS_VALID (obj2), 1); @@ -999,11 +818,16 @@ nmp_object_cmp (const NMPObject *obj1, const NMPObject *obj2) static int _vt_cmd_obj_cmp_link (const NMPObject *obj1, const NMPObject *obj2) { - NM_CMP_RETURN (nm_platform_link_cmp (&obj1->link, &obj2->link)); - NM_CMP_DIRECT (obj1->_link.netlink.is_in_netlink, obj2->_link.netlink.is_in_netlink); - NM_CMP_RETURN (nmp_object_cmp (obj1->_link.netlink.lnk, obj2->_link.netlink.lnk)); - NM_CMP_DIRECT (obj1->_link.wireguard_family_id, obj2->_link.wireguard_family_id); + int i; + i = nm_platform_link_cmp (&obj1->link, &obj2->link); + if (i) + return i; + if (obj1->_link.netlink.is_in_netlink != obj2->_link.netlink.is_in_netlink) + return obj1->_link.netlink.is_in_netlink ? -1 : 1; + i = nmp_object_cmp (obj1->_link.netlink.lnk, obj2->_link.netlink.lnk); + if (i) + return i; if (obj1->_link.udev.device != obj2->_link.udev.device) { if (!obj1->_link.udev.device) return -1; @@ -1016,7 +840,6 @@ _vt_cmd_obj_cmp_link (const NMPObject *obj1, const NMPObject *obj2) * Have this check as very last. */ return (obj1->_link.udev.device < obj2->_link.udev.device) ? -1 : 1; } - return 0; } @@ -1042,21 +865,6 @@ _vt_cmd_obj_cmp_lnk_vlan (const NMPObject *obj1, const NMPObject *obj2) return c; } -static int -_vt_cmd_obj_cmp_lnk_wireguard (const NMPObject *obj1, const NMPObject *obj2) -{ - guint i; - - NM_CMP_RETURN (nm_platform_lnk_wireguard_cmp (&obj1->lnk_wireguard, &obj2->lnk_wireguard)); - - NM_CMP_FIELD (obj1, obj2, _lnk_wireguard.peers_len); - - for (i = 0; i < obj1->_lnk_wireguard.peers_len; i++) - NM_CMP_RETURN (_wireguard_peer_cmp (&obj1->_lnk_wireguard.peers[i], &obj2->_lnk_wireguard.peers[i])); - - return 0; -} - /* @src is a const object, which is not entirely correct for link types, where * we increase the ref count for src->_link.udev.device. * Hence, nmp_object_copy() can violate the const promise of @src. @@ -1100,12 +908,6 @@ _vt_cmd_obj_copy_link (NMPObject *dst, const NMPObject *src) nmp_object_unref (dst->_link.netlink.lnk); dst->_link.netlink.lnk = src->_link.netlink.lnk; } - if (dst->_link.ext_data != src->_link.ext_data) { - if (dst->_link.ext_data) - g_clear_object (&dst->_link.ext_data); - if (src->_link.ext_data) - dst->_link.ext_data = g_object_ref (src->_link.ext_data); - } dst->_link = src->_link; } @@ -1123,41 +925,6 @@ _vt_cmd_obj_copy_lnk_vlan (NMPObject *dst, const NMPObject *src) src->_lnk_vlan.egress_qos_map); } -static void -_vt_cmd_obj_copy_lnk_wireguard (NMPObject *dst, const NMPObject *src) -{ - guint i; - - nm_assert (dst != src); - - _wireguard_clear (&dst->_lnk_wireguard); - - dst->_lnk_wireguard = src->_lnk_wireguard; - - dst->_lnk_wireguard.peers = nm_memdup (dst->_lnk_wireguard.peers, - sizeof (NMPWireGuardPeer) * dst->_lnk_wireguard.peers_len); - dst->_lnk_wireguard._allowed_ips_buf = nm_memdup (dst->_lnk_wireguard._allowed_ips_buf, - sizeof (NMPWireGuardAllowedIP) * dst->_lnk_wireguard._allowed_ips_buf_len); - - /* all the peers' pointers point into the buffer. They need to be readjusted. */ - for (i = 0; i < dst->_lnk_wireguard.peers_len; i++) { - NMPWireGuardPeer *peer = (NMPWireGuardPeer *) &dst->_lnk_wireguard.peers[i]; - - if (peer->allowed_ips_len == 0) { - nm_assert (!peer->allowed_ips); - continue; - } - nm_assert (dst->_lnk_wireguard._allowed_ips_buf_len > 0); - nm_assert (src->_lnk_wireguard._allowed_ips_buf); - nm_assert (peer->allowed_ips >= src->_lnk_wireguard._allowed_ips_buf); - nm_assert (&peer->allowed_ips[peer->allowed_ips_len] <= &src->_lnk_wireguard._allowed_ips_buf[src->_lnk_wireguard._allowed_ips_buf_len]); - - peer->allowed_ips = &dst->_lnk_wireguard._allowed_ips_buf[peer->allowed_ips - src->_lnk_wireguard._allowed_ips_buf]; - } - - nm_assert (nmp_object_equal (src, dst)); -} - #define _vt_cmd_plobj_id_copy(type, plat_type, cmd) \ static void \ _vt_cmd_plobj_id_copy_##type (NMPlatformObject *_dst, const NMPlatformObject *_src) \ @@ -2935,17 +2702,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_gre_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_gre_cmp, }, - [NMP_OBJECT_TYPE_LNK_GRETAP - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_GRETAP, - .sizeof_data = sizeof (NMPObjectLnkGre), - .sizeof_public = sizeof (NMPlatformLnkGre), - .obj_type_name = "gretap", - .lnk_link_type = NM_LINK_TYPE_GRETAP, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_gre_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_gre_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_gre_cmp, - }, [NMP_OBJECT_TYPE_LNK_INFINIBAND - 1] = { .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), .obj_type = NMP_OBJECT_TYPE_LNK_INFINIBAND, @@ -2968,28 +2724,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ip6tnl_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ip6tnl_cmp, }, - [NMP_OBJECT_TYPE_LNK_IP6GRE - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_IP6GRE, - .sizeof_data = sizeof (NMPObjectLnkIp6Tnl), - .sizeof_public = sizeof (NMPlatformLnkIp6Tnl), - .obj_type_name = "ip6gre", - .lnk_link_type = NM_LINK_TYPE_IP6GRE, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ip6tnl_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ip6tnl_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ip6tnl_cmp, - }, - [NMP_OBJECT_TYPE_LNK_IP6GRETAP - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_IP6GRETAP, - .sizeof_data = sizeof (NMPObjectLnkIp6Tnl), - .sizeof_public = sizeof (NMPlatformLnkIp6Tnl), - .obj_type_name = "ip6gretap", - .lnk_link_type = NM_LINK_TYPE_IP6GRETAP, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_ip6tnl_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_ip6tnl_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_ip6tnl_cmp, - }, [NMP_OBJECT_TYPE_LNK_IPIP - 1] = { .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), .obj_type = NMP_OBJECT_TYPE_LNK_IPIP, @@ -3083,20 +2817,5 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vxlan_hash_update, .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vxlan_cmp, }, - [NMP_OBJECT_TYPE_LNK_WIREGUARD - 1] = { - .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), - .obj_type = NMP_OBJECT_TYPE_LNK_WIREGUARD, - .sizeof_data = sizeof (NMPObjectLnkWireGuard), - .sizeof_public = sizeof (NMPlatformLnkWireGuard), - .obj_type_name = "wireguard", - .lnk_link_type = NM_LINK_TYPE_WIREGUARD, - .cmd_obj_hash_update = _vt_cmd_obj_hash_update_lnk_wireguard, - .cmd_obj_cmp = _vt_cmd_obj_cmp_lnk_wireguard, - .cmd_obj_copy = _vt_cmd_obj_copy_lnk_wireguard, - .cmd_obj_dispose = _vt_cmd_obj_dispose_lnk_wireguard, - .cmd_obj_to_string = _vt_cmd_obj_to_string_lnk_wireguard, - .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_wireguard_to_string, - .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vlan_hash_update, - .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vlan_cmp, - }, }; + diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 97be8321..f473f462 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2015 - 2018 Red Hat, Inc. + * Copyright (C) 2015 - 2017 Red Hat, Inc. */ #ifndef __NMP_OBJECT_H__ @@ -27,36 +27,6 @@ struct udev_device; -/*****************************************************************************/ - -typedef struct { - NMIPAddr addr; - guint8 family; - guint8 mask; -} NMPWireGuardAllowedIP; - -typedef struct _NMPWireGuardPeer { - NMIPAddr endpoint_addr; - struct timespec last_handshake_time; - guint64 rx_bytes; - guint64 tx_bytes; - union { - const NMPWireGuardAllowedIP *allowed_ips; - guint _construct_idx_start; - }; - union { - guint allowed_ips_len; - guint _construct_idx_end; - }; - guint16 persistent_keepalive_interval; - guint16 endpoint_port; - guint8 public_key[NMP_WIREGUARD_PUBLIC_KEY_LEN]; - guint8 preshared_key[NMP_WIREGUARD_SYMMETRIC_KEY_LEN]; - guint8 endpoint_family; -} NMPWireGuardPeer; - -/*****************************************************************************/ - typedef enum { /*< skip >*/ NMP_OBJECT_TO_STRING_ID, NMP_OBJECT_TO_STRING_PUBLIC, @@ -194,14 +164,6 @@ typedef struct { */ struct udev_device *device; } udev; - - /* Auxiliary data object for Wi-Fi and WPAN */ - GObject *ext_data; - - /* FIXME: not every NMPObjectLink should pay the price for tracking - * the wireguard family id. This should be tracked via ext_data, which - * would be exactly the right place. */ - int wireguard_family_id; } NMPObjectLink; typedef struct { @@ -252,14 +214,6 @@ typedef struct { } NMPObjectLnkVxlan; typedef struct { - NMPlatformLnkWireGuard _public; - const NMPWireGuardPeer *peers; - const NMPWireGuardAllowedIP *_allowed_ips_buf; - guint peers_len; - guint _allowed_ips_buf_len; -} NMPObjectLnkWireGuard; - -typedef struct { NMPlatformIP4Address _public; } NMPObjectIP4Address; @@ -324,9 +278,6 @@ struct _NMPObject { NMPlatformLnkVxlan lnk_vxlan; NMPObjectLnkVxlan _lnk_vxlan; - NMPlatformLnkWireGuard lnk_wireguard; - NMPObjectLnkWireGuard _lnk_wireguard; - NMPlatformIPAddress ip_address; NMPlatformIPXAddress ipx_address; NMPlatformIP4Address ip4_address; diff --git a/src/platform/tests/test-cleanup.c b/src/platform/tests/test-cleanup.c index 12d91812..8b8c87d8 100644 --- a/src/platform/tests/test-cleanup.c +++ b/src/platform/tests/test-cleanup.c @@ -60,7 +60,7 @@ test_cleanup_internal (void) g_assert (ifindex > 0); /* wait for kernel to add the IPv6 link local address... it takes a bit. */ - NMTST_WAIT_ASSERT (300, { + NMTST_WAIT_ASSERT (100, { gs_unref_array GArray *addrs = NULL; const NMPlatformIP6Address *a; diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 3dedbd10..42569d5b 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -1243,29 +1243,21 @@ nmtstp_link_gre_add (NMPlatform *platform, const NMPlatformLink *pllink = NULL; gboolean success; char buffer[INET_ADDRSTRLEN]; - NMLinkType link_type; g_assert (nm_utils_is_valid_iface_name (name, NULL)); external_command = nmtstp_run_command_check_external (external_command); - link_type = lnk->is_tap ? NM_LINK_TYPE_GRETAP : NM_LINK_TYPE_GRE; _init_platform (&platform, external_command); if (external_command) { gs_free char *dev = NULL; - char *obj, *type; if (lnk->parent_ifindex) dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); - obj = lnk->is_tap ? "link" : "tunnel"; - type = lnk->is_tap ? "type gretap" : "mode gre"; - - success = !nmtstp_run_command ("ip %s add %s %s %s local %s remote %s ttl %u tos %02x %s", - obj, + success = !nmtstp_run_command ("ip tunnel add %s mode gre %s local %s remote %s ttl %u tos %02x %s", name, - type, dev ?: "", nm_utils_inet4_ntop (lnk->local, NULL), nm_utils_inet4_ntop (lnk->remote, buffer), @@ -1273,11 +1265,11 @@ nmtstp_link_gre_add (NMPlatform *platform, lnk->tos, lnk->path_mtu_discovery ? "pmtudisc" : "nopmtudisc"); if (success) - pllink = nmtstp_assert_wait_for_link (platform, name, link_type, 100); + pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_GRE, 100); } else success = nm_platform_link_gre_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; - _assert_pllink (platform, success, pllink, name, link_type); + _assert_pllink (platform, success, pllink, name, NM_LINK_TYPE_GRE); return pllink; } @@ -1297,7 +1289,6 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform, gboolean tclass_inherit; g_assert (nm_utils_is_valid_iface_name (name, NULL)); - g_assert (!lnk->is_gre); external_command = nmtstp_run_command_check_external (external_command); @@ -1345,56 +1336,6 @@ nmtstp_link_ip6tnl_add (NMPlatform *platform, } const NMPlatformLink * -nmtstp_link_ip6gre_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIp6Tnl *lnk) -{ - const NMPlatformLink *pllink = NULL; - gboolean success; - char buffer[INET6_ADDRSTRLEN]; - char tclass[20]; - gboolean tclass_inherit; - - g_assert (nm_utils_is_valid_iface_name (name, NULL)); - g_assert (lnk->is_gre); - - external_command = nmtstp_run_command_check_external (external_command); - - _init_platform (&platform, external_command); - - if (external_command) { - gs_free char *dev = NULL; - - if (lnk->parent_ifindex) - dev = g_strdup_printf ("dev %s", nm_platform_link_get_name (platform, lnk->parent_ifindex)); - - tclass_inherit = NM_FLAGS_HAS (lnk->flags, IP6_TNL_F_USE_ORIG_TCLASS); - - success = !nmtstp_run_command ("ip link add %s type %s %s local %s remote %s ttl %u tclass %s flowlabel %x", - name, - lnk->is_tap ? "ip6gretap" : "ip6gre", - dev, - nm_utils_inet6_ntop (&lnk->local, NULL), - nm_utils_inet6_ntop (&lnk->remote, buffer), - lnk->ttl, - tclass_inherit ? "inherit" : nm_sprintf_buf (tclass, "%02x", lnk->tclass), - lnk->flow_label); - if (success) { - pllink = nmtstp_assert_wait_for_link (platform, - name, - lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE, - 100); - } - } else - success = nm_platform_link_ip6gre_add (platform, name, lnk, &pllink) == NM_PLATFORM_ERROR_SUCCESS; - - _assert_pllink (platform, success, pllink, name, lnk->is_tap ? NM_LINK_TYPE_IP6GRETAP : NM_LINK_TYPE_IP6GRE); - - return pllink; -} - -const NMPlatformLink * nmtstp_link_ipip_add (NMPlatform *platform, gboolean external_command, const char *name, diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 1baadfa1..bd02b0d7 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -80,7 +80,7 @@ typedef struct { gulong handler_id; const char *name; NMPlatformSignalChangeType change_type; - int received_count; + gint received_count; GMainLoop *loop; int ifindex; const char *ifname; @@ -297,10 +297,6 @@ const NMPlatformLink *nmtstp_link_ip6tnl_add (NMPlatform *platform, gboolean external_command, const char *name, const NMPlatformLnkIp6Tnl *lnk); -const NMPlatformLink *nmtstp_link_ip6gre_add (NMPlatform *platform, - gboolean external_command, - const char *name, - const NMPlatformLnkIp6Tnl *lnk); const NMPlatformLink *nmtstp_link_ipip_add (NMPlatform *platform, gboolean external_command, const char *name, diff --git a/src/platform/tests/test-general.c b/src/platform/tests/test-general.c index eebc15d8..8708c80f 100644 --- a/src/platform/tests/test-general.c +++ b/src/platform/tests/test-general.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2015 - 2018 Red Hat, Inc. + * Copyright (C) 2015 Red Hat, Inc. */ #include "nm-default.h" @@ -57,7 +57,7 @@ NMTST_DEFINE (); int main (int argc, char **argv) { - nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT"); + nmtst_init_assert_logging (&argc, &argv, "INFO", "DEFAULT"); g_test_add_func ("/general/init_linux_platform", test_init_linux_platform); g_test_add_func ("/general/link_get_all", test_link_get_all); diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 057490c4..cd5880e3 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -25,7 +25,6 @@ #include <sys/types.h> #include <linux/if_tun.h> -#include "nm-utils/nm-io-utils.h" #include "platform/nmp-object.h" #include "platform/nmp-netns.h" #include "platform/nm-platform-utils.h" @@ -700,7 +699,6 @@ test_software_detect (gconstpointer user_data) guint i_step; const gboolean ext = test_data->external_command; NMPlatformLnkTun lnk_tun; - NMPlatformLnkGre lnk_gre = { }; nm_auto_close int tun_fd = -1; nmtstp_run_command_check ("ip link add %s type dummy", PARENT_NAME); @@ -708,6 +706,7 @@ test_software_detect (gconstpointer user_data) switch (test_data->link_type) { case NM_LINK_TYPE_GRE: { + NMPlatformLnkGre lnk_gre = { }; gboolean gracefully_skip = FALSE; lnk_gre.local = nmtst_inet4_from_string ("192.168.233.204"); @@ -731,31 +730,6 @@ test_software_detect (gconstpointer user_data) } break; } - case NM_LINK_TYPE_GRETAP: { - gboolean gracefully_skip = FALSE; - - lnk_gre.local = nmtst_inet4_from_string ("192.168.1.133"); - lnk_gre.remote = nmtst_inet4_from_string ("172.168.101.2"); - lnk_gre.parent_ifindex = ifindex_parent; - lnk_gre.ttl = 39; - lnk_gre.tos = 12; - lnk_gre.path_mtu_discovery = FALSE; - lnk_gre.is_tap = TRUE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "gretap0")) { - /* Seems that the ip_gre module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip_gre", NULL) != 0; - } - - if (!nmtstp_link_gre_add (NULL, ext, DEVICE_NAME, &lnk_gre)) { - if (gracefully_skip) { - g_test_skip ("Cannot create gretap tunnel because of missing ip_gre module (modprobe ip_gre)"); - goto out_delete_parent; - } - g_error ("Failed adding GRETAP tunnel"); - } - break; - } case NM_LINK_TYPE_IPIP: { NMPlatformLnkIpIp lnk_ipip = { }; gboolean gracefully_skip = FALSE; @@ -820,58 +794,6 @@ test_software_detect (gconstpointer user_data) } break; } - case NM_LINK_TYPE_IP6GRE: { - NMPlatformLnkIp6Tnl lnk_ip6tnl = { }; - gboolean gracefully_skip = FALSE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "ip6gre0")) { - /* Seems that the ip6_tunnel module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_gre", NULL) != 0; - } - - lnk_ip6tnl.local = *nmtst_inet6_from_string ("fd01::42"); - lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fd01::aaaa"); - lnk_ip6tnl.parent_ifindex = ifindex_parent; - lnk_ip6tnl.tclass = 21; - lnk_ip6tnl.flow_label = 1338; - lnk_ip6tnl.is_gre = TRUE; - - if (!nmtstp_link_ip6gre_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) { - if (gracefully_skip) { - g_test_skip ("Cannot create ip6gre tunnel because of missing ip6_gre module (modprobe ip6_gre)"); - goto out_delete_parent; - } - g_error ("Failed adding IP6GRE tunnel"); - } - break; - } - case NM_LINK_TYPE_IP6GRETAP: { - NMPlatformLnkIp6Tnl lnk_ip6tnl = { }; - gboolean gracefully_skip = FALSE; - - if (!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "ip6gre0")) { - /* Seems that the ip6_tunnel module is not loaded... try to load it. */ - gracefully_skip = nm_utils_modprobe (NULL, TRUE, "ip6_gre", NULL) != 0; - } - - lnk_ip6tnl.local = *nmtst_inet6_from_string ("fe80::abcd"); - lnk_ip6tnl.remote = *nmtst_inet6_from_string ("fc01::bbbb"); - lnk_ip6tnl.parent_ifindex = ifindex_parent; - lnk_ip6tnl.ttl = 10; - lnk_ip6tnl.tclass = 22; - lnk_ip6tnl.flow_label = 1339; - lnk_ip6tnl.is_gre = TRUE; - lnk_ip6tnl.is_tap = TRUE; - - if (!nmtstp_link_ip6gre_add (NULL, ext, DEVICE_NAME, &lnk_ip6tnl)) { - if (gracefully_skip) { - g_test_skip ("Cannot create ip6gretap tunnel because of missing ip6_gre module (modprobe ip6_gre)"); - goto out_delete_parent; - } - g_error ("Failed adding IP6GRETAP tunnel"); - } - break; - } case NM_LINK_TYPE_MACVLAN: { NMPlatformLnkMacvlan lnk_macvlan = { }; const NMPlatformLink *dummy; @@ -1048,15 +970,16 @@ test_software_detect (gconstpointer user_data) const NMPlatformLnkGre *plnk = &lnk->lnk_gre; g_assert (plnk == nm_platform_link_get_lnk_gre (NM_PLATFORM_GET, ifindex, NULL)); - g_assert (nm_platform_lnk_gre_cmp (plnk, &lnk_gre) == 0); - - break; - } - case NM_LINK_TYPE_GRETAP: { - const NMPlatformLnkGre *plnk = &lnk->lnk_gre; - - g_assert (plnk == nm_platform_link_get_lnk_gretap (NM_PLATFORM_GET, ifindex, NULL)); - g_assert (nm_platform_lnk_gre_cmp (plnk, &lnk_gre) == 0); + g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); + g_assert_cmpint (plnk->input_flags, ==, 0); + g_assert_cmpint (plnk->output_flags, ==, 0); + g_assert_cmpint (plnk->input_key, ==, 0); + g_assert_cmpint (plnk->output_key, ==, 0); + nmtst_assert_ip4_address (plnk->local, "192.168.233.204"); + nmtst_assert_ip4_address (plnk->remote, "172.168.10.25"); + g_assert_cmpint (plnk->ttl, ==, 174); + g_assert_cmpint (plnk->tos, ==, 37); + g_assert_cmpint (plnk->path_mtu_discovery, ==, TRUE); break; } case NM_LINK_TYPE_IP6TNL: { @@ -1089,33 +1012,6 @@ test_software_detect (gconstpointer user_data) } break; } - case NM_LINK_TYPE_IP6GRE: { - const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl; - - g_assert (plnk == nm_platform_link_get_lnk_ip6gre (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); - nmtst_assert_ip6_address (&plnk->local, "fd01::42"); - nmtst_assert_ip6_address (&plnk->remote, "fd01::aaaa"); - g_assert_cmpint (plnk->tclass, ==, 21); - g_assert_cmpint (plnk->flow_label, ==, 1338); - g_assert_cmpint (plnk->is_gre, ==, TRUE); - g_assert_cmpint (plnk->is_tap, ==, FALSE); - break; - } - case NM_LINK_TYPE_IP6GRETAP: { - const NMPlatformLnkIp6Tnl *plnk = &lnk->lnk_ip6tnl; - - g_assert (plnk == nm_platform_link_get_lnk_ip6gretap (NM_PLATFORM_GET, ifindex, NULL)); - g_assert_cmpint (plnk->parent_ifindex, ==, ifindex_parent); - nmtst_assert_ip6_address (&plnk->local, "fe80::abcd"); - nmtst_assert_ip6_address (&plnk->remote, "fc01::bbbb"); - g_assert_cmpint (plnk->ttl, ==, 10); - g_assert_cmpint (plnk->tclass, ==, 22); - g_assert_cmpint (plnk->flow_label, ==, 1339); - g_assert_cmpint (plnk->is_gre, ==, TRUE); - g_assert_cmpint (plnk->is_tap, ==, TRUE); - break; - } case NM_LINK_TYPE_IPIP: { const NMPlatformLnkIpIp *plnk = &lnk->lnk_ipip; @@ -1836,7 +1732,7 @@ test_create_many_links_do (guint n_devices) char name[64]; const NMPlatformLink *pllink; gs_unref_array GArray *ifindexes = g_array_sized_new (FALSE, FALSE, sizeof (int), n_devices); - const int EX = ((int) (nmtst_get_rand_int () % 4)) - 1; + const gint EX = ((int) (nmtst_get_rand_int () % 4)) - 1; g_assert (EX >= -1 && EX <= 2); @@ -2623,9 +2519,7 @@ test_sysctl_rename (void) case 0: { gs_free char *c = NULL; - if (nm_utils_file_get_contents (dirfd, "ifindex", 1*1024*1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &c, NULL, NULL) < 0) + if (nm_utils_file_get_contents (dirfd, "ifindex", 1*1024*1024, &c, NULL, NULL) < 0) g_assert_not_reached(); g_assert_cmpint (ifindex[0], ==, (int) _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -1)); break; @@ -2689,9 +2583,7 @@ test_sysctl_netns_switch (void) { gs_free char *c = NULL; - if (nm_utils_file_get_contents (dirfd, "ifindex", 0, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &c, NULL, NULL) < 0) + if (nm_utils_file_get_contents (dirfd, "ifindex", 0, &c, NULL, NULL) < 0) g_assert_not_reached(); g_assert_cmpint (ifindex, ==, (int) _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -1)); } @@ -2703,11 +2595,7 @@ test_sysctl_netns_switch (void) { gs_free char *c = NULL; - if (nm_utils_file_get_contents (-1, - nm_sprintf_bufa (100, "/sys/class/net/%s/ifindex", IFNAME), - 0, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, - &c, NULL, NULL) < 0) + if (nm_utils_file_get_contents (-1, nm_sprintf_bufa (100, "/sys/class/net/%s/ifindex", IFNAME), 0, &c, NULL, NULL) < 0) ifindex_tmp = -1; else ifindex_tmp = _nm_utils_ascii_str_to_int64 (c, 10, 0, G_MAXINT, -2); @@ -2722,102 +2610,6 @@ test_sysctl_netns_switch (void) /*****************************************************************************/ -static void -ethtool_features_dump (const NMEthtoolFeatureStates *features) -{ - guint i, j; - - g_assert (features); - - _LOGT (">>> %u features (%u ss-features)", features->n_states, features->n_ss_features); - - for (i = 0; i < features->n_states; i++) { - const NMEthtoolFeatureState *s = &features->states_list[i]; - - _LOGT (">>> feature-list[%3u]: %3d = %-32s (%3u) | %s %s %s %s", - i, - (int) s->info->ethtool_id, - s->info->kernel_names[s->idx_kernel_name], - s->idx_ss_features, - s->active ? "ACT" : "act", - s->available ? "AVA" : "ava", - s->never_changed ? "NCH" : "nch", - s->requested ? "REQ" : "req"); - } - for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) { - _LOGT (">>> feature-idx [%3u]: %-32s = %u features", - i + (guint) _NM_ETHTOOL_ID_FEATURE_FIRST, - nm_ethtool_data[i + _NM_ETHTOOL_ID_FEATURE_FIRST]->optname, - (guint) NM_PTRARRAY_LEN (features->states_indexed[i])); - for (j = 0; features->states_indexed[i] && features->states_indexed[i][j]; j++) { - const NMEthtoolFeatureState *s = features->states_indexed[i][j]; - - _LOGT (">>> %3u: %-32s | %s %s %s %s", - j, - s->info->kernel_names[s->idx_kernel_name], - s->active ? "ACT" : "act", - s->available ? "AVA" : "ava", - s->never_changed ? "NCH" : "nch", - s->requested ? "REQ" : "req"); - } - } -} - -static void -test_ethtool_features_get (void) -{ - gs_unref_ptrarray GPtrArray *gfree_keeper = g_ptr_array_new_with_free_func (g_free); - const int IFINDEX = 1; - guint i; - guint i_run; - - for (i_run = 0; i_run < 5; i_run++) { - NMEthtoolFeatureStates *features; - NMTernary *requested; - gboolean do_set = TRUE; - - requested = g_new (NMTernary, _NM_ETHTOOL_ID_FEATURE_NUM); - for (i = 0; i < _NM_ETHTOOL_ID_FEATURE_NUM; i++) - requested[i] = NM_TERNARY_DEFAULT; - g_ptr_array_add (gfree_keeper, requested); - - if (i_run == 0) { - requested[NM_ETHTOOL_ID_FEATURE_RX] = NM_TERNARY_FALSE; - requested[NM_ETHTOOL_ID_FEATURE_TSO] = NM_TERNARY_FALSE; - requested[NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION] = NM_TERNARY_FALSE; - } else if (i_run == 1) - do_set = FALSE; - else if (i_run == 2) { - requested[NM_ETHTOOL_ID_FEATURE_TSO] = NM_TERNARY_FALSE; - requested[NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION] = NM_TERNARY_TRUE; - } else if (i_run == 3) - do_set = FALSE; - - _LOGT (">>> ethtool-features-get RUN %u (do-set=%s", i_run, do_set ? "set" : "reset"); - - features = nmp_utils_ethtool_get_features (IFINDEX); - g_ptr_array_add (gfree_keeper, features); - - ethtool_features_dump (features); - - if (_LOGT_ENABLED ()) { - int ignore; - - ignore = system ("ethtool -k lo"); - (void) ignore; - } - - if (!do_set) { - requested = gfree_keeper->pdata[i_run * 2 - 2]; - features = gfree_keeper->pdata[i_run * 2 - 1]; - } - - nmp_utils_ethtool_set_features (IFINDEX, features, requested, do_set); - } -} - -/*****************************************************************************/ - NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP; void @@ -2849,11 +2641,8 @@ _nmtstp_setup_tests (void) g_test_add_func ("/link/external", test_external); test_software_detect_add ("/link/software/detect/gre", NM_LINK_TYPE_GRE, 0); - test_software_detect_add ("/link/software/detect/gretap", NM_LINK_TYPE_GRETAP, 0); test_software_detect_add ("/link/software/detect/ip6tnl/0", NM_LINK_TYPE_IP6TNL, 0); test_software_detect_add ("/link/software/detect/ip6tnl/1", NM_LINK_TYPE_IP6TNL, 1); - test_software_detect_add ("/link/software/detect/ip6gre", NM_LINK_TYPE_IP6GRE, 0); - test_software_detect_add ("/link/software/detect/ip6gretap", NM_LINK_TYPE_IP6GRETAP, 0); test_software_detect_add ("/link/software/detect/ipip", NM_LINK_TYPE_IPIP, 0); test_software_detect_add ("/link/software/detect/macvlan", NM_LINK_TYPE_MACVLAN, 0); test_software_detect_add ("/link/software/detect/macvtap", NM_LINK_TYPE_MACVTAP, 0); @@ -2879,7 +2668,5 @@ _nmtstp_setup_tests (void) g_test_add_func ("/general/sysctl/rename", test_sysctl_rename); g_test_add_func ("/general/sysctl/netns-switch", test_sysctl_netns_switch); - - g_test_add_func ("/link/ethtool/features/get", test_ethtool_features_get); } } diff --git a/src/platform/wifi/nm-wifi-utils.c b/src/platform/wifi/nm-wifi-utils.c deleted file mode 100644 index 25d71c6a..00000000 --- a/src/platform/wifi/nm-wifi-utils.c +++ /dev/null @@ -1,240 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2005 - 2018 Red Hat, Inc. - * Copyright (C) 2006 - 2008 Novell, Inc. - */ - -#include "nm-default.h" - -#include "nm-wifi-utils.h" - -#include <sys/stat.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> - -#include "nm-wifi-utils-private.h" -#include "nm-wifi-utils-nl80211.h" -#if HAVE_WEXT -#include "nm-wifi-utils-wext.h" -#endif -#include "nm-core-utils.h" - -#include "platform/nm-platform-utils.h" - -G_DEFINE_ABSTRACT_TYPE (NMWifiUtils, nm_wifi_utils, G_TYPE_OBJECT) - -/*****************************************************************************/ - -static void -nm_wifi_utils_init (NMWifiUtils *self) -{ -} - -static void -nm_wifi_utils_class_init (NMWifiUtilsClass *klass) -{ -} - -NMWifiUtils * -nm_wifi_utils_new (int ifindex, struct nl_sock *genl, gboolean check_scan) -{ - NMWifiUtils *ret; - - g_return_val_if_fail (ifindex > 0, NULL); - - ret = nm_wifi_utils_nl80211_new (ifindex, genl); - -#if HAVE_WEXT - if (ret == NULL) - ret = nm_wifi_utils_wext_new (ifindex, check_scan); -#endif - - return ret; -} - -NMDeviceWifiCapabilities -nm_wifi_utils_get_caps (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, NM_WIFI_DEVICE_CAP_NONE); - - return data->caps; -} - -NM80211Mode -nm_wifi_utils_get_mode (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, NM_802_11_MODE_UNKNOWN); - return NM_WIFI_UTILS_GET_CLASS (data)->get_mode (data); -} - -gboolean -nm_wifi_utils_set_mode (NMWifiUtils *data, const NM80211Mode mode) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail ( (mode == NM_802_11_MODE_INFRA) - || (mode == NM_802_11_MODE_AP) - || (mode == NM_802_11_MODE_ADHOC), FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - - /* nl80211 probably doesn't need this */ - return klass->set_mode ? klass->set_mode (data, mode) : TRUE; -} - -gboolean -nm_wifi_utils_set_powersave (NMWifiUtils *data, guint32 powersave) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - return klass->set_powersave ? klass->set_powersave (data, powersave) : TRUE; -} - -NMSettingWirelessWakeOnWLan -nm_wifi_utils_get_wake_on_wlan (NMWifiUtils *data) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - - return klass->get_wake_on_wlan ? klass->get_wake_on_wlan (data) : NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; -} - -gboolean -nm_wifi_utils_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - return klass->set_wake_on_wlan ? klass->set_wake_on_wlan (data, wowl) : FALSE; -} - -guint32 -nm_wifi_utils_get_freq (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->get_freq (data); -} - -guint32 -nm_wifi_utils_find_freq (NMWifiUtils *data, const guint32 *freqs) -{ - g_return_val_if_fail (data != NULL, 0); - g_return_val_if_fail (freqs != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->find_freq (data, freqs); -} - -gboolean -nm_wifi_utils_get_bssid (NMWifiUtils *data, guint8 *out_bssid) -{ - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (out_bssid != NULL, FALSE); - - memset (out_bssid, 0, ETH_ALEN); - return NM_WIFI_UTILS_GET_CLASS (data)->get_bssid (data, out_bssid); -} - -guint32 -nm_wifi_utils_get_rate (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->get_rate (data); -} - -int -nm_wifi_utils_get_qual (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->get_qual (data); -} - -gboolean -nm_wifi_utils_is_wifi (int dirfd, const char *ifname) -{ - g_return_val_if_fail (dirfd >= 0, FALSE); - - if (faccessat (dirfd, "phy80211", F_OK, 0) == 0) - return TRUE; -#if HAVE_WEXT - if (nm_wifi_utils_wext_is_wifi (ifname)) - return TRUE; -#endif - return FALSE; -} - -/* OLPC Mesh-only functions */ - -guint32 -nm_wifi_utils_get_mesh_channel (NMWifiUtils *data) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - g_return_val_if_fail (klass->get_mesh_channel != NULL, FALSE); - - return klass->get_mesh_channel (data); -} - -gboolean -nm_wifi_utils_set_mesh_channel (NMWifiUtils *data, guint32 channel) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (channel <= 13, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - g_return_val_if_fail (klass->set_mesh_channel != NULL, FALSE); - - return klass->set_mesh_channel (data, channel); -} - -gboolean -nm_wifi_utils_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - g_return_val_if_fail (klass->set_mesh_ssid != NULL, FALSE); - - return klass->set_mesh_ssid (data, ssid, len); -} - -gboolean -nm_wifi_utils_indicate_addressing_running (NMWifiUtils *data, gboolean running) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - return klass->indicate_addressing_running ? klass->indicate_addressing_running (data, running) : FALSE; -} diff --git a/src/platform/wifi/nm-wifi-utils.h b/src/platform/wifi/nm-wifi-utils.h deleted file mode 100644 index 6cd178bd..00000000 --- a/src/platform/wifi/nm-wifi-utils.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2005 - 2018 Red Hat, Inc. - * Copyright (C) 2006 - 2008 Novell, Inc. - */ - -#ifndef __WIFI_UTILS_H__ -#define __WIFI_UTILS_H__ - -#include <net/ethernet.h> - -#include "nm-dbus-interface.h" -#include "nm-setting-wireless.h" -#include "platform/nm-netlink.h" - -typedef struct NMWifiUtils NMWifiUtils; - -#define NM_TYPE_WIFI_UTILS (nm_wifi_utils_get_type ()) -#define NM_WIFI_UTILS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_UTILS, NMWifiUtils)) -#define NM_WIFI_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_UTILS, NMWifiUtilsClass)) -#define NM_IS_WIFI_UTILS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_UTILS)) -#define NM_IS_WIFI_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_UTILS)) -#define NM_WIFI_UTILS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_UTILS, NMWifiUtilsClass)) - -GType nm_wifi_utils_get_type (void); - -gboolean nm_wifi_utils_is_wifi (int dirfd, const char *ifname); - -NMWifiUtils *nm_wifi_utils_new (int ifindex, struct nl_sock *genl, gboolean check_scan); - -NMDeviceWifiCapabilities nm_wifi_utils_get_caps (NMWifiUtils *data); - -NM80211Mode nm_wifi_utils_get_mode (NMWifiUtils *data); - -gboolean nm_wifi_utils_set_mode (NMWifiUtils *data, const NM80211Mode mode); - -/* Returns frequency in MHz */ -guint32 nm_wifi_utils_get_freq (NMWifiUtils *data); - -/* Return the first supported frequency in the zero-terminated list. - * Frequencies are specified in MHz. */ -guint32 nm_wifi_utils_find_freq (NMWifiUtils *data, const guint32 *freqs); - -/* out_bssid must be ETH_ALEN bytes */ -gboolean nm_wifi_utils_get_bssid (NMWifiUtils *data, guint8 *out_bssid); - -/* Returns current bitrate in Kbps */ -guint32 nm_wifi_utils_get_rate (NMWifiUtils *data); - -/* Returns quality 0 - 100% on succes, or -1 on error */ -int nm_wifi_utils_get_qual (NMWifiUtils *data); - -/* Tells the driver DHCP or SLAAC is running */ -gboolean nm_wifi_utils_indicate_addressing_running (NMWifiUtils *data, gboolean running); - -gboolean nm_wifi_utils_set_powersave (NMWifiUtils *data, guint32 powersave); - -NMSettingWirelessWakeOnWLan nm_wifi_utils_get_wake_on_wlan (NMWifiUtils *data); - -gboolean nm_wifi_utils_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl); - -/* OLPC Mesh-only functions */ -guint32 nm_wifi_utils_get_mesh_channel (NMWifiUtils *data); - -gboolean nm_wifi_utils_set_mesh_channel (NMWifiUtils *data, guint32 channel); - -gboolean nm_wifi_utils_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len); - -#endif /* __WIFI_UTILS_H__ */ diff --git a/src/platform/wifi/nm-wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c index b3bb2bb6..6c2ff3f5 100644 --- a/src/platform/wifi/nm-wifi-utils-nl80211.c +++ b/src/platform/wifi/wifi-utils-nl80211.c @@ -15,14 +15,14 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2018 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. * Copyright (C) 2011 Intel Corporation. All rights reserved. */ #include "nm-default.h" -#include "nm-wifi-utils-nl80211.h" +#include "wifi-utils-nl80211.h" #include <errno.h> #include <string.h> @@ -32,7 +32,7 @@ #include <linux/nl80211.h> #include "platform/nm-netlink.h" -#include "nm-wifi-utils-private.h" +#include "wifi-utils-private.h" #include "platform/nm-platform.h" #include "platform/nm-platform-utils.h" #include "nm-utils.h" @@ -47,20 +47,14 @@ } G_STMT_END typedef struct { - NMWifiUtils parent; + WifiData parent; struct nl_sock *nl_sock; guint32 *freqs; int id; int num_freqs; int phy; bool can_wowlan:1; -} NMWifiUtilsNl80211; - -typedef struct { - NMWifiUtilsClass parent; -} NMWifiUtilsNl80211Class; - -G_DEFINE_TYPE (NMWifiUtilsNl80211, nm_wifi_utils_nl80211, NM_TYPE_WIFI_UTILS) +} WifiDataNl80211; static int ack_handler (struct nl_msg *msg, void *arg) @@ -103,7 +97,7 @@ nla_put_failure: } static struct nl_msg * -nl80211_alloc_msg (NMWifiUtilsNl80211 *nl80211, guint32 cmd, guint32 flags) +nl80211_alloc_msg (WifiDataNl80211 *nl80211, guint32 cmd, guint32 flags) { return _nl80211_alloc_msg (nl80211->id, nl80211->parent.ifindex, nl80211->phy, cmd, flags); } @@ -160,7 +154,7 @@ _nl80211_send_and_recv (struct nl_sock *nl_sock, } static int -nl80211_send_and_recv (NMWifiUtilsNl80211 *nl80211, +nl80211_send_and_recv (WifiDataNl80211 *nl80211, struct nl_msg *msg, int (*valid_handler) (struct nl_msg *, void *), void *valid_data) @@ -170,11 +164,13 @@ nl80211_send_and_recv (NMWifiUtilsNl80211 *nl80211, } static void -dispose (GObject *object) +wifi_nl80211_deinit (WifiData *parent) { - NMWifiUtilsNl80211 *nl80211 = NM_WIFI_UTILS_NL80211 (object); + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) parent; - g_clear_pointer (&nl80211->freqs, g_free); + if (nl80211->nl_sock) + nl_socket_free (nl80211->nl_sock); + g_free (nl80211->freqs); } struct nl80211_iface_info { @@ -211,9 +207,9 @@ nl80211_iface_info_handler (struct nl_msg *msg, void *arg) } static NM80211Mode -wifi_nl80211_get_mode (NMWifiUtils *data) +wifi_nl80211_get_mode (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_iface_info iface_info = { .mode = NM_802_11_MODE_UNKNOWN, }; @@ -229,9 +225,9 @@ wifi_nl80211_get_mode (NMWifiUtils *data) } static gboolean -wifi_nl80211_set_mode (NMWifiUtils *data, const NM80211Mode mode) +wifi_nl80211_set_mode (WifiData *data, const NM80211Mode mode) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -259,9 +255,9 @@ nla_put_failure: } static gboolean -wifi_nl80211_set_powersave (NMWifiUtils *data, guint32 powersave) +wifi_nl80211_set_powersave (WifiData *data, guint32 powersave) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -275,64 +271,10 @@ nla_put_failure: return FALSE; } -static int -nl80211_get_wake_on_wlan_handler (struct nl_msg *msg, void *arg) -{ - NMSettingWirelessWakeOnWLan *wowl = arg; - struct nlattr *attrs[NL80211_ATTR_MAX + 1]; - struct nlattr *trig[NUM_NL80211_WOWLAN_TRIG]; - struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); - - nla_parse (attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), NULL); - - if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) - return NL_SKIP; - - nla_parse (trig, MAX_NL80211_WOWLAN_TRIG, - nla_data (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), - nla_len (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), - NULL); - - *wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE; - if (trig[NL80211_WOWLAN_TRIG_ANY]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY; - if (trig[NL80211_WOWLAN_TRIG_DISCONNECT]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT; - if (trig[NL80211_WOWLAN_TRIG_MAGIC_PKT]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC; - if (trig[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE; - if (trig[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST; - if (trig[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE; - if (trig[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE; - if (trig[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP; - - return NL_SKIP; -} - -static NMSettingWirelessWakeOnWLan -wifi_nl80211_get_wake_on_wlan (NMWifiUtils *data) -{ - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; - NMSettingWirelessWakeOnWLan wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; - nm_auto_nlmsg struct nl_msg *msg = NULL; - - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0); - - nl80211_send_and_recv (nl80211, msg, nl80211_get_wake_on_wlan_handler, &wowl); - - return wowl; -} - static gboolean -wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl) +wifi_nl80211_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; struct nlattr *triggers; int err; @@ -340,11 +282,11 @@ wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wo if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) return TRUE; - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_WOWLAN, 0); + msg = nl80211_alloc_msg(nl80211, NL80211_CMD_SET_WOWLAN, 0); if (!msg) return FALSE; - triggers = nla_nest_start (msg, NL80211_ATTR_WOWLAN_TRIGGERS); + triggers = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY)) NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_ANY); @@ -364,8 +306,7 @@ wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wo nla_nest_end(msg, triggers); err = nl80211_send_and_recv (nl80211, msg, NULL, NULL); - - return err >= 0; + return err ? FALSE : TRUE; nla_put_failure: return FALSE; @@ -491,7 +432,7 @@ nl80211_bss_dump_handler (struct nl_msg *msg, void *arg) } static void -nl80211_get_bss_info (NMWifiUtilsNl80211 *nl80211, +nl80211_get_bss_info (WifiDataNl80211 *nl80211, struct nl80211_bss_info *bss_info) { nm_auto_nlmsg struct nl_msg *msg = NULL; @@ -504,9 +445,9 @@ nl80211_get_bss_info (NMWifiUtilsNl80211 *nl80211, } static guint32 -wifi_nl80211_get_freq (NMWifiUtils *data) +wifi_nl80211_get_freq (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_bss_info bss_info; nl80211_get_bss_info (nl80211, &bss_info); @@ -515,9 +456,9 @@ wifi_nl80211_get_freq (NMWifiUtils *data) } static guint32 -wifi_nl80211_find_freq (NMWifiUtils *data, const guint32 *freqs) +wifi_nl80211_find_freq (WifiData *data, const guint32 *freqs) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; int i; for (i = 0; i < nl80211->num_freqs; i++) { @@ -531,9 +472,9 @@ wifi_nl80211_find_freq (NMWifiUtils *data, const guint32 *freqs) } static gboolean -wifi_nl80211_get_bssid (NMWifiUtils *data, guint8 *out_bssid) +wifi_nl80211_get_bssid (WifiData *data, guint8 *out_bssid) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_bss_info bss_info; nl80211_get_bss_info (nl80211, &bss_info); @@ -615,7 +556,7 @@ nl80211_station_handler (struct nl_msg *msg, void *arg) } static void -nl80211_get_ap_info (NMWifiUtilsNl80211 *nl80211, +nl80211_get_ap_info (WifiDataNl80211 *nl80211, struct nl80211_station_info *sta_info) { nm_auto_nlmsg struct nl_msg *msg = NULL; @@ -645,9 +586,9 @@ nla_put_failure: } static guint32 -wifi_nl80211_get_rate (NMWifiUtils *data) +wifi_nl80211_get_rate (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_station_info sta_info; nl80211_get_ap_info (nl80211, &sta_info); @@ -656,9 +597,9 @@ wifi_nl80211_get_rate (NMWifiUtils *data) } static int -wifi_nl80211_get_qual (NMWifiUtils *data) +wifi_nl80211_get_qual (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_station_info sta_info; nl80211_get_ap_info (nl80211, &sta_info); @@ -666,9 +607,9 @@ wifi_nl80211_get_qual (NMWifiUtils *data) } static gboolean -wifi_nl80211_indicate_addressing_running (NMWifiUtils *data, gboolean running) +wifi_nl80211_indicate_addressing_running (WifiData *data, gboolean running) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -697,6 +638,44 @@ nla_put_failure: return FALSE; } +struct nl80211_wowlan_info { + gboolean enabled; +}; + +static int +nl80211_wowlan_handler (struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); + struct nl80211_wowlan_info *info = arg; + + info->enabled = FALSE; + + if (nla_parse (tb, NL80211_ATTR_MAX, genlmsg_attrdata (gnlh, 0), + genlmsg_attrlen (gnlh, 0), NULL) < 0) + return NL_SKIP; + + if (tb[NL80211_ATTR_WOWLAN_TRIGGERS]) + info->enabled = TRUE; + + return NL_SKIP; +} + +static gboolean +wifi_nl80211_get_wowlan (WifiData *data) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl80211_wowlan_info info; + + if (!nl80211->can_wowlan) + return FALSE; + + msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0); + nl80211_send_and_recv (nl80211, msg, nl80211_wowlan_handler, &info); + return info.enabled; +} + struct nl80211_device_info { int phy; guint32 *freqs; @@ -900,58 +879,48 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) return NL_SKIP; } -static void -nm_wifi_utils_nl80211_init (NMWifiUtilsNl80211 *self) -{ -} - -static void -nm_wifi_utils_nl80211_class_init (NMWifiUtilsNl80211Class *klass) +WifiData * +wifi_nl80211_init (int ifindex) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMWifiUtilsClass *wifi_utils_class = NM_WIFI_UTILS_CLASS (klass); - - object_class->dispose = dispose; - - wifi_utils_class->get_mode = wifi_nl80211_get_mode; - wifi_utils_class->set_mode = wifi_nl80211_set_mode; - wifi_utils_class->set_powersave = wifi_nl80211_set_powersave; - wifi_utils_class->get_wake_on_wlan = wifi_nl80211_get_wake_on_wlan, - wifi_utils_class->set_wake_on_wlan = wifi_nl80211_set_wake_on_wlan, - wifi_utils_class->get_freq = wifi_nl80211_get_freq; - wifi_utils_class->find_freq = wifi_nl80211_find_freq; - wifi_utils_class->get_bssid = wifi_nl80211_get_bssid; - wifi_utils_class->get_rate = wifi_nl80211_get_rate; - wifi_utils_class->get_qual = wifi_nl80211_get_qual; - wifi_utils_class->indicate_addressing_running = wifi_nl80211_indicate_addressing_running; -} - -NMWifiUtils * -nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl) -{ - gs_unref_object NMWifiUtilsNl80211 *nl80211 = NULL; + static const WifiDataClass klass = { + .struct_size = sizeof (WifiDataNl80211), + .get_mode = wifi_nl80211_get_mode, + .set_mode = wifi_nl80211_set_mode, + .set_powersave = wifi_nl80211_set_powersave, + .set_wake_on_wlan = wifi_nl80211_set_wake_on_wlan, + .get_freq = wifi_nl80211_get_freq, + .find_freq = wifi_nl80211_find_freq, + .get_bssid = wifi_nl80211_get_bssid, + .get_rate = wifi_nl80211_get_rate, + .get_qual = wifi_nl80211_get_qual, + .get_wowlan = wifi_nl80211_get_wowlan, + .indicate_addressing_running = wifi_nl80211_indicate_addressing_running, + .deinit = wifi_nl80211_deinit, + }; + WifiDataNl80211 *nl80211; nm_auto_nlmsg struct nl_msg *msg = NULL; struct nl80211_device_info device_info = {}; char ifname[IFNAMSIZ]; - if (!genl) - return NULL; - if (!nmp_utils_if_indextoname (ifindex, ifname)) { _LOGW (LOGD_PLATFORM | LOGD_WIFI, "can't determine interface name for ifindex %d", ifindex); nm_sprintf_buf (ifname, "if %d", ifindex); } - nl80211 = g_object_new (NM_TYPE_WIFI_UTILS_NL80211, NULL); + nl80211 = wifi_data_new (&klass, ifindex); + + nl80211->nl_sock = nl_socket_alloc (); + if (nl80211->nl_sock == NULL) + goto error; - nl80211->parent.ifindex = ifindex; - nl80211->nl_sock = genl; + if (nl_connect (nl80211->nl_sock, NETLINK_GENERIC)) + goto error; nl80211->id = genl_ctrl_resolve (nl80211->nl_sock, "nl80211"); if (nl80211->id < 0) { _LOGD (LOGD_WIFI, "genl_ctrl_resolve: failed to resolve \"nl80211\""); - return NULL; + goto error; } nl80211->phy = -1; @@ -963,42 +932,42 @@ nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl) _LOGD (LOGD_PLATFORM | LOGD_WIFI, "(%s): NL80211_CMD_GET_WIPHY request failed", ifname); - return NULL; + goto error; } if (!device_info.success) { _LOGD (LOGD_PLATFORM | LOGD_WIFI, "(%s): NL80211_CMD_GET_WIPHY request indicated failure", ifname); - return NULL; + goto error; } if (!device_info.supported) { _LOGD (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver does not fully support nl80211, falling back to WEXT", ifname); - return NULL; + goto error; } if (!device_info.can_scan_ssid) { _LOGE (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver does not support SSID scans", ifname); - return NULL; + goto error; } if (device_info.num_freqs == 0 || device_info.freqs == NULL) { nm_log_err (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver reports no supported frequencies", ifname); - return NULL; + goto error; } if (device_info.caps == 0) { _LOGE (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver doesn't report support of any encryption", ifname); - return NULL; + goto error; } nl80211->phy = device_info.phy; @@ -1010,5 +979,10 @@ nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl) _LOGI (LOGD_PLATFORM | LOGD_WIFI, "(%s): using nl80211 for WiFi device control", ifname); - return (NMWifiUtils *) g_steal_pointer (&nl80211); + return (WifiData *) nl80211; + +error: + wifi_utils_unref ((WifiData *) nl80211); + return NULL; } + diff --git a/src/platform/wifi/nm-wifi-utils-nl80211.h b/src/platform/wifi/wifi-utils-nl80211.h index 27f67697..aff24555 100644 --- a/src/platform/wifi/nm-wifi-utils-nl80211.h +++ b/src/platform/wifi/wifi-utils-nl80211.h @@ -16,24 +16,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2011 Intel Corporation. All rights reserved. - * Copyright (C) 2018 Red Hat, Inc. */ #ifndef __WIFI_UTILS_NL80211_H__ #define __WIFI_UTILS_NL80211_H__ -#include "nm-wifi-utils.h" -#include "platform/nm-netlink.h" +#include "wifi-utils.h" -#define NM_TYPE_WIFI_UTILS_NL80211 (nm_wifi_utils_nl80211_get_type ()) -#define NM_WIFI_UTILS_NL80211(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211)) -#define NM_WIFI_UTILS_NL80211_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211Class)) -#define NM_IS_WIFI_UTILS_NL80211(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_UTILS_NL80211)) -#define NM_IS_WIFI_UTILS_NL80211_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_UTILS_NL80211)) -#define NM_WIFI_UTILS_NL80211_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211Class)) - -GType nm_wifi_utils_nl80211_get_type (void); - -NMWifiUtils *nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl); +WifiData *wifi_nl80211_init (int ifindex); #endif /* __WIFI_UTILS_NL80211_H__ */ diff --git a/src/platform/wifi/nm-wifi-utils-private.h b/src/platform/wifi/wifi-utils-private.h index bcbc1c51..627108cb 100644 --- a/src/platform/wifi/nm-wifi-utils-private.h +++ b/src/platform/wifi/wifi-utils-private.h @@ -15,65 +15,67 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2018 Red Hat, Inc. + * Copyright (C) 2011 Red Hat, Inc. */ #ifndef __WIFI_UTILS_PRIVATE_H__ #define __WIFI_UTILS_PRIVATE_H__ #include "nm-dbus-interface.h" -#include "nm-wifi-utils.h" +#include "wifi-utils.h" typedef struct { - GObjectClass parent; + gsize struct_size; - NM80211Mode (*get_mode) (NMWifiUtils *data); + NM80211Mode (*get_mode) (WifiData *data); - gboolean (*set_mode) (NMWifiUtils *data, const NM80211Mode mode); + gboolean (*set_mode) (WifiData *data, const NM80211Mode mode); /* Set power saving mode on an interface */ - gboolean (*set_powersave) (NMWifiUtils *data, guint32 powersave); - - /* Get WakeOnWLAN configuration on an interface */ - NMSettingWirelessWakeOnWLan (*get_wake_on_wlan) (NMWifiUtils *data); + gboolean (*set_powersave) (WifiData *data, guint32 powersave); /* Set WakeOnWLAN mode on an interface */ - gboolean (*set_wake_on_wlan) (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl); + gboolean (*set_wake_on_wlan) (WifiData *data, NMSettingWirelessWakeOnWLan wowl); /* Return current frequency in MHz (really associated BSS frequency) */ - guint32 (*get_freq) (NMWifiUtils *data); + guint32 (*get_freq) (WifiData *data); /* Return first supported frequency in the zero-terminated list */ - guint32 (*find_freq) (NMWifiUtils *data, const guint32 *freqs); + guint32 (*find_freq) (WifiData *data, const guint32 *freqs); /* Return current bitrate in Kbps */ - guint32 (*get_rate) (NMWifiUtils *data); + guint32 (*get_rate) (WifiData *data); - gboolean (*get_bssid) (NMWifiUtils *data, guint8 *out_bssid); + gboolean (*get_bssid) (WifiData *data, guint8 *out_bssid); /* Return a signal strength percentage 0 - 100% for the current BSSID; * return -1 on errors or if not associated. */ - int (*get_qual) (NMWifiUtils *data); + int (*get_qual) (WifiData *data); + + void (*deinit) (WifiData *data); + + gboolean (*get_wowlan) (WifiData *data); /* OLPC Mesh-only functions */ - guint32 (*get_mesh_channel) (NMWifiUtils *data); + guint32 (*get_mesh_channel) (WifiData *data); /* channel == 0 means "auto channel" */ - gboolean (*set_mesh_channel) (NMWifiUtils *data, guint32 channel); + gboolean (*set_mesh_channel) (WifiData *data, guint32 channel); /* ssid == NULL means "auto SSID" */ - gboolean (*set_mesh_ssid) (NMWifiUtils *data, const guint8 *ssid, gsize len); + gboolean (*set_mesh_ssid) (WifiData *data, const guint8 *ssid, gsize len); - gboolean (*indicate_addressing_running) (NMWifiUtils *data, gboolean running); -} NMWifiUtilsClass; - -struct NMWifiUtils { - GObject parent; + gboolean (*indicate_addressing_running) (WifiData *data, gboolean running); +} WifiDataClass; +struct WifiData { + const WifiDataClass *klass; int ifindex; NMDeviceWifiCapabilities caps; }; +gpointer wifi_data_new (const WifiDataClass *klass, int ifindex); + #endif /* __WIFI_UTILS_PRIVATE_H__ */ diff --git a/src/platform/wifi/nm-wifi-utils-wext.c b/src/platform/wifi/wifi-utils-wext.c index e52ae5a3..c8744f79 100644 --- a/src/platform/wifi/nm-wifi-utils-wext.c +++ b/src/platform/wifi/wifi-utils-wext.c @@ -15,13 +15,13 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2018 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ #include "nm-default.h" -#include "nm-wifi-utils-wext.h" +#include "wifi-utils-wext.h" #include <errno.h> #include <string.h> @@ -38,24 +38,17 @@ #include <sys/socket.h> #include <linux/wireless.h> -#include "nm-wifi-utils-private.h" +#include "wifi-utils-private.h" #include "nm-utils.h" #include "platform/nm-platform-utils.h" -#include "nm-core-internal.h" typedef struct { - NMWifiUtils parent; + WifiData parent; int fd; struct iw_quality max_qual; gint8 num_freqs; guint32 freqs[IW_MAX_FREQUENCIES]; -} NMWifiUtilsWext; - -typedef struct { - NMWifiUtilsClass parent; -} NMWifiUtilsWextClass; - -G_DEFINE_TYPE (NMWifiUtilsWext, nm_wifi_utils_wext, NM_TYPE_WIFI_UTILS) +} WifiDataWext; /* Until a new wireless-tools comes out that has the defs and the structure, * need to copy them here. @@ -101,11 +94,11 @@ iw_freq_to_uint32 (const struct iw_freq *freq) } static void -dispose (GObject *object) +wifi_wext_deinit (WifiData *parent) { - NMWifiUtilsWext *wext = NM_WIFI_UTILS_WEXT (object); + WifiDataWext *wext = (WifiDataWext *) parent; - wext->fd = nm_close (wext->fd); + nm_close (wext->fd); } static gboolean @@ -125,9 +118,9 @@ get_ifname (int ifindex, char *buffer, const char *op) } static NM80211Mode -wifi_wext_get_mode_ifname (NMWifiUtils *data, const char *ifname) +wifi_wext_get_mode_ifname (WifiData *data, const char *ifname) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; memset (&wrq, 0, sizeof (struct iwreq)); @@ -157,7 +150,7 @@ wifi_wext_get_mode_ifname (NMWifiUtils *data, const char *ifname) } static NM80211Mode -wifi_wext_get_mode (NMWifiUtils *data) +wifi_wext_get_mode (WifiData *data) { char ifname[IFNAMSIZ]; @@ -168,9 +161,9 @@ wifi_wext_get_mode (NMWifiUtils *data) } static gboolean -wifi_wext_set_mode (NMWifiUtils *data, const NM80211Mode mode) +wifi_wext_set_mode (WifiData *data, const NM80211Mode mode) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -210,9 +203,9 @@ wifi_wext_set_mode (NMWifiUtils *data, const NM80211Mode mode) } static gboolean -wifi_wext_set_powersave (NMWifiUtils *data, guint32 powersave) +wifi_wext_set_powersave (WifiData *data, guint32 powersave) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -239,9 +232,9 @@ wifi_wext_set_powersave (NMWifiUtils *data, guint32 powersave) } static guint32 -wifi_wext_get_freq (NMWifiUtils *data) +wifi_wext_get_freq (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -261,9 +254,9 @@ wifi_wext_get_freq (NMWifiUtils *data) } static guint32 -wifi_wext_find_freq (NMWifiUtils *data, const guint32 *freqs) +wifi_wext_find_freq (WifiData *data, const guint32 *freqs) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; int i; for (i = 0; i < wext->num_freqs; i++) { @@ -277,9 +270,9 @@ wifi_wext_find_freq (NMWifiUtils *data, const guint32 *freqs) } static gboolean -wifi_wext_get_bssid (NMWifiUtils *data, guint8 *out_bssid) +wifi_wext_get_bssid (WifiData *data, guint8 *out_bssid) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -299,9 +292,9 @@ wifi_wext_get_bssid (NMWifiUtils *data, guint8 *out_bssid) } static guint32 -wifi_wext_get_rate (NMWifiUtils *data) +wifi_wext_get_rate (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; int err; char ifname[IFNAMSIZ]; @@ -410,9 +403,9 @@ wext_qual_to_percent (const struct iw_quality *qual, } static int -wifi_wext_get_qual (NMWifiUtils *data) +wifi_wext_get_qual (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; struct iw_statistics stats; char ifname[IFNAMSIZ]; @@ -440,13 +433,13 @@ wifi_wext_get_qual (NMWifiUtils *data) /* OLPC Mesh-only functions */ static guint32 -wifi_wext_get_mesh_channel (NMWifiUtils *data) +wifi_wext_get_mesh_channel (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; guint32 freq; int i; - freq = nm_wifi_utils_get_freq (data); + freq = wifi_utils_get_freq (data); for (i = 0; i < wext->num_freqs; i++) { if (freq == wext->freqs[i]) return i + 1; @@ -455,9 +448,9 @@ wifi_wext_get_mesh_channel (NMWifiUtils *data) } static gboolean -wifi_wext_set_mesh_channel (NMWifiUtils *data, guint32 channel) +wifi_wext_set_mesh_channel (WifiData *data, guint32 channel) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -484,9 +477,9 @@ wifi_wext_set_mesh_channel (NMWifiUtils *data, guint32 channel) } static gboolean -wifi_wext_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) +wifi_wext_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char buf[IW_ESSID_MAX_SIZE + 1]; char ifname[IFNAMSIZ]; @@ -507,13 +500,11 @@ wifi_wext_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) return TRUE; if (errno != ENODEV) { - gs_free char *ssid_str = NULL; - errsv = errno; _LOGE (LOGD_PLATFORM | LOGD_WIFI | LOGD_OLPC, "(%s): error setting SSID to '%s': %s", ifname, - (ssid_str = _nm_utils_ssid_to_string_arr (ssid, len)), + ssid ? nm_utils_escape_ssid (ssid, len) : "(null)", strerror (errsv)); } @@ -523,7 +514,7 @@ wifi_wext_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) /*****************************************************************************/ static gboolean -wext_can_scan_ifname (NMWifiUtilsWext *wext, const char *ifname) +wext_can_scan_ifname (WifiDataWext *wext, const char *ifname) { struct iwreq wrq; @@ -537,7 +528,7 @@ wext_can_scan_ifname (NMWifiUtilsWext *wext, const char *ifname) } static gboolean -wext_get_range_ifname (NMWifiUtilsWext *wext, +wext_get_range_ifname (WifiDataWext *wext, const char *ifname, struct iw_range *range, guint32 *response_len) @@ -586,7 +577,7 @@ wext_get_range_ifname (NMWifiUtilsWext *wext, NM_WIFI_DEVICE_CAP_RSN) static guint32 -wext_get_caps (NMWifiUtilsWext *wext, const char *ifname, struct iw_range *range) +wext_get_caps (WifiDataWext *wext, const char *ifname, struct iw_range *range) { guint32 caps = NM_WIFI_DEVICE_CAP_NONE; @@ -635,38 +626,25 @@ wext_get_caps (NMWifiUtilsWext *wext, const char *ifname, struct iw_range *range return caps; } -/*****************************************************************************/ - -static void -nm_wifi_utils_wext_init (NMWifiUtilsWext *self) -{ -} - -static void -nm_wifi_utils_wext_class_init (NMWifiUtilsWextClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMWifiUtilsClass *wifi_utils_class = NM_WIFI_UTILS_CLASS (klass); - - object_class->dispose = dispose; - - wifi_utils_class->get_mode = wifi_wext_get_mode; - wifi_utils_class->set_mode = wifi_wext_set_mode; - wifi_utils_class->set_powersave = wifi_wext_set_powersave; - wifi_utils_class->get_freq = wifi_wext_get_freq; - wifi_utils_class->find_freq = wifi_wext_find_freq; - wifi_utils_class->get_bssid = wifi_wext_get_bssid; - wifi_utils_class->get_rate = wifi_wext_get_rate; - wifi_utils_class->get_qual = wifi_wext_get_qual; - wifi_utils_class->get_mesh_channel = wifi_wext_get_mesh_channel; - wifi_utils_class->set_mesh_channel = wifi_wext_set_mesh_channel; - wifi_utils_class->set_mesh_ssid = wifi_wext_set_mesh_ssid; -} - -NMWifiUtils * -nm_wifi_utils_wext_new (int ifindex, gboolean check_scan) +WifiData * +wifi_wext_init (int ifindex, gboolean check_scan) { - NMWifiUtilsWext *wext; + static const WifiDataClass klass = { + .struct_size = sizeof (WifiDataWext), + .get_mode = wifi_wext_get_mode, + .set_mode = wifi_wext_set_mode, + .set_powersave = wifi_wext_set_powersave, + .get_freq = wifi_wext_get_freq, + .find_freq = wifi_wext_find_freq, + .get_bssid = wifi_wext_get_bssid, + .get_rate = wifi_wext_get_rate, + .get_qual = wifi_wext_get_qual, + .deinit = wifi_wext_deinit, + .get_mesh_channel = wifi_wext_get_mesh_channel, + .set_mesh_channel = wifi_wext_set_mesh_channel, + .set_mesh_ssid = wifi_wext_set_mesh_ssid, + }; + WifiDataWext *wext; struct iw_range range; guint32 response_len = 0; struct iw_range_with_scan_capa *scan_capa_range; @@ -680,9 +658,8 @@ nm_wifi_utils_wext_new (int ifindex, gboolean check_scan) return NULL; } - wext = g_object_new (NM_TYPE_WIFI_UTILS_WEXT, NULL); + wext = wifi_data_new (&klass, ifindex); - wext->parent.ifindex = ifindex; wext->fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (wext->fd < 0) goto error; @@ -754,15 +731,15 @@ nm_wifi_utils_wext_new (int ifindex, gboolean check_scan) "(%s): using WEXT for WiFi device control", ifname); - return (NMWifiUtils *) wext; + return (WifiData *) wext; error: - g_object_unref (wext); + wifi_utils_unref ((WifiData *) wext); return NULL; } gboolean -nm_wifi_utils_wext_is_wifi (const char *iface) +wifi_wext_is_wifi (const char *iface) { int fd; struct iwreq iwr; diff --git a/src/platform/wifi/nm-wifi-utils-wext.h b/src/platform/wifi/wifi-utils-wext.h index 44b11afb..3ef5a173 100644 --- a/src/platform/wifi/nm-wifi-utils-wext.h +++ b/src/platform/wifi/wifi-utils-wext.h @@ -15,25 +15,16 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2018 Red Hat, Inc. + * Copyright (C) 2011 Red Hat, Inc. */ #ifndef __WIFI_UTILS_WEXT_H__ #define __WIFI_UTILS_WEXT_H__ -#include "nm-wifi-utils.h" +#include "wifi-utils.h" -#define NM_TYPE_WIFI_UTILS_WEXT (nm_wifi_utils_wext_get_type ()) -#define NM_WIFI_UTILS_WEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWext)) -#define NM_WIFI_UTILS_WEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWextClass)) -#define NM_IS_WIFI_UTILS_WEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_UTILS_WEXT)) -#define NM_IS_WIFI_UTILS_WEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_UTILS_WEXT)) -#define NM_WIFI_UTILS_WEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWextClass)) +WifiData *wifi_wext_init (int ifindex, gboolean check_scan); -GType nm_wifi_utils_wext_get_type (void); - -NMWifiUtils *nm_wifi_utils_wext_new (int ifindex, gboolean check_scan); - -gboolean nm_wifi_utils_wext_is_wifi (const char *iface); +gboolean wifi_wext_is_wifi (const char *iface); #endif /* __WIFI_UTILS_WEXT_H__ */ diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c new file mode 100644 index 00000000..b3dd92ba --- /dev/null +++ b/src/platform/wifi/wifi-utils.c @@ -0,0 +1,231 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#include "nm-default.h" + +#include "wifi-utils.h" + +#include <sys/stat.h> +#include <stdio.h> +#include <string.h> +#include <fcntl.h> + +#include "wifi-utils-private.h" +#include "wifi-utils-nl80211.h" +#if HAVE_WEXT +#include "wifi-utils-wext.h" +#endif +#include "nm-core-utils.h" + +#include "platform/nm-platform-utils.h" + +gpointer +wifi_data_new (const WifiDataClass *klass, int ifindex) +{ + WifiData *data; + + nm_assert (klass); + nm_assert (klass->struct_size > sizeof (WifiData)); + + data = g_malloc0 (klass->struct_size); + data->klass = klass; + data->ifindex = ifindex; + return data; +} + +/*****************************************************************************/ + +WifiData * +wifi_utils_init (int ifindex, gboolean check_scan) +{ + WifiData *ret; + + g_return_val_if_fail (ifindex > 0, NULL); + + ret = wifi_nl80211_init (ifindex); + if (ret == NULL) { +#if HAVE_WEXT + ret = wifi_wext_init (ifindex, check_scan); +#endif + } + return ret; +} + +int +wifi_utils_get_ifindex (WifiData *data) +{ + g_return_val_if_fail (data != NULL, -1); + + return data->ifindex; +} + +NMDeviceWifiCapabilities +wifi_utils_get_caps (WifiData *data) +{ + g_return_val_if_fail (data != NULL, NM_WIFI_DEVICE_CAP_NONE); + + return data->caps; +} + +NM80211Mode +wifi_utils_get_mode (WifiData *data) +{ + g_return_val_if_fail (data != NULL, NM_802_11_MODE_UNKNOWN); + return data->klass->get_mode (data); +} + +gboolean +wifi_utils_set_mode (WifiData *data, const NM80211Mode mode) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail ( (mode == NM_802_11_MODE_INFRA) + || (mode == NM_802_11_MODE_AP) + || (mode == NM_802_11_MODE_ADHOC), FALSE); + + /* nl80211 probably doesn't need this */ + return data->klass->set_mode ? data->klass->set_mode (data, mode) : TRUE; +} + +gboolean +wifi_utils_set_powersave (WifiData *data, guint32 powersave) +{ + g_return_val_if_fail (data != NULL, FALSE); + + return data->klass->set_powersave ? data->klass->set_powersave (data, powersave) : TRUE; +} + +gboolean +wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl) +{ + g_return_val_if_fail (data != NULL, FALSE); + + return data->klass->set_wake_on_wlan ? + data->klass->set_wake_on_wlan (data, wowl) : FALSE; +} + +guint32 +wifi_utils_get_freq (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->klass->get_freq (data); +} + +guint32 +wifi_utils_find_freq (WifiData *data, const guint32 *freqs) +{ + g_return_val_if_fail (data != NULL, 0); + g_return_val_if_fail (freqs != NULL, 0); + return data->klass->find_freq (data, freqs); +} + +gboolean +wifi_utils_get_bssid (WifiData *data, guint8 *out_bssid) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (out_bssid != NULL, FALSE); + + memset (out_bssid, 0, ETH_ALEN); + return data->klass->get_bssid (data, out_bssid); +} + +guint32 +wifi_utils_get_rate (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->klass->get_rate (data); +} + +int +wifi_utils_get_qual (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->klass->get_qual (data); +} + +gboolean +wifi_utils_get_wowlan (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + + if (!data->klass->get_wowlan) + return FALSE; + return data->klass->get_wowlan (data); +} + +void +wifi_utils_unref (WifiData *data) +{ + g_return_if_fail (data != NULL); + + data->klass->deinit (data); + g_free (data); +} + +gboolean +wifi_utils_is_wifi (int dirfd, const char *ifname) +{ + g_return_val_if_fail (dirfd >= 0, FALSE); + + if (faccessat (dirfd, "phy80211", F_OK, 0) == 0) + return TRUE; +#if HAVE_WEXT + if (wifi_wext_is_wifi (ifname)) + return TRUE; +#endif + return FALSE; +} + +/* OLPC Mesh-only functions */ + +guint32 +wifi_utils_get_mesh_channel (WifiData *data) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data->klass->get_mesh_channel != NULL, FALSE); + return data->klass->get_mesh_channel (data); +} + +gboolean +wifi_utils_set_mesh_channel (WifiData *data, guint32 channel) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (channel <= 13, FALSE); + g_return_val_if_fail (data->klass->set_mesh_channel != NULL, FALSE); + return data->klass->set_mesh_channel (data, channel); +} + +gboolean +wifi_utils_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data->klass->set_mesh_ssid != NULL, FALSE); + return data->klass->set_mesh_ssid (data, ssid, len); +} + +gboolean +wifi_utils_indicate_addressing_running (WifiData *data, gboolean running) +{ + g_return_val_if_fail (data != NULL, FALSE); + if (data->klass->indicate_addressing_running) + return data->klass->indicate_addressing_running (data, running); + return FALSE; +} + diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h new file mode 100644 index 00000000..c69561de --- /dev/null +++ b/src/platform/wifi/wifi-utils.h @@ -0,0 +1,79 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#ifndef __WIFI_UTILS_H__ +#define __WIFI_UTILS_H__ + +#include <net/ethernet.h> + +#include "nm-dbus-interface.h" +#include "nm-setting-wireless.h" + +typedef struct WifiData WifiData; + +gboolean wifi_utils_is_wifi (int dirfd, const char *ifname); + +WifiData *wifi_utils_init (int ifindex, gboolean check_scan); + +int wifi_utils_get_ifindex (WifiData *data); + +void wifi_utils_unref (WifiData *data); + +NMDeviceWifiCapabilities wifi_utils_get_caps (WifiData *data); + +NM80211Mode wifi_utils_get_mode (WifiData *data); + +gboolean wifi_utils_set_mode (WifiData *data, const NM80211Mode mode); + +/* Returns frequency in MHz */ +guint32 wifi_utils_get_freq (WifiData *data); + +/* Return the first supported frequency in the zero-terminated list. + * Frequencies are specified in MHz. */ +guint32 wifi_utils_find_freq (WifiData *data, const guint32 *freqs); + +/* out_bssid must be ETH_ALEN bytes */ +gboolean wifi_utils_get_bssid (WifiData *data, guint8 *out_bssid); + +/* Returns current bitrate in Kbps */ +guint32 wifi_utils_get_rate (WifiData *data); + +/* Returns quality 0 - 100% on succes, or -1 on error */ +int wifi_utils_get_qual (WifiData *data); + +/* Tells the driver DHCP or SLAAC is running */ +gboolean wifi_utils_indicate_addressing_running (WifiData *data, gboolean running); + +/* Returns true if WoWLAN is enabled on device */ +gboolean wifi_utils_get_wowlan (WifiData *data); + +gboolean wifi_utils_set_powersave (WifiData *data, guint32 powersave); + +gboolean wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl); + +/* OLPC Mesh-only functions */ +guint32 wifi_utils_get_mesh_channel (WifiData *data); + +gboolean wifi_utils_set_mesh_channel (WifiData *data, guint32 channel); + +gboolean wifi_utils_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len); + +#endif /* __WIFI_UTILS_H__ */ diff --git a/src/platform/wpan/nm-wpan-utils.c b/src/platform/wpan/nm-wpan-utils.c deleted file mode 100644 index 0544539a..00000000 --- a/src/platform/wpan/nm-wpan-utils.c +++ /dev/null @@ -1,286 +0,0 @@ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2018 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include "nm-wpan-utils.h" - -#include "platform/linux/nl802154.h" -#include "platform/nm-netlink.h" - -#define _NMLOG_PREFIX_NAME "wpan-nl802154" -#define _NMLOG(level, domain, ...) \ - G_STMT_START { \ - nm_log ((level), (domain), NULL, NULL, \ - "%s: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - _NMLOG_PREFIX_NAME \ - _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } G_STMT_END - -/*****************************************************************************/ - -struct NMWpanUtils { - GObject parent; - int ifindex; - struct nl_sock *nl_sock; - int id; -}; - -typedef struct { - GObjectClass parent; -} NMWpanUtilsClass; - -G_DEFINE_TYPE (NMWpanUtils, nm_wpan_utils, G_TYPE_OBJECT) - -/*****************************************************************************/ - -static int -ack_handler (struct nl_msg *msg, void *arg) -{ - int *done = arg; - *done = 1; - return NL_STOP; -} - -static int -finish_handler (struct nl_msg *msg, void *arg) -{ - int *done = arg; - *done = 1; - return NL_SKIP; -} - -static int -error_handler (struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) -{ - int *done = arg; - *done = err->error; - return NL_SKIP; -} - -static struct nl_msg * -_nl802154_alloc_msg (int id, int ifindex, guint32 cmd, guint32 flags) -{ - nm_auto_nlmsg struct nl_msg *msg = NULL; - - msg = nlmsg_alloc (); - genlmsg_put (msg, 0, 0, id, 0, flags, cmd, 0); - NLA_PUT_U32 (msg, NL802154_ATTR_IFINDEX, ifindex); - return g_steal_pointer (&msg); - -nla_put_failure: - return NULL; -} - -static struct nl_msg * -nl802154_alloc_msg (NMWpanUtils *self, guint32 cmd, guint32 flags) -{ - return _nl802154_alloc_msg (self->id, self->ifindex, cmd, flags); -} - -static int -_nl802154_send_and_recv (struct nl_sock *nl_sock, - struct nl_msg *msg, - int (*valid_handler) (struct nl_msg *, void *), - void *valid_data) -{ - int err; - int done = 0; - const struct nl_cb cb = { - .err_cb = error_handler, - .err_arg = &done, - .finish_cb = finish_handler, - .finish_arg = &done, - .ack_cb = ack_handler, - .ack_arg = &done, - .valid_cb = valid_handler, - .valid_arg = valid_data, - }; - - g_return_val_if_fail (msg != NULL, -ENOMEM); - - err = nl_send_auto (nl_sock, msg); - if (err < 0) - return err; - - /* Loop until one of our NL callbacks says we're done; on success - * done will be 1, on error it will be < 0. - */ - while (!done) { - err = nl_recvmsgs (nl_sock, &cb); - if (err < 0 && err != -EAGAIN) { - _LOGW (LOGD_PLATFORM, "nl_recvmsgs() error: (%d) %s", - err, nl_geterror (err)); - break; - } - } - - if (err >= 0 && done < 0) - err = done; - return err; -} - -static int -nl802154_send_and_recv (NMWpanUtils *self, - struct nl_msg *msg, - int (*valid_handler) (struct nl_msg *, void *), - void *valid_data) -{ - return _nl802154_send_and_recv (self->nl_sock, msg, - valid_handler, valid_data); -} - -struct nl802154_interface { - guint16 pan_id; - guint16 short_addr; - - gboolean valid; -}; - -static int -nl802154_get_interface_handler (struct nl_msg *msg, void *arg) -{ - struct nl802154_interface *info = arg; - struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); - struct nlattr *tb[NL802154_ATTR_MAX + 1] = { 0, }; - static const struct nla_policy nl802154_policy[NL802154_ATTR_MAX + 1] = { - [NL802154_ATTR_PAN_ID] = { .type = NLA_U16 }, - [NL802154_ATTR_SHORT_ADDR] = { .type = NLA_U16 }, - }; - - if (nla_parse (tb, NL802154_ATTR_MAX, genlmsg_attrdata (gnlh, 0), - genlmsg_attrlen (gnlh, 0), nl802154_policy) < 0) - return NL_SKIP; - - if (tb[NL802154_ATTR_PAN_ID]) - info->pan_id = le16toh (nla_get_u16 (tb[NL802154_ATTR_PAN_ID])); - - if (tb[NL802154_ATTR_SHORT_ADDR]) - info->short_addr = le16toh (nla_get_u16 (tb[NL802154_ATTR_SHORT_ADDR])); - - info->valid = TRUE; - - return NL_SKIP; -} - -static void -nl802154_get_interface (NMWpanUtils *self, - struct nl802154_interface *interface) -{ - nm_auto_nlmsg struct nl_msg *msg = NULL; - - memset (interface, 0, sizeof (*interface)); - - msg = nl802154_alloc_msg (self, NL802154_CMD_GET_INTERFACE, 0); - - nl802154_send_and_recv (self, msg, nl802154_get_interface_handler, interface); -} - -/*****************************************************************************/ - -guint16 -nm_wpan_utils_get_pan_id (NMWpanUtils *self) -{ - struct nl802154_interface interface; - - nl802154_get_interface (self, &interface); - - return interface.pan_id; -} - -gboolean -nm_wpan_utils_set_pan_id (NMWpanUtils *self, guint16 pan_id) -{ - nm_auto_nlmsg struct nl_msg *msg = NULL; - int err; - - g_return_val_if_fail (self != NULL, FALSE); - - msg = nl802154_alloc_msg (self, NL802154_CMD_SET_PAN_ID, 0); - NLA_PUT_U16 (msg, NL802154_ATTR_PAN_ID, htole16 (pan_id)); - err = nl802154_send_and_recv (self, msg, NULL, NULL); - return err >= 0; - -nla_put_failure: - return FALSE; -} - -guint16 -nm_wpan_utils_get_short_addr (NMWpanUtils *self) -{ - struct nl802154_interface interface; - - nl802154_get_interface (self, &interface); - - return interface.short_addr; -} - -gboolean -nm_wpan_utils_set_short_addr (NMWpanUtils *self, guint16 short_addr) -{ - nm_auto_nlmsg struct nl_msg *msg = NULL; - int err; - - g_return_val_if_fail (self != NULL, FALSE); - - msg = nl802154_alloc_msg (self, NL802154_CMD_SET_SHORT_ADDR, 0); - NLA_PUT_U16 (msg, NL802154_ATTR_SHORT_ADDR, htole16 (short_addr)); - err = nl802154_send_and_recv (self, msg, NULL, NULL); - return err >= 0; - -nla_put_failure: - return FALSE; -} - -/*****************************************************************************/ - -static void -nm_wpan_utils_init (NMWpanUtils *self) -{ -} - -static void -nm_wpan_utils_class_init (NMWpanUtilsClass *klass) -{ -} - -NMWpanUtils * -nm_wpan_utils_new (int ifindex, struct nl_sock *genl, gboolean check_scan) -{ - NMWpanUtils *self; - int id; - - g_return_val_if_fail (ifindex > 0, NULL); - - if (!genl) - return NULL; - - id = genl_ctrl_resolve (genl, "nl802154"); - if (id < 0) { - _LOGD (LOGD_PLATFORM, "genl_ctrl_resolve: failed to resolve \"nl802154\""); - return NULL; - } - - self = g_object_new (NM_TYPE_WPAN_UTILS, NULL); - self->ifindex = ifindex; - self->nl_sock = genl; - self->id = id; - - return self; -} diff --git a/src/platform/wpan/nm-wpan-utils.h b/src/platform/wpan/nm-wpan-utils.h deleted file mode 100644 index f7d0c03e..00000000 --- a/src/platform/wpan/nm-wpan-utils.h +++ /dev/null @@ -1,47 +0,0 @@ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2018 Red Hat, Inc. - */ - -#ifndef __WPAN_UTILS_H__ -#define __WPAN_UTILS_H__ - -#include <net/ethernet.h> - -#include "nm-dbus-interface.h" -#include "platform/nm-netlink.h" - -typedef struct NMWpanUtils NMWpanUtils; - -#define NM_TYPE_WPAN_UTILS (nm_wpan_utils_get_type ()) -#define NM_WPAN_UTILS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WPAN_UTILS, NMWpanUtils)) -#define NM_WPAN_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WPAN_UTILS, NMWpanUtilsClass)) -#define NM_IS_WPAN_UTILS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WPAN_UTILS)) -#define NM_IS_WPAN_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WPAN_UTILS)) -#define NM_WPAN_UTILS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WPAN_UTILS, NMWpanUtilsClass)) - -GType nm_wpan_utils_get_type (void); - -NMWpanUtils *nm_wpan_utils_new (int ifindex, struct nl_sock *genl, gboolean check_scan); - -guint16 nm_wpan_utils_get_pan_id (NMWpanUtils *self); -gboolean nm_wpan_utils_set_pan_id (NMWpanUtils *self, guint16 pan_id); - -guint16 nm_wpan_utils_get_short_addr (NMWpanUtils *self); -gboolean nm_wpan_utils_set_short_addr (NMWpanUtils *self, guint16 short_addr); - -#endif /* __WPAN_UTILS_H__ */ diff --git a/src/ppp/meson.build b/src/ppp/meson.build index 20ed64ed..38f9a0f1 100644 --- a/src/ppp/meson.build +++ b/src/ppp/meson.build @@ -31,6 +31,7 @@ core_plugins += shared_module( name, sources: 'nm-ppp-manager.c', dependencies: deps, + c_args: '-DPPPD_PLUGIN_DIR="@0@"'.format(pppd_plugin_dir), link_args: [ '-Wl,--version-script,@0@'.format(linker_script), ], diff --git a/src/ppp/nm-ppp-manager.c b/src/ppp/nm-ppp-manager.c index b231ff20..40bdea64 100644 --- a/src/ppp/nm-ppp-manager.c +++ b/src/ppp/nm-ppp-manager.c @@ -438,11 +438,10 @@ impl_ppp_manager_set_ifindex (NMDBusObject *obj, g_variant_get (parameters, "(i)", &ifindex); + _LOGD ("set-ifindex %d", (int) ifindex); + if (priv->ifindex >= 0) { - if (priv->ifindex == ifindex) - _LOGD ("set-ifindex: ignore repeated calls setting ifindex to %d", (int) ifindex); - else - _LOGW ("set-ifindex: can't change the ifindex from %d to %d", priv->ifindex, (int) ifindex); + _LOGW ("can't change the ifindex from %d to %d", priv->ifindex, (int) ifindex); goto out; } @@ -455,15 +454,14 @@ impl_ppp_manager_set_ifindex (NMDBusObject *obj, } if (!plink) { - _LOGW ("set-ifindex: unknown interface with ifindex %d", ifindex); + _LOGW ("unknown interface with ifindex %d", ifindex); ifindex = 0; - } else { - obj_keep_alive = nmp_object_ref (NMP_OBJECT_UP_CAST (plink)); - _LOGD ("set-ifindex: %d, name \"%s\"", (int) ifindex, plink->name); } priv->ifindex = ifindex; + obj_keep_alive = nmp_object_ref (NMP_OBJECT_UP_CAST (plink)); + g_signal_emit (self, signals[IFINDEX_SET], 0, @@ -703,7 +701,7 @@ nm_cmd_line_to_str (NMCmdLine *cmd) char *str; g_ptr_array_add (cmd->array, NULL); - str = g_strjoinv (" ", (char **) cmd->array->pdata); + str = g_strjoinv (" ", (gchar **) cmd->array->pdata); g_ptr_array_remove_index (cmd->array, cmd->array->len - 1); return str; @@ -882,13 +880,13 @@ create_pppd_cmd_line (NMPPPManager *self, nm_cmd_line_add_string (cmd, pppoe_service); } } else if (adsl) { - const char *protocol = nm_setting_adsl_get_protocol (adsl); + const gchar *protocol = nm_setting_adsl_get_protocol (adsl); if (!strcmp (protocol, NM_SETTING_ADSL_PROTOCOL_PPPOA)) { guint32 vpi = nm_setting_adsl_get_vpi (adsl); guint32 vci = nm_setting_adsl_get_vci (adsl); const char *encaps = nm_setting_adsl_get_encapsulation (adsl); - char *vpivci; + gchar *vpivci; nm_cmd_line_add_string (cmd, "plugin"); nm_cmd_line_add_string (cmd, "pppoatm.so"); diff --git a/src/ppp/nm-pppd-plugin.c b/src/ppp/nm-pppd-plugin.c index 09196340..989f7433 100644 --- a/src/ppp/nm-pppd-plugin.c +++ b/src/ppp/nm-pppd-plugin.c @@ -147,7 +147,7 @@ nm_phasechange (void *data, int arg) if ( if_indextoname (index, new_name) && !nm_streq0 (ifname, new_name)) { g_message ("nm-ppp-plugin: interface name changed from '%s' to '%s'", ifname, new_name); - g_strlcpy (ifname, new_name, IF_NAMESIZE); + strncpy (ifname, new_name, IF_NAMESIZE); } } } diff --git a/src/settings/nm-agent-manager.c b/src/settings/nm-agent-manager.c index 953d3ce4..453136e4 100644 --- a/src/settings/nm-agent-manager.c +++ b/src/settings/nm-agent-manager.c @@ -349,7 +349,7 @@ agent_register_permissions_done (NMAuthChain *chain, priv->agent_version_id += 1; sender = nm_secret_agent_get_dbus_owner (agent); g_hash_table_insert (priv->agents, g_strdup (sender), agent); - _LOGI (agent, "agent registered"); + _LOGD (agent, "agent registered"); g_dbus_method_invocation_return_value (context, NULL); /* Signal an agent was registered */ @@ -642,7 +642,7 @@ req_complete_error (Request *req, GError *error) req_complete (req, NULL, NULL, NULL, error); } -static int +static gint agent_compare_func (gconstpointer aa, gconstpointer bb, gpointer user_data) { NMSecretAgent *a = (NMSecretAgent *)aa; @@ -651,14 +651,12 @@ agent_compare_func (gconstpointer aa, gconstpointer bb, gpointer user_data) NMSessionMonitor *sm; gboolean a_active, b_active; gulong a_pid, b_pid, requester; - guint64 a_start, b_start; - - a_pid = nm_secret_agent_get_pid (a); - b_pid = nm_secret_agent_get_pid (b); /* Prefer agents in the process the request came from */ if (nm_auth_subject_is_unix_process (req->subject)) { requester = nm_auth_subject_get_unix_process_pid (req->subject); + a_pid = nm_secret_agent_get_pid (a); + b_pid = nm_secret_agent_get_pid (b); if (a_pid != b_pid) { if (a_pid == requester) @@ -674,17 +672,11 @@ agent_compare_func (gconstpointer aa, gconstpointer bb, gpointer user_data) b_active = nm_session_monitor_session_exists (sm, nm_secret_agent_get_owner_uid (b), TRUE); if (a_active && !b_active) return -1; + else if (a_active == b_active) + return 0; else if (!a_active && b_active) return 1; - /* Prefer agents launched later (this is essentially to ease agent debugging) */ - a_start = nm_utils_get_start_time_for_pid (a_pid, NULL, NULL); - b_start = nm_utils_get_start_time_for_pid (b_pid, NULL, NULL); - if (a_start > b_start) - return -1; - else if (a_start < b_start) - return 1; - return 0; } diff --git a/src/settings/nm-secret-agent.c b/src/settings/nm-secret-agent.c index 836ab21d..af6d7017 100644 --- a/src/settings/nm-secret-agent.c +++ b/src/settings/nm-secret-agent.c @@ -648,10 +648,10 @@ _on_disconnected_private_connection (NMDBusManager *mgr, static void _on_disconnected_name_owner_changed (GDBusConnection *connection, - const char *sender_name, - const char *object_path, - const char *interface_name, - const char *signal_name, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, GVariant *parameters, gpointer user_data) { diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index 1b2edc83..c09f6804 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -49,26 +49,7 @@ /*****************************************************************************/ -NMConnection ** -nm_settings_connections_array_to_connections (NMSettingsConnection *const*connections, - gssize n_connections) -{ - NMConnection **arr; - gssize i; - - if (n_connections < 0) - n_connections = NM_PTRARRAY_LEN (connections); - if (n_connections == 0) - return NULL; - - arr = g_new (NMConnection *, n_connections + 1); - for (i = 0; i < n_connections; i++) - arr[i] = nm_settings_connection_get_connection (connections[i]); - arr[i] = NULL; - return arr; -} - -/*****************************************************************************/ +static void nm_settings_connection_connection_interface_init (NMConnectionInterface *iface); NM_GOBJECT_PROPERTIES_DEFINE (NMSettingsConnection, PROP_UNSAVED, @@ -106,8 +87,6 @@ typedef struct _NMSettingsConnectionPrivate { CList call_ids_lst_head; /* in-progress secrets requests */ - NMConnection *connection; - /* Caches secrets from on-disk connections; were they not cached any * call to nm_connection_clear_secrets() wipes them out and we'd have * to re-read them from disk which defeats the purpose of having the @@ -136,7 +115,9 @@ typedef struct _NMSettingsConnectionPrivate { } NMSettingsConnectionPrivate; -G_DEFINE_TYPE (NMSettingsConnection, nm_settings_connection, NM_TYPE_DBUS_OBJECT) +G_DEFINE_TYPE_WITH_CODE (NMSettingsConnection, nm_settings_connection, NM_TYPE_DBUS_OBJECT, + G_IMPLEMENT_INTERFACE (NM_TYPE_CONNECTION, nm_settings_connection_connection_interface_init) + ) #define NM_SETTINGS_CONNECTION_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR (self, NMSettingsConnection, NM_IS_SETTINGS_CONNECTION) @@ -171,16 +152,6 @@ static const NMDBusInterfaceInfoExtended interface_info_settings_connection; /*****************************************************************************/ -NMConnection * -nm_settings_connection_get_connection (NMSettingsConnection *self) -{ - g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL); - - return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->connection; -} - -/*****************************************************************************/ - gboolean nm_settings_connection_has_unmodified_applied_connection (NMSettingsConnection *self, NMConnection *applied_connection, @@ -192,8 +163,7 @@ nm_settings_connection_has_unmodified_applied_connection (NMSettingsConnection * /* for convenience, we *always* ignore certain settings. */ compare_flags |= NM_SETTING_COMPARE_FLAG_IGNORE_SECRETS | NM_SETTING_COMPARE_FLAG_IGNORE_TIMESTAMP; - return nm_connection_compare (nm_settings_connection_get_connection (self), - applied_connection, compare_flags); + return nm_connection_compare (NM_CONNECTION (self), applied_connection, compare_flags); } /*****************************************************************************/ @@ -362,7 +332,8 @@ nm_settings_connection_recheck_visibility (NMSettingsConnection *self) priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (self)); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (self)); + g_assert (s_con); /* Check every user in the ACL for a session */ num = nm_setting_connection_get_num_permissions (s_con); @@ -391,9 +362,9 @@ nm_settings_connection_recheck_visibility (NMSettingsConnection *self) } static void -session_changed_cb (NMSessionMonitor *self, NMSettingsConnection *sett_conn) +session_changed_cb (NMSessionMonitor *self, gpointer user_data) { - nm_settings_connection_recheck_visibility (sett_conn); + nm_settings_connection_recheck_visibility (NM_SETTINGS_CONNECTION (user_data)); } /*****************************************************************************/ @@ -419,7 +390,8 @@ nm_settings_connection_check_permission (NMSettingsConnection *self, NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE)) return FALSE; - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (self)); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (self)); + g_assert (s_con); /* Check every user in the ACL for a session */ num = nm_setting_connection_get_num_permissions (s_con); @@ -475,7 +447,7 @@ update_system_secrets_cache (NMSettingsConnection *self) if (priv->system_secrets) g_object_unref (priv->system_secrets); - priv->system_secrets = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self)); + priv->system_secrets = nm_simple_connection_new_clone (NM_CONNECTION (self)); /* Clear out non-system-owned and not-saved secrets */ nm_connection_clear_secrets_with_flags (priv->system_secrets, @@ -491,8 +463,7 @@ update_agent_secrets_cache (NMSettingsConnection *self, NMConnection *new) if (priv->agent_secrets) g_object_unref (priv->agent_secrets); - priv->agent_secrets = nm_simple_connection_new_clone ( new - ?: nm_settings_connection_get_connection (self)); + priv->agent_secrets = nm_simple_connection_new_clone (new ?: NM_CONNECTION(self)); /* Clear out non-system-owned secrets */ nm_connection_clear_secrets_with_flags (priv->agent_secrets, @@ -501,7 +472,7 @@ update_agent_secrets_cache (NMSettingsConnection *self, NMConnection *new) } static void -secrets_cleared_cb (NMConnection *connection, NMSettingsConnection *self) +secrets_cleared_cb (NMSettingsConnection *self) { NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); @@ -562,7 +533,7 @@ _emit_updated (NMSettingsConnection *self, gboolean by_user) } static void -connection_changed_cb (NMConnection *connection, NMSettingsConnection *self) +connection_changed_cb (NMSettingsConnection *self, gpointer unused) { set_persist_mode (self, NM_SETTINGS_CONNECTION_PERSIST_MODE_UNSAVED); _emit_updated (self, FALSE); @@ -665,7 +636,7 @@ nm_settings_connection_update (NMSettingsConnection *self, if (persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK) { if (!klass->commit_changes (self, - new_connection ?: nm_settings_connection_get_connection (self), + new_connection ?: NM_CONNECTION (self), commit_reason, &reread_connection, &logmsg_change, @@ -684,30 +655,30 @@ nm_settings_connection_update (NMSettingsConnection *self, /* Disconnect the changed signal to ensure we don't set Unsaved when * it's not required. */ - g_signal_handlers_block_by_func (priv->connection, G_CALLBACK (connection_changed_cb), self); + g_signal_handlers_block_by_func (self, G_CALLBACK (connection_changed_cb), NULL); /* Do nothing if there's nothing to update */ if ( replace_connection - && !nm_connection_compare (nm_settings_connection_get_connection (self), + && !nm_connection_compare (NM_CONNECTION (self), replace_connection, NM_SETTING_COMPARE_FLAG_EXACT)) { gs_unref_object NMConnection *simple = NULL; if (log_diff_name) { - nm_utils_log_connection_diff (replace_connection, nm_settings_connection_get_connection (self), LOGL_DEBUG, LOGD_CORE, log_diff_name, "++ ", + nm_utils_log_connection_diff (replace_connection, NM_CONNECTION (self), LOGL_DEBUG, LOGD_CORE, log_diff_name, "++ ", nm_dbus_object_get_path (NM_DBUS_OBJECT (self))); } /* Make a copy of agent-owned secrets because they won't be present in * the connection returned by plugins, as plugins return only what was * reread from the file. */ - simple = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self)); + simple = nm_simple_connection_new_clone (NM_CONNECTION (self)); nm_connection_clear_secrets_with_flags (simple, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); con_agent_secrets = nm_connection_to_dbus (simple, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); - nm_connection_replace_settings_from_connection (nm_settings_connection_get_connection (self), replace_connection); + nm_connection_replace_settings_from_connection (NM_CONNECTION (self), replace_connection); replaced = TRUE; } @@ -730,12 +701,12 @@ nm_settings_connection_update (NMSettingsConnection *self, dict = nm_connection_to_dbus (priv->agent_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); if (dict) { - (void) nm_connection_update_secrets (nm_settings_connection_get_connection (self), NULL, dict, NULL); + (void) nm_connection_update_secrets (NM_CONNECTION (self), NULL, dict, NULL); g_variant_unref (dict); } } if (con_agent_secrets) - (void) nm_connection_update_secrets (nm_settings_connection_get_connection (self), NULL, con_agent_secrets, NULL); + (void) nm_connection_update_secrets (NM_CONNECTION (self), NULL, con_agent_secrets, NULL); } nm_settings_connection_recheck_visibility (self); @@ -753,7 +724,7 @@ nm_settings_connection_update (NMSettingsConnection *self, NM_SETTINGS_CONNECTION_PERSIST_MODE_VOLATILE_DETACHED)) nm_settings_connection_set_filename (self, NULL); - g_signal_handlers_unblock_by_func (priv->connection, G_CALLBACK (connection_changed_cb), self); + g_signal_handlers_unblock_by_func (self, G_CALLBACK (connection_changed_cb), NULL); _emit_updated (self, TRUE); @@ -829,7 +800,7 @@ nm_settings_connection_delete (NMSettingsConnection *self, set_visible (self, FALSE); /* Tell agents to remove secrets for this connection */ - for_agents = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self)); + for_agents = nm_simple_connection_new_clone (NM_CONNECTION (self)); nm_connection_clear_secrets (for_agents); nm_agent_manager_delete_secrets (priv->agent_mgr, nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), @@ -949,7 +920,7 @@ get_cmp_flags (NMSettingsConnection *self, /* only needed for logging */ gboolean *agent_had_system, ForEachSecretFlags *cmp_flags) { - gboolean is_self = (nm_settings_connection_get_connection (self) == connection); + gboolean is_self = (((NMConnection *) self) == connection); g_return_if_fail (secrets); @@ -1030,7 +1001,7 @@ nm_settings_connection_new_secrets (NMSettingsConnection *self, return FALSE; } - if (!nm_connection_update_secrets (nm_settings_connection_get_connection (self), setting_name, secrets, error)) + if (!nm_connection_update_secrets (NM_CONNECTION (self), setting_name, secrets, error)) return FALSE; update_system_secrets_cache (self); @@ -1102,7 +1073,7 @@ get_secrets_done_cb (NMAgentManager *manager, goto out; } - if (!nm_connection_get_setting_by_name (nm_settings_connection_get_connection (self), setting_name)) { + if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { g_set_error (&local, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, "Connection didn't have requested setting '%s'.", setting_name); @@ -1112,7 +1083,7 @@ get_secrets_done_cb (NMAgentManager *manager, get_cmp_flags (self, call_id, - nm_settings_connection_get_connection (self), + NM_CONNECTION (self), agent_dbus_owner, agent_has_modify, setting_name, @@ -1129,8 +1100,8 @@ get_secrets_done_cb (NMAgentManager *manager, dict = nm_connection_to_dbus (priv->system_secrets, NM_CONNECTION_SERIALIZE_ONLY_SECRETS); /* Update the connection with our existing secrets from backing storage */ - nm_connection_clear_secrets (nm_settings_connection_get_connection (self)); - if (!dict || nm_connection_update_secrets (nm_settings_connection_get_connection (self), setting_name, dict, &local)) { + nm_connection_clear_secrets (NM_CONNECTION (self)); + if (!dict || nm_connection_update_secrets (NM_CONNECTION (self), setting_name, dict, &local)) { GVariant *filtered_secrets; /* Update the connection with the agent's secrets; by this point if any @@ -1138,8 +1109,8 @@ get_secrets_done_cb (NMAgentManager *manager, * will have been authenticated, so those secrets can replace the existing * system secrets. */ - filtered_secrets = for_each_secret (nm_settings_connection_get_connection (self), secrets, TRUE, validate_secret_flags, &cmp_flags); - if (nm_connection_update_secrets (nm_settings_connection_get_connection (self), setting_name, filtered_secrets, &local)) { + filtered_secrets = for_each_secret (NM_CONNECTION (self), secrets, TRUE, validate_secret_flags, &cmp_flags); + if (nm_connection_update_secrets (NM_CONNECTION (self), setting_name, filtered_secrets, &local)) { /* Now that all secrets are updated, copy and cache new secrets, * then save them to backing storage. */ @@ -1279,7 +1250,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NULL); g_return_val_if_fail ( !applied_connection || ( NM_IS_CONNECTION (applied_connection) - && (nm_settings_connection_get_connection (self) != applied_connection)), NULL); + && (((NMConnection *) self) != applied_connection)), NULL); call_id = g_slice_new0 (NMSettingsConnectionCallId); call_id->self = self; @@ -1293,7 +1264,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, c_list_link_tail (&priv->call_ids_lst_head, &call_id->call_ids_lst); /* Make sure the request actually requests something we can return */ - if (!nm_connection_get_setting_by_name (nm_settings_connection_get_connection (self), setting_name)) { + if (!nm_connection_get_setting_by_name (NM_CONNECTION (self), setting_name)) { g_set_error (&local, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_SETTING_NOT_FOUND, "Connection didn't have requested setting '%s'.", setting_name); @@ -1324,7 +1295,7 @@ nm_settings_connection_get_secrets (NMSettingsConnection *self, call_id_a = nm_agent_manager_get_secrets (priv->agent_mgr, nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), - nm_settings_connection_get_connection (self), + NM_CONNECTION (self), subject, existing_secrets, setting_name, @@ -1494,7 +1465,7 @@ auth_start (NMSettingsConnection *self, nm_assert (G_IS_DBUS_METHOD_INVOCATION (invocation)); nm_assert (NM_IS_AUTH_SUBJECT (subject)); - if (!nm_auth_is_subject_in_acl_set_error (nm_settings_connection_get_connection (self), + if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (self), subject, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, @@ -1568,14 +1539,15 @@ get_settings_auth_cb (NMSettingsConnection *self, if (error) g_dbus_method_invocation_return_gerror (context, error); else { - gs_unref_object NMConnection *dupl_con = NULL; GVariant *settings; + NMConnection *dupl_con; NMSettingConnection *s_con; NMSettingWireless *s_wifi; guint64 timestamp = 0; - gs_free char **bssids = NULL; + char **bssids; - dupl_con = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self)); + dupl_con = nm_simple_connection_new_clone (NM_CONNECTION (self)); + g_assert (dupl_con); /* Timestamp is not updated in connection's 'timestamp' property, * because it would force updating the connection and in turn @@ -1585,7 +1557,8 @@ get_settings_auth_cb (NMSettingsConnection *self, */ nm_settings_connection_get_timestamp (self, ×tamp); if (timestamp) { - s_con = nm_connection_get_setting_connection (dupl_con); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (dupl_con)); + g_assert (s_con); g_object_set (s_con, NM_SETTING_CONNECTION_TIMESTAMP, timestamp, NULL); } /* Seen BSSIDs are not updated in 802-11-wireless 'seen-bssids' property @@ -1593,17 +1566,20 @@ get_settings_auth_cb (NMSettingsConnection *self, * return settings too. */ bssids = nm_settings_connection_get_seen_bssids (self); - s_wifi = nm_connection_get_setting_wireless (dupl_con); + s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (dupl_con)); if (bssids && bssids[0] && s_wifi) g_object_set (s_wifi, NM_SETTING_WIRELESS_SEEN_BSSIDS, bssids, NULL); + g_free (bssids); /* Secrets should *never* be returned by the GetSettings method, they * get returned by the GetSecrets method which can be better * protected against leakage of secrets to unprivileged callers. */ - settings = nm_connection_to_dbus (dupl_con, NM_CONNECTION_SERIALIZE_NO_SECRETS); + settings = nm_connection_to_dbus (NM_CONNECTION (dupl_con), NM_CONNECTION_SERIALIZE_NO_SECRETS); + g_assert (settings); g_dbus_method_invocation_return_value (context, g_variant_new ("(@a{sa{sv}})", settings)); + g_object_unref (dupl_con); } } @@ -1758,7 +1734,7 @@ update_auth_cb (NMSettingsConnection *self, gs_unref_hashtable GHashTable *diff = NULL; gboolean same; - same = nm_connection_diff (nm_settings_connection_get_connection (self), info->new_settings, + same = nm_connection_diff (NM_CONNECTION (self), info->new_settings, NM_SETTING_COMPARE_FLAG_EXACT | NM_SETTING_COMPARE_FLAG_DIFF_RESULT_NO_DEFAULT, &diff); @@ -1769,7 +1745,7 @@ update_auth_cb (NMSettingsConnection *self, commit_reason = NM_SETTINGS_CONNECTION_COMMIT_REASON_USER_ACTION; if ( info->new_settings - && !nm_streq0 (nm_connection_get_id (nm_settings_connection_get_connection (self)), + && !nm_streq0 (nm_connection_get_id (NM_CONNECTION (self)), nm_connection_get_id (info->new_settings))) commit_reason |= NM_SETTINGS_CONNECTION_COMMIT_REASON_ID_CHANGED; @@ -1815,7 +1791,7 @@ update_auth_cb (NMSettingsConnection *self, * as agent-owned secrets are the only ones we send back be saved. * Only send secrets to agents of the same UID that called update too. */ - for_agent = nm_simple_connection_new_clone (nm_settings_connection_get_connection (self)); + for_agent = nm_simple_connection_new_clone (NM_CONNECTION (self)); nm_connection_clear_secrets_with_flags (for_agent, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); @@ -1835,9 +1811,11 @@ get_update_modify_permission (NMConnection *old, NMConnection *new) guint32 orig_num = 0, new_num = 0; s_con = nm_connection_get_setting_connection (old); + g_assert (s_con); orig_num = nm_setting_connection_get_num_permissions (s_con); s_con = nm_connection_get_setting_connection (new); + g_assert (s_con); new_num = nm_setting_connection_get_num_permissions (s_con); /* If the caller is the only user in either connection's permissions, then @@ -1870,7 +1848,7 @@ settings_connection_update (NMSettingsConnection *self, * the problem (ex a system settings plugin that can't write connections out) * instead of over D-Bus. */ - if (!check_writable (nm_settings_connection_get_connection (self), &error)) + if (!check_writable (NM_CONNECTION (self), &error)) goto error; /* Check if the settings are valid first */ @@ -1901,7 +1879,7 @@ settings_connection_update (NMSettingsConnection *self, * that's sending the update request. You can't make a connection * invisible to yourself. */ - if (!nm_auth_is_subject_in_acl_set_error (tmp ?: nm_settings_connection_get_connection (self), + if (!nm_auth_is_subject_in_acl_set_error (tmp ?: NM_CONNECTION(self), subject, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, @@ -1916,8 +1894,8 @@ settings_connection_update (NMSettingsConnection *self, info->flags = flags; info->new_settings = tmp; - permission = get_update_modify_permission (nm_settings_connection_get_connection (self), - tmp ?: nm_settings_connection_get_connection (self)); + permission = get_update_modify_permission (NM_CONNECTION (self), + tmp ?: NM_CONNECTION(self)); auth_start (self, context, subject, permission, update_auth_cb, info); return; @@ -2088,7 +2066,8 @@ get_modify_permission_basic (NMSettingsConnection *self) * we use the 'modify.own' permission instead of 'modify.system'. If the * request affects more than just the caller, require 'modify.system'. */ - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (self)); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (self)); + nm_assert (s_con); if (nm_setting_connection_get_num_permissions (s_con) == 1) return NM_AUTH_PERMISSION_SETTINGS_MODIFY_OWN; @@ -2108,7 +2087,7 @@ impl_settings_connection_delete (NMDBusObject *obj, gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; - if (!check_writable (nm_settings_connection_get_connection (self), &error)) + if (!check_writable (NM_CONNECTION (self), &error)) goto err; subject = _new_auth_subject (invocation, &error); @@ -2143,7 +2122,7 @@ dbus_get_agent_secrets_cb (NMSettingsConnection *self, * secrets from backing storage and those returned from the agent * by the time we get here. */ - dict = nm_connection_to_dbus (nm_settings_connection_get_connection (self), NM_CONNECTION_SERIALIZE_ONLY_SECRETS); + dict = nm_connection_to_dbus (NM_CONNECTION (self), NM_CONNECTION_SERIALIZE_ONLY_SECRETS); if (!dict) dict = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0); g_dbus_method_invocation_return_value (context, g_variant_new ("(@a{sa{sv}})", dict)); @@ -2225,7 +2204,7 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self, } /* Clear secrets in connection and caches */ - nm_connection_clear_secrets (nm_settings_connection_get_connection (self)); + nm_connection_clear_secrets (NM_CONNECTION (self)); if (priv->system_secrets) nm_connection_clear_secrets (priv->system_secrets); if (priv->agent_secrets) @@ -2234,7 +2213,7 @@ dbus_clear_secrets_auth_cb (NMSettingsConnection *self, /* Tell agents to remove secrets for this connection */ nm_agent_manager_delete_secrets (priv->agent_mgr, nm_dbus_object_get_path (NM_DBUS_OBJECT (self)), - nm_settings_connection_get_connection (self)); + NM_CONNECTION (self)); nm_settings_connection_update (self, NULL, @@ -2409,8 +2388,15 @@ _cmp_timestamp (NMSettingsConnection *a, NMSettingsConnection *b) static int _cmp_last_resort (NMSettingsConnection *a, NMSettingsConnection *b) { - NM_CMP_DIRECT_STRCMP0 (nm_settings_connection_get_uuid (a), - nm_settings_connection_get_uuid (b)); + int c; + + nm_assert (NM_IS_SETTINGS_CONNECTION (a)); + nm_assert (NM_IS_SETTINGS_CONNECTION (b)); + + c = g_strcmp0 (nm_connection_get_uuid (NM_CONNECTION (a)), + nm_connection_get_uuid (NM_CONNECTION (b))); + if (c) + return c; /* hm, same UUID. Use their pointer value to give them a stable * order. */ @@ -2425,11 +2411,19 @@ _cmp_last_resort (NMSettingsConnection *a, NMSettingsConnection *b) int nm_settings_connection_cmp_timestamp (NMSettingsConnection *a, NMSettingsConnection *b) { - NM_CMP_SELF (a, b); + int c; - NM_CMP_RETURN (_cmp_timestamp (a, b)); - NM_CMP_RETURN (nm_utils_cmp_connection_by_autoconnect_priority (nm_settings_connection_get_connection (a), - nm_settings_connection_get_connection (b))); + if (a == b) + return 0; + if (!a) + return 1; + if (!b) + return -1; + + if ((c = _cmp_timestamp (a, b))) + return c; + if ((c = nm_utils_cmp_connection_by_autoconnect_priority (NM_CONNECTION (a), NM_CONNECTION (b)))) + return c; return _cmp_last_resort (a, b); } @@ -2443,11 +2437,14 @@ nm_settings_connection_cmp_timestamp_p_with_data (gconstpointer pa, gconstpointe int nm_settings_connection_cmp_autoconnect_priority (NMSettingsConnection *a, NMSettingsConnection *b) { + int c; + if (a == b) return 0; - NM_CMP_RETURN (nm_utils_cmp_connection_by_autoconnect_priority (nm_settings_connection_get_connection (a), - nm_settings_connection_get_connection (b))); - NM_CMP_RETURN (_cmp_timestamp (a, b)); + if ((c = nm_utils_cmp_connection_by_autoconnect_priority (NM_CONNECTION (a), NM_CONNECTION (b)))) + return c; + if ((c = _cmp_timestamp (a, b))) + return c; return _cmp_last_resort (a, b); } @@ -2730,7 +2727,7 @@ nm_settings_connection_read_and_fill_seen_bssids (NMSettingsConnection *self) * seen-bssids list from the deprecated seen-bssids property of the * wifi setting. */ - s_wifi = nm_connection_get_setting_wireless (nm_settings_connection_get_connection (self)); + s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (self)); if (s_wifi) { len = nm_setting_wireless_get_num_seen_bssids (s_wifi); for (i = 0; i < len; i++) { @@ -2750,7 +2747,7 @@ _autoconnect_retries_initial (NMSettingsConnection *self) NMSettingConnection *s_con; int retries = -1; - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (self)); + s_con = nm_connection_get_setting_connection ((NMConnection *) self); if (s_con) retries = nm_setting_connection_get_autoconnect_retries (s_con); @@ -2962,19 +2959,13 @@ nm_settings_connection_get_filename (NMSettingsConnection *self) const char * nm_settings_connection_get_id (NMSettingsConnection *self) { - return nm_connection_get_id (nm_settings_connection_get_connection (self)); + return nm_connection_get_id (NM_CONNECTION (self)); } const char * nm_settings_connection_get_uuid (NMSettingsConnection *self) { - return nm_connection_get_uuid (nm_settings_connection_get_connection (self)); -} - -const char * -nm_settings_connection_get_connection_type (NMSettingsConnection *self) -{ - return nm_connection_get_connection_type (nm_settings_connection_get_connection (self)); + return nm_connection_get_uuid (NM_CONNECTION (self)); } /*****************************************************************************/ @@ -3004,10 +2995,8 @@ nm_settings_connection_init (NMSettingsConnection *self) priv->autoconnect_retries = AUTOCONNECT_RETRIES_UNSET; - priv->connection = nm_simple_connection_new (); - - g_signal_connect (priv->connection, NM_CONNECTION_SECRETS_CLEARED, G_CALLBACK (secrets_cleared_cb), self); - g_signal_connect (priv->connection, NM_CONNECTION_CHANGED, G_CALLBACK (connection_changed_cb), self); + g_signal_connect (self, NM_CONNECTION_SECRETS_CLEARED, G_CALLBACK (secrets_cleared_cb), NULL); + g_signal_connect (self, NM_CONNECTION_CHANGED, G_CALLBACK (connection_changed_cb), NULL); } static void @@ -3038,32 +3027,26 @@ dispose (GObject *object) _get_secrets_cancel (self, call_id, TRUE); } - set_visible (self, FALSE); - - if (priv->connection) { - /* Disconnect handlers. - * connection_changed_cb() has to be disconnected *before* nm_connection_clear_secrets(), - * because nm_connection_clear_secrets() emits NM_CONNECTION_CHANGED signal. - */ - g_signal_handlers_disconnect_by_func (priv->connection, G_CALLBACK (secrets_cleared_cb), self); - g_signal_handlers_disconnect_by_func (priv->connection, G_CALLBACK (connection_changed_cb), self); - - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - nm_connection_clear_secrets (priv->connection); - } + /* Disconnect handlers. + * connection_changed_cb() has to be disconnected *before* nm_connection_clear_secrets(), + * because nm_connection_clear_secrets() emits NM_CONNECTION_CHANGED signal. + */ + g_signal_handlers_disconnect_by_func (self, G_CALLBACK (secrets_cleared_cb), NULL); + g_signal_handlers_disconnect_by_func (self, G_CALLBACK (connection_changed_cb), NULL); + nm_connection_clear_secrets (NM_CONNECTION (self)); g_clear_object (&priv->system_secrets); g_clear_object (&priv->agent_secrets); g_clear_pointer (&priv->seen_bssids, g_hash_table_destroy); + set_visible (self, FALSE); + nm_clear_g_signal_handler (priv->session_monitor, &priv->session_changed_id); g_clear_object (&priv->session_monitor); g_clear_object (&priv->agent_mgr); - g_clear_object (&priv->connection); - g_clear_pointer (&priv->filename, g_free); G_OBJECT_CLASS (nm_settings_connection_parent_class)->dispose (object); @@ -3281,3 +3264,9 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } + +static void +nm_settings_connection_connection_interface_init (NMConnectionInterface *iface) +{ +} + diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index e796b716..cd64f976 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -139,8 +139,6 @@ struct _NMSettingsConnectionClass { GType nm_settings_connection_get_type (void); -NMConnection *nm_settings_connection_get_connection (NMSettingsConnection *self); - guint64 nm_settings_connection_get_last_secret_agent_version_id (NMSettingsConnection *self); gboolean nm_settings_connection_has_unmodified_applied_connection (NMSettingsConnection *self, @@ -270,13 +268,7 @@ void nm_settings_connection_set_filename (NMSettingsConnection *self, const char *filename); const char *nm_settings_connection_get_filename (NMSettingsConnection *self); -const char *nm_settings_connection_get_id (NMSettingsConnection *connection); -const char *nm_settings_connection_get_uuid (NMSettingsConnection *connection); -const char *nm_settings_connection_get_connection_type (NMSettingsConnection *connection); - -/*****************************************************************************/ - -NMConnection **nm_settings_connections_array_to_connections (NMSettingsConnection *const*connections, - gssize n_connections); +const char *nm_settings_connection_get_id (NMSettingsConnection *connection); +const char *nm_settings_connection_get_uuid (NMSettingsConnection *connection); #endif /* __NETWORKMANAGER_SETTINGS_CONNECTION_H__ */ diff --git a/src/settings/nm-settings-plugin.c b/src/settings/nm-settings-plugin.c index e7275631..f6dd2cfb 100644 --- a/src/settings/nm-settings-plugin.c +++ b/src/settings/nm-settings-plugin.c @@ -15,94 +15,117 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2018 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. */ #include "nm-default.h" #include "nm-settings-plugin.h" - #include "nm-settings-connection.h" -/*****************************************************************************/ - -enum { - CONNECTION_ADDED, - UNMANAGED_SPECS_CHANGED, - UNRECOGNIZED_SPECS_CHANGED, - - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (NMSettingsPlugin, nm_settings_plugin, G_TYPE_OBJECT) +G_DEFINE_INTERFACE (NMSettingsPlugin, nm_settings_plugin, G_TYPE_OBJECT) -/*****************************************************************************/ +static void +nm_settings_plugin_default_init (NMSettingsPluginInterface *g_iface) +{ + GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); + static gboolean initialized = FALSE; + + if (initialized) + return; + + /* Signals */ + g_signal_new (NM_SETTINGS_PLUGIN_CONNECTION_ADDED, + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSettingsPluginInterface, connection_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + NM_TYPE_SETTINGS_CONNECTION); + + g_signal_new (NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED, + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSettingsPluginInterface, unmanaged_specs_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + g_signal_new (NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED, + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMSettingsPluginInterface, unrecognized_specs_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + initialized = TRUE; +} void -nm_settings_plugin_initialize (NMSettingsPlugin *self) +nm_settings_plugin_init (NMSettingsPlugin *config) { - g_return_if_fail (NM_IS_SETTINGS_PLUGIN (self)); + g_return_if_fail (config != NULL); - if (NM_SETTINGS_PLUGIN_GET_CLASS (self)->initialize) - NM_SETTINGS_PLUGIN_GET_CLASS (self)->initialize (self); + if (NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->init) + NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->init (config); } GSList * -nm_settings_plugin_get_connections (NMSettingsPlugin *self) +nm_settings_plugin_get_connections (NMSettingsPlugin *config) { - g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), NULL); + g_return_val_if_fail (config != NULL, NULL); - if (NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_connections) - return NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_connections (self); + if (NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->get_connections) + return NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->get_connections (config); return NULL; } gboolean -nm_settings_plugin_load_connection (NMSettingsPlugin *self, +nm_settings_plugin_load_connection (NMSettingsPlugin *config, const char *filename) { - g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), FALSE); + g_return_val_if_fail (config != NULL, FALSE); - if (NM_SETTINGS_PLUGIN_GET_CLASS (self)->load_connection) - return NM_SETTINGS_PLUGIN_GET_CLASS (self)->load_connection (self, filename); + if (NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->load_connection) + return NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->load_connection (config, filename); return FALSE; } void -nm_settings_plugin_reload_connections (NMSettingsPlugin *self) +nm_settings_plugin_reload_connections (NMSettingsPlugin *config) { - g_return_if_fail (NM_IS_SETTINGS_PLUGIN (self)); + g_return_if_fail (config != NULL); - if (NM_SETTINGS_PLUGIN_GET_CLASS (self)->reload_connections) - NM_SETTINGS_PLUGIN_GET_CLASS (self)->reload_connections (self); + if (NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->reload_connections) + NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->reload_connections (config); } GSList * -nm_settings_plugin_get_unmanaged_specs (NMSettingsPlugin *self) +nm_settings_plugin_get_unmanaged_specs (NMSettingsPlugin *config) { - g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), NULL); + g_return_val_if_fail (config != NULL, NULL); - if (NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_unmanaged_specs) - return NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_unmanaged_specs (self); + if (NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->get_unmanaged_specs) + return NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->get_unmanaged_specs (config); return NULL; } GSList * -nm_settings_plugin_get_unrecognized_specs (NMSettingsPlugin *self) +nm_settings_plugin_get_unrecognized_specs (NMSettingsPlugin *config) { - g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), NULL); + g_return_val_if_fail (config != NULL, NULL); - if (NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_unrecognized_specs) - return NM_SETTINGS_PLUGIN_GET_CLASS (self)->get_unrecognized_specs (self); + if (NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->get_unrecognized_specs) + return NM_SETTINGS_PLUGIN_GET_INTERFACE (config)->get_unrecognized_specs (config); return NULL; } /** * nm_settings_plugin_add_connection: - * @self: the #NMSettingsPlugin + * @config: the #NMSettingsPlugin * @connection: the source connection to create a plugin-specific * #NMSettingsConnection from * @save_to_disk: %TRUE to save the connection to disk immediately, %FALSE to @@ -117,88 +140,22 @@ nm_settings_plugin_get_unrecognized_specs (NMSettingsPlugin *self) * Returns: the new #NMSettingsConnection or %NULL */ NMSettingsConnection * -nm_settings_plugin_add_connection (NMSettingsPlugin *self, +nm_settings_plugin_add_connection (NMSettingsPlugin *config, NMConnection *connection, gboolean save_to_disk, GError **error) { - NMSettingsPluginClass *klass; + NMSettingsPluginInterface *config_interface; - g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (self), NULL); + g_return_val_if_fail (config != NULL, NULL); g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - klass = NM_SETTINGS_PLUGIN_GET_CLASS (self); - if (!klass->add_connection) { + config_interface = NM_SETTINGS_PLUGIN_GET_INTERFACE (config); + if (!config_interface->add_connection) { g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_NOT_SUPPORTED, "Plugin does not support adding connections"); return NULL; } - return klass->add_connection (self, connection, save_to_disk, error); -} - -/*****************************************************************************/ - -void -_nm_settings_plugin_emit_signal_connection_added (NMSettingsPlugin *self, - NMSettingsConnection *sett_conn) -{ - nm_assert (NM_IS_SETTINGS_PLUGIN (self)); - nm_assert (NM_IS_SETTINGS_CONNECTION (sett_conn)); - - g_signal_emit (self, signals[CONNECTION_ADDED], 0, sett_conn); -} - -void -_nm_settings_plugin_emit_signal_unmanaged_specs_changed (NMSettingsPlugin *self) -{ - nm_assert (NM_IS_SETTINGS_PLUGIN (self)); - - g_signal_emit (self, signals[UNMANAGED_SPECS_CHANGED], 0); -} - -void -_nm_settings_plugin_emit_signal_unrecognized_specs_changed (NMSettingsPlugin *self) -{ - nm_assert (NM_IS_SETTINGS_PLUGIN (self)); - - g_signal_emit (self, signals[UNRECOGNIZED_SPECS_CHANGED], 0); -} - -/*****************************************************************************/ - -static void -nm_settings_plugin_init (NMSettingsPlugin *self) -{ -} - -static void -nm_settings_plugin_class_init (NMSettingsPluginClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - signals[CONNECTION_ADDED] = - g_signal_new (NM_SETTINGS_PLUGIN_CONNECTION_ADDED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, - NM_TYPE_SETTINGS_CONNECTION); - - signals[UNMANAGED_SPECS_CHANGED] = - g_signal_new (NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[UNRECOGNIZED_SPECS_CHANGED] = - g_signal_new (NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED, - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - 0, NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + return config_interface->add_connection (config, connection, save_to_disk, error); } diff --git a/src/settings/nm-settings-plugin.h b/src/settings/nm-settings-plugin.h index fdd48f2b..6fba25e7 100644 --- a/src/settings/nm-settings-plugin.h +++ b/src/settings/nm-settings-plugin.h @@ -15,52 +15,53 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2007 - 2018 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. * Copyright (C) 2008 Novell, Inc. */ -#ifndef __NM_SETTINGS_PLUGIN_H__ -#define __NM_SETTINGS_PLUGIN_H__ +#ifndef __NETWORKMANAGER_SETTINGS_PLUGIN_H__ +#define __NETWORKMANAGER_SETTINGS_PLUGIN_H__ #include "nm-connection.h" +/* Plugin's factory function that returns a GObject that implements + * NMSettingsPlugin. + */ +GObject * nm_settings_plugin_factory (void); + #define NM_TYPE_SETTINGS_PLUGIN (nm_settings_plugin_get_type ()) #define NM_SETTINGS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPlugin)) -#define NM_SETTINGS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPluginClass)) #define NM_IS_SETTINGS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTINGS_PLUGIN)) -#define NM_IS_SETTINGS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTINGS_PLUGIN)) -#define NM_SETTINGS_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPluginClass)) +#define NM_SETTINGS_PLUGIN_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_SETTINGS_PLUGIN, NMSettingsPluginInterface)) -#define NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED "unmanaged-specs-changed" +#define NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED "unmanaged-specs-changed" #define NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED "unrecognized-specs-changed" -#define NM_SETTINGS_PLUGIN_CONNECTION_ADDED "connection-added" +#define NM_SETTINGS_PLUGIN_CONNECTION_ADDED "connection-added" -typedef struct { - GObject parent; -} NMSettingsPlugin; +typedef struct _NMSettingsPlugin NMSettingsPlugin; typedef struct { - GObjectClass parent; + GTypeInterface g_iface; /* Called when the plugin is loaded to initialize it */ - void (*initialize) (NMSettingsPlugin *plugin); + void (*init) (NMSettingsPlugin *config); /* Returns a GSList of NMSettingsConnection objects that represent * connections the plugin knows about. The returned list is freed by the * system settings service. */ - GSList * (*get_connections) (NMSettingsPlugin *plugin); + GSList * (*get_connections) (NMSettingsPlugin *config); /* Requests that the plugin load/reload a single connection, if it * recognizes the filename. Returns success or failure. */ - gboolean (*load_connection) (NMSettingsPlugin *plugin, + gboolean (*load_connection) (NMSettingsPlugin *config, const char *filename); /* Requests that the plugin reload all connection files from disk, * and emit signals reflecting new, changed, and removed connections. */ - void (*reload_connections) (NMSettingsPlugin *plugin); + void (*reload_connections) (NMSettingsPlugin *config); /* * Return a string list of specifications of devices which NetworkManager @@ -71,7 +72,7 @@ typedef struct { * Each string in the list must be in one of the formats recognized by * nm_device_spec_match_list(). */ - GSList * (*get_unmanaged_specs) (NMSettingsPlugin *plugin); + GSList * (*get_unmanaged_specs) (NMSettingsPlugin *config); /* * Return a string list of specifications of devices for which at least @@ -83,7 +84,7 @@ typedef struct { * Each string in the list must be in one of the formats recognized by * nm_device_spec_match_list(). */ - GSList * (*get_unrecognized_specs) (NMSettingsPlugin *plugin); + GSList * (*get_unrecognized_specs) (NMSettingsPlugin *config); /* * Initialize the plugin-specific connection and return a new @@ -92,42 +93,40 @@ typedef struct { * storage if @save_to_disk is TRUE. The returned object is owned by the * plugin and must be referenced by the owner if necessary. */ - NMSettingsConnection * (*add_connection) (NMSettingsPlugin *plugin, + NMSettingsConnection * (*add_connection) (NMSettingsPlugin *config, NMConnection *connection, gboolean save_to_disk, GError **error); -} NMSettingsPluginClass; -GType nm_settings_plugin_get_type (void); + /* Signals */ + + /* Emitted when a new connection has been found by the plugin */ + void (*connection_added) (NMSettingsPlugin *config, + NMSettingsConnection *connection); -typedef NMSettingsPlugin *(*NMSettingsPluginFactoryFunc) (void); + /* Emitted when the list of unmanaged device specifications changes */ + void (*unmanaged_specs_changed) (NMSettingsPlugin *config); -/* Plugin's factory function that returns a #NMSettingsPlugin */ -NMSettingsPlugin *nm_settings_plugin_factory (void); + /* Emitted when the list of devices with unrecognized connections changes */ + void (*unrecognized_specs_changed) (NMSettingsPlugin *config); +} NMSettingsPluginInterface; -void nm_settings_plugin_initialize (NMSettingsPlugin *config); +GType nm_settings_plugin_get_type (void); -GSList *nm_settings_plugin_get_connections (NMSettingsPlugin *plugin); +void nm_settings_plugin_init (NMSettingsPlugin *config); -gboolean nm_settings_plugin_load_connection (NMSettingsPlugin *plugin, +GSList *nm_settings_plugin_get_connections (NMSettingsPlugin *config); + +gboolean nm_settings_plugin_load_connection (NMSettingsPlugin *config, const char *filename); -void nm_settings_plugin_reload_connections (NMSettingsPlugin *plugin); +void nm_settings_plugin_reload_connections (NMSettingsPlugin *config); -GSList *nm_settings_plugin_get_unmanaged_specs (NMSettingsPlugin *plugin); -GSList *nm_settings_plugin_get_unrecognized_specs (NMSettingsPlugin *plugin); +GSList *nm_settings_plugin_get_unmanaged_specs (NMSettingsPlugin *config); +GSList *nm_settings_plugin_get_unrecognized_specs (NMSettingsPlugin *config); -NMSettingsConnection *nm_settings_plugin_add_connection (NMSettingsPlugin *plugin, +NMSettingsConnection *nm_settings_plugin_add_connection (NMSettingsPlugin *config, NMConnection *connection, gboolean save_to_disk, GError **error); -/* internal API */ - -void _nm_settings_plugin_emit_signal_connection_added (NMSettingsPlugin *plugin, - NMSettingsConnection *sett_conn); - -void _nm_settings_plugin_emit_signal_unmanaged_specs_changed (NMSettingsPlugin *plugin); - -void _nm_settings_plugin_emit_signal_unrecognized_specs_changed (NMSettingsPlugin *plugin); - -#endif /* __NM_SETTINGS_PLUGIN_H__ */ +#endif /* __NETWORKMANAGER_SETTINGS_PLUGIN_H__ */ diff --git a/src/settings/nm-settings.c b/src/settings/nm-settings.c index 2253d56a..5bb629dc 100644 --- a/src/settings/nm-settings.c +++ b/src/settings/nm-settings.c @@ -214,9 +214,9 @@ connection_ready_changed (NMSettingsConnection *conn, static void plugin_connection_added (NMSettingsPlugin *config, NMSettingsConnection *connection, - NMSettings *self) + gpointer user_data) { - claim_connection (self, connection); + claim_connection (NM_SETTINGS (user_data), connection); } static void @@ -237,7 +237,7 @@ load_connections (NMSettings *self) // priority plugin. for (elt = plugin_connections; elt; elt = g_slist_next (elt)) - claim_connection (self, elt->data); + claim_connection (self, NM_SETTINGS_CONNECTION (elt->data)); g_slist_free (plugin_connections); @@ -306,15 +306,15 @@ impl_settings_get_connection_by_uuid (NMDBusObject *obj, GVariant *parameters) { NMSettings *self = NM_SETTINGS (obj); - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection = NULL; gs_unref_object NMAuthSubject *subject = NULL; GError *error = NULL; const char *uuid; g_variant_get (parameters, "(&s)", &uuid); - sett_conn = nm_settings_get_connection_by_uuid (self, uuid); - if (!sett_conn) { + connection = nm_settings_get_connection_by_uuid (self, uuid); + if (!connection) { error = g_error_new_literal (NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "No connection with the UUID was found."); @@ -329,7 +329,7 @@ impl_settings_get_connection_by_uuid (NMDBusObject *obj, goto error; } - if (!nm_auth_is_subject_in_acl_set_error (nm_settings_connection_get_connection (sett_conn), + if (!nm_auth_is_subject_in_acl_set_error (NM_CONNECTION (connection), subject, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_PERMISSION_DENIED, @@ -338,7 +338,7 @@ impl_settings_get_connection_by_uuid (NMDBusObject *obj, g_dbus_method_invocation_return_value (invocation, g_variant_new ("(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn)))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)))); return; error: @@ -362,7 +362,6 @@ _clear_connections_cached_list (NMSettingsPrivate *priv) 0xdeaddead, sizeof (NMSettingsConnection *) * (priv->connections_len + 1)); #endif - nm_clear_g_free (&priv->connections_cached_list); } @@ -481,8 +480,8 @@ nm_settings_get_connection_by_path (NMSettings *self, const char *path) priv = NM_SETTINGS_GET_PRIVATE (self); - connection = nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), - path); + connection = (NMSettingsConnection *) nm_dbus_manager_lookup_object (nm_dbus_object_get_manager (NM_DBUS_OBJECT (self)), + path); if ( !connection || !NM_IS_SETTINGS_CONNECTION (connection)) return NULL; @@ -526,6 +525,28 @@ nm_settings_get_unmanaged_specs (NMSettings *self) return priv->unmanaged_specs; } +static NMSettingsPlugin * +get_plugin (NMSettings *self, gboolean has_add_connection) +{ + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); + GSList *iter; + + g_return_val_if_fail (self != NULL, NULL); + + /* Do any of the plugins support the given capability? */ + for (iter = priv->plugins; iter; iter = iter->next) { + NMSettingsPlugin *plugin = NM_SETTINGS_PLUGIN (iter->data); + + if (!has_add_connection) + return plugin; + + if (NM_SETTINGS_PLUGIN_GET_INTERFACE (iter->data)->add_connection != NULL) + return plugin; + } + + return NULL; +} + static gboolean find_spec (GSList *spec_list, const char *spec) { @@ -586,49 +607,67 @@ unrecognized_specs_changed (NMSettingsPlugin *config, nm_settings_plugin_get_unrecognized_specs); } -static void -add_plugin (NMSettings *self, NMSettingsPlugin *plugin, const char *path) +static gboolean +add_plugin (NMSettings *self, NMSettingsPlugin *plugin) { NMSettingsPrivate *priv; + const char *path; - nm_assert (NM_IS_SETTINGS (self)); - nm_assert (NM_IS_SETTINGS_PLUGIN (plugin)); + g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); + g_return_val_if_fail (NM_IS_SETTINGS_PLUGIN (plugin), FALSE); priv = NM_SETTINGS_GET_PRIVATE (self); - nm_assert (!g_slist_find (priv->plugins, plugin)); + if (g_slist_find (priv->plugins, plugin)) { + /* don't add duplicates. */ + return FALSE; + } priv->plugins = g_slist_append (priv->plugins, g_object_ref (plugin)); + nm_settings_plugin_init (plugin); + + + path = g_object_get_qdata (G_OBJECT (plugin), plugin_module_path_quark ()); - nm_settings_plugin_initialize (plugin); + _LOGI ("Loaded settings plugin: %s (%s)", G_OBJECT_TYPE_NAME (plugin), path ?: "internal"); - _LOGI ("Loaded settings plugin: %s (%s%s%s)", - G_OBJECT_TYPE_NAME (plugin), - NM_PRINT_FMT_QUOTED (path, "\"", path, "\"", "internal")); + return TRUE; } static gboolean -add_plugin_load_file (NMSettings *self, const char *pname, GError **error) +plugin_loaded (GSList *list, const char *path) +{ + GSList *iter; + + g_return_val_if_fail (path != NULL, TRUE); + + for (iter = list; iter; iter = g_slist_next (iter)) { + const char *list_path = g_object_get_qdata (G_OBJECT (iter->data), + plugin_module_path_quark ()); + + if (g_strcmp0 (path, list_path) == 0) + return TRUE; + } + + return FALSE; +} + +static gboolean +load_plugin (NMSettings *self, GSList **list, const char *pname, GError **error) { - NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); gs_free char *full_name = NULL; gs_free char *path = NULL; - gs_unref_object NMSettingsPlugin *plugin = NULL; - GModule *module; - NMSettingsPluginFactoryFunc factory_func; - GSList *iter; + gs_unref_object GObject *obj = NULL; + GModule *plugin; + GObject * (*factory_func) (void); struct stat st; int errsv; full_name = g_strdup_printf ("nm-settings-plugin-%s", pname); path = g_module_build_path (NMPLUGINDIR, full_name); - for (iter = priv->plugins; iter; iter = iter->next) { - if (nm_streq0 (path, - g_object_get_qdata (iter->data, - plugin_module_path_quark ()))) - return TRUE; - } + if (plugin_loaded (*list, path)) + return TRUE; if (stat (path, &st) != 0) { errsv = errno; @@ -648,8 +687,8 @@ add_plugin_load_file (NMSettings *self, const char *pname, GError **error) return TRUE; } - module = g_module_open (path, G_MODULE_BIND_LOCAL); - if (!module) { + plugin = g_module_open (path, G_MODULE_BIND_LOCAL); + if (!plugin) { _LOGW ("could not load plugin '%s' from file '%s': %s", pname, path, g_module_error ()); return TRUE; @@ -657,46 +696,48 @@ add_plugin_load_file (NMSettings *self, const char *pname, GError **error) /* errors after this point are fatal, because we loaded the shared library already. */ - if (!g_module_symbol (module, "nm_settings_plugin_factory", (gpointer) (&factory_func))) { + if (!g_module_symbol (plugin, "nm_settings_plugin_factory", (gpointer) (&factory_func))) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, "Could not find plugin '%s' factory function.", pname); - g_module_close (module); + g_module_close (plugin); return FALSE; } /* after accessing the plugin we cannot unload it anymore, because the glib * types cannot be properly unregistered. */ - g_module_make_resident (module); + g_module_make_resident (plugin); - plugin = (*factory_func) (); - if (!NM_IS_SETTINGS_PLUGIN (plugin)) { + obj = (*factory_func) (); + if (!obj || !NM_IS_SETTINGS_PLUGIN (obj)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, - "plugin '%s' returned invalid settings plugin", + "Plugin '%s' returned invalid system config object.", pname); return FALSE; } - add_plugin (self, NM_SETTINGS_PLUGIN (plugin), path); - g_object_set_qdata_full (G_OBJECT (plugin), - plugin_module_path_quark (), - g_steal_pointer (&path), - g_free); + g_object_set_qdata_full (obj, plugin_module_path_quark (), path, g_free); + path = NULL; + if (add_plugin (self, NM_SETTINGS_PLUGIN (obj))) + *list = g_slist_append (*list, g_steal_pointer (&obj)); + return TRUE; } static void -add_plugin_keyfile (NMSettings *self) +add_keyfile_plugin (NMSettings *self) { gs_unref_object NMSKeyfilePlugin *keyfile_plugin = NULL; keyfile_plugin = nms_keyfile_plugin_new (); - add_plugin (self, NM_SETTINGS_PLUGIN (keyfile_plugin), NULL); + if (!add_plugin (self, NM_SETTINGS_PLUGIN (keyfile_plugin))) + g_return_if_reached (); } static gboolean load_plugins (NMSettings *self, const char **plugins, GError **error) { + GSList *list = NULL; const char **iter; gboolean keyfile_added = FALSE; gboolean success = TRUE; @@ -724,15 +765,15 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) continue; } - if (nm_streq (pname, "no-ibft")) + if (!strcmp (pname, "no-ibft")) continue; - if (has_no_ibft && nm_streq (pname, "ibft")) + if (has_no_ibft && !strcmp (pname, "ibft")) continue; /* keyfile plugin is built-in now */ - if (nm_streq (pname, "keyfile")) { + if (strcmp (pname, "keyfile") == 0) { if (!keyfile_added) { - add_plugin_keyfile (self); + add_keyfile_plugin (self); keyfile_added = TRUE; } continue; @@ -746,25 +787,27 @@ load_plugins (NMSettings *self, const char **plugins, GError **error) continue; } - success = add_plugin_load_file (self, pname, error); + success = load_plugin (self, &list, pname, error); if (!success) break; - if (add_ibft && nm_streq (pname, "ifcfg-rh")) { + if (add_ibft && !strcmp (pname, "ifcfg-rh")) { /* The plugin ibft is not explicitly mentioned but we just enabled "ifcfg-rh". * Enable "ibft" by default after "ifcfg-rh". */ pname = "ibft"; add_ibft = FALSE; - success = add_plugin_load_file (self, "ibft", error); + success = load_plugin (self, &list, "ibft", error); if (!success) break; } } /* If keyfile plugin was not among configured plugins, add it as the last one */ - if (!keyfile_added && success) - add_plugin_keyfile (self); + if (!keyfile_added) + add_keyfile_plugin (self); + + g_slist_free_full (list, g_object_unref); return success; } @@ -888,33 +931,29 @@ openconnect_migrate_hack (NMConnection *connection) } static void -claim_connection (NMSettings *self, NMSettingsConnection *sett_conn) +claim_connection (NMSettings *self, NMSettingsConnection *connection) { - NMSettingsPrivate *priv; + NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); GError *error = NULL; const char *path; NMSettingsConnection *existing; - g_return_if_fail (NM_IS_SETTINGS (self)); - g_return_if_fail (NM_IS_SETTINGS_CONNECTION (sett_conn)); - g_return_if_fail (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (sett_conn))); - - priv = NM_SETTINGS_GET_PRIVATE (self); + g_return_if_fail (NM_IS_SETTINGS_CONNECTION (connection)); + g_return_if_fail (!nm_dbus_object_is_exported (NM_DBUS_OBJECT (connection))); /* prevent duplicates */ - if (!c_list_is_empty (&sett_conn->_connections_lst)) { - nm_assert (c_list_contains (&priv->connections_lst_head, &sett_conn->_connections_lst)); + if (!c_list_is_empty (&connection->_connections_lst)) { + nm_assert (c_list_contains (&priv->connections_lst_head, &connection->_connections_lst)); return; } - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - if (!nm_connection_normalize (nm_settings_connection_get_connection (sett_conn), NULL, NULL, &error)) { + if (!nm_connection_normalize (NM_CONNECTION (connection), NULL, NULL, &error)) { _LOGW ("plugin provided invalid connection: %s", error->message); g_error_free (error); return; } - existing = nm_settings_get_connection_by_uuid (self, nm_settings_connection_get_uuid (sett_conn)); + existing = nm_settings_get_connection_by_uuid (self, nm_settings_connection_get_uuid (connection)); if (existing) { /* Cannot add duplicate connections per UUID. Just return without action and * log a warning. @@ -927,56 +966,51 @@ claim_connection (NMSettings *self, NMSettingsConnection *sett_conn) * error out. That should not happen unless the admin misconfigured the system * to create conflicting connections. */ _LOGW ("plugin provided duplicate connection with UUID %s", - nm_settings_connection_get_uuid (sett_conn)); + nm_settings_connection_get_uuid (connection)); return; } /* Read timestamp from look-aside file and put it into the connection's data */ - nm_settings_connection_read_and_fill_timestamp (sett_conn); + nm_settings_connection_read_and_fill_timestamp (connection); /* Read seen-bssids from look-aside file and put it into the connection's data */ - nm_settings_connection_read_and_fill_seen_bssids (sett_conn); + nm_settings_connection_read_and_fill_seen_bssids (connection); /* Ensure its initial visibility is up-to-date */ - nm_settings_connection_recheck_visibility (sett_conn); + nm_settings_connection_recheck_visibility (connection); /* Evil openconnect migration hack */ - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - openconnect_migrate_hack (nm_settings_connection_get_connection (sett_conn)); + openconnect_migrate_hack (NM_CONNECTION (connection)); /* This one unexports the connection, it needs to run late to give the active * connection a chance to deal with its reference to this settings connection. */ - g_signal_connect_after (sett_conn, NM_SETTINGS_CONNECTION_REMOVED, + g_signal_connect_after (connection, NM_SETTINGS_CONNECTION_REMOVED, G_CALLBACK (connection_removed), self); - g_signal_connect (sett_conn, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, + g_signal_connect (connection, NM_SETTINGS_CONNECTION_UPDATED_INTERNAL, G_CALLBACK (connection_updated), self); - g_signal_connect (sett_conn, NM_SETTINGS_CONNECTION_FLAGS_CHANGED, + g_signal_connect (connection, NM_SETTINGS_CONNECTION_FLAGS_CHANGED, G_CALLBACK (connection_flags_changed), self); if (!priv->startup_complete) { - g_signal_connect (sett_conn, "notify::" NM_SETTINGS_CONNECTION_READY, + g_signal_connect (connection, "notify::" NM_SETTINGS_CONNECTION_READY, G_CALLBACK (connection_ready_changed), self); } _clear_connections_cached_list (priv); - g_object_ref (sett_conn); + g_object_ref (connection); /* FIXME(shutdown): The NMSettings instance can't be disposed * while there is any exported connection. Ideally we should * unexport all connections on NMSettings' disposal, but for now * leak @self on termination when there are connections alive. */ g_object_ref (self); priv->connections_len++; - c_list_link_tail (&priv->connections_lst_head, &sett_conn->_connections_lst); + c_list_link_tail (&priv->connections_lst_head, &connection->_connections_lst); - path = nm_dbus_object_export (NM_DBUS_OBJECT (sett_conn)); + path = nm_dbus_object_export (NM_DBUS_OBJECT (connection)); - nm_utils_log_connection_diff (nm_settings_connection_get_connection (sett_conn), - NULL, - LOGL_DEBUG, - LOGD_CORE, - "new connection", "++ ", + nm_utils_log_connection_diff (NM_CONNECTION (connection), NULL, LOGL_DEBUG, LOGD_CORE, "new connection", "++ ", path); /* Only emit the individual connection-added signal after connections @@ -987,13 +1021,13 @@ claim_connection (NMSettings *self, NMSettingsConnection *sett_conn) &interface_info_settings, &signal_info_new_connection, "(o)", - nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn))); + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection))); - g_signal_emit (self, signals[CONNECTION_ADDED], 0, sett_conn); + g_signal_emit (self, signals[CONNECTION_ADDED], 0, connection); _notify (self, PROP_CONNECTIONS); } - nm_settings_connection_added (sett_conn); + nm_settings_connection_added (connection); } static gboolean @@ -1045,7 +1079,7 @@ nm_settings_add_connection (NMSettings *self, /* Make sure a connection with this UUID doesn't already exist */ c_list_for_each_entry (candidate, &priv->connections_lst_head, _connections_lst) { - if (nm_streq0 (uuid, nm_settings_connection_get_uuid (candidate))) { + if (nm_streq0 (uuid, nm_connection_get_uuid (NM_CONNECTION (candidate)))) { g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_UUID_EXISTS, @@ -1079,13 +1113,8 @@ nm_settings_add_connection (NMSettings *self, added = nm_settings_plugin_add_connection (plugin, connection, save_to_disk, &add_error); if (added) { - if (secrets) { - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - nm_connection_update_secrets (nm_settings_connection_get_connection (added), - NULL, - secrets, - NULL); - } + if (secrets) + nm_connection_update_secrets (NM_CONNECTION (added), NULL, secrets, NULL); claim_connection (self, added); return added; } @@ -1103,7 +1132,7 @@ nm_settings_add_connection (NMSettings *self, static void send_agent_owned_secrets (NMSettings *self, - NMSettingsConnection *sett_conn, + NMSettingsConnection *connection, NMAuthSubject *subject) { NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); @@ -1113,12 +1142,12 @@ send_agent_owned_secrets (NMSettings *self, * as agent-owned secrets are the only ones we send back to be saved. * Only send secrets to agents of the same UID that called update too. */ - for_agent = nm_simple_connection_new_clone (nm_settings_connection_get_connection (sett_conn)); + for_agent = nm_simple_connection_new_clone (NM_CONNECTION (connection)); nm_connection_clear_secrets_with_flags (for_agent, secrets_filter_cb, GUINT_TO_POINTER (NM_SETTING_SECRET_FLAG_AGENT_OWNED)); nm_agent_manager_save_secrets (priv->agent_mgr, - nm_dbus_object_get_path (NM_DBUS_OBJECT (sett_conn)), + nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)), for_agent, subject); } @@ -1161,8 +1190,7 @@ pk_add_cb (NMAuthChain *chain, } else { /* Authorized */ connection = nm_auth_chain_get_data (chain, "connection"); - nm_assert (connection); - + g_assert (connection); save_to_disk = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "save-to-disk")); added = nm_settings_add_connection (self, connection, save_to_disk, &error); } @@ -1253,6 +1281,14 @@ nm_settings_add_connection_dbus (NMSettings *self, goto done; } + /* Do any of the plugins support adding? */ + if (!get_plugin (self, TRUE)) { + error = g_error_new_literal (NM_SETTINGS_ERROR, + NM_SETTINGS_ERROR_NOT_SUPPORTED, + "None of the registered plugins support add."); + goto done; + } + if (!nm_auth_is_subject_in_acl_set_error (connection, subject, NM_SETTINGS_ERROR, @@ -1576,21 +1612,20 @@ have_connection_for_device (NMSettings *self, NMDevice *device) NMSettingWired *s_wired; const char *setting_hwaddr; const char *perm_hw_addr; - NMSettingsConnection *sett_conn; + NMSettingsConnection *connection; g_return_val_if_fail (NM_IS_SETTINGS (self), FALSE); perm_hw_addr = nm_device_get_permanent_hw_address (device); /* Find a wired connection locked to the given MAC address, if any */ - c_list_for_each_entry (sett_conn, &priv->connections_lst_head, _connections_lst) { - NMConnection *connection = nm_settings_connection_get_connection (sett_conn); + c_list_for_each_entry (connection, &priv->connections_lst_head, _connections_lst) { const char *ctype, *iface; - if (!nm_device_check_connection_compatible (device, connection, NULL)) + if (!nm_device_check_connection_compatible (device, NM_CONNECTION (connection))) continue; - s_con = nm_connection_get_setting_connection (connection); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); iface = nm_setting_connection_get_interface_name (s_con); if (iface && strcmp (iface, nm_device_get_iface (device)) != 0) @@ -1601,15 +1636,14 @@ have_connection_for_device (NMSettings *self, NMDevice *device) && strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) continue; - s_wired = nm_connection_get_setting_wired (connection); + s_wired = nm_connection_get_setting_wired (NM_CONNECTION (connection)); - if ( !s_wired - && nm_streq (ctype, NM_SETTING_PPPOE_SETTING_NAME)) { + if (!s_wired && !strcmp (ctype, NM_SETTING_PPPOE_SETTING_NAME)) { /* No wired setting; therefore the PPPoE connection applies to any device */ return TRUE; } - nm_assert (s_wired); + g_assert (s_wired != NULL); setting_hwaddr = nm_setting_wired_get_mac_address (s_wired); if (setting_hwaddr) { @@ -1653,11 +1687,11 @@ default_wired_clear_tag (NMSettings *self, NMSettingsConnection *connection, gboolean add_to_no_auto_default) { - nm_assert (NM_IS_SETTINGS (self)); - nm_assert (NM_IS_DEVICE (device)); - nm_assert (NM_IS_SETTINGS_CONNECTION (connection)); - nm_assert (device == g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ())); - nm_assert (connection == g_object_get_qdata (G_OBJECT (device), _default_wired_connection_quark ())); + g_return_if_fail (NM_IS_SETTINGS (self)); + g_return_if_fail (NM_IS_DEVICE (device)); + g_return_if_fail (NM_IS_CONNECTION (connection)); + g_return_if_fail (device == g_object_get_qdata (G_OBJECT (connection), _default_wired_device_quark ())); + g_return_if_fail (connection == g_object_get_qdata (G_OBJECT (device), _default_wired_connection_quark ())); g_object_set_qdata (G_OBJECT (connection), _default_wired_device_quark (), NULL); g_object_set_qdata (G_OBJECT (device), _default_wired_connection_quark (), NULL); @@ -1832,7 +1866,7 @@ get_property (GObject *object, guint prop_id, : NULL); break; case PROP_CAN_MODIFY: - g_value_set_boolean (value, TRUE); + g_value_set_boolean (value, !!get_plugin (self, TRUE)); break; case PROP_CONNECTIONS: if (priv->connections_loaded) { @@ -1896,7 +1930,6 @@ finalize (GObject *object) { NMSettings *self = NM_SETTINGS (object); NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE (self); - GSList *iter; _clear_connections_cached_list (priv); @@ -1905,12 +1938,7 @@ finalize (GObject *object) g_slist_free_full (priv->unmanaged_specs, g_free); g_slist_free_full (priv->unrecognized_specs, g_free); - while ((iter = priv->plugins)) { - gs_unref_object NMSettingsPlugin *plugin = iter->data; - - priv->plugins = g_slist_delete_link (priv->plugins, iter); - g_signal_handlers_disconnect_by_data (plugin, self); - } + g_slist_free_full (priv->plugins, g_object_unref); g_clear_object (&priv->agent_mgr); diff --git a/src/settings/nm-settings.h b/src/settings/nm-settings.h index 38d8ad4e..021512fd 100644 --- a/src/settings/nm-settings.h +++ b/src/settings/nm-settings.h @@ -85,7 +85,7 @@ void nm_settings_add_connection_dbus (NMSettings *self, NMSettingsAddCallback callback, gpointer user_data); -NMSettingsConnection *const*nm_settings_get_connections (NMSettings *settings, guint *out_len); +NMSettingsConnection *const* nm_settings_get_connections (NMSettings *settings, guint *out_len); NMSettingsConnection **nm_settings_get_connections_clone (NMSettings *self, guint *out_len, diff --git a/src/settings/plugins/ibft/meson.build b/src/settings/plugins/ibft/meson.build index c7dbe459..1b6ff28a 100644 --- a/src/settings/plugins/ibft/meson.build +++ b/src/settings/plugins/ibft/meson.build @@ -1,9 +1,15 @@ name = 'nm-settings-plugin-ibft' +cflags = [ + '-DSBINDIR="@0@"'.format(nm_sbindir), + '-DSYSCONFDIR="@0@"'.format(nm_sysconfdir) +] + libnms_ibft_core = static_library( 'nms-ibft-core', 'nms-ibft-reader.c', dependencies: nm_dep, + c_args: cflags ) sources = files( @@ -15,6 +21,7 @@ libnm_settings_plugin_ibft = shared_module( name, sources: sources, dependencies: nm_dep, + c_args: cflags, link_with: libnms_ibft_core, link_args: ldflags_linker_script_settings, link_depends: linker_script_settings, diff --git a/src/settings/plugins/ibft/nms-ibft-plugin.c b/src/settings/plugins/ibft/nms-ibft-plugin.c index 69dd3733..77ce208f 100644 --- a/src/settings/plugins/ibft/nms-ibft-plugin.c +++ b/src/settings/plugins/ibft/nms-ibft-plugin.c @@ -42,15 +42,19 @@ typedef struct { } NMSIbftPluginPrivate; struct _NMSIbftPlugin { - NMSettingsPlugin parent; + GObject parent; NMSIbftPluginPrivate _priv; }; struct _NMSIbftPluginClass { - NMSettingsPluginClass parent; + GObjectClass parent; }; -G_DEFINE_TYPE (NMSIbftPlugin, nms_ibft_plugin, NM_TYPE_SETTINGS_PLUGIN); +static void settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface); + +G_DEFINE_TYPE_EXTENDED (NMSIbftPlugin, nms_ibft_plugin, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_PLUGIN, + settings_plugin_interface_init)) #define NMS_IBFT_PLUGIN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSIbftPlugin, NMS_IS_IBFT_PLUGIN) @@ -80,9 +84,9 @@ read_connections (NMSIbftPlugin *self) connection = nms_ibft_connection_new (iter->data, &error); if (connection) { nm_log_info (LOGD_SETTINGS, "ibft: read connection '%s'", - nm_settings_connection_get_id (NM_SETTINGS_CONNECTION (connection))); + nm_connection_get_id (NM_CONNECTION (connection))); g_hash_table_insert (priv->connections, - g_strdup (nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (connection))), + g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection))), connection); } else { nm_log_warn (LOGD_SETTINGS, "ibft: failed to read iscsiadm record: %s", error->message); @@ -117,6 +121,11 @@ get_connections (NMSettingsPlugin *config) /*****************************************************************************/ static void +init (NMSettingsPlugin *config) +{ +} + +static void nms_ibft_plugin_init (NMSIbftPlugin *self) { NMSIbftPluginPrivate *priv = NMS_IBFT_PLUGIN_GET_PRIVATE (self); @@ -139,20 +148,24 @@ dispose (GObject *object) } static void -nms_ibft_plugin_class_init (NMSIbftPluginClass *klass) +nms_ibft_plugin_class_init (NMSIbftPluginClass *req_class) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMSettingsPluginClass *plugin_class = NM_SETTINGS_PLUGIN_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (req_class); object_class->dispose = dispose; +} - plugin_class->get_connections = get_connections; +static void +settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface) +{ + plugin_iface->get_connections = get_connections; + plugin_iface->init = init; } /*****************************************************************************/ -G_MODULE_EXPORT NMSettingsPlugin * +G_MODULE_EXPORT GObject * nm_settings_plugin_factory (void) { - return NM_SETTINGS_PLUGIN (g_object_ref (nms_ibft_plugin_get ())); + return G_OBJECT (g_object_ref (nms_ibft_plugin_get ())); } diff --git a/src/settings/plugins/ibft/nms-ibft-reader.c b/src/settings/plugins/ibft/nms-ibft-reader.c index ac5824a1..cf849e28 100644 --- a/src/settings/plugins/ibft/nms-ibft-reader.c +++ b/src/settings/plugins/ibft/nms-ibft-reader.c @@ -98,7 +98,7 @@ nms_ibft_reader_load_blocks (const char *iscsiadm_path, const char *envp[1] = { NULL }; GSList *blocks = NULL; char *out = NULL, *err = NULL; - int status = 0; + gint status = 0; char **lines = NULL, **iter; GPtrArray *block_lines = NULL; gboolean success = FALSE; diff --git a/src/settings/plugins/ibft/tests/meson.build b/src/settings/plugins/ibft/tests/meson.build index 8b5e143a..59f49c31 100644 --- a/src/settings/plugins/ibft/tests/meson.build +++ b/src/settings/plugins/ibft/tests/meson.build @@ -6,6 +6,7 @@ exe = executable( test_unit, test_unit + '.c', dependencies: test_nm_dep, + c_args: nm_build_cflags, link_with: libnms_ibft_core ) diff --git a/src/settings/plugins/ifcfg-rh/meson.build b/src/settings/plugins/ifcfg-rh/meson.build index e4bce09b..964ce22d 100644 --- a/src/settings/plugins/ifcfg-rh/meson.build +++ b/src/settings/plugins/ifcfg-rh/meson.build @@ -3,6 +3,11 @@ install_data( install_dir: dbus_conf_dir ) +cflags = [ + '-DSBINDIR="@0@"'.format(nm_sbindir), + '-DSYSCONFDIR="@0@"'.format(nm_sysconfdir) +] + name = 'nmdbus-ifcfg-rh' dbus_sources = gnome.gdbus_codegen( @@ -16,9 +21,10 @@ libnmdbus_ifcfg_rh = static_library( name, sources: dbus_sources, dependencies: glib_dep, + c_args: cflags ) -core_sources = files( +sources = files( 'nm-inotify-helper.c', 'nms-ifcfg-rh-reader.c', 'nms-ifcfg-rh-utils.c', @@ -27,21 +33,24 @@ core_sources = files( ) deps = [ + crypto_dep, nm_dep ] libnms_ifcfg_rh_core = static_library( 'nms-ifcfg-rh-core', - sources: core_sources, + sources: sources, dependencies: deps, + c_args: cflags ) -sources = [dbus_sources] + core_sources + files('nms-ifcfg-rh-connection.c', 'nms-ifcfg-rh-plugin.c') +sources = [dbus_sources] + files('nms-ifcfg-rh-connection.c') libnm_settings_plugin_ifcfg_rh = shared_module( 'nm-settings-plugin-ifcfg-rh', sources: sources, dependencies: deps, + c_args: cflags, link_with: [libnms_ifcfg_rh_core], link_args: ldflags_linker_script_settings, link_depends: linker_script_settings, diff --git a/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c index e7a74a1a..2863df64 100644 --- a/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c +++ b/src/settings/plugins/ifcfg-rh/nm-inotify-helper.c @@ -120,8 +120,8 @@ inotify_event_handler (GIOChannel *channel, GIOCondition cond, gpointer user_dat struct inotify_event evt; /* read the notifications from the watch descriptor */ - while (g_io_channel_read_chars (channel, (char *) &evt, sizeof (struct inotify_event), NULL, NULL) == G_IO_STATUS_NORMAL) { - char filename[PATH_MAX + 1]; + while (g_io_channel_read_chars (channel, (gchar *) &evt, sizeof (struct inotify_event), NULL, NULL) == G_IO_STATUS_NORMAL) { + gchar filename[PATH_MAX + 1]; filename[0] = '\0'; if (evt.len > 0) { diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c index ca319ddc..6979fdaa 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-connection.c @@ -143,7 +143,7 @@ devtimeout_expired (gpointer user_data) NMIfcfgConnectionPrivate *priv = NM_IFCFG_CONNECTION_GET_PRIVATE (self); nm_log_info (LOGD_SETTINGS, "Device for connection '%s' did not appear before timeout", - nm_settings_connection_get_id (NM_SETTINGS_CONNECTION (self))); + nm_connection_get_id (NM_CONNECTION (self))); g_signal_handler_disconnect (NM_PLATFORM_GET, priv->devtimeout_link_changed_handler); priv->devtimeout_link_changed_handler = 0; @@ -163,7 +163,7 @@ nm_ifcfg_connection_check_devtimeout (NMIfcfgConnection *self) guint devtimeout; const NMPlatformLink *pllink; - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (self))); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (self)); if (!nm_setting_connection_get_autoconnect (s_con)) return; @@ -186,7 +186,7 @@ nm_ifcfg_connection_check_devtimeout (NMIfcfgConnection *self) nm_settings_connection_set_ready (NM_SETTINGS_CONNECTION (self), FALSE); nm_log_info (LOGD_SETTINGS, "Waiting %u seconds for %s to appear for connection '%s'", - devtimeout, ifname, nm_settings_connection_get_id (NM_SETTINGS_CONNECTION (self))); + devtimeout, ifname, nm_connection_get_id (NM_CONNECTION (self))); priv->devtimeout_link_changed_handler = g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_LINK_CHANGED, diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c index 6cac8cb6..0fb77b9d 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-plugin.c @@ -70,15 +70,19 @@ typedef struct { } SettingsPluginIfcfgPrivate; struct _SettingsPluginIfcfg { - NMSettingsPlugin parent; + GObject parent; SettingsPluginIfcfgPrivate _priv; }; struct _SettingsPluginIfcfgClass { - NMSettingsPluginClass parent; + GObjectClass parent; }; -G_DEFINE_TYPE (SettingsPluginIfcfg, settings_plugin_ifcfg, NM_TYPE_SETTINGS_PLUGIN) +static void settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface); + +G_DEFINE_TYPE_EXTENDED (SettingsPluginIfcfg, settings_plugin_ifcfg, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_PLUGIN, + settings_plugin_interface_init)) #define SETTINGS_PLUGIN_IFCFG_GET_PRIVATE(self) _NM_GET_PRIVATE (self, SettingsPluginIfcfg, SETTINGS_IS_PLUGIN_IFCFG) @@ -135,7 +139,7 @@ static void connection_removed_cb (NMSettingsConnection *obj, gpointer user_data) { g_hash_table_remove (SETTINGS_PLUGIN_IFCFG_GET_PRIVATE ((SettingsPluginIfcfg *) user_data)->connections, - nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (obj))); + nm_connection_get_uuid (NM_CONNECTION (obj))); } static void @@ -153,16 +157,16 @@ remove_connection (SettingsPluginIfcfg *self, NMIfcfgConnection *connection) unrecognized = !!nm_ifcfg_connection_get_unrecognized_spec (connection); g_object_ref (connection); - g_hash_table_remove (priv->connections, nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (connection))); + g_hash_table_remove (priv->connections, nm_connection_get_uuid (NM_CONNECTION (connection))); if (!unmanaged && !unrecognized) nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection)); g_object_unref (connection); /* Emit changes _after_ removing the connection */ if (unmanaged) - _nm_settings_plugin_emit_signal_unmanaged_specs_changed (NM_SETTINGS_PLUGIN (self)); + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED); if (unrecognized) - _nm_settings_plugin_emit_signal_unrecognized_specs_changed (NM_SETTINGS_PLUGIN (self)); + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED); } static NMIfcfgConnection * @@ -224,7 +228,7 @@ update_connection (SettingsPluginIfcfg *self, return NULL; } - uuid = nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (connection_new)); + uuid = nm_connection_get_uuid (NM_CONNECTION (connection_new)); connection_by_uuid = g_hash_table_lookup (priv->connections, uuid); if ( connection @@ -281,16 +285,12 @@ update_connection (SettingsPluginIfcfg *self, if ( !unmanaged_changed && !unrecognized_changed - && nm_connection_compare (nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (connection_by_uuid)), - nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (connection_new)), + && nm_connection_compare (NM_CONNECTION (connection_by_uuid), + NM_CONNECTION (connection_new), NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) { - if ( old_path - && !nm_streq0 (old_path, full_path)) { - _LOGI ("rename \"%s\" to "NM_IFCFG_CONNECTION_LOG_FMT" without other changes", - nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_by_uuid)), - NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); - } + if (old_path && g_strcmp0 (old_path, full_path) != 0) + _LOGI ("rename \"%s\" to "NM_IFCFG_CONNECTION_LOG_FMT" without other changes", nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_by_uuid)), NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); } else { /******************************************************* @@ -299,7 +299,7 @@ update_connection (SettingsPluginIfcfg *self, if (source) _LOGI ("update "NM_IFCFG_CONNECTION_LOG_FMT" from %s", NM_IFCFG_CONNECTION_LOG_ARG (connection_new), NM_IFCFG_CONNECTION_LOG_PATH (old_path)); - else if (nm_streq0 (old_path, nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_new)))) + else if (!g_strcmp0 (old_path, nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_new)))) _LOGI ("update "NM_IFCFG_CONNECTION_LOG_FMT, NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); else if (old_path) _LOGI ("rename \"%s\" to "NM_IFCFG_CONNECTION_LOG_FMT, old_path, NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); @@ -312,7 +312,7 @@ update_connection (SettingsPluginIfcfg *self, NULL); if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (connection_by_uuid), - nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (connection_new)), + NM_CONNECTION (connection_new), NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP_SAVED, NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, "ifcfg-update", @@ -338,27 +338,25 @@ update_connection (SettingsPluginIfcfg *self, * so add it back now. */ g_hash_table_insert (priv->connections, - g_strdup (nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (connection_by_uuid))), + g_strdup (nm_connection_get_uuid (NM_CONNECTION (connection_by_uuid))), connection_by_uuid /* we took reference above and pass it on */); } } else { if (old_unmanaged /* && !new_unmanaged */) { _LOGI ("Managing connection "NM_IFCFG_CONNECTION_LOG_FMT" and its device because NM_CONTROLLED was true.", NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); - _nm_settings_plugin_emit_signal_connection_added (NM_SETTINGS_PLUGIN (self), - NM_SETTINGS_CONNECTION (connection_by_uuid)); + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, connection_by_uuid); } else if (old_unrecognized /* && !new_unrecognized */) { _LOGI ("Managing connection "NM_IFCFG_CONNECTION_LOG_FMT" because it is now a recognized type.", NM_IFCFG_CONNECTION_LOG_ARG (connection_new)); - _nm_settings_plugin_emit_signal_connection_added (NM_SETTINGS_PLUGIN (self), - NM_SETTINGS_CONNECTION (connection_by_uuid)); + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, connection_by_uuid); } } if (unmanaged_changed) - _nm_settings_plugin_emit_signal_unmanaged_specs_changed (NM_SETTINGS_PLUGIN (self)); + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED); if (unrecognized_changed) - _nm_settings_plugin_emit_signal_unrecognized_specs_changed (NM_SETTINGS_PLUGIN (self)); + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED); } nm_settings_connection_set_filename (NM_SETTINGS_CONNECTION (connection_by_uuid), full_path); g_object_unref (connection_new); @@ -396,13 +394,11 @@ update_connection (SettingsPluginIfcfg *self, /* Only raise the signal if we were called without source, i.e. if we read the connection from file. * Otherwise, we were called by add_connection() which does not expect the signal. */ if (nm_ifcfg_connection_get_unmanaged_spec (connection_new)) - _nm_settings_plugin_emit_signal_unmanaged_specs_changed (NM_SETTINGS_PLUGIN (self)); + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED); else if (nm_ifcfg_connection_get_unrecognized_spec (connection_new)) - _nm_settings_plugin_emit_signal_unrecognized_specs_changed (NM_SETTINGS_PLUGIN (self)); - else { - _nm_settings_plugin_emit_signal_connection_added (NM_SETTINGS_PLUGIN (self), - NM_SETTINGS_CONNECTION (connection_new)); - } + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_UNRECOGNIZED_SPECS_CHANGED); + else + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, connection_new); } return connection_new; } @@ -735,7 +731,7 @@ impl_ifcfgrh_get_ifcfg_details (SettingsPluginIfcfg *plugin, return; } - s_con = nm_connection_get_setting_connection (nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (connection))); + s_con = nm_connection_get_setting_connection (NM_CONNECTION (connection)); if (!s_con) { g_dbus_method_invocation_return_error (context, NM_SETTINGS_ERROR, @@ -1002,6 +998,11 @@ config_changed_cb (NMConfig *config, /*****************************************************************************/ static void +init (NMSettingsPlugin *config) +{ +} + +static void settings_plugin_ifcfg_init (SettingsPluginIfcfg *plugin) { SettingsPluginIfcfgPrivate *priv = SETTINGS_PLUGIN_IFCFG_GET_PRIVATE ((SettingsPluginIfcfg *) plugin); @@ -1058,26 +1059,30 @@ dispose (GObject *object) } static void -settings_plugin_ifcfg_class_init (SettingsPluginIfcfgClass *klass) +settings_plugin_ifcfg_class_init (SettingsPluginIfcfgClass *req_class) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMSettingsPluginClass *plugin_class = NM_SETTINGS_PLUGIN_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (req_class); object_class->constructed = constructed; object_class->dispose = dispose; +} - plugin_class->get_connections = get_connections; - plugin_class->add_connection = add_connection; - plugin_class->load_connection = load_connection; - plugin_class->reload_connections = reload_connections; - plugin_class->get_unmanaged_specs = get_unmanaged_specs; - plugin_class->get_unrecognized_specs = get_unrecognized_specs; +static void +settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface) +{ + plugin_iface->get_connections = get_connections; + plugin_iface->add_connection = add_connection; + plugin_iface->load_connection = load_connection; + plugin_iface->reload_connections = reload_connections; + plugin_iface->get_unmanaged_specs = get_unmanaged_specs; + plugin_iface->get_unrecognized_specs = get_unrecognized_specs; + plugin_iface->init = init; } /*****************************************************************************/ -G_MODULE_EXPORT NMSettingsPlugin * +G_MODULE_EXPORT GObject * nm_settings_plugin_factory (void) { - return NM_SETTINGS_PLUGIN (g_object_ref (settings_plugin_ifcfg_get ())); + return G_OBJECT (g_object_ref (settings_plugin_ifcfg_get ())); } diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 09a37991..c1960846 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -33,7 +33,6 @@ #include <sys/ioctl.h> #include <unistd.h> -#include "nm-utils/nm-secret-utils.h" #include "nm-connection.h" #include "nm-dbus-interface.h" #include "nm-setting-connection.h" @@ -42,7 +41,6 @@ #include "nm-setting-ip6-config.h" #include "nm-setting-wired.h" #include "nm-setting-wireless.h" -#include "nm-setting-ethtool.h" #include "nm-setting-8021x.h" #include "nm-setting-bond.h" #include "nm-setting-team.h" @@ -55,7 +53,6 @@ #include "nm-setting-generic.h" #include "nm-core-internal.h" #include "nm-utils.h" -#include "nm-ethtool-utils.h" #include "platform/nm-platform.h" #include "NetworkManagerUtils.h" @@ -80,210 +77,6 @@ /*****************************************************************************/ -static char * -get_full_file_path (const char *ifcfg_path, const char *file_path) -{ - const char *base = file_path; - char *p, *ret, *dirname; - - g_return_val_if_fail (ifcfg_path != NULL, NULL); - g_return_val_if_fail (file_path != NULL, NULL); - - if (file_path[0] == '/') - return g_strdup (file_path); - - p = strrchr (file_path, '/'); - if (p) - base = p + 1; - - dirname = g_path_get_dirname (ifcfg_path); - ret = g_build_path ("/", dirname, base, NULL); - g_free (dirname); - return ret; -} - -/*****************************************************************************/ - -static NMSettingSecretFlags -_secret_read_ifcfg_flags (shvarFile *ifcfg, const char *flags_key) -{ - NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; - gs_free char *val_free = NULL; - const char *val; - - nm_assert (flags_key); - nm_assert (g_str_has_suffix (flags_key, "_FLAGS")); - - val = svGetValueStr (ifcfg, flags_key, &val_free); - if (val) { - if (strstr (val, SECRET_FLAG_AGENT)) - flags |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; - if (strstr (val, SECRET_FLAG_NOT_SAVED)) - flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED; - if (strstr (val, SECRET_FLAG_NOT_REQUIRED)) - flags |= NM_SETTING_SECRET_FLAG_NOT_REQUIRED; - } - return flags; -} - -static void -_secret_read_ifcfg (shvarFile *ifcfg, - shvarFile *keys_ifcfg, - const char *name, - char **value, - NMSettingSecretFlags *flags) -{ - char flags_key[250]; - - nm_sprintf_buf (flags_key, "%s_FLAGS", name); - - *flags = _secret_read_ifcfg_flags (ifcfg, flags_key); - - if (*flags != NM_SETTING_SECRET_FLAG_NONE) - *value = NULL; - else { - *value = svGetValue_cp (ifcfg, name); - if (!*value && keys_ifcfg) - *value = svGetValue_cp (keys_ifcfg, name); - } -} - -static void -_secret_set_from_ifcfg (gpointer setting, - shvarFile *ifcfg, - shvarFile *keys_ifcfg, - const char *ifcfg_key, - const char *property_name) -{ - nm_auto_free_secret char *secret = NULL; - NMSettingSecretFlags flags; - char flags_key[250]; - - nm_assert (NM_IS_SETTING (setting)); - - _secret_read_ifcfg (ifcfg, keys_ifcfg, ifcfg_key, &secret, &flags); - - g_object_set (setting, - property_name, - secret, - nm_sprintf_buf (flags_key, "%s-flags", property_name), - flags, - NULL); -} - -static gboolean -_secret_password_raw_to_bytes (const char *ifcfg_key, - const char *password_raw, - GBytes **out_bytes, - GError **error) -{ - nm_auto_free_secret_buf NMSecretBuf *secret = NULL; - gsize len; - - if (!password_raw) { - NM_SET_OUT (out_bytes, NULL); - return TRUE; - } - - if (password_raw[0] == '0' && password_raw[1] == 'x') - password_raw += 2; - - secret = nm_secret_buf_new (strlen (password_raw) / 2 + 3); - if (!_nm_utils_str2bin_full (password_raw, FALSE, ":", secret->bin, secret->len, &len)) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid hex password in %s", - ifcfg_key); - return FALSE; - } - - NM_SET_OUT (out_bytes, nm_secret_buf_to_gbytes_take (g_steal_pointer (&secret), len)); - return TRUE; -} - -/*****************************************************************************/ - -static GBytes * -_cert_get_cert_bytes (const char *ifcfg_path, - const char *value, - GError **error) -{ - gs_free char *path = NULL; - - if (g_str_has_prefix (value, "pkcs11:")) - return _nm_setting_802_1x_cert_value_to_bytes (NM_SETTING_802_1X_CK_SCHEME_PKCS11, (guint8 *) value, -1, error); - - path = get_full_file_path (ifcfg_path, value); - return _nm_setting_802_1x_cert_value_to_bytes (NM_SETTING_802_1X_CK_SCHEME_PATH, (guint8 *) path, -1, error); -} - -static gboolean -_cert_get_cert (shvarFile *ifcfg, - const char *ifcfg_key, - GBytes **out_cert, - NMSetting8021xCKScheme *out_scheme, - GError **error) -{ - nm_auto_free_secret char *val_free = NULL; - const char *val; - gs_unref_bytes GBytes *cert = NULL; - GError *local = NULL; - NMSetting8021xCKScheme scheme; - - val = svGetValueStr (ifcfg, ifcfg_key, &val_free); - if (!val) { - NM_SET_OUT (out_cert, NULL); - NM_SET_OUT (out_scheme, NM_SETTING_802_1X_CK_SCHEME_UNKNOWN); - return TRUE; - } - - cert = _cert_get_cert_bytes (svFileGetName (ifcfg), val, &local); - if (!cert) - goto err; - - scheme = _nm_setting_802_1x_cert_get_scheme (cert, &local); - if (scheme == NM_SETTING_802_1X_CK_SCHEME_UNKNOWN) - goto err; - - NM_SET_OUT (out_cert, g_steal_pointer (&cert)); - NM_SET_OUT (out_scheme, scheme); - return TRUE; - -err: - g_set_error (error, - NM_SETTINGS_ERROR, - NM_SETTINGS_ERROR_INVALID_CONNECTION, - "invalid certificate %s: %s", - ifcfg_key, - local->message); - g_error_free (local); - return FALSE; -} - -static gboolean -_cert_set_from_ifcfg (gpointer setting, - shvarFile *ifcfg, - const char *ifcfg_key, - const char *property_name, - GBytes **out_cert, - GError **error) -{ - gs_unref_bytes GBytes *cert = NULL; - - if (!_cert_get_cert (ifcfg, - ifcfg_key, - &cert, - NULL, - error)) - return FALSE; - - g_object_set (setting, property_name, cert, NULL); - - NM_SET_OUT (out_cert, g_steal_pointer (&cert)); - return TRUE; -} - -/*****************************************************************************/ - static void check_if_bond_slave (shvarFile *ifcfg, NMSettingConnection *s_con) @@ -439,16 +232,13 @@ make_connection_setting (const char *file, NM_SETTING_CONNECTION_AUTOCONNECT, svGetValueBoolean (ifcfg, "ONBOOT", TRUE), NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY, - (int) svGetValueInt64 (ifcfg, "AUTOCONNECT_PRIORITY", 10, + (gint) svGetValueInt64 (ifcfg, "AUTOCONNECT_PRIORITY", 10, NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MIN, NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_MAX, NM_SETTING_CONNECTION_AUTOCONNECT_PRIORITY_DEFAULT), NM_SETTING_CONNECTION_AUTOCONNECT_RETRIES, - (int) svGetValueInt64 (ifcfg, "AUTOCONNECT_RETRIES", 10, + (gint) svGetValueInt64 (ifcfg, "AUTOCONNECT_RETRIES", 10, -1, G_MAXINT32, -1), - NM_SETTING_CONNECTION_MULTI_CONNECT, - (gint) svGetValueInt64 (ifcfg, "MULTI_CONNECT", 10, - G_MININT32, G_MAXINT32, NM_CONNECTION_MULTI_CONNECT_DEFAULT), NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES, svGetValueBoolean (ifcfg, "AUTOCONNECT_SLAVES", NM_SETTING_CONNECTION_AUTOCONNECT_SLAVES_DEFAULT), NM_SETTING_CONNECTION_LLDP, lldp, @@ -459,7 +249,7 @@ make_connection_setting (const char *file, if (v) { gs_free const char **items = NULL; - items = nm_utils_strsplit_set (v, " ", FALSE); + items = nm_utils_strsplit_set (v, " "); for (iter = items; iter && *iter; iter++) { if (!nm_setting_connection_add_permission (s_con, "user", *iter, NULL)) PARSE_WARNING ("invalid USERS item '%s'", *iter); @@ -475,7 +265,7 @@ make_connection_setting (const char *file, if (v) { gs_free const char **items = NULL; - items = nm_utils_strsplit_set (v, " \t", FALSE); + items = nm_utils_strsplit_set (v, " \t"); for (iter = items; iter && *iter; iter++) { if (!nm_setting_connection_add_secondary (s_con, *iter)) PARSE_WARNING ("secondary connection UUID '%s' already added", *iter); @@ -545,7 +335,7 @@ make_connection_setting (const char *file, } vint64 = svGetValueInt64 (ifcfg, "AUTH_RETRIES", 10, -1, G_MAXINT32, -1); - g_object_set (s_con, NM_SETTING_CONNECTION_AUTH_RETRIES, (int) vint64, NULL); + g_object_set (s_con, NM_SETTING_CONNECTION_AUTH_RETRIES, (gint) vint64, NULL); i_val = NM_SETTING_CONNECTION_MDNS_DEFAULT; if (!svGetValueEnum (ifcfg, "MDNS", @@ -554,13 +344,6 @@ make_connection_setting (const char *file, PARSE_WARNING ("invalid MDNS setting"); g_object_set (s_con, NM_SETTING_CONNECTION_MDNS, i_val, NULL); - i_val = NM_SETTING_CONNECTION_LLMNR_DEFAULT; - if (!svGetValueEnum (ifcfg, "LLMNR", - nm_setting_connection_llmnr_get_type (), - &i_val, NULL)) - PARSE_WARNING ("invalid LLMNR setting"); - g_object_set (s_con, NM_SETTING_CONNECTION_LLMNR, i_val, NULL); - return NM_SETTING (s_con); } @@ -891,7 +674,7 @@ parse_route_line (const char *line, * Maybe later we want to support some form of quotation here. * Which of course, would be incompatible with initscripts. */ - words_free = nm_utils_strsplit_set (line, " \t\n", FALSE); + words_free = nm_utils_strsplit_set (line, " \t\n"); words = words_free ?: NM_PTRARRAY_EMPTY (const char *); @@ -1327,7 +1110,7 @@ parse_dns_options (NMSettingIPConfig *ip_config, const char *value) if (!nm_setting_ip_config_has_dns_options (ip_config)) nm_setting_ip_config_clear_dns_options (ip_config, TRUE); - options = nm_utils_strsplit_set (value, " ", FALSE); + options = nm_utils_strsplit_set (value, " "); if (options) { for (item = options; *item; item++) { if (!nm_setting_ip_config_add_dns_option (ip_config, *item)) @@ -1395,7 +1178,7 @@ make_user_setting (shvarFile *ifcfg) const char *key; nm_auto_free_gstring GString *str = NULL; - keys = svGetKeys (ifcfg, SV_KEY_TYPE_USER); + keys = svGetKeys (ifcfg); if (!keys) return NULL; @@ -1404,6 +1187,9 @@ make_user_setting (shvarFile *ifcfg) const char *value; gs_free char *value_to_free = NULL; + if (!g_str_has_prefix (key, "NM_USER_")) + continue; + value = svGetValue (ifcfg, key, &value_to_free); if (!value) @@ -1431,32 +1217,6 @@ make_user_setting (shvarFile *ifcfg) } static NMSetting * -make_match_setting (shvarFile *ifcfg) -{ - NMSettingMatch *s_match = NULL; - gs_free const char **strv = NULL; - gs_free char *value = NULL; - const char *v; - gsize i; - - v = svGetValueStr (ifcfg, "MATCH_INTERFACE_NAME", &value); - if (!v) - return NULL; - - strv = nm_utils_strsplit_set (v, " \t", TRUE); - if (strv) { - for (i = 0; strv[i]; i++) { - if (!s_match) - s_match = (NMSettingMatch *) nm_setting_match_new (); - nm_setting_match_add_interface_name (s_match, - _nm_utils_unescape_spaces ((char *) strv[i])); - } - } - - return (NMSetting *) s_match; -} - -static NMSetting * make_proxy_setting (shvarFile *ifcfg) { NMSettingProxy *s_proxy = NULL; @@ -1526,7 +1286,7 @@ make_ip4_setting (shvarFile *ifcfg, shvarFile *route_ifcfg; gboolean never_default; gint64 timeout; - int priority; + gint priority; char inet_buf[NM_UTILS_INET_ADDRSTRLEN]; const char *const *item; guint32 route_table; @@ -1723,7 +1483,7 @@ make_ip4_setting (shvarFile *ifcfg, if (v) { gs_free const char **searches = NULL; - searches = nm_utils_strsplit_set (v, " ", FALSE); + searches = nm_utils_strsplit_set (v, " "); if (searches) { for (item = searches; *item; item++) { if (!nm_setting_ip_config_add_dns_search (s_ip4, *item)) @@ -1784,7 +1544,7 @@ make_ip4_setting (shvarFile *ifcfg, if (v) { gs_free const char **searches = NULL; - searches = nm_utils_strsplit_set (v, " ", FALSE); + searches = nm_utils_strsplit_set (v, " "); if (searches) { for (item = searches; *item; item++) { if (!nm_setting_ip_config_add_dns_search (s_ip4, *item)) @@ -1801,7 +1561,7 @@ make_ip4_setting (shvarFile *ifcfg, if (timeout > 0) timeout *= 1000; } - g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DAD_TIMEOUT, (int) timeout, NULL); + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_DAD_TIMEOUT, (gint) timeout, NULL); return g_steal_pointer (&s_ip4); } @@ -1937,7 +1697,7 @@ make_ip6_setting (shvarFile *ifcfg, guint32 i; int i_val; GError *local = NULL; - int priority; + gint priority; gboolean never_default = FALSE; gboolean ip6_privacy = FALSE, ip6_privacy_prefer_public_ip; NMSettingIP6ConfigPrivacy ip6_privacy_val; @@ -2100,7 +1860,7 @@ make_ip6_setting (shvarFile *ifcfg, ipv6addr_secondaries ?: "", NULL); - list = nm_utils_strsplit_set (value, " ", FALSE); + list = nm_utils_strsplit_set (value, " "); for (iter = list, i = 0; iter && *iter; iter++, i++) { NMIPAddress *addr = NULL; @@ -2193,7 +1953,7 @@ make_ip6_setting (shvarFile *ifcfg, if (v) { gs_free const char **searches = NULL; - searches = nm_utils_strsplit_set (v, " ", FALSE); + searches = nm_utils_strsplit_set (v, " "); if (searches) { for (iter = searches; *iter; iter++) { if (!nm_setting_ip_config_add_dns_search (s_ip6, *iter)) @@ -2222,68 +1982,6 @@ error: } static NMSetting * -make_sriov_setting (shvarFile *ifcfg) -{ - gs_unref_hashtable GHashTable *keys = NULL; - gs_unref_ptrarray GPtrArray *vfs = NULL; - NMTernary autoprobe_drivers; - NMSettingSriov *s_sriov; - int total_vfs; - - total_vfs = svGetValueInt64 (ifcfg, "SRIOV_TOTAL_VFS", 10, 0, G_MAXINT32, 0); - if (!total_vfs) - return NULL; - - autoprobe_drivers = svGetValueInt64 (ifcfg, - "SRIOV_AUTOPROBE_DRIVERS", - 10, - NM_TERNARY_FALSE, - NM_TERNARY_TRUE, - NM_TERNARY_DEFAULT); - - keys = svGetKeys (ifcfg, SV_KEY_TYPE_SRIOV_VF); - if (keys) { - GHashTableIter iter; - const char *key; - - g_hash_table_iter_init (&iter, keys); - while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL)) { - gs_free_error GError *error = NULL; - gs_free char *value_to_free = NULL; - const char *value; - NMSriovVF *vf; - - nm_assert (g_str_has_prefix (key, "SRIOV_VF")); - - value = svGetValue (ifcfg, key, &value_to_free); - if (!value) - continue; - - key += NM_STRLEN ("SRIOV_VF"); - - vf = _nm_utils_sriov_vf_from_strparts (key, value, &error); - if (!vf) { - PARSE_WARNING ("ignoring invalid SR-IOV VF '%s %s': %s", - key, value, error->message); - continue; - } - if (!vfs) - vfs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_sriov_vf_unref); - g_ptr_array_add (vfs, vf); - } - } - - s_sriov = (NMSettingSriov *) nm_setting_sriov_new (); - g_object_set (s_sriov, - NM_SETTING_SRIOV_TOTAL_VFS, total_vfs, - NM_SETTING_SRIOV_VFS, vfs, - NM_SETTING_SRIOV_AUTOPROBE_DRIVERS, (int) autoprobe_drivers, - NULL); - - return (NMSetting *) s_sriov; -} - -static NMSetting * make_tc_setting (shvarFile *ifcfg) { NMSettingTCConfig *s_tc = NULL; @@ -2543,7 +2241,7 @@ read_dcb_percent_array (shvarFile *ifcfg, return TRUE; } - split = nm_utils_strsplit_set (val, ",", FALSE); + split = nm_utils_strsplit_set (val, ","); if (NM_PTRARRAY_LEN (split) != 8) { PARSE_WARNING ("invalid %s percentage list value '%s'", prop, val); g_set_error_literal (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, @@ -2820,6 +2518,30 @@ read_wep_keys (shvarFile *ifcfg, return TRUE; } +static NMSettingSecretFlags +read_secret_flags (shvarFile *ifcfg, const char *flags_key) +{ + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + char *val; + + g_return_val_if_fail (flags_key != NULL, NM_SETTING_SECRET_FLAG_NONE); + g_return_val_if_fail (flags_key[0] != '\0', NM_SETTING_SECRET_FLAG_NONE); + g_return_val_if_fail (g_str_has_suffix (flags_key, "_FLAGS"), NM_SETTING_SECRET_FLAG_NONE); + + val = svGetValueStr_cp (ifcfg, flags_key); + if (val) { + if (strstr (val, SECRET_FLAG_AGENT)) + flags |= NM_SETTING_SECRET_FLAG_AGENT_OWNED; + if (strstr (val, SECRET_FLAG_NOT_SAVED)) + flags |= NM_SETTING_SECRET_FLAG_NOT_SAVED; + if (strstr (val, SECRET_FLAG_NOT_REQUIRED)) + flags |= NM_SETTING_SECRET_FLAG_NOT_REQUIRED; + + g_free (val); + } + return flags; +} + static NMSetting * make_wep_setting (shvarFile *ifcfg, const char *file, @@ -2851,7 +2573,7 @@ make_wep_setting (shvarFile *ifcfg, } /* Read WEP key flags */ - key_flags = _secret_read_ifcfg_flags (ifcfg, "WEP_KEY_FLAGS"); + key_flags = read_secret_flags (ifcfg, "WEP_KEY_FLAGS"); g_object_set (s_wsec, NM_SETTING_WIRELESS_SECURITY_WEP_KEY_FLAGS, key_flags, NULL); /* Read keys in the ifcfg file if they are system-owned */ @@ -2955,7 +2677,7 @@ fill_wpa_ciphers (shvarFile *ifcfg, if (!p) return TRUE; - list = nm_utils_strsplit_set (p, " ", FALSE); + list = nm_utils_strsplit_set (p, " "); for (iter = list; iter && *iter; iter++, i++) { /* Ad-Hoc configurations cannot have pairwise ciphers, and can only * have one group cipher. Ignore any additional group ciphers and @@ -3050,118 +2772,254 @@ parse_wpa_psk (shvarFile *ifcfg, return g_steal_pointer (&psk); } +static void +read_8021x_password (shvarFile *ifcfg, shvarFile *keys_ifcfg, const char *name, + char **value, NMSettingSecretFlags *flags) +{ + gs_free char *flags_key = NULL; + + *value = NULL; + flags_key = g_strdup_printf ("%s_FLAGS", name); + *flags = read_secret_flags (ifcfg, flags_key); + + if (*flags == NM_SETTING_SECRET_FLAG_NONE) { + *value = svGetValueStr_cp (ifcfg, name); + if (!*value && keys_ifcfg) + *value = svGetValueStr_cp (keys_ifcfg, name); + } +} + static gboolean eap_simple_reader (const char *eap_method, shvarFile *ifcfg, - shvarFile *keys_ifcfg, + shvarFile *keys, NMSetting8021x *s_8021x, gboolean phase2, GError **error) { NMSettingSecretFlags flags; - gs_free char *identity_free = NULL; - nm_auto_free_secret char *password_raw_str = NULL; - gs_unref_bytes GBytes *password_raw_bytes = NULL; - - g_object_set (s_8021x, - NM_SETTING_802_1X_IDENTITY, - svGetValueStr (ifcfg, "IEEE_8021X_IDENTITY", &identity_free), - NULL); + GBytes *bytes; + char *value; - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - "IEEE_8021X_PASSWORD", - NM_SETTING_802_1X_PASSWORD); - - _secret_read_ifcfg (ifcfg, keys_ifcfg, "IEEE_8021X_PASSWORD_RAW", &password_raw_str, &flags); - if (!_secret_password_raw_to_bytes ("IEEE_8021X_PASSWORD_RAW", - password_raw_str, - &password_raw_bytes, - error)) + value = svGetValueStr_cp (ifcfg, "IEEE_8021X_IDENTITY"); + if (!value) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing IEEE_8021X_IDENTITY for EAP method '%s'.", + eap_method); return FALSE; + } + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); + nm_clear_g_free (&value); - g_object_set (s_8021x, - NM_SETTING_802_1X_PASSWORD_RAW_FLAGS, - flags, - NM_SETTING_802_1X_PASSWORD_RAW, - password_raw_bytes, - NULL); + read_8021x_password (ifcfg, keys, "IEEE_8021X_PASSWORD", &value, &flags); + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD_FLAGS, flags, NULL); + if (value) { + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD, value, NULL); + nm_clear_g_free (&value); + } + + read_8021x_password (ifcfg, keys, "IEEE_8021X_PASSWORD_RAW", &value, &flags); + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD_RAW_FLAGS, flags, NULL); + if (value) { + bytes = nm_utils_hexstr2bin (value); + if (!bytes) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Invalid hex string '%s' in IEEE_8021X_PASSWORD_RAW.", + value); + g_free (value); + return FALSE; + } + g_object_set (s_8021x, NM_SETTING_802_1X_PASSWORD_RAW, bytes, NULL); + g_bytes_unref (bytes); + nm_clear_g_free (&value); + } return TRUE; } +static char * +get_full_file_path (const char *ifcfg_path, const char *file_path) +{ + const char *base = file_path; + char *p, *ret, *dirname; + + g_return_val_if_fail (ifcfg_path != NULL, NULL); + g_return_val_if_fail (file_path != NULL, NULL); + + if (file_path[0] == '/') + return g_strdup (file_path); + + p = strrchr (file_path, '/'); + if (p) + base = p + 1; + + dirname = g_path_get_dirname (ifcfg_path); + ret = g_build_path ("/", dirname, base, NULL); + g_free (dirname); + return ret; +} + +static char * +get_cert_value (const char *ifcfg_path, const char *value, + NMSetting8021xCKScheme *out_scheme) +{ + if (strncmp (value, "pkcs11:", 7) == 0) { + *out_scheme = NM_SETTING_802_1X_CK_SCHEME_PKCS11; + return g_strdup (value); + } + + *out_scheme = NM_SETTING_802_1X_CK_SCHEME_PATH; + return get_full_file_path (ifcfg_path, value); +} + static gboolean eap_tls_reader (const char *eap_method, shvarFile *ifcfg, - shvarFile *keys_ifcfg, + shvarFile *keys, NMSetting8021x *s_8021x, gboolean phase2, GError **error) { - gs_unref_bytes GBytes *privkey = NULL; - gs_unref_bytes GBytes *client_cert = NULL; - gs_free char *identity_free = NULL; + gs_free char *ca_cert = NULL; + gs_free char *privkey = NULL; + gs_free char *privkey_password = NULL; + char *value; + char *ca_cert_password = NULL; + char *client_cert_password = NULL; + NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; + const char *ca_cert_key = phase2 ? "IEEE_8021X_INNER_CA_CERT" : "IEEE_8021X_CA_CERT"; + const char *ca_cert_pw_key = phase2 ? "IEEE_8021X_INNER_CA_CERT_PASSWORD" : "IEEE_8021X_CA_CERT_PASSWORD"; + const char *ca_cert_pw_prop = phase2 ? NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD : NM_SETTING_802_1X_CA_CERT_PASSWORD; + const char *ca_cert_pw_flags_key = phase2 ? "IEEE_8021X_INNER_CA_CERT_PASSWORD_FLAGS" : "IEEE_8021X_CA_CERT_PASSWORD_FLAGS"; + const char *ca_cert_pw_flags_prop = phase2 ? NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD_FLAGS : NM_SETTING_802_1X_CA_CERT_PASSWORD_FLAGS; + const char *cli_cert_key = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT"; + const char *cli_cert_pw_key = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT_PASSWORD" : "IEEE_8021X_CLIENT_CERT_PASSWORD"; + const char *cli_cert_pw_prop = phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD : NM_SETTING_802_1X_CLIENT_CERT_PASSWORD; + const char *cli_cert_pw_flags_key = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT_PASSWORD_FLAGS" : "IEEE_8021X_CLIENT_CERT_PASSWORD_FLAGS"; + const char *cli_cert_pw_flags_prop = phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS : NM_SETTING_802_1X_CLIENT_CERT_PASSWORD_FLAGS; + const char *pk_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY"; + const char *pk_pw_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD": "IEEE_8021X_PRIVATE_KEY_PASSWORD"; + const char *pk_pw_flags_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS" : "IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS"; + const char *pk_pw_flags_prop = phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS; + NMSettingSecretFlags flags; + NMSetting8021xCKScheme scheme; - g_object_set (s_8021x, - NM_SETTING_802_1X_IDENTITY, - svGetValueStr (ifcfg, "IEEE_8021X_IDENTITY", &identity_free), - NULL); + value = svGetValueStr_cp (ifcfg, "IEEE_8021X_IDENTITY"); + if (value) { + g_object_set (s_8021x, NM_SETTING_802_1X_IDENTITY, value, NULL); + g_free (value); + } - if (!_cert_set_from_ifcfg (s_8021x, - ifcfg, - phase2 ? "IEEE_8021X_INNER_CA_CERT" : "IEEE_8021X_CA_CERT", - phase2 ? NM_SETTING_802_1X_PHASE2_CA_CERT : NM_SETTING_802_1X_CA_CERT, - NULL, - error)) - return FALSE; - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - phase2 ? "IEEE_8021X_INNER_CA_CERT_PASSWORD" : "IEEE_8021X_CA_CERT_PASSWORD", - phase2 ? NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD : NM_SETTING_802_1X_CA_CERT_PASSWORD); - - if (!_cert_set_from_ifcfg (s_8021x, - ifcfg, - phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY", - phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY : NM_SETTING_802_1X_PRIVATE_KEY, - &privkey, - error)) - return FALSE; - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD" : "IEEE_8021X_PRIVATE_KEY_PASSWORD", - phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); + ca_cert = svGetValueStr_cp (ifcfg, ca_cert_key); + if (ca_cert) { + gs_free char *real_cert_value = NULL; + + real_cert_value = get_cert_value (svFileGetName (ifcfg), ca_cert, &scheme); + if (phase2) { + if (!nm_setting_802_1x_set_phase2_ca_cert (s_8021x, real_cert_value, scheme, NULL, error)) + return FALSE; + } else { + if (!nm_setting_802_1x_set_ca_cert (s_8021x, real_cert_value, scheme, NULL, error)) + return FALSE; + } + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) { + flags = read_secret_flags (ifcfg, ca_cert_pw_flags_key); + g_object_set (s_8021x, ca_cert_pw_flags_prop, flags, NULL); + + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + ca_cert_password = svGetValueStr_cp (ifcfg, ca_cert_pw_key); + g_object_set (s_8021x, ca_cert_pw_prop, ca_cert_password, NULL); + } + } + } else { + PARSE_WARNING ("missing %s for EAP method '%s'; this is insecure!", + ca_cert_key, eap_method); + } + + /* Read and set private key password flags */ + flags = read_secret_flags (ifcfg, pk_pw_flags_key); + g_object_set (s_8021x, pk_pw_flags_prop, flags, NULL); + + /* Read the private key password if it's system-owned */ + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + /* Private key password */ + privkey_password = svGetValueStr_cp (ifcfg, pk_pw_key); + if (!privkey_password && keys) { + /* Try the lookaside keys file */ + privkey_password = svGetValueStr_cp (keys, pk_pw_key); + } + } + + /* The private key itself */ + privkey = svGetValueStr_cp (ifcfg, pk_key); if (!privkey) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing %s for EAP method '%s'.", - phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY", + pk_key, eap_method); return FALSE; } - if (!_cert_set_from_ifcfg (s_8021x, - ifcfg, - phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT", - phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT : NM_SETTING_802_1X_CLIENT_CERT, - &client_cert, - error)) - return FALSE; - /* FIXME: writer does not actually write IEEE_8021X_CLIENT_CERT_PASSWORD and other - * certificate related passwords. It should, because otherwise persisting such profiles - * to ifcfg looses information. As this currently only matters for PKCS11 URIs, it seems - * a seldomly used feature so that it is not fixed yet. */ - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - phase2 ? "IEEE_8021X_INNER_CLIENT_CERT_PASSWORD" : "IEEE_8021X_CLIENT_CERT_PASSWORD", - phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD : NM_SETTING_802_1X_CLIENT_CERT_PASSWORD); - if (!client_cert) { - g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Missing certificate for EAP method '%s'.", - eap_method); - return FALSE; + { + gs_free char *real_cert_value = NULL; + + real_cert_value = get_cert_value (svFileGetName (ifcfg), privkey, &scheme); + if (phase2) { + if (!nm_setting_802_1x_set_phase2_private_key (s_8021x, + real_cert_value, + privkey_password, + scheme, + &privkey_format, + error)) + return FALSE; + } else { + if (!nm_setting_802_1x_set_private_key (s_8021x, + real_cert_value, + privkey_password, + scheme, + &privkey_format, + error)) + return FALSE; + } + } + + /* Only set the client certificate if the private key is not PKCS#12 format, + * as NM (due to supplicant restrictions) requires. If the key was PKCS#12, + * then nm_setting_802_1x_set_private_key() already set the client certificate + * to the same value as the private key. + */ + if (privkey_format != NM_SETTING_802_1X_CK_FORMAT_PKCS12) { + gs_free char *real_cert_value = NULL; + gs_free char *client_cert = NULL; + + client_cert = svGetValueStr_cp (ifcfg, cli_cert_key); + if (!client_cert) { + g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, + "Missing %s for EAP method '%s'.", + cli_cert_key, + eap_method); + return FALSE; + } + + real_cert_value = get_cert_value (svFileGetName (ifcfg), client_cert, &scheme); + if (phase2) { + if (!nm_setting_802_1x_set_phase2_client_cert (s_8021x, real_cert_value, scheme, NULL, error)) + return FALSE; + } else { + if (!nm_setting_802_1x_set_client_cert (s_8021x, real_cert_value, scheme, NULL, error)) + return FALSE; + } + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) { + flags = read_secret_flags (ifcfg, cli_cert_pw_flags_key); + g_object_set (s_8021x, cli_cert_pw_flags_prop, flags, NULL); + + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + client_cert_password = svGetValueStr_cp (ifcfg, cli_cert_pw_key); + g_object_set (s_8021x, cli_cert_pw_prop, client_cert_password, NULL); + } + } } return TRUE; @@ -3170,7 +3028,7 @@ eap_tls_reader (const char *eap_method, static gboolean eap_peap_reader (const char *eap_method, shvarFile *ifcfg, - shvarFile *keys_ifcfg, + shvarFile *keys, NMSetting8021x *s_8021x, gboolean phase2, GError **error) @@ -3179,19 +3037,19 @@ eap_peap_reader (const char *eap_method, const char *v; gs_free const char **list = NULL; const char *const *iter; + NMSetting8021xCKScheme scheme; - if (!_cert_set_from_ifcfg (s_8021x, - ifcfg, - "IEEE_8021X_CA_CERT", - NM_SETTING_802_1X_CA_CERT, - NULL, - error)) - return FALSE; - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - "IEEE_8021X_CA_CERT_PASSWORD", - NM_SETTING_802_1X_CA_CERT_PASSWORD); + v = svGetValueStr (ifcfg, "IEEE_8021X_CA_CERT", &value); + if (v) { + gs_free char *real_cert_value = NULL; + + real_cert_value = get_cert_value (svFileGetName (ifcfg), v, &scheme); + if (!nm_setting_802_1x_set_ca_cert (s_8021x, real_cert_value, scheme, NULL, error)) + return FALSE; + } else { + PARSE_WARNING ("missing IEEE_8021X_CA_CERT for EAP method '%s'; this is insecure!", + eap_method); + } nm_clear_g_free (&value); v = svGetValueStr (ifcfg, "IEEE_8021X_PEAP_VERSION", &value); @@ -3225,16 +3083,16 @@ eap_peap_reader (const char *eap_method, } /* Handle options for the inner auth method */ - list = nm_utils_strsplit_set (v, " ", FALSE); + list = nm_utils_strsplit_set (v, " "); iter = list; if (iter) { if (NM_IN_STRSET (*iter, "MSCHAPV2", "MD5", "GTC")) { - if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) + if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) return FALSE; } else if (nm_streq (*iter, "TLS")) { - if (!eap_tls_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) + if (!eap_tls_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) return FALSE; } else { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, @@ -3263,7 +3121,7 @@ eap_peap_reader (const char *eap_method, static gboolean eap_ttls_reader (const char *eap_method, shvarFile *ifcfg, - shvarFile *keys_ifcfg, + shvarFile *keys, NMSetting8021x *s_8021x, gboolean phase2, GError **error) @@ -3273,19 +3131,19 @@ eap_ttls_reader (const char *eap_method, const char *v; gs_free const char **list = NULL; const char *const *iter; + NMSetting8021xCKScheme scheme; - if (!_cert_set_from_ifcfg (s_8021x, - ifcfg, - "IEEE_8021X_CA_CERT", - NM_SETTING_802_1X_CA_CERT, - NULL, - error)) - return FALSE; - _secret_set_from_ifcfg (s_8021x, - ifcfg, - keys_ifcfg, - "IEEE_8021X_CA_CERT_PASSWORD", - NM_SETTING_802_1X_CA_CERT_PASSWORD); + v = svGetValueStr (ifcfg, "IEEE_8021X_CA_CERT", &value); + if (v) { + gs_free char *real_cert_value = NULL; + + real_cert_value = get_cert_value (svFileGetName (ifcfg), v, &scheme); + if (!nm_setting_802_1x_set_ca_cert (s_8021x, real_cert_value, scheme, NULL, error)) + return FALSE; + } else { + PARSE_WARNING ("missing IEEE_8021X_CA_CERT for EAP method '%s'; this is insecure!", + eap_method); + } nm_clear_g_free (&value); v = svGetValueStr (ifcfg, "IEEE_8021X_ANON_IDENTITY", &value); @@ -3303,24 +3161,24 @@ eap_ttls_reader (const char *eap_method, inner_auth = g_ascii_strdown (v, -1); /* Handle options for the inner auth method */ - list = nm_utils_strsplit_set (inner_auth, " ", FALSE); + list = nm_utils_strsplit_set (inner_auth, " "); iter = list; if (iter) { if (NM_IN_STRSET (*iter, "mschapv2", "mschap", "pap", "chap")) { - if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) + if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) return FALSE; g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, *iter, NULL); } else if (nm_streq (*iter, "eap-tls")) { - if (!eap_tls_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) + if (!eap_tls_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) return FALSE; g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, "tls", NULL); } else if (NM_IN_STRSET (*iter, "eap-mschapv2", "eap-md5", "eap-gtc")) { - if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) + if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) return FALSE; g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_AUTHEAP, (*iter + NM_STRLEN ("eap-")), NULL); } else { @@ -3337,7 +3195,7 @@ eap_ttls_reader (const char *eap_method, static gboolean eap_fast_reader (const char *eap_method, shvarFile *ifcfg, - shvarFile *keys_ifcfg, + shvarFile *keys, NMSetting8021x *s_8021x, gboolean phase2, GError **error) @@ -3364,7 +3222,7 @@ eap_fast_reader (const char *eap_method, if (fast_provisioning) { gs_free const char **list1 = NULL; - list1 = nm_utils_strsplit_set (fast_provisioning, " \t", FALSE); + list1 = nm_utils_strsplit_set (fast_provisioning, " \t"); for (iter = list1; iter && *iter; iter++) { if (strcmp (*iter, "allow-unauth") == 0) allow_unauth = TRUE; @@ -3398,12 +3256,12 @@ eap_fast_reader (const char *eap_method, } /* Handle options for the inner auth method */ - list = nm_utils_strsplit_set (inner_auth, " ", FALSE); + list = nm_utils_strsplit_set (inner_auth, " "); iter = list; if (iter) { if ( !strcmp (*iter, "MSCHAPV2") || !strcmp (*iter, "GTC")) { - if (!eap_simple_reader (*iter, ifcfg, keys_ifcfg, s_8021x, TRUE, error)) + if (!eap_simple_reader (*iter, ifcfg, keys, s_8021x, TRUE, error)) goto done; } else { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, @@ -3438,7 +3296,7 @@ typedef struct { const char *method; gboolean (*reader) (const char *eap_method, shvarFile *ifcfg, - shvarFile *keys_ifcfg, + shvarFile *keys, NMSetting8021x *s_8021x, gboolean phase2, GError **error); @@ -3478,7 +3336,7 @@ read_8021x_list_value (shvarFile *ifcfg, if (!v) return; - strv = nm_utils_strsplit_set (v, " \t", FALSE); + strv = nm_utils_strsplit_set (v, " \t"); if (strv) g_object_set (setting, prop_name, strv, NULL); } @@ -3490,7 +3348,7 @@ fill_8021x (shvarFile *ifcfg, gboolean wifi, GError **error) { - nm_auto_shvar_file_close shvarFile *keys_ifcfg = NULL; + nm_auto_shvar_file_close shvarFile *keys = NULL; gs_unref_object NMSetting8021x *s_8021x = NULL; gs_free char *value = NULL; const char *v; @@ -3507,12 +3365,12 @@ fill_8021x (shvarFile *ifcfg, return NULL; } - list = nm_utils_strsplit_set (v, " ", FALSE); + list = nm_utils_strsplit_set (v, " "); s_8021x = (NMSetting8021x *) nm_setting_802_1x_new (); - /* Read in the lookaside keys_ifcfg file, if present */ - keys_ifcfg = utils_get_keys_ifcfg (file, FALSE); + /* Read in the lookaside keys file, if present */ + keys = utils_get_keys_ifcfg (file, FALSE); /* Validate and handle each EAP method */ for (iter = list; iter && *iter; iter++) { @@ -3536,7 +3394,7 @@ fill_8021x (shvarFile *ifcfg, } /* Parse EAP method specific options */ - if (!(*eap->reader)(lower, ifcfg, keys_ifcfg, s_8021x, FALSE, error)) + if (!(*eap->reader)(lower, ifcfg, keys, s_8021x, FALSE, error)) return NULL; nm_setting_802_1x_add_eap_method (s_8021x, lower); @@ -3586,7 +3444,7 @@ next: g_object_set (s_8021x, NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH, v, NULL); timeout = svGetValueInt64 (ifcfg, "IEEE_8021X_AUTH_TIMEOUT", 10, 0, G_MAXINT32, 0); - g_object_set (s_8021x, NM_SETTING_802_1X_AUTH_TIMEOUT, (int) timeout, NULL); + g_object_set (s_8021x, NM_SETTING_802_1X_AUTH_TIMEOUT, (gint) timeout, NULL); return g_steal_pointer (&s_8021x); } @@ -3652,7 +3510,7 @@ make_wpa_setting (shvarFile *ifcfg, if (wpa_psk) { NMSettingSecretFlags psk_flags; - psk_flags = _secret_read_ifcfg_flags (ifcfg, "WPA_PSK_FLAGS"); + psk_flags = read_secret_flags (ifcfg, "WPA_PSK_FLAGS"); g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_PSK_FLAGS, psk_flags, NULL); /* Read PSK if it's system-owned */ @@ -3739,7 +3597,7 @@ make_leap_setting (shvarFile *ifcfg, return NULL; /* Not LEAP */ nm_clear_g_free (&value); - flags = _secret_read_ifcfg_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS"); + flags = read_secret_flags (ifcfg, "IEEE_8021X_PASSWORD_FLAGS"); g_object_set (wsec, NM_SETTING_WIRELESS_SECURITY_LEAP_PASSWORD_FLAGS, flags, NULL); /* Read LEAP password if it's system-owned */ @@ -3816,7 +3674,7 @@ transform_hwaddr_blacklist (const char *blacklist) const char **strv; gsize i, j; - strv = nm_utils_strsplit_set (blacklist, " \t", FALSE); + strv = nm_utils_strsplit_set (blacklist, " \t"); if (!strv) return NULL; for (i = 0, j = 0; strv[j]; j++) { @@ -4065,7 +3923,7 @@ wireless_connection_from_ifcfg (const char *file, NMSetting8021x *s_8021x = NULL; GBytes *ssid; NMSetting *security_setting = NULL; - gs_free char *ssid_utf8 = NULL; + char *printable_ssid = NULL; const char *mode; gboolean adhoc = FALSE; GError *local = NULL; @@ -4085,6 +3943,12 @@ wireless_connection_from_ifcfg (const char *file, nm_connection_add_setting (connection, wireless_setting); ssid = nm_setting_wireless_get_ssid (NM_SETTING_WIRELESS (wireless_setting)); + if (ssid) { + printable_ssid = nm_utils_ssid_to_utf8 (g_bytes_get_data (ssid, NULL), + g_bytes_get_size (ssid)); + } else + printable_ssid = g_strdup ("unmanaged"); + mode = nm_setting_wireless_get_mode (NM_SETTING_WIRELESS (wireless_setting)); if (mode && !strcmp (mode, "adhoc")) adhoc = TRUE; @@ -4092,6 +3956,7 @@ wireless_connection_from_ifcfg (const char *file, /* Wireless security */ security_setting = make_wireless_security_setting (ifcfg, file, ssid, adhoc, &s_8021x, &local); if (local) { + g_free (printable_ssid); g_object_unref (connection); g_propagate_error (error, local); return NULL; @@ -4102,16 +3967,11 @@ wireless_connection_from_ifcfg (const char *file, nm_connection_add_setting (connection, NM_SETTING (s_8021x)); } - if (ssid) - ssid_utf8 = _nm_utils_ssid_to_utf8 (ssid); - /* Connection */ - con_setting = make_connection_setting (file, - ifcfg, + con_setting = make_connection_setting (file, ifcfg, NM_SETTING_WIRELESS_SETTING_NAME, - nm_str_not_empty (ssid_utf8) ?: "unmanaged", - NULL); - + printable_ssid, NULL); + g_free (printable_ssid); if (!con_setting) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Failed to create connection setting."); @@ -4124,253 +3984,199 @@ wireless_connection_from_ifcfg (const char *file, } static void -parse_ethtool_option (const char *value, - NMSettingWiredWakeOnLan *out_flags, - char **out_password, - gboolean *out_autoneg, - guint32 *out_speed, - const char **out_duplex, - NMSettingEthtool **out_s_ethtool) +parse_ethtool_option_autoneg (const char *value, gboolean *out_autoneg) { - gs_free const char **words = NULL; - guint i; - - words = nm_utils_strsplit_set (value, NULL, FALSE); - if (!words) + if (!value) { + PARSE_WARNING ("Auto-negotiation option missing"); return; + } - if (words[0] && words[0][0] == '-') { - /* /sbin/ethtool $opts */ - if (NM_IN_STRSET (words[0], "-K", "--features", "--offload")) { - if (!words[1]) { - /* first argument must be the interface name. This is invalid. */ - return; - } - - if (!*out_s_ethtool) - *out_s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ()); - - for (i = 2; words[i]; ) { - const char *opt = words[i]; - const char *opt_val = words[++i]; - const NMEthtoolData *d = NULL; - NMTernary onoff = NM_TERNARY_DEFAULT; - - if (nm_streq0 (opt_val, "on")) - onoff = NM_TERNARY_TRUE; - else if (nm_streq0 (opt_val, "off")) - onoff = NM_TERNARY_FALSE; - - d = nms_ifcfg_rh_utils_get_ethtool_by_name (opt); - - if (!d) { - if (onoff != NM_TERNARY_DEFAULT) { - /* the next value is just the on/off argument. Skip it too. */ - i++; - } - - /* silently ignore unsupported offloading features. */ - continue; - } + if (g_str_equal (value, "off")) + *out_autoneg = FALSE; + else if (g_str_equal (value, "on")) + *out_autoneg = TRUE; + else + PARSE_WARNING ("Auto-negotiation unknown value: %s", value); +} - i++; +static void +parse_ethtool_option_speed (const char *value, guint32 *out_speed) +{ + if (!value) { + PARSE_WARNING ("Speed option missing"); + return; + } - if (onoff == NM_TERNARY_DEFAULT) { - PARSE_WARNING ("Expects on/off argument for feature '%s'", opt); - continue; - } + *out_speed = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, 0); + if (errno) + PARSE_WARNING ("Speed value '%s' is invalid", value); +} - nm_setting_ethtool_set_feature (*out_s_ethtool, - d->optname, - onoff); - } - } +static void +parse_ethtool_option_duplex (const char *value, const char **out_duplex) +{ + if (!value) { + PARSE_WARNING ("Duplex option missing"); return; } - /* /sbin/ethtool -s ${REALDEVICE} $opts */ - for (i = 0; words[i]; ) { - const char *opt = words[i]; - const char *opt_val = words[++i]; - - if (nm_streq (opt, "autoneg")) { - if (!opt_val) { - PARSE_WARNING ("Auto-negotiation option missing"); - break; - } - i++; + if (g_str_equal (value, "half")) + *out_duplex = "half"; + else if (g_str_equal (value, "full")) + *out_duplex = "full"; + else + PARSE_WARNING ("Duplex unknown value: %s", value); - if (nm_streq (opt_val, "off")) - *out_autoneg = FALSE; - else if (nm_streq (opt_val, "on")) - *out_autoneg = TRUE; - else - PARSE_WARNING ("Auto-negotiation unknown value: %s", opt_val); - continue; - } +} - if (nm_streq (opt, "speed")) { - guint32 speed; +static void +parse_ethtool_option_wol (const char *value, NMSettingWiredWakeOnLan *out_flags) +{ + NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; - if (!opt_val) { - PARSE_WARNING ("Speed option missing"); - break; - } - i++; + if (!value) { + PARSE_WARNING ("Wake-on-LAN options missing"); + return; + } - speed = _nm_utils_ascii_str_to_int64 (opt_val, 10, 0, G_MAXUINT32, 0); - if (errno == 0) - *out_speed = speed; - else - PARSE_WARNING ("Speed value '%s' is invalid", opt_val); - continue; + for (; *value; value++) { + switch (*value) { + case 'p': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_PHY; + break; + case 'u': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST; + break; + case 'm': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST; + break; + case 'b': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST; + break; + case 'a': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_ARP; + break; + case 'g': + wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC; + break; + case 's': + break; + case 'd': + wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; + break; + default: + PARSE_WARNING ("unrecognized Wake-on-LAN option '%c'", *value); } + } - if (nm_streq (opt, "duplex")) { - if (!opt_val) { - PARSE_WARNING ("Duplex option missing"); - break; - } - i++; - - if (nm_streq (opt_val, "half")) - *out_duplex = "half"; - else if (nm_streq (opt_val, "full")) - *out_duplex = "full"; - else - PARSE_WARNING ("Duplex unknown value: %s", opt_val); - continue; - } + *out_flags = wol_flags; +} - if (nm_streq (opt, "wol")) { - NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; +static void parse_ethtool_option_sopass (const char *value, char **out_password) +{ + if (!value) { + PARSE_WARNING ("Wake-on-LAN password missing"); + return; + } - if (!opt_val) { - PARSE_WARNING ("Wake-on-LAN options missing"); - break; - } - i++; + g_clear_pointer (out_password, g_free); + if (!nm_utils_hwaddr_valid (value, ETH_ALEN)) { + PARSE_WARNING ("Wake-on-LAN password '%s' is invalid", value); + return; + } - for (; *opt_val; opt_val++) { - switch (*opt_val) { - case 'p': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_PHY; - break; - case 'u': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST; - break; - case 'm': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST; - break; - case 'b': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST; - break; - case 'a': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_ARP; - break; - case 'g': - wol_flags |= NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC; - break; - case 's': - break; - case 'd': - wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_NONE; - break; - default: - PARSE_WARNING ("unrecognized Wake-on-LAN option '%c'", *opt_val); - } - } + *out_password = g_strdup (value); +} - *out_flags = wol_flags; - continue; - } +static void +parse_ethtool_option (const char *value, + NMSettingWiredWakeOnLan *out_flags, + char **out_password, + gboolean *out_autoneg, + guint32 *out_speed, + const char **out_duplex) +{ + gs_free const char **words = NULL; + const char *const *iter; + const char *opt_val, *opt; - if (nm_streq (opt, "sopass")) { - if (!opt_val) { - PARSE_WARNING ("Wake-on-LAN password missing"); - break; - } - i++; + words = nm_utils_strsplit_set (value, "\t "); + if (!words) + return; - if (nm_utils_hwaddr_valid (opt_val, ETH_ALEN)) { - g_clear_pointer (out_password, g_free); - *out_password = g_strdup (opt_val); - } else - PARSE_WARNING ("Wake-on-LAN password '%s' is invalid", opt_val); + iter = words; + + while (iter[0]) { + opt = iter++[0]; + opt_val = iter[0]; + + if (nm_streq (opt, "autoneg")) + parse_ethtool_option_autoneg (opt_val, out_autoneg); + else if (nm_streq (opt, "speed")) + parse_ethtool_option_speed (opt_val, out_speed); + else if (nm_streq (opt, "duplex")) + parse_ethtool_option_duplex (opt_val, out_duplex); + else if (nm_streq (opt, "wol")) + parse_ethtool_option_wol (opt_val, out_flags); + else if (nm_streq (opt, "sopass")) + parse_ethtool_option_sopass (opt_val, out_password); + else { + /* Silently skip unknown options */ continue; } - /* Silently skip unknown options */ + if (iter[0]) + iter++; } } static void -parse_ethtool_options (shvarFile *ifcfg, NMConnection *connection) +parse_ethtool_options (shvarFile *ifcfg, NMSettingWired *s_wired, const char *value) { - NMSettingWired *s_wired; - gs_unref_object NMSettingEthtool *s_ethtool = NULL; NMSettingWiredWakeOnLan wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT; - gs_free char *ethtool_opts_free = NULL; - const char *ethtool_opts; - gs_free char *wol_password = NULL; - gs_free char *wol_value_free = NULL; - const char *tmp; - gboolean autoneg = FALSE; + gs_free char *wol_password = NULL, *wol_value = NULL; + gboolean ignore_wol_password = FALSE, autoneg = FALSE; guint32 speed = 0; const char *duplex = NULL; - ethtool_opts = svGetValue (ifcfg, "ETHTOOL_OPTS", ðtool_opts_free); - if (ethtool_opts) { + if (value) { + gs_free const char **opts = NULL; + const char *const *iter; + /* WAKE_ON_LAN_IGNORE is inferred from a specified but empty ETHTOOL_OPTS */ - if (!ethtool_opts[0]) + if (!value[0]) wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; - else { - gs_free const char **opts = NULL; - const char *const *iter; - - opts = nm_utils_strsplit_set (ethtool_opts, ";", FALSE); - for (iter = opts; iter && iter[0]; iter++) { - /* in case of repeated wol_passwords, parse_ethtool_option() - * will do the right thing and clear wol_password before resetting. */ - parse_ethtool_option (iter[0], - &wol_flags, - &wol_password, - &autoneg, - &speed, - &duplex, - &s_ethtool); - } + + opts = nm_utils_strsplit_set (value, ";"); + for (iter = opts; iter && iter[0]; iter++) { + /* in case of repeated wol_passwords, parse_ethtool_option() + * will do the right thing and clear wol_password before resetting. */ + parse_ethtool_option (iter[0], &wol_flags, &wol_password, &autoneg, &speed, &duplex); } } /* ETHTOOL_WAKE_ON_LAN = ignore overrides WoL settings in ETHTOOL_OPTS */ - tmp = svGetValueStr (ifcfg, "ETHTOOL_WAKE_ON_LAN", &wol_value_free); - if (nm_streq0 (tmp, "ignore")) - wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; - else if (tmp) - PARSE_WARNING ("invalid ETHTOOL_WAKE_ON_LAN value '%s'", tmp); + wol_value = svGetValueStr_cp (ifcfg, "ETHTOOL_WAKE_ON_LAN"); + if (wol_value) { + if (strcmp (wol_value, "ignore") == 0) + wol_flags = NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE; + else + PARSE_WARNING ("invalid ETHTOOL_WAKE_ON_LAN value '%s'", wol_value); + } if ( wol_password && !NM_FLAGS_HAS (wol_flags, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) { PARSE_WARNING ("Wake-on-LAN password not expected"); - nm_clear_g_free (&wol_password); + ignore_wol_password = TRUE; } - s_wired = nm_connection_get_setting_wired (connection); - if (s_wired) { - g_object_set (s_wired, - NM_SETTING_WIRED_WAKE_ON_LAN, wol_flags, - NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, wol_password, - NM_SETTING_WIRED_AUTO_NEGOTIATE, autoneg, - NM_SETTING_WIRED_SPEED, speed, - NM_SETTING_WIRED_DUPLEX, duplex, - NULL); - } - - if (s_ethtool) { - nm_connection_add_setting (connection, - NM_SETTING (g_steal_pointer (&s_ethtool))); - } + g_object_set (s_wired, + NM_SETTING_WIRED_WAKE_ON_LAN, wol_flags, + NM_SETTING_WIRED_WAKE_ON_LAN_PASSWORD, ignore_wol_password ? NULL : wol_password, + NM_SETTING_WIRED_AUTO_NEGOTIATE, autoneg, + NM_SETTING_WIRED_SPEED, speed, + NM_SETTING_WIRED_DUPLEX, duplex, + NULL); } static NMSetting * @@ -4424,7 +4230,7 @@ make_wired_setting (shvarFile *ifcfg, gs_free const char **chans = NULL; guint32 num_chans; - chans = nm_utils_strsplit_set (value, ",", FALSE); + chans = nm_utils_strsplit_set (value, ","); num_chans = NM_PTRARRAY_LEN (chans); if (num_chans < 2 || num_chans > 3) { PARSE_WARNING ("invalid SUBCHANNELS '%s' (%u channels, 2 or 3 expected)", @@ -4512,6 +4318,10 @@ make_wired_setting (shvarFile *ifcfg, nm_clear_g_free (&value); } + parse_ethtool_options (ifcfg, s_wired, + svGetValue (ifcfg, "ETHTOOL_OPTS", &value)); + nm_clear_g_free (&value); + return (NMSetting *) g_steal_pointer (&s_wired); } @@ -4747,7 +4557,7 @@ make_bond_setting (shvarFile *ifcfg, gs_free const char **items = NULL; const char *const *iter; - items = nm_utils_strsplit_set (v, " ", FALSE); + items = nm_utils_strsplit_set (v, " "); for (iter = items; iter && *iter; iter++) { gs_strfreev char **keys = NULL; const char *key, *val; @@ -5025,7 +4835,7 @@ handle_bridging_opts (NMSetting *setting, gs_free const char **items = NULL; const char *const *iter; - items = nm_utils_strsplit_set (value, " ", FALSE); + items = nm_utils_strsplit_set (value, " "); for (iter = items; iter && *iter; iter++) { gs_strfreev char **keys = NULL; const char *key, *val; @@ -5245,7 +5055,7 @@ parse_prio_map_list (NMSettingVlan *s_vlan, v = svGetValueStr (ifcfg, key, &value); if (!v) return; - list = nm_utils_strsplit_set (v, ",", FALSE); + list = nm_utils_strsplit_set (v, ","); for (iter = list; iter && *iter; iter++) { if (!strchr (*iter, ':')) @@ -5267,7 +5077,7 @@ make_vlan_setting (shvarFile *ifcfg, const char *v = NULL; int vlan_id = -1; guint32 vlan_flags = 0; - int gvrp, reorder_hdr; + gint gvrp, reorder_hdr; v = svGetValueStr (ifcfg, "VLAN_ID", &value); if (v) { @@ -5350,7 +5160,7 @@ make_vlan_setting (shvarFile *ifcfg, gs_free const char **strv = NULL; const char *const *ptr; - strv = nm_utils_strsplit_set (v, ", ", FALSE); + strv = nm_utils_strsplit_set (v, ", "); for (ptr = strv; ptr && *ptr; ptr++) { if (nm_streq (*ptr, "GVRP") && gvrp == -1) vlan_flags |= NM_VLAN_FLAG_GVRP; @@ -5492,7 +5302,7 @@ check_dns_search_domains (shvarFile *ifcfg, NMSetting *s_ip4, NMSetting *s_ip6) gs_free const char **searches = NULL; const char *const *item; - searches = nm_utils_strsplit_set (v, " ", FALSE); + searches = nm_utils_strsplit_set (v, " "); if (searches) { for (item = searches; *item; item++) { if (!nm_setting_ip_config_add_dns_search (NM_SETTING_IP_CONFIG (s_ip6), *item)) @@ -5511,13 +5321,12 @@ connection_from_file_full (const char *filename, GError **error, gboolean *out_ignore_error) { - nm_auto_shvar_file_close shvarFile *main_ifcfg = NULL; + nm_auto_shvar_file_close shvarFile *parsed = NULL; nm_auto_shvar_file_close shvarFile *network_ifcfg = NULL; gs_unref_object NMConnection *connection = NULL; gs_free char *type = NULL; char *devtype, *bootproto; NMSetting *s_ip4, *s_ip6, *s_tc, *s_proxy, *s_port, *s_dcb = NULL, *s_user; - NMSetting *s_sriov, *s_match; const char *ifcfg_name = NULL; gboolean has_ip4_defroute = FALSE; gboolean has_complex_routes_v4; @@ -5539,14 +5348,14 @@ connection_from_file_full (const char *filename, return NULL; } - main_ifcfg = svOpenFile (filename, error); - if (!main_ifcfg) + parsed = svOpenFile (filename, error); + if (!parsed) return NULL; network_ifcfg = svOpenFile (network_file, NULL); - if (!svGetValueBoolean (main_ifcfg, "NM_CONTROLLED", TRUE)) { - connection = create_unhandled_connection (filename, main_ifcfg, "unmanaged", out_unhandled); + if (!svGetValueBoolean (parsed, "NM_CONTROLLED", TRUE)) { + connection = create_unhandled_connection (filename, parsed, "unmanaged", out_unhandled); if (!connection) { NM_SET_OUT (out_ignore_error, TRUE); g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_FAILED, @@ -5556,7 +5365,7 @@ connection_from_file_full (const char *filename, } /* iBFT is handled by the iBFT settings plugin */ - bootproto = svGetValueStr_cp (main_ifcfg, "BOOTPROTO"); + bootproto = svGetValueStr_cp (parsed, "BOOTPROTO"); if (bootproto && !g_ascii_strcasecmp (bootproto, "ibft")) { NM_SET_OUT (out_ignore_error, TRUE); g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, @@ -5566,19 +5375,19 @@ connection_from_file_full (const char *filename, } g_free (bootproto); - devtype = svGetValueStr_cp (main_ifcfg, "DEVICETYPE"); + devtype = svGetValueStr_cp (parsed, "DEVICETYPE"); if (devtype) { if (!strcasecmp (devtype, TYPE_TEAM)) type = g_strdup (TYPE_TEAM); else if (!strcasecmp (devtype, TYPE_TEAM_PORT)) { gs_free char *device = NULL; - type = svGetValueStr_cp (main_ifcfg, "TYPE"); - device = svGetValueStr_cp (main_ifcfg, "DEVICE"); + type = svGetValueStr_cp (parsed, "TYPE"); + device = svGetValueStr_cp (parsed, "DEVICE"); if (type) { /* nothing to do */ - } else if (device && is_vlan_device (device, main_ifcfg)) + } else if (device && is_vlan_device (device, parsed)) type = g_strdup (TYPE_VLAN); else type = g_strdup (TYPE_ETHERNET); @@ -5591,26 +5400,26 @@ connection_from_file_full (const char *filename, /* Team and TeamPort types are also accepted by the mere * presence of TEAM_CONFIG/TEAM_MASTER. They don't require * DEVICETYPE. */ - t = svGetValueStr_cp (main_ifcfg, "TEAM_CONFIG"); + t = svGetValueStr_cp (parsed, "TEAM_CONFIG"); if (t) type = g_strdup (TYPE_TEAM); } if (!type) - type = svGetValueStr_cp (main_ifcfg, "TYPE"); + type = svGetValueStr_cp (parsed, "TYPE"); if (!type) { gs_free char *tmp = NULL; char *device; - if ((tmp = svGetValueStr_cp (main_ifcfg, "IPV6TUNNELIPV4"))) { + if ((tmp = svGetValueStr_cp (parsed, "IPV6TUNNELIPV4"))) { NM_SET_OUT (out_ignore_error, TRUE); g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Ignoring unsupported connection due to IPV6TUNNELIPV4"); return NULL; } - device = svGetValueStr_cp (main_ifcfg, "DEVICE"); + device = svGetValueStr_cp (parsed, "DEVICE"); if (!device) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "File '%s' had neither TYPE nor DEVICE keys.", filename); @@ -5626,11 +5435,11 @@ connection_from_file_full (const char *filename, } if (!test_type) { - if (is_bond_device (device, main_ifcfg)) + if (is_bond_device (device, parsed)) type = g_strdup (TYPE_BOND); - else if (is_vlan_device (device, main_ifcfg)) + else if (is_vlan_device (device, parsed)) type = g_strdup (TYPE_VLAN); - else if (is_wifi_device (device, main_ifcfg)) + else if (is_wifi_device (device, parsed)) type = g_strdup (TYPE_WIRELESS); else { gs_free char *p_path = NULL; @@ -5696,14 +5505,14 @@ connection_from_file_full (const char *filename, if (nm_streq0 (type, TYPE_ETHERNET)) { gs_free char *bond_options = NULL; - if (svGetValueStr (main_ifcfg, "BONDING_OPTS", &bond_options)) { + if (svGetValueStr (parsed, "BONDING_OPTS", &bond_options)) { /* initscripts consider these as bond masters */ g_free (type); type = g_strdup (TYPE_BOND); } } - if (svGetValueBoolean (main_ifcfg, "BONDING_MASTER", FALSE) && + if (svGetValueBoolean (parsed, "BONDING_MASTER", FALSE) && strcasecmp (type, TYPE_BOND)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "BONDING_MASTER=yes key only allowed in TYPE=bond connections"); @@ -5712,21 +5521,21 @@ connection_from_file_full (const char *filename, /* Construct the connection */ if (!strcasecmp (type, TYPE_ETHERNET)) - connection = wired_connection_from_ifcfg (filename, main_ifcfg, error); + connection = wired_connection_from_ifcfg (filename, parsed, error); else if (!strcasecmp (type, TYPE_WIRELESS)) - connection = wireless_connection_from_ifcfg (filename, main_ifcfg, error); + connection = wireless_connection_from_ifcfg (filename, parsed, error); else if (!strcasecmp (type, TYPE_INFINIBAND)) - connection = infiniband_connection_from_ifcfg (filename, main_ifcfg, error); + connection = infiniband_connection_from_ifcfg (filename, parsed, error); else if (!strcasecmp (type, TYPE_BOND)) - connection = bond_connection_from_ifcfg (filename, main_ifcfg, error); + connection = bond_connection_from_ifcfg (filename, parsed, error); else if (!strcasecmp (type, TYPE_TEAM)) - connection = team_connection_from_ifcfg (filename, main_ifcfg, error); + connection = team_connection_from_ifcfg (filename, parsed, error); else if (!strcasecmp (type, TYPE_VLAN)) - connection = vlan_connection_from_ifcfg (filename, main_ifcfg, error); + connection = vlan_connection_from_ifcfg (filename, parsed, error); else if (!strcasecmp (type, TYPE_BRIDGE)) - connection = bridge_connection_from_ifcfg (filename, main_ifcfg, error); + connection = bridge_connection_from_ifcfg (filename, parsed, error); else { - connection = create_unhandled_connection (filename, main_ifcfg, "unrecognized", out_unhandled); + connection = create_unhandled_connection (filename, parsed, "unrecognized", out_unhandled); if (!connection) { PARSE_WARNING ("connection type was unrecognized but device was not uniquely identified; device may be managed"); g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, @@ -5738,8 +5547,6 @@ connection_from_file_full (const char *filename, if (!connection) return NULL; - parse_ethtool_options (main_ifcfg, connection); - has_complex_routes_v4 = utils_has_complex_routes (filename, AF_INET); has_complex_routes_v6 = utils_has_complex_routes (filename, AF_INET6); @@ -5752,7 +5559,7 @@ connection_from_file_full (const char *filename, PARSE_WARNING ("'rule-' and 'rule6-' files are present; you will need to use a dispatcher script to apply these routes"); } - s_ip6 = make_ip6_setting (main_ifcfg, + s_ip6 = make_ip6_setting (parsed, network_ifcfg, !has_complex_routes_v4 && !has_complex_routes_v6, error); @@ -5761,7 +5568,7 @@ connection_from_file_full (const char *filename, else nm_connection_add_setting (connection, s_ip6); - s_ip4 = make_ip4_setting (main_ifcfg, + s_ip4 = make_ip4_setting (parsed, network_ifcfg, !has_complex_routes_v4 && !has_complex_routes_v6, &has_ip4_defroute, @@ -5775,11 +5582,7 @@ connection_from_file_full (const char *filename, nm_connection_add_setting (connection, s_ip4); } - s_sriov = make_sriov_setting (main_ifcfg); - if (s_sriov) - nm_connection_add_setting (connection, s_sriov); - - s_tc = make_tc_setting (main_ifcfg); + s_tc = make_tc_setting (parsed); if (s_tc) nm_connection_add_setting (connection, s_tc); @@ -5787,31 +5590,27 @@ connection_from_file_full (const char *filename, * config fails for some reason, we read DOMAIN and put the * values into IPv6 config instead of IPv4. */ - check_dns_search_domains (main_ifcfg, s_ip4, s_ip6); + check_dns_search_domains (parsed, s_ip4, s_ip6); - s_proxy = make_proxy_setting (main_ifcfg); + s_proxy = make_proxy_setting (parsed); if (s_proxy) nm_connection_add_setting (connection, s_proxy); - s_user = make_user_setting (main_ifcfg); + s_user = make_user_setting (parsed); if (s_user) nm_connection_add_setting (connection, s_user); - s_match = make_match_setting (main_ifcfg); - if (s_match) - nm_connection_add_setting (connection, s_match); - /* Bridge port? */ - s_port = make_bridge_port_setting (main_ifcfg); + s_port = make_bridge_port_setting (parsed); if (s_port) nm_connection_add_setting (connection, s_port); /* Team port? */ - s_port = make_team_port_setting (main_ifcfg); + s_port = make_team_port_setting (parsed); if (s_port) nm_connection_add_setting (connection, s_port); - if (!make_dcb_setting (main_ifcfg, &s_dcb, error)) + if (!make_dcb_setting (parsed, &s_dcb, error)) return NULL; if (s_dcb) nm_connection_add_setting (connection, s_dcb); diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c index 49096d26..862e640e 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c @@ -470,104 +470,3 @@ nms_ifcfg_rh_utils_user_key_decode (const char *name, GString *str_buffer) return TRUE; } - -/*****************************************************************************/ - -const char *const _nm_ethtool_ifcfg_names[] = { -#define ETHT_NAME(eid, ename) \ -[eid - _NM_ETHTOOL_ID_FEATURE_FIRST] = ""ename"" - /* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */ - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_ESP_HW_OFFLOAD, "esp-hw-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_ESP_TX_CSUM_HW_OFFLOAD, "esp-tx-csum-hw-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_FCOE_MTU, "fcoe-mtu"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GRO, "gro"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_GSO, "gso"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_HIGHDMA, "highdma"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_HW_TC_OFFLOAD, "hw-tc-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_L2_FWD_OFFLOAD, "l2-fwd-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_LOOPBACK, "loopback"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_LRO, "lro"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_NTUPLE, "ntuple"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX, "rx"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXHASH, "rxhash"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RXVLAN, "rxvlan"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_ALL, "rx-all"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_FCS, "rx-fcs"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_GRO_HW, "rx-gro-hw"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_UDP_TUNNEL_PORT_OFFLOAD, "rx-udp_tunnel-port-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_VLAN_FILTER, "rx-vlan-filter"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_FILTER, "rx-vlan-stag-filter"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_RX_VLAN_STAG_HW_PARSE, "rx-vlan-stag-hw-parse"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_SG, "sg"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TLS_HW_RECORD, "tls-hw-record"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TLS_HW_TX_OFFLOAD, "tls-hw-tx-offload"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TSO, "tso"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX, "tx"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TXVLAN, "txvlan"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_FCOE_CRC, "tx-checksum-fcoe-crc"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV4, "tx-checksum-ipv4"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IPV6, "tx-checksum-ipv6"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_IP_GENERIC, "tx-checksum-ip-generic"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_CHECKSUM_SCTP, "tx-checksum-sctp"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_ESP_SEGMENTATION, "tx-esp-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_FCOE_SEGMENTATION, "tx-fcoe-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GRE_CSUM_SEGMENTATION, "tx-gre-csum-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GRE_SEGMENTATION, "tx-gre-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GSO_PARTIAL, "tx-gso-partial"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_GSO_ROBUST, "tx-gso-robust"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_IPXIP4_SEGMENTATION, "tx-ipxip4-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_IPXIP6_SEGMENTATION, "tx-ipxip6-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_NOCACHE_COPY, "tx-nocache-copy"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER, "tx-scatter-gather"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_SCATTER_GATHER_FRAGLIST, "tx-scatter-gather-fraglist"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_SCTP_SEGMENTATION, "tx-sctp-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP6_SEGMENTATION, "tx-tcp6-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP_ECN_SEGMENTATION, "tx-tcp-ecn-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP_MANGLEID_SEGMENTATION, "tx-tcp-mangleid-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_TCP_SEGMENTATION, "tx-tcp-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_UDP_SEGMENTATION, "tx-udp-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_CSUM_SEGMENTATION, "tx-udp_tnl-csum-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_UDP_TNL_SEGMENTATION, "tx-udp_tnl-segmentation"), - ETHT_NAME (NM_ETHTOOL_ID_FEATURE_TX_VLAN_STAG_HW_INSERT, "tx-vlan-stag-hw-insert"), -}; - -const NMEthtoolData * -nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name) -{ - static const struct { - NMEthtoolID ethtool_id; - const char *kernel_name; - } kernel_names[] = { - { NM_ETHTOOL_ID_FEATURE_GRO, "rx-gro" }, - { NM_ETHTOOL_ID_FEATURE_GSO, "tx-generic-segmentation" }, - { NM_ETHTOOL_ID_FEATURE_LRO, "rx-lro" }, - { NM_ETHTOOL_ID_FEATURE_NTUPLE, "rx-ntuple-filter" }, - { NM_ETHTOOL_ID_FEATURE_RX, "rx-checksum" }, - { NM_ETHTOOL_ID_FEATURE_RXHASH, "rx-hashing" }, - { NM_ETHTOOL_ID_FEATURE_RXVLAN, "rx-vlan-hw-parse" }, - { NM_ETHTOOL_ID_FEATURE_TXVLAN, "tx-vlan-hw-insert" }, - }; - guint i; - - for (i = 0; i < G_N_ELEMENTS (_nm_ethtool_ifcfg_names); i++) { - if (nm_streq (name, _nm_ethtool_ifcfg_names[i])) - return nm_ethtool_data[i]; - } - - /* Option not found. Note that ethtool utility has built-in features and - * NetworkManager's API follows the naming of these built-in features, whenever - * they exist. - * For example, NM's "ethtool.feature-ntuple" corresponds to ethtool utility's "ntuple" - * feature. However the underlying kernel feature is called "rx-ntuple-filter" (as reported - * for ETH_SS_FEATURES). - * - * With ethtool utility, whose command line we attempt to parse here, the user can also - * specify the name of the underlying kernel feature directly. So, check whether that is - * the case and if yes, map them to the corresponding NetworkManager's features. */ - for (i = 0; i < G_N_ELEMENTS (kernel_names); i++) { - if (nm_streq (name, kernel_names[i].kernel_name)) - return nm_ethtool_data[kernel_names[i].ethtool_id]; - } - - return NULL; -} diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h index 84c22094..3756af7c 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h @@ -22,15 +22,14 @@ #define _UTILS_H_ #include "nm-connection.h" -#include "nm-ethtool-utils.h" #include "shvar.h" #define NM_IFCFG_CONNECTION_LOG_PATH(path) ((path) ?: "in-memory") #define NM_IFCFG_CONNECTION_LOG_FMT "%s (%s,\"%s\")" -#define NM_IFCFG_CONNECTION_LOG_ARG(con) NM_IFCFG_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_settings_connection_get_uuid ((NMSettingsConnection *) (con)), nm_settings_connection_get_id ((NMSettingsConnection *) (con)) +#define NM_IFCFG_CONNECTION_LOG_ARG(con) NM_IFCFG_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_connection_get_uuid ((NMConnection *) (con)), nm_connection_get_id ((NMConnection *) (con)) #define NM_IFCFG_CONNECTION_LOG_FMTD "%s (%s,\"%s\",%p)" -#define NM_IFCFG_CONNECTION_LOG_ARGD(con) NM_IFCFG_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_settings_connection_get_uuid ((NMSettingsConnection *) (con)), nm_settings_connection_get_id ((NMSettingsConnection *) (con)), (con) +#define NM_IFCFG_CONNECTION_LOG_ARGD(con) NM_IFCFG_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_connection_get_uuid ((NMConnection *) (con)), nm_connection_get_id ((NMConnection *) (con)), (con) char *utils_cert_path (const char *parent, const char *suffix, const char *extension); @@ -81,20 +80,4 @@ _nms_ifcfg_rh_utils_numbered_tag (char *buf, gsize buf_len, const char *tag_name _nms_ifcfg_rh_utils_numbered_tag (buf, sizeof (buf), ""tag_name"", (which)); \ }) -/*****************************************************************************/ - -extern const char *const _nm_ethtool_ifcfg_names[_NM_ETHTOOL_ID_FEATURE_NUM]; - -static inline const char * -nms_ifcfg_rh_utils_get_ethtool_name (NMEthtoolID ethtool_id) -{ - nm_assert (ethtool_id >= _NM_ETHTOOL_ID_FEATURE_FIRST && ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST); - nm_assert ((ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST) < G_N_ELEMENTS (_nm_ethtool_ifcfg_names)); - nm_assert (_nm_ethtool_ifcfg_names[ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]); - - return _nm_ethtool_ifcfg_names[ethtool_id - _NM_ETHTOOL_ID_FEATURE_FIRST]; -} - -const NMEthtoolData *nms_ifcfg_rh_utils_get_ethtool_by_name (const char *name); - #endif /* _UTILS_H_ */ diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index b70690cc..fdb2e10a 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -33,12 +33,10 @@ #include <stdio.h> #include "nm-utils/nm-enum-utils.h" -#include "nm-utils/nm-io-utils.h" #include "nm-manager.h" #include "nm-setting-connection.h" #include "nm-setting-wired.h" #include "nm-setting-wireless.h" -#include "nm-setting-ethtool.h" #include "nm-setting-8021x.h" #include "nm-setting-proxy.h" #include "nm-setting-ip4-config.h" @@ -52,7 +50,6 @@ #include "nm-core-internal.h" #include "NetworkManagerUtils.h" #include "nm-meta-setting.h" -#include "nm-ethtool-utils.h" #include "nms-ifcfg-rh-common.h" #include "nms-ifcfg-rh-reader.h" @@ -812,7 +809,7 @@ write_wireless_setting (NMConnection *connection, const char *device_mac, *cloned_mac; guint32 mtu, chan, i; gboolean adhoc = FALSE, hex_ssid = FALSE; - const char *const*macaddr_blacklist; + const char * const *macaddr_blacklist; s_wireless = nm_connection_get_setting_wireless (connection); if (!s_wireless) { @@ -1044,9 +1041,16 @@ static gboolean write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { NMSettingWired *s_wired; - const char *const*s390_subchannels; - guint32 mtu, num_opts, i; - const char *const*macaddr_blacklist; + const char *device_mac, *cloned_mac; + char *tmp; + const char *nettype, *portname, *ctcprot, *s390_key, *s390_val, *duplex; + guint32 mtu, num_opts, speed, i; + const char *const *s390_subchannels; + GString *str = NULL; + const char * const *macaddr_blacklist; + gboolean auto_negotiate; + NMSettingWiredWakeOnLan wol; + const char *wol_password; s_wired = nm_connection_get_setting_wired (connection); if (!s_wired) { @@ -1055,211 +1059,144 @@ write_wired_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) return FALSE; } - svSetValueStr (ifcfg, "HWADDR", - nm_setting_wired_get_mac_address (s_wired)); + device_mac = nm_setting_wired_get_mac_address (s_wired); + svSetValueStr (ifcfg, "HWADDR", device_mac); - svSetValueStr (ifcfg, "MACADDR", - nm_setting_wired_get_cloned_mac_address (s_wired)); + cloned_mac = nm_setting_wired_get_cloned_mac_address (s_wired); + svSetValueStr (ifcfg, "MACADDR", cloned_mac); svSetValueStr (ifcfg, "GENERATE_MAC_ADDRESS_MASK", nm_setting_wired_get_generate_mac_address_mask (s_wired)); + svUnsetValue (ifcfg, "HWADDR_BLACKLIST"); macaddr_blacklist = nm_setting_wired_get_mac_address_blacklist (s_wired); if (macaddr_blacklist[0]) { - gs_free char *blacklist_str = NULL; + char *blacklist_str; blacklist_str = g_strjoinv (" ", (char **) macaddr_blacklist); svSetValueStr (ifcfg, "HWADDR_BLACKLIST", blacklist_str); - } else - svUnsetValue (ifcfg, "HWADDR_BLACKLIST"); + g_free (blacklist_str); + } mtu = nm_setting_wired_get_mtu (s_wired); svSetValueInt64_cond (ifcfg, "MTU", mtu != 0, mtu); + svUnsetValue (ifcfg, "SUBCHANNELS"); s390_subchannels = nm_setting_wired_get_s390_subchannels (s_wired); + if (s390_subchannels) { + int len = g_strv_length ((char **)s390_subchannels); - { - gs_free char *tmp = NULL; - gsize len = NM_PTRARRAY_LEN (s390_subchannels); - + tmp = NULL; if (len == 2) { - tmp = g_strdup_printf ("%s,%s", - s390_subchannels[0], - s390_subchannels[1]); + tmp = g_strdup_printf ("%s,%s", s390_subchannels[0], s390_subchannels[1]); } else if (len == 3) { - tmp = g_strdup_printf ("%s,%s,%s", - s390_subchannels[0], - s390_subchannels[1], + tmp = g_strdup_printf ("%s,%s,%s", s390_subchannels[0], s390_subchannels[1], s390_subchannels[2]); } - svSetValueStr (ifcfg, "SUBCHANNELS", tmp); + g_free (tmp); } - svSetValueStr (ifcfg, "NETTYPE", - nm_setting_wired_get_s390_nettype (s_wired)); + svUnsetValue (ifcfg, "NETTYPE"); + nettype = nm_setting_wired_get_s390_nettype (s_wired); + if (nettype) + svSetValueStr (ifcfg, "NETTYPE", nettype); - svSetValueStr (ifcfg, "PORTNAME", - nm_setting_wired_get_s390_option_by_key (s_wired, "portname")); + svUnsetValue (ifcfg, "PORTNAME"); + portname = nm_setting_wired_get_s390_option_by_key (s_wired, "portname"); + if (portname) + svSetValueStr (ifcfg, "PORTNAME", portname); - svSetValueStr (ifcfg, "CTCPROT", - nm_setting_wired_get_s390_option_by_key (s_wired, "ctcprot")); + svUnsetValue (ifcfg, "CTCPROT"); + ctcprot = nm_setting_wired_get_s390_option_by_key (s_wired, "ctcprot"); + if (ctcprot) + svSetValueStr (ifcfg, "CTCPROT", ctcprot); svUnsetValue (ifcfg, "OPTIONS"); num_opts = nm_setting_wired_get_num_s390_options (s_wired); if (s390_subchannels && num_opts) { - nm_auto_free_gstring GString *tmp = NULL; - + str = g_string_sized_new (30); for (i = 0; i < num_opts; i++) { - const char *s390_key, *s390_val; - nm_setting_wired_get_s390_option (s_wired, i, &s390_key, &s390_val); /* portname is handled separately */ if (!strcmp (s390_key, "portname") || !strcmp (s390_key, "ctcprot")) continue; - if (!tmp) - tmp = g_string_sized_new (30); - else - g_string_append_c (tmp, ' '); - g_string_append_printf (tmp, "%s=%s", s390_key, s390_val); + if (str->len) + g_string_append_c (str, ' '); + g_string_append_printf (str, "%s=%s", s390_key, s390_val); } - if (tmp) - svSetValueStr (ifcfg, "OPTIONS", tmp->str); + if (str->len) + svSetValueStr (ifcfg, "OPTIONS", str->str); + g_string_free (str, TRUE); } - svSetValueStr (ifcfg, "TYPE", TYPE_ETHERNET); + /* Stuff ETHTOOL_OPT with required options */ + str = NULL; + auto_negotiate = nm_setting_wired_get_auto_negotiate (s_wired); + speed = nm_setting_wired_get_speed (s_wired); + duplex = nm_setting_wired_get_duplex (s_wired); - return TRUE; -} - -static gboolean -write_ethtool_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) -{ - NMSettingWired *s_wired; - NMSettingEthtool *s_ethtool; - const char *duplex; - guint32 speed; - GString *str = NULL; - gboolean auto_negotiate; - NMSettingWiredWakeOnLan wol; - const char *wol_password; - - s_wired = nm_connection_get_setting_wired (connection); - s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (connection, NM_TYPE_SETTING_ETHTOOL)); - - if (!s_wired && !s_ethtool) { - svUnsetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN"); - svUnsetValue (ifcfg, "ETHTOOL_OPTS"); - return TRUE; + /* autoneg off + speed 0 + duplex NULL, means we want NM + * to skip link configuration which is default. So write + * down link config only if we have auto-negotiate true or + * a valid value for one among speed and duplex. + */ + if (auto_negotiate) { + str = g_string_sized_new (64); + g_string_printf (str, "autoneg on"); + } else if (speed || duplex) { + str = g_string_sized_new (64); + g_string_printf (str, "autoneg off"); } + if (speed) + g_string_append_printf (str, " speed %u", speed); + if (duplex) + g_string_append_printf (str, " duplex %s", duplex); - if (s_wired) { - auto_negotiate = nm_setting_wired_get_auto_negotiate (s_wired); - speed = nm_setting_wired_get_speed (s_wired); - duplex = nm_setting_wired_get_duplex (s_wired); - - /* autoneg off + speed 0 + duplex NULL, means we want NM - * to skip link configuration which is default. So write - * down link config only if we have auto-negotiate true or - * a valid value for one among speed and duplex. - */ - if (auto_negotiate) { - str = g_string_sized_new (64); - g_string_printf (str, "autoneg on"); - } else if (speed || duplex) { - str = g_string_sized_new (64); - g_string_printf (str, "autoneg off"); - } - if (speed) - g_string_append_printf (str, " speed %u", speed); - if (duplex) - g_string_append_printf (str, " duplex %s", duplex); - - wol = nm_setting_wired_get_wake_on_lan (s_wired); - wol_password = nm_setting_wired_get_wake_on_lan_password (s_wired); - - svSetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN", - wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE - ? "ignore" - : NULL); - if (!NM_IN_SET (wol, NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE, - NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT)) { - if (!str) - str = g_string_sized_new (30); - else - g_string_append (str, " "); - - g_string_append (str, "wol "); - - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_PHY)) - g_string_append (str, "p"); - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST)) - g_string_append (str, "u"); - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST)) - g_string_append (str, "m"); - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST)) - g_string_append (str, "b"); - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ARP)) - g_string_append (str, "a"); - if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) - g_string_append (str, "g"); - - if (!NM_FLAGS_ANY (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ALL)) - g_string_append (str, "d"); - - if (wol_password && NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) - g_string_append_printf (str, "s sopass %s", wol_password); - } - } else - svUnsetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN"); - - if (s_ethtool) { - NMEthtoolID ethtool_id; - NMSettingConnection *s_con; - const char *iface = NULL; - - s_con = nm_connection_get_setting_connection (connection); - if (s_con) { - iface = nm_setting_connection_get_interface_name (s_con); - if ( iface - && ( !iface[0] - || !NM_STRCHAR_ALL (iface, ch, (ch >= 'a' && ch <= 'z') - || (ch >= 'A' && ch <= 'Z') - || (ch >= '0' && ch <= '9') - || NM_IN_SET (ch, '_')))) - iface = NULL; - } + wol = nm_setting_wired_get_wake_on_lan (s_wired); + wol_password = nm_setting_wired_get_wake_on_lan_password (s_wired); + if (wol == NM_SETTING_WIRED_WAKE_ON_LAN_IGNORE) + svSetValue (ifcfg, "ETHTOOL_WAKE_ON_LAN", "ignore"); + else if (wol == NM_SETTING_WIRED_WAKE_ON_LAN_DEFAULT) { + if (!str) + svUnsetValue (ifcfg, "ETHTOOL_OPTS"); + } else { if (!str) str = g_string_sized_new (30); else - g_string_append (str, " ; "); - g_string_append (str, "-K "); - g_string_append (str, iface ?: "net0"); + g_string_append (str, " "); - for (ethtool_id = _NM_ETHTOOL_ID_FEATURE_FIRST; ethtool_id <= _NM_ETHTOOL_ID_FEATURE_LAST; ethtool_id++) { - const NMEthtoolData *ed = nm_ethtool_data[ethtool_id]; - NMTernary val; + g_string_append (str, "wol "); - nm_assert (nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); + if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_PHY)) + g_string_append (str, "p"); + if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_UNICAST)) + g_string_append (str, "u"); + if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MULTICAST)) + g_string_append (str, "m"); + if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_BROADCAST)) + g_string_append (str, "b"); + if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ARP)) + g_string_append (str, "a"); + if (NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) + g_string_append (str, "g"); - val = nm_setting_ethtool_get_feature (s_ethtool, ed->optname); - if (val == NM_TERNARY_DEFAULT) - continue; + if (!NM_FLAGS_ANY (wol, NM_SETTING_WIRED_WAKE_ON_LAN_ALL)) + g_string_append (str, "d"); - g_string_append_c (str, ' '); - g_string_append (str, nms_ifcfg_rh_utils_get_ethtool_name (ethtool_id)); - g_string_append (str, val == NM_TERNARY_TRUE ? " on" : " off"); - } + if (wol_password && NM_FLAGS_HAS (wol, NM_SETTING_WIRED_WAKE_ON_LAN_MAGIC)) + g_string_append_printf (str, "s sopass %s", wol_password); } - if (str) { svSetValueStr (ifcfg, "ETHTOOL_OPTS", str->str); g_string_free (str, TRUE); - } else - svUnsetValue (ifcfg, "ETHTOOL_OPTS"); + } + /* End ETHTOOL_OPT stuffing */ + + svSetValueStr (ifcfg, "TYPE", TYPE_ETHERNET); return TRUE; } @@ -1618,7 +1555,7 @@ static void write_dcb_app (shvarFile *ifcfg, const char *tag, NMSettingDcbFlags flags, - int priority) + gint priority) { char prop[NM_STRLEN ("DCB_xxxxxxxxxxxxxxxxxxxxxxx_yyyyyyyyyyyyyyyyyyyy")]; @@ -1788,9 +1725,8 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) guint32 n, i; GString *str; const char *master, *master_iface = NULL, *type; - int vint; + gint vint; NMSettingConnectionMdns mdns; - NMSettingConnectionLlmnr llmnr; guint32 vuint32; const char *tmp; @@ -1810,11 +1746,6 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) vint != -1, vint); - vint = nm_setting_connection_get_multi_connect (s_con); - svSetValueInt64_cond (ifcfg, "MULTI_CONNECT", - vint != NM_CONNECTION_MULTI_CONNECT_DEFAULT, - vint); - /* Only save the value for master connections */ type = nm_setting_connection_get_connection_type (s_con); if (_nm_connection_type_is_master (type)) { @@ -1961,13 +1892,6 @@ write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg) mdns); } else svUnsetValue (ifcfg, "MDNS"); - - llmnr = nm_setting_connection_get_llmnr (s_con); - if (llmnr != NM_SETTING_CONNECTION_LLMNR_DEFAULT) { - svSetValueEnum (ifcfg, "LLMNR", nm_setting_connection_llmnr_get_type (), - llmnr); - } else - svUnsetValue (ifcfg, "LLMNR"); } static char * @@ -2211,45 +2135,6 @@ write_user_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) return TRUE; } -static void -write_sriov_setting (NMConnection *connection, shvarFile *ifcfg) -{ - NMSettingSriov *s_sriov; - guint i, num = 0; - NMTernary b; - NMSriovVF *vf; - char key[32]; - char *str; - - svUnsetAll (ifcfg, SV_KEY_TYPE_SRIOV_VF); - - s_sriov = NM_SETTING_SRIOV (nm_connection_get_setting (connection, NM_TYPE_SETTING_SRIOV)); - if (s_sriov) - num = nm_setting_sriov_get_total_vfs (s_sriov); - if (num == 0) { - svUnsetValue (ifcfg, "SRIOV_TOTAL_VFS"); - svUnsetValue (ifcfg, "SRIOV_AUTOPROBE_DRIVERS"); - return; - } - - svSetValueInt64 (ifcfg, "SRIOV_TOTAL_VFS", num); - - b = nm_setting_sriov_get_autoprobe_drivers (s_sriov); - if (b != NM_TERNARY_DEFAULT) - svSetValueInt64 (ifcfg, "SRIOV_AUTOPROBE_DRIVERS", b); - else - svUnsetValue (ifcfg, "SRIOV_AUTOPROBE_DRIVERS"); - - num = nm_setting_sriov_get_num_vfs (s_sriov); - for (i = 0; i < num; i++) { - vf = nm_setting_sriov_get_vf (s_sriov, i); - nm_sprintf_buf (key, "SRIOV_VF%u", nm_sriov_vf_get_index (vf)); - str = nm_utils_sriov_vf_to_str (vf, TRUE, NULL); - svSetValueStr (ifcfg, key, str); - g_free (str); - } -} - static gboolean write_tc_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) { @@ -2294,38 +2179,6 @@ write_tc_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) return TRUE; } -static gboolean -write_match_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) -{ - NMSettingMatch *s_match; - nm_auto_free_gstring GString *str = NULL; - guint i, num; - - svUnsetValue (ifcfg, "MATCH_INTERFACE_NAME"); - - s_match = (NMSettingMatch *) nm_connection_get_setting (connection, NM_TYPE_SETTING_MATCH); - if (!s_match) - return TRUE; - - num = nm_setting_match_get_num_interface_names (s_match); - for (i = 0; i < num; i++) { - gs_free char *to_free = NULL; - const char *name; - - if (i == 0) - str = g_string_new (""); - else - g_string_append_c (str, ' '); - name = nm_setting_match_get_interface_name (s_match, i); - g_string_append (str, _nm_utils_escape_spaces (name, &to_free)); - } - - if (str) - svSetValueStr (ifcfg, "MATCH_INTERFACE_NAME", str->str); - - return TRUE; -} - static void write_res_options (shvarFile *ifcfg, NMSettingIPConfig *s_ip, const char *var) { @@ -2359,11 +2212,11 @@ write_ip4_setting (NMConnection *connection, const char *value; char *tmp; char tag[64]; - int j; + gint j; guint i, num, n; gint64 route_metric; NMIPRouteTableSyncMode route_table; - int priority; + gint priority; int timeout; GString *searches; const char *method = NULL; @@ -2695,7 +2548,7 @@ write_ip6_setting (NMConnection *connection, NMSettingIPConfig *s_ip4; const char *value; guint i, num, num4; - int priority; + gint priority; NMIPAddress *addr; const char *dns; gint64 route_metric; @@ -3065,17 +2918,9 @@ do_write_construct (NMConnection *connection, if (!write_proxy_setting (connection, ifcfg, error)) return FALSE; - if (!write_ethtool_setting (connection, ifcfg, error)) - return FALSE; - if (!write_user_setting (connection, ifcfg, error)) return FALSE; - if (!write_match_setting (connection, ifcfg, error)) - return FALSE; - - write_sriov_setting (connection, ifcfg); - if (!write_tc_setting (connection, ifcfg, error)) return FALSE; diff --git a/src/settings/plugins/ifcfg-rh/shvar.c b/src/settings/plugins/ifcfg-rh/shvar.c index fe82fbdd..9120b870 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.c +++ b/src/settings/plugins/ifcfg-rh/shvar.c @@ -39,7 +39,6 @@ #include "nm-core-internal.h" #include "nm-core-utils.h" #include "nm-utils/nm-enum-utils.h" -#include "nm-utils/nm-io-utils.h" #include "c-list/src/c-list.h" /*****************************************************************************/ @@ -91,8 +90,8 @@ struct _shvarFile { * * Returns: the parsed boolean value or @fallback. */ -int -svParseBoolean (const char *value, int fallback) +gint +svParseBoolean (const char *value, gint fallback) { if (!value) return fallback; @@ -149,8 +148,8 @@ static char * _escape_ansic (const char *source) { const char *p; - char *dest; - char *q; + gchar *dest; + gchar *q; nm_assert (source); @@ -822,7 +821,6 @@ svOpenFileInternal (const char *name, gboolean create, GError **error) if (nm_utils_fd_get_contents (closefd ? nm_steal_fd (&fd) : fd, closefd, 10 * 1024 * 1024, - NM_UTILS_FILE_GET_CONTENTS_FLAG_NONE, &arena, NULL, &local) < 0) { @@ -872,61 +870,8 @@ svCreateFile (const char *name) /*****************************************************************************/ -static gboolean -_is_all_digits (const char *str) -{ - return str[0] - && NM_STRCHAR_ALL (str, ch, g_ascii_isdigit (ch)); -} - -#define IS_NUMBERED_TAG(key, tab_name) \ - ({ \ - const char *_key = (key); \ - \ - ( (strncmp (_key, tab_name, NM_STRLEN (tab_name)) == 0) \ - && _is_all_digits (&_key[NM_STRLEN (tab_name)])); \ - }) - -static gboolean -_svKeyMatchesType (const char *key, SvKeyType match_key_type) -{ - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ANY)) - return TRUE; - - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTE_SVFORMAT)) { - if ( IS_NUMBERED_TAG (key, "ADDRESS") - || IS_NUMBERED_TAG (key, "NETMASK") - || IS_NUMBERED_TAG (key, "GATEWAY") - || IS_NUMBERED_TAG (key, "METRIC") - || IS_NUMBERED_TAG (key, "OPTIONS")) - return TRUE; - } - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_IP4_ADDRESS)) { - if ( IS_NUMBERED_TAG (key, "IPADDR") - || IS_NUMBERED_TAG (key, "PREFIX") - || IS_NUMBERED_TAG (key, "NETMASK") - || IS_NUMBERED_TAG (key, "GATEWAY")) - return TRUE; - } - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_USER)) { - if (g_str_has_prefix (key, "NM_USER_")) - return TRUE; - } - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_TC)) { - if ( IS_NUMBERED_TAG (key, "QDISC") - || IS_NUMBERED_TAG (key, "FILTER")) - return TRUE; - } - if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_SRIOV_VF)) { - if (IS_NUMBERED_TAG (key, "SRIOV_VF")) - return TRUE; - } - - return FALSE; -} - GHashTable * -svGetKeys (shvarFile *s, SvKeyType match_key_type) +svGetKeys (shvarFile *s) { GHashTable *keys = NULL; CList *current; @@ -936,9 +881,7 @@ svGetKeys (shvarFile *s, SvKeyType match_key_type) c_list_for_each (current, &s->lst_head) { line = c_list_entry (current, shvarLine, lst); - if ( line->key - && line->line - && _svKeyMatchesType (line->key, match_key_type)) { + if (line->key && line->line) { /* we don't clone the keys. The keys are only valid * until @s gets modified. */ if (!keys) @@ -1101,8 +1044,8 @@ svGetValueStr_cp (shvarFile *s, const char *key) * * Returns: the parsed boolean value or @fallback. */ -int -svGetValueBoolean (shvarFile *s, const char *key, int fallback) +gint +svGetValueBoolean (shvarFile *s, const char *key, gint fallback) { gs_free char *to_free = NULL; const char *value; @@ -1177,6 +1120,21 @@ svGetValueEnum (shvarFile *s, const char *key, /*****************************************************************************/ +static gboolean +_is_all_digits (const char *str) +{ + return str[0] + && NM_STRCHAR_ALL (str, ch, g_ascii_isdigit (ch)); +} + +#define IS_NUMBERED_TAG(key, tab_name) \ + ({ \ + const char *_key = (key); \ + \ + ( (strncmp (_key, tab_name, NM_STRLEN (tab_name)) == 0) \ + && _is_all_digits (&_key[NM_STRLEN (tab_name)])); \ + }) + gboolean svUnsetAll (shvarFile *s, SvKeyType match_key_type) { @@ -1192,11 +1150,38 @@ svUnsetAll (shvarFile *s, SvKeyType match_key_type) if (!line->key) continue; - if (_svKeyMatchesType (line->key, match_key_type)) { - if (nm_clear_g_free (&line->line)) { - ASSERT_shvarLine (line); - changed = TRUE; - } + if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ANY)) + goto do_clear; + if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_ROUTE_SVFORMAT)) { + if ( IS_NUMBERED_TAG (line->key, "ADDRESS") + || IS_NUMBERED_TAG (line->key, "NETMASK") + || IS_NUMBERED_TAG (line->key, "GATEWAY") + || IS_NUMBERED_TAG (line->key, "METRIC") + || IS_NUMBERED_TAG (line->key, "OPTIONS")) + goto do_clear; + } + if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_IP4_ADDRESS)) { + if ( IS_NUMBERED_TAG (line->key, "IPADDR") + || IS_NUMBERED_TAG (line->key, "PREFIX") + || IS_NUMBERED_TAG (line->key, "NETMASK") + || IS_NUMBERED_TAG (line->key, "GATEWAY")) + goto do_clear; + } + if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_USER)) { + if (g_str_has_prefix (line->key, "NM_USER_")) + goto do_clear; + } + if (NM_FLAGS_HAS (match_key_type, SV_KEY_TYPE_TC)) { + if ( IS_NUMBERED_TAG (line->key, "QDISC") + || IS_NUMBERED_TAG (line->key, "FILTER")) + goto do_clear; + } + + continue; +do_clear: + if (nm_clear_g_free (&line->line)) { + ASSERT_shvarLine (line); + changed = TRUE; } } diff --git a/src/settings/plugins/ifcfg-rh/shvar.h b/src/settings/plugins/ifcfg-rh/shvar.h index 622bb474..dbc4d950 100644 --- a/src/settings/plugins/ifcfg-rh/shvar.h +++ b/src/settings/plugins/ifcfg-rh/shvar.h @@ -33,15 +33,6 @@ typedef struct _shvarFile shvarFile; -typedef enum { - SV_KEY_TYPE_ANY = (1LL << 0), - SV_KEY_TYPE_ROUTE_SVFORMAT = (1LL << 1), - SV_KEY_TYPE_IP4_ADDRESS = (1LL << 2), - SV_KEY_TYPE_TC = (1LL << 3), - SV_KEY_TYPE_USER = (1LL << 4), - SV_KEY_TYPE_SRIOV_VF = (1LL << 5), -} SvKeyType; - const char *svFileGetName (const shvarFile *s); void _nmtst_svFileSetName (shvarFile *s, const char *fileName); @@ -65,15 +56,15 @@ char *svGetValue_cp (shvarFile *s, const char *key); const char *svGetValueStr (shvarFile *s, const char *key, char **to_free); char *svGetValueStr_cp (shvarFile *s, const char *key); -int svParseBoolean (const char *value, int def); +gint svParseBoolean (const char *value, gint def); -GHashTable *svGetKeys (shvarFile *s, SvKeyType match_key_type); +GHashTable *svGetKeys (shvarFile *s); /* return TRUE if <key> resolves to any truth value (e.g. "yes", "y", "true") * return FALSE if <key> resolves to any non-truth value (e.g. "no", "n", "false") * return <def> otherwise */ -int svGetValueBoolean (shvarFile *s, const char *key, int def); +gint svGetValueBoolean (shvarFile *s, const char *key, gint def); gint64 svGetValueInt64 (shvarFile *s, const char *key, guint base, gint64 min, gint64 max, gint64 fallback); @@ -94,6 +85,15 @@ gboolean svSetValueInt64_cond (shvarFile *s, const char *key, gboolean do_set, g gboolean svSetValueEnum (shvarFile *s, const char *key, GType gtype, int value); gboolean svUnsetValue (shvarFile *s, const char *key); + +typedef enum { + SV_KEY_TYPE_ANY = (1LL << 0), + SV_KEY_TYPE_ROUTE_SVFORMAT = (1LL << 1), + SV_KEY_TYPE_IP4_ADDRESS = (1LL << 2), + SV_KEY_TYPE_TC = (1LL << 3), + SV_KEY_TYPE_USER = (1LL << 4), +} SvKeyType; + gboolean svUnsetAll (shvarFile *s, SvKeyType match_key_type); /* Write the current contents iff modified. Returns FALSE on error diff --git a/src/settings/plugins/ifcfg-rh/tests/meson.build b/src/settings/plugins/ifcfg-rh/tests/meson.build index 0593f12d..3d72d892 100644 --- a/src/settings/plugins/ifcfg-rh/tests/meson.build +++ b/src/settings/plugins/ifcfg-rh/tests/meson.build @@ -6,6 +6,7 @@ exe = executable( test_unit, test_unit + '.c', dependencies: test_nm_dep, + c_args: nm_build_cflags, link_with: libnms_ifcfg_rh_core ) diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected index 214f5da5..8f421cfb 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Auto-Negotiate.cexpected @@ -1,7 +1,7 @@ +ETHTOOL_OPTS="autoneg off speed 10 duplex half" TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no -ETHTOOL_OPTS="autoneg off speed 10 duplex half" BOOTPROTO=dhcp DEFROUTE=yes IPV4_FAILURE_FATAL=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected index de66dcdd..398a3017 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_Wake-on-LAN.cexpected @@ -1,7 +1,7 @@ +ETHTOOL_OPTS="wol umgs sopass 00:00:00:11:22:33" TYPE=Ethernet PROXY_METHOD=none BROWSER_ONLY=no -ETHTOOL_OPTS="wol umgs sopass 00:00:00:11:22:33" BOOTPROTO=dhcp DEFROUTE=yes IPV4_FAILURE_FATAL=no diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_match.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_match.cexpected deleted file mode 100644 index f0cd36cb..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-Test_Write_Wired_match.cexpected +++ /dev/null @@ -1,11 +0,0 @@ -TYPE=Ethernet -PROXY_METHOD=none -BROWSER_ONLY=no -MATCH_INTERFACE_NAME="ens* eth\\ 1? !veth*" -BOOTPROTO=dhcp -DEFROUTE=yes -IPV4_FAILURE_FATAL=no -IPV6INIT=no -NAME="Test Write Wired with Match setting" -UUID=${UUID} -ONBOOT=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov deleted file mode 100644 index 142f56e4..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov +++ /dev/null @@ -1,19 +0,0 @@ -TYPE=Ethernet -DEVICE=eth0 -HWADDR=00:11:22:33:44:55 -BOOTPROTO=none -ONBOOT=yes -DNS1=4.2.2.1 -DNS2=4.2.2.2 -IPADDR=192.168.1.5 -PREFIX=24 -NETMASK=255.255.255.0 -GATEWAY=192.168.1.1 -IPV6INIT=no -NAME=ethernet-sriov -UUID=acc703b8-e751-44ce-b456-1550bdf2057e -SRIOV_TOTAL_VFS=16 -SRIOV_AUTOPROBE_DRIVERS=0 -SRIOV_VF15="max-tx-rate=200 mac=01:23:45:67:89:ab vlans=2" -SRIOV_VF12="trust=false min-tx-rate=100 vlans=1.200.ad" -SRIOV_VF3="mac=55:44:33:22:11:00 spoof-check=true" diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov-write.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov-write.cexpected deleted file mode 100644 index c882c479..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-sriov-write.cexpected +++ /dev/null @@ -1,18 +0,0 @@ -TYPE=Ethernet -PROXY_METHOD=none -BROWSER_ONLY=no -SRIOV_TOTAL_VFS=64 -SRIOV_AUTOPROBE_DRIVERS=1 -SRIOV_VF2="mac=55:55:55:55:55:55 vlans=3.10.ad;10" -SRIOV_VF19=spoof-check=true -BOOTPROTO=none -IPADDR=1.1.1.3 -PREFIX=24 -GATEWAY=1.1.1.1 -DEFROUTE=yes -IPV4_FAILURE_FATAL=no -IPV6INIT=no -NAME="Test Write SR-IOV config" -UUID=${UUID} -DEVICE=eth0 -ONBOOT=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected deleted file mode 100644 index 42608576..00000000 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test_write_wired_auto_negotiate_on.cexpected +++ /dev/null @@ -1,15 +0,0 @@ -TYPE=Ethernet -PROXY_METHOD=none -BROWSER_ONLY=no -ETHTOOL_OPTS="autoneg on ; -K net0 rxvlan off tx on" -BOOTPROTO=dhcp -DEFROUTE=yes -IPV4_FAILURE_FATAL=no -IPV6INIT=yes -IPV6_AUTOCONF=yes -IPV6_DEFROUTE=yes -IPV6_FAILURE_FATAL=no -IPV6_ADDR_GEN_MODE=stable-privacy -NAME="Test Write Wired Auto-Negotiate" -UUID=${UUID} -ONBOOT=yes diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index 0c0dd64e..1331391d 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -43,14 +43,12 @@ #include "nm-setting-pppoe.h" #include "nm-setting-ppp.h" #include "nm-setting-vpn.h" -#include "nm-setting-ethtool.h" #include "nm-setting-gsm.h" #include "nm-setting-cdma.h" #include "nm-setting-serial.h" #include "nm-setting-vlan.h" #include "nm-setting-dcb.h" #include "nm-core-internal.h" -#include "nm-ethtool-utils.h" #include "NetworkManagerUtils.h" @@ -187,8 +185,7 @@ _assert_expected_content (NMConnection *connection, const char *filename, const if ( len_expectd != len_written || memcmp (content_expectd, content_written, len_expectd) != 0) { - if ( g_getenv ("NMTST_IFCFG_RH_UPDATE_EXPECTED") - || nm_streq0 (g_getenv ("NM_TEST_REGENERATE"), "1")) { + if (g_getenv ("NMTST_IFCFG_RH_UPDATE_EXPECTED")) { if (uuid) { gs_free char *search = g_strdup_printf ("UUID=%s\n", uuid); const char *s; @@ -1901,8 +1898,10 @@ test_read_write_802_1X_subj_matches (void) gs_unref_object NMConnection *reread = NULL; NMSetting8021x *s_8021x; + NMTST_EXPECT_NM_WARN ("*missing IEEE_8021X_CA_CERT*peap*"); connection = _connection_from_file (TEST_IFCFG_DIR"/ifcfg-test-wired-802-1X-subj-matches", NULL, TYPE_ETHERNET, NULL); + g_test_assert_expected_messages (); /* ===== 802.1x SETTING ===== */ s_8021x = nm_connection_get_setting_802_1x (connection); @@ -1920,12 +1919,16 @@ test_read_write_802_1X_subj_matches (void) g_assert_cmpstr (nm_setting_802_1x_get_phase2_altsubject_match (s_8021x, 0), ==, "x.yourdomain.tld"); g_assert_cmpstr (nm_setting_802_1x_get_phase2_altsubject_match (s_8021x, 1), ==, "y.yourdomain.tld"); + NMTST_EXPECT_NM_WARN ("*missing IEEE_8021X_CA_CERT for EAP method 'peap'; this is insecure!"); _writer_new_connec_exp (connection, TEST_SCRATCH_DIR, TEST_IFCFG_DIR"/ifcfg-System_test-wired-802-1X-subj-matches.cexpected", &testfile); + g_test_assert_expected_messages (); + NMTST_EXPECT_NM_WARN ("*missing IEEE_8021X_CA_CERT for EAP method 'peap'; this is insecure!"); reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); + g_test_assert_expected_messages (); nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); @@ -3114,7 +3117,8 @@ test_read_wifi_wpa_psk_hex (void) ssid = nm_setting_wireless_get_ssid (s_wireless); g_assert (ssid); - g_assert (nm_utils_gbytes_equal_mem (ssid, expected_ssid, strlen (expected_ssid))); + g_assert_cmpint (g_bytes_get_size (ssid), ==, strlen (expected_ssid)); + g_assert (memcmp (g_bytes_get_data (ssid, NULL), expected_ssid, strlen (expected_ssid)) == 0); /* ===== WIRELESS SECURITY SETTING ===== */ @@ -3721,7 +3725,6 @@ test_write_wired_auto_negotiate_on (void) gs_unref_object NMConnection *connection = NULL; gs_unref_object NMConnection *reread = NULL; NMSettingWired *s_wired; - NMSettingEthtool *s_ethtool; char *val; shvarFile *f; @@ -3731,14 +3734,8 @@ test_write_wired_auto_negotiate_on (void) NM_SETTING_WIRED_AUTO_NEGOTIATE, TRUE, NULL); - s_ethtool = NM_SETTING_ETHTOOL (nm_setting_ethtool_new ()); - nm_setting_ethtool_set_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TX, NM_TERNARY_TRUE); - nm_setting_ethtool_set_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN, NM_TERNARY_FALSE); - nm_connection_add_setting (connection, NM_SETTING (s_ethtool)); - - _writer_new_connec_exp (connection, + _writer_new_connection (connection, TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-test_write_wired_auto_negotiate_on.cexpected", &testfile); f = _svOpenFile (testfile); @@ -3752,15 +3749,7 @@ test_write_wired_auto_negotiate_on (void) reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_verifies_without_normalization (reread); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); - - s_ethtool = NM_SETTING_ETHTOOL (nm_connection_get_setting (reread, NM_TYPE_SETTING_ETHTOOL)); - g_assert (s_ethtool); - g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TX), ==, NM_TERNARY_TRUE); - g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_RXVLAN), ==, NM_TERNARY_FALSE); - g_assert_cmpint (nm_setting_ethtool_get_feature (s_ethtool, NM_ETHTOOL_OPTNAME_FEATURE_TXVLAN), ==, NM_TERNARY_DEFAULT); } static void @@ -4428,67 +4417,6 @@ test_write_wired_dhcp (void) } static void -test_write_wired_match (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingWired *s_wired; - NMSettingMatch *s_match; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write Wired with Match setting", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NULL); - - /* Match setting */ - s_match = (NMSettingMatch *) nm_setting_match_new (); - nm_setting_match_add_interface_name (s_match, "ens*"); - nm_setting_match_add_interface_name (s_match, "eth 1?"); - nm_setting_match_add_interface_name (s_match, "!veth*"); - nm_connection_add_setting (connection, NM_SETTING (s_match)); - - nmtst_assert_connection_verifies (connection); - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR"/ifcfg-Test_Write_Wired_match.cexpected", - &testfile); - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -static void test_write_wired_dhcp_plus_ip (void) { nmtst_auto_unlinkfile char *testfile = NULL; @@ -9704,153 +9632,6 @@ test_utils_ignore (void) do_test_utils_ignored ("ignored-augtmp", "ifcfg-FooBar" AUGTMP_TAG, TRUE); } -/*****************************************************************************/ - -static void -test_sriov_read (void) -{ - gs_unref_object NMConnection *connection = NULL; - NMSettingSriov *s_sriov; - NMSriovVF *vf; - GVariant *variant; - GError *error = NULL; - char *str; - - connection = _connection_from_file (TEST_IFCFG_DIR "/ifcfg-test-sriov", - NULL, TYPE_ETHERNET,NULL); - - g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "eth0"); - - s_sriov = NM_SETTING_SRIOV (nm_connection_get_setting (connection, NM_TYPE_SETTING_SRIOV)); - g_assert (s_sriov); - - g_assert_cmpint (nm_setting_sriov_get_total_vfs (s_sriov), ==, 16); - g_assert_cmpint (nm_setting_sriov_get_num_vfs (s_sriov), ==, 3); - g_assert_cmpint (nm_setting_sriov_get_autoprobe_drivers (s_sriov), ==, NM_TERNARY_FALSE); - - /* VF 3 */ - vf = nm_setting_sriov_get_vf (s_sriov, 0); - g_assert (vf); - g_assert_cmpint (nm_sriov_vf_get_index (vf), ==, 3); - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_MAC); - g_assert (variant); - g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)); - g_assert_cmpstr (g_variant_get_string (variant, NULL), ==, "55:44:33:22:11:00"); - - variant = nm_sriov_vf_get_attribute (vf, NM_SRIOV_VF_ATTRIBUTE_SPOOF_CHECK); - g_assert (variant); - g_assert (g_variant_is_of_type (variant, G_VARIANT_TYPE_BOOLEAN)); - g_assert_cmpint (g_variant_get_boolean (variant), ==, TRUE); - - /* VF 12 */ - vf = nm_setting_sriov_get_vf (s_sriov, 1); - str = nm_utils_sriov_vf_to_str (vf, FALSE, &error); - g_assert_no_error (error); - g_assert_cmpstr (str, ==, "12 min-tx-rate=100 trust=false vlans=1.200.ad"); - g_free (str); - - /* VF 15 */ - vf = nm_setting_sriov_get_vf (s_sriov, 2); - str = nm_utils_sriov_vf_to_str (vf, FALSE, &error); - g_assert_no_error (error); - g_assert_cmpstr (str, ==, "15 mac=01:23:45:67:89:ab max-tx-rate=200 vlans=2"); - g_free (str); -} - -static void -test_sriov_write (void) -{ - nmtst_auto_unlinkfile char *testfile = NULL; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMConnection *reread = NULL; - NMSettingConnection *s_con; - NMSettingIPConfig *s_ip4; - NMSettingIPConfig *s_ip6; - NMSettingWired *s_wired; - NMSettingSriov *s_sriov; - NMSriovVF *vf; - gs_unref_ptrarray GPtrArray *vfs = NULL; - NMIPAddress *addr; - GError *error = NULL; - - connection = nm_simple_connection_new (); - - /* Connection setting */ - s_con = (NMSettingConnection *) nm_setting_connection_new (); - nm_connection_add_setting (connection, NM_SETTING (s_con)); - - g_object_set (s_con, - NM_SETTING_CONNECTION_ID, "Test Write SR-IOV config", - NM_SETTING_CONNECTION_UUID, nm_utils_uuid_generate_a (), - NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, - NM_SETTING_CONNECTION_INTERFACE_NAME, "eth0", - NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME, - NULL); - - /* Wired setting */ - s_wired = (NMSettingWired *) nm_setting_wired_new (); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); - - /* IP4 setting */ - s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip4)); - - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, - NM_SETTING_IP_CONFIG_GATEWAY, "1.1.1.1", - NM_SETTING_IP_CONFIG_MAY_FAIL, TRUE, - NULL); - - addr = nm_ip_address_new (AF_INET, "1.1.1.3", 24, &error); - g_assert_no_error (error); - nm_setting_ip_config_add_address (s_ip4, addr); - nm_ip_address_unref (addr); - - /* IP6 setting */ - s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); - nm_connection_add_setting (connection, NM_SETTING (s_ip6)); - - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_IGNORE, - NULL); - - /* SRIOV setting */ - s_sriov = (NMSettingSriov *) nm_setting_sriov_new (); - nm_connection_add_setting (connection, NM_SETTING (s_sriov)); - - vfs = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_sriov_vf_unref); - - vf = nm_utils_sriov_vf_from_str ("2 mac=55:55:55:55:55:55 vlans=3.10.ad;10", &error); - nmtst_assert_success (vf, error); - g_ptr_array_add (vfs, vf); - - vf = nm_utils_sriov_vf_from_str ("19 spoof-check=true", &error); - nmtst_assert_success (vf, error); - g_ptr_array_add (vfs, vf); - - g_object_set (s_sriov, - NM_SETTING_SRIOV_TOTAL_VFS, 64, - NM_SETTING_SRIOV_VFS, vfs, - NM_SETTING_SRIOV_AUTOPROBE_DRIVERS, NM_TERNARY_TRUE, - NULL); - - nm_connection_add_setting (connection, nm_setting_proxy_new ()); - - nmtst_assert_connection_verifies_without_normalization (connection); - - _writer_new_connec_exp (connection, - TEST_SCRATCH_DIR, - TEST_IFCFG_DIR "/ifcfg-test-sriov-write.cexpected", - &testfile); - - reread = _connection_from_file (testfile, NULL, TYPE_ETHERNET, NULL); - - nmtst_assert_connection_equals (connection, TRUE, reread, FALSE); -} - -/*****************************************************************************/ - static void test_tc_read (void) { @@ -10126,7 +9907,6 @@ int main (int argc, char **argv) g_test_add_func (TPATH "wired/write/dhcp", test_write_wired_dhcp); g_test_add_func (TPATH "wired/write-dhcp-plus-ip", test_write_wired_dhcp_plus_ip); g_test_add_func (TPATH "wired/write/dhcp-8021x-peap-mschapv2", test_write_wired_dhcp_8021x_peap_mschapv2); - g_test_add_func (TPATH "wired/write/match", test_write_wired_match); #define _add_test_write_wired_8021x_tls(testpath, scheme, flags) \ nmtst_add_test_func (testpath, test_write_wired_8021x_tls, GINT_TO_POINTER (scheme), GINT_TO_POINTER (flags)) @@ -10253,9 +10033,6 @@ int main (int argc, char **argv) g_test_add_func (TPATH "utils/path", test_utils_path); g_test_add_func (TPATH "utils/ignore", test_utils_ignore); - g_test_add_func (TPATH "sriov/read", test_sriov_read); - g_test_add_func (TPATH "sriov/write", test_sriov_write); - g_test_add_func (TPATH "tc/read", test_tc_read); g_test_add_func (TPATH "tc/write", test_tc_write); diff --git a/src/settings/plugins/ifupdown/meson.build b/src/settings/plugins/ifupdown/meson.build index 826c7458..fd028f4d 100644 --- a/src/settings/plugins/ifupdown/meson.build +++ b/src/settings/plugins/ifupdown/meson.build @@ -8,10 +8,13 @@ deps = [ nm_dep ] +cflags = '-DSYSCONFDIR="@0@"'.format(nm_sysconfdir) + libnms_ifupdown_core = static_library( 'nms-ifupdown-core', sources: sources, dependencies: deps, + c_args: cflags ) sources = files( @@ -23,6 +26,7 @@ libnm_settings_plugin_ifupdown = shared_module( 'nm-settings-plugin-ifupdown', sources: sources, dependencies: deps, + c_args: cflags, link_with: libnms_ifupdown_core, link_args: ldflags_linker_script_settings, link_depends: linker_script_settings, diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-connection.c b/src/settings/plugins/ifupdown/nms-ifupdown-connection.c index 1b817044..c3d231fe 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-connection.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-connection.c @@ -49,20 +49,10 @@ G_DEFINE_TYPE (NMIfupdownConnection, nm_ifupdown_connection, NM_TYPE_SETTINGS_CO /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "ifupdown" -#define _NMLOG_DOMAIN LOGD_SETTINGS -#define _NMLOG(level, ...) \ - nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME": " \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)) - -/*****************************************************************************/ - static gboolean supports_secrets (NMSettingsConnection *connection, const char *setting_name) { - _LOGI ("supports_secrets() for setting_name: '%s'", setting_name); + nm_log_info (LOGD_SETTINGS, "supports_secrets() for setting_name: '%s'", setting_name); return (strcmp (setting_name, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME) == 0); } @@ -74,27 +64,26 @@ nm_ifupdown_connection_init (NMIfupdownConnection *connection) { } -NMIfupdownConnection * +NMIfupdownConnection* nm_ifupdown_connection_new (if_block *block) { - NMIfupdownConnection *connection; + GObject *object; GError *error = NULL; g_return_val_if_fail (block != NULL, NULL); - connection = g_object_new (NM_TYPE_IFUPDOWN_CONNECTION, NULL); + object = g_object_new (NM_TYPE_IFUPDOWN_CONNECTION, NULL); - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - if (!ifupdown_update_connection_from_if_block (nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (connection)), - block, - &error)) { - _LOGW ("invalid connection read from /etc/network/interfaces: %s", - error->message); - g_object_unref (connection); + if (!ifupdown_update_connection_from_if_block (NM_CONNECTION (object), block, &error)) { + nm_log_warn (LOGD_SETTINGS, "%s.%d - invalid connection read from /etc/network/interfaces: %s", + __FILE__, + __LINE__, + error->message); + g_object_unref (object); return NULL; } - return connection; + return (NMIfupdownConnection *) object; } static void diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c index d926829f..94a65ecb 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.c @@ -32,90 +32,78 @@ #include "nm-utils.h" -/*****************************************************************************/ +if_block* first; +if_block* last; -static void _ifparser_source (if_parser *parser, const char *path, const char *en_dir, int quiet, int dir); +if_data* last_data; -/*****************************************************************************/ - -#define _NMLOG_PREFIX_NAME "ifupdown" -#define _NMLOG_DOMAIN LOGD_SETTINGS -#define _NMLOG(level, ...) \ - nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME": " \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)) - -/*****************************************************************************/ - -static void -add_block (if_parser *parser, const char *type, const char* name) +void add_block(const char *type, const char* name) { - if_block *ifb; - gsize l_type, l_name; - - l_type = strlen (type) + 1; - l_name = strlen (name) + 1; - - ifb = g_malloc (sizeof (if_block) + l_type + l_name); - memcpy ((char *) ifb->name, name, l_name); - ifb->type = &ifb->name[l_name]; - memcpy ((char *) ifb->type, type, l_type); - c_list_init (&ifb->data_lst_head); - c_list_link_tail (&parser->block_lst_head, &ifb->block_lst); + if_block *ret = g_slice_new0 (struct _if_block); + ret->name = g_strdup(name); + ret->type = g_strdup(type); + if (first == NULL) + first = last = ret; + else + { + last->next = ret; + last = ret; + } + last_data = NULL; } -static void -add_data (if_parser *parser, const char *key, const char *data) +void add_data(const char *key,const char *data) { - if_block *last_block; - if_data *ifd; + if_data *ret; char *idx; - gsize l_key, l_data; - - last_block = c_list_last_entry (&parser->block_lst_head, if_block, block_lst); /* Check if there is a block where we can attach our data */ - if (!last_block) + if (first == NULL) return; - l_key = strlen (key) + 1; - l_data = strlen (data) + 1; - - ifd = g_malloc (sizeof (if_data) + l_key + l_data); - memcpy ((char *) ifd->key, key, l_key); - ifd->data = &ifd->key[l_key]; - memcpy ((char *) ifd->data, data, l_data); + ret = g_slice_new0 (struct _if_data); + ret->key = g_strdup(key); /* Normalize keys. Convert '_' to '-', as ifupdown accepts both variants. * When querying keys via ifparser_getkey(), use '-'. */ - idx = (char *) ifd->key; - while ((idx = strchr (idx, '_'))) - *(idx++) = '-'; + while ((idx = strrchr(ret->key, '_'))) { + *idx = '-'; + } + ret->data = g_strdup(data); - c_list_link_tail (&last_block->data_lst_head, &ifd->data_lst); + if (last->info == NULL) + { + last->info = ret; + last_data = ret; + } + else + { + last_data->next = ret; + last_data = last_data->next; + } } /* join values in src with spaces into dst; dst needs to be large enough */ -static char * -join_values_with_spaces (char *dst, char **src) +static char *join_values_with_spaces(char *dst, char **src) { if (dst != NULL) { *dst = '\0'; if (src != NULL && *src != NULL) { - strcat (dst, *src); + strcat(dst, *src); for (src++; *src != NULL; src++) { - strcat (dst, " "); - strcat (dst, *src); + strcat(dst, " "); + strcat(dst, *src); } } } - return (dst); + return(dst); } +static void _ifparser_source (const char *path, const char *en_dir, int quiet, int dir); + static void -_recursive_ifparser (if_parser *parser, const char *eni_file, int quiet) +_recursive_ifparser (const char *eni_file, int quiet) { FILE *inp; char line[255]; @@ -126,35 +114,36 @@ _recursive_ifparser (if_parser *parser, const char *eni_file, int quiet) /* Check if interfaces file exists and open it */ if (!g_file_test (eni_file, G_FILE_TEST_EXISTS)) { if (!quiet) - _LOGW ("interfaces file %s doesn't exist\n", eni_file); + nm_log_warn (LOGD_SETTINGS, "interfaces file %s doesn't exist\n", eni_file); return; } inp = fopen (eni_file, "re"); if (inp == NULL) { if (!quiet) - _LOGW ("Can't open %s\n", eni_file); + nm_log_warn (LOGD_SETTINGS, "Can't open %s\n", eni_file); return; } if (!quiet) - _LOGI (" interface-parser: parsing file %s\n", eni_file); + nm_log_info (LOGD_SETTINGS, " interface-parser: parsing file %s\n", eni_file); - while (!feof (inp)) { + while (!feof(inp)) + { char *token[128]; /* 255 chars can only be split into 127 tokens */ char value[255]; /* large enough to join previously split tokens */ char *safeptr; int toknum; int len = 0; - char *ptr = fgets (line+offs, 255-offs, inp); + char *ptr = fgets(line+offs, 255-offs, inp); if (ptr == NULL) break; - len = strlen (line); + len = strlen(line); /* skip over-long lines */ - if (!feof (inp) && len > 0 && line[len-1] != '\n') { + if (!feof(inp) && len > 0 && line[len-1] != '\n') { if (!skip_long_line) { if (!quiet) - _LOGW ("Skipping over-long-line '%s...'\n", line); + nm_log_warn (LOGD_SETTINGS, "Skipping over-long-line '%s...'\n", line); } skip_long_line = 1; continue; @@ -181,9 +170,9 @@ _recursive_ifparser (if_parser *parser, const char *eni_file, int quiet) #define SPACES " \t" /* tokenize input; */ - for (toknum = 0, token[toknum] = strtok_r (line, SPACES, &safeptr); + for (toknum = 0, token[toknum] = strtok_r(line, SPACES, &safeptr); token[toknum] != NULL; - toknum++, token[toknum] = strtok_r (NULL, SPACES, &safeptr)) + toknum++, token[toknum] = strtok_r(NULL, SPACES, &safeptr)) ; /* ignore comments and empty lines */ @@ -192,8 +181,8 @@ _recursive_ifparser (if_parser *parser, const char *eni_file, int quiet) if (toknum < 2) { if (!quiet) { - _LOGW ("Can't parse interface line '%s'\n", - join_values_with_spaces (value, token)); + nm_log_warn (LOGD_SETTINGS, "Can't parse interface line '%s'\n", + join_values_with_spaces(value, token)); } skip_to_block = 1; continue; @@ -204,71 +193,71 @@ _recursive_ifparser (if_parser *parser, const char *eni_file, int quiet) * Create a block for each of them except source and source-directory. */ /* iface stanza takes at least 3 parameters */ - if (nm_streq (token[0], "iface")) { + if (strcmp(token[0], "iface") == 0) { if (toknum < 4) { if (!quiet) { - _LOGW ("Can't parse iface line '%s'\n", - join_values_with_spaces (value, token)); + nm_log_warn (LOGD_SETTINGS, "Can't parse iface line '%s'\n", + join_values_with_spaces(value, token)); } continue; } - add_block (parser, token[0], token[1]); + add_block(token[0], token[1]); skip_to_block = 0; - add_data (parser, token[2], join_values_with_spaces (value, token + 3)); + add_data(token[2], join_values_with_spaces(value, token + 3)); } /* auto and allow-auto stanzas are equivalent, * both can take multiple interfaces as parameters: add one block for each */ - else if (NM_IN_STRSET (token[0], "auto", "allow-auto")) { + else if (strcmp(token[0], "auto") == 0 || + strcmp(token[0], "allow-auto") == 0) { int i; - for (i = 1; i < toknum; i++) - add_block (parser, "auto", token[i]); + add_block("auto", token[i]); skip_to_block = 0; } - else if (nm_streq (token[0], "mapping")) { - add_block (parser, token[0], join_values_with_spaces (value, token + 1)); + else if (strcmp(token[0], "mapping") == 0) { + add_block(token[0], join_values_with_spaces(value, token + 1)); skip_to_block = 0; } /* allow-* can take multiple interfaces as parameters: add one block for each */ - else if (g_str_has_prefix (token[0], "allow-")) { + else if (strncmp(token[0],"allow-",6) == 0) { int i; for (i = 1; i < toknum; i++) - add_block (parser, token[0], token[i]); + add_block(token[0], token[i]); skip_to_block = 0; } /* source and source-directory stanzas take one or more paths as parameters */ - else if (NM_IN_STRSET (token[0], "source", "source-directory")) { + else if (strcmp (token[0], "source") == 0 || strcmp (token[0], "source-directory") == 0) { int i; char *en_dir; skip_to_block = 0; en_dir = g_path_get_dirname (eni_file); for (i = 1; i < toknum; ++i) { - if (nm_streq (token[0], "source-directory")) - _ifparser_source (parser, token[i], en_dir, quiet, TRUE); + if (strcmp (token[0], "source-directory") == 0) + _ifparser_source (token[i], en_dir, quiet, TRUE); else - _ifparser_source (parser, token[i], en_dir, quiet, FALSE); + _ifparser_source (token[i], en_dir, quiet, FALSE); } g_free (en_dir); } else { if (skip_to_block) { if (!quiet) { - _LOGW ("ignoring out-of-block data '%s'\n", - join_values_with_spaces (value, token)); + nm_log_warn (LOGD_SETTINGS, "ignoring out-of-block data '%s'\n", + join_values_with_spaces(value, token)); } } else - add_data (parser, token[0], join_values_with_spaces (value, token + 1)); + add_data(token[0], join_values_with_spaces(value, token + 1)); } } - fclose (inp); + fclose(inp); if (!quiet) - _LOGI (" interface-parser: finished parsing file %s\n", eni_file); + nm_log_info (LOGD_SETTINGS, " interface-parser: finished parsing file %s\n", eni_file); } static void -_ifparser_source (if_parser *parser, const char *path, const char *en_dir, int quiet, int dir) +_ifparser_source (const char *path, const char *en_dir, int quiet, int dir) { char *abs_path; const char *item; @@ -283,128 +272,132 @@ _ifparser_source (if_parser *parser, const char *path, const char *en_dir, int q abs_path = g_build_filename (en_dir, path, NULL); if (!quiet) - _LOGI (" interface-parser: source line includes interfaces file(s) %s\n", abs_path); + nm_log_info (LOGD_SETTINGS, " interface-parser: source line includes interfaces file(s) %s\n", abs_path); /* ifupdown uses WRDE_NOCMD for wordexp. */ if (wordexp (abs_path, &we, WRDE_NOCMD)) { if (!quiet) - _LOGW ("word expansion for %s failed\n", abs_path); + nm_log_warn (LOGD_SETTINGS, "word expansion for %s failed\n", abs_path); } else { for (i = 0; i < we.we_wordc; i++) { if (dir) { source_dir = g_dir_open (we.we_wordv[i], 0, &error); if (!source_dir) { if (!quiet) { - _LOGW ("Failed to open directory %s: %s", - we.we_wordv[i], error->message); + nm_log_warn (LOGD_SETTINGS, "Failed to open directory %s: %s", + we.we_wordv[i], error->message); } g_clear_error (&error); } else { while ((item = g_dir_read_name (source_dir))) - _ifparser_source (parser, item, we.we_wordv[i], quiet, FALSE); + _ifparser_source (item, we.we_wordv[i], quiet, FALSE); g_dir_close (source_dir); } } else - _recursive_ifparser (parser, we.we_wordv[i], quiet); + _recursive_ifparser (we.we_wordv[i], quiet); } wordfree (&we); } g_free (abs_path); } -if_parser * -ifparser_parse (const char *eni_file, int quiet) +void ifparser_init (const char *eni_file, int quiet) { - if_parser *parser; - - parser = g_slice_new (if_parser); - c_list_init (&parser->block_lst_head); - _recursive_ifparser (parser, eni_file, quiet); - return parser; + first = last = NULL; + _recursive_ifparser (eni_file, quiet); } -static void -_destroy_data (if_data *ifd) +void _destroy_data(if_data *ifd) { - c_list_unlink_stale (&ifd->data_lst); - g_free (ifd); + if (ifd == NULL) + return; + _destroy_data(ifd->next); + g_free(ifd->key); + g_free(ifd->data); + g_slice_free(struct _if_data, ifd); + return; } -static void -_destroy_block (if_block* ifb) +void _destroy_block(if_block* ifb) { - if_data *ifd; - - while ((ifd = c_list_first_entry (&ifb->data_lst_head, if_data, data_lst))) - _destroy_data (ifd); - c_list_unlink_stale (&ifb->block_lst); - g_free (ifb); + if (ifb == NULL) + return; + _destroy_block(ifb->next); + _destroy_data(ifb->info); + g_free(ifb->name); + g_free(ifb->type); + g_slice_free(struct _if_block, ifb); + return; } -void -ifparser_destroy (if_parser *parser) +void ifparser_destroy(void) { - if_block *ifb; - - while ((ifb = c_list_first_entry (&parser->block_lst_head, if_block, block_lst))) - _destroy_block (ifb); - g_slice_free (if_parser, parser); + _destroy_block(first); + first = last = NULL; } -if_block * -ifparser_getfirst (if_parser *parser) +if_block *ifparser_getfirst(void) { - return c_list_first_entry (&parser->block_lst_head, if_block, block_lst); + return first; } -guint -ifparser_get_num_blocks (if_parser *parser) +int ifparser_get_num_blocks(void) { - return c_list_length (&parser->block_lst_head); + int i = 0; + if_block *iter = first; + + while (iter) { + i++; + iter = iter->next; + } + return i; } -if_block * -ifparser_getif (if_parser *parser, const char* iface) +if_block *ifparser_getif(const char* iface) { - if_block *ifb; - - c_list_for_each_entry (ifb, &parser->block_lst_head, block_lst) { - if ( nm_streq (ifb->type, "iface") - && nm_streq (ifb->name, iface)) - return ifb; + if_block *curr = first; + while(curr!=NULL) + { + if (strcmp(curr->type,"iface")==0 && strcmp(curr->name,iface)==0) + return curr; + curr = curr->next; } return NULL; } -static if_data * -ifparser_findkey (if_block* iface, const char *key) +const char *ifparser_getkey(if_block* iface, const char *key) { - if_data *ifd; - - c_list_for_each_entry (ifd, &iface->data_lst_head, data_lst) { - if (nm_streq (ifd->key, key)) - return ifd; + if_data *curr = iface->info; + while(curr!=NULL) + { + if (strcmp(curr->key,key)==0) + return curr->data; + curr = curr->next; } return NULL; } -const char * -ifparser_getkey (if_block* iface, const char *key) +gboolean +ifparser_haskey(if_block* iface, const char *key) { - if_data *ifd; + if_data *curr = iface->info; - ifd = ifparser_findkey (iface, key); - return ifd ? ifd->data : NULL; + while (curr != NULL) { + if (strcmp (curr->key, key) == 0) + return TRUE; + curr = curr->next; + } + return FALSE; } -gboolean -ifparser_haskey (if_block* iface, const char *key) +int ifparser_get_num_info(if_block* iface) { - return !!ifparser_findkey (iface, key); -} + int i = 0; + if_data *iter = iface->info; -guint -ifparser_get_num_info (if_block* iface) -{ - return c_list_length (&iface->data_lst_head); + while (iter) { + i++; + iter = iter->next; + } + return i; } diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h index f367f626..7e6c8e34 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h +++ b/src/settings/plugins/ifupdown/nms-ifupdown-interface-parser.h @@ -23,37 +23,33 @@ #ifndef _INTERFACE_PARSER_H #define _INTERFACE_PARSER_H -#include "c-list/src/c-list.h" - -typedef struct { - CList data_lst; - const char *data; - const char key[]; +typedef struct _if_data +{ + char *key; + char *data; + struct _if_data *next; } if_data; -typedef struct { - CList block_lst; - CList data_lst_head; - const char *type; - const char name[]; +typedef struct _if_block +{ + char *type; + char *name; + if_data *info; + struct _if_block *next; } if_block; -typedef struct { - CList block_lst_head; -} if_parser; - -if_parser *ifparser_parse (const char *eni_file, int quiet); - -void ifparser_destroy (if_parser *parser); -NM_AUTO_DEFINE_FCN0 (if_parser *, _nm_auto_ifparser, ifparser_destroy); -#define nm_auto_ifparser nm_auto(_nm_auto_ifparser) - -if_block *ifparser_getif (if_parser *parser, const char* iface); -if_block *ifparser_getfirst (if_parser *parser); -const char *ifparser_getkey (if_block* iface, const char *key); -gboolean ifparser_haskey (if_block* iface, const char *key); +void ifparser_init(const char *eni_file, int quiet); +void ifparser_destroy(void); -guint ifparser_get_num_blocks (if_parser *parser); -guint ifparser_get_num_info (if_block* iface); +if_block *ifparser_getif(const char* iface); +if_block *ifparser_getfirst(void); +const char *ifparser_getkey(if_block* iface, const char *key); +gboolean ifparser_haskey(if_block* iface, const char *key); +int ifparser_get_num_blocks(void); +int ifparser_get_num_info(if_block* iface); +void add_block(const char *type, const char* name); +void add_data(const char *key,const char *data); +void _destroy_data(if_data *ifd); +void _destroy_block(if_block* ifb); #endif diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-parser.c b/src/settings/plugins/ifupdown/nms-ifupdown-parser.c index 369fa70d..884c6591 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-parser.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-parser.c @@ -37,64 +37,42 @@ #include "nms-ifupdown-plugin.h" #include "nms-ifupdown-parser.h" -/*****************************************************************************/ - -#define _NMLOG_PREFIX_NAME "ifupdown" -#define _NMLOG_DOMAIN LOGD_SETTINGS -#define _NMLOG(level, ...) \ - nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME": " \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)) - -/*****************************************************************************/ - -#define _str_has_prefix(val, prefix, require_suffix) \ - ({ \ - const char *_val = (val); \ - \ - (strncmp (_val, ""prefix"", NM_STRLEN (prefix)) == 0) \ - && ( !(require_suffix) \ - || _val[NM_STRLEN (prefix)] != '\0'); \ - }) - -static const char* +static const gchar* _ifupdownplugin_guess_connection_type (if_block *block) { - const char *ret_type = NULL; - - if(nm_streq0 (ifparser_getkey (block, "inet"), "ppp")) + if_data *curr = block->info; + const gchar* ret_type = NULL; + const gchar* value = ifparser_getkey(block, "inet"); + if(value && !strcmp("ppp", value)) { ret_type = NM_SETTING_PPP_SETTING_NAME; - else { - if_data *ifb; - - c_list_for_each_entry (ifb, &block->data_lst_head, data_lst) { - if ( _str_has_prefix (ifb->key, "wireless-", FALSE) - || _str_has_prefix (ifb->key, "wpa-", FALSE)) { - ret_type = NM_SETTING_WIRELESS_SETTING_NAME; - break; - } + } + + while(!ret_type && curr) { + if(!strncmp("wireless-", curr->key, strlen("wireless-")) || + !strncmp("wpa-", curr->key, strlen("wpa-"))) { + ret_type = NM_SETTING_WIRELESS_SETTING_NAME; } - if(!ret_type) - ret_type = NM_SETTING_WIRED_SETTING_NAME; + curr = curr->next; } - _LOGI ("guessed connection type (%s) = %s", block->name, ret_type); + if(!ret_type) + ret_type = NM_SETTING_WIRED_SETTING_NAME; + + nm_log_info (LOGD_SETTINGS, "guessed connection type (%s) = %s", block->name, ret_type); return ret_type; } struct _Mapping { - const char *domain; + const gchar *domain; const gpointer target; }; static gpointer -map_by_mapping (struct _Mapping *mapping, const char *key) +map_by_mapping(struct _Mapping *mapping, const gchar *key) { struct _Mapping *curr = mapping; - - while (curr->domain) { - if (nm_streq (curr->domain, key)) + while(curr->domain) { + if(!strcmp(curr->domain, key)) return curr->target; curr++; } @@ -102,11 +80,14 @@ map_by_mapping (struct _Mapping *mapping, const char *key) } static void -update_wireless_setting_from_if_block (NMConnection *connection, - if_block *block) +update_wireless_setting_from_if_block(NMConnection *connection, + if_block *block) { - if_data *curr; - const char *value = ifparser_getkey (block, "inet"); + gint wpa_l= strlen("wpa-"); + gint wireless_l= strlen("wireless-"); + + if_data *curr = block->info; + const gchar* value = ifparser_getkey (block, "inet"); struct _Mapping mapping[] = { {"ssid", "ssid"}, {"essid", "ssid"}, @@ -116,26 +97,27 @@ update_wireless_setting_from_if_block (NMConnection *connection, NMSettingWireless *wireless_setting = NULL; - if (nm_streq0 (value, "ppp")) + if(value && !strcmp("ppp", value)) { return; + } - _LOGI ("update wireless settings (%s).", block->name); - wireless_setting = NM_SETTING_WIRELESS (nm_setting_wireless_new ()); - - c_list_for_each_entry (curr, &block->data_lst_head, data_lst) { - if (_str_has_prefix (curr->key, "wireless-", TRUE)) { - const char* newkey = map_by_mapping (mapping, curr->key + NM_STRLEN ("wireless-")); + nm_log_info (LOGD_SETTINGS, "update wireless settings (%s).", block->name); + wireless_setting = NM_SETTING_WIRELESS(nm_setting_wireless_new()); - _LOGI ("wireless setting key: %s='%s'", newkey, curr->data); - if (nm_streq0 (newkey, "ssid")) { + while(curr) { + if(strlen(curr->key) > wireless_l && + !strncmp("wireless-", curr->key, wireless_l)) { + const gchar* newkey = map_by_mapping(mapping, curr->key+wireless_l); + nm_log_info (LOGD_SETTINGS, "wireless setting key: %s='%s'", newkey, curr->data); + if(newkey && !strcmp("ssid", newkey)) { GBytes *ssid; - int len = strlen (curr->data); + gint len = strlen(curr->data); ssid = g_bytes_new (curr->data, len); g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, ssid, NULL); g_bytes_unref (ssid); - _LOGI ("setting wireless ssid = %d", len); - } else if (nm_streq0 (newkey, "mode")) { + nm_log_info (LOGD_SETTINGS, "setting wireless ssid = %d", len); + } else if(newkey && !strcmp("mode", newkey)) { if (!g_ascii_strcasecmp (curr->data, "Managed") || !g_ascii_strcasecmp (curr->data, "Auto")) g_object_set (wireless_setting, NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_INFRA, NULL); else if (!g_ascii_strcasecmp (curr->data, "Ad-Hoc")) @@ -143,37 +125,39 @@ update_wireless_setting_from_if_block (NMConnection *connection, else if (!g_ascii_strcasecmp (curr->data, "Master")) g_object_set (wireless_setting, NM_SETTING_WIRELESS_MODE, NM_SETTING_WIRELESS_MODE_AP, NULL); else - _LOGW ("Invalid mode '%s' (not 'Ad-Hoc', 'Ap', 'Managed', or 'Auto')", curr->data); + nm_log_warn (LOGD_SETTINGS, "Invalid mode '%s' (not 'Ad-Hoc', 'Ap', 'Managed', or 'Auto')", curr->data); } else { - g_object_set (wireless_setting, - newkey, curr->data, - NULL); + g_object_set(wireless_setting, + newkey, curr->data, + NULL); } - } else if (_str_has_prefix (curr->key, "wpa-", TRUE)) { - const char* newkey = map_by_mapping (mapping, curr->key + NM_STRLEN ("wpa-")); + } else if(strlen(curr->key) > wpa_l && + !strncmp("wpa-", curr->key, wpa_l)) { + const gchar* newkey = map_by_mapping(mapping, curr->key+wpa_l); - if (nm_streq0 (newkey, "ssid")) { + if(newkey && !strcmp("ssid", newkey)) { GBytes *ssid; - int len = strlen (curr->data); + gint len = strlen(curr->data); ssid = g_bytes_new (curr->data, len); g_object_set (wireless_setting, NM_SETTING_WIRELESS_SSID, ssid, NULL); g_bytes_unref (ssid); - _LOGI ("setting wpa ssid = %d", len); - } else if (newkey) { + nm_log_info (LOGD_SETTINGS, "setting wpa ssid = %d", len); + } else if(newkey) { - g_object_set (wireless_setting, - newkey, curr->data, - NULL); - _LOGI ("setting wpa newkey(%s)=data(%s)", newkey, curr->data); + g_object_set(wireless_setting, + newkey, curr->data, + NULL); + nm_log_info (LOGD_SETTINGS, "setting wpa newkey(%s)=data(%s)", newkey, curr->data); } } + curr = curr->next; } - nm_connection_add_setting (connection, (NMSetting*) wireless_setting); + nm_connection_add_setting(connection, (NMSetting*) wireless_setting); } -typedef char* (*IfupdownStrDupeFunc) (gconstpointer value, gpointer data); -typedef gpointer (*IfupdownStrToTypeFunc) (const char* value); +typedef gchar* (*IfupdownStrDupeFunc) (gpointer value, gpointer data); +typedef gpointer (*IfupdownStrToTypeFunc) (const gchar* value); static char* normalize_dupe_wireless_key (gpointer value, gpointer data) { @@ -193,7 +177,7 @@ normalize_dupe_wireless_key (gpointer value, gpointer data) { result_cur += next - delim; delim = next + 1; } - if (*delim && strlen (valuec) > GPOINTER_TO_UINT (delim - valuec)) { + if (*delim && strlen (valuec) > GPOINTER_TO_UINT(delim - valuec)) { strncpy (result_cur, delim, endc - delim); result_cur += endc - delim; } @@ -203,12 +187,12 @@ normalize_dupe_wireless_key (gpointer value, gpointer data) { static char* normalize_dupe (gpointer value, gpointer data) { - return g_strdup (value); + return g_strdup(value); } static char* normalize_tolower (gpointer value, gpointer data) { - return g_ascii_strdown (value, -1); + return g_ascii_strdown(value, -1); } static char *normalize_psk (gpointer value, gpointer data) @@ -219,25 +203,25 @@ static char *normalize_psk (gpointer value, gpointer data) } static gpointer -string_to_gpointerint (const char* data) +string_to_gpointerint(const gchar* data) { - int result = (int) strtol (data, NULL, 10); - return GINT_TO_POINTER (result); + gint result = (gint) strtol (data, NULL, 10); + return GINT_TO_POINTER(result); } static gpointer -string_to_glist_of_strings (const char* data) +string_to_glist_of_strings(const gchar* data) { GSList *ret = NULL; - char *string = (char*) data; - while (string) { - char* next = NULL; - if ( (next = strchr (string, ' ')) || - (next = strchr (string, '\t')) || - (next = strchr (string, '\0')) ) { - - char *part = g_strndup (string, (next - string)); - ret = g_slist_append (ret, part); + gchar *string = (gchar*) data; + while(string) { + gchar* next = NULL; + if( (next = strchr(string, ' ')) || + (next = strchr(string, '\t')) || + (next = strchr(string, '\0')) ) { + + gchar *part = g_strndup(string, (next - string)); + ret = g_slist_append(ret, part); if (*next) string = next+1; else @@ -250,17 +234,19 @@ string_to_glist_of_strings (const char* data) } static void -slist_free_all (gpointer slist) +slist_free_all(gpointer slist) { g_slist_free_full ((GSList *) slist, g_free); } static void -update_wireless_security_setting_from_if_block (NMConnection *connection, - if_block *block) +update_wireless_security_setting_from_if_block(NMConnection *connection, + if_block *block) { - if_data *curr; - const char* value = ifparser_getkey (block, "inet"); + gint wpa_l= strlen("wpa-"); + gint wireless_l= strlen("wireless-"); + if_data *curr = block->info; + const gchar* value = ifparser_getkey (block, "inet"); struct _Mapping mapping[] = { {"psk", "psk"}, {"identity", "leap-username"}, @@ -316,93 +302,101 @@ update_wireless_security_setting_from_if_block (NMConnection *connection, NMSettingWireless *s_wireless; gboolean security = FALSE; - if (nm_streq0 (value, "ppp")) + if(value && !strcmp("ppp", value)) { return; + } + + s_wireless = nm_connection_get_setting_wireless(connection); + g_return_if_fail(s_wireless); - s_wireless = nm_connection_get_setting_wireless (connection); - g_return_if_fail (s_wireless); + nm_log_info (LOGD_SETTINGS, "update wireless security settings (%s).", block->name); + wireless_security_setting = + NM_SETTING_WIRELESS_SECURITY(nm_setting_wireless_security_new()); - _LOGI ("update wireless security settings (%s).", block->name); - wireless_security_setting = NM_SETTING_WIRELESS_SECURITY (nm_setting_wireless_security_new ()); + while(curr) { + if(strlen(curr->key) > wireless_l && + !strncmp("wireless-", curr->key, wireless_l)) { - c_list_for_each_entry (curr, &block->data_lst_head, data_lst) { - if (_str_has_prefix (curr->key, "wireless-", TRUE)) { - const char *key = curr->key + NM_STRLEN ("wireless-"); - char *property_value = NULL; + gchar *property_value = NULL; gpointer typed_property_value = NULL; - const char* newkey = map_by_mapping (mapping, key); - IfupdownStrDupeFunc dupe_func = map_by_mapping (dupe_mapping, key); - IfupdownStrToTypeFunc type_map_func = map_by_mapping (type_mapping, key); - GFreeFunc free_func = map_by_mapping (free_type_mapping, key); - if (!newkey || !dupe_func) + const gchar* newkey = map_by_mapping(mapping, curr->key+wireless_l); + IfupdownStrDupeFunc dupe_func = map_by_mapping (dupe_mapping, curr->key+wireless_l); + IfupdownStrToTypeFunc type_map_func = map_by_mapping (type_mapping, curr->key+wireless_l); + GFreeFunc free_func = map_by_mapping (free_type_mapping, curr->key+wireless_l); + if(!newkey || !dupe_func) goto next; property_value = (*dupe_func) (curr->data, connection); - _LOGI ("setting wireless security key: %s=%s", - newkey, property_value); + nm_log_info (LOGD_SETTINGS, "setting wireless security key: %s=%s", + newkey, property_value); if (type_map_func) { errno = 0; typed_property_value = (*type_map_func) (property_value); - if (errno) + if(errno) goto wireless_next; } - g_object_set (wireless_security_setting, - newkey, typed_property_value ?: property_value, - NULL); + g_object_set(wireless_security_setting, + newkey, typed_property_value ?: property_value, + NULL); security = TRUE; -wireless_next: - g_free (property_value); + wireless_next: + g_free(property_value); if (typed_property_value && free_func) (*free_func) (typed_property_value); - } else if (_str_has_prefix (curr->key, "wpa-", TRUE)) { - const char *key = curr->key + NM_STRLEN ("wpa-"); - char *property_value = NULL; + } else if(strlen(curr->key) > wpa_l && + !strncmp("wpa-", curr->key, wpa_l)) { + + gchar *property_value = NULL; gpointer typed_property_value = NULL; - const char* newkey = map_by_mapping (mapping, key); - IfupdownStrDupeFunc dupe_func = map_by_mapping (dupe_mapping, key); - IfupdownStrToTypeFunc type_map_func = map_by_mapping (type_mapping, key); - GFreeFunc free_func = map_by_mapping (free_type_mapping, key); - if (!newkey || !dupe_func) + const gchar* newkey = map_by_mapping(mapping, curr->key+wpa_l); + IfupdownStrDupeFunc dupe_func = map_by_mapping (dupe_mapping, curr->key+wpa_l); + IfupdownStrToTypeFunc type_map_func = map_by_mapping (type_mapping, curr->key+wpa_l); + GFreeFunc free_func = map_by_mapping (free_type_mapping, curr->key+wpa_l); + if(!newkey || !dupe_func) goto next; property_value = (*dupe_func) (curr->data, connection); - _LOGI ("setting wpa security key: %s=%s", - newkey, - NM_IN_STRSET (newkey, "key", - "leap-password", - "pin", - "psk", - "wep-key0", - "wep-key1", - "wep-key2", - "wep-key3") - ? "<omitted>" - : property_value - ); + nm_log_info (LOGD_SETTINGS, "setting wpa security key: %s=%s", + newkey, +#ifdef DEBUG_SECRETS + property_value +#else /* DEBUG_SECRETS */ + !strcmp("key", newkey) || + !strcmp("leap-password", newkey) || + !strcmp("pin", newkey) || + !strcmp("psk", newkey) || + !strcmp("wep-key0", newkey) || + !strcmp("wep-key1", newkey) || + !strcmp("wep-key2", newkey) || + !strcmp("wep-key3", newkey) || + NULL ? + "<omitted>" : property_value +#endif /* DEBUG_SECRETS */ + ); if (type_map_func) { errno = 0; typed_property_value = (*type_map_func) (property_value); - if (errno) + if(errno) goto wpa_next; } - g_object_set (wireless_security_setting, - newkey, typed_property_value ?: property_value, - NULL); + g_object_set(wireless_security_setting, + newkey, typed_property_value ?: property_value, + NULL); security = TRUE; -wpa_next: - g_free (property_value); + wpa_next: + g_free(property_value); if (free_func && typed_property_value) (*free_func) (typed_property_value); } -next: - ; + next: + curr = curr->next; } if (security) @@ -410,52 +404,51 @@ next: } static void -update_wired_setting_from_if_block (NMConnection *connection, - if_block *block) +update_wired_setting_from_if_block(NMConnection *connection, + if_block *block) { NMSettingWired *s_wired = NULL; - s_wired = NM_SETTING_WIRED (nm_setting_wired_new ()); - nm_connection_add_setting (connection, NM_SETTING (s_wired)); + s_wired = NM_SETTING_WIRED(nm_setting_wired_new()); + nm_connection_add_setting(connection, NM_SETTING(s_wired)); } static void ifupdown_ip4_add_dns (NMSettingIPConfig *s_ip4, const char *dns) { guint32 addr; - gs_strfreev char **list = NULL; - char **iter; + char **list, **iter; if (dns == NULL) return; list = g_strsplit_set (dns, " \t", -1); for (iter = list; iter && *iter; iter++) { - if ((*iter)[0] == '\0') + g_strstrip (*iter); + if (g_ascii_isspace (*iter[0])) continue; if (!inet_pton (AF_INET, *iter, &addr)) { - _LOGW (" ignoring invalid nameserver '%s'", *iter); + nm_log_warn (LOGD_SETTINGS, " ignoring invalid nameserver '%s'", *iter); continue; } if (!nm_setting_ip_config_add_dns (s_ip4, *iter)) - _LOGW (" duplicate DNS domain '%s'", *iter); + nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *iter); } + g_strfreev (list); } static gboolean -update_ip4_setting_from_if_block (NMConnection *connection, - if_block *block, - GError **error) +update_ip4_setting_from_if_block(NMConnection *connection, + if_block *block, + GError **error) { - gs_unref_object NMSettingIPConfig *s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new ()); - const char *type = ifparser_getkey (block, "inet"); + NMSettingIPConfig *s_ip4 = NM_SETTING_IP_CONFIG (nm_setting_ip4_config_new()); + const char *type = ifparser_getkey(block, "inet"); + gboolean is_static = type && !strcmp("static", type); - if (!nm_streq0 (type, "static")) { - g_object_set (s_ip4, - NM_SETTING_IP_CONFIG_METHOD, - NM_SETTING_IP4_CONFIG_METHOD_AUTO, - NULL); + if (!is_static) { + g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL); } else { guint32 tmp_mask; NMIPAddress *addr; @@ -465,6 +458,7 @@ update_ip4_setting_from_if_block (NMConnection *connection, const char *nameserver_v; const char *nameservers_v; const char *search_v; + char **list, **iter; guint32 netmask_int = 32; /* Address */ @@ -472,7 +466,7 @@ update_ip4_setting_from_if_block (NMConnection *connection, if (!address_v) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IPv4 address"); - return FALSE; + goto error; } /* mask/prefix */ @@ -482,8 +476,8 @@ update_ip4_setting_from_if_block (NMConnection *connection, netmask_int = atoi (netmask_v); } else if (!inet_pton (AF_INET, netmask_v, &tmp_mask)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, - "Invalid IPv4 netmask '%s'", netmask_v); - return FALSE; + "Invalid IPv4 netmask '%s'", netmask_v); + goto error; } else { netmask_int = nm_utils_ip4_netmask_to_prefix (tmp_mask); } @@ -492,13 +486,13 @@ update_ip4_setting_from_if_block (NMConnection *connection, /* Add the new address to the setting */ addr = nm_ip_address_new (AF_INET, address_v, netmask_int, error); if (!addr) - return FALSE; + goto error; if (nm_setting_ip_config_add_address (s_ip4, addr)) { - _LOGI ("addresses count: %d", - nm_setting_ip_config_get_num_addresses (s_ip4)); + nm_log_info (LOGD_SETTINGS, "addresses count: %d", + nm_setting_ip_config_get_num_addresses (s_ip4)); } else { - _LOGI ("ignoring duplicate IP4 address"); + nm_log_info (LOGD_SETTINGS, "ignoring duplicate IP4 address"); } nm_ip_address_unref (addr); @@ -508,7 +502,7 @@ update_ip4_setting_from_if_block (NMConnection *connection, if (!nm_utils_ipaddr_valid (AF_INET, gateway_v)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IPv4 gateway '%s'", gateway_v); - return FALSE; + goto error; } if (!nm_setting_ip_config_get_gateway (s_ip4)) g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL); @@ -521,67 +515,70 @@ update_ip4_setting_from_if_block (NMConnection *connection, ifupdown_ip4_add_dns (s_ip4, nameservers_v); if (!nm_setting_ip_config_get_num_dns (s_ip4)) - _LOGI ("No dns-nameserver configured in /etc/network/interfaces"); + nm_log_info (LOGD_SETTINGS, "No dns-nameserver configured in /etc/network/interfaces"); /* DNS searches */ search_v = ifparser_getkey (block, "dns-search"); if (search_v) { - gs_strfreev char **list = NULL; - char **iter; - list = g_strsplit_set (search_v, " \t", -1); for (iter = list; iter && *iter; iter++) { - if ((*iter)[0] == '\0') + g_strstrip (*iter); + if (g_ascii_isspace (*iter[0])) continue; if (!nm_setting_ip_config_add_dns_search (s_ip4, *iter)) - _LOGW (" duplicate DNS domain '%s'", *iter); + nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *iter); } + g_strfreev (list); } g_object_set (s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_MANUAL, NULL); } - nm_connection_add_setting (connection, NM_SETTING (g_steal_pointer (&s_ip4))); + nm_connection_add_setting (connection, NM_SETTING (s_ip4)); return TRUE; + +error: + g_object_unref (s_ip4); + return FALSE; } static void ifupdown_ip6_add_dns (NMSettingIPConfig *s_ip6, const char *dns) { struct in6_addr addr; - gs_strfreev char **list = NULL; - char **iter; + char **list, **iter; if (dns == NULL) return; list = g_strsplit_set (dns, " \t", -1); for (iter = list; iter && *iter; iter++) { - if ((*iter)[0] == '\0') + g_strstrip (*iter); + if (g_ascii_isspace (*iter[0])) continue; if (!inet_pton (AF_INET6, *iter, &addr)) { - _LOGW (" ignoring invalid nameserver '%s'", *iter); + nm_log_warn (LOGD_SETTINGS, " ignoring invalid nameserver '%s'", *iter); continue; } if (!nm_setting_ip_config_add_dns (s_ip6, *iter)) - _LOGW (" duplicate DNS domain '%s'", *iter); + nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *iter); } + g_strfreev (list); } static gboolean -update_ip6_setting_from_if_block (NMConnection *connection, - if_block *block, - GError **error) +update_ip6_setting_from_if_block(NMConnection *connection, + if_block *block, + GError **error) { - gs_unref_object NMSettingIPConfig *s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new ()); - const char *type = ifparser_getkey (block, "inet6"); + NMSettingIPConfig *s_ip6 = NM_SETTING_IP_CONFIG (nm_setting_ip6_config_new()); + const char *type = ifparser_getkey(block, "inet6"); + gboolean is_static = type && (!strcmp("static", type) || + !strcmp("v4tunnel", type)); - if (!NM_IN_STRSET (type, "static", "v4tunnel")) { - g_object_set (s_ip6, - NM_SETTING_IP_CONFIG_METHOD, - NM_SETTING_IP6_CONFIG_METHOD_AUTO, - NULL); + if (!is_static) { + g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL); } else { NMIPAddress *addr; const char *address_v; @@ -591,30 +588,31 @@ update_ip6_setting_from_if_block (NMConnection *connection, const char *nameservers_v; const char *search_v; int prefix_int = 128; + char **list, **iter; /* Address */ - address_v = ifparser_getkey (block, "address"); + address_v = ifparser_getkey(block, "address"); if (!address_v) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Missing IPv6 address"); - return FALSE; + goto error; } /* Prefix */ - prefix_v = ifparser_getkey (block, "netmask"); + prefix_v = ifparser_getkey(block, "netmask"); if (prefix_v) prefix_int = g_ascii_strtoll (prefix_v, NULL, 10); /* Add the new address to the setting */ addr = nm_ip_address_new (AF_INET6, address_v, prefix_int, error); if (!addr) - return FALSE; + goto error; if (nm_setting_ip_config_add_address (s_ip6, addr)) { - _LOGI ("addresses count: %d", + nm_log_info (LOGD_SETTINGS, "addresses count: %d", nm_setting_ip_config_get_num_addresses (s_ip6)); } else { - _LOGI ("ignoring duplicate IP6 address"); + nm_log_info (LOGD_SETTINGS, "ignoring duplicate IP6 address"); } nm_ip_address_unref (addr); @@ -624,34 +622,33 @@ update_ip6_setting_from_if_block (NMConnection *connection, if (!nm_utils_ipaddr_valid (AF_INET6, gateway_v)) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Invalid IPv6 gateway '%s'", gateway_v); - return FALSE; + goto error; } if (!nm_setting_ip_config_get_gateway (s_ip6)) g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, gateway_v, NULL); } - nameserver_v = ifparser_getkey (block, "dns-nameserver"); + nameserver_v = ifparser_getkey(block, "dns-nameserver"); ifupdown_ip6_add_dns (s_ip6, nameserver_v); - nameservers_v = ifparser_getkey (block, "dns-nameservers"); + nameservers_v = ifparser_getkey(block, "dns-nameservers"); ifupdown_ip6_add_dns (s_ip6, nameservers_v); if (!nm_setting_ip_config_get_num_dns (s_ip6)) - _LOGI ("No dns-nameserver configured in /etc/network/interfaces"); + nm_log_info (LOGD_SETTINGS, "No dns-nameserver configured in /etc/network/interfaces"); /* DNS searches */ search_v = ifparser_getkey (block, "dns-search"); if (search_v) { - gs_strfreev char **list = NULL; - char **iter; - list = g_strsplit_set (search_v, " \t", -1); for (iter = list; iter && *iter; iter++) { - if ((*iter)[0] == '\0') + g_strstrip (*iter); + if (isblank (*iter[0])) continue; if (!nm_setting_ip_config_add_dns_search (s_ip6, *iter)) - _LOGW (" duplicate DNS domain '%s'", *iter); + nm_log_warn (LOGD_SETTINGS, " duplicate DNS domain '%s'", *iter); } + g_strfreev (list); } g_object_set (s_ip6, @@ -659,8 +656,12 @@ update_ip6_setting_from_if_block (NMConnection *connection, NULL); } - nm_connection_add_setting (connection, NM_SETTING (g_steal_pointer (&s_ip6))); + nm_connection_add_setting (connection, NM_SETTING (s_ip6)); return TRUE; + +error: + g_object_unref (s_ip6); + return FALSE; } gboolean @@ -668,22 +669,25 @@ ifupdown_update_connection_from_if_block (NMConnection *connection, if_block *block, GError **error) { - const char *type; - gs_free char *idstr = NULL; - gs_free char *uuid = NULL; + const char *type = NULL; + char *idstr = NULL; + char *uuid_base = NULL; + char *uuid = NULL; NMSettingConnection *s_con; gboolean success = FALSE; s_con = nm_connection_get_setting_connection (connection); - if (!s_con) { - s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); + if(!s_con) { + s_con = NM_SETTING_CONNECTION (nm_setting_connection_new()); + g_assert (s_con); nm_connection_add_setting (connection, NM_SETTING (s_con)); } type = _ifupdownplugin_guess_connection_type (block); idstr = g_strconcat ("Ifupdown (", block->name, ")", NULL); + uuid_base = idstr; - uuid = nm_utils_uuid_generate_from_string (idstr, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); + uuid = nm_utils_uuid_generate_from_string (uuid_base, -1, NM_UTILS_UUID_TYPE_LEGACY, NULL); g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, type, NM_SETTING_CONNECTION_INTERFACE_NAME, block->name, @@ -692,18 +696,19 @@ ifupdown_update_connection_from_if_block (NMConnection *connection, NM_SETTING_CONNECTION_READ_ONLY, TRUE, NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, NULL); + g_free (uuid); - _LOGI ("update_connection_setting_from_if_block: name:%s, type:%s, id:%s, uuid: %s", - block->name, type, idstr, nm_setting_connection_get_uuid (s_con)); + nm_log_info (LOGD_SETTINGS, "update_connection_setting_from_if_block: name:%s, type:%s, id:%s, uuid: %s", + block->name, type, idstr, nm_setting_connection_get_uuid (s_con)); - if (nm_streq (type, NM_SETTING_WIRED_SETTING_NAME)) + if (!strcmp (NM_SETTING_WIRED_SETTING_NAME, type)) update_wired_setting_from_if_block (connection, block); - else if (nm_streq (type, NM_SETTING_WIRELESS_SETTING_NAME)) { + else if (!strcmp (NM_SETTING_WIRELESS_SETTING_NAME, type)) { update_wireless_setting_from_if_block (connection, block); update_wireless_security_setting_from_if_block (connection, block); } - if (ifparser_haskey (block, "inet6")) + if (ifparser_haskey(block, "inet6")) success = update_ip6_setting_from_if_block (connection, block, error); else success = update_ip4_setting_from_if_block (connection, block, error); @@ -711,5 +716,6 @@ ifupdown_update_connection_from_if_block (NMConnection *connection, if (success == TRUE) success = nm_connection_verify (connection, error); + g_free (idstr); return success; } diff --git a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c index 88c651b8..8bd72d02 100644 --- a/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c +++ b/src/settings/plugins/ifupdown/nms-ifupdown-plugin.c @@ -29,6 +29,7 @@ #include <string.h> #include <arpa/inet.h> #include <gmodule.h> +#include <libudev.h> #include "nm-setting-connection.h" #include "nm-dbus-interface.h" @@ -41,6 +42,7 @@ #include "nm-core-internal.h" #include "NetworkManagerUtils.h" #include "nm-config.h" +#include "nm-utils/nm-udev-utils.h" #include "nms-ifupdown-interface-parser.h" #include "nms-ifupdown-connection.h" @@ -50,27 +52,43 @@ #define IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT TRUE +/* #define ALWAYS_UNMANAGE TRUE */ +#ifndef ALWAYS_UNMANAGE +#define ALWAYS_UNMANAGE FALSE +#endif + /*****************************************************************************/ typedef struct { - /* Stores an entry for blocks/interfaces read from /e/n/i and (if exists) - * the NMIfupdownConnection associated with the block. + NMUdevClient *udev_client; + + GHashTable *connections; /* /e/n/i block name :: NMIfupdownConnection */ + + /* Stores all blocks/interfaces read from /e/n/i regardless of whether + * there is an NMIfupdownConnection for block. */ GHashTable *eni_ifaces; - bool ifupdown_managed; + /* Stores any network interfaces the kernel knows about */ + GHashTable *kernel_ifaces; + + gboolean unmanage_well_known; } SettingsPluginIfupdownPrivate; struct _SettingsPluginIfupdown { - NMSettingsPlugin parent; + GObject parent; SettingsPluginIfupdownPrivate _priv; }; struct _SettingsPluginIfupdownClass { - NMSettingsPluginClass parent; + GObjectClass parent; }; -G_DEFINE_TYPE (SettingsPluginIfupdown, settings_plugin_ifupdown, NM_TYPE_SETTINGS_PLUGIN) +static void settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface); + +G_DEFINE_TYPE_EXTENDED (SettingsPluginIfupdown, settings_plugin_ifupdown, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_PLUGIN, + settings_plugin_interface_init)) #define SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, SettingsPluginIfupdown, SETTINGS_IS_PLUGIN_IFUPDOWN) @@ -81,41 +99,169 @@ NM_DEFINE_SINGLETON_GETTER (SettingsPluginIfupdown, settings_plugin_ifupdown_get /*****************************************************************************/ -#define _NMLOG_PREFIX_NAME "ifupdown" -#define _NMLOG_DOMAIN LOGD_SETTINGS -#define _NMLOG(level, ...) \ - nm_log ((level), _NMLOG_DOMAIN, NULL, NULL, \ - "%s" _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - _NMLOG_PREFIX_NAME": " \ - _NM_UTILS_MACRO_REST (__VA_ARGS__)) +static void +bind_device_to_connection (SettingsPluginIfupdown *self, + struct udev_device *device, + NMIfupdownConnection *exported) +{ + NMSettingWired *s_wired; + NMSettingWireless *s_wifi; + const char *iface, *address; + + iface = udev_device_get_sysname (device); + if (!iface) { + nm_log_warn (LOGD_SETTINGS, "failed to get ifname for device."); + return; + } + + address = udev_device_get_sysattr_value (device, "address"); + if (!address || !address[0]) { + nm_log_warn (LOGD_SETTINGS, "failed to get MAC address for %s", iface); + return; + } -/*****************************************************************************/ + if (!nm_utils_hwaddr_valid (address, ETH_ALEN)) { + nm_log_warn (LOGD_SETTINGS, "failed to parse MAC address '%s' for %s", + address, iface); + return; + } + + s_wired = nm_connection_get_setting_wired (NM_CONNECTION (exported)); + s_wifi = nm_connection_get_setting_wireless (NM_CONNECTION (exported)); + if (s_wired) { + nm_log_info (LOGD_SETTINGS, "locking wired connection setting"); + g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, address, NULL); + } else if (s_wifi) { + nm_log_info (LOGD_SETTINGS, "locking wireless connection setting"); + g_object_set (s_wifi, NM_SETTING_WIRELESS_MAC_ADDRESS, address, NULL); + } + + nm_settings_connection_update (NM_SETTINGS_CONNECTION (exported), + NULL, + NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK, + NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, + "ifupdown-new", + NULL); +} + +static void +udev_device_added (SettingsPluginIfupdown *self, struct udev_device *device) +{ + SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self); + const char *iface, *path; + NMIfupdownConnection *exported; + + iface = udev_device_get_sysname (device); + path = udev_device_get_syspath (device); + if (!iface || !path) + return; + + nm_log_info (LOGD_SETTINGS, "devices added (path: %s, iface: %s)", path, iface); + + /* if we have a configured connection for this particular iface + * we want to either unmanage the device or lock it + */ + exported = g_hash_table_lookup (priv->connections, iface); + if (!exported && !g_hash_table_lookup (priv->eni_ifaces, iface)) { + nm_log_info (LOGD_SETTINGS, "device added (path: %s, iface: %s): no ifupdown configuration found.", + path, iface); + return; + } + + g_hash_table_insert (priv->kernel_ifaces, g_strdup (iface), udev_device_ref (device)); + + if (exported) + bind_device_to_connection (self, device, exported); + + if (ALWAYS_UNMANAGE || priv->unmanage_well_known) + g_signal_emit_by_name (G_OBJECT (self), NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED); +} + +static void +udev_device_removed (SettingsPluginIfupdown *self, struct udev_device *device) +{ + SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self); + const char *iface, *path; + + iface = udev_device_get_sysname (device); + path = udev_device_get_syspath (device); + if (!iface || !path) + return; + + nm_log_info (LOGD_SETTINGS, "devices removed (path: %s, iface: %s)", path, iface); + + if (!g_hash_table_remove (priv->kernel_ifaces, iface)) + return; + + if (ALWAYS_UNMANAGE || priv->unmanage_well_known) + g_signal_emit_by_name (G_OBJECT (self), NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED); +} + +static void +udev_device_changed (SettingsPluginIfupdown *self, struct udev_device *device) +{ + SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self); + const char *iface, *path; + + iface = udev_device_get_sysname (device); + path = udev_device_get_syspath (device); + if (!iface || !path) + return; + + nm_log_info (LOGD_SETTINGS, "device changed (path: %s, iface: %s)", path, iface); + + if (!g_hash_table_lookup (priv->kernel_ifaces, iface)) + return; + + if (ALWAYS_UNMANAGE || priv->unmanage_well_known) + g_signal_emit_by_name (G_OBJECT (self), NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED); +} + +static void +handle_uevent (NMUdevClient *client, + struct udev_device *device, + gpointer user_data) +{ + SettingsPluginIfupdown *self = SETTINGS_PLUGIN_IFUPDOWN (user_data); + const char *subsys; + const char *action; + + action = udev_device_get_action (device); + + g_return_if_fail (action != NULL); + + /* A bit paranoid */ + subsys = udev_device_get_subsystem (device); + g_return_if_fail (nm_streq0 (subsys, "net")); + + if (!strcmp (action, "add")) + udev_device_added (self, device); + else if (!strcmp (action, "remove")) + udev_device_removed (self, device); + else if (!strcmp (action, "change")) + udev_device_changed (self, device); +} /* Returns the plugins currently known list of connections. The returned * list is freed by the system settings service. */ static GSList* -get_connections (NMSettingsPlugin *plugin) +get_connections (NMSettingsPlugin *config) { - SettingsPluginIfupdown *self = SETTINGS_PLUGIN_IFUPDOWN (plugin); - SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self); - GSList *list = NULL; - GHashTableIter iter; - void *value; + SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE ((SettingsPluginIfupdown *) config); + GSList *connections; + + nm_log_info (LOGD_SETTINGS, "(%d) ... get_connections.", GPOINTER_TO_UINT(config)); - if (!priv->ifupdown_managed) { - _LOGD ("get_connections: not connections due to managed=false"); + if(priv->unmanage_well_known) { + nm_log_info (LOGD_SETTINGS, "(%d) ... get_connections (managed=false): return empty list.", GPOINTER_TO_UINT(config)); return NULL; } - g_hash_table_iter_init (&iter, priv->eni_ifaces); - while (g_hash_table_iter_next (&iter, NULL, &value)) { - if (value) - list = g_slist_prepend (list, value); - } + connections = _nm_utils_hash_values_to_slist (priv->connections); - _LOGD ("get_connections: %u connections", g_slist_length (list)); - return list; + nm_log_info (LOGD_SETTINGS, "(%d) connections count: %d", GPOINTER_TO_UINT(config), g_slist_length(connections)); + return connections; } /* @@ -124,178 +270,202 @@ get_connections (NMSettingsPlugin *plugin) * each element must be allocated using g_malloc() or its variants. */ static GSList* -get_unmanaged_specs (NMSettingsPlugin *plugin) +get_unmanaged_specs (NMSettingsPlugin *config) { - SettingsPluginIfupdown *self = SETTINGS_PLUGIN_IFUPDOWN (plugin); - SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self); + SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE ((SettingsPluginIfupdown *) config); GSList *specs = NULL; GHashTableIter iter; + struct udev_device *device; const char *iface; - if (priv->ifupdown_managed) + if (!ALWAYS_UNMANAGE && !priv->unmanage_well_known) return NULL; - _LOGD ("unmanaged-specs: unmanaged devices count %u", - g_hash_table_size (priv->eni_ifaces)); + nm_log_info (LOGD_SETTINGS, "get unmanaged devices count: %d", + g_hash_table_size (priv->kernel_ifaces)); + + g_hash_table_iter_init (&iter, priv->kernel_ifaces); + while (g_hash_table_iter_next (&iter, (gpointer) &iface, (gpointer) &device)) { + const char *address; - g_hash_table_iter_init (&iter, priv->eni_ifaces); - while (g_hash_table_iter_next (&iter, (gpointer) &iface, NULL)) - specs = g_slist_append (specs, g_strdup_printf ("interface-name:=%s", iface)); + address = udev_device_get_sysattr_value (device, "address"); + if (address) + specs = g_slist_append (specs, g_strdup_printf ("mac:%s", address)); + else + specs = g_slist_append (specs, g_strdup_printf ("interface-name:%s", iface)); + } return specs; } /*****************************************************************************/ static void -initialize (NMSettingsPlugin *plugin) +_udev_device_unref (gpointer ptr) { - SettingsPluginIfupdown *self = SETTINGS_PLUGIN_IFUPDOWN (plugin); + udev_device_unref (ptr); +} + +static void +init (NMSettingsPlugin *config) +{ + SettingsPluginIfupdown *self = SETTINGS_PLUGIN_IFUPDOWN (config); SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self); - gs_unref_hashtable GHashTable *auto_ifaces = NULL; - nm_auto_ifparser if_parser *parser = NULL; - if_block *block; + GHashTable *auto_ifaces; + if_block *block = NULL; + struct udev_enumerate *enumerate; + struct udev_list_entry *keys; GHashTableIter con_iter; const char *block_name; - NMIfupdownConnection *conn; + NMIfupdownConnection *connection; - parser = ifparser_parse (ENI_INTERFACES_FILE, 0); + auto_ifaces = g_hash_table_new (nm_str_hash, g_str_equal); - c_list_for_each_entry (block, &parser->block_lst_head, block_lst) { + if(!priv->connections) + priv->connections = g_hash_table_new (nm_str_hash, g_str_equal); - if (NM_IN_STRSET (block->type, "auto", "allow-hotplug")) { - if (!auto_ifaces) - auto_ifaces = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, NULL); - g_hash_table_add (auto_ifaces, g_strdup (block->name)); - continue; - } + if(!priv->kernel_ifaces) + priv->kernel_ifaces = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, _udev_device_unref); + + if(!priv->eni_ifaces) + priv->eni_ifaces = g_hash_table_new (nm_str_hash, g_str_equal); + + nm_log_info (LOGD_SETTINGS, "init!"); + + priv->udev_client = nm_udev_client_new ((const char *[]) { "net", NULL }, + handle_uevent, self); + + /* Read in all the interfaces */ + ifparser_init (ENI_INTERFACES_FILE, 0); + block = ifparser_getfirst (); + while (block) { + if(!strcmp ("auto", block->type) || !strcmp ("allow-hotplug", block->type)) + g_hash_table_insert (auto_ifaces, block->name, GUINT_TO_POINTER (1)); + else if (!strcmp ("iface", block->type)) { + NMIfupdownConnection *exported; - if (nm_streq (block->type, "iface")) { /* Bridge configuration */ - if (g_str_has_prefix (block_name, "br")) { + if(!strncmp ("br", block->name, 2)) { /* Try to find bridge ports */ const char *ports = ifparser_getkey (block, "bridge-ports"); - if (ports) { - guint i; + int i; int state = 0; - gs_strfreev char **port_ifaces = NULL; + char **port_ifaces; - _LOGD ("parse: found bridge ports %s for %s", ports, block->name); + nm_log_info (LOGD_SETTINGS, "found bridge ports %s for %s", ports, block->name); port_ifaces = g_strsplit_set (ports, " \t", -1); - for (i = 0; port_ifaces[i]; i++) { - const char *token = port_ifaces[i]; - + for (i = 0; i < g_strv_length (port_ifaces); i++) { + char *token = port_ifaces[i]; /* Skip crazy stuff like regex or all */ - if (nm_streq (token, "all")) + if (!strcmp ("all", token)) { continue; - + } /* Small SM to skip everything inside regex */ - if (nm_streq (token, "regex")) { + if (!strcmp ("regex", token)) { state++; continue; } - if (nm_streq (token, "noregex")) { + if (!strcmp ("noregex", token)) { state--; continue; } - if (nm_streq (token, "none")) - continue; if (state == 0 && strlen (token) > 0) { - conn = g_hash_table_lookup (priv->eni_ifaces, block->name); - if (!conn) { - _LOGD ("parse: adding bridge port \"%s\"", token); - g_hash_table_insert (priv->eni_ifaces, g_strdup (token), NULL); - } else { - _LOGD ("parse: adding bridge port \"%s\" (have connection %s)", token, - nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (conn))); - } + nm_log_info (LOGD_SETTINGS, "adding bridge port %s to eni_ifaces", token); + g_hash_table_insert (priv->eni_ifaces, g_strdup (token), "known"); } } + g_strfreev (port_ifaces); } - continue; + goto next; } /* Skip loopback configuration */ - if (nm_streq (block->name, "lo")) - continue; + if(!strcmp ("lo", block->name)) { + goto next; + } /* Remove any connection for this block that was previously found */ - conn = g_hash_table_lookup (priv->eni_ifaces, block->name); - if (conn) { - _LOGD ("parse: replace connection \"%s\" (%s)", - block->name, - nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (conn))); - nm_settings_connection_delete (NM_SETTINGS_CONNECTION (conn), NULL); - g_hash_table_remove (priv->eni_ifaces, block->name); + exported = g_hash_table_lookup (priv->connections, block->name); + if (exported) { + nm_log_info (LOGD_SETTINGS, "deleting %s from connections", block->name); + nm_settings_connection_delete (NM_SETTINGS_CONNECTION (exported), NULL); + g_hash_table_remove (priv->connections, block->name); } /* add the new connection */ - conn = nm_ifupdown_connection_new (block); - if (conn) { - _LOGD ("parse: adding connection \"%s\" (%s)", block->name, - nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (conn))); - } else - _LOGD ("parse: adding place holder for connection \"%s\"", block->name); - g_hash_table_insert (priv->eni_ifaces, g_strdup (block->name), conn); - continue; - } - - if (nm_streq (block->type, "mapping")) { - conn = g_hash_table_lookup (priv->eni_ifaces, block->name); - if (!conn) { - _LOGD ("parse: adding mapping \"%s\"", block->name); - g_hash_table_insert (priv->eni_ifaces, g_strdup (block->name), NULL); - } else { - _LOGD ("parse: adding mapping \"%s\" (have connection %s)", block->name, - nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (conn))); + exported = nm_ifupdown_connection_new (block); + if (exported) { + nm_log_info (LOGD_SETTINGS, "adding %s to connections", block->name); + g_hash_table_insert (priv->connections, block->name, exported); } - continue; + nm_log_info (LOGD_SETTINGS, "adding iface %s to eni_ifaces", block->name); + g_hash_table_insert (priv->eni_ifaces, block->name, "known"); + } else if (!strcmp ("mapping", block->type)) { + g_hash_table_insert (priv->eni_ifaces, block->name, "known"); + nm_log_info (LOGD_SETTINGS, "adding mapping %s to eni_ifaces", block->name); } + next: + block = block->next; } /* Make 'auto' interfaces autoconnect=TRUE */ - g_hash_table_iter_init (&con_iter, priv->eni_ifaces); - while (g_hash_table_iter_next (&con_iter, (gpointer) &block_name, (gpointer) &conn)) { + g_hash_table_iter_init (&con_iter, priv->connections); + while (g_hash_table_iter_next (&con_iter, (gpointer) &block_name, (gpointer) &connection)) { NMSettingConnection *setting; - if ( !conn - || !auto_ifaces - || !g_hash_table_contains (auto_ifaces, block_name)) - continue; - - /* FIXME(copy-on-write-connection): avoid modifying NMConnection instances and share them via copy-on-write. */ - setting = nm_connection_get_setting_connection (nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (conn))); - g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL); + if (g_hash_table_lookup (auto_ifaces, block_name)) { + setting = nm_connection_get_setting_connection (NM_CONNECTION (connection)); + g_object_set (setting, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NULL); + nm_log_info (LOGD_SETTINGS, "autoconnect"); + } } + g_hash_table_destroy (auto_ifaces); /* Check the config file to find out whether to manage interfaces */ - priv->ifupdown_managed = nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG, - NM_CONFIG_KEYFILE_GROUP_IFUPDOWN, - NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED, - !IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT); - _LOGI ("management mode: %s", priv->ifupdown_managed ? "managed" : "unmanaged"); + priv->unmanage_well_known = !nm_config_data_get_value_boolean (NM_CONFIG_GET_DATA_ORIG, + NM_CONFIG_KEYFILE_GROUP_IFUPDOWN, + NM_CONFIG_KEYFILE_KEY_IFUPDOWN_MANAGED, + !IFUPDOWN_UNMANAGE_WELL_KNOWN_DEFAULT); + nm_log_info (LOGD_SETTINGS, "management mode: %s", priv->unmanage_well_known ? "unmanaged" : "managed"); + + /* Add well-known interfaces */ + enumerate = nm_udev_client_enumerate_new (priv->udev_client); + udev_enumerate_scan_devices (enumerate); + keys = udev_enumerate_get_list_entry (enumerate); + for (; keys; keys = udev_list_entry_get_next (keys)) { + struct udev_device *udevice; + + udevice = udev_device_new_from_syspath (udev_enumerate_get_udev (enumerate), + udev_list_entry_get_name (keys)); + if (udevice) { + udev_device_added (self, udevice); + udev_device_unref (udevice); + } + } + udev_enumerate_unref (enumerate); /* Now if we're running in managed mode, let NM know there are new connections */ - if (priv->ifupdown_managed) { - GHashTableIter iter; - - g_hash_table_iter_init (&iter, priv->eni_ifaces); - while (g_hash_table_iter_next (&iter, NULL, (gpointer *) conn)) { - _nm_settings_plugin_emit_signal_connection_added (NM_SETTINGS_PLUGIN (self), - NM_SETTINGS_CONNECTION (conn)); + if (!priv->unmanage_well_known) { + GList *con_list = g_hash_table_get_values (priv->connections); + GList *cl_iter; + + for (cl_iter = con_list; cl_iter; cl_iter = g_list_next (cl_iter)) { + g_signal_emit_by_name (self, + NM_SETTINGS_PLUGIN_CONNECTION_ADDED, + NM_SETTINGS_CONNECTION (cl_iter->data)); } + g_list_free (con_list); } + + nm_log_info (LOGD_SETTINGS, "end _init."); } /*****************************************************************************/ static void -settings_plugin_ifupdown_init (SettingsPluginIfupdown *self) +settings_plugin_ifupdown_init (SettingsPluginIfupdown *plugin) { - SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (self); - - priv->eni_ifaces = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_object_unref); } static void @@ -304,28 +474,35 @@ dispose (GObject *object) SettingsPluginIfupdown *plugin = SETTINGS_PLUGIN_IFUPDOWN (object); SettingsPluginIfupdownPrivate *priv = SETTINGS_PLUGIN_IFUPDOWN_GET_PRIVATE (plugin); + g_clear_pointer (&priv->kernel_ifaces, g_hash_table_destroy); g_clear_pointer (&priv->eni_ifaces, g_hash_table_destroy); + priv->udev_client = nm_udev_client_unref (priv->udev_client); + G_OBJECT_CLASS (settings_plugin_ifupdown_parent_class)->dispose (object); } static void -settings_plugin_ifupdown_class_init (SettingsPluginIfupdownClass *klass) +settings_plugin_ifupdown_class_init (SettingsPluginIfupdownClass *req_class) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMSettingsPluginClass *plugin_class = NM_SETTINGS_PLUGIN_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (req_class); object_class->dispose = dispose; +} - plugin_class->initialize = initialize; - plugin_class->get_connections = get_connections; - plugin_class->get_unmanaged_specs = get_unmanaged_specs; +static void +settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface) +{ + plugin_iface->init = init; + plugin_iface->get_connections = get_connections; + plugin_iface->get_unmanaged_specs = get_unmanaged_specs; } /*****************************************************************************/ -G_MODULE_EXPORT NMSettingsPlugin * +G_MODULE_EXPORT GObject * nm_settings_plugin_factory (void) { - return NM_SETTINGS_PLUGIN (g_object_ref (settings_plugin_ifupdown_get ())); + return G_OBJECT (g_object_ref (settings_plugin_ifupdown_get ())); } + diff --git a/src/settings/plugins/ifupdown/tests/meson.build b/src/settings/plugins/ifupdown/tests/meson.build index 5a2383d9..ee3b6a34 100644 --- a/src/settings/plugins/ifupdown/tests/meson.build +++ b/src/settings/plugins/ifupdown/tests/meson.build @@ -4,6 +4,7 @@ exe = executable( test_unit, test_unit + '.c', dependencies: test_nm_dep, + c_args: nm_build_cflags, link_with: libnms_ifupdown_core ) diff --git a/src/settings/plugins/ifupdown/tests/test-ifupdown.c b/src/settings/plugins/ifupdown/tests/test-ifupdown.c index e96350c0..18bad65e 100644 --- a/src/settings/plugins/ifupdown/tests/test-ifupdown.c +++ b/src/settings/plugins/ifupdown/tests/test-ifupdown.c @@ -130,15 +130,16 @@ expected_free (Expected *e) } static void -compare_expected_to_ifparser (if_parser *parser, Expected *e) +compare_expected_to_ifparser (Expected *e) { if_block *n; GSList *biter, *kiter; - g_assert_cmpint (g_slist_length (e->blocks), ==, ifparser_get_num_blocks (parser)); + g_assert_cmpint (g_slist_length (e->blocks), ==, ifparser_get_num_blocks ()); - biter = e->blocks; - c_list_for_each_entry (n, &parser->block_lst_head, block_lst) { + for (n = ifparser_getfirst (), biter = e->blocks; + n && biter; + n = n->next, biter = g_slist_next (biter)) { if_data *m; ExpectedBlock *b = biter->data; @@ -149,31 +150,26 @@ compare_expected_to_ifparser (if_parser *parser, Expected *e) g_assert_cmpint (g_slist_length (b->keys), ==, ifparser_get_num_info (n)); - kiter = b->keys; - c_list_for_each_entry (m, &n->data_lst_head, data_lst) { + for (m = n->info, kiter = b->keys; + m && kiter; + m = m->next, kiter = g_slist_next (kiter)) { ExpectedKey *k = kiter->data; g_assert (k->key && m->key); g_assert_cmpstr (k->key, ==, m->key); g_assert (k->data && m->data); g_assert_cmpstr (k->data, ==, m->data); - - kiter = g_slist_next (kiter); } - g_assert (!kiter); - - biter = g_slist_next (biter); } - g_assert (!biter); } static void -dump_blocks (if_parser *parser) +dump_blocks (void) { if_block *n; g_message ("\n***************************************************"); - c_list_for_each_entry (n, &parser->block_lst_head, block_lst) { + for (n = ifparser_getfirst (); n != NULL; n = n->next) { if_data *m; // each block start with its type & name @@ -182,8 +178,8 @@ dump_blocks (if_parser *parser) // each key-value pair within a block is indented & separated by a tab // (single quotes used to show typ & name baoundaries) - c_list_for_each_entry (m, &n->data_lst_head, data_lst) - g_print("\t'%s'\t'%s'\n", m->key, m->data); + for (m = n->info; m != NULL; m = m->next) + g_print("\t'%s'\t'%s'\n", m->key, m->data); // blocks are separated by an empty line g_print("\n"); @@ -191,24 +187,21 @@ dump_blocks (if_parser *parser) g_message ("##################################################\n"); } -static if_parser * -init_ifparser_with_file (const char *file) +static void +init_ifparser_with_file (const char *path, const char *file) { - if_parser *parser; - gs_free char *tmp = NULL; + char *tmp; - tmp = g_strdup_printf ("%s/%s", TEST_DIR, file); - parser = ifparser_parse (tmp, 1); - g_assert (parser); - return parser; + tmp = g_strdup_printf ("%s/%s", path, file); + ifparser_init (tmp, 1); + g_free (tmp); } static void -test1_ignore_line_before_first_block (void) +test1_ignore_line_before_first_block (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test1"); e = expected_new (); b = expected_block_new ("auto", "eth0"); @@ -217,33 +210,35 @@ test1_ignore_line_before_first_block (void) expected_add_block (e, b); expected_block_add_key (b, expected_key_new ("inet", "dhcp")); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test1"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test2_wrapped_line (void) +test2_wrapped_line (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test2"); e = expected_new (); b = expected_block_new ("auto", "lo"); expected_add_block (e, b); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test2"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test3_wrapped_multiline_multiarg (void) +test3_wrapped_multiline_multiarg (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test3"); e = expected_new (); b = expected_block_new ("allow-hotplug", "eth0"); @@ -253,33 +248,35 @@ test3_wrapped_multiline_multiarg (void) b = expected_block_new ("allow-hotplug", "bnep0"); expected_add_block (e, b); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test3"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test4_allow_auto_is_auto (void) +test4_allow_auto_is_auto (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test4"); e = expected_new (); b = expected_block_new ("auto", "eth0"); expected_add_block (e, b); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test4"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test5_allow_auto_multiarg (void) +test5_allow_auto_multiarg (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test5"); e = expected_new (); b = expected_block_new ("allow-hotplug", "eth0"); @@ -287,50 +284,52 @@ test5_allow_auto_multiarg (void) b = expected_block_new ("allow-hotplug", "wlan0"); expected_add_block (e, b); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test5"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test6_mixed_whitespace (void) +test6_mixed_whitespace (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test6"); e = expected_new (); b = expected_block_new ("iface", "lo"); expected_block_add_key (b, expected_key_new ("inet", "loopback")); expected_add_block (e, b); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test6"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test7_long_line (void) +test7_long_line (const char *path) { - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test7"); - - g_assert_cmpint (ifparser_get_num_blocks (parser), ==, 0); + init_ifparser_with_file (path, "test7"); + g_assert_cmpint (ifparser_get_num_blocks (), ==, 0); + ifparser_destroy (); } static void -test8_long_line_wrapped (void) +test8_long_line_wrapped (const char *path) { - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test8"); - - g_assert_cmpint (ifparser_get_num_blocks (parser), ==, 0); + init_ifparser_with_file (path, "test8"); + g_assert_cmpint (ifparser_get_num_blocks (), ==, 0); + ifparser_destroy (); } static void -test9_wrapped_lines_in_block (void) +test9_wrapped_lines_in_block (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test9"); e = expected_new (); b = expected_block_new ("iface", "eth0"); @@ -341,17 +340,18 @@ test9_wrapped_lines_in_block (void) expected_block_add_key (b, expected_key_new ("broadcast", "10.250.2.63")); expected_block_add_key (b, expected_key_new ("gateway", "10.250.2.50")); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test9"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test11_complex_wrap (void) +test11_complex_wrap (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test11"); e = expected_new (); b = expected_block_new ("iface", "pppoe"); @@ -359,17 +359,18 @@ test11_complex_wrap (void) expected_block_add_key (b, expected_key_new ("inet", "manual")); expected_block_add_key (b, expected_key_new ("pre-up", "/sbin/ifconfig eth0 up")); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test11"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test12_complex_wrap_split_word (void) +test12_complex_wrap_split_word (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test12"); e = expected_new (); b = expected_block_new ("iface", "pppoe"); @@ -377,34 +378,36 @@ test12_complex_wrap_split_word (void) expected_block_add_key (b, expected_key_new ("inet", "manual")); expected_block_add_key (b, expected_key_new ("up", "ifup ppp0=dsl")); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test12"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test13_more_mixed_whitespace (void) +test13_more_mixed_whitespace (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test13"); e = expected_new (); b = expected_block_new ("iface", "dsl"); expected_block_add_key (b, expected_key_new ("inet", "ppp")); expected_add_block (e, b); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test13"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test14_mixed_whitespace_block_start (void) +test14_mixed_whitespace_block_start (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test14"); e = expected_new (); b = expected_block_new ("iface", "wlan0"); @@ -417,43 +420,47 @@ test14_mixed_whitespace_block_start (void) expected_block_add_key (b, expected_key_new ("inet", "dhcp")); expected_add_block (e, b); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test14"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test15_trailing_space (void) +test15_trailing_space (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test15"); e = expected_new (); b = expected_block_new ("iface", "bnep0"); expected_block_add_key (b, expected_key_new ("inet", "static")); expected_add_block (e, b); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test15"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test16_missing_newline (void) +test16_missing_newline (const char *path) { Expected *e; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test16"); e = expected_new (); expected_add_block (e, expected_block_new ("mapping", "eth0")); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test16"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test17_read_static_ipv4 (void) +test17_read_static_ipv4 (const char *path) { NMConnection *connection; NMSettingConnection *s_con; @@ -463,13 +470,13 @@ test17_read_static_ipv4 (void) gboolean success; NMIPAddress *ip4_addr; if_block *block = NULL; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test17-wired-static-verify-ip4"); - block = ifparser_getfirst (parser); + init_ifparser_with_file (path, "test17-wired-static-verify-ip4"); + block = ifparser_getfirst (); connection = nm_simple_connection_new(); g_assert (connection); - ifupdown_update_connection_from_if_block (connection, block, &error); + ifupdown_update_connection_from_if_block(connection, block, &error); g_assert_no_error (error); success = nm_connection_verify (connection, &error); @@ -504,11 +511,12 @@ test17_read_static_ipv4 (void) g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 0), ==, "example.com"); g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip4, 1), ==, "foo.example.com"); + ifparser_destroy (); g_object_unref (connection); } static void -test18_read_static_ipv6 (void) +test18_read_static_ipv6 (const char *path) { NMConnection *connection; NMSettingConnection *s_con; @@ -518,12 +526,12 @@ test18_read_static_ipv6 (void) gboolean success; NMIPAddress *ip6_addr; if_block *block = NULL; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test18-wired-static-verify-ip6"); - block = ifparser_getfirst (parser); + init_ifparser_with_file (path, "test18-wired-static-verify-ip6"); + block = ifparser_getfirst (); connection = nm_simple_connection_new(); g_assert (connection); - ifupdown_update_connection_from_if_block (connection, block, &error); + ifupdown_update_connection_from_if_block(connection, block, &error); g_assert_no_error (error); success = nm_connection_verify (connection, &error); @@ -558,11 +566,12 @@ test18_read_static_ipv6 (void) g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 0), ==, "example.com"); g_assert_cmpstr (nm_setting_ip_config_get_dns_search (s_ip6, 1), ==, "foo.example.com"); + ifparser_destroy (); g_object_unref (connection); } static void -test19_read_static_ipv4_plen (void) +test19_read_static_ipv4_plen (const char *path) { NMConnection *connection; NMSettingIPConfig *s_ip4; @@ -570,12 +579,12 @@ test19_read_static_ipv4_plen (void) NMIPAddress *ip4_addr; if_block *block = NULL; gboolean success; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test19-wired-static-verify-ip4-plen"); - block = ifparser_getfirst (parser); + init_ifparser_with_file (path, "test19-wired-static-verify-ip4-plen"); + block = ifparser_getfirst (); connection = nm_simple_connection_new(); g_assert (connection); - ifupdown_update_connection_from_if_block (connection, block, &error); + ifupdown_update_connection_from_if_block(connection, block, &error); g_assert_no_error (error); success = nm_connection_verify (connection, &error); @@ -592,15 +601,15 @@ test19_read_static_ipv4_plen (void) g_assert_cmpstr (nm_ip_address_get_address (ip4_addr), ==, "10.0.0.3"); g_assert_cmpint (nm_ip_address_get_prefix (ip4_addr), ==, 8); + ifparser_destroy (); g_object_unref (connection); } static void -test20_source_stanza (void) +test20_source_stanza (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test20-source-stanza"); e = expected_new (); @@ -616,17 +625,18 @@ test20_source_stanza (void) expected_add_block (e, b); expected_block_add_key (b, expected_key_new ("inet", "dhcp")); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test20-source-stanza"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } static void -test21_source_dir_stanza (void) +test21_source_dir_stanza (const char *path) { Expected *e; ExpectedBlock *b; - nm_auto_ifparser if_parser *parser = init_ifparser_with_file ("test21-source-dir-stanza"); e = expected_new (); @@ -636,8 +646,10 @@ test21_source_dir_stanza (void) expected_add_block (e, b); expected_block_add_key (b, expected_key_new ("inet", "dhcp")); - compare_expected_to_ifparser (parser, e); + init_ifparser_with_file (path, "test21-source-dir-stanza"); + compare_expected_to_ifparser (e); + ifparser_destroy (); expected_free (e); } @@ -648,28 +660,49 @@ main (int argc, char **argv) { nmtst_init_assert_logging (&argc, &argv, "WARN", "DEFAULT"); - (void) dump_blocks; - - g_test_add_func ("/ifupdate/ignore_line_before_first_block", test1_ignore_line_before_first_block); - g_test_add_func ("/ifupdate/wrapped_line", test2_wrapped_line); - g_test_add_func ("/ifupdate/wrapped_multiline_multiarg", test3_wrapped_multiline_multiarg); - g_test_add_func ("/ifupdate/allow_auto_is_auto", test4_allow_auto_is_auto); - g_test_add_func ("/ifupdate/allow_auto_multiarg", test5_allow_auto_multiarg); - g_test_add_func ("/ifupdate/mixed_whitespace", test6_mixed_whitespace); - g_test_add_func ("/ifupdate/long_line", test7_long_line); - g_test_add_func ("/ifupdate/long_line_wrapped", test8_long_line_wrapped); - g_test_add_func ("/ifupdate/wrapped_lines_in_block", test9_wrapped_lines_in_block); - g_test_add_func ("/ifupdate/complex_wrap", test11_complex_wrap); - g_test_add_func ("/ifupdate/complex_wrap_split_word", test12_complex_wrap_split_word); - g_test_add_func ("/ifupdate/more_mixed_whitespace", test13_more_mixed_whitespace); - g_test_add_func ("/ifupdate/mixed_whitespace_block_start", test14_mixed_whitespace_block_start); - g_test_add_func ("/ifupdate/trailing_space", test15_trailing_space); - g_test_add_func ("/ifupdate/missing_newline", test16_missing_newline); - g_test_add_func ("/ifupdate/read_static_ipv4", test17_read_static_ipv4); - g_test_add_func ("/ifupdate/read_static_ipv6", test18_read_static_ipv6); - g_test_add_func ("/ifupdate/read_static_ipv4_plen", test19_read_static_ipv4_plen); - g_test_add_func ("/ifupdate/source_stanza", test20_source_stanza); - g_test_add_func ("/ifupdate/source_dir_stanza", test21_source_dir_stanza); + if (0) + dump_blocks (); + + g_test_add_data_func ("/ifupdate/ignore_line_before_first_block", TEST_DIR, + (GTestDataFunc) test1_ignore_line_before_first_block); + g_test_add_data_func ("/ifupdate/wrapped_line", TEST_DIR, + (GTestDataFunc) test2_wrapped_line); + g_test_add_data_func ("/ifupdate/wrapped_multiline_multiarg", TEST_DIR, + (GTestDataFunc) test3_wrapped_multiline_multiarg); + g_test_add_data_func ("/ifupdate/allow_auto_is_auto", TEST_DIR, + (GTestDataFunc) test4_allow_auto_is_auto); + g_test_add_data_func ("/ifupdate/allow_auto_multiarg", TEST_DIR, + (GTestDataFunc) test5_allow_auto_multiarg); + g_test_add_data_func ("/ifupdate/mixed_whitespace", TEST_DIR, + (GTestDataFunc) test6_mixed_whitespace); + g_test_add_data_func ("/ifupdate/long_line", TEST_DIR, + (GTestDataFunc) test7_long_line); + g_test_add_data_func ("/ifupdate/long_line_wrapped", TEST_DIR, + (GTestDataFunc) test8_long_line_wrapped); + g_test_add_data_func ("/ifupdate/wrapped_lines_in_block", TEST_DIR, + (GTestDataFunc) test9_wrapped_lines_in_block); + g_test_add_data_func ("/ifupdate/complex_wrap", TEST_DIR, + (GTestDataFunc) test11_complex_wrap); + g_test_add_data_func ("/ifupdate/complex_wrap_split_word", TEST_DIR, + (GTestDataFunc) test12_complex_wrap_split_word); + g_test_add_data_func ("/ifupdate/more_mixed_whitespace", TEST_DIR, + (GTestDataFunc) test13_more_mixed_whitespace); + g_test_add_data_func ("/ifupdate/mixed_whitespace_block_start", TEST_DIR, + (GTestDataFunc) test14_mixed_whitespace_block_start); + g_test_add_data_func ("/ifupdate/trailing_space", TEST_DIR, + (GTestDataFunc) test15_trailing_space); + g_test_add_data_func ("/ifupdate/missing_newline", TEST_DIR, + (GTestDataFunc) test16_missing_newline); + g_test_add_data_func ("/ifupdate/read_static_ipv4", TEST_DIR, + (GTestDataFunc) test17_read_static_ipv4); + g_test_add_data_func ("/ifupdate/read_static_ipv6", TEST_DIR, + (GTestDataFunc) test18_read_static_ipv6); + g_test_add_data_func ("/ifupdate/read_static_ipv4_plen", TEST_DIR, + (GTestDataFunc) test19_read_static_ipv4_plen); + g_test_add_data_func ("/ifupdate/source_stanza", TEST_DIR, + (GTestDataFunc) test20_source_stanza); + g_test_add_data_func ("/ifupdate/source_dir_stanza", TEST_DIR, + (GTestDataFunc) test21_source_dir_stanza); return g_test_run (); } diff --git a/src/settings/plugins/keyfile/nms-keyfile-connection.c b/src/settings/plugins/keyfile/nms-keyfile-connection.c index 64e94b26..5f72a9fa 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-connection.c +++ b/src/settings/plugins/keyfile/nms-keyfile-connection.c @@ -75,7 +75,9 @@ commit_changes (NMSettingsConnection *connection, error)) return FALSE; - if (!nm_streq0 (path, nm_settings_connection_get_filename (connection))) { + /* Update the filename if it changed */ + if ( path + && g_strcmp0 (path, nm_settings_connection_get_filename (connection)) != 0) { gs_free char *old_path = g_strdup (nm_settings_connection_get_filename (connection)); nm_settings_connection_set_filename (connection, path); @@ -140,7 +142,7 @@ nms_keyfile_connection_new (NMConnection *source, if (!tmp) return NULL; - uuid = nm_connection_get_uuid (tmp); + uuid = nm_connection_get_uuid (NM_CONNECTION (tmp)); if (!uuid) { g_set_error (error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION, "Connection in file %s had no UUID", full_path); @@ -152,9 +154,9 @@ nms_keyfile_connection_new (NMConnection *source, update_unsaved = FALSE; } - object = g_object_new (NMS_TYPE_KEYFILE_CONNECTION, - NM_SETTINGS_CONNECTION_FILENAME, full_path, - NULL); + object = (GObject *) g_object_new (NMS_TYPE_KEYFILE_CONNECTION, + NM_SETTINGS_CONNECTION_FILENAME, full_path, + NULL); /* Update our settings with what was read from the file */ if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (object), diff --git a/src/settings/plugins/keyfile/nms-keyfile-plugin.c b/src/settings/plugins/keyfile/nms-keyfile-plugin.c index 89b89467..3723db94 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-plugin.c +++ b/src/settings/plugins/keyfile/nms-keyfile-plugin.c @@ -56,15 +56,19 @@ typedef struct { } NMSKeyfilePluginPrivate; struct _NMSKeyfilePlugin { - NMSettingsPlugin parent; + GObject parent; NMSKeyfilePluginPrivate _priv; }; struct _NMSKeyfilePluginClass { - NMSettingsPluginClass parent; + GObjectClass parent; }; -G_DEFINE_TYPE (NMSKeyfilePlugin, nms_keyfile_plugin, NM_TYPE_SETTINGS_PLUGIN) +static void settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface); + +G_DEFINE_TYPE_EXTENDED (NMSKeyfilePlugin, nms_keyfile_plugin, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_PLUGIN, + settings_plugin_interface_init)) #define NMS_KEYFILE_PLUGIN_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMSKeyfilePlugin, NMS_IS_KEYFILE_PLUGIN) @@ -81,10 +85,10 @@ G_DEFINE_TYPE (NMSKeyfilePlugin, nms_keyfile_plugin, NM_TYPE_SETTINGS_PLUGIN) /*****************************************************************************/ static void -connection_removed_cb (NMSettingsConnection *sett_conn, NMSKeyfilePlugin *self) +connection_removed_cb (NMSettingsConnection *obj, gpointer user_data) { - g_hash_table_remove (NMS_KEYFILE_PLUGIN_GET_PRIVATE (self)->connections, - nm_settings_connection_get_uuid (sett_conn)); + g_hash_table_remove (NMS_KEYFILE_PLUGIN_GET_PRIVATE ((NMSKeyfilePlugin *) user_data)->connections, + nm_connection_get_uuid (NM_CONNECTION (obj))); } /* Monitoring */ @@ -102,7 +106,7 @@ remove_connection (NMSKeyfilePlugin *self, NMSKeyfileConnection *connection) g_object_ref (connection); g_signal_handlers_disconnect_by_func (connection, connection_removed_cb, self); removed = g_hash_table_remove (NMS_KEYFILE_PLUGIN_GET_PRIVATE (self)->connections, - nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (connection))); + nm_connection_get_uuid (NM_CONNECTION (connection))); nm_settings_connection_signal_remove (NM_SETTINGS_CONNECTION (connection)); g_object_unref (connection); @@ -193,7 +197,7 @@ update_connection (NMSKeyfilePlugin *self, return NULL; } - uuid = nm_settings_connection_get_uuid (NM_SETTINGS_CONNECTION (connection_new)); + uuid = nm_connection_get_uuid (NM_CONNECTION (connection_new)); connection_by_uuid = g_hash_table_lookup (priv->connections, uuid); if ( connection @@ -236,8 +240,8 @@ update_connection (NMSKeyfilePlugin *self, old_path = nm_settings_connection_get_filename (NM_SETTINGS_CONNECTION (connection_by_uuid)); - if (nm_connection_compare (nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (connection_by_uuid)), - nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (connection_new)), + if (nm_connection_compare (NM_CONNECTION (connection_by_uuid), + NM_CONNECTION (connection_new), NM_SETTING_COMPARE_FLAG_IGNORE_AGENT_OWNED_SECRETS | NM_SETTING_COMPARE_FLAG_IGNORE_NOT_SAVED_SECRETS)) { /* Nothing to do... except updating the path. */ @@ -255,7 +259,7 @@ update_connection (NMSKeyfilePlugin *self, _LOGI ("update and persist "NMS_KEYFILE_CONNECTION_LOG_FMT, NMS_KEYFILE_CONNECTION_LOG_ARG (connection_new)); if (!nm_settings_connection_update (NM_SETTINGS_CONNECTION (connection_by_uuid), - nm_settings_connection_get_connection (NM_SETTINGS_CONNECTION (connection_new)), + NM_CONNECTION (connection_new), NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP_SAVED, NM_SETTINGS_CONNECTION_COMMIT_REASON_NONE, "keyfile-update", @@ -283,10 +287,8 @@ update_connection (NMSKeyfilePlugin *self, if (!source) { /* Only raise the signal if we were called without source, i.e. if we read the connection from file. * Otherwise, we were called by add_connection() which does not expect the signal. */ - _nm_settings_plugin_emit_signal_connection_added (NM_SETTINGS_PLUGIN (self), - NM_SETTINGS_CONNECTION (connection_new)); + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_CONNECTION_ADDED, connection_new); } - return connection_new; } } @@ -339,14 +341,13 @@ config_changed_cb (NMConfig *config, NMConfigData *old_data, NMSKeyfilePlugin *self) { - gs_free char *old_value = NULL; - gs_free char *new_value = NULL; + gs_free char *old_value = NULL, *new_value = NULL; old_value = nm_config_data_get_value (old_data, NM_CONFIG_KEYFILE_GROUP_KEYFILE, NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES, NM_CONFIG_GET_VALUE_TYPE_SPEC); new_value = nm_config_data_get_value (config_data, NM_CONFIG_KEYFILE_GROUP_KEYFILE, NM_CONFIG_KEYFILE_KEY_KEYFILE_UNMANAGED_DEVICES, NM_CONFIG_GET_VALUE_TYPE_SPEC); - if (!nm_streq0 (old_value, new_value)) - _nm_settings_plugin_emit_signal_unmanaged_specs_changed (NM_SETTINGS_PLUGIN (self)); + if (g_strcmp0 (old_value, new_value) != 0) + g_signal_emit_by_name (self, NM_SETTINGS_PLUGIN_UNMANAGED_SPECS_CHANGED); } static void @@ -615,17 +616,20 @@ dispose (GObject *object) } static void -nms_keyfile_plugin_class_init (NMSKeyfilePluginClass *klass) +nms_keyfile_plugin_class_init (NMSKeyfilePluginClass *req_class) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMSettingsPluginClass *plugin_class = NM_SETTINGS_PLUGIN_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (req_class); object_class->constructed = constructed; - object_class->dispose = dispose; + object_class->dispose = dispose; +} - plugin_class->get_connections = get_connections; - plugin_class->load_connection = load_connection; - plugin_class->reload_connections = reload_connections; - plugin_class->add_connection = add_connection; - plugin_class->get_unmanaged_specs = get_unmanaged_specs; +static void +settings_plugin_interface_init (NMSettingsPluginInterface *plugin_iface) +{ + plugin_iface->get_connections = get_connections; + plugin_iface->load_connection = load_connection; + plugin_iface->reload_connections = reload_connections; + plugin_iface->add_connection = add_connection; + plugin_iface->get_unmanaged_specs = get_unmanaged_specs; } diff --git a/src/settings/plugins/keyfile/nms-keyfile-reader.c b/src/settings/plugins/keyfile/nms-keyfile-reader.c index 71578686..cb4b8379 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-reader.c +++ b/src/settings/plugins/keyfile/nms-keyfile-reader.c @@ -115,7 +115,7 @@ nms_keyfile_reader_from_keyfile (GKeyFile *key_file, NMConnection * nms_keyfile_reader_from_file (const char *filename, GError **error) { - gs_unref_keyfile GKeyFile *key_file = NULL; + GKeyFile *key_file; struct stat statbuf; NMConnection *connection = NULL; GError *verify_error = NULL; @@ -144,11 +144,11 @@ nms_keyfile_reader_from_file (const char *filename, GError **error) key_file = g_key_file_new (); if (!g_key_file_load_from_file (key_file, filename, G_KEY_FILE_NONE, error)) - return NULL; + goto out; connection = nms_keyfile_reader_from_keyfile (key_file, filename, TRUE, error); if (!connection) - return NULL; + goto out; /* Normalize and verify the connection */ if (!nm_connection_normalize (connection, NULL, NULL, &verify_error)) { @@ -160,6 +160,8 @@ nms_keyfile_reader_from_file (const char *filename, GError **error) connection = NULL; } +out: + g_key_file_free (key_file); return connection; } diff --git a/src/settings/plugins/keyfile/nms-keyfile-utils.h b/src/settings/plugins/keyfile/nms-keyfile-utils.h index d5ddb8d5..cd3f42b9 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-utils.h +++ b/src/settings/plugins/keyfile/nms-keyfile-utils.h @@ -25,9 +25,9 @@ #define NMS_KEYFILE_CONNECTION_LOG_PATH(path) ((path) ?: "in-memory") #define NMS_KEYFILE_CONNECTION_LOG_FMT "%s (%s,\"%s\")" -#define NMS_KEYFILE_CONNECTION_LOG_ARG(con) NMS_KEYFILE_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_settings_connection_get_uuid ((NMSettingsConnection *) (con)), nm_settings_connection_get_id ((NMSettingsConnection *) (con)) +#define NMS_KEYFILE_CONNECTION_LOG_ARG(con) NMS_KEYFILE_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_connection_get_uuid ((NMConnection *) (con)), nm_connection_get_id ((NMConnection *) (con)) #define NMS_KEYFILE_CONNECTION_LOG_FMTD "%s (%s,\"%s\",%p)" -#define NMS_KEYFILE_CONNECTION_LOG_ARGD(con) NMS_KEYFILE_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_settings_connection_get_uuid ((NMSettingsConnection *) (con)), nm_settings_connection_get_id ((NMSettingsConnection *) (con)), (con) +#define NMS_KEYFILE_CONNECTION_LOG_ARGD(con) NMS_KEYFILE_CONNECTION_LOG_PATH (nm_settings_connection_get_filename ((NMSettingsConnection *) (con))), nm_connection_get_uuid ((NMConnection *) (con)), nm_connection_get_id ((NMConnection *) (con)), (con) gboolean nms_keyfile_utils_should_ignore_file (const char *filename); diff --git a/src/settings/plugins/keyfile/nms-keyfile-writer.c b/src/settings/plugins/keyfile/nms-keyfile-writer.c index 194b97d4..270a217e 100644 --- a/src/settings/plugins/keyfile/nms-keyfile-writer.c +++ b/src/settings/plugins/keyfile/nms-keyfile-writer.c @@ -34,8 +34,6 @@ #include "nms-keyfile-utils.h" #include "nms-keyfile-reader.h" -#include "nm-utils/nm-io-utils.h" - /*****************************************************************************/ typedef struct { @@ -129,7 +127,7 @@ cert_writer (NMConnection *connection, new_path = g_strdup_printf ("%s/%s-%s.%s", info->keyfile_dir, nm_connection_get_uuid (connection), cert_data->vtable->file_suffix, ext); - success = nm_utils_file_set_contents (new_path, (const char *) blob_data, + success = nm_utils_file_set_contents (new_path, (const gchar *) blob_data, blob_len, 0600, &local); if (success) { /* Write the path value to the keyfile. @@ -299,6 +297,11 @@ _internal_write_connection (NMConnection *connection, return FALSE; } + if (out_path && g_strcmp0 (existing_path, path)) { + *out_path = path; /* pass path out to caller */ + path = NULL; + } + if (out_reread || out_reread_same) { gs_unref_object NMConnection *reread = NULL; @@ -330,8 +333,6 @@ _internal_write_connection (NMConnection *connection, NM_SET_OUT (out_reread_same, reread_same); } - NM_SET_OUT (out_path, g_steal_pointer (&path)); - return TRUE; } diff --git a/src/settings/plugins/keyfile/tests/meson.build b/src/settings/plugins/keyfile/tests/meson.build index 8b94b256..33aaa264 100644 --- a/src/settings/plugins/keyfile/tests/meson.build +++ b/src/settings/plugins/keyfile/tests/meson.build @@ -6,6 +6,7 @@ exe = executable( test_unit, test_unit + '.c', dependencies: test_nm_dep, + c_args: nm_build_cflags, ) test( diff --git a/src/settings/plugins/keyfile/tests/test-keyfile.c b/src/settings/plugins/keyfile/tests/test-keyfile.c index b4c6b1e2..a3045f7d 100644 --- a/src/settings/plugins/keyfile/tests/test-keyfile.c +++ b/src/settings/plugins/keyfile/tests/test-keyfile.c @@ -960,7 +960,7 @@ test_write_intlist_ssid (void) unsigned char tmpssid[] = { 65, 49, 50, 51, 0, 50, 50 }; gs_free_error GError *error = NULL; gs_unref_keyfile GKeyFile *keyfile = NULL; - int *intlist; + gint *intlist; gsize len = 0, i; connection = nm_simple_connection_new (); @@ -1018,20 +1018,27 @@ test_read_intlike_ssid (void) gs_free_error GError *error = NULL; gboolean success; GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; const char *expected_ssid = "101"; connection = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Intlike_SSID", &error); - nmtst_assert_success (connection, error); + g_assert_no_error (error); + g_assert (connection); success = nm_connection_verify (connection, &error); - nmtst_assert_success (success, error); + g_assert_no_error (error); + g_assert (success); + /* SSID */ s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); ssid = nm_setting_wireless_get_ssid (s_wifi); - g_assert (ssid); - g_assert (nm_utils_gbytes_equal_mem (ssid, expected_ssid, strlen (expected_ssid))); + g_assert (ssid != NULL); + ssid_data = g_bytes_get_data (ssid, &ssid_len); + g_assert_cmpint (ssid_len, ==, strlen (expected_ssid)); + g_assert_cmpint (memcmp (ssid_data, expected_ssid, strlen (expected_ssid)), ==, 0); } static void @@ -1042,20 +1049,27 @@ test_read_intlike_ssid_2 (void) gs_free_error GError *error = NULL; gboolean success; GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; const char *expected_ssid = "11;12;13;"; connection = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR "/Test_Intlike_SSID_2", &error); - nmtst_assert_success (connection, error); + g_assert_no_error (error); + g_assert (connection); success = nm_connection_verify (connection, &error); - nmtst_assert_success (success, error); + g_assert_no_error (error); + g_assert (success); + /* SSID */ s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); ssid = nm_setting_wireless_get_ssid (s_wifi); - g_assert (ssid); - g_assert (nm_utils_gbytes_equal_mem (ssid, expected_ssid, strlen (expected_ssid))); + g_assert (ssid != NULL); + ssid_data = g_bytes_get_data (ssid, &ssid_len); + g_assert_cmpint (ssid_len, ==, strlen (expected_ssid)); + g_assert_cmpint (memcmp (ssid_data, expected_ssid, strlen (expected_ssid)), ==, 0); } static void @@ -1773,8 +1787,7 @@ test_write_wired_8021x_tls_connection_blob (void) const char *uuid; gboolean reread_same = FALSE; gs_free_error GError *error = NULL; - GBytes *password_raw; - + GBytes *password_raw = NULL; #define PASSWORD_RAW "password-raw\0test" connection = create_wired_tls_connection (NM_SETTING_802_1X_CK_SCHEME_BLOB); @@ -1833,7 +1846,8 @@ test_write_wired_8021x_tls_connection_blob (void) password_raw = nm_setting_802_1x_get_password_raw (s_8021x); g_assert (password_raw); - g_assert (nm_utils_gbytes_equal_mem (password_raw, PASSWORD_RAW, NM_STRLEN (PASSWORD_RAW))); + g_assert (g_bytes_get_size (password_raw) == NM_STRLEN (PASSWORD_RAW)); + g_assert (!memcmp (g_bytes_get_data (password_raw, NULL), PASSWORD_RAW, NM_STRLEN (PASSWORD_RAW))); unlink (testfile); @@ -2172,7 +2186,7 @@ test_write_new_wired_group_name (void) gs_free char *testfile = NULL; gs_free_error GError *error = NULL; char *s; - int mtu; + gint mtu; connection = nm_simple_connection_new (); g_assert (connection); @@ -2220,25 +2234,32 @@ test_read_new_wireless_group_names (void) NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; GBytes *ssid; + const guint8 *ssid_data; + gsize ssid_len; const char *expected_ssid = "foobar"; gs_free_error GError *error = NULL; gboolean success; connection = nms_keyfile_reader_from_file (TEST_KEYFILES_DIR"/Test_New_Wireless_Group_Names", &error); - nmtst_assert_success (connection, error); - + g_assert_no_error (error); + g_assert (connection); success = nm_connection_verify (connection, &error); - nmtst_assert_success (success, error); + g_assert_no_error (error); + g_assert (success); + /* Wifi setting */ s_wifi = nm_connection_get_setting_wireless (connection); g_assert (s_wifi); ssid = nm_setting_wireless_get_ssid (s_wifi); g_assert (ssid); - g_assert (nm_utils_gbytes_equal_mem (ssid, expected_ssid, strlen (expected_ssid))); + ssid_data = g_bytes_get_data (ssid, &ssid_len); + g_assert_cmpint (ssid_len, ==, strlen (expected_ssid)); + g_assert_cmpint (memcmp (ssid_data, expected_ssid, ssid_len), ==, 0); g_assert_cmpstr (nm_setting_wireless_get_mode (s_wifi), ==, NM_SETTING_WIRELESS_MODE_INFRA); + /* Wifi security setting */ s_wsec = nm_connection_get_setting_wireless_security (connection); g_assert (s_wsec); g_assert_cmpstr (nm_setting_wireless_security_get_key_mgmt (s_wsec), ==, "wpa-psk"); diff --git a/src/supplicant/nm-supplicant-config.c b/src/supplicant/nm-supplicant-config.c index 41d510e8..80db5baa 100644 --- a/src/supplicant/nm-supplicant-config.c +++ b/src/supplicant/nm-supplicant-config.c @@ -89,17 +89,23 @@ config_option_free (ConfigOption *opt) } static void +blob_free (GByteArray *array) +{ + g_byte_array_free (array, TRUE); +} + +static void nm_supplicant_config_init (NMSupplicantConfig * self) { NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); priv->config = g_hash_table_new_full (nm_str_hash, g_str_equal, - g_free, + (GDestroyNotify) g_free, (GDestroyNotify) config_option_free); priv->blobs = g_hash_table_new_full (nm_str_hash, g_str_equal, - g_free, - (GDestroyNotify) g_bytes_unref); + (GDestroyNotify) g_free, + (GDestroyNotify) blob_free); priv->ap_scan = 1; priv->dispose_has_run = FALSE; @@ -192,6 +198,7 @@ nm_supplicant_config_add_blob (NMSupplicantConfig *self, ConfigOption *old_opt; ConfigOption *opt; OptType type; + GByteArray *blob; const guint8 *data; gsize data_len; @@ -219,6 +226,9 @@ nm_supplicant_config_add_blob (NMSupplicantConfig *self, return FALSE; } + blob = g_byte_array_sized_new (data_len); + g_byte_array_append (blob, data, data_len); + opt = g_slice_new0 (ConfigOption); opt->value = g_strdup_printf ("blob://%s", blobid); opt->len = strlen (opt->value); @@ -227,9 +237,7 @@ nm_supplicant_config_add_blob (NMSupplicantConfig *self, nm_log_info (LOGD_SUPPLICANT, "Config: added '%s' value '%s'", key, opt->value); g_hash_table_insert (priv->config, g_strdup (key), opt); - g_hash_table_insert (priv->blobs, - g_strdup (blobid), - g_bytes_ref (value)); + g_hash_table_insert (priv->blobs, g_strdup (blobid), blob); return TRUE; } @@ -941,7 +949,7 @@ add_pkcs11_uri_with_pin (NMSupplicantConfig *self, const NMSettingSecretFlags pin_flags, GError **error) { - gs_strfreev char **split = NULL; + gs_strfreev gchar **split = NULL; gs_free char *tmp = NULL; gs_free char *tmp_log = NULL; gs_free char *pin_qattr = NULL; @@ -1001,7 +1009,6 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, guint32 frag, hdrs; gs_free char *frag_str = NULL; NMSetting8021xAuthFlags phase1_auth_flags; - nm_auto_free_gstring GString *eap_str = NULL; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (setting != NULL, FALSE); @@ -1038,38 +1045,20 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self, priv->ap_scan = 0; } - /* Build the "eap" option string while we check for EAP methods needing - * special handling: PEAP + GTC, FAST, external */ - eap_str = g_string_new (NULL); + if (!ADD_STRING_LIST_VAL (self, setting, 802_1x, eap_method, eap_methods, "eap", ' ', TRUE, NULL, error)) + return FALSE; + + /* Check EAP method for special handling: PEAP + GTC, FAST */ num_eap = nm_setting_802_1x_get_num_eap_methods (setting); for (i = 0; i < num_eap; i++) { const char *method = nm_setting_802_1x_get_eap_method (setting, i); - if (nm_streq (method, "fast")) { + if (method && (strcasecmp (method, "fast") == 0)) { fast = TRUE; priv->fast_required = TRUE; } - - if (nm_streq (method, "external")) { - if (num_eap == 1) { - g_set_error (error, NM_SUPPLICANT_ERROR, NM_SUPPLICANT_ERROR_CONFIG, - "Connection settings managed externally to NM, connection" - " cannot be used with wpa_supplicant"); - return FALSE; - } - continue; - } - - if (eap_str->len) - g_string_append_c (eap_str, ' '); - g_string_append (eap_str, method); } - g_string_ascii_up (eap_str); - if ( eap_str->len - && !nm_supplicant_config_add_option (self, "eap", eap_str->str, -1, NULL, error)) - return FALSE; - /* Adjust the fragment size according to MTU, but do not set it higher than 1280-14 * for better compatibility */ hdrs = 14; /* EAPOL + EAP-TLS */ diff --git a/src/supplicant/nm-supplicant-interface.c b/src/supplicant/nm-supplicant-interface.c index 5237acb2..e16e3130 100644 --- a/src/supplicant/nm-supplicant-interface.c +++ b/src/supplicant/nm-supplicant-interface.c @@ -1579,7 +1579,7 @@ assoc_add_network_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_dat GHashTable *blobs; GHashTableIter iter; const char *blob_name; - GBytes *blob_data; + GByteArray *blob_data; assoc_data = add_network_data->assoc_data; if (assoc_data) @@ -1637,7 +1637,8 @@ assoc_add_network_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_dat "AddBlob", g_variant_new ("(s@ay)", blob_name, - nm_utils_gbytes_to_variant_ay (blob_data)), + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + blob_data->data, blob_data->len, 1)), G_DBUS_CALL_FLAGS_NONE, -1, priv->assoc_data->cancellable, @@ -1789,9 +1790,7 @@ scan_request_cb (GDBusProxy *proxy, GAsyncResult *result, gpointer user_data) } void -nm_supplicant_interface_request_scan (NMSupplicantInterface *self, - GBytes *const*ssids, - guint ssids_len) +nm_supplicant_interface_request_scan (NMSupplicantInterface *self, const GPtrArray *ssids) { NMSupplicantInterfacePrivate *priv; GVariantBuilder builder; @@ -1805,14 +1804,15 @@ nm_supplicant_interface_request_scan (NMSupplicantInterface *self, g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add (&builder, "{sv}", "Type", g_variant_new_string ("active")); g_variant_builder_add (&builder, "{sv}", "AllowRoam", g_variant_new_boolean (FALSE)); - if (ssids_len > 0) { + if (ssids) { GVariantBuilder ssids_builder; g_variant_builder_init (&ssids_builder, G_VARIANT_TYPE_BYTESTRING_ARRAY); - for (i = 0; i < ssids_len; i++) { - nm_assert (ssids[i]); + for (i = 0; i < ssids->len; i++) { + GByteArray *ssid = g_ptr_array_index (ssids, i); g_variant_builder_add (&ssids_builder, "@ay", - nm_utils_gbytes_to_variant_ay (ssids[i])); + g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, + ssid->data, ssid->len, 1)); } g_variant_builder_add (&builder, "{sv}", "SSIDs", g_variant_builder_end (&ssids_builder)); } diff --git a/src/supplicant/nm-supplicant-interface.h b/src/supplicant/nm-supplicant-interface.h index 0365fdcd..31272b3c 100644 --- a/src/supplicant/nm-supplicant-interface.h +++ b/src/supplicant/nm-supplicant-interface.h @@ -100,9 +100,7 @@ void nm_supplicant_interface_disconnect (NMSupplicantInterface * iface); const char *nm_supplicant_interface_get_object_path (NMSupplicantInterface * iface); -void nm_supplicant_interface_request_scan (NMSupplicantInterface *self, - GBytes *const*ssids, - guint ssids_len); +void nm_supplicant_interface_request_scan (NMSupplicantInterface * self, const GPtrArray *ssids); NMSupplicantInterfaceState nm_supplicant_interface_get_state (NMSupplicantInterface * self); diff --git a/src/supplicant/nm-supplicant-settings-verify.c b/src/supplicant/nm-supplicant-settings-verify.c index 8a0cadc7..317afff9 100644 --- a/src/supplicant/nm-supplicant-settings-verify.c +++ b/src/supplicant/nm-supplicant-settings-verify.c @@ -220,7 +220,7 @@ validate_type_keyword (const struct Opt * opt, const guint32 len) { char **allowed; - char **candidates = NULL; + gchar **candidates = NULL; char **candidate; gboolean found = FALSE; diff --git a/src/supplicant/tests/meson.build b/src/supplicant/tests/meson.build index 5e4cbdbe..b8bad7f3 100644 --- a/src/supplicant/tests/meson.build +++ b/src/supplicant/tests/meson.build @@ -4,6 +4,7 @@ exe = executable( test_unit, test_unit + '.c', dependencies: test_nm_dep, + c_args: nm_build_cflags, ) test( diff --git a/src/systemd/meson.build b/src/systemd/meson.build index 870721b0..0c7d0aec 100644 --- a/src/systemd/meson.build +++ b/src/systemd/meson.build @@ -2,7 +2,6 @@ sources = files( 'sd-adapt/nm-sd-adapt.c', 'src/basic/alloc-util.c', 'src/basic/escape.c', - 'src/basic/env-util.c', 'src/basic/ether-addr-util.c', 'src/basic/extract-word.c', 'src/basic/fd-util.c', diff --git a/src/systemd/nm-sd.c b/src/systemd/nm-sd.c index cbef91d1..e05b345b 100644 --- a/src/systemd/nm-sd.c +++ b/src/systemd/nm-sd.c @@ -35,7 +35,7 @@ typedef struct SDEventSource { } SDEventSource; static gboolean -event_prepare (GSource *source, int *timeout_) +event_prepare (GSource *source, gint *timeout_) { return sd_event_prepare (((SDEventSource *) source)->event) > 0; } diff --git a/src/systemd/sd-adapt/sd-device.h b/src/systemd/sd-adapt/env-util.h index 637892c2..637892c2 100644 --- a/src/systemd/sd-adapt/sd-device.h +++ b/src/systemd/sd-adapt/env-util.h diff --git a/src/systemd/sd-adapt/libudev.h b/src/systemd/sd-adapt/libudev.h new file mode 100644 index 00000000..8c49f075 --- /dev/null +++ b/src/systemd/sd-adapt/libudev.h @@ -0,0 +1,5 @@ +#pragma once + +/* dummy header */ + +struct udev_device; diff --git a/src/systemd/sd-adapt/nm-sd-adapt.h b/src/systemd/sd-adapt/nm-sd-adapt.h index e163eeda..380cbc60 100644 --- a/src/systemd/sd-adapt/nm-sd-adapt.h +++ b/src/systemd/sd-adapt/nm-sd-adapt.h @@ -26,6 +26,10 @@ #include <sys/resource.h> #include <time.h> +#ifndef CLOCK_BOOTTIME +#define CLOCK_BOOTTIME 7 +#endif + #if defined(HAVE_DECL_REALLOCARRAY) && HAVE_DECL_REALLOCARRAY == 1 #define HAVE_REALLOCARRAY 1 #else @@ -176,6 +180,15 @@ sd_notify (int unset_environment, const char *state) #define MAX_HANDLE_SZ 128 #endif +/* + * Some toolchains (E.G. uClibc 0.9.33 and earlier) don't export + * CLOCK_BOOTTIME even though the kernel supports it, so provide a + * local definition + */ +#ifndef CLOCK_BOOTTIME +#define CLOCK_BOOTTIME 7 +#endif + #include "sd-id128.h" #include "sparse-endian.h" #include "async.h" diff --git a/src/systemd/sd-adapt/udev-util.h b/src/systemd/sd-adapt/udev-util.h new file mode 100644 index 00000000..637892c2 --- /dev/null +++ b/src/systemd/sd-adapt/udev-util.h @@ -0,0 +1,3 @@ +#pragma once + +/* dummy header */ diff --git a/src/systemd/sd-adapt/udev.h b/src/systemd/sd-adapt/udev.h new file mode 100644 index 00000000..419abcbf --- /dev/null +++ b/src/systemd/sd-adapt/udev.h @@ -0,0 +1,6 @@ +#pragma once + +/* dummy header */ + +#include "libudev.h" +#include "strv.h" diff --git a/src/systemd/src/basic/env-util.c b/src/systemd/src/basic/env-util.c deleted file mode 100644 index 52d12a8a..00000000 --- a/src/systemd/src/basic/env-util.c +++ /dev/null @@ -1,791 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1+ */ - -#include "nm-sd-adapt.h" - -#include <errno.h> -#include <limits.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "alloc-util.h" -#include "env-util.h" -#include "escape.h" -#include "extract-word.h" -#include "macro.h" -#include "parse-util.h" -#include "string-util.h" -#include "strv.h" -#include "utf8.h" - -#if 0 /* NM_IGNORED */ -#define VALID_CHARS_ENV_NAME \ - DIGITS LETTERS \ - "_" - -#ifndef ARG_MAX -#define ARG_MAX ((size_t) sysconf(_SC_ARG_MAX)) -#endif - -static bool env_name_is_valid_n(const char *e, size_t n) { - const char *p; - - if (!e) - return false; - - if (n <= 0) - return false; - - if (e[0] >= '0' && e[0] <= '9') - return false; - - /* POSIX says the overall size of the environment block cannot - * be > ARG_MAX, an individual assignment hence cannot be - * either. Discounting the equal sign and trailing NUL this - * hence leaves ARG_MAX-2 as longest possible variable - * name. */ - if (n > ARG_MAX - 2) - return false; - - for (p = e; p < e + n; p++) - if (!strchr(VALID_CHARS_ENV_NAME, *p)) - return false; - - return true; -} - -bool env_name_is_valid(const char *e) { - if (!e) - return false; - - return env_name_is_valid_n(e, strlen(e)); -} - -bool env_value_is_valid(const char *e) { - if (!e) - return false; - - if (!utf8_is_valid(e)) - return false; - - /* bash allows tabs and newlines in environment variables, and so - * should we */ - if (string_has_cc(e, "\t\n")) - return false; - - /* POSIX says the overall size of the environment block cannot - * be > ARG_MAX, an individual assignment hence cannot be - * either. Discounting the shortest possible variable name of - * length 1, the equal sign and trailing NUL this hence leaves - * ARG_MAX-3 as longest possible variable value. */ - if (strlen(e) > ARG_MAX - 3) - return false; - - return true; -} - -bool env_assignment_is_valid(const char *e) { - const char *eq; - - eq = strchr(e, '='); - if (!eq) - return false; - - if (!env_name_is_valid_n(e, eq - e)) - return false; - - if (!env_value_is_valid(eq + 1)) - return false; - - /* POSIX says the overall size of the environment block cannot - * be > ARG_MAX, hence the individual variable assignments - * cannot be either, but let's leave room for one trailing NUL - * byte. */ - if (strlen(e) > ARG_MAX - 1) - return false; - - return true; -} - -bool strv_env_is_valid(char **e) { - char **p, **q; - - STRV_FOREACH(p, e) { - size_t k; - - if (!env_assignment_is_valid(*p)) - return false; - - /* Check if there are duplicate assginments */ - k = strcspn(*p, "="); - STRV_FOREACH(q, p + 1) - if (strneq(*p, *q, k) && (*q)[k] == '=') - return false; - } - - return true; -} - -bool strv_env_name_is_valid(char **l) { - char **p, **q; - - STRV_FOREACH(p, l) { - if (!env_name_is_valid(*p)) - return false; - - STRV_FOREACH(q, p + 1) - if (streq(*p, *q)) - return false; - } - - return true; -} - -bool strv_env_name_or_assignment_is_valid(char **l) { - char **p, **q; - - STRV_FOREACH(p, l) { - if (!env_assignment_is_valid(*p) && !env_name_is_valid(*p)) - return false; - - STRV_FOREACH(q, p + 1) - if (streq(*p, *q)) - return false; - } - - return true; -} - -static int env_append(char **r, char ***k, char **a) { - assert(r); - assert(k); - - if (!a) - return 0; - - /* Add the entries of a to *k unless they already exist in *r - * in which case they are overridden instead. This assumes - * there is enough space in the r array. */ - - for (; *a; a++) { - char **j; - size_t n; - - n = strcspn(*a, "="); - - if ((*a)[n] == '=') - n++; - - for (j = r; j < *k; j++) - if (strneq(*j, *a, n)) - break; - - if (j >= *k) - (*k)++; - else - free(*j); - - *j = strdup(*a); - if (!*j) - return -ENOMEM; - } - - return 0; -} - -char **strv_env_merge(size_t n_lists, ...) { - size_t n = 0; - char **l, **k, **r; - va_list ap; - size_t i; - - /* Merges an arbitrary number of environment sets */ - - va_start(ap, n_lists); - for (i = 0; i < n_lists; i++) { - l = va_arg(ap, char**); - n += strv_length(l); - } - va_end(ap); - - r = new(char*, n+1); - if (!r) - return NULL; - - k = r; - - va_start(ap, n_lists); - for (i = 0; i < n_lists; i++) { - l = va_arg(ap, char**); - if (env_append(r, &k, l) < 0) - goto fail; - } - va_end(ap); - - *k = NULL; - - return r; - -fail: - va_end(ap); - strv_free(r); - - return NULL; -} - -static bool env_match(const char *t, const char *pattern) { - assert(t); - assert(pattern); - - /* pattern a matches string a - * a matches a= - * a matches a=b - * a= matches a= - * a=b matches a=b - * a= does not match a - * a=b does not match a= - * a=b does not match a - * a=b does not match a=c */ - - if (streq(t, pattern)) - return true; - - if (!strchr(pattern, '=')) { - size_t l = strlen(pattern); - - return strneq(t, pattern, l) && t[l] == '='; - } - - return false; -} - -static bool env_entry_has_name(const char *entry, const char *name) { - const char *t; - - assert(entry); - assert(name); - - t = startswith(entry, name); - if (!t) - return false; - - return *t == '='; -} - -char **strv_env_delete(char **x, size_t n_lists, ...) { - size_t n, i = 0; - char **k, **r; - va_list ap; - - /* Deletes every entry from x that is mentioned in the other - * string lists */ - - n = strv_length(x); - - r = new(char*, n+1); - if (!r) - return NULL; - - STRV_FOREACH(k, x) { - size_t v; - - va_start(ap, n_lists); - for (v = 0; v < n_lists; v++) { - char **l, **j; - - l = va_arg(ap, char**); - STRV_FOREACH(j, l) - if (env_match(*k, *j)) - goto skip; - } - va_end(ap); - - r[i] = strdup(*k); - if (!r[i]) { - strv_free(r); - return NULL; - } - - i++; - continue; - - skip: - va_end(ap); - } - - r[i] = NULL; - - assert(i <= n); - - return r; -} - -char **strv_env_unset(char **l, const char *p) { - - char **f, **t; - - if (!l) - return NULL; - - assert(p); - - /* Drops every occurrence of the env var setting p in the - * string list. Edits in-place. */ - - for (f = t = l; *f; f++) { - - if (env_match(*f, p)) { - free(*f); - continue; - } - - *(t++) = *f; - } - - *t = NULL; - return l; -} - -char **strv_env_unset_many(char **l, ...) { - - char **f, **t; - - if (!l) - return NULL; - - /* Like strv_env_unset() but applies many at once. Edits in-place. */ - - for (f = t = l; *f; f++) { - bool found = false; - const char *p; - va_list ap; - - va_start(ap, l); - - while ((p = va_arg(ap, const char*))) { - if (env_match(*f, p)) { - found = true; - break; - } - } - - va_end(ap); - - if (found) { - free(*f); - continue; - } - - *(t++) = *f; - } - - *t = NULL; - return l; -} - -int strv_env_replace(char ***l, char *p) { - char **f; - const char *t, *name; - - assert(p); - - /* Replace first occurrence of the env var or add a new one in the - * string list. Drop other occurences. Edits in-place. Does not copy p. - * p must be a valid key=value assignment. - */ - - t = strchr(p, '='); - assert(t); - - name = strndupa(p, t - p); - - for (f = *l; f && *f; f++) - if (env_entry_has_name(*f, name)) { - free_and_replace(*f, p); - strv_env_unset(f + 1, *f); - return 0; - } - - /* We didn't find a match, we need to append p or create a new strv */ - if (strv_push(l, p) < 0) - return -ENOMEM; - return 1; -} - -char **strv_env_set(char **x, const char *p) { - - char **k; - _cleanup_strv_free_ char **r = NULL; - char* m[2] = { (char*) p, NULL }; - - /* Overrides the env var setting of p, returns a new copy */ - - r = new(char*, strv_length(x)+2); - if (!r) - return NULL; - - k = r; - if (env_append(r, &k, x) < 0) - return NULL; - - if (env_append(r, &k, m) < 0) - return NULL; - - *k = NULL; - - return TAKE_PTR(r); -} - -char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) { - char **i; - - assert(name); - - if (k <= 0) - return NULL; - - STRV_FOREACH_BACKWARDS(i, l) - if (strneq(*i, name, k) && - (*i)[k] == '=') - return *i + k + 1; - - if (flags & REPLACE_ENV_USE_ENVIRONMENT) { - const char *t; - - t = strndupa(name, k); - return getenv(t); - }; - - return NULL; -} - -char *strv_env_get(char **l, const char *name) { - assert(name); - - return strv_env_get_n(l, name, strlen(name), 0); -} - -char **strv_env_clean_with_callback(char **e, void (*invalid_callback)(const char *p, void *userdata), void *userdata) { - char **p, **q; - int k = 0; - - STRV_FOREACH(p, e) { - size_t n; - bool duplicate = false; - - if (!env_assignment_is_valid(*p)) { - if (invalid_callback) - invalid_callback(*p, userdata); - free(*p); - continue; - } - - n = strcspn(*p, "="); - STRV_FOREACH(q, p + 1) - if (strneq(*p, *q, n) && (*q)[n] == '=') { - duplicate = true; - break; - } - - if (duplicate) { - free(*p); - continue; - } - - e[k++] = *p; - } - - if (e) - e[k] = NULL; - - return e; -} - -char *replace_env_n(const char *format, size_t n, char **env, unsigned flags) { - enum { - WORD, - CURLY, - VARIABLE, - VARIABLE_RAW, - TEST, - DEFAULT_VALUE, - ALTERNATE_VALUE, - } state = WORD; - - const char *e, *word = format, *test_value; - char *k; - _cleanup_free_ char *r = NULL; - size_t i, len; - int nest = 0; - - assert(format); - - for (e = format, i = 0; *e && i < n; e ++, i ++) - switch (state) { - - case WORD: - if (*e == '$') - state = CURLY; - break; - - case CURLY: - if (*e == '{') { - k = strnappend(r, word, e-word-1); - if (!k) - return NULL; - - free_and_replace(r, k); - - word = e-1; - state = VARIABLE; - nest++; - } else if (*e == '$') { - k = strnappend(r, word, e-word); - if (!k) - return NULL; - - free_and_replace(r, k); - - word = e+1; - state = WORD; - - } else if (flags & REPLACE_ENV_ALLOW_BRACELESS && strchr(VALID_CHARS_ENV_NAME, *e)) { - k = strnappend(r, word, e-word-1); - if (!k) - return NULL; - - free_and_replace(r, k); - - word = e-1; - state = VARIABLE_RAW; - - } else - state = WORD; - break; - - case VARIABLE: - if (*e == '}') { - const char *t; - - t = strv_env_get_n(env, word+2, e-word-2, flags); - - k = strappend(r, t); - if (!k) - return NULL; - - free_and_replace(r, k); - - word = e+1; - state = WORD; - } else if (*e == ':') { - if (!(flags & REPLACE_ENV_ALLOW_EXTENDED)) - /* Treat this as unsupported syntax, i.e. do no replacement */ - state = WORD; - else { - len = e-word-2; - state = TEST; - } - } - break; - - case TEST: - if (*e == '-') - state = DEFAULT_VALUE; - else if (*e == '+') - state = ALTERNATE_VALUE; - else { - state = WORD; - break; - } - - test_value = e+1; - break; - - case DEFAULT_VALUE: /* fall through */ - case ALTERNATE_VALUE: - assert(flags & REPLACE_ENV_ALLOW_EXTENDED); - - if (*e == '{') { - nest++; - break; - } - - if (*e != '}') - break; - - nest--; - if (nest == 0) { - const char *t; - _cleanup_free_ char *v = NULL; - - t = strv_env_get_n(env, word+2, len, flags); - - if (t && state == ALTERNATE_VALUE) - t = v = replace_env_n(test_value, e-test_value, env, flags); - else if (!t && state == DEFAULT_VALUE) - t = v = replace_env_n(test_value, e-test_value, env, flags); - - k = strappend(r, t); - if (!k) - return NULL; - - free_and_replace(r, k); - - word = e+1; - state = WORD; - } - break; - - case VARIABLE_RAW: - assert(flags & REPLACE_ENV_ALLOW_BRACELESS); - - if (!strchr(VALID_CHARS_ENV_NAME, *e)) { - const char *t; - - t = strv_env_get_n(env, word+1, e-word-1, flags); - - k = strappend(r, t); - if (!k) - return NULL; - - free_and_replace(r, k); - - word = e--; - i--; - state = WORD; - } - break; - } - - if (state == VARIABLE_RAW) { - const char *t; - - assert(flags & REPLACE_ENV_ALLOW_BRACELESS); - - t = strv_env_get_n(env, word+1, e-word-1, flags); - return strappend(r, t); - } else - return strnappend(r, word, e-word); -} - -char **replace_env_argv(char **argv, char **env) { - char **ret, **i; - size_t k = 0, l = 0; - - l = strv_length(argv); - - ret = new(char*, l+1); - if (!ret) - return NULL; - - STRV_FOREACH(i, argv) { - - /* If $FOO appears as single word, replace it by the split up variable */ - if ((*i)[0] == '$' && !IN_SET((*i)[1], '{', '$')) { - char *e; - char **w, **m = NULL; - size_t q; - - e = strv_env_get(env, *i+1); - if (e) { - int r; - - r = strv_split_extract(&m, e, WHITESPACE, EXTRACT_RELAX|EXTRACT_QUOTES); - if (r < 0) { - ret[k] = NULL; - strv_free(ret); - return NULL; - } - } else - m = NULL; - - q = strv_length(m); - l = l + q - 1; - - w = reallocarray(ret, l + 1, sizeof(char *)); - if (!w) { - ret[k] = NULL; - strv_free(ret); - strv_free(m); - return NULL; - } - - ret = w; - if (m) { - memcpy(ret + k, m, q * sizeof(char*)); - free(m); - } - - k += q; - continue; - } - - /* If ${FOO} appears as part of a word, replace it by the variable as-is */ - ret[k] = replace_env(*i, env, 0); - if (!ret[k]) { - strv_free(ret); - return NULL; - } - k++; - } - - ret[k] = NULL; - return ret; -} -#endif /* NM_IGNORED */ - -int getenv_bool(const char *p) { - const char *e; - - e = getenv(p); - if (!e) - return -ENXIO; - - return parse_boolean(e); -} - -#if 0 /* NM_IGNORED */ -int getenv_bool_secure(const char *p) { - const char *e; - - e = secure_getenv(p); - if (!e) - return -ENXIO; - - return parse_boolean(e); -} - -int serialize_environment(FILE *f, char **environment) { - char **e; - - STRV_FOREACH(e, environment) { - _cleanup_free_ char *ce; - - ce = cescape(*e); - if (!ce) - return -ENOMEM; - - fprintf(f, "env=%s\n", ce); - } - - /* caller should call ferror() */ - - return 0; -} - -int deserialize_environment(char ***environment, const char *line) { - char *uce; - int r; - - assert(line); - assert(environment); - - assert(startswith(line, "env=")); - r = cunescape(line + 4, 0, &uce); - if (r < 0) - return r; - - return strv_env_replace(environment, uce); -} -#endif /* NM_IGNORED */ diff --git a/src/systemd/src/basic/env-util.h b/src/systemd/src/basic/env-util.h deleted file mode 100644 index 174433ea..00000000 --- a/src/systemd/src/basic/env-util.h +++ /dev/null @@ -1,50 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1+ */ -#pragma once - -#include <stdbool.h> -#include <stddef.h> -#include <stdio.h> - -#include "macro.h" -#include "string.h" - -bool env_name_is_valid(const char *e); -bool env_value_is_valid(const char *e); -bool env_assignment_is_valid(const char *e); - -enum { - REPLACE_ENV_USE_ENVIRONMENT = 1u, - REPLACE_ENV_ALLOW_BRACELESS = 2u, - REPLACE_ENV_ALLOW_EXTENDED = 4u, -}; - -char *replace_env_n(const char *format, size_t n, char **env, unsigned flags); -char **replace_env_argv(char **argv, char **env); - -static inline char *replace_env(const char *format, char **env, unsigned flags) { - return replace_env_n(format, strlen(format), env, flags); -} - -bool strv_env_is_valid(char **e); -#define strv_env_clean(l) strv_env_clean_with_callback(l, NULL, NULL) -char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const char *p, void *userdata), void *userdata); - -bool strv_env_name_is_valid(char **l); -bool strv_env_name_or_assignment_is_valid(char **l); - -char **strv_env_merge(size_t n_lists, ...); -char **strv_env_delete(char **x, size_t n_lists, ...); /* New copy */ - -char **strv_env_set(char **x, const char *p); /* New copy ... */ -char **strv_env_unset(char **l, const char *p); /* In place ... */ -char **strv_env_unset_many(char **l, ...) _sentinel_; -int strv_env_replace(char ***l, char *p); /* In place ... */ - -char *strv_env_get_n(char **l, const char *name, size_t k, unsigned flags) _pure_; -char *strv_env_get(char **x, const char *n) _pure_; - -int getenv_bool(const char *p); -int getenv_bool_secure(const char *p); - -int serialize_environment(FILE *f, char **environment); -int deserialize_environment(char ***environment, const char *line); diff --git a/src/systemd/src/basic/ether-addr-util.c b/src/systemd/src/basic/ether-addr-util.c index ed92bc60..6f946c3e 100644 --- a/src/systemd/src/basic/ether-addr-util.c +++ b/src/systemd/src/basic/ether-addr-util.c @@ -1,4 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright © 2014 Tom Gundersen +***/ #include "nm-sd-adapt.h" diff --git a/src/systemd/src/basic/ether-addr-util.h b/src/systemd/src/basic/ether-addr-util.h index 3be03700..f02cefea 100644 --- a/src/systemd/src/basic/ether-addr-util.h +++ b/src/systemd/src/basic/ether-addr-util.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +/*** + Copyright © 2014 Tom Gundersen +***/ + #include <net/ethernet.h> #include <stdbool.h> diff --git a/src/systemd/src/basic/fd-util.h b/src/systemd/src/basic/fd-util.h index 00303a7e..8adc959d 100644 --- a/src/systemd/src/basic/fd-util.h +++ b/src/systemd/src/basic/fd-util.h @@ -78,12 +78,8 @@ int acquire_data_fd(const void *data, size_t size, unsigned flags); int fd_duplicate_data_fd(int fd); /* Hint: ENETUNREACH happens if we try to connect to "non-existing" special IP addresses, such as ::5 */ -/* The kernel sends e.g., EHOSTUNREACH or ENONET to userspace in some ICMP error cases. - * See the icmp_err_convert[] in net/ipv4/icmp.c in the kernel sources */ -#define ERRNO_IS_DISCONNECT(r) \ - IN_SET(r, \ - ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, \ - ENETUNREACH, EHOSTUNREACH, ENOPROTOOPT, EHOSTDOWN, ENONET) +#define ERRNO_IS_DISCONNECT(r) \ + IN_SET(r, ENOTCONN, ECONNRESET, ECONNREFUSED, ECONNABORTED, EPIPE, ENETUNREACH) /* Resource exhaustion, could be our fault or general system trouble */ #define ERRNO_IS_RESOURCE(r) \ diff --git a/src/systemd/src/basic/fileio.c b/src/systemd/src/basic/fileio.c index 3978c3a7..2d3aef2c 100644 --- a/src/systemd/src/basic/fileio.c +++ b/src/systemd/src/basic/fileio.c @@ -1235,13 +1235,9 @@ int tempfn_xxxxxx(const char *p, const char *extra, char **ret) { const char *fn; char *t; + assert(p); assert(ret); - if (isempty(p)) - return -EINVAL; - if (path_equal(p, "/")) - return -EINVAL; - /* * Turns this: * /foo/bar/waldo @@ -1273,13 +1269,9 @@ int tempfn_random(const char *p, const char *extra, char **ret) { uint64_t u; unsigned i; + assert(p); assert(ret); - if (isempty(p)) - return -EINVAL; - if (path_equal(p, "/")) - return -EINVAL; - /* * Turns this: * /foo/bar/waldo @@ -1338,10 +1330,7 @@ int tempfn_random_child(const char *p, const char *extra, char **ret) { if (!t) return -ENOMEM; - if (isempty(p)) - x = stpcpy(stpcpy(t, ".#"), extra); - else - x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra); + x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra); u = random_u64(); for (i = 0; i < 16; i++) { @@ -1428,8 +1417,7 @@ int open_tmpfile_unlinkable(const char *directory, int flags) { r = tmp_dir(&directory); if (r < 0) return r; - } else if (isempty(directory)) - return -EINVAL; + } /* Returns an unlinked temporary file that cannot be linked into the file system anymore */ @@ -1464,13 +1452,21 @@ int open_tmpfile_linkable(const char *target, int flags, char **ret_path) { * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */ - fd = open_parent(target, O_TMPFILE|flags, 0640); - if (fd >= 0) { - *ret_path = NULL; - return fd; - } + { + _cleanup_free_ char *dn = NULL; + + dn = dirname_malloc(target); + if (!dn) + return -ENOMEM; - log_debug_errno(fd, "Failed to use O_TMPFILE for %s: %m", target); + fd = open(dn, O_TMPFILE|flags, 0640); + if (fd >= 0) { + *ret_path = NULL; + return fd; + } + + log_debug_errno(errno, "Failed to use O_TMPFILE on %s: %m", dn); + } r = tempfn_random(target, NULL, &tmp); if (r < 0) diff --git a/src/systemd/src/basic/fs-util.c b/src/systemd/src/basic/fs-util.c index 8c19e9c7..e3ae9916 100644 --- a/src/systemd/src/basic/fs-util.c +++ b/src/systemd/src/basic/fs-util.c @@ -442,31 +442,6 @@ int mkfifo_atomic(const char *path, mode_t mode) { return 0; } -int mkfifoat_atomic(int dirfd, const char *path, mode_t mode) { - _cleanup_free_ char *t = NULL; - int r; - - assert(path); - - if (path_is_absolute(path)) - return mkfifo_atomic(path, mode); - - /* We're only interested in the (random) filename. */ - r = tempfn_random_child("", NULL, &t); - if (r < 0) - return r; - - if (mkfifoat(dirfd, t, mode) < 0) - return -errno; - - if (renameat(dirfd, t, dirfd, path) < 0) { - unlink_noerrno(t); - return -errno; - } - - return 0; -} - int get_files_in_directory(const char *path, char ***list) { _cleanup_closedir_ DIR *d = NULL; struct dirent *de; @@ -704,7 +679,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, if (!original_root && !ret && (flags & (CHASE_NONEXISTENT|CHASE_NO_AUTOFS|CHASE_SAFE|CHASE_OPEN|CHASE_STEP)) == CHASE_OPEN) { /* Shortcut the CHASE_OPEN case if the caller isn't interested in the actual path and has no root set * and doesn't care about any of the other special features we provide either. */ - r = open(path, O_PATH|O_CLOEXEC|((flags & CHASE_NOFOLLOW) ? O_NOFOLLOW : 0)); + r = open(path, O_PATH|O_CLOEXEC); if (r < 0) return -errno; @@ -859,7 +834,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags, fd_is_fs_type(child, AUTOFS_SUPER_MAGIC) > 0) return -EREMOTE; - if (S_ISLNK(st.st_mode) && !((flags & CHASE_NOFOLLOW) && isempty(todo))) { + if (S_ISLNK(st.st_mode)) { char *joined; _cleanup_free_ char *destination = NULL; @@ -1190,7 +1165,7 @@ int unlinkat_deallocate(int fd, const char *name, int flags) { } int fsync_directory_of_file(int fd) { - _cleanup_free_ char *path = NULL; + _cleanup_free_ char *path = NULL, *dn = NULL; _cleanup_close_ int dfd = -1; int r; @@ -1216,41 +1191,17 @@ int fsync_directory_of_file(int fd) { if (!path_is_absolute(path)) return -EINVAL; - dfd = open_parent(path, O_CLOEXEC, 0); + dn = dirname_malloc(path); + if (!dn) + return -ENOMEM; + + dfd = open(dn, O_RDONLY|O_CLOEXEC|O_DIRECTORY); if (dfd < 0) - return dfd; + return -errno; if (fsync(dfd) < 0) return -errno; return 0; } - -int open_parent(const char *path, int flags, mode_t mode) { - _cleanup_free_ char *parent = NULL; - int fd; - - if (isempty(path)) - return -EINVAL; - if (path_equal(path, "/")) /* requesting the parent of the root dir is fishy, let's prohibit that */ - return -EINVAL; - - parent = dirname_malloc(path); - if (!parent) - return -ENOMEM; - - /* Let's insist on O_DIRECTORY since the parent of a file or directory is a directory. Except if we open an - * O_TMPFILE file, because in that case we are actually create a regular file below the parent directory. */ - - if ((flags & O_PATH) == O_PATH) - flags |= O_DIRECTORY; - else if ((flags & O_TMPFILE) != O_TMPFILE) - flags |= O_DIRECTORY|O_RDONLY; - - fd = open(parent, flags, mode); - if (fd < 0) - return -errno; - - return fd; -} #endif /* NM_IGNORED */ diff --git a/src/systemd/src/basic/fs-util.h b/src/systemd/src/basic/fs-util.h index 4b656258..28566773 100644 --- a/src/systemd/src/basic/fs-util.h +++ b/src/systemd/src/basic/fs-util.h @@ -42,7 +42,6 @@ int symlink_idempotent(const char *from, const char *to); int symlink_atomic(const char *from, const char *to); int mknod_atomic(const char *path, mode_t mode, dev_t dev); int mkfifo_atomic(const char *path, mode_t mode); -int mkfifoat_atomic(int dir_fd, const char *path, mode_t mode); int get_files_in_directory(const char *path, char ***list); @@ -73,7 +72,6 @@ enum { CHASE_OPEN = 1 << 4, /* If set, return an O_PATH object to the final component */ CHASE_TRAIL_SLASH = 1 << 5, /* If set, any trailing slash will be preserved */ CHASE_STEP = 1 << 6, /* If set, just execute a single step of the normalization */ - CHASE_NOFOLLOW = 1 << 7, /* Only valid with CHASE_OPEN: when the path's right-most component refers to symlink return O_PATH fd of the symlink, rather than following it. */ }; /* How many iterations to execute before returning -ELOOP */ @@ -105,5 +103,3 @@ void unlink_tempfilep(char (*p)[]); int unlinkat_deallocate(int fd, const char *name, int flags); int fsync_directory_of_file(int fd); - -int open_parent(const char *path, int flags, mode_t mode); diff --git a/src/systemd/src/basic/hash-funcs.c b/src/systemd/src/basic/hash-funcs.c index fc2c4f78..7ed35cb1 100644 --- a/src/systemd/src/basic/hash-funcs.c +++ b/src/systemd/src/basic/hash-funcs.c @@ -1,4 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright © 2014 Michal Schmidt +***/ #include "nm-sd-adapt.h" @@ -75,7 +78,7 @@ void trivial_hash_func(const void *p, struct siphash *state) { } int trivial_compare_func(const void *a, const void *b) { - return CMP(a, b); + return a < b ? -1 : (a > b ? 1 : 0); } const struct hash_ops trivial_hash_ops = { @@ -91,7 +94,7 @@ int uint64_compare_func(const void *_a, const void *_b) { uint64_t a, b; a = *(const uint64_t*) _a; b = *(const uint64_t*) _b; - return CMP(a, b); + return a < b ? -1 : (a > b ? 1 : 0); } const struct hash_ops uint64_hash_ops = { @@ -109,7 +112,7 @@ int devt_compare_func(const void *_a, const void *_b) { dev_t a, b; a = *(const dev_t*) _a; b = *(const dev_t*) _b; - return CMP(a, b); + return a < b ? -1 : (a > b ? 1 : 0); } const struct hash_ops devt_hash_ops = { diff --git a/src/systemd/src/basic/hash-funcs.h b/src/systemd/src/basic/hash-funcs.h index fa45cfe2..3715c56e 100644 --- a/src/systemd/src/basic/hash-funcs.h +++ b/src/systemd/src/basic/hash-funcs.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +/*** + Copyright © 2014 Michal Schmidt +***/ + #include "macro.h" #include "siphash24.h" diff --git a/src/systemd/src/basic/hashmap.c b/src/systemd/src/basic/hashmap.c index cfddeafe..c91f8bd2 100644 --- a/src/systemd/src/basic/hashmap.c +++ b/src/systemd/src/basic/hashmap.c @@ -1,4 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright © 2014 Michal Schmidt +***/ #include "nm-sd-adapt.h" @@ -8,9 +11,8 @@ #include <string.h> #include "alloc-util.h" -#include "env-util.h" -#include "fileio.h" #include "hashmap.h" +#include "fileio.h" #include "macro.h" #include "mempool.h" #include "process-util.h" @@ -769,31 +771,20 @@ static void reset_direct_storage(HashmapBase *h) { memset(p, DIB_RAW_INIT, sizeof(dib_raw_t) * hi->n_direct_buckets); } -static bool use_pool(void) { - static int b = -1; - - if (!is_main_thread()) - return false; - - if (b < 0) - b = getenv_bool("SYSTEMD_MEMPOOL") != 0; - - return b; -} - static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enum HashmapType type HASHMAP_DEBUG_PARAMS) { HashmapBase *h; const struct hashmap_type_info *hi = &hashmap_type_info[type]; - bool up; + bool use_pool; - up = use_pool(); + use_pool = is_main_thread(); + + h = use_pool ? mempool_alloc0_tile(hi->mempool) : malloc0(hi->head_size); - h = up ? mempool_alloc0_tile(hi->mempool) : malloc0(hi->head_size); if (!h) return NULL; h->type = type; - h->from_pool = up; + h->from_pool = use_pool; h->hash_ops = hash_ops ? hash_ops : &trivial_hash_ops; if (type == HASHMAP_TYPE_ORDERED) { @@ -871,11 +862,9 @@ static void hashmap_free_no_clear(HashmapBase *h) { assert_se(pthread_mutex_unlock(&hashmap_debug_list_mutex) == 0); #endif - if (h->from_pool) { - /* Ensure that the object didn't get migrated between threads. */ - assert_se(is_main_thread()); + if (h->from_pool) mempool_free_tile(hashmap_type_info[h->type].mempool, h); - } else + else free(h); } diff --git a/src/systemd/src/basic/hashmap.h b/src/systemd/src/basic/hashmap.h index 274afb39..d1d1b9c8 100644 --- a/src/systemd/src/basic/hashmap.h +++ b/src/systemd/src/basic/hashmap.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +/*** + Copyright © 2014 Michal Schmidt +***/ + #include <limits.h> #include <stdbool.h> #include <stddef.h> diff --git a/src/systemd/src/basic/in-addr-util.c b/src/systemd/src/basic/in-addr-util.c index 19d0db25..d945567a 100644 --- a/src/systemd/src/basic/in-addr-util.c +++ b/src/systemd/src/basic/in-addr-util.c @@ -576,27 +576,4 @@ int in_addr_prefix_from_string_auto( return 0; } - -void in_addr_data_hash_func(const void *p, struct siphash *state) { - const struct in_addr_data *a = p; - - siphash24_compress(&a->family, sizeof(a->family), state); - siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state); -} - -int in_addr_data_compare_func(const void *a, const void *b) { - const struct in_addr_data *x = a, *y = b; - int r; - - r = CMP(x->family, y->family); - if (r != 0) - return r; - - return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family)); -} - -const struct hash_ops in_addr_data_hash_ops = { - .hash = in_addr_data_hash_func, - .compare = in_addr_data_compare_func, -}; #endif /* NM_IGNORED */ diff --git a/src/systemd/src/basic/in-addr-util.h b/src/systemd/src/basic/in-addr-util.h index e4be30dc..956c00a8 100644 --- a/src/systemd/src/basic/in-addr-util.h +++ b/src/systemd/src/basic/in-addr-util.h @@ -5,7 +5,6 @@ #include <stddef.h> #include <sys/socket.h> -#include "hash-funcs.h" #include "macro.h" #include "util.h" @@ -54,7 +53,3 @@ static inline size_t FAMILY_ADDRESS_SIZE(int family) { } #define IN_ADDR_NULL ((union in_addr_union) {}) - -void in_addr_data_hash_func(const void *p, struct siphash *state); -int in_addr_data_compare_func(const void *a, const void *b); -extern const struct hash_ops in_addr_data_hash_ops; diff --git a/src/systemd/src/basic/macro.h b/src/systemd/src/basic/macro.h index 22193fe3..cdb54f82 100644 --- a/src/systemd/src/basic/macro.h +++ b/src/systemd/src/basic/macro.h @@ -7,7 +7,7 @@ #include <sys/sysmacros.h> #include <sys/types.h> -#define _printf_(a, b) __attribute__ ((format (printf, a, b))) +#define _printf_(a,b) __attribute__ ((format (printf, a, b))) #ifdef __clang__ # define _alloc_(...) #else @@ -22,8 +22,8 @@ #define _packed_ __attribute__ ((packed)) #define _malloc_ __attribute__ ((malloc)) #define _weak_ __attribute__ ((weak)) -#define _likely_(x) (__builtin_expect(!!(x), 1)) -#define _unlikely_(x) (__builtin_expect(!!(x), 0)) +#define _likely_(x) (__builtin_expect(!!(x),1)) +#define _unlikely_(x) (__builtin_expect(!!(x),0)) #define _public_ __attribute__ ((visibility("default"))) #define _hidden_ __attribute__ ((visibility("hidden"))) #define _weakref_(x) __attribute__((weakref(#x))) @@ -155,10 +155,10 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { # define VOID_0 ((void*)0) #endif -#define ELEMENTSOF(x) \ - (__builtin_choose_expr( \ +#define ELEMENTSOF(x) \ + __extension__ (__builtin_choose_expr( \ !__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \ - sizeof(x)/sizeof((x)[0]), \ + sizeof(x)/sizeof((x)[0]), \ VOID_0)) /* @@ -176,23 +176,23 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { */ #define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member) #define __container_of(uniq, ptr, type, member) \ - ({ \ + __extension__ ({ \ const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \ - (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type, member) ); \ + (type*)( (char *)UNIQ_T(A, uniq) - offsetof(type,member) ); \ }) #undef MAX #define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b)) #define __MAX(aq, a, bq, b) \ - ({ \ + __extension__ ({ \ const typeof(a) UNIQ_T(A, aq) = (a); \ const typeof(b) UNIQ_T(B, bq) = (b); \ - UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \ + UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \ }) /* evaluates to (void) if _A or _B are not constant or of different types */ #define CONST_MAX(_A, _B) \ - (__builtin_choose_expr( \ + __extension__ (__builtin_choose_expr( \ __builtin_constant_p(_A) && \ __builtin_constant_p(_B) && \ __builtin_types_compatible_p(typeof(_A), typeof(_B)), \ @@ -202,56 +202,47 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { /* takes two types and returns the size of the larger one */ #define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; })) -#define MAX3(x, y, z) \ - ({ \ - const typeof(x) _c = MAX(x, y); \ - MAX(_c, z); \ - }) +#define MAX3(x,y,z) \ + __extension__ ({ \ + const typeof(x) _c = MAX(x,y); \ + MAX(_c, z); \ + }) #undef MIN #define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b)) #define __MIN(aq, a, bq, b) \ - ({ \ + __extension__ ({ \ const typeof(a) UNIQ_T(A, aq) = (a); \ const typeof(b) UNIQ_T(B, bq) = (b); \ - UNIQ_T(A, aq) < UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \ + UNIQ_T(A,aq) < UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \ }) -#define MIN3(x, y, z) \ - ({ \ - const typeof(x) _c = MIN(x, y); \ - MIN(_c, z); \ - }) +#define MIN3(x,y,z) \ + __extension__ ({ \ + const typeof(x) _c = MIN(x,y); \ + MIN(_c, z); \ + }) #define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b)) #define __LESS_BY(aq, a, bq, b) \ - ({ \ - const typeof(a) UNIQ_T(A, aq) = (a); \ - const typeof(b) UNIQ_T(B, bq) = (b); \ - UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) - UNIQ_T(B, bq) : 0; \ - }) - -#define CMP(a, b) __CMP(UNIQ, (a), UNIQ, (b)) -#define __CMP(aq, a, bq, b) \ - ({ \ + __extension__ ({ \ const typeof(a) UNIQ_T(A, aq) = (a); \ const typeof(b) UNIQ_T(B, bq) = (b); \ - UNIQ_T(A, aq) < UNIQ_T(B, bq) ? -1 : \ - UNIQ_T(A, aq) > UNIQ_T(B, bq) ? 1 : 0; \ + UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) - UNIQ_T(B,bq) : 0; \ }) #undef CLAMP #define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high)) #define __CLAMP(xq, x, lowq, low, highq, high) \ - ({ \ - const typeof(x) UNIQ_T(X, xq) = (x); \ - const typeof(low) UNIQ_T(LOW, lowq) = (low); \ - const typeof(high) UNIQ_T(HIGH, highq) = (high); \ - UNIQ_T(X, xq) > UNIQ_T(HIGH, highq) ? \ - UNIQ_T(HIGH, highq) : \ - UNIQ_T(X, xq) < UNIQ_T(LOW, lowq) ? \ - UNIQ_T(LOW, lowq) : \ - UNIQ_T(X, xq); \ + __extension__ ({ \ + const typeof(x) UNIQ_T(X,xq) = (x); \ + const typeof(low) UNIQ_T(LOW,lowq) = (low); \ + const typeof(high) UNIQ_T(HIGH,highq) = (high); \ + UNIQ_T(X,xq) > UNIQ_T(HIGH,highq) ? \ + UNIQ_T(HIGH,highq) : \ + UNIQ_T(X,xq) < UNIQ_T(LOW,lowq) ? \ + UNIQ_T(LOW,lowq) : \ + UNIQ_T(X,xq); \ }) /* [(x + y - 1) / y] suffers from an integer overflow, even though the @@ -259,54 +250,18 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { * [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the * quotient and the remainder, so both should be equally fast. */ #define DIV_ROUND_UP(_x, _y) \ - ({ \ + __extension__ ({ \ const typeof(_x) __x = (_x); \ const typeof(_y) __y = (_y); \ (__x / __y + !!(__x % __y)); \ }) -#ifdef __COVERITY__ - -/* Use special definitions of assertion macros in order to prevent - * false positives of ASSERT_SIDE_EFFECT on Coverity static analyzer - * for uses of assert_se() and assert_return(). - * - * These definitions make expression go through a (trivial) function - * call to ensure they are not discarded. Also use ! or !! to ensure - * the boolean expressions are seen as such. - * - * This technique has been described and recommended in: - * https://community.synopsys.com/s/question/0D534000046Yuzb/suppressing-assertsideeffect-for-functions-that-allow-for-sideeffects - */ - -extern void __coverity_panic__(void); - -static inline int __coverity_check__(int condition) { - return condition; -} - -#define assert_message_se(expr, message) \ - do { \ - if (__coverity_check__(!(expr))) \ - __coverity_panic__(); \ - } while (false) - -#define assert_log(expr, message) __coverity_check__(!!(expr)) - -#else /* ! __COVERITY__ */ - #define assert_message_se(expr, message) \ do { \ if (_unlikely_(!(expr))) \ log_assert_failed(message, __FILE__, __LINE__, __PRETTY_FUNCTION__); \ } while (false) -#define assert_log(expr, message) ((_likely_(expr)) \ - ? (true) \ - : (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false)) - -#endif /* __COVERITY__ */ - #define assert_se(expr) assert_message_se(expr, #expr) /* We override the glibc assert() here. */ @@ -339,6 +294,10 @@ static inline int __coverity_check__(int condition) { REENABLE_WARNING #endif +#define assert_log(expr, message) ((_likely_(expr)) \ + ? (true) \ + : (log_assert_failed_return(message, __FILE__, __LINE__, __PRETTY_FUNCTION__), false)) + #define assert_return(expr, r) \ do { \ if (!assert_log(expr, #expr)) \ @@ -460,7 +419,7 @@ static inline int __coverity_check__(int condition) { * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__ * see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 */ -#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16)) #define thread_local _Thread_local #else #define thread_local __thread diff --git a/src/systemd/src/basic/mempool.c b/src/systemd/src/basic/mempool.c index dd1b1e5f..a0154263 100644 --- a/src/systemd/src/basic/mempool.c +++ b/src/systemd/src/basic/mempool.c @@ -1,4 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright © 2014 Michal Schmidt +***/ #include "nm-sd-adapt.h" diff --git a/src/systemd/src/basic/mempool.h b/src/systemd/src/basic/mempool.h index 4098535c..291415de 100644 --- a/src/systemd/src/basic/mempool.h +++ b/src/systemd/src/basic/mempool.h @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +/*** + Copyright © 2014 Michal Schmidt +***/ + #include <stddef.h> struct pool; diff --git a/src/systemd/src/basic/parse-util.c b/src/systemd/src/basic/parse-util.c index b0ccce28..7d6bcb5a 100644 --- a/src/systemd/src/basic/parse-util.c +++ b/src/systemd/src/basic/parse-util.c @@ -642,8 +642,6 @@ int parse_permille_unbounded(const char *p) { r = safe_atoi(n, &v); if (r < 0) return r; - if (v < 0) - return -ERANGE; } else { pc = endswith(p, "%"); if (!pc) @@ -664,14 +662,15 @@ int parse_permille_unbounded(const char *p) { r = safe_atoi(n, &v); if (r < 0) return r; - if (v < 0) - return -ERANGE; if (v > (INT_MAX - q) / 10) return -ERANGE; v = v * 10 + q; } + if (v < 0) + return -ERANGE; + return v; } diff --git a/src/systemd/src/basic/path-util.c b/src/systemd/src/basic/path-util.c index 5202eae3..69bdb894 100644 --- a/src/systemd/src/basic/path-util.c +++ b/src/systemd/src/basic/path-util.c @@ -113,7 +113,10 @@ int path_make_absolute_cwd(const char *p, char **ret) { if (r < 0) return r; - c = path_join(NULL, cwd, p); + if (endswith(cwd, "/")) + c = strjoin(cwd, p); + else + c = strjoin(cwd, "/", p); } if (!c) return -ENOMEM; @@ -423,7 +426,6 @@ char* path_startswith(const char *path, const char *prefix) { prefix += b; } } -#endif /* NM_IGNORED */ int path_compare(const char *a, const char *b) { int d; @@ -475,7 +477,6 @@ bool path_equal(const char *a, const char *b) { return path_compare(a, b) == 0; } -#if 0 /* NM_IGNORED */ bool path_equal_or_files_same(const char *a, const char *b, int flags) { return path_equal(a, b) || files_same(a, b, flags) > 0; } diff --git a/src/systemd/src/basic/path-util.h b/src/systemd/src/basic/path-util.h index 72f3ce36..519060cf 100644 --- a/src/systemd/src/basic/path-util.h +++ b/src/systemd/src/basic/path-util.h @@ -60,10 +60,10 @@ static inline bool path_equal_ptr(const char *a, const char *b) { /* Note: the search terminates on the first NULL item. */ #define PATH_IN_SET(p, ...) \ ({ \ - char **_s; \ + char **s; \ bool _found = false; \ - STRV_FOREACH(_s, STRV_MAKE(__VA_ARGS__)) \ - if (path_equal(p, *_s)) { \ + STRV_FOREACH(s, STRV_MAKE(__VA_ARGS__)) \ + if (path_equal(p, *s)) { \ _found = true; \ break; \ } \ diff --git a/src/systemd/src/basic/process-util.c b/src/systemd/src/basic/process-util.c index 1412f036..10aa0e56 100644 --- a/src/systemd/src/basic/process-util.c +++ b/src/systemd/src/basic/process-util.c @@ -1115,7 +1115,12 @@ int pid_compare_func(const void *a, const void *b) { const pid_t *p = a, *q = b; /* Suitable for usage in qsort() */ - return CMP(*p, *q); + + if (*p < *q) + return -1; + if (*p > *q) + return 1; + return 0; } int ioprio_parse_priority(const char *s, int *ret) { @@ -1156,7 +1161,7 @@ void reset_cached_pid(void) { /* We use glibc __register_atfork() + __dso_handle directly here, as they are not included in the glibc * headers. __register_atfork() is mostly equivalent to pthread_atfork(), but doesn't require us to link against * libpthread, as it is part of glibc anyway. */ -extern int __register_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void), void *dso_handle); +extern int __register_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void), void * __dso_handle); extern void* __dso_handle __attribute__ ((__weak__)); pid_t getpid_cached(void) { diff --git a/src/systemd/src/basic/random-util.c b/src/systemd/src/basic/random-util.c index 5c07e067..01a8488f 100644 --- a/src/systemd/src/basic/random-util.c +++ b/src/systemd/src/basic/random-util.c @@ -2,10 +2,6 @@ #include "nm-sd-adapt.h" -#ifdef __x86_64__ -#include <cpuid.h> -#endif - #include <elf.h> #include <errno.h> #include <fcntl.h> @@ -32,41 +28,6 @@ #include "random-util.h" #include "time-util.h" - -int rdrand64(uint64_t *ret) { - -#ifdef __x86_64__ - static int have_rdrand = -1; - unsigned char err; - - if (have_rdrand < 0) { - uint32_t eax, ebx, ecx, edx; - - /* Check if RDRAND is supported by the CPU */ - if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0) { - have_rdrand = false; - return -EOPNOTSUPP; - } - - have_rdrand = !!(ecx & (1U << 30)); - } - - if (have_rdrand == 0) - return -EOPNOTSUPP; - - asm volatile("rdrand %0;" - "setc %1" - : "=r" (*ret), - "=qm" (err)); - if (!err) - return -EAGAIN; - - return 0; -#else - return -EOPNOTSUPP; -#endif -} - int acquire_random_bytes(void *p, size_t n, bool high_quality_required) { static int have_syscall = -1; @@ -116,26 +77,8 @@ int acquire_random_bytes(void *p, size_t n, bool high_quality_required) { * a best-effort basis. */ have_syscall = true; - if (!high_quality_required) { - uint64_t u; - size_t k; - - /* Try x86-64' RDRAND intrinsic if we have it. We only use it if high quality - * randomness is not required, as we don't trust it (who does?). Note that we only do a - * single iteration of RDRAND here, even though the Intel docs suggest calling this in - * a tight loop of 10 invocatins or so. That's because we don't really care about the - * quality here. */ - - if (rdrand64(&u) < 0) - return -ENODATA; - - k = MIN(n, sizeof(u)); - memcpy(p, &u, k); - - /* We only get 64bit out of RDRAND, the rest let's fill up with pseudo-random crap. */ - pseudorandom_bytes((uint8_t*) p + k, n - k); - return 0; - } + if (!high_quality_required) + return -ENODATA; } else return -errno; } diff --git a/src/systemd/src/basic/random-util.h b/src/systemd/src/basic/random-util.h index affcc9ac..9a103f0e 100644 --- a/src/systemd/src/basic/random-util.h +++ b/src/systemd/src/basic/random-util.h @@ -21,5 +21,3 @@ static inline uint32_t random_u32(void) { random_bytes(&u, sizeof(u)); return u; } - -int rdrand64(uint64_t *ret); diff --git a/src/systemd/src/basic/socket-util.c b/src/systemd/src/basic/socket-util.c index acc22901..a71db5a7 100644 --- a/src/systemd/src/basic/socket-util.c +++ b/src/systemd/src/basic/socket-util.c @@ -53,8 +53,7 @@ static const char* const socket_address_type_table[] = { DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int); int socket_address_parse(SocketAddress *a, const char *s) { - _cleanup_free_ char *n = NULL; - char *e; + char *e, *n; int r; assert(a); @@ -72,9 +71,7 @@ int socket_address_parse(SocketAddress *a, const char *s) { if (!e) return -EINVAL; - n = strndup(s+1, e-s-1); - if (!n) - return -ENOMEM; + n = strndupa(s+1, e-s-1); errno = 0; if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0) @@ -131,10 +128,7 @@ int socket_address_parse(SocketAddress *a, const char *s) { if (r < 0) return r; - n = strndup(cid_start, e - cid_start); - if (!n) - return -ENOMEM; - + n = strndupa(cid_start, e - cid_start); if (!isempty(n)) { r = safe_atou(n, &a->sockaddr.vm.svm_cid); if (r < 0) @@ -155,9 +149,7 @@ int socket_address_parse(SocketAddress *a, const char *s) { if (r < 0) return r; - n = strndup(s, e-s); - if (!n) - return -ENOMEM; + n = strndupa(s, e-s); /* IPv4 in w.x.y.z:p notation? */ r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr); @@ -1014,10 +1006,9 @@ int getpeergroups(int fd, gid_t **ret) { return (int) n; } -ssize_t send_one_fd_iov_sa( +int send_one_fd_sa( int transport_fd, int fd, - struct iovec *iov, size_t iovlen, const struct sockaddr *sa, socklen_t len, int flags) { @@ -1028,58 +1019,28 @@ ssize_t send_one_fd_iov_sa( struct msghdr mh = { .msg_name = (struct sockaddr*) sa, .msg_namelen = len, - .msg_iov = iov, - .msg_iovlen = iovlen, + .msg_control = &control, + .msg_controllen = sizeof(control), }; - ssize_t k; + struct cmsghdr *cmsg; assert(transport_fd >= 0); + assert(fd >= 0); - /* - * We need either an FD or data to send. - * If there's nothing, return an error. - */ - if (fd < 0 && !iov) - return -EINVAL; - - if (fd >= 0) { - struct cmsghdr *cmsg; - - mh.msg_control = &control; - mh.msg_controllen = sizeof(control); - - cmsg = CMSG_FIRSTHDR(&mh); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); - - mh.msg_controllen = CMSG_SPACE(sizeof(int)); - } - k = sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags); - if (k < 0) - return (ssize_t) -errno; - - return k; -} + cmsg = CMSG_FIRSTHDR(&mh); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + memcpy(CMSG_DATA(cmsg), &fd, sizeof(int)); -int send_one_fd_sa( - int transport_fd, - int fd, - const struct sockaddr *sa, socklen_t len, - int flags) { - - assert(fd >= 0); + mh.msg_controllen = CMSG_SPACE(sizeof(int)); + if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0) + return -errno; - return (int) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, sa, len, flags); + return 0; } -ssize_t receive_one_fd_iov( - int transport_fd, - struct iovec *iov, size_t iovlen, - int flags, - int *ret_fd) { - +int receive_one_fd(int transport_fd, int flags) { union { struct cmsghdr cmsghdr; uint8_t buf[CMSG_SPACE(sizeof(int))]; @@ -1087,14 +1048,10 @@ ssize_t receive_one_fd_iov( struct msghdr mh = { .msg_control = &control, .msg_controllen = sizeof(control), - .msg_iov = iov, - .msg_iovlen = iovlen, }; struct cmsghdr *cmsg, *found = NULL; - ssize_t k; assert(transport_fd >= 0); - assert(ret_fd); /* * Receive a single FD via @transport_fd. We don't care for @@ -1104,9 +1061,8 @@ ssize_t receive_one_fd_iov( * combination with send_one_fd(). */ - k = recvmsg(transport_fd, &mh, MSG_CMSG_CLOEXEC | flags); - if (k < 0) - return (ssize_t) -errno; + if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0) + return -errno; CMSG_FOREACH(cmsg, &mh) { if (cmsg->cmsg_level == SOL_SOCKET && @@ -1118,33 +1074,12 @@ ssize_t receive_one_fd_iov( } } - if (!found) + if (!found) { cmsg_close_all(&mh); - - /* If didn't receive an FD or any data, return an error. */ - if (k == 0 && !found) return -EIO; + } - if (found) - *ret_fd = *(int*) CMSG_DATA(found); - else - *ret_fd = -1; - - return k; -} - -int receive_one_fd(int transport_fd, int flags) { - int fd; - ssize_t k; - - k = receive_one_fd_iov(transport_fd, NULL, 0, flags, &fd); - if (k == 0) - return fd; - - /* k must be negative, since receive_one_fd_iov() only returns - * a positive value if data was received through the iov. */ - assert(k < 0); - return (int) k; + return *(int*) CMSG_DATA(found); } #endif /* NM_IGNORED */ diff --git a/src/systemd/src/basic/socket-util.h b/src/systemd/src/basic/socket-util.h index d7b814ae..e2db795a 100644 --- a/src/systemd/src/basic/socket-util.h +++ b/src/systemd/src/basic/socket-util.h @@ -132,19 +132,11 @@ int getpeercred(int fd, struct ucred *ucred); int getpeersec(int fd, char **ret); int getpeergroups(int fd, gid_t **ret); -ssize_t send_one_fd_iov_sa( - int transport_fd, - int fd, - struct iovec *iov, size_t iovlen, - const struct sockaddr *sa, socklen_t len, - int flags); int send_one_fd_sa(int transport_fd, int fd, const struct sockaddr *sa, socklen_t len, int flags); -#define send_one_fd_iov(transport_fd, fd, iov, iovlen, flags) send_one_fd_iov_sa(transport_fd, fd, iov, iovlen, NULL, 0, flags) -#define send_one_fd(transport_fd, fd, flags) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, NULL, 0, flags) -ssize_t receive_one_fd_iov(int transport_fd, struct iovec *iov, size_t iovlen, int flags, int *ret_fd); +#define send_one_fd(transport_fd, fd, flags) send_one_fd_sa(transport_fd, fd, NULL, 0, flags) int receive_one_fd(int transport_fd, int flags); ssize_t next_datagram_size_fd(int fd); diff --git a/src/systemd/src/basic/stat-util.c b/src/systemd/src/basic/stat-util.c index d645ce30..9892d8bc 100644 --- a/src/systemd/src/basic/stat-util.c +++ b/src/systemd/src/basic/stat-util.c @@ -48,17 +48,6 @@ int is_dir(const char* path, bool follow) { return !!S_ISDIR(st.st_mode); } -int is_dir_fd(int fd) { - struct stat st; - int r; - - r = fstat(fd, &st); - if (r < 0) - return -errno; - - return !!S_ISDIR(st.st_mode); -} - int is_device_node(const char *path) { struct stat info; diff --git a/src/systemd/src/basic/stat-util.h b/src/systemd/src/basic/stat-util.h index 1a725f1d..f8014ed3 100644 --- a/src/systemd/src/basic/stat-util.h +++ b/src/systemd/src/basic/stat-util.h @@ -12,7 +12,6 @@ int is_symlink(const char *path); int is_dir(const char *path, bool follow); -int is_dir_fd(int fd); int is_device_node(const char *path); int dir_is_empty(const char *path); diff --git a/src/systemd/src/basic/strv.c b/src/systemd/src/basic/strv.c index 6f80b317..9da8cece 100644 --- a/src/systemd/src/basic/strv.c +++ b/src/systemd/src/basic/strv.c @@ -255,10 +255,6 @@ char **strv_split(const char *s, const char *separator) { assert(s); - s += strspn(s, separator); - if (isempty(s)) - return new0(char*, 1); - n = 0; FOREACH_WORD_SEPARATOR(word, l, s, separator, state) n++; diff --git a/src/systemd/src/basic/time-util.c b/src/systemd/src/basic/time-util.c index c0f53a47..aafa0375 100644 --- a/src/systemd/src/basic/time-util.c +++ b/src/systemd/src/basic/time-util.c @@ -2,7 +2,6 @@ #include "nm-sd-adapt.h" -#include <ctype.h> #include <errno.h> #include <limits.h> #include <stdlib.h> @@ -1002,10 +1001,10 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) { } for (;;) { - usec_t multiplier = default_unit, k; long long l, z = 0; - unsigned n = 0; char *e; + unsigned n = 0; + usec_t multiplier = default_unit, k; p += strspn(p, WHITESPACE); @@ -1016,9 +1015,6 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) { break; } - if (*p == '-') /* Don't allow "-0" */ - return -ERANGE; - errno = 0; l = strtoll(p, &e, 10); if (errno > 0) @@ -1029,16 +1025,14 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit) { if (*e == '.') { char *b = e + 1; - /* Don't allow "0.-0", "3.+1" or "3. 1" */ - if (*b == '-' || *b == '+' || isspace(*b)) - return -EINVAL; - errno = 0; z = strtoll(b, &e, 10); if (errno > 0) return -errno; + if (z < 0) return -ERANGE; + if (e == b) return -EINVAL; @@ -1155,28 +1149,26 @@ int parse_nsec(const char *t, nsec_t *nsec) { break; } - if (*p == '-') - return -ERANGE; - errno = 0; l = strtoll(p, &e, 10); + if (errno > 0) return -errno; + if (l < 0) return -ERANGE; if (*e == '.') { char *b = e + 1; - if (*b == '-' || *b == '+' || isspace(*b)) - return -EINVAL; - errno = 0; z = strtoll(b, &e, 10); if (errno > 0) return -errno; + if (z < 0) return -ERANGE; + if (e == b) return -EINVAL; diff --git a/src/systemd/src/basic/utf8.c b/src/systemd/src/basic/utf8.c index 7238bca7..80de43c5 100644 --- a/src/systemd/src/basic/utf8.c +++ b/src/systemd/src/basic/utf8.c @@ -1,4 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright © 2008-2011 Kay Sievers +***/ /* Parts of this file are based on the GLIB utf8 validation functions. The * original license text follows. */ diff --git a/src/systemd/src/basic/util.c b/src/systemd/src/basic/util.c index 2c6101ea..ba7474f0 100644 --- a/src/systemd/src/basic/util.c +++ b/src/systemd/src/basic/util.c @@ -82,6 +82,31 @@ bool display_is_local(const char *display) { display[1] <= '9'; } +int socket_from_display(const char *display, char **path) { + size_t k; + char *f, *c; + + assert(display); + assert(path); + + if (!display_is_local(display)) + return -EINVAL; + + k = strspn(display+1, "0123456789"); + + f = new(char, STRLEN("/tmp/.X11-unix/X") + k + 1); + if (!f) + return -ENOMEM; + + c = stpcpy(f, "/tmp/.X11-unix/X"); + memcpy(c, display+1, k); + c[k] = 0; + + *path = f; + + return 0; +} + bool kexec_loaded(void) { _cleanup_free_ char *s = NULL; @@ -235,11 +260,6 @@ int container_get_leader(const char *machine, pid_t *pid) { assert(machine); assert(pid); - if (streq(machine, ".host")) { - *pid = 1; - return 0; - } - if (!machine_name_is_valid(machine)) return -EINVAL; diff --git a/src/systemd/src/basic/util.h b/src/systemd/src/basic/util.h index 308933ac..9699d228 100644 --- a/src/systemd/src/basic/util.h +++ b/src/systemd/src/basic/util.h @@ -50,6 +50,7 @@ static inline const char* enable_disable(bool b) { bool plymouth_running(void); bool display_is_local(const char *display) _pure_; +int socket_from_display(const char *display, char **path); #define NULSTR_FOREACH(i, l) \ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) @@ -112,7 +113,9 @@ static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, int (*com qsort_r(base, nmemb, size, compar, userdata); } -/* Normal memcpy requires src to be nonnull. We do nothing if n is 0. */ +/** + * Normal memcpy requires src to be nonnull. We do nothing if n is 0. + */ static inline void memcpy_safe(void *dst, const void *src, size_t n) { if (n == 0) return; @@ -120,15 +123,6 @@ static inline void memcpy_safe(void *dst, const void *src, size_t n) { memcpy(dst, src, n); } -/* Normal memcmp requires s1 and s2 to be nonnull. We do nothing if n is 0. */ -static inline int memcmp_safe(const void *s1, const void *s2, size_t n) { - if (n == 0) - return 0; - assert(s1); - assert(s2); - return memcmp(s1, s2, n); -} - int on_ac_power(void); #define memzero(x,l) (memset((x), 0, (l))) diff --git a/src/systemd/src/libsystemd-network/arp-util.c b/src/systemd/src/libsystemd-network/arp-util.c index 4fbecb54..1b711c95 100644 --- a/src/systemd/src/libsystemd-network/arp-util.c +++ b/src/systemd/src/libsystemd-network/arp-util.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** Copyright © 2014 Axis Communications AB. All rights reserved. + Copyright © 2015 Tom Gundersen ***/ #include "nm-sd-adapt.h" diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.c b/src/systemd/src/libsystemd-network/dhcp-identifier.c index f18713e8..75357367 100644 --- a/src/systemd/src/libsystemd-network/dhcp-identifier.c +++ b/src/systemd/src/libsystemd-network/dhcp-identifier.c @@ -1,11 +1,11 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright © 2015 Tom Gundersen <teg@jklmen> +***/ #include "nm-sd-adapt.h" -#include <linux/if_infiniband.h> -#include <net/if_arp.h> - -#include "sd-device.h" +#include "libudev.h" #include "sd-id128.h" #include "dhcp-identifier.h" @@ -13,6 +13,7 @@ #include "network-internal.h" #include "siphash24.h" #include "sparse-endian.h" +#include "udev-util.h" #include "virt.h" #if 0 /* NM_IGNORED */ @@ -20,10 +21,8 @@ #include <net/if.h> #endif /* NM_IGNORED */ -#define SYSTEMD_PEN 43793 -#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09) -#define APPLICATION_ID SD_ID128_MAKE(a5,0a,d1,12,bf,60,45,77,a2,fb,74,1a,b1,95,5b,03) -#define USEC_2000 ((usec_t) 946684800000000) /* 2000-01-01 00:00:00 UTC */ +#define SYSTEMD_PEN 43793 +#define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09) int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) { struct duid d; @@ -56,58 +55,6 @@ int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) { return 0; } -#if 0 /* NM_IGNORED */ -int dhcp_identifier_set_duid_llt(struct duid *duid, usec_t t, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len) { - uint16_t time_from_2000y; - - assert(duid); - assert(len); - assert(addr); - - if (arp_type == ARPHRD_ETHER) - assert_return(addr_len == ETH_ALEN, -EINVAL); - else if (arp_type == ARPHRD_INFINIBAND) - assert_return(addr_len == INFINIBAND_ALEN, -EINVAL); - else - return -EINVAL; - - if (t < USEC_2000) - time_from_2000y = 0; - else - time_from_2000y = (uint16_t) (((t - USEC_2000) / USEC_PER_SEC) & 0xffffffff); - - unaligned_write_be16(&duid->type, DUID_TYPE_LLT); - unaligned_write_be16(&duid->llt.htype, arp_type); - unaligned_write_be32(&duid->llt.time, time_from_2000y); - memcpy(duid->llt.haddr, addr, addr_len); - - *len = sizeof(duid->type) + sizeof(duid->llt.htype) + sizeof(duid->llt.time) + addr_len; - - return 0; -} - -int dhcp_identifier_set_duid_ll(struct duid *duid, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len) { - assert(duid); - assert(len); - assert(addr); - - if (arp_type == ARPHRD_ETHER) - assert_return(addr_len == ETH_ALEN, -EINVAL); - else if (arp_type == ARPHRD_INFINIBAND) - assert_return(addr_len == INFINIBAND_ALEN, -EINVAL); - else - return -EINVAL; - - unaligned_write_be16(&duid->type, DUID_TYPE_LL); - unaligned_write_be16(&duid->ll.htype, arp_type); - memcpy(duid->ll.haddr, addr, addr_len); - - *len = sizeof(duid->type) + sizeof(duid->ll.htype) + addr_len; - - return 0; -} -#endif /* NM_IGNORED */ - int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) { sd_id128_t machine_id; uint64_t hash; @@ -126,39 +73,18 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) { *len = sizeof(duid->type) + sizeof(duid->en); /* a bit of snake-oil perhaps, but no need to expose the machine-id - * directly; duid->en.id might not be aligned, so we need to copy */ + directly; duid->en.id might not be aligned, so we need to copy */ hash = htole64(siphash24(&machine_id, sizeof(machine_id), HASH_KEY.bytes)); memcpy(duid->en.id, &hash, sizeof(duid->en.id)); return 0; } -#if 0 /* NM_IGNORED */ -int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len) { - sd_id128_t machine_id; - int r; - - assert(duid); - assert(len); - - r = sd_id128_get_machine_app_specific(APPLICATION_ID, &machine_id); - if (r < 0) - return r; - - unaligned_write_be16(&duid->type, DUID_TYPE_UUID); - memcpy(&duid->raw.data, &machine_id, sizeof(machine_id)); - - *len = sizeof(duid->type) + sizeof(machine_id); - - return 0; -} -#endif - int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id) { #if 0 /* NM_IGNORED */ - /* name is a pointer to memory in the sd_device struct, so must - * have the same scope */ - _cleanup_(sd_device_unrefp) sd_device *device = NULL; + /* name is a pointer to memory in the udev_device struct, so must + have the same scope */ + _cleanup_(udev_device_unrefp) struct udev_device *device = NULL; #else /* NM_IGNORED */ char name_buf[IF_NAMESIZE]; #endif /* NM_IGNORED */ @@ -168,15 +94,17 @@ int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_i #if 0 /* NM_IGNORED */ if (detect_container() <= 0) { /* not in a container, udev will be around */ + _cleanup_(udev_unrefp) struct udev *udev; char ifindex_str[2 + DECIMAL_STR_MAX(int)]; - int initialized, r; + + udev = udev_new(); + if (!udev) + return -ENOMEM; sprintf(ifindex_str, "n%d", ifindex); - if (sd_device_new_from_device_id(&device, ifindex_str) >= 0) { - r = sd_device_get_is_initialized(device, &initialized); - if (r < 0) - return r; - if (!initialized) + device = udev_device_new_from_device_id(udev, ifindex_str); + if (device) { + if (udev_device_get_is_initialized(device) <= 0) /* not yet ready */ return -EBUSY; diff --git a/src/systemd/src/libsystemd-network/dhcp-identifier.h b/src/systemd/src/libsystemd-network/dhcp-identifier.h index 64315d3a..42d4956d 100644 --- a/src/systemd/src/libsystemd-network/dhcp-identifier.h +++ b/src/systemd/src/libsystemd-network/dhcp-identifier.h @@ -1,11 +1,14 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +/*** + Copyright © 2015 Tom Gundersen <teg@jklmen> +***/ + #include "sd-id128.h" #include "macro.h" #include "sparse-endian.h" -#include "time-util.h" #include "unaligned.h" typedef enum DUIDType { @@ -28,18 +31,18 @@ struct duid { union { struct { /* DUID_TYPE_LLT */ - be16_t htype; - be32_t time; + uint16_t htype; + uint32_t time; uint8_t haddr[0]; } _packed_ llt; struct { /* DUID_TYPE_EN */ - be32_t pen; + uint32_t pen; uint8_t id[8]; } _packed_ en; struct { /* DUID_TYPE_LL */ - be16_t htype; + int16_t htype; uint8_t haddr[0]; } _packed_ ll; struct { @@ -53,8 +56,5 @@ struct duid { } _packed_; int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len); -int dhcp_identifier_set_duid_llt(struct duid *duid, usec_t t, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len); -int dhcp_identifier_set_duid_ll(struct duid *duid, const uint8_t *addr, size_t addr_len, uint16_t arp_type, size_t *len); int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len); -int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len); int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id); diff --git a/src/systemd/src/libsystemd-network/dhcp-internal.h b/src/systemd/src/libsystemd-network/dhcp-internal.h index a0f9c229..257a3c2e 100644 --- a/src/systemd/src/libsystemd-network/dhcp-internal.h +++ b/src/systemd/src/libsystemd-network/dhcp-internal.h @@ -3,6 +3,7 @@ /*** Copyright © 2013 Intel Corporation. All rights reserved. + Copyright © 2014 Tom Gundersen ***/ #include <linux/if_packet.h> diff --git a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h index 9d245a90..fabac183 100644 --- a/src/systemd/src/libsystemd-network/dhcp-lease-internal.h +++ b/src/systemd/src/libsystemd-network/dhcp-lease-internal.h @@ -3,6 +3,7 @@ /*** Copyright © 2013 Intel Corporation. All rights reserved. + Copyright © 2014 Tom Gundersen ***/ #include <stdint.h> diff --git a/src/systemd/src/libsystemd-network/dhcp-network.c b/src/systemd/src/libsystemd-network/dhcp-network.c index 80e9577c..90fe29d0 100644 --- a/src/systemd/src/libsystemd-network/dhcp-network.c +++ b/src/systemd/src/libsystemd-network/dhcp-network.c @@ -128,6 +128,8 @@ int dhcp_network_bind_raw_socket(int ifindex, union sockaddr_union *link, const uint8_t *bcast_addr = NULL; uint8_t dhcp_hlen = 0; + assert_return(mac_addr_len > 0, -EINVAL); + if (arp_type == ARPHRD_ETHER) { assert_return(mac_addr_len == ETH_ALEN, -EINVAL); memcpy(ð_mac, mac_addr, ETH_ALEN); diff --git a/src/systemd/src/libsystemd-network/dhcp-packet.c b/src/systemd/src/libsystemd-network/dhcp-packet.c index 8f8acb0d..214aed8e 100644 --- a/src/systemd/src/libsystemd-network/dhcp-packet.c +++ b/src/systemd/src/libsystemd-network/dhcp-packet.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** Copyright © 2013 Intel Corporation. All rights reserved. + Copyright © 2014 Tom Gundersen ***/ #include "nm-sd-adapt.h" diff --git a/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h b/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h index ff0b0f00..dc85c437 100644 --- a/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h +++ b/src/systemd/src/libsystemd-network/dhcp6-lease-internal.h @@ -2,6 +2,7 @@ #pragma once /*** + Copyright © 2014 Tom Gundersen Copyright © 2014-2015 Intel Corporation. All rights reserved. ***/ diff --git a/src/systemd/src/libsystemd-network/lldp-internal.h b/src/systemd/src/libsystemd-network/lldp-internal.h index 328d51f8..e5650988 100644 --- a/src/systemd/src/libsystemd-network/lldp-internal.h +++ b/src/systemd/src/libsystemd-network/lldp-internal.h @@ -1,6 +1,11 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +/*** + Copyright © 2014 Tom Gundersen + Copyright © 2014 Susant Sahani +***/ + #include "sd-event.h" #include "sd-lldp.h" diff --git a/src/systemd/src/libsystemd-network/lldp-neighbor.c b/src/systemd/src/libsystemd-network/lldp-neighbor.c index cd9358a4..c28c9956 100644 --- a/src/systemd/src/libsystemd-network/lldp-neighbor.c +++ b/src/systemd/src/libsystemd-network/lldp-neighbor.c @@ -28,15 +28,22 @@ static int lldp_neighbor_id_compare_func(const void *a, const void *b) { if (r != 0) return r; - r = CMP(x->chassis_id_size, y->chassis_id_size); - if (r != 0) - return r; + if (x->chassis_id_size < y->chassis_id_size) + return -1; + + if (x->chassis_id_size > y->chassis_id_size) + return 1; r = memcmp(x->port_id, y->port_id, MIN(x->port_id_size, y->port_id_size)); if (r != 0) return r; - return CMP(x->port_id_size, y->port_id_size); + if (x->port_id_size < y->port_id_size) + return -1; + if (x->port_id_size > y->port_id_size) + return 1; + + return 0; } const struct hash_ops lldp_neighbor_id_hash_ops = { @@ -47,7 +54,13 @@ const struct hash_ops lldp_neighbor_id_hash_ops = { int lldp_neighbor_prioq_compare_func(const void *a, const void *b) { const sd_lldp_neighbor *x = a, *y = b; - return CMP(x->until, y->until); + if (x->until < y->until) + return -1; + + if (x->until > y->until) + return 1; + + return 0; } _public_ sd_lldp_neighbor *sd_lldp_neighbor_ref(sd_lldp_neighbor *n) { diff --git a/src/systemd/src/libsystemd-network/lldp-network.c b/src/systemd/src/libsystemd-network/lldp-network.c index db779aaa..bc6c20d1 100644 --- a/src/systemd/src/libsystemd-network/lldp-network.c +++ b/src/systemd/src/libsystemd-network/lldp-network.c @@ -1,4 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright © 2014 Tom Gundersen + Copyright © 2014 Susant Sahani +***/ #include "nm-sd-adapt.h" diff --git a/src/systemd/src/libsystemd-network/lldp-network.h b/src/systemd/src/libsystemd-network/lldp-network.h index e4ed2898..1d773acc 100644 --- a/src/systemd/src/libsystemd-network/lldp-network.h +++ b/src/systemd/src/libsystemd-network/lldp-network.h @@ -1,6 +1,11 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +/*** + Copyright © 2014 Tom Gundersen + Copyright © 2014 Susant Sahani +***/ + #include "sd-event.h" int lldp_network_bind_raw_socket(int ifindex); diff --git a/src/systemd/src/libsystemd-network/network-internal.c b/src/systemd/src/libsystemd-network/network-internal.c index 57a59030..308762ee 100644 --- a/src/systemd/src/libsystemd-network/network-internal.c +++ b/src/systemd/src/libsystemd-network/network-internal.c @@ -1,4 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright © 2013 Tom Gundersen <teg@jklm.no> +***/ #include "nm-sd-adapt.h" @@ -26,22 +29,24 @@ #include "util.h" #if 0 /* NM_IGNORED */ -const char *net_get_name(sd_device *device) { +const char *net_get_name(struct udev_device *device) { const char *name, *field; assert(device); /* fetch some persistent data unique (on this machine) to this device */ - FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC") - if (sd_device_get_property_value(device, field, &name) >= 0) + FOREACH_STRING(field, "ID_NET_NAME_ONBOARD", "ID_NET_NAME_SLOT", "ID_NET_NAME_PATH", "ID_NET_NAME_MAC") { + name = udev_device_get_property_value(device, field); + if (name) return name; + } return NULL; } #define HASH_KEY SD_ID128_MAKE(d3,1e,48,fa,90,fe,4b,4c,9d,af,d5,d7,a1,b1,2e,8a) -int net_get_unique_predictable_data(sd_device *device, uint64_t *result) { +int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result) { size_t l, sz = 0; const char *name = NULL; int r; @@ -125,7 +130,7 @@ bool net_match_config(Set *match_mac, if (match_arch && condition_test(match_arch) <= 0) return false; - if (match_mac && (!dev_mac || !set_contains(match_mac, dev_mac))) + if (match_mac && dev_mac && !set_contains(match_mac, dev_mac)) return false; if (!net_condition_test_strv(match_paths, dev_path)) diff --git a/src/systemd/src/libsystemd-network/network-internal.h b/src/systemd/src/libsystemd-network/network-internal.h index 06d61184..ef69e701 100644 --- a/src/systemd/src/libsystemd-network/network-internal.h +++ b/src/systemd/src/libsystemd-network/network-internal.h @@ -1,14 +1,18 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +/*** + Copyright © 2013 Tom Gundersen <teg@jklm.no> +***/ + #include <stdbool.h> -#include "sd-device.h" #include "sd-dhcp-lease.h" #include "condition.h" #include "conf-parser.h" #include "set.h" +#include "udev.h" #define LINK_BRIDGE_PORT_PRIORITY_INVALID 128 #define LINK_BRIDGE_PORT_PRIORITY_MAX 63 @@ -38,11 +42,11 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ifnames); CONFIG_PARSER_PROTOTYPE(config_parse_ifalias); CONFIG_PARSER_PROTOTYPE(config_parse_iaid); CONFIG_PARSER_PROTOTYPE(config_parse_bridge_port_priority); - -int net_get_unique_predictable_data(sd_device *device, uint64_t *result); -const char *net_get_name(sd_device *device); #endif /* NM_IGNORED */ +int net_get_unique_predictable_data(struct udev_device *device, uint64_t *result); +const char *net_get_name(struct udev_device *device); + void serialize_in_addrs(FILE *f, const struct in_addr *addresses, size_t size); int deserialize_in_addrs(struct in_addr **addresses, const char *string); void serialize_in6_addrs(FILE *f, const struct in6_addr *addresses, diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-client.c b/src/systemd/src/libsystemd-network/sd-dhcp-client.c index 42707f10..c2f81e1c 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-client.c @@ -345,14 +345,13 @@ int sd_dhcp_client_set_client_id( * without further modification. Otherwise, if duid_type is supported, DUID * is set based on that type. Otherwise, an error is returned. */ -static int dhcp_client_set_iaid_duid_internal( +static int dhcp_client_set_iaid_duid( sd_dhcp_client *client, uint32_t iaid, bool append_iaid, uint16_t duid_type, const void *duid, - size_t duid_len, - usec_t llt_time) { + size_t duid_len) { DHCP_CLIENT_DONT_DESTROY(client); int r; @@ -386,43 +385,18 @@ static int dhcp_client_set_iaid_duid_internal( client->client_id.ns.duid.type = htobe16(duid_type); memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len); len = sizeof(client->client_id.ns.duid.type) + duid_len; + } else if (duid_type == DUID_TYPE_EN) { + r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len); + if (r < 0) + return r; } else - switch (duid_type) { - case DUID_TYPE_LLT: - if (!client->mac_addr || client->mac_addr_len == 0) - return -EOPNOTSUPP; - - r = dhcp_identifier_set_duid_llt(&client->client_id.ns.duid, llt_time, client->mac_addr, client->mac_addr_len, client->arp_type, &len); - if (r < 0) - return r; - break; - case DUID_TYPE_EN: - r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len); - if (r < 0) - return r; - break; - case DUID_TYPE_LL: - if (!client->mac_addr || client->mac_addr_len == 0) - return -EOPNOTSUPP; - - r = dhcp_identifier_set_duid_ll(&client->client_id.ns.duid, client->mac_addr, client->mac_addr_len, client->arp_type, &len); - if (r < 0) - return r; - break; - case DUID_TYPE_UUID: - r = dhcp_identifier_set_duid_uuid(&client->client_id.ns.duid, &len); - if (r < 0) - return r; - break; - default: - return -EINVAL; - } + return -EOPNOTSUPP; client->client_id_len = sizeof(client->client_id.type) + len + (append_iaid ? sizeof(client->client_id.ns.iaid) : 0); if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) { - log_dhcp_client(client, "Configured %sDUID, restarting.", append_iaid ? "IAID+" : ""); + log_dhcp_client(client, "Configured IAID+DUID, restarting."); client_stop(client, SD_DHCP_CLIENT_EVENT_STOP); sd_dhcp_client_start(client); } @@ -436,14 +410,7 @@ int sd_dhcp_client_set_iaid_duid( uint16_t duid_type, const void *duid, size_t duid_len) { - return dhcp_client_set_iaid_duid_internal(client, iaid, true, duid_type, duid, duid_len, 0); -} - -int sd_dhcp_client_set_iaid_duid_llt( - sd_dhcp_client *client, - uint32_t iaid, - usec_t llt_time) { - return dhcp_client_set_iaid_duid_internal(client, iaid, true, DUID_TYPE_LLT, NULL, 0, llt_time); + return dhcp_client_set_iaid_duid(client, iaid, true, duid_type, duid, duid_len); } int sd_dhcp_client_set_duid( @@ -451,13 +418,7 @@ int sd_dhcp_client_set_duid( uint16_t duid_type, const void *duid, size_t duid_len) { - return dhcp_client_set_iaid_duid_internal(client, 0, false, duid_type, duid, duid_len, 0); -} - -int sd_dhcp_client_set_duid_llt( - sd_dhcp_client *client, - usec_t llt_time) { - return dhcp_client_set_iaid_duid_internal(client, 0, false, DUID_TYPE_LLT, NULL, 0, llt_time); + return dhcp_client_set_iaid_duid(client, 0, false, duid_type, duid, duid_len); } #endif /* NM_IGNORED */ diff --git a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c index d2402595..33a0796a 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp-lease.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp-lease.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** Copyright © 2013 Intel Corporation. All rights reserved. + Copyright © 2014 Tom Gundersen ***/ #include "nm-sd-adapt.h" @@ -27,7 +28,6 @@ #include "parse-util.h" #include "stdio-util.h" #include "string-util.h" -#include "strv.h" #include "unaligned.h" int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) { diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c index 882a7eb8..ca03f580 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp6-client.c @@ -184,14 +184,13 @@ static int client_ensure_duid(sd_dhcp6_client *client) { * without further modification. Otherwise, if duid_type is supported, DUID * is set based on that type. Otherwise, an error is returned. */ -static int dhcp6_client_set_duid_internal( +int sd_dhcp6_client_set_duid( sd_dhcp6_client *client, uint16_t duid_type, const void *duid, - size_t duid_len, - usec_t llt_time) { - int r; + size_t duid_len) { + int r; assert_return(client, -EINVAL); assert_return(duid_len == 0 || duid != NULL, -EINVAL); assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY); @@ -200,64 +199,23 @@ static int dhcp6_client_set_duid_internal( r = dhcp_validate_duid_len(duid_type, duid_len); if (r < 0) return r; + } + if (duid != NULL) { client->duid.type = htobe16(duid_type); memcpy(&client->duid.raw.data, duid, duid_len); client->duid_len = sizeof(client->duid.type) + duid_len; + } else if (duid_type == DUID_TYPE_EN) { + r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len); + if (r < 0) + return r; } else -#if 0 /* NM_IGNORED */ - switch (duid_type) { - case DUID_TYPE_LLT: - if (!client->mac_addr || client->mac_addr_len == 0) - return -EOPNOTSUPP; - - r = dhcp_identifier_set_duid_llt(&client->duid, 0, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len); - if (r < 0) - return r; - break; - case DUID_TYPE_EN: - r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len); - if (r < 0) - return r; - break; - case DUID_TYPE_LL: - if (!client->mac_addr || client->mac_addr_len == 0) - return -EOPNOTSUPP; - - r = dhcp_identifier_set_duid_ll(&client->duid, client->mac_addr, client->mac_addr_len, client->arp_type, &client->duid_len); - if (r < 0) - return r; - break; - case DUID_TYPE_UUID: - r = dhcp_identifier_set_duid_uuid(&client->duid, &client->duid_len); - if (r < 0) - return r; - break; - default: - return -EINVAL; - } -#else /* NM_IGNORED */ - g_return_val_if_reached (-EINVAL); -#endif /* NM_IGNORED */ + return -EOPNOTSUPP; return 0; } -int sd_dhcp6_client_set_duid( - sd_dhcp6_client *client, - uint16_t duid_type, - const void *duid, - size_t duid_len) { - return dhcp6_client_set_duid_internal(client, duid_type, duid, duid_len, 0); -} - #if 0 /* NM_IGNORED */ -int sd_dhcp6_client_set_duid_llt( - sd_dhcp6_client *client, - usec_t llt_time) { - return dhcp6_client_set_duid_internal(client, DUID_TYPE_LLT, NULL, 0, llt_time); -} - int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid) { assert_return(client, -EINVAL); assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY); @@ -1190,8 +1148,9 @@ static int client_receive_message( return 0; } - log_dhcp6_client(client, "Recv %s", - dhcp6_message_type_to_string(message->type)); + if (r >= 0) + log_dhcp6_client(client, "Recv %s", + dhcp6_message_type_to_string(message->type)); return 0; } diff --git a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c index cca0b500..1c8346d4 100644 --- a/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c +++ b/src/systemd/src/libsystemd-network/sd-dhcp6-lease.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** + Copyright © 2014 Tom Gundersen Copyright © 2014-2015 Intel Corporation. All rights reserved. ***/ diff --git a/src/systemd/src/libsystemd-network/sd-ipv4acd.c b/src/systemd/src/libsystemd-network/sd-ipv4acd.c index a39a865a..3766c1f3 100644 --- a/src/systemd/src/libsystemd-network/sd-ipv4acd.c +++ b/src/systemd/src/libsystemd-network/sd-ipv4acd.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** Copyright © 2014 Axis Communications AB. All rights reserved. + Copyright © 2015 Tom Gundersen ***/ #include "nm-sd-adapt.h" diff --git a/src/systemd/src/libsystemd-network/sd-ipv4ll.c b/src/systemd/src/libsystemd-network/sd-ipv4ll.c index 69fa60e2..ca1e0bdb 100644 --- a/src/systemd/src/libsystemd-network/sd-ipv4ll.c +++ b/src/systemd/src/libsystemd-network/sd-ipv4ll.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ /*** Copyright © 2014 Axis Communications AB. All rights reserved. + Copyright © 2015 Tom Gundersen ***/ #include "nm-sd-adapt.h" diff --git a/src/systemd/src/libsystemd-network/sd-lldp.c b/src/systemd/src/libsystemd-network/sd-lldp.c index 74ba8236..ea1dda4d 100644 --- a/src/systemd/src/libsystemd-network/sd-lldp.c +++ b/src/systemd/src/libsystemd-network/sd-lldp.c @@ -1,4 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + Copyright © 2014 Tom Gundersen + Copyright © 2014 Susant Sahani +***/ #include "nm-sd-adapt.h" diff --git a/src/systemd/src/libsystemd/sd-event/sd-event.c b/src/systemd/src/libsystemd/sd-event/sd-event.c index 2af3572d..f4d5dbe4 100644 --- a/src/systemd/src/libsystemd/sd-event/sd-event.c +++ b/src/systemd/src/libsystemd/sd-event/sd-event.c @@ -1,4 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** +***/ #include "nm-sd-adapt.h" @@ -92,7 +94,7 @@ struct sd_event_source { char *description; EventSourceType type:5; - signed int enabled:3; + int enabled:3; bool pending:1; bool dispatching:1; bool floating:1; diff --git a/src/systemd/src/libsystemd/sd-id128/id128-util.c b/src/systemd/src/libsystemd/sd-id128/id128-util.c index d4d668e8..03a38699 100644 --- a/src/systemd/src/libsystemd/sd-id128/id128-util.c +++ b/src/systemd/src/libsystemd/sd-id128/id128-util.c @@ -1,4 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** +***/ #include "nm-sd-adapt.h" diff --git a/src/systemd/src/libsystemd/sd-id128/id128-util.h b/src/systemd/src/libsystemd/sd-id128/id128-util.h index 44f159c0..f0b4eca5 100644 --- a/src/systemd/src/libsystemd/sd-id128/id128-util.h +++ b/src/systemd/src/libsystemd/sd-id128/id128-util.h @@ -1,6 +1,9 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +/*** +***/ + #include <stdbool.h> #include "sd-id128.h" diff --git a/src/systemd/src/libsystemd/sd-id128/sd-id128.c b/src/systemd/src/libsystemd/sd-id128/sd-id128.c index 483b2fe0..8fe8ff43 100644 --- a/src/systemd/src/libsystemd/sd-id128/sd-id128.c +++ b/src/systemd/src/libsystemd/sd-id128/sd-id128.c @@ -1,4 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** +***/ #include "nm-sd-adapt.h" diff --git a/src/systemd/src/shared/dns-domain.c b/src/systemd/src/shared/dns-domain.c index 048075f2..ab034043 100644 --- a/src/systemd/src/shared/dns-domain.c +++ b/src/systemd/src/shared/dns-domain.c @@ -1,4 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ +/*** + ***/ #include "nm-sd-adapt.h" @@ -512,7 +514,7 @@ int dns_name_compare_func(const void *a, const void *b) { r = dns_label_unescape_suffix(a, &x, la, sizeof(la)); q = dns_label_unescape_suffix(b, &y, lb, sizeof(lb)); if (r < 0 || q < 0) - return CMP(r, q); + return r - q; r = ascii_strcasecmp_nn(la, r, lb, q); if (r != 0) diff --git a/src/systemd/src/shared/dns-domain.h b/src/systemd/src/shared/dns-domain.h index 95f4069c..8781eec6 100644 --- a/src/systemd/src/shared/dns-domain.h +++ b/src/systemd/src/shared/dns-domain.h @@ -1,6 +1,9 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once +/*** + ***/ + #include <errno.h> #include <stdbool.h> #include <stddef.h> diff --git a/src/systemd/src/systemd/_sd-common.h b/src/systemd/src/systemd/_sd-common.h index 4742b2e7..7b54d179 100644 --- a/src/systemd/src/systemd/_sd-common.h +++ b/src/systemd/src/systemd/_sd-common.h @@ -3,6 +3,7 @@ #define foosdcommonhfoo /*** + systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or diff --git a/src/systemd/src/systemd/sd-dhcp-client.h b/src/systemd/src/systemd/sd-dhcp-client.h index e3885520..931b0e89 100644 --- a/src/systemd/src/systemd/sd-dhcp-client.h +++ b/src/systemd/src/systemd/sd-dhcp-client.h @@ -131,18 +131,11 @@ int sd_dhcp_client_set_iaid_duid( uint16_t duid_type, const void *duid, size_t duid_len); -int sd_dhcp_client_set_iaid_duid_llt( - sd_dhcp_client *client, - uint32_t iaid, - uint64_t llt_time); int sd_dhcp_client_set_duid( sd_dhcp_client *client, uint16_t duid_type, const void *duid, size_t duid_len); -int sd_dhcp_client_set_duid_llt( - sd_dhcp_client *client, - uint64_t llt_time); int sd_dhcp_client_get_client_id( sd_dhcp_client *client, uint8_t *type, diff --git a/src/systemd/src/systemd/sd-dhcp-lease.h b/src/systemd/src/systemd/sd-dhcp-lease.h index 2a60145f..16c05661 100644 --- a/src/systemd/src/systemd/sd-dhcp-lease.h +++ b/src/systemd/src/systemd/sd-dhcp-lease.h @@ -4,6 +4,8 @@ /*** Copyright © 2013 Intel Corporation. All rights reserved. + Copyright © 2014 Tom Gundersen + systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or diff --git a/src/systemd/src/systemd/sd-dhcp6-client.h b/src/systemd/src/systemd/sd-dhcp6-client.h index fa36dca9..4f3b2d9e 100644 --- a/src/systemd/src/systemd/sd-dhcp6-client.h +++ b/src/systemd/src/systemd/sd-dhcp6-client.h @@ -102,9 +102,6 @@ int sd_dhcp6_client_set_duid( uint16_t duid_type, const void *duid, size_t duid_len); -int sd_dhcp6_client_set_duid_llt( - sd_dhcp6_client *client, - uint64_t llt_time); int sd_dhcp6_client_set_iaid( sd_dhcp6_client *client, uint32_t iaid); diff --git a/src/systemd/src/systemd/sd-dhcp6-lease.h b/src/systemd/src/systemd/sd-dhcp6-lease.h index 33a32a6d..a673de5e 100644 --- a/src/systemd/src/systemd/sd-dhcp6-lease.h +++ b/src/systemd/src/systemd/sd-dhcp6-lease.h @@ -3,6 +3,7 @@ #define foosddhcp6leasehfoo /*** + Copyright © 2014 Tom Gundersen Copyright © 2014-2015 Intel Corporation. All rights reserved. systemd is free software; you can redistribute it and/or modify it diff --git a/src/systemd/src/systemd/sd-event.h b/src/systemd/src/systemd/sd-event.h index eb35b834..7fcae4ac 100644 --- a/src/systemd/src/systemd/sd-event.h +++ b/src/systemd/src/systemd/sd-event.h @@ -3,6 +3,7 @@ #define foosdeventhfoo /*** + systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or diff --git a/src/systemd/src/systemd/sd-id128.h b/src/systemd/src/systemd/sd-id128.h index 143a0ffb..b24fd06f 100644 --- a/src/systemd/src/systemd/sd-id128.h +++ b/src/systemd/src/systemd/sd-id128.h @@ -3,6 +3,7 @@ #define foosdid128hfoo /*** + systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or diff --git a/src/systemd/src/systemd/sd-ipv4acd.h b/src/systemd/src/systemd/sd-ipv4acd.h index 039ed3c7..259db263 100644 --- a/src/systemd/src/systemd/sd-ipv4acd.h +++ b/src/systemd/src/systemd/sd-ipv4acd.h @@ -4,6 +4,8 @@ /*** Copyright © 2014 Axis Communications AB. All rights reserved. + Copyright © 2015 Tom Gundersen + systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or diff --git a/src/systemd/src/systemd/sd-lldp.h b/src/systemd/src/systemd/sd-lldp.h index d650794c..11a2119a 100644 --- a/src/systemd/src/systemd/sd-lldp.h +++ b/src/systemd/src/systemd/sd-lldp.h @@ -3,6 +3,9 @@ #define foosdlldphfoo /*** + Copyright © 2014 Tom Gundersen + Copyright © 2014 Susant Sahani + systemd is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or diff --git a/src/tests/config/meson.build b/src/tests/config/meson.build index fd6c89b7..f542c453 100644 --- a/src/tests/config/meson.build +++ b/src/tests/config/meson.build @@ -11,6 +11,7 @@ exe = executable( test_unit, sources, dependencies: test_nm_dep, + c_args: nm_build_cflags, ) test( diff --git a/src/tests/test-general-with-expect.c b/src/tests/test-general-with-expect.c index ba8e3ce4..a78b5311 100644 --- a/src/tests/test-general-with-expect.c +++ b/src/tests/test-general-with-expect.c @@ -32,6 +32,10 @@ #include "nm-test-utils-core.h" +#ifndef CLOCK_BOOTTIME +#define CLOCK_BOOTTIME 7 +#endif + /*****************************************************************************/ static void diff --git a/src/tests/test-general.c b/src/tests/test-general.c index 1e7329d1..4db05ac8 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -907,79 +907,6 @@ test_connection_match_ip6_routes (void) g_assert (matched == copy); } -#define do_test_wildcard_match(str, result, ...) \ - g_assert (nm_wildcard_match_check (str, \ - (const char *const[]) { __VA_ARGS__ }, \ - NM_NARG (__VA_ARGS__)) \ - == result); - -static void -test_wildcard_match (void) -{ - do_test_wildcard_match ("foobar", TRUE); - - do_test_wildcard_match ("foo", TRUE, "foo", "bar", "baz"); - do_test_wildcard_match ("bar", TRUE, "foo", "bar", "baz"); - do_test_wildcard_match ("baz", TRUE, "foo", "bar", "baz"); - do_test_wildcard_match ("aaa", FALSE, "foo", "bar", "baz"); - do_test_wildcard_match ("", FALSE, "foo", "bar", "baz"); - - do_test_wildcard_match ("ens1", TRUE, "ens1*"); - do_test_wildcard_match ("ens10", TRUE, "ens1*"); - do_test_wildcard_match ("ens11", TRUE, "ens1*"); - do_test_wildcard_match ("ens12", TRUE, "ens1*"); - do_test_wildcard_match ("eth0", FALSE, "ens1*"); - do_test_wildcard_match ("ens", FALSE, "ens1*"); - - do_test_wildcard_match ("ens1*", TRUE, "ens1\\*"); - do_test_wildcard_match ("ens1" , FALSE, "ens1\\*"); - do_test_wildcard_match ("ens10", FALSE, "ens1\\*"); - - do_test_wildcard_match ("abcd", TRUE, "ab??"); - do_test_wildcard_match ("ab", FALSE, "ab??"); - - do_test_wildcard_match ("ab??", TRUE, "ab\\?\\?"); - do_test_wildcard_match ("abcd", FALSE, "ab\\?\\?"); - - do_test_wildcard_match ("ens10", TRUE, "ens1*", "!ens11"); - do_test_wildcard_match ("ens11", FALSE, "ens1*", "!ens11"); - do_test_wildcard_match ("ens12", TRUE, "ens1*", "!ens11"); - - do_test_wildcard_match ("a", FALSE, "!a", "!b"); - do_test_wildcard_match ("b", FALSE, "!a", "!b"); - do_test_wildcard_match ("c", TRUE, "!a", "!b"); - do_test_wildcard_match ("!a", TRUE, "!a", "!b"); - - do_test_wildcard_match ("!net", TRUE, "\\!net"); - do_test_wildcard_match ("net", FALSE, "\\!net"); - do_test_wildcard_match ("ens10", FALSE, "\\!net"); - do_test_wildcard_match ("\\!net", FALSE, "\\!net"); - - do_test_wildcard_match ("eth0", FALSE, "*eth?", "!veth*", "!*0"); - do_test_wildcard_match ("eth1", TRUE, "*eth?", "!veth*", "!*0"); - do_test_wildcard_match ("myeth0", FALSE, "*eth?", "!veth*", "!*0"); - do_test_wildcard_match ("myeth2", TRUE, "*eth?", "!veth*", "!*0"); - do_test_wildcard_match ("veth0", FALSE, "*eth?", "!veth*", "!*0"); - do_test_wildcard_match ("veth1", FALSE, "*eth?", "!veth*", "!*0"); - do_test_wildcard_match ("dummy1", FALSE, "*eth?", "!veth*", "!*0"); - - do_test_wildcard_match ("a", TRUE, "!!a"); - do_test_wildcard_match ("b", TRUE, "!!a"); - do_test_wildcard_match ("!a", FALSE, "!!a"); - - do_test_wildcard_match ("\\", TRUE, "\\\\"); - do_test_wildcard_match ("\\\\", FALSE, "\\\\"); - do_test_wildcard_match ("", FALSE, "\\\\"); - - do_test_wildcard_match ("name", FALSE, "name[123]"); - do_test_wildcard_match ("name1", TRUE, "name[123]"); - do_test_wildcard_match ("name2", TRUE, "name[123]"); - do_test_wildcard_match ("name3", TRUE, "name[123]"); - do_test_wildcard_match ("name4", FALSE, "name[123]"); - - do_test_wildcard_match ("[a]", TRUE, "\\[a\\]"); -} - static NMConnection * _create_connection_autoconnect (const char *id, gboolean autoconnect, int autoconnect_priority) { @@ -1278,7 +1205,7 @@ test_match_spec_device (void) /*****************************************************************************/ static void -_do_test_match_spec_config (const char *file, int line, const char *spec_str, guint version, guint v_maj, guint v_min, guint v_mic, NMMatchSpecMatchType expected) +_do_test_match_spec_config (const char *file, gint line, const char *spec_str, guint version, guint v_maj, guint v_min, guint v_mic, NMMatchSpecMatchType expected) { GSList *specs; NMMatchSpecMatchType match_result; @@ -1445,7 +1372,7 @@ test_nm_utils_strbuf_append (void) t_buf = buf; t_len = buf_len; - test_mode = nmtst_get_rand_int () % 5; + test_mode = nmtst_get_rand_int () % 4; switch (test_mode) { case 0: @@ -1466,45 +1393,6 @@ test_nm_utils_strbuf_append (void) case 3: nm_utils_strbuf_append (&t_buf, &t_len, "%s", str); break; - case 4: - g_snprintf (t_buf, t_len, "%s", str); - if ( t_len > 0 - && strlen (str) >= buf_len - && (nmtst_get_rand_int () % 2)) { - /* the string was truncated by g_snprintf(). That means, at the last position in the - * buffer is now NUL. - * Replace the NUL by the actual character, and check that nm_utils_strbuf_seek_end() - * does the right thing: NUL terminate the buffer and seek past the end of the buffer. */ - g_assert_cmpmem (t_buf, t_len - 1, str, t_len - 1); - g_assert (t_buf[t_len - 1] == '\0'); - g_assert (str[t_len - 1] != '\0'); - t_buf[t_len - 1] = str[t_len - 1]; - nm_utils_strbuf_seek_end (&t_buf, &t_len); - g_assert (t_len == 0); - g_assert (t_buf == &buf[buf_len]); - g_assert (t_buf[-1] == '\0'); - } else { - nm_utils_strbuf_seek_end (&t_buf, &t_len); - if ( buf_len > 0 - && strlen (str) + 1 > buf_len) { - /* the buffer was truncated by g_snprintf() above. - * - * But nm_utils_strbuf_seek_end() does not recognize that and returns - * a remaining length of 1. - * - * Note that other nm_utils_strbuf_append*() functions recognize - * truncation, and properly set the remaining length to zero. - * As the assertions below check for the behavior of nm_utils_strbuf_append*(), - * we assert here that nm_utils_strbuf_seek_end() behaved as expected, and then - * adjust t_buf/t_len according to the "is-truncated" case. */ - g_assert (t_len == 1); - g_assert (t_buf == &buf[buf_len - 1]); - g_assert (t_buf[0] == '\0'); - t_len = 0; - t_buf++; - } - } - break; } /* Assert that the source-buffer is unmodified. */ @@ -1877,8 +1765,6 @@ main (int argc, char **argv) g_test_add_func ("/general/connection-match/routes/ip4/2", test_connection_match_ip4_routes2); g_test_add_func ("/general/connection-match/routes/ip6", test_connection_match_ip6_routes); - g_test_add_func ("/general/wildcard-match", test_wildcard_match); - g_test_add_func ("/general/connection-sort/autoconnect-priority", test_connection_sort_autoconnect_priority); g_test_add_func ("/general/match-spec/device", test_match_spec_device); diff --git a/src/tests/test-wired-defname.c b/src/tests/test-wired-defname.c index 97a6c319..a966ed21 100644 --- a/src/tests/test-wired-defname.c +++ b/src/tests/test-wired-defname.c @@ -44,14 +44,15 @@ _new_connection (const char *id) static char * _get_default_wired_name (GSList *list) { - gs_unref_hashtable GHashTable *existing_ids = NULL; - - if (list) { - existing_ids = g_hash_table_new (nm_str_hash, g_str_equal); - for (; list; list = list->next) - g_hash_table_add (existing_ids, (char *) nm_connection_get_id (list->data)); - } - return nm_device_ethernet_utils_get_default_wired_name (existing_ids); + gs_free NMConnection **v = NULL; + guint l, i; + + l = g_slist_length (list); + v = g_new0 (NMConnection *, l + 1); + for (i = 0; list; list = list->next, i++) + v[i] = NM_CONNECTION (list->data); + g_assert (i == l); + return nm_device_ethernet_utils_get_default_wired_name (v); } /*****************************************************************************/ diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c index bd847d75..91acf07e 100644 --- a/src/vpn/nm-vpn-connection.c +++ b/src/vpn/nm-vpn-connection.c @@ -193,7 +193,7 @@ static void _set_vpn_state (NMVpnConnection *self, #define __NMLOG_prefix_buf_len 128 static const char * -__LOG_create_prefix (char *buf, NMVpnConnection *self, NMSettingsConnection *con) +__LOG_create_prefix (char *buf, NMVpnConnection *self, NMConnection *con) { NMVpnConnectionPrivate *priv; const char *id; @@ -202,7 +202,7 @@ __LOG_create_prefix (char *buf, NMVpnConnection *self, NMSettingsConnection *con return _NMLOG_PREFIX_NAME; priv = NM_VPN_CONNECTION_GET_PRIVATE (self); - id = con ? nm_settings_connection_get_id (con) : NULL; + id = con ? nm_connection_get_id (con) : NULL; g_snprintf (buf, __NMLOG_prefix_buf_len, "%s[" @@ -214,7 +214,7 @@ __LOG_create_prefix (char *buf, NMVpnConnection *self, NMSettingsConnection *con "]", _NMLOG_PREFIX_NAME, self, - con ? "," : "--", con ? (nm_settings_connection_get_uuid (con) ?: "??") : "", + con ? "," : "--", con ? (nm_connection_get_uuid (con) ?: "??") : "", con ? "," : "", NM_PRINT_FMT_QUOTED (id, "\"", id, "\"", con ? "??" : ""), priv->ip_ifindex, NM_PRINT_FMT_QUOTED (priv->ip_iface, ":(", priv->ip_iface, ")", "") @@ -225,17 +225,17 @@ __LOG_create_prefix (char *buf, NMVpnConnection *self, NMSettingsConnection *con #define _NMLOG(level, ...) \ G_STMT_START { \ - const NMLogLevel _level = (level); \ - NMSettingsConnection *_con = (self) ? _get_settings_connection (self, TRUE) : NULL; \ + const NMLogLevel __level = (level); \ + NMConnection *__con = (self) ? (NMConnection *) _get_settings_connection (self, TRUE) : NULL; \ \ - if (nm_logging_enabled (_level, _NMLOG_DOMAIN)) { \ + if (nm_logging_enabled (__level, _NMLOG_DOMAIN)) { \ char __prefix[__NMLOG_prefix_buf_len]; \ \ - _nm_log (_level, _NMLOG_DOMAIN, 0, \ + _nm_log (__level, _NMLOG_DOMAIN, 0, \ (self) ? NM_VPN_CONNECTION_GET_PRIVATE (self)->ip_iface : NULL, \ - (_con) ? nm_settings_connection_get_uuid (_con) : NULL, \ + (__con) ? nm_connection_get_uuid (__con) : NULL, \ "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ - __LOG_create_prefix (__prefix, (self), _con) \ + __LOG_create_prefix (__prefix, (self), __con) \ _NM_UTILS_MACRO_REST (__VA_ARGS__)); \ } \ } G_STMT_END @@ -1619,7 +1619,6 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) nm_ip4_config_merge_setting (config, s_ip, nm_setting_connection_get_mdns (s_con), - nm_setting_connection_get_llmnr (s_con), route_table, route_metric); @@ -1877,10 +1876,13 @@ connect_success (NMVpnConnection *self) * It is a configured value or 60 seconds */ timeout = nm_setting_vpn_get_timeout (s_vpn); if (timeout == 0) { - timeout = nm_config_data_get_connection_default_int64 (NM_CONFIG_GET_DATA, - "vpn.timeout", - NULL, - 1, G_MAXUINT32, 60); + char *value; + + value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, + "vpn.timeout", NULL); + timeout = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, 60); + timeout = timeout == 0 ? 60 : timeout; + g_free (value); } priv->connect_timeout = g_timeout_add_seconds (timeout, connect_timeout_cb, self); diff --git a/src/vpn/nm-vpn-connection.h b/src/vpn/nm-vpn-connection.h index e409cc31..3046634d 100644 --- a/src/vpn/nm-vpn-connection.h +++ b/src/vpn/nm-vpn-connection.h @@ -59,7 +59,7 @@ void nm_vpn_connection_activate (NMVpnConnection *self, NMVpnPluginInfo *plugin_info); NMVpnConnectionState nm_vpn_connection_get_vpn_state (NMVpnConnection *self); const char * nm_vpn_connection_get_banner (NMVpnConnection *self); -const char * nm_vpn_connection_get_service (NMVpnConnection *self); +const gchar * nm_vpn_connection_get_service (NMVpnConnection *self); gboolean nm_vpn_connection_deactivate (NMVpnConnection *self, NMActiveConnectionStateReason reason, |