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__ */