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/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, 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. */ 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;