diff options
Diffstat (limited to 'src/libnm-client-impl')
| -rw-r--r-- | src/libnm-client-impl/libnm.ver | 25 | ||||
| -rw-r--r-- | src/libnm-client-impl/meson.build | 1 | ||||
| -rw-r--r-- | src/libnm-client-impl/nm-client.c | 1 | ||||
| -rw-r--r-- | src/libnm-client-impl/nm-device-geneve.c | 344 | ||||
| -rw-r--r-- | src/libnm-client-impl/nm-device.c | 73 | ||||
| -rw-r--r-- | src/libnm-client-impl/nm-libnm-utils.c | 1 | ||||
| -rw-r--r-- | src/libnm-client-impl/nm-libnm-utils.h | 3 |
7 files changed, 444 insertions, 4 deletions
diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver index 6c48978a..c03b8f39 100644 --- a/src/libnm-client-impl/libnm.ver +++ b/src/libnm-client-impl/libnm.ver @@ -2103,3 +2103,28 @@ global: nm_utils_copy_cert_as_user; nm_vpn_plugin_info_supports_safe_private_file_access; } libnm_1_54_0; + +libnm_1_56_1 { +global: + nm_connection_get_setting_geneve; + nm_device_geneve_get_df; + nm_device_geneve_get_dst_port; + nm_device_geneve_get_id; + nm_device_geneve_get_remote; + nm_device_geneve_get_tos; + nm_device_geneve_get_ttl; + nm_device_geneve_get_type; + nm_device_managed_flags_get_type; + nm_device_managed_get_type; + nm_device_set_managed_async; + nm_device_set_managed_finish; + nm_setting_geneve_df_get_type; + nm_setting_geneve_get_destination_port; + nm_setting_geneve_get_df; + nm_setting_geneve_get_id; + nm_setting_geneve_get_remote; + nm_setting_geneve_get_tos; + nm_setting_geneve_get_ttl; + nm_setting_geneve_get_type; + nm_setting_geneve_new; +} libnm_1_56_0; diff --git a/src/libnm-client-impl/meson.build b/src/libnm-client-impl/meson.build index b4936629..3352ebfe 100644 --- a/src/libnm-client-impl/meson.build +++ b/src/libnm-client-impl/meson.build @@ -16,6 +16,7 @@ libnm_client_impl_sources = files( 'nm-device-bt.c', 'nm-device-dummy.c', 'nm-device-ethernet.c', + 'nm-device-geneve.c', 'nm-device-generic.c', 'nm-device-hsr.c', 'nm-device-infiniband.c', diff --git a/src/libnm-client-impl/nm-client.c b/src/libnm-client-impl/nm-client.c index b81ac6e5..f1383526 100644 --- a/src/libnm-client-impl/nm-client.c +++ b/src/libnm-client-impl/nm-client.c @@ -29,6 +29,7 @@ #include "nm-device-dummy.h" #include "nm-device-ethernet.h" #include "nm-device-generic.h" +#include "nm-device-geneve.h" #include "nm-device-hsr.h" #include "nm-device-infiniband.h" #include "nm-device-ip-tunnel.h" diff --git a/src/libnm-client-impl/nm-device-geneve.c b/src/libnm-client-impl/nm-device-geneve.c new file mode 100644 index 00000000..312a99b3 --- /dev/null +++ b/src/libnm-client-impl/nm-device-geneve.c @@ -0,0 +1,344 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * Copyright (C) 2026 Red Hat, Inc. + */ + +#include "libnm-client-impl/nm-default-libnm.h" + +#include "nm-device-geneve.h" + +#include "nm-setting-connection.h" +#include "nm-setting-geneve.h" +#include "nm-utils.h" +#include "nm-object-private.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_ID, + PROP_REMOTE, + PROP_TOS, + PROP_TTL, + PROP_DST_PORT, + PROP_DF, ); + +typedef struct { + char *remote; + guint32 id; + gint32 ttl; + guint16 dst_port; + guint8 df; + guint8 tos; +} NMDeviceGenevePrivate; + +struct _NMDeviceGeneve { + NMDevice parent; + NMDeviceGenevePrivate _priv; +}; + +struct _NMDeviceGeneveClass { + NMDeviceClass parent; +}; + +G_DEFINE_TYPE(NMDeviceGeneve, nm_device_geneve, NM_TYPE_DEVICE) + +#define NM_DEVICE_GENEVE_GET_PRIVATE(self) \ + _NM_GET_PRIVATE(self, NMDeviceGeneve, NM_IS_DEVICE_GENEVE, NMObject, NMDevice) + +/*****************************************************************************/ + +/** + * nm_device_geneve_get_id: + * @device: a #NMDeviceGeneve + * + * Returns: the device's GENEVE ID. + * + * Since: 1.58, 1.56.1 + **/ +guint +nm_device_geneve_get_id(NMDeviceGeneve *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_GENEVE(device), 0); + + return NM_DEVICE_GENEVE_GET_PRIVATE(device)->id; +} + +/** + * nm_device_geneve_get_remote: + * @device: a #NMDeviceGeneve + * + * Returns: the IP address of the remote tunnel endpoint + * + * Since: 1.58, 1.56.1 + **/ +const char * +nm_device_geneve_get_remote(NMDeviceGeneve *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_GENEVE(device), NULL); + + return _nml_coerce_property_str_not_empty(NM_DEVICE_GENEVE_GET_PRIVATE(device)->remote); +} + +/** + * nm_device_geneve_get_dst_port: + * @device: a #NMDeviceGeneve + * + * Returns: the UDP destination port + * + * Since: 1.58, 1.56.1 + **/ +guint +nm_device_geneve_get_dst_port(NMDeviceGeneve *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_GENEVE(device), 0); + + return NM_DEVICE_GENEVE_GET_PRIVATE(device)->dst_port; +} + +/** + * nm_device_geneve_get_tos: + * @device: a #NMDeviceGeneve + * + * Returns: the TOS value to use in outgoing packets + * + * Since: 1.58, 1.56.1 + **/ +guint +nm_device_geneve_get_tos(NMDeviceGeneve *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_GENEVE(device), 0); + + return NM_DEVICE_GENEVE_GET_PRIVATE(device)->tos; +} + +/** + * nm_device_geneve_get_ttl: + * @device: a #NMDeviceGeneve + * + * Returns: the time-to-live value to use in outgoing packets + * + * Since: 1.58, 1.56.1 + **/ +guint +nm_device_geneve_get_ttl(NMDeviceGeneve *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_GENEVE(device), 0); + + return NM_DEVICE_GENEVE_GET_PRIVATE(device)->ttl; +} + +/** + * nm_device_geneve_get_df: + * @device: a #NMDeviceGeneve + * + * Returns: the Don't Fragment (DF) bit to set in outgoing packets + * + * Since: 1.58, 1.56.1 + **/ +guint +nm_device_geneve_get_df(NMDeviceGeneve *device) +{ + g_return_val_if_fail(NM_IS_DEVICE_GENEVE(device), 0); + + return NM_DEVICE_GENEVE_GET_PRIVATE(device)->df; +} + +static gboolean +connection_compatible(NMDevice *device, NMConnection *connection, GError **error) +{ + NMSettingGeneve *s_geneve; + + if (!NM_DEVICE_CLASS(nm_device_geneve_parent_class) + ->connection_compatible(device, connection, error)) + return FALSE; + + if (!nm_connection_is_type(connection, NM_SETTING_GENEVE_SETTING_NAME)) { + g_set_error_literal(error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The connection was not a GENEVE connection.")); + return FALSE; + } + + s_geneve = nm_connection_get_setting_geneve(connection); + if (nm_setting_geneve_get_id(s_geneve) != nm_device_geneve_get_id(NM_DEVICE_GENEVE(device))) { + g_set_error_literal( + error, + NM_DEVICE_ERROR, + NM_DEVICE_ERROR_INCOMPATIBLE_CONNECTION, + _("The GENEVE identifiers of the device and the connection didn't match.")); + return FALSE; + } + + return TRUE; +} + +static GType +get_setting_type(NMDevice *device) +{ + return NM_TYPE_SETTING_GENEVE; +} + +/*****************************************************************************/ + +static void +get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + NMDeviceGeneve *device = NM_DEVICE_GENEVE(object); + + switch (prop_id) { + case PROP_ID: + g_value_set_uint(value, nm_device_geneve_get_id(device)); + break; + case PROP_REMOTE: + g_value_set_string(value, nm_device_geneve_get_remote(device)); + break; + case PROP_TOS: + g_value_set_uint(value, nm_device_geneve_get_tos(device)); + break; + case PROP_TTL: + g_value_set_int(value, nm_device_geneve_get_ttl(device)); + break; + case PROP_DST_PORT: + g_value_set_uint(value, nm_device_geneve_get_dst_port(device)); + break; + case PROP_DF: + g_value_set_uint(value, nm_device_geneve_get_df(device)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + break; + } +} + +static void +nm_device_geneve_init(NMDeviceGeneve *device) +{} + +static void +finalize(GObject *object) +{ + NMDeviceGenevePrivate *priv = NM_DEVICE_GENEVE_GET_PRIVATE(object); + + g_free(priv->remote); + + G_OBJECT_CLASS(nm_device_geneve_parent_class)->finalize(object); +} + +const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_geneve = NML_DBUS_META_IFACE_INIT_PROP( + NM_DBUS_INTERFACE_DEVICE_GENEVE, + nm_device_geneve_get_type, + NML_DBUS_META_INTERFACE_PRIO_INSTANTIATE_30, + NML_DBUS_META_IFACE_DBUS_PROPERTIES( + NML_DBUS_META_PROPERTY_INIT_Y("Df", PROP_DF, NMDeviceGeneve, _priv.df), + NML_DBUS_META_PROPERTY_INIT_Q("DstPort", PROP_DST_PORT, NMDeviceGeneve, _priv.dst_port), + NML_DBUS_META_PROPERTY_INIT_U("Id", PROP_ID, NMDeviceGeneve, _priv.id), + NML_DBUS_META_PROPERTY_INIT_S("Remote", PROP_REMOTE, NMDeviceGeneve, _priv.remote), + NML_DBUS_META_PROPERTY_INIT_Y("Tos", PROP_TOS, NMDeviceGeneve, _priv.tos), + NML_DBUS_META_PROPERTY_INIT_I("Ttl", PROP_TTL, NMDeviceGeneve, _priv.ttl), ), ); + +static void +nm_device_geneve_class_init(NMDeviceGeneveClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + NMObjectClass *nm_object_class = NM_OBJECT_CLASS(klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS(klass); + + object_class->get_property = get_property; + object_class->finalize = finalize; + + _NM_OBJECT_CLASS_INIT_PRIV_PTR_DIRECT(nm_object_class, NMDeviceGeneve); + + device_class->connection_compatible = connection_compatible; + device_class->get_setting_type = get_setting_type; + + /** + * NMDeviceGeneve:id: + * + * The device's GENEVE ID. + * + * Since: 1.58, 1.56.1 + **/ + obj_properties[PROP_ID] = g_param_spec_uint(NM_DEVICE_GENEVE_ID, + "", + "", + 0, + (1 << 24) - 1, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceGeneve:remote: + * + * The IP address of the remote tunnel endpoint. + * + * Since: 1.58, 1.56.1 + */ + obj_properties[PROP_REMOTE] = g_param_spec_string(NM_DEVICE_GENEVE_REMOTE, + "", + "", + NULL, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceGeneve:tos: + * + * The TOS value to use in outgoing packets. + * + * Since: 1.58, 1.56.1 + */ + obj_properties[PROP_TOS] = g_param_spec_uchar(NM_DEVICE_GENEVE_TOS, + "", + "", + 0, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceGeneve:ttl: + * + * The time-to-live value to use in outgoing packets. + * + * Since: 1.58, 1.56.1 + */ + obj_properties[PROP_TTL] = g_param_spec_int(NM_DEVICE_GENEVE_TTL, + "", + "", + -1, + 255, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceGeneve:dst-port: + * + * The UDP destination port used to communicate with the remote GENEVE tunnel + * endpoint. + * + * Since: 1.58, 1.56.1 + */ + obj_properties[PROP_DST_PORT] = g_param_spec_uint(NM_DEVICE_GENEVE_DST_PORT, + "", + "", + 0, + 65535, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** + * NMDeviceGeneve:df: + * + * The Don't Fragment (DF) bit to set in outgoing packets. + * + * Since: 1.58, 1.56.1 + */ + obj_properties[PROP_DF] = g_param_spec_uchar(NM_DEVICE_GENEVE_DF, + "", + "", + 0, + 2, + 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + _nml_dbus_meta_class_init_with_properties(object_class, &_nml_dbus_meta_iface_nm_device_geneve); +} diff --git a/src/libnm-client-impl/nm-device.c b/src/libnm-client-impl/nm-device.c index 1712efa5..63a62942 100644 --- a/src/libnm-client-impl/nm-device.c +++ b/src/libnm-client-impl/nm-device.c @@ -302,6 +302,7 @@ coerce_type(NMDeviceType type) case NM_DEVICE_TYPE_TUN: case NM_DEVICE_TYPE_VETH: case NM_DEVICE_TYPE_GENERIC: + case NM_DEVICE_TYPE_GENEVE: case NM_DEVICE_TYPE_UNUSED1: case NM_DEVICE_TYPE_UNUSED2: case NM_DEVICE_TYPE_UNKNOWN: @@ -1445,9 +1446,7 @@ nm_device_get_managed(NMDevice *device) * * Since: 1.2 * - * Deprecated: 1.22: Use the async command nm_client_dbus_set_property() on - * nm_object_get_path(), interface %NM_DBUS_INTERFACE_DEVICE to set the - * "Managed" property to a "(b)" boolean value. + * Deprecated: 1.22: Use nm_device_set_managed_async() instead. * This function is deprecated because it calls a synchronous D-Bus method * and modifies the content of the NMClient cache client side. Also, it does * not emit a property changed signal. @@ -1470,6 +1469,72 @@ nm_device_set_managed(NMDevice *device, gboolean managed) } /** + * nm_device_set_managed_async: + * @device: a #NMDevice + * @managed: the managed state + * @flags: the flags argument. See #NMDeviceManagedFlags. + * @cancellable: a #GCancellable, or %NULL + * @callback: callback to be called when the set_managed operation completes + * @user_data: caller-specific data passed to @callback + * + * Asynchronously begins setting the managed state of the device. With the flags + * argument different behaviors can be achieved, such as persisting the state to + * disk or matching the device by MAC address. + * + * Since: 1.58, 1.56.1 + **/ +void +nm_device_set_managed_async(NMDevice *device, + NMDeviceManaged managed, + NMDeviceManagedFlags flags, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_return_if_fail(NM_IS_DEVICE(device)); + g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable)); + + _nm_client_dbus_call(_nm_object_get_client(device), + device, + nm_device_set_managed_async, + cancellable, + callback, + user_data, + _nm_object_get_path(device), + NM_DBUS_INTERFACE_DEVICE, + "SetManaged", + g_variant_new("(uu)", managed, flags), + G_VARIANT_TYPE("()"), + G_DBUS_CALL_FLAGS_NONE, + NM_DBUS_DEFAULT_TIMEOUT_MSEC, + nm_dbus_connection_call_finish_void_strip_dbus_error_cb); +} + +/** + * nm_device_set_managed_finish: + * @device: a #NMDevice + * @result: the result passed to the #GAsyncReadyCallback + * @error: location for a #GError, or %NULL + * + * Gets the result of a call to nm_device_set_managed_async(). + * + * Returns: %TRUE on success, %FALSE on error, in which case @error + * will be set. + * + * Since: 1.58, 1.56.1 + **/ +gboolean +nm_device_set_managed_finish(NMDevice *device, GAsyncResult *result, GError **error) +{ + g_return_val_if_fail(NM_IS_DEVICE(device), FALSE); + g_return_val_if_fail(nm_g_task_is_valid(result, device, nm_device_set_managed_async), FALSE); + + return g_task_propagate_boolean(G_TASK(result), error); +} + +/*****************************************************************************/ + +/** * nm_device_get_autoconnect: * @device: a #NMDevice * @@ -1792,6 +1857,8 @@ get_type_name(NMDevice *device) return _("MACVLAN"); case NM_DEVICE_TYPE_VXLAN: return _("VXLAN"); + case NM_DEVICE_TYPE_GENEVE: + return _("GENEVE"); case NM_DEVICE_TYPE_IP_TUNNEL: return _("IPTunnel"); case NM_DEVICE_TYPE_TUN: diff --git a/src/libnm-client-impl/nm-libnm-utils.c b/src/libnm-client-impl/nm-libnm-utils.c index 1b25c92c..1c80c1dc 100644 --- a/src/libnm-client-impl/nm-libnm-utils.c +++ b/src/libnm-client-impl/nm-libnm-utils.c @@ -782,6 +782,7 @@ const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[] = { &_nml_dbus_meta_iface_nm_device_bridge, &_nml_dbus_meta_iface_nm_device_dummy, &_nml_dbus_meta_iface_nm_device_generic, + &_nml_dbus_meta_iface_nm_device_geneve, &_nml_dbus_meta_iface_nm_device_hsr, &_nml_dbus_meta_iface_nm_device_iptunnel, &_nml_dbus_meta_iface_nm_device_infiniband, diff --git a/src/libnm-client-impl/nm-libnm-utils.h b/src/libnm-client-impl/nm-libnm-utils.h index 7dcf8c18..27b77b60 100644 --- a/src/libnm-client-impl/nm-libnm-utils.h +++ b/src/libnm-client-impl/nm-libnm-utils.h @@ -579,7 +579,7 @@ struct _NMLDBusMetaIface { NML_DBUS_META_IFACE_OBJ_PROPERTIES(), \ ##__VA_ARGS__) -extern const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[47]; +extern const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[48]; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_accesspoint; @@ -593,6 +593,7 @@ extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bond; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_bridge; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_dummy; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_generic; +extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_geneve; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_hsr; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_infiniband; extern const NMLDBusMetaIface _nml_dbus_meta_iface_nm_device_iptunnel; |