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>
This commit is contained in:
Thomas Haller 2014-09-24 17:03:56 +02:00
commit dfdb4b8e6f
12 changed files with 301 additions and 135 deletions

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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 *

View file

@ -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));

View file

@ -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

View file

@ -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)
{

View file

@ -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);

View file

@ -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)

View file

@ -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);*/

View file

@ -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);
NMSettingsConnectionFlags flags = nm_settings_connection_get_flags (self);
if (priv->unsaved != now_unsaved) {
priv->unsaved = now_unsaved;
if (!priv->unsaved)
priv->nm_generated = FALSE;
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 */

View file

@ -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