From 4b1053da91f86adc9b3ae54189063fad98fb6f35 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 20 Dec 2019 17:52:34 +0100 Subject: [PATCH 1/3] core: add and indicate NM_CAPABILITY_OVS capability on D-Bus https://bugzilla.redhat.com/show_bug.cgi?id=1785147 (cherry picked from commit 785da51d83bf5b76835c457683bb2a4543386338) --- libnm-core/nm-dbus-interface.h | 6 +++++- shared/nm-libnm-core-intern/nm-libnm-core-utils.h | 4 ++++ src/devices/ovs/nm-ovs-factory.c | 1 + src/nm-manager.c | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h index 35f2335f56..1cf1c88812 100644 --- a/libnm-core/nm-dbus-interface.h +++ b/libnm-core/nm-dbus-interface.h @@ -89,7 +89,10 @@ /** * NMCapability: - * @NM_CAPABILITY_TEAM: Teams can be managed + * @NM_CAPABILITY_TEAM: Teams can be managed. This means the team device plugin + * is loaded. + * @NM_CAPABILITY_OVS: OpenVSwitch can be managed. This means the OVS device plugin + * is loaded. Since: 1.24, 1.22.2 * * #NMCapability names the numbers in the Capabilities property. * Capabilities are positive numbers. They are part of stable API @@ -101,6 +104,7 @@ */ typedef enum { NM_CAPABILITY_TEAM = 1, + NM_CAPABILITY_OVS = 2, } NMCapability; /** diff --git a/shared/nm-libnm-core-intern/nm-libnm-core-utils.h b/shared/nm-libnm-core-intern/nm-libnm-core-utils.h index 42e9fc6491..1449a8ba1c 100644 --- a/shared/nm-libnm-core-intern/nm-libnm-core-utils.h +++ b/shared/nm-libnm-core-intern/nm-libnm-core-utils.h @@ -95,4 +95,8 @@ nm_setting_ip_config_get_addr_family (NMSettingIPConfig *s_ip) * depends on other factors. */ #define NM_INFINIBAND_MAX_MTU ((guint) 65520) +/*****************************************************************************/ + +#define _NM_CAPABILITY_MAX NM_CAPABILITY_OVS + #endif /* __NM_LIBNM_SHARED_UTILS_H__ */ diff --git a/src/devices/ovs/nm-ovs-factory.c b/src/devices/ovs/nm-ovs-factory.c index d6dd13eb04..d1d79a1cf0 100644 --- a/src/devices/ovs/nm-ovs-factory.c +++ b/src/devices/ovs/nm-ovs-factory.c @@ -59,6 +59,7 @@ NM_DEVICE_FACTORY_DECLARE_TYPES ( G_MODULE_EXPORT NMDeviceFactory * nm_device_factory_create (GError **error) { + nm_manager_set_capability (NM_MANAGER_GET, NM_CAPABILITY_OVS); return (NMDeviceFactory *) g_object_new (NM_TYPE_OVS_FACTORY, NULL); } diff --git a/src/nm-manager.c b/src/nm-manager.c index 132cf5a0d8..3696c789be 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -7357,7 +7357,7 @@ nm_manager_set_capability (NMManager *self, gssize idx; g_return_if_fail (NM_IS_MANAGER (self)); - if (cap < 1 || cap > NM_CAPABILITY_TEAM) + if (cap < 1 || cap > _NM_CAPABILITY_MAX) g_return_if_reached (); cap_i = (guint32) cap; From 682ad94e4bcd2b099737388ad145eb90c73059a7 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 21 Dec 2019 12:25:03 +0100 Subject: [PATCH 2/3] libnm: handle boxed GType properties in nm_utils_g_param_spec_is_default() (cherry picked from commit 453e56c6e90e755cfe750fb5bbe967154c1f3759) --- libnm/nm-libnm-utils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libnm/nm-libnm-utils.c b/libnm/nm-libnm-utils.c index 73de75e36b..98c7e85785 100644 --- a/libnm/nm-libnm-utils.c +++ b/libnm/nm-libnm-utils.c @@ -926,6 +926,7 @@ nm_utils_g_param_spec_is_default (const GParamSpec *pspec) return ((((GParamSpecString *) pspec)->default_value) == NULL); if (NM_IN_SET (pspec->value_type, G_TYPE_BYTES, G_TYPE_PTR_ARRAY, + G_TYPE_ARRAY, G_TYPE_HASH_TABLE, G_TYPE_STRV)) { /* boxed types have NULL default. */ From d7356546ead2e219a3d8eba07f1238ac9b06cd1c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 20 Dec 2019 18:10:55 +0100 Subject: [PATCH 3/3] libnm: add nm_client_get_capabilities() to expose server Capabilities I hesitated to add this to libnm, because it's hardly used. However, we already fetch the property during GetManagedObjects(), we we should make it accessible, instead of requiring the user to make another D-Bus call. (cherry picked from commit 21b008d0ff7269a1c8b96ea3320f202fdaabd31c) --- libnm/libnm.ver | 5 +++ libnm/nm-client.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++- libnm/nm-client.h | 5 +++ 3 files changed, 104 insertions(+), 1 deletion(-) diff --git a/libnm/libnm.ver b/libnm/libnm.ver index fb5a4f64df..5e6dd230ed 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1652,3 +1652,8 @@ global: nm_setting_gsm_get_auto_config; nm_setting_ip_config_get_dhcp_hostname_flags; } libnm_1_20_0; + +libnm_1_22_2 { +global: + nm_client_get_capabilities; +} libnm_1_22_0; diff --git a/libnm/nm-client.c b/libnm/nm-client.c index e2f0117869..eabbe02215 100644 --- a/libnm/nm-client.c +++ b/libnm/nm-client.c @@ -222,6 +222,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMClient, PROP_DNS_RC_MANAGER, PROP_DNS_CONFIGURATION, PROP_CHECKPOINTS, + PROP_CAPABILITIES, ); enum { @@ -300,6 +301,8 @@ typedef struct { NMLDBusPropertyAO property_ao[_PROPERTY_AO_IDX_NM_NUM]; char *connectivity_check_uri; char *version; + guint32 *capabilities_arr; + gsize capabilities_len; guint32 connectivity; guint32 state; guint32 metered; @@ -6023,6 +6026,64 @@ _notify_update_prop_dns_manager_configuration (NMClient *self, return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; } +/** + * nm_client_get_capabilities: + * @client: the #NMClient instance + * @length: (out) (allow-none): the number of returned capabilities. + * + * Returns: (transfer none) (array length=length): the + * list of capabilities reported by the server or %NULL + * if the capabilities are unknown. + * The numeric values correspond to #NMCapability enum. + * The array is terminated by a numeric zero sentinel + * at position @length. + * + * Since: 1.24, 1.22.2 + */ +const guint32 * +nm_client_get_capabilities (NMClient *client, + gsize *length) +{ + NMClientPrivate *priv; + + g_return_val_if_fail (NM_IS_CLIENT (client), NULL); + g_return_val_if_fail (length, NULL); + + priv = NM_CLIENT_GET_PRIVATE (client); + + NM_SET_OUT (length, priv->nm.capabilities_len); + return priv->nm.capabilities_arr; +} + +static NMLDBusNotifyUpdatePropFlags +_notify_update_prop_nm_capabilities (NMClient *self, + NMLDBusObject *dbobj, + const NMLDBusMetaIface *meta_iface, + guint dbus_property_idx, + GVariant *value) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (self); + + nm_assert (G_OBJECT (self) == dbobj->nmobj); + + nm_clear_g_free (&priv->nm.capabilities_arr); + priv->nm.capabilities_len = 0; + + if (value) { + const guint32 *arr; + gsize len; + + arr = g_variant_get_fixed_array (value, &len, sizeof (guint32)); + priv->nm.capabilities_len = len; + priv->nm.capabilities_arr = g_new (guint32, len + 1); + if (len > 0) + memcpy (priv->nm.capabilities_arr, arr, len * sizeof (guint32)); + priv->nm.capabilities_arr[len] = 0; + } + + return NML_DBUS_NOTIFY_UPDATE_PROP_FLAGS_NOTIFY; +} + /*****************************************************************************/ /** @@ -7003,6 +7064,20 @@ get_property (GObject *object, guint prop_id, case PROP_CHECKPOINTS: g_value_take_boxed (value, _nm_utils_copy_object_array (nm_client_get_checkpoints (self))); break; + case PROP_CAPABILITIES: { + const guint32 *arr; + GArray *out; + gsize len; + + arr = nm_client_get_capabilities (self, &len); + if (arr) { + out = g_array_new (TRUE, FALSE, sizeof (guint32)); + g_array_append_vals (out, arr, len); + } else + out = NULL; + g_value_take_boxed (value, out); + } + break; /* Settings properties. */ case PROP_CONNECTIONS: @@ -7381,6 +7456,9 @@ dispose (GObject *object) g_clear_object (&priv->context_busy_watcher); nm_clear_g_free (&priv->name_owner); + + priv->nm.capabilities_len = 0; + nm_clear_g_free (&priv->nm.capabilities_arr); } const NMLDBusMetaIface _nml_dbus_meta_iface_nm_agentmanager = NML_DBUS_META_IFACE_INIT ( @@ -7397,7 +7475,7 @@ const NMLDBusMetaIface _nml_dbus_meta_iface_nm = NML_DBUS_META_IFACE_INIT_PROP ( NML_DBUS_META_PROPERTY_INIT_O_PROP ("ActivatingConnection", PROP_ACTIVATING_CONNECTION, NMClient, _priv.nm.property_o[PROPERTY_O_IDX_NM_ACTIVATING_CONNECTION], nm_active_connection_get_type ), NML_DBUS_META_PROPERTY_INIT_AO_PROP ("ActiveConnections", PROP_ACTIVE_CONNECTIONS, NMClient, _priv.nm.property_ao[PROPERTY_AO_IDX_ACTIVE_CONNECTIONS], nm_active_connection_get_type, .notify_changed_ao = _property_ao_notify_changed_active_connections_cb ), NML_DBUS_META_PROPERTY_INIT_AO_PROP ("AllDevices", PROP_ALL_DEVICES, NMClient, _priv.nm.property_ao[PROPERTY_AO_IDX_ALL_DEVICES], nm_device_get_type, .notify_changed_ao = _property_ao_notify_changed_all_devices_cb ), - NML_DBUS_META_PROPERTY_INIT_IGNORE ("Capabilities", "au" ), + NML_DBUS_META_PROPERTY_INIT_FCN ("Capabilities", PROP_CAPABILITIES, "au", _notify_update_prop_nm_capabilities, ), NML_DBUS_META_PROPERTY_INIT_AO_PROP ("Checkpoints", PROP_CHECKPOINTS, NMClient, _priv.nm.property_ao[PROPERTY_AO_IDX_CHECKPOINTS], nm_checkpoint_get_type ), NML_DBUS_META_PROPERTY_INIT_U ("Connectivity", PROP_CONNECTIVITY, NMClient, _priv.nm.connectivity ), NML_DBUS_META_PROPERTY_INIT_B ("ConnectivityCheckAvailable", PROP_CONNECTIVITY_CHECK_AVAILABLE, NMClient, _priv.nm.connectivity_check_available ), @@ -7834,6 +7912,21 @@ nm_client_class_init (NMClientClass *client_class) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + /** + * NMClient:capabilities: (type GArray(guint32)) + * + * The list of capabilities numbers as guint32 or %NULL if + * there are no capabitilies. The numeric value correspond + * to %NMCapability enum. + * + * Since: 1.24, 1.22.2 + */ + obj_properties[PROP_CAPABILITIES] = + g_param_spec_boxed (NM_CLIENT_CAPABILITIES, "", "", + G_TYPE_ARRAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + _nml_dbus_meta_class_init_with_properties (object_class, &_nml_dbus_meta_iface_nm, &_nml_dbus_meta_iface_nm_settings, &_nml_dbus_meta_iface_nm_dnsmanager); diff --git a/libnm/nm-client.h b/libnm/nm-client.h index ad17bf3892..8af956b48b 100644 --- a/libnm/nm-client.h +++ b/libnm/nm-client.h @@ -63,6 +63,7 @@ _NM_DEPRECATED_SYNC_WRITABLE_PROPERTY #define NM_CLIENT_DNS_RC_MANAGER "dns-rc-manager" #define NM_CLIENT_DNS_CONFIGURATION "dns-configuration" #define NM_CLIENT_CHECKPOINTS "checkpoints" +#define NM_CLIENT_CAPABILITIES "capabilities" #define NM_CLIENT_DEVICE_ADDED "device-added" #define NM_CLIENT_DEVICE_REMOVED "device-removed" @@ -236,6 +237,10 @@ NMMetered nm_client_get_metered (NMClient *client); gboolean nm_client_networking_get_enabled (NMClient *client); +NM_AVAILABLE_IN_1_22_2 +const guint32 *nm_client_get_capabilities (NMClient *client, + gsize *length); + _NM_DEPRECATED_SYNC_METHOD gboolean nm_client_networking_set_enabled (NMClient *client, gboolean enabled,