diff options
author | Thomas Haller <thaller@redhat.com> | 2014-09-24 17:03:56 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-09-24 17:04:44 +0200 |
commit | dfdb4b8e6f547b8d8119ce75b7477d94b35eeb34 (patch) | |
tree | fc81d116134f40c3ab9d21642d9abafc0a621ccc | |
parent | 3adeffe1f1c747b3845e815ba6bd1f151be83bcd (diff) | |
parent | 54f6666c66f398f3e2a430055cd2f033dd7746ba (diff) | |
download | NetworkManager-dfdb4b8e6f547b8d8119ce75b7477d94b35eeb34.tar.gz |
core: merge branch 'th/bgo731937_delete_nm_generated_connection'
https://bugzilla.gnome.org/show_bug.cgi?id=731937
Signed-off-by: Thomas Haller <thaller@redhat.com>
-rw-r--r-- | src/NetworkManagerUtils.h | 9 | ||||
-rw-r--r-- | src/devices/bluetooth/nm-bluez-device.c | 14 | ||||
-rw-r--r-- | src/devices/nm-device.c | 27 | ||||
-rw-r--r-- | src/nm-manager.c | 113 | ||||
-rw-r--r-- | src/platform/nm-fake-platform.c | 5 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 4 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 80 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 4 | ||||
-rw-r--r-- | src/platform/tests/platform.c | 6 | ||||
-rw-r--r-- | src/platform/tests/test-address.c | 6 | ||||
-rw-r--r-- | src/settings/nm-settings-connection.c | 134 | ||||
-rw-r--r-- | src/settings/nm-settings-connection.h | 34 |
12 files changed, 301 insertions, 135 deletions
diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 0996276a6e..eead08aae3 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -38,6 +38,15 @@ int nm_spawn_process (const char *args); /* macro to return strlen() of a compile time string. */ #define STRLEN(str) ( sizeof ("" str) - 1 ) +/* check if @flags has exactly one flag (@check) set. You should call this + * only with @check being a compile time constant and a power of two. */ +#define NM_FLAGS_HAS(flags, check) \ + ( (G_STATIC_ASSERT_EXPR ( ((check) != 0) && ((check) & ((check)-1)) == 0 )), (NM_FLAGS_ANY ((flags), (check))) ) + +#define NM_FLAGS_ANY(flags, check) ( ( ((flags) & (check)) != 0 ) ? TRUE : FALSE ) +#define NM_FLAGS_ALL(flags, check) ( ( ((flags) & (check)) == (check) ) ? TRUE : FALSE ) + + /** * str_if_set: * @str: input string that will be returned if @str is not %NULL diff --git a/src/devices/bluetooth/nm-bluez-device.c b/src/devices/bluetooth/nm-bluez-device.c index 8e6091150c..8196d66007 100644 --- a/src/devices/bluetooth/nm-bluez-device.c +++ b/src/devices/bluetooth/nm-bluez-device.c @@ -64,7 +64,6 @@ typedef struct { GSList *connections; NMConnection *pan_connection; - NMConnection *pan_connection_original; gboolean pan_connection_no_autocreate; } NMBluezDevicePrivate; @@ -233,9 +232,10 @@ pan_connection_check_create (NMBluezDevice *self) g_assert (connection_compatible (self, added)); g_assert (nm_connection_compare (added, connection, NM_SETTING_COMPARE_FLAG_EXACT)); + nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED, TRUE); + priv->connections = g_slist_prepend (priv->connections, g_object_ref (added)); priv->pan_connection = added; - priv->pan_connection_original = connection; nm_log_dbg (LOGD_BT, "bluez[%s] added new Bluetooth connection for NAP device: '%s' (%s)", priv->path, id, uuid); } else { nm_log_warn (LOGD_BT, "bluez[%s] couldn't add new Bluetooth connection for NAP device: '%s' (%s): %d / %s", @@ -243,8 +243,8 @@ pan_connection_check_create (NMBluezDevice *self) (error && error->message) ? error->message : "(unknown)"); g_clear_error (&error); - g_object_unref (connection); } + g_object_unref (connection); g_free (id); g_free (uuid); @@ -354,10 +354,8 @@ cp_connection_removed (NMConnectionProvider *provider, if (g_slist_find (priv->connections, connection)) { priv->connections = g_slist_remove (priv->connections, connection); - if (priv->pan_connection == connection) { + if (priv->pan_connection == connection) priv->pan_connection = NULL; - g_clear_object (&priv->pan_connection_original); - } g_object_unref (connection); check_emit_usable (self); } @@ -1022,12 +1020,10 @@ dispose (GObject *object) 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_settings_connection_get_unsaved (NM_SETTINGS_CONNECTION (priv->pan_connection)) - && nm_connection_compare (priv->pan_connection, priv->pan_connection_original, NM_SETTING_COMPARE_FLAG_EXACT)) + if (nm_settings_connection_get_nm_generated (NM_SETTINGS_CONNECTION (priv->pan_connection))) to_delete = g_object_ref (priv->pan_connection); priv->pan_connection = NULL; - g_clear_object (&priv->pan_connection_original); } g_signal_handlers_disconnect_by_func (priv->provider, cp_connection_added, self); diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 8eb86d9294..f8bbdda468 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -743,14 +743,19 @@ nm_device_get_physical_port_id (NMDevice *self) /***********************************************************/ static gboolean -nm_device_uses_generated_connection (NMDevice *self) +nm_device_uses_generated_assumed_connection (NMDevice *self) { + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; - connection = nm_device_get_connection (self); - if (!connection) - return FALSE; - return nm_settings_connection_get_nm_generated (NM_SETTINGS_CONNECTION (connection)); + if ( priv->act_request + && nm_active_connection_get_assumed (NM_ACTIVE_CONNECTION (priv->act_request))) { + connection = nm_act_request_get_connection (priv->act_request); + if ( connection + && nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) + return TRUE; + } + return FALSE; } static SlaveInfo * @@ -1390,7 +1395,7 @@ nm_device_master_release_slaves (NMDevice *self) NMDeviceStateReason reason; /* Don't release the slaves if this connection doesn't belong to NM. */ - if (nm_device_uses_generated_connection (self)) + if (nm_device_uses_generated_assumed_connection (self)) return; reason = priv->state_reason; @@ -1993,8 +1998,10 @@ nm_device_emit_recheck_assume (gpointer self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); priv->recheck_assume_id = 0; - if (!nm_device_get_act_request (self) && (priv->ip4_config || priv->ip6_config)) + if (!nm_device_get_act_request (self) && (priv->ip4_config || priv->ip6_config)) { + _LOGD (LOGD_DEVICE, "emit RECHECK_ASSUME signal"); g_signal_emit (self, signals[RECHECK_ASSUME], 0); + } return G_SOURCE_REMOVE; } @@ -2283,7 +2290,7 @@ nm_device_activate_stage2_device_config (gpointer user_data) if (slave_state == NM_DEVICE_STATE_IP_CONFIG) nm_device_enslave_slave (self, info->slave, nm_device_get_connection (info->slave)); - else if ( nm_device_uses_generated_connection (self) + else if ( nm_device_uses_generated_assumed_connection (self) && slave_state <= NM_DEVICE_STATE_DISCONNECTED) nm_device_queue_recheck_assume (info->slave); } @@ -5236,7 +5243,7 @@ nm_device_set_ip4_config (NMDevice *self, if (old_config != priv->ip4_config && old_config) g_object_unref (old_config); - if (nm_device_uses_generated_connection (self)) { + if (nm_device_uses_generated_assumed_connection (self)) { NMConnection *connection = nm_device_get_connection (self); NMSetting *s_ip4; @@ -5355,7 +5362,7 @@ nm_device_set_ip6_config (NMDevice *self, if (old_config != priv->ip6_config && old_config) g_object_unref (old_config); - if (nm_device_uses_generated_connection (self)) { + if (nm_device_uses_generated_assumed_connection (self)) { NMConnection *connection = nm_device_get_connection (self); NMSetting *s_ip6; diff --git a/src/nm-manager.c b/src/nm-manager.c index e08e595877..eb20ada399 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -118,7 +118,7 @@ static void impl_manager_check_connectivity (NMManager *manager, #include "nm-manager-glue.h" -static void add_device (NMManager *self, NMDevice *device, gboolean generate_con); +static void add_device (NMManager *self, NMDevice *device, gboolean try_assume); static void remove_device (NMManager *self, NMDevice *device, gboolean quitting); static NMActiveConnection *_new_active_connection (NMManager *self, @@ -281,11 +281,28 @@ active_connection_remove (NMManager *self, NMActiveConnection *active) /* FIXME: switch to a GList for faster removal */ found = g_slist_find (priv->active_connections, active); if (found) { + NMConnection *connection; + priv->active_connections = g_slist_remove (priv->active_connections, active); g_signal_emit (self, signals[ACTIVE_CONNECTION_REMOVED], 0, active); g_signal_handlers_disconnect_by_func (active, active_connection_state_changed, self); g_signal_handlers_disconnect_by_func (active, active_connection_default_changed, self); + + if ( nm_active_connection_get_assumed (active) + && (connection = nm_active_connection_get_connection (active)) + && nm_settings_connection_get_nm_generated_assumed (NM_SETTINGS_CONNECTION (connection))) + g_object_ref (connection); + else + connection = NULL; + g_object_unref (active); + + if (connection) { + nm_log_dbg (LOGD_DEVICE, "Assumed connection disconnected. Deleting generated connection '%s' (%s)", + nm_connection_get_id (connection), nm_connection_get_uuid (connection)); + nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL); + g_object_unref (connection); + } } return found && notify; @@ -1488,12 +1505,13 @@ match_connection_filter (NMConnection *connection, gpointer user_data) * get_existing_connection: * @manager: #NMManager instance * @device: #NMDevice instance + * @out_generated: (allow-none): return TRUE, if the connection was generated. * * Returns: a #NMSettingsConnection to be assumed by the device, or %NULL if * the device does not support assuming existing connections. */ static NMConnection * -get_existing_connection (NMManager *manager, NMDevice *device) +get_existing_connection (NMManager *manager, NMDevice *device, gboolean *out_generated) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); gs_free_slist GSList *connections = nm_manager_get_activatable_connections (manager); @@ -1503,6 +1521,9 @@ get_existing_connection (NMManager *manager, NMDevice *device) NMDevice *master = NULL; int ifindex = nm_device_get_ifindex (device); + if (out_generated) + *out_generated = FALSE; + nm_device_capture_initial_config (device); if (ifindex) { @@ -1561,9 +1582,14 @@ get_existing_connection (NMManager *manager, NMDevice *device) nm_connection_get_id (connection)); added = nm_settings_add_connection (priv->settings, connection, FALSE, &error); - if (added) - nm_settings_connection_set_nm_generated (added); - else { + if (added) { + nm_settings_connection_set_flags (NM_SETTINGS_CONNECTION (added), + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED, + TRUE); + if (out_generated) + *out_generated = TRUE; + } else { nm_log_warn (LOGD_SETTINGS, "(%s) Couldn't save generated connection '%s': %s", nm_device_get_iface (device), nm_connection_get_id (connection), @@ -1620,42 +1646,62 @@ assume_connection (NMManager *self, NMDevice *device, NMConnection *connection) return TRUE; } -static void +static gboolean recheck_assume_connection (NMDevice *device, gpointer user_data) { - NMManager *self = user_data; + NMManager *self = NM_MANAGER (user_data); NMConnection *connection; - gboolean was_unmanaged = FALSE; + gboolean was_unmanaged = FALSE, success, generated; + NMDeviceState state; if (manager_sleeping (self)) - return; + return FALSE; if (nm_device_get_unmanaged_flag (device, NM_UNMANAGED_USER)) - return; + return FALSE; - connection = get_existing_connection (self, device); + connection = get_existing_connection (self, device, &generated); if (!connection) { nm_log_dbg (LOGD_DEVICE, "(%s): can't assume; no connection", nm_device_get_iface (device)); - return; + return FALSE; } - if (nm_device_get_state (device) == NM_DEVICE_STATE_UNMANAGED) { + state = nm_device_get_state (device); + + if (state > NM_DEVICE_STATE_DISCONNECTED) + return FALSE; + + if (state == NM_DEVICE_STATE_UNMANAGED) { was_unmanaged = TRUE; nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED); } - if (!assume_connection (self, device, connection)) { + success = assume_connection (self, device, connection); + if (!success) { if (was_unmanaged) { nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, NM_DEVICE_STATE_REASON_CONFIG_FAILED); - nm_device_state_changed (device, - NM_DEVICE_STATE_UNMANAGED, - NM_DEVICE_STATE_REASON_CONFIG_FAILED); + + /* Return default-unmanaged devices to their original state */ + if (nm_device_get_unmanaged_flag (device, NM_UNMANAGED_DEFAULT)) { + nm_device_state_changed (device, + NM_DEVICE_STATE_UNMANAGED, + NM_DEVICE_STATE_REASON_CONFIG_FAILED); + } + } + + if (generated) { + nm_log_dbg (LOGD_DEVICE, "(%s): connection assumption failed. Deleting generated connection", + nm_device_get_iface (device)); + + nm_settings_connection_delete (NM_SETTINGS_CONNECTION (connection), NULL, NULL); } } + + return success; } static void @@ -1686,22 +1732,22 @@ device_ip_iface_changed (NMDevice *device, * add_device: * @self: the #NMManager * @device: the #NMDevice to add - * @generate_con: %TRUE if existing connection (if any) should be assumed + * @try_assume: %TRUE if existing connection (if any) should be assumed * * If successful, this function will increase the references count of @device. * Callers should decrease the reference count. */ static void -add_device (NMManager *self, NMDevice *device, gboolean generate_con) +add_device (NMManager *self, NMDevice *device, gboolean try_assume) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); const char *iface, *driver, *type_desc; const GSList *unmanaged_specs; gboolean user_unmanaged, sleeping; - NMConnection *connection = NULL; gboolean enabled = FALSE; RfKillType rtype; GSList *iter, *remove = NULL; + gboolean connection_assumed = FALSE; /* No duplicates */ if (nm_manager_get_device_by_udi (self, nm_device_get_udi (device))) @@ -1778,19 +1824,16 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) nm_device_dbus_export (device); - /* Don't generate a connection e.g. for devices NM just created, or - * for the loopback, or when we're sleeping. */ - if (generate_con && !user_unmanaged && !sleeping) - connection = get_existing_connection (self, device); + if (try_assume) { + connection_assumed = recheck_assume_connection (device, self); + g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME, + G_CALLBACK (recheck_assume_connection), self); + } - /* Start the device if it's supposed to be managed. Note that this will - * manage default-unmanaged devices if they have a generated connection. - */ - if (nm_device_get_managed (device) || connection) { + if (!connection_assumed && nm_device_get_managed (device)) { nm_device_state_changed (device, NM_DEVICE_STATE_UNAVAILABLE, - connection ? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED : - NM_DEVICE_STATE_REASON_NOW_MANAGED); + NM_DEVICE_STATE_REASON_NOW_MANAGED); } nm_settings_device_added (priv->settings, device); @@ -1801,16 +1844,6 @@ add_device (NMManager *self, NMDevice *device, gboolean generate_con) * need to create new virtual interfaces now. */ system_create_virtual_devices (self); - - /* If the device has a connection it can assume, do that now. If it's a - * device that we might ever want to assume a connection on, then set that up. - */ - if (connection) - assume_connection (self, device, connection); - if (generate_con) { - g_signal_connect (device, NM_DEVICE_RECHECK_ASSUME, - G_CALLBACK (recheck_assume_connection), self); - } } static NMDevice * diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c index f4a9396022..4e5d424e33 100644 --- a/src/platform/nm-fake-platform.c +++ b/src/platform/nm-fake-platform.c @@ -901,7 +901,7 @@ ip6_address_add (NMPlatform *platform, int ifindex, } static gboolean -ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) +ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, in_addr_t peer_address) { NMFakePlatformPrivate *priv = NM_FAKE_PLATFORM_GET_PRIVATE (platform); int i; @@ -909,7 +909,8 @@ ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) for (i = 0; i < priv->ip4_addresses->len; i++) { NMPlatformIP4Address *address = &g_array_index (priv->ip4_addresses, NMPlatformIP4Address, i); - if (address->ifindex == ifindex && address->plen == plen && address->address == addr) { + if (address->ifindex == ifindex && address->plen == plen && address->address == addr && + (!peer_address || address->peer_address == peer_address)) { NMPlatformIP4Address deleted_address; memcpy (&deleted_address, address, sizeof (deleted_address)); diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 73994cc362..5b308f7e2f 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -3567,9 +3567,9 @@ ip6_address_add (NMPlatform *platform, } static gboolean -ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen) +ip4_address_delete (NMPlatform *platform, int ifindex, in_addr_t addr, int plen, in_addr_t peer_address) { - return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, NULL, plen, 0, 0, 0, NULL), TRUE); + return delete_object (platform, build_rtnl_addr (AF_INET, ifindex, &addr, peer_address ? &peer_address : NULL, plen, 0, 0, 0, NULL), TRUE); } static gboolean diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index e26e10e158..ffe09238d8 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -1448,6 +1448,30 @@ nm_platform_mesh_set_ssid (int ifindex, const guint8 *ssid, gsize len) return klass->mesh_set_ssid (platform, ifindex, ssid, len); } +#define TO_STRING_DEV_BUF_SIZE (5+15+1) +static const char * +_to_string_dev (int ifindex, char *buf, size_t size) +{ + g_assert (buf && size >= TO_STRING_DEV_BUF_SIZE); + + if (ifindex) { + const char *name = ifindex > 0 ? nm_platform_link_get_name (ifindex) : NULL; + char *buf2; + + strcpy (buf, " dev "); + buf2 = buf + 5; + size -= 5; + + if (name) + g_strlcpy (buf2, name, size); + else + g_snprintf (buf2, size, "%d", ifindex); + } else + buf[0] = 0; + + return buf; +} + /******************************************************************/ GArray * @@ -1543,28 +1567,41 @@ nm_platform_ip6_address_add (int ifindex, } gboolean -nm_platform_ip4_address_delete (int ifindex, in_addr_t address, int plen) +nm_platform_ip4_address_delete (int ifindex, in_addr_t address, int plen, in_addr_t peer_address) { + char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_peer[NM_UTILS_INET_ADDRSTRLEN]; + reset_error (); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (plen > 0, FALSE); g_return_val_if_fail (klass->ip4_address_delete, FALSE); - debug ("address: deleting IPv4 address %s/%d", nm_utils_inet4_ntop (address, NULL), plen); - return klass->ip4_address_delete (platform, ifindex, address, plen); + debug ("address: deleting IPv4 address %s/%d, %s%s%sifindex %d%s", + nm_utils_inet4_ntop (address, NULL), plen, + peer_address ? "peer " : "", + peer_address ? nm_utils_inet4_ntop (peer_address, str_peer) : "", + peer_address ? ", " : "", + ifindex, + _to_string_dev (ifindex, str_dev, sizeof (str_dev))); + return klass->ip4_address_delete (platform, ifindex, address, plen, peer_address); } gboolean nm_platform_ip6_address_delete (int ifindex, struct in6_addr address, int plen) { + char str_dev[TO_STRING_DEV_BUF_SIZE]; + reset_error (); g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (plen > 0, FALSE); g_return_val_if_fail (klass->ip6_address_delete, FALSE); - debug ("address: deleting IPv6 address %s/%d", nm_utils_inet6_ntop (&address, NULL), plen); + debug ("address: deleting IPv6 address %s/%d, ifindex %d%s", + nm_utils_inet6_ntop (&address, NULL), plen, ifindex, + _to_string_dev (ifindex, str_dev, sizeof (str_dev))); return klass->ip6_address_delete (platform, ifindex, address, plen); } @@ -1712,7 +1749,7 @@ nm_platform_ip4_address_sync (int ifindex, const GArray *known_addresses) address = &g_array_index (addresses, NMPlatformIP4Address, i); if (!array_contains_ip4_address (known_addresses, address)) - nm_platform_ip4_address_delete (ifindex, address->address, address->plen); + nm_platform_ip4_address_delete (ifindex, address->address, address->plen, address->peer_address); } g_array_free (addresses, TRUE); @@ -1879,24 +1916,32 @@ nm_platform_ip6_route_add (int ifindex, NMPlatformSource source, gboolean nm_platform_ip4_route_delete (int ifindex, in_addr_t network, int plen, int metric) { + char str_dev[TO_STRING_DEV_BUF_SIZE]; + reset_error (); g_return_val_if_fail (platform, FALSE); g_return_val_if_fail (klass->ip4_route_delete, FALSE); - debug ("route: deleting IPv4 route %s/%d, metric=%d", nm_utils_inet4_ntop (network, NULL), plen, metric); + debug ("route: deleting IPv4 route %s/%d, metric=%d, ifindex %d%s", + nm_utils_inet4_ntop (network, NULL), plen, metric, ifindex, + _to_string_dev (ifindex, str_dev, sizeof (str_dev))); return klass->ip4_route_delete (platform, ifindex, network, plen, metric); } gboolean nm_platform_ip6_route_delete (int ifindex, struct in6_addr network, int plen, int metric) { + char str_dev[TO_STRING_DEV_BUF_SIZE]; + reset_error (); g_return_val_if_fail (platform, FALSE); g_return_val_if_fail (klass->ip6_route_delete, FALSE); - debug ("route: deleting IPv6 route %s/%d, metric=%d", nm_utils_inet6_ntop (&network, NULL), plen, metric); + debug ("route: deleting IPv6 route %s/%d, metric=%d, ifindex %d%s", + nm_utils_inet6_ntop (&network, NULL), plen, metric, ifindex, + _to_string_dev (ifindex, str_dev, sizeof (str_dev))); return klass->ip6_route_delete (platform, ifindex, network, plen, metric); } @@ -2132,27 +2177,6 @@ source_to_string (NMPlatformSource source) return "unknown"; } -#define TO_STRING_DEV_BUF_SIZE (5+15+1) -static void -_to_string_dev (int ifindex, char *buf, size_t size) -{ - g_assert (buf && size >= TO_STRING_DEV_BUF_SIZE); - - if (ifindex){ - const char *name = ifindex > 0 ? nm_platform_link_get_name (ifindex) : NULL; - - strcpy (buf, " dev "); - buf += 5; - size -= 5; - - if (name) - g_strlcpy (buf, name, size); - else - g_snprintf (buf, size, "%d", ifindex); - } else - buf[0] = 0; -} - static const char * _lifetime_to_string (guint32 timestamp, guint32 lifetime, gint32 now, char *buf, size_t buf_size) { diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 7bc80637c5..4cddd9c2b7 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -447,7 +447,7 @@ typedef struct { gboolean (*ip6_address_add) (NMPlatform *, int ifindex, struct in6_addr address, struct in6_addr peer_address, int plen, guint32 lifetime, guint32 preferred_lft, guint flags); - gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, int plen); + gboolean (*ip4_address_delete) (NMPlatform *, int ifindex, in_addr_t address, int plen, in_addr_t peer_address); gboolean (*ip6_address_delete) (NMPlatform *, int ifindex, struct in6_addr address, int plen); gboolean (*ip4_address_exists) (NMPlatform *, int ifindex, in_addr_t address, int plen); gboolean (*ip6_address_exists) (NMPlatform *, int ifindex, struct in6_addr address, int plen); @@ -591,7 +591,7 @@ gboolean nm_platform_ip4_address_add (int ifindex, gboolean nm_platform_ip6_address_add (int ifindex, struct in6_addr address, struct in6_addr peer_address, int plen, guint32 lifetime, guint32 preferred_lft, guint flags); -gboolean nm_platform_ip4_address_delete (int ifindex, in_addr_t address, int plen); +gboolean nm_platform_ip4_address_delete (int ifindex, in_addr_t address, int plen, in_addr_t peer_address); gboolean nm_platform_ip6_address_delete (int ifindex, struct in6_addr address, int plen); gboolean nm_platform_ip4_address_exists (int ifindex, in_addr_t address, int plen); gboolean nm_platform_ip6_address_exists (int ifindex, struct in6_addr address, int plen); diff --git a/src/platform/tests/platform.c b/src/platform/tests/platform.c index 9d2f970a24..3bc2acbf9d 100644 --- a/src/platform/tests/platform.c +++ b/src/platform/tests/platform.c @@ -597,7 +597,7 @@ do_ip6_address_add (char **argv) return FALSE; } -#define ADDR_CMD_FULL(v, cmdname, print) \ +#define ADDR_CMD_FULL(v, cmdname, print, ...) \ static gboolean \ do_##v##_address_##cmdname (char **argv) \ { \ @@ -605,7 +605,7 @@ do_ip6_address_add (char **argv) v##_t address; \ int plen; \ if (ifindex && parse_##v##_address (*argv++, &address, &plen)) { \ - gboolean value = nm_platform_##v##_address_##cmdname (ifindex, address, plen); \ + gboolean value = nm_platform_##v##_address_##cmdname (ifindex, address, plen, ##__VA_ARGS__); \ if (print) { \ print_boolean (value); \ return TRUE; \ @@ -614,7 +614,7 @@ do_ip6_address_add (char **argv) } else \ return FALSE; \ } -#define ADDR_CMD(cmdname) ADDR_CMD_FULL (ip4, cmdname, FALSE) ADDR_CMD_FULL (ip6, cmdname, FALSE) +#define ADDR_CMD(cmdname) ADDR_CMD_FULL (ip4, cmdname, FALSE, 0) ADDR_CMD_FULL (ip6, cmdname, FALSE) #define ADDR_CMD_PRINT(cmdname) ADDR_CMD_FULL (ip4, cmdname, TRUE) ADDR_CMD_FULL (ip6, cmdname, TRUE) ADDR_CMD (delete) diff --git a/src/platform/tests/test-address.c b/src/platform/tests/test-address.c index 3fef537528..8d297e501c 100644 --- a/src/platform/tests/test-address.c +++ b/src/platform/tests/test-address.c @@ -91,13 +91,13 @@ test_ip4_address (void) g_array_unref (addresses); /* Remove address */ - g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN)); + g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN, 0)); no_error (); g_assert (!nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); accept_signal (address_removed); /* Remove address again */ - g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN)); + g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN, 0)); no_error (); free_signal (address_added); @@ -196,7 +196,7 @@ test_ip4_address_external (void) g_assert (nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); accept_signal (address_added); /*run_command ("ip address delete %s/%d dev %s", IP4_ADDRESS, IP4_PLEN, DEVICE_NAME); - g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN)); + g_assert (nm_platform_ip4_address_delete (ifindex, addr, IP4_PLEN, 0)); no_error (); g_assert (!nm_platform_ip4_address_exists (ifindex, addr, IP4_PLEN)); accept_signal (address_removed);*/ diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index db382adb82..9fa2801dd3 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -82,6 +82,7 @@ enum { PROP_0 = 0, PROP_VISIBLE, PROP_UNSAVED, + PROP_FLAGS, }; enum { @@ -97,15 +98,7 @@ typedef struct { NMSessionMonitor *session_monitor; guint session_changed_id; - /* TRUE if the connection has not yet been saved to disk, - * or if it contains changes that have not been saved to disk. - */ - gboolean unsaved; - - /* TRUE if the connection was generated by NetworkManager and has - * not been saved or modified by the user. - */ - gboolean nm_generated; + NMSettingsConnectionFlags flags; guint updated_idle_id; @@ -405,14 +398,17 @@ emit_updated (NMSettingsConnection *self) static void set_unsaved (NMSettingsConnection *self, gboolean now_unsaved) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); - - if (priv->unsaved != now_unsaved) { - priv->unsaved = now_unsaved; - if (!priv->unsaved) - priv->nm_generated = FALSE; + NMSettingsConnectionFlags flags = nm_settings_connection_get_flags (self); - g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTION_UNSAVED); + if (NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED) != !!now_unsaved) { + if (now_unsaved) + flags |= NM_SETTINGS_CONNECTION_FLAGS_UNSAVED; + else { + flags &= ~(NM_SETTINGS_CONNECTION_FLAGS_UNSAVED | + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED); + } + nm_settings_connection_set_flags_all (self, flags); } } @@ -462,7 +458,9 @@ nm_settings_connection_replace_settings (NMSettingsConnection *self, g_signal_handlers_block_by_func (self, G_CALLBACK (changed_cb), GUINT_TO_POINTER (TRUE)); nm_connection_replace_settings_from_connection (NM_CONNECTION (self), new_connection); - priv->nm_generated = FALSE; + nm_settings_connection_set_flags (self, + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED | NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED, + FALSE); /* Cache the just-updated system secrets in case something calls * nm_connection_clear_secrets() and clears them. @@ -1411,7 +1409,7 @@ impl_settings_connection_save (NMSettingsConnection *self, DBusGMethodInvocation *context) { /* Do nothing if the connection is already synced with disk */ - if (NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->unsaved == TRUE) + if (nm_settings_connection_get_unsaved (self)) impl_settings_connection_update_helper (self, NULL, context, TRUE); else dbus_g_method_return (context); @@ -1597,11 +1595,57 @@ nm_settings_connection_signal_remove (NMSettingsConnection *self) gboolean nm_settings_connection_get_unsaved (NMSettingsConnection *self) { - return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->unsaved; + return NM_FLAGS_HAS (nm_settings_connection_get_flags (self), NM_SETTINGS_CONNECTION_FLAGS_UNSAVED); } /**************************************************************/ +NMSettingsConnectionFlags +nm_settings_connection_get_flags (NMSettingsConnection *self) +{ + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_FLAGS_NONE); + + return NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->flags; +} + +NMSettingsConnectionFlags +nm_settings_connection_set_flags (NMSettingsConnection *self, NMSettingsConnectionFlags flags, gboolean set) +{ + NMSettingsConnectionFlags new_flags; + + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_FLAGS_NONE); + g_return_val_if_fail ((flags & ~NM_SETTINGS_CONNECTION_FLAGS_ALL) == 0, NM_SETTINGS_CONNECTION_FLAGS_NONE); + + new_flags = NM_SETTINGS_CONNECTION_GET_PRIVATE (self)->flags; + if (set) + new_flags |= flags; + else + new_flags &= ~flags; + return nm_settings_connection_set_flags_all (self, new_flags); +} + +NMSettingsConnectionFlags +nm_settings_connection_set_flags_all (NMSettingsConnection *self, NMSettingsConnectionFlags flags) +{ + NMSettingsConnectionPrivate *priv; + NMSettingsConnectionFlags old_flags; + + g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION (self), NM_SETTINGS_CONNECTION_FLAGS_NONE); + g_return_val_if_fail ((flags & ~NM_SETTINGS_CONNECTION_FLAGS_ALL) == 0, NM_SETTINGS_CONNECTION_FLAGS_NONE); + priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); + + old_flags = priv->flags; + if (old_flags != flags) { + priv->flags = flags; + g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTION_FLAGS); + if (NM_FLAGS_HAS (old_flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED) != NM_FLAGS_HAS (flags, NM_SETTINGS_CONNECTION_FLAGS_UNSAVED)) + g_object_notify (G_OBJECT (self), NM_SETTINGS_CONNECTION_UNSAVED); + } + return old_flags; +} + +/*************************************************************/ + /** * nm_settings_connection_get_timestamp: * @connection: the #NMSettingsConnection @@ -1962,30 +2006,28 @@ nm_settings_connection_can_autoconnect (NMSettingsConnection *connection) * Gets the "nm-generated" flag on @connection. * * A connection is "nm-generated" if it was generated by - * nm_device_generate_connection() and then assumed by #NMManager, and - * it has not been modified or saved by the user since then. In other - * words, an "nm-generated" connection reflects state that is entirely - * external to NetworkManager. + * nm_device_generate_connection() and has not been modified or + * saved by the user since then. */ gboolean nm_settings_connection_get_nm_generated (NMSettingsConnection *connection) { - return NM_SETTINGS_CONNECTION_GET_PRIVATE (connection)->nm_generated; + return NM_FLAGS_HAS (nm_settings_connection_get_flags (connection), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED); } /** - * nm_settings_connection_set_nm_generated: + * nm_settings_connection_get_nm_generated_assumed: * @connection: an #NMSettingsConnection * - * Sets the "nm-generated" flag on @connection; see - * nm_settings_connection_get_nm_generated(). + * Gets the "nm-generated-assumed" flag on @connection. + * + * The connection is a generated connection especially + * generated for connection assumption. */ -void -nm_settings_connection_set_nm_generated (NMSettingsConnection *connection) +gboolean +nm_settings_connection_get_nm_generated_assumed (NMSettingsConnection *connection) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (connection); - - priv->nm_generated = TRUE; + return NM_FLAGS_HAS (nm_settings_connection_get_flags (connection), NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED); } /**************************************************************/ @@ -2064,14 +2106,18 @@ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (object); + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object); + NMSettingsConnectionPrivate *priv = NM_SETTINGS_CONNECTION_GET_PRIVATE (self); switch (prop_id) { case PROP_VISIBLE: g_value_set_boolean (value, priv->visible); break; case PROP_UNSAVED: - g_value_set_boolean (value, priv->unsaved); + g_value_set_boolean (value, nm_settings_connection_get_unsaved (self)); + break; + case PROP_FLAGS: + g_value_set_uint (value, nm_settings_connection_get_flags (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -2083,7 +2129,16 @@ static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + NMSettingsConnection *self = NM_SETTINGS_CONNECTION (object); + + switch (prop_id) { + case PROP_FLAGS: + nm_settings_connection_set_flags_all (self, g_value_get_uint (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void @@ -2117,6 +2172,15 @@ nm_settings_connection_class_init (NMSettingsConnectionClass *class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property + (object_class, PROP_FLAGS, + g_param_spec_uint (NM_SETTINGS_CONNECTION_FLAGS, "", "", + NM_SETTINGS_CONNECTION_FLAGS_NONE, + NM_SETTINGS_CONNECTION_FLAGS_ALL, + NM_SETTINGS_CONNECTION_FLAGS_NONE, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /* Signals */ /* Emitted when the connection is changed for any reason */ diff --git a/src/settings/nm-settings-connection.h b/src/settings/nm-settings-connection.h index 3ee62465fd..254e927bfd 100644 --- a/src/settings/nm-settings-connection.h +++ b/src/settings/nm-settings-connection.h @@ -48,6 +48,34 @@ G_BEGIN_DECLS /* Properties */ #define NM_SETTINGS_CONNECTION_VISIBLE "visible" #define NM_SETTINGS_CONNECTION_UNSAVED "unsaved" +#define NM_SETTINGS_CONNECTION_FLAGS "flags" + + +/** + * NMSettingsConnectionFlags: + * @NM_SETTINGS_CONNECTION_FLAGS_NONE: no flag set + * @NM_SETTINGS_CONNECTION_FLAGS_UNSAVED: the connection is not saved to disk + * @NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED: A connection is "nm-generated" if + * it was generated by NetworkManger. If the connection gets modified or saved + * by the user, the flag gets cleared. A nm-generated is implicitly unsaved. + * @NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED: A special kind of "nm-generated" + * connection that was specifically created for connection assumption. "nm-generated-assumed" + * implies "nm-generated". + * @NM_SETTINGS_CONNECTION_FLAGS_ALL: special mask, for all known flags + * + * #NMSettingsConnection flags. + **/ +typedef enum +{ + NM_SETTINGS_CONNECTION_FLAGS_NONE = 0x00, + NM_SETTINGS_CONNECTION_FLAGS_UNSAVED = 0x01, + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED = 0x02, + NM_SETTINGS_CONNECTION_FLAGS_NM_GENERATED_ASSUMED = 0x04, + + __NM_SETTINGS_CONNECTION_FLAGS_LAST, + NM_SETTINGS_CONNECTION_FLAGS_ALL = ((__NM_SETTINGS_CONNECTION_FLAGS_LAST - 1) << 1) - 1, +} NMSettingsConnectionFlags; + typedef struct _NMSettingsConnectionClass NMSettingsConnectionClass; @@ -129,6 +157,10 @@ void nm_settings_connection_signal_remove (NMSettingsConnection *self); gboolean nm_settings_connection_get_unsaved (NMSettingsConnection *self); +NMSettingsConnectionFlags nm_settings_connection_get_flags (NMSettingsConnection *connection); +NMSettingsConnectionFlags nm_settings_connection_set_flags (NMSettingsConnection *connection, NMSettingsConnectionFlags flags, gboolean set); +NMSettingsConnectionFlags nm_settings_connection_set_flags_all (NMSettingsConnection *connection, NMSettingsConnectionFlags flags); + gboolean nm_settings_connection_get_timestamp (NMSettingsConnection *connection, guint64 *out_timestamp); @@ -161,8 +193,8 @@ void nm_settings_connection_set_autoconnect_blocked_reason (NMSettingsConnection gboolean nm_settings_connection_can_autoconnect (NMSettingsConnection *connection); -void nm_settings_connection_set_nm_generated (NMSettingsConnection *connection); gboolean nm_settings_connection_get_nm_generated (NMSettingsConnection *connection); +gboolean nm_settings_connection_get_nm_generated_assumed (NMSettingsConnection *connection); G_END_DECLS |