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.
This commit is contained in:
Andrew Zaborowski 2022-10-26 19:58:28 +02:00 committed by Denis Kenzior
parent 72c2a94df9
commit 639e2a6fa3
3 changed files with 19 additions and 0 deletions

View File

@ -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\")",

View File

@ -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);

View File

@ -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;