diff --git a/src/NetworkManager.c b/src/NetworkManager.c index 6c2834fd81..1b0beab9df 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -405,7 +405,7 @@ main (int argc, char *argv[]) goto done; } - manager = nm_manager_get (plugins, &error); + manager = nm_manager_get (config, plugins, &error); if (manager == NULL) { nm_error ("Failed to initialize the network manager: %s", error && error->message ? error->message : "(unknown)"); diff --git a/src/nm-manager.c b/src/nm-manager.c index ff205b7237..f789b37c16 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -126,6 +126,8 @@ typedef struct { } PendingConnectionInfo; typedef struct { + char *config_file; + GSList *devices; NMState state; @@ -348,11 +350,14 @@ manager_device_state_changed (NMDevice *device, static GSList * remove_one_device (NMManager *manager, GSList *list, NMDevice *device) { + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + if (nm_device_get_managed (device)) nm_device_set_managed (device, FALSE, NM_DEVICE_STATE_REASON_REMOVED); g_signal_handlers_disconnect_by_func (device, manager_device_state_changed, manager); + nm_sysconfig_settings_device_removed (priv->sys_settings, device); g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device); g_object_unref (device); @@ -1179,6 +1184,7 @@ add_device (NMManager *self, NMDevice *device) if (!priv->sleeping && !nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs)) nm_device_set_managed (device, TRUE, NM_DEVICE_STATE_REASON_NOW_MANAGED); + nm_sysconfig_settings_device_added (priv->sys_settings, device); g_signal_emit (self, signals[DEVICE_ADDED], 0, device); } @@ -1260,7 +1266,7 @@ static void bluez_manager_resync_devices (NMManager *self) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); - GSList *iter, *gone = NULL, *keep = NULL;; + GSList *iter, *gone = NULL, *keep = NULL; /* Remove devices from the device list that don't have a corresponding connection */ for (iter = priv->devices; iter; iter = g_slist_next (iter)) { @@ -1279,11 +1285,18 @@ bluez_manager_resync_devices (NMManager *self) } else keep = g_slist_prepend (keep, candidate); } - g_slist_free (priv->devices); - priv->devices = keep; - while (g_slist_length (gone)) - gone = remove_one_device (self, gone, NM_DEVICE (gone->data)); + /* Only touch the device list if anything actually changed */ + if (g_slist_length (gone)) { + g_slist_free (priv->devices); + priv->devices = keep; + + while (g_slist_length (gone)) + gone = remove_one_device (self, gone, NM_DEVICE (gone->data)); + } else { + g_slist_free (keep); + g_slist_free (gone); + } /* Now look for devices without connections */ nm_bluez_manager_query_devices (priv->bluez_mgr); @@ -2408,7 +2421,7 @@ nm_manager_start (NMManager *self) } NMManager * -nm_manager_get (const char *plugins, GError **error) +nm_manager_get (const char *config_file, const char *plugins, GError **error) { static NMManager *singleton = NULL; NMManagerPrivate *priv; @@ -2421,12 +2434,14 @@ nm_manager_get (const char *plugins, GError **error) priv = NM_MANAGER_GET_PRIVATE (singleton); - priv->sys_settings = nm_sysconfig_settings_new (plugins, error); + priv->sys_settings = nm_sysconfig_settings_new (config_file, plugins, error); if (!priv->sys_settings) { g_object_unref (singleton); return NULL; } + priv->config_file = g_strdup (config_file); + g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, G_CALLBACK (system_unmanaged_devices_changed_cb), singleton); g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_HOSTNAME, @@ -2493,9 +2508,11 @@ dispose (GObject *object) free_get_secrets_info (info); } +g_message ("%s: priv->devices %p (length %d)", __func__, priv->devices, g_slist_length (priv->devices)); while (g_slist_length (priv->devices)) { NMDevice *device = NM_DEVICE (priv->devices->data); +g_message ("%s: candidate %p", __func__, device); priv->devices = remove_one_device (manager, priv->devices, device); } @@ -2509,6 +2526,7 @@ dispose (GObject *object) priv->system_connections = NULL; g_free (priv->hostname); + g_free (priv->config_file); if (priv->sys_settings) { g_object_unref (priv->sys_settings); diff --git a/src/nm-manager.h b/src/nm-manager.h index a364f8eb9c..0c6da150d6 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -73,7 +73,7 @@ typedef struct { GType nm_manager_get_type (void); -NMManager *nm_manager_get (const char *plugins, GError **error); +NMManager *nm_manager_get (const char *config_file, const char *plugins, GError **error); void nm_manager_start (NMManager *manager); diff --git a/src/system-settings/nm-default-wired-connection.c b/src/system-settings/nm-default-wired-connection.c index c8a6daab72..d95c1bac86 100644 --- a/src/system-settings/nm-default-wired-connection.c +++ b/src/system-settings/nm-default-wired-connection.c @@ -38,7 +38,7 @@ G_DEFINE_TYPE (NMDefaultWiredConnection, nm_default_wired_connection, NM_TYPE_SY #define NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionPrivate)) typedef struct { - char *iface; + NMDevice *device; GByteArray *mac; gboolean read_only; } NMDefaultWiredConnectionPrivate; @@ -46,7 +46,7 @@ typedef struct { enum { PROP_0, PROP_MAC, - PROP_IFACE, + PROP_DEVICE, PROP_READ_ONLY, LAST_PROP }; @@ -62,21 +62,29 @@ static guint signals[LAST_SIGNAL] = { 0 }; NMDefaultWiredConnection * nm_default_wired_connection_new (const GByteArray *mac, - const char *iface, + NMDevice *device, gboolean read_only) { g_return_val_if_fail (mac != NULL, NULL); g_return_val_if_fail (mac->len == ETH_ALEN, NULL); - g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); return g_object_new (NM_TYPE_DEFAULT_WIRED_CONNECTION, NM_DEFAULT_WIRED_CONNECTION_MAC, mac, - NM_DEFAULT_WIRED_CONNECTION_IFACE, iface, + NM_DEFAULT_WIRED_CONNECTION_DEVICE, device, NM_DEFAULT_WIRED_CONNECTION_READ_ONLY, read_only, NULL); } +NMDevice * +nm_default_wired_connection_get_device (NMDefaultWiredConnection *wired) +{ + g_return_val_if_fail (NM_IS_DEFAULT_WIRED_CONNECTION (wired), NULL); + + return NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (wired)->device; +} + static GByteArray * dup_wired_mac (NMExportedConnection *exported) { @@ -179,7 +187,7 @@ constructor (GType type, s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ()); - id = g_strdup_printf (_("Auto %s"), priv->iface); + id = g_strdup_printf (_("Auto %s"), nm_device_get_iface (priv->device)); uuid = nm_utils_uuid_generate (); g_object_set (s_con, @@ -211,7 +219,7 @@ finalize (GObject *object) { NMDefaultWiredConnectionPrivate *priv = NM_DEFAULT_WIRED_CONNECTION_GET_PRIVATE (object); - g_free (priv->iface); + g_object_unref (priv->device); g_byte_array_free (priv->mac, TRUE); G_OBJECT_CLASS (nm_default_wired_connection_parent_class)->finalize (object); @@ -227,8 +235,8 @@ get_property (GObject *object, guint prop_id, case PROP_MAC: g_value_set_pointer (value, priv->mac); break; - case PROP_IFACE: - g_value_set_string (value, priv->iface); + case PROP_DEVICE: + g_value_set_object (value, priv->device); break; case PROP_READ_ONLY: g_value_set_boolean (value, priv->read_only); @@ -260,9 +268,10 @@ set_property (GObject *object, guint prop_id, g_byte_array_append (priv->mac, array->data, ETH_ALEN); } break; - case PROP_IFACE: - g_free (priv->iface); - priv->iface = g_value_dup_string (value); + case PROP_DEVICE: + if (priv->device) + g_object_unref (priv->device); + priv->device = g_value_dup_object (value); break; case PROP_READ_ONLY: priv->read_only = g_value_get_boolean (value); @@ -313,11 +322,11 @@ nm_default_wired_connection_class_init (NMDefaultWiredConnectionClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property - (object_class, PROP_IFACE, - g_param_spec_string (NM_DEFAULT_WIRED_CONNECTION_IFACE, - "Iface", - "Interface", - NULL, + (object_class, PROP_DEVICE, + g_param_spec_object (NM_DEFAULT_WIRED_CONNECTION_DEVICE, + "Device", + "Device", + NM_TYPE_DEVICE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property diff --git a/src/system-settings/nm-default-wired-connection.h b/src/system-settings/nm-default-wired-connection.h index 50c8b182e1..22a2276d96 100644 --- a/src/system-settings/nm-default-wired-connection.h +++ b/src/system-settings/nm-default-wired-connection.h @@ -24,6 +24,7 @@ #include #include "nm-sysconfig-connection.h" +#include "nm-device.h" G_BEGIN_DECLS @@ -35,7 +36,7 @@ G_BEGIN_DECLS #define NM_DEFAULT_WIRED_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEFAULT_WIRED_CONNECTION, NMDefaultWiredConnectionClass)) #define NM_DEFAULT_WIRED_CONNECTION_MAC "mac" -#define NM_DEFAULT_WIRED_CONNECTION_IFACE "iface" +#define NM_DEFAULT_WIRED_CONNECTION_DEVICE "device" #define NM_DEFAULT_WIRED_CONNECTION_READ_ONLY "read-only" typedef struct { @@ -49,9 +50,11 @@ typedef struct { GType nm_default_wired_connection_get_type (void); NMDefaultWiredConnection *nm_default_wired_connection_new (const GByteArray *mac, - const char *iface, + NMDevice *device, gboolean read_only); +NMDevice *nm_default_wired_connection_get_device (NMDefaultWiredConnection *wired); + G_END_DECLS #endif /* NM_DEFAULT_WIRED_CONNECTION_H */ diff --git a/src/system-settings/nm-sysconfig-settings.c b/src/system-settings/nm-sysconfig-settings.c index 7d139e6e14..99f71c166b 100644 --- a/src/system-settings/nm-sysconfig-settings.c +++ b/src/system-settings/nm-sysconfig-settings.c @@ -26,12 +26,17 @@ #include #include #include +#include +#include #include #include #include #include +#include +#include +#include "../nm-device-ethernet.h" #include "nm-dbus-glib-types.h" #include "nm-sysconfig-settings.h" #include "nm-sysconfig-connection.h" @@ -39,7 +44,9 @@ #include "nm-polkit-helpers.h" #include "nm-system-config-error.h" #include "nm-utils.h" +#include "nm-default-wired-connection.h" +#define CONFIG_KEY_NO_AUTO_DEFAULT "no-auto-default" /* LINKER CRACKROCK */ #define EXPORT(sym) void * __export_##sym = &sym; @@ -67,6 +74,7 @@ static void unmanaged_devices_changed (NMSystemConfigInterface *config, gpointer typedef struct { NMDBusManager *dbus_mgr; PolKitContext *pol_ctx; + char *config_file; GSList *plugins; gboolean connections_loaded; @@ -221,6 +229,7 @@ finalize (GObject *object) g_object_unref (priv->dbus_mgr); g_free (priv->orig_hostname); + g_free (priv->config_file); G_OBJECT_CLASS (nm_sysconfig_settings_parent_class)->finalize (object); } @@ -816,8 +825,312 @@ impl_settings_save_hostname (NMSysconfigSettings *self, } } +static gboolean +have_connection_for_device (NMSysconfigSettings *self, GByteArray *mac) +{ + GSList *list, *iter; + NMSettingConnection *s_con; + NMSettingWired *s_wired; + const GByteArray *setting_mac; + gboolean ret = FALSE; + + g_return_val_if_fail (NM_IS_SYSCONFIG_SETTINGS (self), FALSE); + g_return_val_if_fail (mac != NULL, FALSE); + + /* Find a wired connection locked to the given MAC address, if any */ + list = nm_settings_list_connections (NM_SETTINGS (self)); + for (iter = list; iter; iter = g_slist_next (iter)) { + NMExportedConnection *exported = NM_EXPORTED_CONNECTION (iter->data); + NMConnection *connection; + const char *connection_type; + + connection = nm_exported_connection_get_connection (exported); + if (!connection) + continue; + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + connection_type = nm_setting_connection_get_connection_type (s_con); + + if ( strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME) + && strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) + continue; + + s_wired = (NMSettingWired *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED); + + /* No wired setting; therefore the PPPoE connection applies to any device */ + if (!s_wired && !strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME)) { + ret = TRUE; + break; + } + + setting_mac = nm_setting_wired_get_mac_address (s_wired); + if (setting_mac) { + /* A connection mac-locked to this device */ + if (!memcmp (setting_mac->data, mac->data, ETH_ALEN)) { + ret = TRUE; + break; + } + } else { + /* A connection that applies to any wired device */ + ret = TRUE; + break; + } + } + + g_slist_free (list); + return ret; +} + +/* Search through the list of blacklisted MAC addresses in the config file. */ +static gboolean +is_mac_auto_wired_blacklisted (NMSysconfigSettings *self, const GByteArray *mac) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + GKeyFile *config; + char **list, **iter; + gboolean found = FALSE; + + g_return_val_if_fail (mac != NULL, FALSE); + + if (!priv->config_file) + return FALSE; + + config = g_key_file_new (); + if (!config) { + g_warning ("%s: not enough memory to load config file.", __func__); + return FALSE; + } + + g_key_file_set_list_separator (config, ','); + if (!g_key_file_load_from_file (config, priv->config_file, G_KEY_FILE_NONE, NULL)) + goto out; + + list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, NULL, NULL); + for (iter = list; iter && *iter; iter++) { + struct ether_addr *candidate; + + candidate = ether_aton (*iter); + if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) { + found = TRUE; + break; + } + } + + if (list) + g_strfreev (list); + +out: + g_key_file_free (config); + return found; +} + +#define DEFAULT_WIRED_TAG "default-wired" + +static void +default_wired_deleted (NMDefaultWiredConnection *wired, + const GByteArray *mac, + NMSysconfigSettings *self) +{ + NMSysconfigSettingsPrivate *priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + NMConnection *wrapped; + NMSettingConnection *s_con; + char *tmp; + GKeyFile *config; + char **list, **iter, **updated; + gboolean found = FALSE; + gsize len = 0; + char *data; + + /* If there was no config file specified, there's nothing to do */ + if (!priv->config_file) + goto cleanup; + + /* When the default wired connection is removed (either deleted or saved + * to a new persistent connection by a plugin), write the MAC address of + * the wired device to the config file and don't create a new default wired + * connection for that device again. + */ + + wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (wired)); + g_assert (wrapped); + s_con = (NMSettingConnection *) nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + + /* Ignore removals of read-only connections, since they couldn't have + * been removed by the user. + */ + if (nm_setting_connection_get_read_only (s_con)) + goto cleanup; + + config = g_key_file_new (); + if (!config) + goto cleanup; + + g_key_file_set_list_separator (config, ','); + g_key_file_load_from_file (config, priv->config_file, G_KEY_FILE_KEEP_COMMENTS, NULL); + + list = g_key_file_get_string_list (config, "main", CONFIG_KEY_NO_AUTO_DEFAULT, &len, NULL); + /* Traverse entire list to get count of # items */ + for (iter = list; iter && *iter; iter++) { + struct ether_addr *candidate; + + candidate = ether_aton (*iter); + if (candidate && !memcmp (mac->data, candidate->ether_addr_octet, ETH_ALEN)) + found = TRUE; + } + + /* Add this device's MAC to the list */ + if (!found) { + tmp = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x", + mac->data[0], mac->data[1], mac->data[2], + mac->data[3], mac->data[4], mac->data[5]); + + updated = g_malloc0 (sizeof (char*) * (len + 2)); + if (list && len) + memcpy (updated, list, len); + updated[len] = tmp; + + g_key_file_set_string_list (config, + "main", CONFIG_KEY_NO_AUTO_DEFAULT, + (const char **) updated, + len + 1); + /* g_free() not g_strfreev() since 'updated' isn't a deep-copy */ + g_free (updated); + g_free (tmp); + + data = g_key_file_to_data (config, &len, NULL); + if (data) { + g_file_set_contents (priv->config_file, data, len, NULL); + g_free (data); + } + } + + if (list) + g_strfreev (list); + g_key_file_free (config); + +cleanup: + g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)), + DEFAULT_WIRED_TAG, + NULL); +} + +static void +default_wired_try_update (NMDefaultWiredConnection *wired, + GHashTable *new_settings, + NMSysconfigSettings *self) +{ + GError *error = NULL; + NMConnection *wrapped; + NMSettingConnection *s_con; + const char *id; + + /* Try to move this default wired conneciton to a plugin so that it has + * persistent storage. + */ + + wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (wired)); + g_assert (wrapped); + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + id = nm_setting_connection_get_id (s_con); + g_assert (id); + + nm_sysconfig_settings_remove_connection (self, NM_EXPORTED_CONNECTION (wired), FALSE); + if (nm_sysconfig_settings_add_new_connection (self, new_settings, &error)) { + g_object_set_data (G_OBJECT (nm_default_wired_connection_get_device (wired)), + DEFAULT_WIRED_TAG, + NULL); + g_message ("Saved default wired connection '%s' to persistent storage", id); + return; + } + + g_warning ("%s: couldn't save default wired connection '%s': %d / %s", + __func__, id, error ? error->code : -1, + (error && error->message) ? error->message : "(unknown)"); + g_clear_error (&error); + + /* If there was an error, don't destroy the default wired connection, + * but add it back to the system settings service. Connection is already + * exported on the bus, don't export it again, thus do_export == FALSE. + */ + nm_sysconfig_settings_add_connection (self, NM_EXPORTED_CONNECTION (wired), FALSE); +} + +void +nm_sysconfig_settings_device_added (NMSysconfigSettings *self, NMDevice *device) +{ + GByteArray *mac = NULL; + struct ether_addr tmp; + NMDefaultWiredConnection *connection; + NMSettingConnection *s_con; + NMConnection *wrapped; + gboolean read_only = TRUE; + const char *id; + + if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET) + return; + + /* If the device isn't managed or it already has a default wired connection, + * ignore it. + */ + if ( !nm_device_get_managed (device) + || g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG)) + return; + + nm_device_ethernet_get_address (NM_DEVICE_ETHERNET (device), &tmp); + + mac = g_byte_array_sized_new (ETH_ALEN); + g_byte_array_append (mac, tmp.ether_addr_octet, ETH_ALEN); + + if ( have_connection_for_device (self, mac) + || is_mac_auto_wired_blacklisted (self, mac)) + goto ignore; + + if (nm_sysconfig_settings_get_plugin (self, NM_SYSTEM_CONFIG_INTERFACE_CAP_MODIFY_CONNECTIONS)) + read_only = FALSE; + + connection = nm_default_wired_connection_new (mac, device, read_only); + if (!connection) + goto ignore; + + wrapped = nm_exported_connection_get_connection (NM_EXPORTED_CONNECTION (connection)); + g_assert (wrapped); + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (wrapped, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + id = nm_setting_connection_get_id (s_con); + g_assert (id); + + g_message ("Added default wired connection '%s' for %s", id, nm_device_get_udi (device)); + + g_signal_connect (connection, "try-update", (GCallback) default_wired_try_update, self); + g_signal_connect (connection, "deleted", (GCallback) default_wired_deleted, self); + nm_sysconfig_settings_add_connection (self, NM_EXPORTED_CONNECTION (connection), TRUE); + g_object_unref (connection); + + g_object_set_data (G_OBJECT (device), DEFAULT_WIRED_TAG, connection); + +ignore: + g_byte_array_free (mac, TRUE); +} + +void +nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *device) +{ + NMExportedConnection *exported; + + if (nm_device_get_device_type (device) != NM_DEVICE_TYPE_ETHERNET) + return; + + exported = (NMExportedConnection *) g_object_get_data (G_OBJECT (device), DEFAULT_WIRED_TAG); + if (exported) + nm_sysconfig_settings_remove_connection (self, exported, TRUE); +} + NMSysconfigSettings * -nm_sysconfig_settings_new (const char *plugins, GError **error) +nm_sysconfig_settings_new (const char *config_file, + const char *plugins, + GError **error) { NMSysconfigSettings *self; NMSysconfigSettingsPrivate *priv; @@ -829,6 +1142,8 @@ nm_sysconfig_settings_new (const char *plugins, GError **error) priv = NM_SYSCONFIG_SETTINGS_GET_PRIVATE (self); + priv->config_file = g_strdup (config_file); + priv->dbus_mgr = nm_dbus_manager_get (); g_assert (priv->dbus_mgr); diff --git a/src/system-settings/nm-sysconfig-settings.h b/src/system-settings/nm-sysconfig-settings.h index f3b0a458d1..632c75daf8 100644 --- a/src/system-settings/nm-sysconfig-settings.h +++ b/src/system-settings/nm-sysconfig-settings.h @@ -31,6 +31,7 @@ #include "nm-sysconfig-connection.h" #include "nm-system-config-interface.h" +#include "nm-device.h" typedef struct _NMSysconfigSettings NMSysconfigSettings; typedef struct _NMSysconfigSettingsClass NMSysconfigSettingsClass; @@ -61,7 +62,9 @@ struct _NMSysconfigSettingsClass GType nm_sysconfig_settings_get_type (void); -NMSysconfigSettings *nm_sysconfig_settings_new (const char *plugins, GError **error); +NMSysconfigSettings *nm_sysconfig_settings_new (const char *config_file, + const char *plugins, + GError **error); /* Registers an exising connection with the settings service */ void nm_sysconfig_settings_add_connection (NMSysconfigSettings *settings, @@ -91,4 +94,8 @@ GSList *nm_sysconfig_settings_list_connections (NMSysconfigSettings *self); NMSysconfigConnection *nm_sysconfig_settings_get_connection_by_path (NMSysconfigSettings *self, const char *path); +void nm_sysconfig_settings_device_added (NMSysconfigSettings *self, NMDevice *device); + +void nm_sysconfig_settings_device_removed (NMSysconfigSettings *self, NMDevice *device); + #endif /* __NM_SYSCONFIG_SETTINGS_H__ */