summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-07-18 19:01:04 +0200
committerThomas Haller <thaller@redhat.com>2020-07-23 15:29:24 +0200
commit88d057978d6f2c40f7d72ab7db4f723768cfef10 (patch)
tree84e828450b65cf540eed84fee2ce9766d15628c0
parentd32074e2b6e637aab7e64c985c6da35a748344cc (diff)
downloadNetworkManager-88d057978d6f2c40f7d72ab7db4f723768cfef10.tar.gz
core: add "nm-l3cfg.[hc]"
-rw-r--r--Makefile.am3
-rw-r--r--src/meson.build1
-rw-r--r--src/nm-l3cfg.c137
-rw-r--r--src/nm-l3cfg.h55
-rw-r--r--src/nm-netns.c93
-rw-r--r--src/nm-netns.h3
-rw-r--r--src/nm-types.h1
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;