summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2020-10-26 21:42:04 +0100
committerThomas Haller <thaller@redhat.com>2020-10-27 17:04:20 +0100
commit379dde287cafd383024495b8fa83f2fbe3b5af07 (patch)
tree865e47ce04e8e738f66d3bfb44392948a60670e8
parent291b3a52b7286abb08ddeffb57f1883fd4dedb8a (diff)
downloadNetworkManager-379dde287cafd383024495b8fa83f2fbe3b5af07.tar.gz
l3cfg: let NML3Cfg return a singleton NML3IPv4LL instance
NML3Cfg is the manager instance for one interface (ifindex). For one interface, it is not supported (nor useful) to run IPv4LL multiple times. Hence, let NML3Cfg manage and return a single instance.
-rw-r--r--src/nm-l3-ipv4ll.c3
-rw-r--r--src/nm-l3cfg.c44
-rw-r--r--src/nm-l3cfg.h8
3 files changed, 55 insertions, 0 deletions
diff --git a/src/nm-l3-ipv4ll.c b/src/nm-l3-ipv4ll.c
index dea9cd3aee..fe76b96955 100644
--- a/src/nm-l3-ipv4ll.c
+++ b/src/nm-l3-ipv4ll.c
@@ -1028,6 +1028,9 @@ nm_l3_ipv4ll_unref(NML3IPv4LL *self)
if (--self->ref_count > 0)
return;
+ if (nm_l3cfg_get_ipv4ll(self->l3cfg) == self)
+ _nm_l3cfg_unregister_ipv4ll(self->l3cfg);
+
_LOGT("finalize");
nm_assert(c_list_is_empty(&self->reg_lst_head));
diff --git a/src/nm-l3cfg.c b/src/nm-l3cfg.c
index 901a21214a..b45084bb7b 100644
--- a/src/nm-l3cfg.c
+++ b/src/nm-l3cfg.c
@@ -147,6 +147,8 @@ typedef struct _NML3CfgPrivate {
GArray *property_emit_list;
GArray *l3_config_datas;
+ NML3IPv4LL *ipv4ll;
+
const NML3ConfigData *combined_l3cd_merged;
const NML3ConfigData *combined_l3cd_commited;
@@ -3608,6 +3610,47 @@ nm_l3cfg_has_commited_ip6_addresses_pending_dad(NML3Cfg *self)
/*****************************************************************************/
+NML3IPv4LL *
+nm_l3cfg_get_ipv4ll(NML3Cfg *self)
+{
+ g_return_val_if_fail(NM_IS_L3CFG(self), NULL);
+
+ return self->priv.p->ipv4ll;
+}
+
+NML3IPv4LL *
+nm_l3cfg_access_ipv4ll(NML3Cfg *self)
+{
+ g_return_val_if_fail(NM_IS_L3CFG(self), NULL);
+
+ if (self->priv.p->ipv4ll)
+ return nm_l3_ipv4ll_ref(self->priv.p->ipv4ll);
+
+ /* We return the reference. But the NML3IPv4LL instance
+ * will call _nm_l3cfg_unregister_ipv4ll() when it gets
+ * destroyed.
+ *
+ * We don't have weak references, but NML3Cfg and NML3IPv4LL
+ * cooperate to handle this reference. */
+ self->priv.p->ipv4ll = nm_l3_ipv4ll_new(self);
+ return self->priv.p->ipv4ll;
+}
+
+void
+_nm_l3cfg_unregister_ipv4ll(NML3Cfg *self)
+{
+ nm_assert(NM_IS_L3CFG(self));
+
+ /* we don't own the refernce to "self->priv.p->ipv4ll", but
+ * when that instance gets destroyed, we get called back to
+ * forget about it. Basically, it's like a weak pointer. */
+
+ nm_assert(self->priv.p->ipv4ll);
+ self->priv.p->ipv4ll = NULL;
+}
+
+/*****************************************************************************/
+
static void
set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
@@ -3675,6 +3718,7 @@ finalize(GObject *object)
NML3Cfg *self = NM_L3CFG(object);
nm_assert(!self->priv.p->l3_config_datas);
+ nm_assert(!self->priv.p->ipv4ll);
nm_assert(c_list_is_empty(&self->priv.p->commit_type_lst_head));
diff --git a/src/nm-l3cfg.h b/src/nm-l3cfg.h
index 52b0261fee..e83bdc9163 100644
--- a/src/nm-l3cfg.h
+++ b/src/nm-l3cfg.h
@@ -345,4 +345,12 @@ gboolean nm_l3cfg_has_commited_ip6_addresses_pending_dad(NML3Cfg *self);
/*****************************************************************************/
+struct _NML3IPv4LL *nm_l3cfg_get_ipv4ll(NML3Cfg *self);
+
+struct _NML3IPv4LL *nm_l3cfg_access_ipv4ll(NML3Cfg *self);
+
+void _nm_l3cfg_unregister_ipv4ll(NML3Cfg *self);
+
+/*****************************************************************************/
+
#endif /* __NM_L3CFG_H__ */