NetworkManager/src/core/nm-dhcp-config.c
Thomas Haller 0b1177cb18
all: use _NM_G_TYPE_CHECK_INSTANCE_CAST() for internal uses
G_TYPE_CHECK_INSTANCE_CAST() can trigger a "-Wcast-align":

    src/core/devices/nm-device-macvlan.c: In function 'parent_changed_notify':
    /usr/include/glib-2.0/gobject/gtype.h:2421:42: error: cast increases required alignment of target type [-Werror=cast-align]
     2421 | #  define _G_TYPE_CIC(ip, gt, ct)       ((ct*) ip)
          |                                          ^
    /usr/include/glib-2.0/gobject/gtype.h:501:66: note: in expansion of macro '_G_TYPE_CIC'
      501 | #define G_TYPE_CHECK_INSTANCE_CAST(instance, g_type, c_type)    (_G_TYPE_CIC ((instance), (g_type), c_type))
          |                                                                  ^~~~~~~~~~~
    src/core/devices/nm-device-macvlan.h:13:6: note: in expansion of macro 'G_TYPE_CHECK_INSTANCE_CAST'
       13 |     (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_MACVLAN, NMDeviceMacvlan))
          |      ^~~~~~~~~~~~~~~~~~~~~~~~~~

Avoid that by using _NM_G_TYPE_CHECK_INSTANCE_CAST().

This can only be done for our internal usages. The public headers
of libnm are not changed.
2022-12-16 10:55:03 +01:00

