diff options
author | Thomas Haller <thaller@redhat.com> | 2020-07-18 19:01:04 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-07-23 15:29:24 +0200 |
commit | 88d057978d6f2c40f7d72ab7db4f723768cfef10 (patch) | |
tree | 84e828450b65cf540eed84fee2ce9766d15628c0 | |
parent | d32074e2b6e637aab7e64c985c6da35a748344cc (diff) | |
download | NetworkManager-88d057978d6f2c40f7d72ab7db4f723768cfef10.tar.gz |
core: add "nm-l3cfg.[hc]"
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | src/meson.build | 1 | ||||
-rw-r--r-- | src/nm-l3cfg.c | 137 | ||||
-rw-r--r-- | src/nm-l3cfg.h | 55 | ||||
-rw-r--r-- | src/nm-netns.c | 93 | ||||
-rw-r--r-- | src/nm-netns.h | 3 | ||||
-rw-r--r-- | src/nm-types.h | 1 |
7 files changed, 293 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index 01fd835e17..20bc92cb3d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2170,6 +2170,9 @@ src_libNetworkManager_la_SOURCES = \ src/nm-checkpoint-manager.c \ src/nm-checkpoint-manager.h \ \ + src/nm-l3cfg.c \ + src/nm-l3cfg.h \ + \ src/devices/nm-acd-manager.c \ src/devices/nm-acd-manager.h \ src/devices/nm-lldp-listener.c \ diff --git a/src/meson.build b/src/meson.build index 8ff9bd11de..eaba2b4ea5 100644 --- a/src/meson.build +++ b/src/meson.build @@ -131,6 +131,7 @@ sources = files( 'nm-auth-manager.c', 'nm-auth-utils.c', 'nm-dbus-manager.c', + 'nm-l3cfg.c', 'nm-checkpoint.c', 'nm-checkpoint-manager.c', 'nm-config.c', diff --git a/src/nm-l3cfg.c b/src/nm-l3cfg.c new file mode 100644 index 0000000000..aaaad02b6e --- /dev/null +++ b/src/nm-l3cfg.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: LGPL-2.1+ + +#include "nm-default.h" + +#include "nm-l3cfg.h" + +#include "platform/nm-platform.h" +#include "nm-netns.h" + +/*****************************************************************************/ + +NM_GOBJECT_PROPERTIES_DEFINE (NML3Cfg, + PROP_NETNS, + PROP_IFINDEX, +); + +struct _NML3CfgClass { + GObjectClass parent; +}; + +G_DEFINE_TYPE (NML3Cfg, nm_l3cfg, G_TYPE_OBJECT) + +/*****************************************************************************/ + +#define _NMLOG_DOMAIN LOGD_CORE +#define _NMLOG_PREFIX_NAME "l3cfg" +#define _NMLOG(level, ...) \ + G_STMT_START { \ + nm_log ((level), (_NMLOG_DOMAIN), NULL, NULL, \ + "l3cfg["NM_HASH_OBFUSCATE_PTR_FMT",ifindex=%d]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + NM_HASH_OBFUSCATE_PTR (self), \ + nm_l3cfg_get_ifindex (self) \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } G_STMT_END + +/*****************************************************************************/ + +static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + NML3Cfg *self = NM_L3CFG (object); + + switch (prop_id) { + case PROP_NETNS: + /* construct-only */ + self->priv.netns = g_object_ref (g_value_get_pointer (value)); + nm_assert (NM_IS_NETNS (self->priv.netns)); + break; + case PROP_IFINDEX: + /* construct-only */ + self->priv.ifindex = g_value_get_int (value); + nm_assert (self->priv.ifindex > 0); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/*****************************************************************************/ + +static void +nm_l3cfg_init (NML3Cfg *self) +{ +} + +static void +constructed (GObject *object) +{ + NML3Cfg *self = NM_L3CFG (object); + + nm_assert (NM_IS_NETNS (self->priv.netns)); + nm_assert (self->priv.ifindex > 0); + + self->priv.platform = g_object_ref (nm_netns_get_platform (self->priv.netns)); + nm_assert (NM_IS_PLATFORM (self->priv.platform)); + + _LOGT ("created (netns="NM_HASH_OBFUSCATE_PTR_FMT")", + NM_HASH_OBFUSCATE_PTR (self->priv.netns)); + + G_OBJECT_CLASS (nm_l3cfg_parent_class)->constructed (object); +} + +NML3Cfg * +nm_l3cfg_new (NMNetns *netns, int ifindex) +{ + nm_assert (NM_IS_NETNS (netns)); + nm_assert (ifindex > 0); + + return g_object_new (NM_TYPE_L3CFG, + NM_L3CFG_NETNS, netns, + NM_L3CFG_IFINDEX, ifindex, + NULL); +} + +static void +finalize (GObject *object) +{ + NML3Cfg *self = NM_L3CFG (object); + + g_clear_object (&self->priv.netns); + g_clear_object (&self->priv.platform); + + _LOGT ("finalized"); + + G_OBJECT_CLASS (nm_l3cfg_parent_class)->finalize (object); +} + +static void +nm_l3cfg_class_init (NML3CfgClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = set_property; + object_class->constructed = constructed; + object_class->finalize = finalize; + + obj_properties[PROP_NETNS] = + g_param_spec_pointer (NM_L3CFG_NETNS, "", "", + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + obj_properties[PROP_IFINDEX] = + g_param_spec_int (NM_L3CFG_IFINDEX, "", "", + 0, + G_MAXINT, + 0, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); +} diff --git a/src/nm-l3cfg.h b/src/nm-l3cfg.h new file mode 100644 index 0000000000..4f035e231a --- /dev/null +++ b/src/nm-l3cfg.h @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: LGPL-2.1+ + +#ifndef __NM_L3CFG_H__ +#define __NM_L3CFG_H__ + +#define NM_TYPE_L3CFG (nm_l3cfg_get_type ()) +#define NM_L3CFG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_L3CFG, NML3Cfg)) +#define NM_L3CFG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_L3CFG, NML3CfgClass)) +#define NM_IS_L3CFG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_L3CFG)) +#define NM_IS_L3CFG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_L3CFG)) +#define NM_L3CFG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_L3CFG, NML3CfgClass)) + +#define NM_L3CFG_NETNS "netns" +#define NM_L3CFG_IFINDEX "ifindex" + +struct _NML3Cfg { + GObject parent; + struct { + NMNetns *netns; + NMPlatform *platform; + int ifindex; + } priv; +}; + +typedef struct _NML3CfgClass NML3CfgClass; + +GType nm_l3cfg_get_type (void); + +NML3Cfg *nm_l3cfg_new (NMNetns *netns, int ifindex); + +static inline int +nm_l3cfg_get_ifindex (const NML3Cfg *self) +{ + nm_assert (NM_IS_L3CFG (self)); + + return self->priv.ifindex; +} + +static inline NMNetns * +nm_l3cfg_get_netns (const NML3Cfg *self) +{ + nm_assert (NM_IS_L3CFG (self)); + + return self->priv.netns; +} + +static inline NMPlatform * +nm_l3cfg_get_platform (const NML3Cfg *self) +{ + nm_assert (NM_IS_L3CFG (self)); + + return self->priv.platform; +} + +#endif /* __NM_L3CFG_H__ */ diff --git a/src/nm-netns.c b/src/nm-netns.c index 3652384ad9..cafb73164c 100644 --- a/src/nm-netns.c +++ b/src/nm-netns.c @@ -11,6 +11,7 @@ #include "NetworkManagerUtils.h" #include "nm-core-internal.h" +#include "nm-l3cfg.h" #include "platform/nm-platform.h" #include "platform/nmp-netns.h" #include "platform/nmp-rules-manager.h" @@ -25,6 +26,7 @@ typedef struct { NMPlatform *platform; NMPNetns *platform_netns; NMPRulesManager *rules_manager; + GHashTable *l3cfgs; } NMNetnsPrivate; struct _NMNetns { @@ -42,6 +44,18 @@ G_DEFINE_TYPE (NMNetns, nm_netns, G_TYPE_OBJECT); /*****************************************************************************/ +#define _NMLOG_DOMAIN LOGD_CORE +#define _NMLOG_PREFIX_NAME "netns" +#define _NMLOG(level, ...) \ + G_STMT_START { \ + nm_log ((level), (_NMLOG_DOMAIN), NULL, NULL, \ + "netns["NM_HASH_OBFUSCATE_PTR_FMT"]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + NM_HASH_OBFUSCATE_PTR (self) \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } G_STMT_END + +/*****************************************************************************/ + NM_DEFINE_SINGLETON_GETTER (NMNetns, nm_netns_get, NM_TYPE_NETNS); /*****************************************************************************/ @@ -72,6 +86,80 @@ nm_netns_get_multi_idx (NMNetns *self) /*****************************************************************************/ +typedef struct { + int ifindex; + NML3Cfg *l3cfg; +} L3CfgData; + +static void +_l3cfg_data_free (gpointer ptr) +{ + L3CfgData *l3cfg_data = ptr; + + nm_g_slice_free (l3cfg_data); +} + +static void +_l3cfg_weak_notify (gpointer data, + GObject *where_the_object_was) +{ + NMNetns *self = NM_NETNS (data); + NMNetnsPrivate *priv = NM_NETNS_GET_PRIVATE(data); + NML3Cfg *l3cfg = NM_L3CFG (where_the_object_was); + int ifindex = nm_l3cfg_get_ifindex (l3cfg); + + if (!g_hash_table_remove (priv->l3cfgs, &ifindex)) + nm_assert_not_reached (); + + if (NM_UNLIKELY (g_hash_table_size (priv->l3cfgs) == 0)) + g_object_unref (self); +} + +NML3Cfg * +nm_netns_access_l3cfg (NMNetns *self, + int ifindex) +{ + NMNetnsPrivate *priv; + L3CfgData *l3cfg_data; + + g_return_val_if_fail (NM_IS_NETNS (self), NULL); + g_return_val_if_fail (ifindex > 0, NULL); + + priv = NM_NETNS_GET_PRIVATE (self); + + l3cfg_data = g_hash_table_lookup (priv->l3cfgs, &ifindex); + + if (l3cfg_data) { + nm_log_trace (LOGD_CORE, + "l3cfg["NM_HASH_OBFUSCATE_PTR_FMT",ifindex=%d] %s", + NM_HASH_OBFUSCATE_PTR (l3cfg_data->l3cfg), + ifindex, + "referenced"); + return g_object_ref (l3cfg_data->l3cfg); + } + + l3cfg_data = g_slice_new (L3CfgData); + *l3cfg_data = (L3CfgData) { + .ifindex = ifindex, + .l3cfg = nm_l3cfg_new (self, ifindex), + }; + + if (!g_hash_table_add (priv->l3cfgs, l3cfg_data)) + nm_assert_not_reached (); + + if (NM_UNLIKELY (g_hash_table_size (priv->l3cfgs) == 1)) + g_object_ref (self); + + g_object_weak_ref (G_OBJECT (l3cfg_data->l3cfg), + _l3cfg_weak_notify, + self); + + /* Transfer ownership! We keep only a weak ref. */ + return l3cfg_data->l3cfg; +} + +/*****************************************************************************/ + static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) @@ -109,6 +197,8 @@ constructed (GObject *object) if (!priv->platform) g_return_if_reached (); + priv->l3cfgs = g_hash_table_new_full (nm_pint_hash, nm_pint_equals, _l3cfg_data_free, NULL); + priv->platform_netns = nm_platform_netns_get (priv->platform); priv->rules_manager = nmp_rules_manager_new (priv->platform); @@ -152,7 +242,10 @@ dispose (GObject *object) NMNetns *self = NM_NETNS (object); NMNetnsPrivate *priv = NM_NETNS_GET_PRIVATE (self); + nm_assert (nm_g_hash_table_size (priv->l3cfgs) == 0); + g_clear_object (&priv->platform); + g_clear_pointer (&priv->l3cfgs, g_hash_table_unref); nm_clear_pointer (&priv->rules_manager, nmp_rules_manager_unref); diff --git a/src/nm-netns.h b/src/nm-netns.h index c65dd9076c..2af0242b8d 100644 --- a/src/nm-netns.h +++ b/src/nm-netns.h @@ -31,4 +31,7 @@ struct _NMDedupMultiIndex *nm_netns_get_multi_idx (NMNetns *self); #define NM_NETNS_GET (nm_netns_get ()) +NML3Cfg *nm_netns_access_l3cfg (NMNetns *netns, + int ifindex); + #endif /* __NM_NETNS_H__ */ diff --git a/src/nm-types.h b/src/nm-types.h index d2c999fada..5835c64188 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -23,6 +23,7 @@ typedef struct _NMDBusManager NMDBusManager; typedef struct _NMConfig NMConfig; typedef struct _NMConfigData NMConfigData; typedef struct _NMConnectivity NMConnectivity; +typedef struct _NML3Cfg NML3Cfg; typedef struct _NMDevice NMDevice; typedef struct _NMDhcpConfig NMDhcpConfig; typedef struct _NMProxyConfig NMProxyConfig; |