From 379dde287cafd383024495b8fa83f2fbe3b5af07 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 26 Oct 2020 21:42:04 +0100 Subject: [PATCH] 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. --- src/nm-l3-ipv4ll.c | 3 +++ src/nm-l3cfg.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/nm-l3cfg.h | 8 ++++++++ 3 files changed, 55 insertions(+) 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__ */