340 lines
11 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2008 Red Hat, Inc.
*/
#include "src/core/nm-default-daemon.h"
#include "nm-dhcp-config.h"
#include "nm-dbus-interface.h"
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
#include "nm-dbus-object.h"
#include "nm-core-utils.h"
#include "nm-l3-config-data.h"
/*****************************************************************************/
#define NM_TYPE_DHCP4_CONFIG (nm_dhcp4_config_get_type())
#define NM_DHCP4_CONFIG(obj) \
(_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP4_CONFIG, NMDhcp4Config))
#define NM_DHCP4_CONFIG_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP4_CONFIG, NMDhcp4ConfigClass))
#define NM_IS_DHCP4_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP4_CONFIG))
#define NM_IS_DHCP4_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP4_CONFIG))
#define NM_DHCP4_CONFIG_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP4_CONFIG, NMDhcp4ConfigClass))
typedef struct _NMDhcp4Config NMDhcp4Config;
typedef struct _NMDhcp4ConfigClass NMDhcp4ConfigClass;
static GType nm_dhcp4_config_get_type(void);
#define NM_TYPE_DHCP6_CONFIG (nm_dhcp6_config_get_type())
#define NM_DHCP6_CONFIG(obj) \
(_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DHCP6_CONFIG, NMDhcp6Config))
#define NM_DHCP6_CONFIG_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DHCP6_CONFIG, NMDhcp6ConfigClass))
#define NM_IS_DHCP6_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DHCP6_CONFIG))
#define NM_IS_DHCP6_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DHCP6_CONFIG))
#define NM_DHCP6_CONFIG_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DHCP6_CONFIG, NMDhcp6ConfigClass))
typedef struct _NMDhcp6Config NMDhcp6Config;
typedef struct _NMDhcp6ConfigClass NMDhcp6ConfigClass;
static GType nm_dhcp6_config_get_type(void);
/*****************************************************************************/
NM_GOBJECT_PROPERTIES_DEFINE(NMDhcpConfig, PROP_L3CD, PROP_OPTIONS, );
typedef struct {
const NML3ConfigData *l3cd;
GVariant *options;
} NMDhcpConfigPrivate;
struct _NMDhcpConfig {
NMDBusObject parent;
NMDhcpConfigPrivate _priv;
};
struct _NMDhcpConfigClass {
NMDBusObjectClass parent;
int addr_family;
};
G_DEFINE_ABSTRACT_TYPE(NMDhcpConfig, nm_dhcp_config, NM_TYPE_DBUS_OBJECT)
#define NM_DHCP_CONFIG_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMDhcpConfig, NM_IS_DHCP_CONFIG)
/*****************************************************************************/
int
nm_dhcp_config_get_addr_family(NMDhcpConfig *self)
{
return NM_DHCP_CONFIG_GET_CLASS(self)->addr_family;
}
/*****************************************************************************/
static GVariant *
_l3cd_to_options(const NML3ConfigData *l3cd, int addr_family)
{
GVariant *options;
options = NULL;
if (l3cd) {
NMDhcpLease *lease;
lease = nm_l3_config_data_get_dhcp_lease(l3cd, addr_family);
if (lease)
options = nm_strdict_to_variant_asv(nm_dhcp_lease_get_options(lease));
}
if (!options)
options = nm_g_variant_singleton_aLsvI();
return g_variant_ref_sink(options);
}
void
nm_dhcp_config_set_lease(NMDhcpConfig *self, const NML3ConfigData *l3cd)
{
nm_auto_unref_l3cd const NML3ConfigData *l3cd_old = NULL;
gs_unref_variant GVariant *options2 = NULL;
NMDhcpConfigPrivate *priv;
g_return_if_fail(NM_IS_DHCP_CONFIG(self));
priv = NM_DHCP_CONFIG_GET_PRIVATE(self);
if (priv->l3cd == l3cd)
return;
l3cd_old = g_steal_pointer(&priv->l3cd);
if (l3cd)
priv->l3cd = nm_l3_config_data_ref_and_seal(l3cd);
options2 = _l3cd_to_options(priv->l3cd, nm_dhcp_config_get_addr_family(self));
if (g_variant_equal(priv->options, options2))
return;
NM_SWAP(&priv->options, &options2);
_notify(self, PROP_OPTIONS);
}
NMUtilsNamedValue *
nm_dhcp_config_get_option_values(NMDhcpConfig *self, guint *num)
{
NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE(self);
NMDhcpLease *lease;
NMUtilsNamedValue *buffer = NULL;
if (!priv->l3cd) {
NM_SET_OUT(num, 0);
return NULL;
}
lease = nm_l3_config_data_get_dhcp_lease(priv->l3cd, nm_dhcp_config_get_addr_family(self));
nm_utils_named_values_from_strdict_full(nm_dhcp_lease_get_options(lease),
num,
nm_strcmp_p_with_data,
NULL,
NULL,
0,
&buffer);
return buffer;
}
const char *
nm_dhcp_config_get_option(NMDhcpConfig *self, const char *key)
{
NMDhcpConfigPrivate *priv;
NMDhcpLease *lease;
g_return_val_if_fail(NM_IS_DHCP_CONFIG(self), NULL);
g_return_val_if_fail(key, NULL);
priv = NM_DHCP_CONFIG_GET_PRIVATE(self);
if (!priv->l3cd)
return NULL;
lease = nm_l3_config_data_get_dhcp_lease(priv->l3cd, nm_dhcp_config_get_addr_family(self));
return nm_dhcp_lease_lookup_option(lease, key);
}
/*****************************************************************************/
GVariant *
nm_dhcp_config_get_options(NMDhcpConfig *self)
{
g_return_val_if_fail(NM_IS_DHCP_CONFIG(self), NULL);
return NM_DHCP_CONFIG_GET_PRIVATE(self)->options;
}
/*****************************************************************************/
static void
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE(object);
switch (prop_id) {
case PROP_OPTIONS:
g_value_set_variant(value, priv->options);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
static void
set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
NMDhcpConfig *self = NM_DHCP_CONFIG(object);
NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE(self);
switch (prop_id) {
case PROP_L3CD:
/* construct-only */
priv->l3cd = nm_l3_config_data_ref_and_seal(g_value_get_pointer(value));
priv->options = _l3cd_to_options(priv->l3cd, nm_dhcp_config_get_addr_family(self));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
/*****************************************************************************/
static void
nm_dhcp_config_init(NMDhcpConfig *self)
{}
NMDhcpConfig *
nm_dhcp_config_new(int addr_family, const NML3ConfigData *l3cd)
{
return g_object_new(NM_IS_IPv4(addr_family) ? NM_TYPE_DHCP4_CONFIG : NM_TYPE_DHCP6_CONFIG,
NM_DHCP_CONFIG_L3CD,
l3cd,
NULL);
}
static void
finalize(GObject *object)
{
NMDhcpConfigPrivate *priv = NM_DHCP_CONFIG_GET_PRIVATE(object);
g_variant_unref(priv->options);
nm_l3_config_data_unref(priv->l3cd);
G_OBJECT_CLASS(nm_dhcp_config_parent_class)->finalize(object);
}
static void
nm_dhcp_config_class_init(NMDhcpConfigClass *config_class)
{
GObjectClass *object_class = G_OBJECT_CLASS(config_class);
object_class->get_property = get_property;
object_class->set_property = set_property;
object_class->finalize = finalize;
obj_properties[PROP_L3CD] =
g_param_spec_pointer(NM_DHCP_CONFIG_L3CD,
"",
"",
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_OPTIONS] = g_param_spec_variant(NM_DHCP_CONFIG_OPTIONS,
"",
"",
G_VARIANT_TYPE("a{sv}"),
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
}
/*****************************************************************************/
struct _NMDhcp4Config {
NMDhcpConfig parent;
};
struct _NMDhcp4ConfigClass {
NMDhcpConfigClass parent;
};
G_DEFINE_TYPE(NMDhcp4Config, nm_dhcp4_config, NM_TYPE_DHCP_CONFIG)
static void
nm_dhcp4_config_init(NMDhcp4Config *self)
{}
static const NMDBusInterfaceInfoExtended interface_info_dhcp4_config = {
.parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
NM_DBUS_INTERFACE_DHCP4_CONFIG,
.properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Options",
"a{sv}",
NM_DHCP_CONFIG_OPTIONS), ), ),
};
static void
nm_dhcp4_config_class_init(NMDhcp4ConfigClass *klass)
{
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
NMDhcpConfigClass *dhcp_config_class = NM_DHCP_CONFIG_CLASS(klass);
dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH "/DHCP4Config");
dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_dhcp4_config);
dbus_object_class->export_on_construction = TRUE;
dhcp_config_class->addr_family = AF_INET;
}
/*****************************************************************************/
struct _NMDhcp6Config {
NMDhcpConfig parent;
};
struct _NMDhcp6ConfigClass {
NMDhcpConfigClass parent;
};
G_DEFINE_TYPE(NMDhcp6Config, nm_dhcp6_config, NM_TYPE_DHCP_CONFIG)
static void
nm_dhcp6_config_init(NMDhcp6Config *self)
{}
static const NMDBusInterfaceInfoExtended interface_info_dhcp6_config = {
.parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
NM_DBUS_INTERFACE_DHCP6_CONFIG,
.properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Options",
"a{sv}",
NM_DHCP_CONFIG_OPTIONS), ), ),
};
static void
nm_dhcp6_config_class_init(NMDhcp6ConfigClass *klass)
{
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
NMDhcpConfigClass *dhcp_config_class = NM_DHCP_CONFIG_CLASS(klass);
dbus_object_class->export_path = NM_DBUS_EXPORT_PATH_NUMBERED(NM_DBUS_PATH "/DHCP6Config");
dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_dhcp6_config);
dbus_object_class->export_on_construction = TRUE;
dhcp_config_class->addr_family = AF_INET6;
}