From 639e2a6fa3174b69c9858c50e59b7e5623e4c88f Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Wed, 26 Oct 2022 19:58:28 +0200 Subject: [PATCH] netconfig: Avoid generating events after netconfig_reset Similarly to l_netconfig track whether IWD's netconfig is active (from the moment of netconfig_configure() till netconfig_reset()) using a "started" flag and avoid handling or emitting any events after "started" is cleared. This fixes an occasional issue with the Netconfig Agent backend where station would reset netconfig, netconfig would issue DBus calls to clear addresses and routes, station would go into DISCONNECTING, perhaps finish and go into DISCONNECTED and after a while the DBus calls would come back with an error which would cause a NETCONFIG_EVENT_FAILED causing station to call netdev_disconnct() for a second time and transition to and get stuck in DISCONNECTING. --- src/netconfig-commit.c | 3 +++ src/netconfig.c | 15 +++++++++++++++ src/netconfig.h | 1 + 3 files changed, 19 insertions(+) diff --git a/src/netconfig-commit.c b/src/netconfig-commit.c index 83459d9c..50dd6f33 100644 --- a/src/netconfig-commit.c +++ b/src/netconfig-commit.c @@ -401,6 +401,9 @@ static void netconfig_agent_receive_reply(struct l_dbus_message *reply, data->pending_id[INDEX_FOR_AF(cd->family)] = 0; + if (!cd->netconfig->started) + return; + if (l_dbus_message_get_error(reply, &error, &text)) { success = false; l_error("netconfig agent call returned %s(\"%s\")", diff --git a/src/netconfig.c b/src/netconfig.c index c7cc6b1b..e6779d7c 100644 --- a/src/netconfig.c +++ b/src/netconfig.c @@ -507,6 +507,9 @@ static bool netconfig_load_fils_settings(struct netconfig *netconfig, bool netconfig_configure(struct netconfig *netconfig, netconfig_notify_func_t notify, void *user_data) { + if (netconfig->started) + return false; + netconfig->notify = notify; netconfig->user_data = user_data; @@ -521,11 +524,15 @@ bool netconfig_configure(struct netconfig *netconfig, if (unlikely(!l_netconfig_start(netconfig->nc))) return false; + netconfig->started = true; return true; } bool netconfig_reconfigure(struct netconfig *netconfig, bool set_arp_gw) { + if (!netconfig->started) + return false; + /* * Starting with kernel 4.20, ARP cache is flushed when the netdev * detects NO CARRIER. This can result in unnecessarily long delays @@ -558,6 +565,10 @@ bool netconfig_reconfigure(struct netconfig *netconfig, bool set_arp_gw) bool netconfig_reset(struct netconfig *netconfig) { + if (!netconfig->started) + return false; + + netconfig->started = false; l_netconfig_unconfigure(netconfig->nc); l_netconfig_stop(netconfig->nc); @@ -620,6 +631,10 @@ static void netconfig_event_handler(struct l_netconfig *nc, uint8_t family, { struct netconfig *netconfig = user_data; + /* Once stopped, only commit a final L_NETCONFIG_EVENT_UNCONFIGURE */ + if (!netconfig->started && event != L_NETCONFIG_EVENT_UNCONFIGURE) + return; + l_debug("l_netconfig event %d", event); netconfig_commit(netconfig, family, event); diff --git a/src/netconfig.h b/src/netconfig.h index f04899ad..a7921571 100644 --- a/src/netconfig.h +++ b/src/netconfig.h @@ -43,6 +43,7 @@ struct netconfig { bool static_config[2]; bool gateway_overridden[2]; bool dns_overridden[2]; + bool started; bool connected[2]; char **dns_list; char **domains;