From 03dc5ad3919f451136ef1b14cbd3f0e971a9307e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 28 Jun 2021 18:14:04 +0200 Subject: [PATCH] libnm: let NMSettingIPConfigPrivate be tracked by subclasses For our property meta data handling we require that all the meta data is associated with one GType. NMSettingIPConfig is a parent class of NMSettingIP[46]Config. Note that we already have _nm_sett_info_property_override_create_array_ip_config() because the meta data must be initialized together at one place. We will require that we can find the offset for properties based on one offset per type. That is cumbersome, if NMSettingIPConfigPrivate is private itself. Simplify that, by internally sharing NMSettingIPConfigPrivate and let the subclasses embed the private data in their own private data. Optimally we would simply embed the private struct as field into NMSettingIPConfig. But that would be an ABI change as that struct was public before 1.32. Don't change ABI for now, so we have to awkwardly place it into the subclasses private data. --- src/libnm-core-impl/nm-setting-ip-config.c | 59 +++++++++------------ src/libnm-core-impl/nm-setting-ip4-config.c | 21 +++++--- src/libnm-core-impl/nm-setting-ip6-config.c | 15 ++++-- src/libnm-core-impl/nm-setting-private.h | 37 ++++++++++++- 4 files changed, 87 insertions(+), 45 deletions(-) diff --git a/src/libnm-core-impl/nm-setting-ip-config.c b/src/libnm-core-impl/nm-setting-ip-config.c index 2ae02eeb99..ddd1cc8d54 100644 --- a/src/libnm-core-impl/nm-setting-ip-config.c +++ b/src/libnm-core-impl/nm-setting-ip-config.c @@ -3911,36 +3911,25 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingIPConfig, PROP_DHCP_IAID, PROP_DHCP_REJECT_SERVERS, ); -typedef struct { - GPtrArray *dns; /* array of IP address strings */ - GPtrArray *dns_search; /* array of domain name strings */ - GPtrArray *dns_options; /* array of DNS options */ - GPtrArray *addresses; /* array of NMIPAddress */ - GPtrArray *routes; /* array of NMIPRoute */ - GPtrArray *routing_rules; - GArray * dhcp_reject_servers; - char * method; - char * gateway; - char * dhcp_hostname; - char * dhcp_iaid; - gint64 route_metric; - guint dhcp_hostname_flags; - int dns_priority; - int dad_timeout; - int dhcp_timeout; - int required_timeout; - guint32 route_table; - bool ignore_auto_routes : 1; - bool ignore_auto_dns : 1; - bool dhcp_send_hostname : 1; - bool never_default : 1; - bool may_fail : 1; -} NMSettingIPConfigPrivate; - G_DEFINE_ABSTRACT_TYPE(NMSettingIPConfig, nm_setting_ip_config, NM_TYPE_SETTING) -#define NM_SETTING_IP_CONFIG_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE((o), NM_TYPE_SETTING_IP_CONFIG, NMSettingIPConfigPrivate)) +static inline NMSettingIPConfigPrivate * +_NM_SETTING_IP_CONFIG_GET_PRIVATE(NMSettingIPConfig *self) +{ + NMSettingIPConfigClass *klass; + + nm_assert(NM_IS_SETTING_IP_CONFIG(self)); + + klass = NM_SETTING_IP_CONFIG_GET_CLASS(self); + + nm_assert(klass->private_offset < 0); + + return (gpointer) (((char *) ((gpointer) self)) + klass->private_offset); +} + +#define NM_SETTING_IP_CONFIG_GET_PRIVATE(self) \ + _NM_SETTING_IP_CONFIG_GET_PRIVATE( \ + NM_GOBJECT_CAST_NON_NULL(NMSettingIPConfig, self, NM_IS_SETTING_IP_CONFIG, NMSetting)) /*****************************************************************************/ @@ -6065,10 +6054,10 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps /*****************************************************************************/ -static void -nm_setting_ip_config_init(NMSettingIPConfig *setting) +void +_nm_setting_ip_config_private_init(gpointer self, NMSettingIPConfigPrivate *priv) { - NMSettingIPConfigPrivate *priv = NM_SETTING_IP_CONFIG_GET_PRIVATE(setting); + nm_assert(NM_IS_SETTING_IP_CONFIG(self)); priv->dns = g_ptr_array_new_with_free_func(g_free); priv->dns_search = g_ptr_array_new_with_free_func(g_free); @@ -6081,6 +6070,12 @@ nm_setting_ip_config_init(NMSettingIPConfig *setting) priv->required_timeout = -1; } +static void +nm_setting_ip_config_init(NMSettingIPConfig *setting) +{ + /* cannot yet access NM_SETTING_IP_CONFIG_GET_PRIVATE(). */ +} + static void finalize(GObject *object) { @@ -6111,8 +6106,6 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass) GObjectClass * object_class = G_OBJECT_CLASS(klass); NMSettingClass *setting_class = NM_SETTING_CLASS(klass); - g_type_class_add_private(klass, sizeof(NMSettingIPConfigPrivate)); - object_class->get_property = get_property; object_class->set_property = set_property; object_class->finalize = finalize; diff --git a/src/libnm-core-impl/nm-setting-ip4-config.c b/src/libnm-core-impl/nm-setting-ip4-config.c index f7f5931e4f..1704820bde 100644 --- a/src/libnm-core-impl/nm-setting-ip4-config.c +++ b/src/libnm-core-impl/nm-setting-ip4-config.c @@ -40,6 +40,8 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_DHCP_CLIENT_ID, PROP_DHCP_VENDOR_CLASS_IDENTIFIER, ); typedef struct { + NMSettingIPConfigPrivate parent; + char *dhcp_client_id; char *dhcp_fqdn; char *dhcp_vendor_class_identifier; @@ -598,7 +600,11 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps static void nm_setting_ip4_config_init(NMSettingIP4Config *setting) -{} +{ + NMSettingIP4ConfigPrivate *priv = NM_SETTING_IP4_CONFIG_GET_PRIVATE(setting); + + _nm_setting_ip_config_private_init(setting, &priv->parent); +} /** * nm_setting_ip4_config_new: @@ -628,11 +634,12 @@ finalize(GObject *object) static void nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) { - GObjectClass * object_class = G_OBJECT_CLASS(klass); - NMSettingClass *setting_class = NM_SETTING_CLASS(klass); - GArray * properties_override = _nm_sett_info_property_override_create_array_ip_config(); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass * setting_class = NM_SETTING_CLASS(klass); + NMSettingIPConfigClass *setting_ip_config_class = NM_SETTING_IP_CONFIG_CLASS(klass); + GArray *properties_override = _nm_sett_info_property_override_create_array_ip_config(); - g_type_class_add_private(setting_class, sizeof(NMSettingIP4ConfigPrivate)); + g_type_class_add_private(klass, sizeof(NMSettingIP4ConfigPrivate)); object_class->get_property = get_property; object_class->set_property = set_property; @@ -640,6 +647,8 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) setting_class->verify = verify; + setting_ip_config_class->private_offset = g_type_class_get_instance_private_offset(klass); + /* ---ifcfg-rh--- * property: method * variable: BOOTPROTO @@ -1056,5 +1065,5 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) NM_META_SETTING_TYPE_IP4_CONFIG, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + setting_ip_config_class->private_offset); } diff --git a/src/libnm-core-impl/nm-setting-ip6-config.c b/src/libnm-core-impl/nm-setting-ip6-config.c index c72418dd69..55564d602f 100644 --- a/src/libnm-core-impl/nm-setting-ip6-config.c +++ b/src/libnm-core-impl/nm-setting-ip6-config.c @@ -45,6 +45,8 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_IP6_PRIVACY, PROP_RA_TIMEOUT, ); typedef struct { + NMSettingIPConfigPrivate parent; + char * token; char * dhcp_duid; NMSettingIP6ConfigPrivacy ip6_privacy; @@ -594,6 +596,8 @@ nm_setting_ip6_config_init(NMSettingIP6Config *setting) { NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE(setting); + _nm_setting_ip_config_private_init(setting, &priv->parent); + priv->ip6_privacy = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; priv->addr_gen_mode = NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY; } @@ -626,9 +630,10 @@ finalize(GObject *object) static void nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) { - GObjectClass * object_class = G_OBJECT_CLASS(klass); - NMSettingClass *setting_class = NM_SETTING_CLASS(klass); - GArray * properties_override = _nm_sett_info_property_override_create_array_ip_config(); + GObjectClass * object_class = G_OBJECT_CLASS(klass); + NMSettingClass * setting_class = NM_SETTING_CLASS(klass); + NMSettingIPConfigClass *setting_ip_config_class = NM_SETTING_IP_CONFIG_CLASS(klass); + GArray *properties_override = _nm_sett_info_property_override_create_array_ip_config(); g_type_class_add_private(klass, sizeof(NMSettingIP6ConfigPrivate)); @@ -638,6 +643,8 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) setting_class->verify = verify; + setting_ip_config_class->private_offset = g_type_class_get_instance_private_offset(klass); + /* ---ifcfg-rh--- * property: method * variable: IPV6INIT, IPV6FORWARDING, IPV6_AUTOCONF, DHCPV6C, IPV6_DISABLED @@ -1100,5 +1107,5 @@ nm_setting_ip6_config_class_init(NMSettingIP6ConfigClass *klass) NM_META_SETTING_TYPE_IP6_CONFIG, NULL, properties_override, - NM_SETT_INFO_PRIVATE_OFFSET_FROM_CLASS); + setting_ip_config_class->private_offset); } diff --git a/src/libnm-core-impl/nm-setting-private.h b/src/libnm-core-impl/nm-setting-private.h index 5c533d4ade..656d438531 100644 --- a/src/libnm-core-impl/nm-setting-private.h +++ b/src/libnm-core-impl/nm-setting-private.h @@ -127,15 +127,48 @@ struct _NMSettingClass { */ struct _NMSettingIPConfig { NMSetting parent; + /* In the past, this struct was public API. Preserve ABI! */ }; struct _NMSettingIPConfigClass { NMSettingClass parent; - /* Padding for future expansion */ - gpointer padding[8]; + /* In the past, this struct was public API. Preserve ABI! */ + union { + gpointer _dummy; + int private_offset; + }; + gpointer padding[7]; }; +typedef struct { + GPtrArray *dns; /* array of IP address strings */ + GPtrArray *dns_search; /* array of domain name strings */ + GPtrArray *dns_options; /* array of DNS options */ + GPtrArray *addresses; /* array of NMIPAddress */ + GPtrArray *routes; /* array of NMIPRoute */ + GPtrArray *routing_rules; + GArray * dhcp_reject_servers; + char * method; + char * gateway; + char * dhcp_hostname; + char * dhcp_iaid; + gint64 route_metric; + guint dhcp_hostname_flags; + int dns_priority; + int dad_timeout; + int dhcp_timeout; + int required_timeout; + guint32 route_table; + bool ignore_auto_routes : 1; + bool ignore_auto_dns : 1; + bool dhcp_send_hostname : 1; + bool never_default : 1; + bool may_fail : 1; +} NMSettingIPConfigPrivate; + +void _nm_setting_ip_config_private_init(gpointer self, NMSettingIPConfigPrivate *priv); + /*****************************************************************************/ NMSettingPriority _nm_setting_get_base_type_priority(NMSetting *setting);