summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2017-10-05 11:50:39 +0200
committerThomas Haller <thaller@redhat.com>2017-10-05 11:50:39 +0200
commit2a63bbfb789819562e352928aba8cd16e0c0d0ee (patch)
treed389b269c2ba6cfb3d176975684b8710a23bb694
parent24a7f88bc56b66745c1e6b9444df8a80125de059 (diff)
parent2f1ab058f129e27eff200f51d3b6e28afb77f71c (diff)
downloadNetworkManager-2a63bbfb789819562e352928aba8cd16e0c0d0ee.tar.gz
core: merge branch 'th/activation-state-flags-rh1454883'
https://bugzilla.redhat.com/show_bug.cgi?id=1454883
-rw-r--r--introspection/org.freedesktop.NetworkManager.Connection.Active.xml9
-rw-r--r--libnm-core/nm-dbus-interface.h26
-rw-r--r--libnm/libnm.ver2
-rw-r--r--libnm/nm-active-connection.c39
-rw-r--r--libnm/nm-active-connection.h3
-rw-r--r--shared/nm-utils/nm-shared-utils.c83
-rw-r--r--shared/nm-utils/nm-shared-utils.h68
-rw-r--r--src/devices/nm-device.c42
-rw-r--r--src/nm-active-connection.c119
-rw-r--r--src/nm-active-connection.h14
-rw-r--r--src/nm-core-utils.c75
-rw-r--r--src/nm-core-utils.h66
12 files changed, 394 insertions, 152 deletions
diff --git a/introspection/org.freedesktop.NetworkManager.Connection.Active.xml b/introspection/org.freedesktop.NetworkManager.Connection.Active.xml
index 31a485c9ff..3962cf88ee 100644
--- a/introspection/org.freedesktop.NetworkManager.Connection.Active.xml
+++ b/introspection/org.freedesktop.NetworkManager.Connection.Active.xml
@@ -81,6 +81,15 @@
<property name="State" type="u" access="read"/>
<!--
+ StateFlags:
+
+ The state flags of this active connection.
+
+ Returns: <link linkend="NMActivationStateFlags">NMActivationStateFlags</link>
+ -->
+ <property name="StateFlags" type="u" access="read"/>
+
+ <!--
StateChanged:
@state: (<link linkend="NMActiveConnectionState">NMActiveConnectionState</link>) The new state of the active connection.
@reason: (<link linkend="NMActiveConnectionStateReason">NMActiveConnectionStateReason</link>) Reason code describing the change to the new state.
diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h
index 11492def2c..229c5d253f 100644
--- a/libnm-core/nm-dbus-interface.h
+++ b/libnm-core/nm-dbus-interface.h
@@ -877,4 +877,30 @@ typedef enum {
NM_IP_ROUTE_TABLE_SYNC_MODE_FULL = 3,
} NMIPRouteTableSyncMode;
+/**
+ * NMActivationStateFlags:
+ * @NM_ACTIVATION_STATE_FLAG_NONE: an alias for numeric zero, no flags set.
+ * @NM_ACTIVATION_STATE_FLAG_IS_MASTER: the device is a master.
+ * @NM_ACTIVATION_STATE_FLAG_IS_SLAVE: the device is a slave.
+ * @NM_ACTIVATION_STATE_FLAG_LAYER2_READY: layer2 is activated and ready.
+ * @NM_ACTIVATION_STATE_FLAG_IP4_READY: IPv4 setting is completed.
+ * @NM_ACTIVATION_STATE_FLAG_IP6_READY: IPv6 setting is completed.
+ * @NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES: The master has any slave devices attached.
+ * This only makes sense if the device is a master.
+ *
+ * Flags describing the current activation state.
+ *
+ * Since: 1.10
+ **/
+typedef enum { /*< flags >*/
+ NM_ACTIVATION_STATE_FLAG_NONE = 0,
+
+ NM_ACTIVATION_STATE_FLAG_IS_MASTER = (1LL << 0),
+ NM_ACTIVATION_STATE_FLAG_IS_SLAVE = (1LL << 1),
+ NM_ACTIVATION_STATE_FLAG_LAYER2_READY = (1LL << 2),
+ NM_ACTIVATION_STATE_FLAG_IP4_READY = (1LL << 3),
+ NM_ACTIVATION_STATE_FLAG_IP6_READY = (1LL << 4),
+ NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES = (1LL << 5),
+} NMActivationStateFlags;
+
#endif /* __NM_DBUS_INTERFACE_H__ */
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 5f3867c4f7..72c6224b3a 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1180,6 +1180,8 @@ global:
libnm_1_10_0 {
global:
+ nm_activation_state_flags_get_type;
+ nm_active_connection_get_state_flags;
nm_client_connectivity_check_get_available;
nm_client_connectivity_check_get_enabled;
nm_client_connectivity_check_set_enabled;
diff --git a/libnm/nm-active-connection.c b/libnm/nm-active-connection.c
index 412cb3babb..a0ea8a254b 100644
--- a/libnm/nm-active-connection.c
+++ b/libnm/nm-active-connection.c
@@ -51,6 +51,7 @@ typedef struct {
char *specific_object_path;
GPtrArray *devices;
NMActiveConnectionState state;
+ guint state_flags;
gboolean is_default;
NMIPConfig *ip4_config;
NMDhcpConfig *dhcp4_config;
@@ -71,6 +72,7 @@ enum {
PROP_SPECIFIC_OBJECT_PATH,
PROP_DEVICES,
PROP_STATE,
+ PROP_STATE_FLAGS,
PROP_DEFAULT,
PROP_IP4_CONFIG,
PROP_DHCP4_CONFIG,
@@ -216,6 +218,24 @@ nm_active_connection_get_state (NMActiveConnection *connection)
}
/**
+ * nm_active_connection_get_state_flags:
+ * @connection: a #NMActiveConnection
+ *
+ * Gets the active connection's state flags.
+ *
+ * Returns: the state flags
+ *
+ * Since: 1.10
+ **/
+NMActivationStateFlags
+nm_active_connection_get_state_flags (NMActiveConnection *connection)
+{
+ g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NM_ACTIVATION_STATE_FLAG_NONE);
+
+ return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->state_flags;
+}
+
+/**
* nm_active_connection_get_state_reason:
* @connection: a #NMActiveConnection
*
@@ -474,6 +494,9 @@ get_property (GObject *object,
case PROP_STATE:
g_value_set_enum (value, nm_active_connection_get_state (self));
break;
+ case PROP_STATE_FLAGS:
+ g_value_set_uint (value, nm_active_connection_get_state_flags (self));
+ break;
case PROP_DEFAULT:
g_value_set_boolean (value, nm_active_connection_get_default (self));
break;
@@ -537,6 +560,7 @@ init_dbus (NMObject *object)
{ "specific-object", &priv->specific_object_path, demarshal_specific_object_path },
{ NM_ACTIVE_CONNECTION_DEVICES, &priv->devices, NULL, NM_TYPE_DEVICE },
{ NM_ACTIVE_CONNECTION_STATE, &priv->state },
+ { NM_ACTIVE_CONNECTION_STATE_FLAGS, &priv->state_flags },
{ NM_ACTIVE_CONNECTION_DEFAULT, &priv->is_default },
{ NM_ACTIVE_CONNECTION_IP4_CONFIG, &priv->ip4_config, NULL, NM_TYPE_IP4_CONFIG },
{ NM_ACTIVE_CONNECTION_DHCP4_CONFIG, &priv->dhcp4_config, NULL, NM_TYPE_DHCP4_CONFIG },
@@ -664,6 +688,21 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class)
G_PARAM_STATIC_STRINGS));
/**
+ * NMActiveConnection:state-flags:
+ *
+ * The state flags of the active connection.
+ *
+ * Since: 1.10
+ **/
+ g_object_class_install_property
+ (object_class, PROP_STATE_FLAGS,
+ g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE_FLAGS, "", "",
+ 0, G_MAXUINT32,
+ NM_ACTIVATION_STATE_FLAG_NONE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
* NMActiveConnection:default:
*
* Whether the active connection is the default IPv4 one.
diff --git a/libnm/nm-active-connection.h b/libnm/nm-active-connection.h
index 23cd737246..093ca64e1c 100644
--- a/libnm/nm-active-connection.h
+++ b/libnm/nm-active-connection.h
@@ -44,6 +44,7 @@ G_BEGIN_DECLS
#define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT_PATH "specific-object-path"
#define NM_ACTIVE_CONNECTION_DEVICES "devices"
#define NM_ACTIVE_CONNECTION_STATE "state"
+#define NM_ACTIVE_CONNECTION_STATE_FLAGS "state-flags"
#define NM_ACTIVE_CONNECTION_DEFAULT "default"
#define NM_ACTIVE_CONNECTION_IP4_CONFIG "ip4-config"
#define NM_ACTIVE_CONNECTION_DHCP4_CONFIG "dhcp4-config"
@@ -76,6 +77,8 @@ const char *nm_active_connection_get_connection_type (NM
const char *nm_active_connection_get_specific_object_path (NMActiveConnection *connection);
const GPtrArray *nm_active_connection_get_devices (NMActiveConnection *connection);
NMActiveConnectionState nm_active_connection_get_state (NMActiveConnection *connection);
+NM_AVAILABLE_IN_1_10
+NMActivationStateFlags nm_active_connection_get_state_flags (NMActiveConnection *connection);
NM_AVAILABLE_IN_1_8
NMActiveConnectionStateReason nm_active_connection_get_state_reason (NMActiveConnection *connection);
NMDevice *nm_active_connection_get_master (NMActiveConnection *connection);
diff --git a/shared/nm-utils/nm-shared-utils.c b/shared/nm-utils/nm-shared-utils.c
index 0810d7b1c1..3be5550b74 100644
--- a/shared/nm-utils/nm-shared-utils.c
+++ b/shared/nm-utils/nm-shared-utils.c
@@ -115,6 +115,89 @@ nm_utils_strbuf_append (char **buf, gsize *len, const char *format, ...)
/*****************************************************************************/
+char _nm_utils_to_string_buffer[];
+
+void
+nm_utils_to_string_buffer_init (char **buf, gsize *len)
+{
+ if (!*buf) {
+ *buf = _nm_utils_to_string_buffer;
+ *len = sizeof (_nm_utils_to_string_buffer);
+ }
+}
+
+gboolean
+nm_utils_to_string_buffer_init_null (gconstpointer obj, char **buf, gsize *len)
+{
+ nm_utils_to_string_buffer_init (buf, len);
+ if (!obj) {
+ g_strlcpy (*buf, "(null)", *len);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+const char *
+nm_utils_flags2str (const NMUtilsFlags2StrDesc *descs,
+ gsize n_descs,
+ unsigned flags,
+ char *buf,
+ gsize len)
+{
+ gsize i;
+ char *p;
+
+#if NM_MORE_ASSERTS > 10
+ nm_assert (descs);
+ nm_assert (n_descs > 0);
+ for (i = 0; i < n_descs; i++) {
+ gsize j;
+
+ nm_assert (descs[i].name && descs[i].name[0]);
+ for (j = 0; j < i; j++)
+ nm_assert (descs[j].flag != descs[i].flag);
+ }
+#endif
+
+ nm_utils_to_string_buffer_init (&buf, &len);
+
+ if (!len)
+ return buf;
+
+ buf[0] = '\0';
+ p = buf;
+ if (!flags) {
+ for (i = 0; i < n_descs; i++) {
+ if (!descs[i].flag) {
+ nm_utils_strbuf_append_str (&p, &len, descs[i].name);
+ break;
+ }
+ }
+ return buf;
+ }
+
+ for (i = 0; flags && i < n_descs; i++) {
+ if ( descs[i].flag
+ && NM_FLAGS_ALL (flags, descs[i].flag)) {
+ flags &= ~descs[i].flag;
+
+ if (buf[0] != '\0')
+ nm_utils_strbuf_append_c (&p, &len, ',');
+ nm_utils_strbuf_append_str (&p, &len, descs[i].name);
+ }
+ }
+ if (flags) {
+ if (buf[0] != '\0')
+ nm_utils_strbuf_append_c (&p, &len, ',');
+ nm_utils_strbuf_append (&p, &len, "0x%x", flags);
+ }
+ return buf;
+};
+
+/*****************************************************************************/
+
/**
* _nm_utils_ip4_prefix_to_netmask:
* @prefix: a CIDR prefix
diff --git a/shared/nm-utils/nm-shared-utils.h b/shared/nm-utils/nm-shared-utils.h
index fc14314445..98cac9afcd 100644
--- a/shared/nm-utils/nm-shared-utils.h
+++ b/shared/nm-utils/nm-shared-utils.h
@@ -212,6 +212,74 @@ gint _nm_utils_ascii_str_to_bool (const char *str,
/*****************************************************************************/
+extern char _nm_utils_to_string_buffer[2096];
+
+void nm_utils_to_string_buffer_init (char **buf, gsize *len);
+gboolean nm_utils_to_string_buffer_init_null (gconstpointer obj, char **buf, gsize *len);
+
+/*****************************************************************************/
+
+typedef struct {
+ unsigned flag;
+ const char *name;
+} NMUtilsFlags2StrDesc;
+
+#define NM_UTILS_FLAGS2STR(f, n) { .flag = f, .name = ""n, }
+
+#define _NM_UTILS_FLAGS2STR_DEFINE(scope, fcn_name, flags_type, ...) \
+scope const char * \
+fcn_name (flags_type flags, char *buf, gsize len) \
+{ \
+ static const NMUtilsFlags2StrDesc descs[] = { \
+ __VA_ARGS__ \
+ }; \
+ G_STATIC_ASSERT (sizeof (flags_type) <= sizeof (unsigned)); \
+ return nm_utils_flags2str (descs, G_N_ELEMENTS (descs), flags, buf, len); \
+};
+
+#define NM_UTILS_FLAGS2STR_DEFINE(fcn_name, flags_type, ...) \
+ _NM_UTILS_FLAGS2STR_DEFINE (, fcn_name, flags_type, __VA_ARGS__)
+#define NM_UTILS_FLAGS2STR_DEFINE_STATIC(fcn_name, flags_type, ...) \
+ _NM_UTILS_FLAGS2STR_DEFINE (static, fcn_name, flags_type, __VA_ARGS__)
+
+const char *nm_utils_flags2str (const NMUtilsFlags2StrDesc *descs,
+ gsize n_descs,
+ unsigned flags,
+ char *buf,
+ gsize len);
+
+/*****************************************************************************/
+
+#define NM_UTILS_ENUM2STR(v, n) (void) 0; case v: s = ""n""; break; (void) 0
+#define NM_UTILS_ENUM2STR_IGNORE(v) (void) 0; case v: break; (void) 0
+
+#define _NM_UTILS_ENUM2STR_DEFINE(scope, fcn_name, lookup_type, int_fmt, ...) \
+scope const char * \
+fcn_name (lookup_type val, char *buf, gsize len) \
+{ \
+ nm_utils_to_string_buffer_init (&buf, &len); \
+ if (len) { \
+ const char *s = NULL; \
+ switch (val) { \
+ (void) 0, \
+ __VA_ARGS__ \
+ (void) 0; \
+ }; \
+ if (s) \
+ g_strlcpy (buf, s, len); \
+ else \
+ g_snprintf (buf, len, "(%"int_fmt")", val); \
+ } \
+ return buf; \
+}
+
+#define NM_UTILS_ENUM2STR_DEFINE(fcn_name, lookup_type, ...) \
+ _NM_UTILS_ENUM2STR_DEFINE (, fcn_name, lookup_type, "d", __VA_ARGS__)
+#define NM_UTILS_ENUM2STR_DEFINE_STATIC(fcn_name, lookup_type, ...) \
+ _NM_UTILS_ENUM2STR_DEFINE (static, fcn_name, lookup_type, "d", __VA_ARGS__)
+
+/*****************************************************************************/
+
#define _nm_g_slice_free_fcn_define(mem_size) \
static inline void \
_nm_g_slice_free_fcn_##mem_size (gpointer mem_block) \
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index 435eeee2d7..b81a235c3e 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -746,6 +746,25 @@ nm_device_sys_iface_state_set (NMDevice *self,
nm_assert (priv->sys_iface_state == sys_iface_state);
}
+static void
+_active_connection_set_state_flags_full (NMDevice *self,
+ NMActivationStateFlags flags,
+ NMActivationStateFlags mask)
+{
+ NMActiveConnection *ac;
+
+ ac = NM_ACTIVE_CONNECTION (nm_device_get_act_request (self));
+ if (ac)
+ nm_active_connection_set_state_flags_full (ac, flags, mask);
+}
+
+static void
+_active_connection_set_state_flags (NMDevice *self,
+ NMActivationStateFlags flags)
+{
+ _active_connection_set_state_flags_full (self, flags, flags);
+}
+
/*****************************************************************************/
void
@@ -993,6 +1012,17 @@ _set_ip_state (NMDevice *self, int addr_family, IpState new_state)
(int) new_state,
_ip_state_to_string (new_state));
*p = new_state;
+
+ if (new_state == IP_DONE) {
+ /* we only set the IPx_READY flag once we reach IP_DONE state. We don't
+ * ever clear it, even if we later enter IP_FAIL state.
+ *
+ * This is not documented/guaranteed behavior, but seems to make sense for now. */
+ _active_connection_set_state_flags (self,
+ addr_family == AF_INET
+ ? NM_ACTIVATION_STATE_FLAG_IP4_READY
+ : NM_ACTIVATION_STATE_FLAG_IP6_READY);
+ }
}
}
@@ -2185,6 +2215,12 @@ nm_device_master_release_one_slave (NMDevice *self, NMDevice *slave, gboolean co
g_object_unref (slave);
g_slice_free (SlaveInfo, info);
+ if (c_list_is_empty (&priv->slaves)) {
+ _active_connection_set_state_flags_full (self,
+ 0,
+ NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES);
+ }
+
/* Ensure the device's hardware address is up-to-date; it often changes
* when slaves change.
*/
@@ -3694,6 +3730,9 @@ nm_device_master_add_slave (NMDevice *self, NMDevice *slave, gboolean configure)
c_list_link_tail (&priv->slaves, &info->lst_slave);
slave_priv->master = g_object_ref (self);
+ _active_connection_set_state_flags (self,
+ NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES);
+
/* no need to emit
*
* _notify (slave, PROP_MASTER);
@@ -8085,6 +8124,9 @@ activate_stage3_ip_config_start (NMDevice *self)
_set_ip_state (self, AF_INET, IP_WAIT);
_set_ip_state (self, AF_INET6, IP_WAIT);
+ _active_connection_set_state_flags (self,
+ NM_ACTIVATION_STATE_FLAG_LAYER2_READY);
+
nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG, NM_DEVICE_STATE_REASON_NONE);
/* Device should be up before we can do anything with it */
diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c
index 862754f9b5..002f11f7e9 100644
--- a/src/nm-active-connection.c
+++ b/src/nm-active-connection.c
@@ -44,6 +44,8 @@ typedef struct _NMActiveConnectionPrivate {
char *pending_activation_id;
+ NMActivationStateFlags state_flags;
+
NMActiveConnectionState state;
bool is_default:1;
bool is_default6:1;
@@ -73,6 +75,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMActiveConnection,
PROP_SPECIFIC_OBJECT,
PROP_DEVICES,
PROP_STATE,
+ PROP_STATE_FLAGS,
PROP_DEFAULT,
PROP_IP4_CONFIG,
PROP_DHCP4_CONFIG,
@@ -120,12 +123,11 @@ static void _set_activation_type_managed (NMActiveConnection *self);
#define _NMLOG(level, ...) \
G_STMT_START { \
char _sbuf[64]; \
- NMDevice *_device = (self) ? NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->device : NULL; \
- NMConnection *_applied_connection = _device ? NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->applied_connection : NULL; \
+ NMActiveConnectionPrivate *_priv = self ? NM_ACTIVE_CONNECTION_GET_PRIVATE (self) : NULL; \
\
nm_log ((level), _NMLOG_DOMAIN, \
- (_device) ? nm_device_get_iface (_device) : NULL, \
- (_applied_connection) ? nm_connection_get_uuid (_applied_connection) : NULL, \
+ (_priv && _priv->device) ? nm_device_get_iface (_priv->device) : NULL, \
+ (_priv && _priv->applied_connection) ? nm_connection_get_uuid (_priv->applied_connection) : NULL, \
"%s%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
_NMLOG_PREFIX_NAME, \
self ? nm_sprintf_buf (_sbuf, "[%p]", self) : "" \
@@ -144,6 +146,16 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_state_to_string, NMActiveConnectionState,
);
#define state_to_string(state) NM_UTILS_LOOKUP_STR (_state_to_string, state)
+NM_UTILS_FLAGS2STR_DEFINE_STATIC (_state_flags_to_string, NMActivationStateFlags,
+ NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_NONE, "none"),
+ NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IS_MASTER, "is-master"),
+ NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IS_SLAVE, "is-slave"),
+ NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_LAYER2_READY, "layer2-ready"),
+ NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IP4_READY, "ip4-ready"),
+ NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_IP6_READY, "ip6-ready"),
+ NM_UTILS_FLAGS2STR (NM_ACTIVATION_STATE_FLAG_MASTER_HAS_SLAVES, "master-has-slaves"),
+);
+
/*****************************************************************************/
static void
@@ -280,6 +292,33 @@ nm_active_connection_set_state (NMActiveConnection *self,
}
}
+NMActivationStateFlags
+nm_active_connection_get_state_flags (NMActiveConnection *self)
+{
+ return NM_ACTIVE_CONNECTION_GET_PRIVATE (self)->state_flags;
+}
+
+void
+nm_active_connection_set_state_flags_full (NMActiveConnection *self,
+ NMActivationStateFlags state_flags,
+ NMActivationStateFlags mask)
+{
+ NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
+ NMActivationStateFlags f;
+
+ f = (priv->state_flags & ~mask) | (state_flags & mask);
+ if (f != priv->state_flags) {
+ char buf1[G_N_ELEMENTS (_nm_utils_to_string_buffer)];
+ char buf2[G_N_ELEMENTS (_nm_utils_to_string_buffer)];
+
+ _LOGD ("set state-flags %s (was %s)",
+ _state_flags_to_string (f, buf1, sizeof (buf1)),
+ _state_flags_to_string (priv->state_flags, buf2, sizeof (buf2)));
+ priv->state_flags = f;
+ _notify (self, PROP_STATE_FLAGS);
+ }
+}
+
const char *
nm_active_connection_get_settings_connection_id (NMActiveConnection *self)
{
@@ -331,6 +370,39 @@ nm_active_connection_get_applied_connection (NMActiveConnection *self)
return con;
}
+static void
+_set_applied_connection_take (NMActiveConnection *self,
+ NMConnection *applied_connection)
+{
+ NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (self);
+ NMSettingConnection *s_con;
+ NMActivationStateFlags flags_val = 0;
+
+ nm_assert (NM_IS_CONNECTION (applied_connection));
+ nm_assert (!priv->applied_connection);
+
+ /* we take ownership of @applied_connection. Ensure to pass in a reference. */
+ priv->applied_connection = applied_connection;
+ nm_connection_clear_secrets (priv->applied_connection);
+
+ /* we determine whether the connection is a master/slave, based solely
+ * on the connection properties itself. */
+ s_con = nm_connection_get_setting_connection (priv->applied_connection);
+ if (nm_setting_connection_get_master (s_con))
+ flags_val |= NM_ACTIVATION_STATE_FLAG_IS_SLAVE;
+
+ if (NM_IN_STRSET (nm_setting_connection_get_connection_type (s_con),
+ NM_SETTING_BOND_SETTING_NAME,
+ NM_SETTING_BRIDGE_SETTING_NAME,
+ NM_SETTING_TEAM_SETTING_NAME))
+ flags_val |= NM_ACTIVATION_STATE_FLAG_IS_MASTER;
+
+ nm_active_connection_set_state_flags_full (self,
+ flags_val,
+ NM_ACTIVATION_STATE_FLAG_IS_MASTER
+ | NM_ACTIVATION_STATE_FLAG_IS_SLAVE);
+}
+
void
nm_active_connection_set_settings_connection (NMActiveConnection *self,
NMSettingsConnection *connection)
@@ -355,8 +427,9 @@ nm_active_connection_set_settings_connection (NMActiveConnection *self,
g_return_if_fail (!nm_exported_object_is_exported (NM_EXPORTED_OBJECT (self)));
_set_settings_connection (self, connection);
- priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection));
- nm_connection_clear_secrets (priv->applied_connection);
+
+ _set_applied_connection_take (self,
+ nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection)));
}
gboolean
@@ -1091,6 +1164,9 @@ get_property (GObject *object, guint prop_id,
g_value_set_uint (value, NM_ACTIVE_CONNECTION_STATE_ACTIVATING);
}
break;
+ case PROP_STATE_FLAGS:
+ g_value_set_uint (value, priv->state_flags);
+ break;
case PROP_DEFAULT:
g_value_set_boolean (value, priv->is_default);
break;
@@ -1151,8 +1227,15 @@ set_property (GObject *object, guint prop_id,
case PROP_INT_APPLIED_CONNECTION:
/* construct-only */
acon = g_value_get_object (value);
- if (acon)
+ if (acon) {
+ /* we don't call _set_applied_connection_take() yet, because the instance
+ * is not yet fully initialized. We are currently in the process of setting
+ * the constructor properties.
+ *
+ * For now, just piggyback the connection, but call _set_applied_connection_take()
+ * in constructed(). */
priv->applied_connection = g_object_ref (acon);
+ }
break;
case PROP_INT_DEVICE:
/* construct-only */
@@ -1220,17 +1303,25 @@ constructed (GObject *object)
G_OBJECT_CLASS (nm_active_connection_parent_class)->constructed (object);
- if (!priv->applied_connection && priv->settings_connection)
+ if ( !priv->applied_connection
+ && priv->settings_connection)
priv->applied_connection = nm_simple_connection_new_clone (NM_CONNECTION (priv->settings_connection));
- if (priv->applied_connection)
- nm_connection_clear_secrets (priv->applied_connection);
-
_LOGD ("constructed (%s, version-id %llu, type %s)",
G_OBJECT_TYPE_NAME (self),
(unsigned long long) priv->version_id,
nm_activation_type_to_string (priv->activation_type));
+ if (priv->applied_connection) {
+ /* priv->applied_connection was set during the construction of the object.
+ * It's not yet fully initialized, so do that now.
+ *
+ * We delayed that, because we may log in _set_applied_connection_take(), and the
+ * first logging line should be "constructed" above). */
+ _set_applied_connection_take (self,
+ g_steal_pointer (&priv->applied_connection));
+ }
+
g_return_if_fail (priv->subject);
}
@@ -1330,6 +1421,12 @@ nm_active_connection_class_init (NMActiveConnectionClass *ac_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_STATE_FLAGS] =
+ g_param_spec_uint (NM_ACTIVE_CONNECTION_STATE_FLAGS, "", "",
+ 0, G_MAXUINT32, NM_ACTIVATION_STATE_FLAG_NONE,
+ G_PARAM_READABLE |
+ G_PARAM_STATIC_STRINGS);
+
obj_properties[PROP_DEFAULT] =
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT, "", "",
FALSE,
diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h
index 8d3478c79d..5562b42f07 100644
--- a/src/nm-active-connection.h
+++ b/src/nm-active-connection.h
@@ -39,6 +39,7 @@
#define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT "specific-object"
#define NM_ACTIVE_CONNECTION_DEVICES "devices"
#define NM_ACTIVE_CONNECTION_STATE "state"
+#define NM_ACTIVE_CONNECTION_STATE_FLAGS "state-flags"
#define NM_ACTIVE_CONNECTION_DEFAULT "default"
#define NM_ACTIVE_CONNECTION_IP4_CONFIG "ip4-config"
#define NM_ACTIVE_CONNECTION_DHCP4_CONFIG "dhcp4-config"
@@ -145,6 +146,19 @@ void nm_active_connection_set_state (NMActiveConnection *self,
NMActiveConnectionState state,
NMActiveConnectionStateReason reason);
+NMActivationStateFlags nm_active_connection_get_state_flags (NMActiveConnection *self);
+
+void nm_active_connection_set_state_flags_full (NMActiveConnection *self,
+ NMActivationStateFlags state_flags,
+ NMActivationStateFlags mask);
+
+static inline void
+nm_active_connection_set_state_flags (NMActiveConnection *self,
+ NMActivationStateFlags state_flags)
+{
+ nm_active_connection_set_state_flags_full (self, state_flags, state_flags);
+}
+
NMDevice * nm_active_connection_get_device (NMActiveConnection *self);
gboolean nm_active_connection_set_device (NMActiveConnection *self, NMDevice *device);
diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c
index 88614278f1..a56f4ccd9f 100644
--- a/src/nm-core-utils.c
+++ b/src/nm-core-utils.c
@@ -1831,81 +1831,6 @@ nm_match_spec_join (GSList *specs)
/*****************************************************************************/
-char _nm_utils_to_string_buffer[];
-
-void
-nm_utils_to_string_buffer_init (char **buf, gsize *len)
-{
- if (!*buf) {
- *buf = _nm_utils_to_string_buffer;
- *len = sizeof (_nm_utils_to_string_buffer);
- }
-}
-
-gboolean
-nm_utils_to_string_buffer_init_null (gconstpointer obj, char **buf, gsize *len)
-{
- nm_utils_to_string_buffer_init (buf, len);
- if (!obj) {
- g_strlcpy (*buf, "(null)", *len);
- return FALSE;
- }
- return TRUE;
-}
-
-const char *
-nm_utils_flags2str (const NMUtilsFlags2StrDesc *descs,
- gsize n_descs,
- unsigned flags,
- char *buf,
- gsize len)
-{
- gsize i;
- char *p;
-
-#if NM_MORE_ASSERTS > 10
- nm_assert (descs);
- nm_assert (n_descs > 0);
- for (i = 0; i < n_descs; i++) {
- gsize j;
-
- nm_assert (descs[i].flag && nm_utils_is_power_of_two (descs[i].flag));
- nm_assert (descs[i].name && descs[i].name[0]);
- for (j = 0; j < i; j++)
- nm_assert (descs[j].flag != descs[i].flag);
- }
-#endif
-
- nm_utils_to_string_buffer_init (&buf, &len);
-
- if (!len)
- return buf;
-
- buf[0] = '\0';
- if (!flags) {
- return buf;
- }
-
- p = buf;
- for (i = 0; flags && i < n_descs; i++) {
- if (NM_FLAGS_HAS (flags, descs[i].flag)) {
- flags &= ~descs[i].flag;
-
- if (buf[0] != '\0')
- nm_utils_strbuf_append_c (&p, &len, ',');
- nm_utils_strbuf_append_str (&p, &len, descs[i].name);
- }
- }
- if (flags) {
- if (buf[0] != '\0')
- nm_utils_strbuf_append_c (&p, &len, ',');
- nm_utils_strbuf_append (&p, &len, "0x%x", flags);
- }
- return buf;
-};
-
-/*****************************************************************************/
-
char *
nm_utils_new_vlan_name (const char *parent_iface, guint32 vlan_id)
{
diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h
index 256e699b54..5221822d96 100644
--- a/src/nm-core-utils.h
+++ b/src/nm-core-utils.h
@@ -212,72 +212,6 @@ NMMatchSpecMatchType nm_match_spec_config (const GSList *specs,
GSList *nm_match_spec_split (const char *value);
char *nm_match_spec_join (GSList *specs);
-extern char _nm_utils_to_string_buffer[2096];
-
-void nm_utils_to_string_buffer_init (char **buf, gsize *len);
-gboolean nm_utils_to_string_buffer_init_null (gconstpointer obj, char **buf, gsize *len);
-
-/*****************************************************************************/
-
-typedef struct {
- unsigned flag;
- const char *name;
-} NMUtilsFlags2StrDesc;
-
-#define NM_UTILS_FLAGS2STR(f, n) { .flag = f, .name = ""n, }
-
-#define _NM_UTILS_FLAGS2STR_DEFINE(scope, fcn_name, flags_type, ...) \
-scope const char * \
-fcn_name (flags_type flags, char *buf, gsize len) \
-{ \
- static const NMUtilsFlags2StrDesc descs[] = { \
- __VA_ARGS__ \
- }; \
- G_STATIC_ASSERT (sizeof (flags_type) <= sizeof (unsigned)); \
- return nm_utils_flags2str (descs, G_N_ELEMENTS (descs), flags, buf, len); \
-};
-
-#define NM_UTILS_FLAGS2STR_DEFINE(fcn_name, flags_type, ...) \
- _NM_UTILS_FLAGS2STR_DEFINE (, fcn_name, flags_type, __VA_ARGS__)
-#define NM_UTILS_FLAGS2STR_DEFINE_STATIC(fcn_name, flags_type, ...) \
- _NM_UTILS_FLAGS2STR_DEFINE (static, fcn_name, flags_type, __VA_ARGS__)
-
-const char *nm_utils_flags2str (const NMUtilsFlags2StrDesc *descs,
- gsize n_descs,
- unsigned flags,
- char *buf,
- gsize len);
-
-/*****************************************************************************/
-
-#define NM_UTILS_ENUM2STR(v, n) (void) 0; case v: s = ""n""; break; (void) 0
-#define NM_UTILS_ENUM2STR_IGNORE(v) (void) 0; case v: break; (void) 0
-
-#define _NM_UTILS_ENUM2STR_DEFINE(scope, fcn_name, lookup_type, int_fmt, ...) \
-scope const char * \
-fcn_name (lookup_type val, char *buf, gsize len) \
-{ \
- nm_utils_to_string_buffer_init (&buf, &len); \
- if (len) { \
- const char *s = NULL; \
- switch (val) { \
- (void) 0, \
- __VA_ARGS__ \
- (void) 0; \
- }; \
- if (s) \
- g_strlcpy (buf, s, len); \
- else \
- g_snprintf (buf, len, "(%"int_fmt")", val); \
- } \
- return buf; \
-}
-
-#define NM_UTILS_ENUM2STR_DEFINE(fcn_name, lookup_type, ...) \
- _NM_UTILS_ENUM2STR_DEFINE (, fcn_name, lookup_type, "d", __VA_ARGS__)
-#define NM_UTILS_ENUM2STR_DEFINE_STATIC(fcn_name, lookup_type, ...) \
- _NM_UTILS_ENUM2STR_DEFINE (static, fcn_name, lookup_type, "d", __VA_ARGS__)
-
/*****************************************************************************/
const char *nm_utils_get_ip_config_method (NMConnection *connection,