summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2014-09-24 17:03:56 +0200
committerThomas Haller <thaller@redhat.com>2014-09-24 17:04:44 +0200
commitdfdb4b8e6f547b8d8119ce75b7477d94b35eeb34 (patch)
treefc81d116134f40c3ab9d21642d9abafc0a621ccc
parent3adeffe1f1c747b3845e815ba6bd1f151be83bcd (diff)
parent54f6666c66f398f3e2a430055cd2f033dd7746ba (diff)
downloadNetworkManager-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.h9
-rw-r--r--src/devices/bluetooth/nm-bluez-device.c14
-rw-r--r--src/devices/nm-device.c27
-rw-r--r--src/nm-manager.c113
-rw-r--r--src/platform/nm-fake-platform.c5
-rw-r--r--src/platform/nm-linux-platform.c4
-rw-r--r--src/platform/nm-platform.c80
-rw-r--r--src/platform/nm-platform.h4
-rw-r--r--src/platform/tests/platform.c6
-rw-r--r--src/platform/tests/test-address.c6
-rw-r--r--src/settings/nm-settings-connection.c134
-rw-r--r--src/settings/nm-settings-connection.h34
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