From 1ce02ffd50cbb9351b176cd9a653d559f3ec98c7 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 18 May 2021 13:35:18 +0200 Subject: [PATCH] l3cfg: emit signal when NML3ConfigData changes --- src/core/nm-l3cfg.c | 44 +++++++++++++++++++++++++++++++++++++ src/core/nm-l3cfg.h | 12 ++++++++++ src/core/tests/test-l3cfg.c | 6 +++++ 3 files changed, 62 insertions(+) diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c index 835192a7f..575840431 100644 --- a/src/core/nm-l3cfg.c +++ b/src/core/nm-l3cfg.c @@ -302,6 +302,7 @@ static NM_UTILS_ENUM2STR_DEFINE( NML3ConfigNotifyType, NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT, "acd-event"), NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_IPV4LL_EVENT, "ipv4ll-event"), + NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED, "l3cd-changed"), NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE, "platform-change"), NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE, "platform-change-on-idle"), NM_UTILS_ENUM2STR(NM_L3_CONFIG_NOTIFY_TYPE_POST_COMMIT, "post-commit"), @@ -348,6 +349,7 @@ _l3_config_notify_data_to_string(const NML3ConfigNotifyData *notify_data, { char sbuf_addr[NM_UTILS_INET_ADDRSTRLEN]; char sbuf100[100]; + char sbufobf[NM_HASH_OBFUSCATE_PTR_STR_BUF_SIZE]; char * s = sbuf; gsize l = sbuf_size; in_addr_t addr4; @@ -359,6 +361,19 @@ _l3_config_notify_data_to_string(const NML3ConfigNotifyData *notify_data, nm_utils_strbuf_seek_end(&s, &l); switch (notify_data->notify_type) { + case NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED: + nm_utils_strbuf_append( + &s, + &l, + ", l3cd-old=%s", + NM_HASH_OBFUSCATE_PTR_STR(notify_data->l3cd_changed.l3cd_old, sbufobf)); + nm_utils_strbuf_append( + &s, + &l, + ", l3cd-new=%s", + NM_HASH_OBFUSCATE_PTR_STR(notify_data->l3cd_changed.l3cd_new, sbufobf)); + nm_utils_strbuf_append(&s, &l, ", commited=%d", notify_data->l3cd_changed.commited); + break; case NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT: nm_utils_strbuf_append(&s, &l, @@ -424,6 +439,23 @@ _nm_l3cfg_emit_signal_notify_simple(NML3Cfg *self, NML3ConfigNotifyType notify_t _nm_l3cfg_emit_signal_notify(self, ¬ify_data); } +static void +_nm_l3cfg_emit_signal_notify_l3cd_changed(NML3Cfg * self, + const NML3ConfigData *l3cd_old, + const NML3ConfigData *l3cd_new, + gboolean commited) +{ + NML3ConfigNotifyData notify_data; + + notify_data.notify_type = NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED; + notify_data.l3cd_changed = (typeof(notify_data.l3cd_changed)){ + .l3cd_old = l3cd_old, + .l3cd_new = l3cd_new, + .commited = commited, + }; + _nm_l3cfg_emit_signal_notify(self, ¬ify_data); +} + /*****************************************************************************/ static void @@ -3009,6 +3041,12 @@ _l3cfg_update_combined_config(NML3Cfg * self, l3cd_old = g_steal_pointer(&self->priv.p->combined_l3cd_merged); self->priv.p->combined_l3cd_merged = nm_l3_config_data_seal(g_steal_pointer(&l3cd)); merged_changed = TRUE; + + _nm_l3cfg_emit_signal_notify_l3cd_changed(self, + l3cd_old, + self->priv.p->combined_l3cd_merged, + FALSE); + if (!to_commit) { NM_SET_OUT(out_old, g_steal_pointer(&l3cd_old)); NM_SET_OUT(out_changed_combined_l3cd, TRUE); @@ -3020,6 +3058,12 @@ out: self->priv.p->combined_l3cd_commited = nm_l3_config_data_ref(self->priv.p->combined_l3cd_merged); commited_changed = TRUE; + + _nm_l3cfg_emit_signal_notify_l3cd_changed(self, + l3cd_commited_old, + self->priv.p->combined_l3cd_commited, + TRUE); + NM_SET_OUT(out_old, g_steal_pointer(&l3cd_commited_old)); NM_SET_OUT(out_changed_combined_l3cd, TRUE); } diff --git a/src/core/nm-l3cfg.h b/src/core/nm-l3cfg.h index f31bca6de..4efae0c54 100644 --- a/src/core/nm-l3cfg.h +++ b/src/core/nm-l3cfg.h @@ -88,6 +88,12 @@ nm_l3_acd_addr_info_find_track_info(const NML3AcdAddrInfo *addr_info, } typedef enum { + /* emitted when the merged/commited NML3ConfigData instance changes. + * Note that this gets emitted "under unsafe circumstances". That means, + * you should not perform complex operations inside this callback, + * and neither should you call into NML3Cfg again (reentrancy). */ + NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED, + NM_L3_CONFIG_NOTIFY_TYPE_ROUTES_TEMPORARY_NOT_AVAILABLE_EXPIRED, NM_L3_CONFIG_NOTIFY_TYPE_ACD_EVENT, @@ -117,6 +123,12 @@ struct _NML3IPv4LL; typedef struct { NML3ConfigNotifyType notify_type; union { + struct { + const NML3ConfigData *l3cd_old; + const NML3ConfigData *l3cd_new; + bool commited; + } l3cd_changed; + struct { NML3AcdAddrInfo info; } acd_event; diff --git a/src/core/tests/test-l3cfg.c b/src/core/tests/test-l3cfg.c index 92996c689..ba065c09b 100644 --- a/src/core/tests/test-l3cfg.c +++ b/src/core/tests/test-l3cfg.c @@ -187,6 +187,12 @@ _test_l3cfg_signal_notify(NML3Cfg * l3cfg, nm_assert(NM_IS_L3_CONFIG_DATA(ti->l3cd)); nm_assert(ti->tag); } + } else if (notify_data->notify_type == NM_L3_CONFIG_NOTIFY_TYPE_L3CD_CHANGED) { + g_assert(!notify_data->l3cd_changed.l3cd_old + || NM_IS_L3_CONFIG_DATA(notify_data->l3cd_changed.l3cd_old)); + g_assert(!notify_data->l3cd_changed.l3cd_new + || NM_IS_L3_CONFIG_DATA(notify_data->l3cd_changed.l3cd_new)); + return; } switch (tdata->notify_type) {