diff options
author | Thomas Haller <thaller@redhat.com> | 2020-09-25 17:05:58 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-09-30 09:49:23 +0200 |
commit | ef198d0202341569f848f3bbf76a6751a1f621b8 (patch) | |
tree | 2ad06924252651fe77b9b616ed721cb85dda0b72 | |
parent | 5ed1027cab967779abac14881d3fb1bac4d8d7af (diff) | |
download | NetworkManager-ef198d0202341569f848f3bbf76a6751a1f621b8.tar.gz |
l3cfg: in NML3Cfg also track the current NMPlatformLink of the platform cache
NML3Cfg tends to perform actions on an idle handler. That means, when
it configures something on platform, it tends to ignore the changes and
process them later.
That means the currently tracked NMPObject with the platform link may
not be the same as NMPlatform currently has cached.
Instead, track them both, and extend the API so that it's clear that
there is a difference. You now need to say whether you want the instance
from the platform cache (the "next") or the currently used instance. Of
course, after the idle handler runs, "next" and the current one
converge.
This is useful because we want to reason about the link state (also) by
looking a our NML3Cfg instance. Since it already is connected to
platform, it can expose the same NMPObject.
-rw-r--r-- | src/nm-l3cfg.c | 36 | ||||
-rw-r--r-- | src/nm-l3cfg.h | 37 |
2 files changed, 46 insertions, 27 deletions
diff --git a/src/nm-l3cfg.c b/src/nm-l3cfg.c index 78d4a2045e..949d53e1a8 100644 --- a/src/nm-l3cfg.c +++ b/src/nm-l3cfg.c @@ -609,13 +609,19 @@ _load_link(NML3Cfg *self, gboolean initial) gboolean nacd_link_now_up; AcdData * acd_data; - obj = nm_platform_link_get_obj(self->priv.platform, self->priv.ifindex, TRUE); + if (initial) { + obj = nm_platform_link_get_obj(self->priv.platform, self->priv.ifindex, TRUE); + self->priv.plobj_next = nmp_object_ref(obj); + } else { + obj = self->priv.plobj_next; + nm_assert(obj == nm_platform_link_get_obj(self->priv.platform, self->priv.ifindex, TRUE)); + } - if (initial && obj == self->priv.pllink) + if (initial && obj == self->priv.plobj) return; - obj_old = g_steal_pointer(&self->priv.pllink); - self->priv.pllink = nmp_object_ref(obj); + obj_old = g_steal_pointer(&self->priv.plobj); + self->priv.plobj = nmp_object_ref(obj); if (obj && NM_FLAGS_HAS(NMP_OBJECT_CAST_LINK(obj)->n_ifi_flags, IFF_UP) && (!obj_old || !NM_FLAGS_HAS(NMP_OBJECT_CAST_LINK(obj_old)->n_ifi_flags, IFF_UP))) @@ -641,7 +647,7 @@ _load_link(NML3Cfg *self, gboolean initial) } else if (nacd_new_valid) nacd_changed = TRUE; ifname_old = nmp_object_link_get_ifname(obj_old); - ifname = nmp_object_link_get_ifname(self->priv.pllink); + ifname = nmp_object_link_get_ifname(self->priv.plobj); if (initial) { _LOGT("link ifname changed: %s%s%s (initial)", NM_PRINT_FMT_QUOTE_STRING(ifname)); @@ -671,7 +677,7 @@ _nm_l3cfg_notify_platform_change_on_idle(NML3Cfg *self, guint32 obj_type_flags) { NML3ConfigNotifyPayload payload; - if (NM_FLAGS_ANY(obj_type_flags, nmp_object_type_to_flags(NMP_OBJECT_TYPE_LINK))) + if (self->priv.plobj_next != self->priv.plobj) _load_link(self, FALSE); payload = (NML3ConfigNotifyPayload){ @@ -703,6 +709,15 @@ _nm_l3cfg_notify_platform_change(NML3Cfg * self, obj_type = NMP_OBJECT_GET_TYPE(obj); switch (obj_type) { + case NMP_OBJECT_TYPE_LINK: + { + const NMPObject *plobj; + + plobj = (change_type != NM_PLATFORM_SIGNAL_REMOVED) ? obj : NULL; + nm_assert(plobj == nm_platform_link_get_obj(self->priv.platform, self->priv.ifindex, TRUE)); + nmp_object_ref_set(&self->priv.plobj_next, plobj); + break; + } case NMP_OBJECT_TYPE_IP4_ADDRESS: _l3_acd_ipv4_addresses_on_link_update(self, NMP_OBJECT_CAST_IP4_ADDRESS(obj)->address, @@ -1067,9 +1082,9 @@ _l3_acd_nacd_event(int fd, GIOCondition condition, gpointer user_data) _LOGW("IPv4 address collision detection sees conflict on interface %i%s%s%s for " "address %s from host %s", self->priv.ifindex, - NM_PRINT_FMT_QUOTED(self->priv.pllink, + NM_PRINT_FMT_QUOTED(self->priv.plobj, " (", - NMP_OBJECT_CAST_LINK(self->priv.pllink)->name, + NMP_OBJECT_CAST_LINK(self->priv.plobj)->name, ")", ""), addr_str ?: _nm_utils_inet4_ntop(acd_data->addr, sbuf_addr), @@ -1188,7 +1203,7 @@ again: return NULL; } - valid = _acd_has_valid_link(self->priv.pllink, &addr_bin, &acd_not_supported); + valid = _acd_has_valid_link(self->priv.plobj, &addr_bin, &acd_not_supported); if (!valid) goto failed_create_acd; @@ -3331,7 +3346,8 @@ finalize(GObject *object) nm_clear_l3cd(&self->priv.p->combined_l3cd_merged); nm_clear_l3cd(&self->priv.p->combined_l3cd_commited); - nm_clear_pointer(&self->priv.pllink, nmp_object_unref); + nm_clear_pointer(&self->priv.plobj, nmp_object_unref); + nm_clear_pointer(&self->priv.plobj_next, nmp_object_unref); nm_clear_pointer(&self->priv.p->acd_ipv4_addresses_on_link, g_hash_table_unref); diff --git a/src/nm-l3cfg.h b/src/nm-l3cfg.h index 6d7fce2a38..e122947004 100644 --- a/src/nm-l3cfg.h +++ b/src/nm-l3cfg.h @@ -75,7 +75,8 @@ struct _NML3Cfg { struct _NML3CfgPrivate *p; NMNetns * netns; NMPlatform * platform; - const NMPObject * pllink; + const NMPObject * plobj; + const NMPObject * plobj_next; int ifindex; bool changed_configs : 1; } priv; @@ -117,34 +118,36 @@ nm_l3cfg_get_ifindex(const NML3Cfg *self) return self->priv.ifindex; } -static inline const char * -nm_l3cfg_get_ifname(const NML3Cfg *self) -{ - nm_assert(NM_IS_L3CFG(self)); - - return nmp_object_link_get_ifname(self->priv.pllink); -} - static inline const NMPObject * -nm_l3cfg_get_plobj(const NML3Cfg *self) +nm_l3cfg_get_plobj(const NML3Cfg *self, gboolean get_next) { if (!self) return NULL; nm_assert(NM_IS_L3CFG(self)); - return self->priv.pllink; + if (get_next) { + /* This is the instance that we just got reported in the last signal from + * the platform cache. It's probably exactly the same as if you would look + * into the platform cache. + * + * On the other hand, we pick up changes only on an idle handler. So the last + * decisions were not made based on this, but instead of "plobj". */ + return self->priv.plobj_next; + } + return self->priv.plobj; } static inline const NMPlatformLink * -nm_l3cfg_get_pllink(const NML3Cfg *self) +nm_l3cfg_get_pllink(const NML3Cfg *self, gboolean get_next) { - if (!self) - return NULL; - - nm_assert(NM_IS_L3CFG(self)); + return NMP_OBJECT_CAST_LINK(nm_l3cfg_get_plobj(self, get_next)); +} - return NMP_OBJECT_CAST_LINK(self->priv.pllink); +static inline const char * +nm_l3cfg_get_ifname(const NML3Cfg *self, gboolean get_next) +{ + return nmp_object_link_get_ifname(nm_l3cfg_get_plobj(self, get_next)); } static inline NMNetns * |