From 88f86e7b5dce9c9214db33786e8c72586496399c Mon Sep 17 00:00:00 2001 From: Emmanuel VAUTRIN Date: Fri, 25 Feb 2022 15:47:22 +0100 Subject: [PATCH] iwd: Forget network on service removal When a service is manually removed, the associated network, at driver side, needs to be forgotten, to remove the corresponding known network. --- include/network.h | 1 + plugins/iwd.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/connman.h | 1 + src/network.c | 13 +++++++++++++ src/service.c | 2 ++ 5 files changed, 58 insertions(+) diff --git a/include/network.h b/include/network.h index 8f9dd94a7ec2..5bca62ad3a0e 100644 --- a/include/network.h +++ b/include/network.h @@ -163,6 +163,7 @@ struct connman_network_driver { void (*remove) (struct connman_network *network); int (*connect) (struct connman_network *network); int (*disconnect) (struct connman_network *network); + int (*forget) (struct connman_network *network); int (*set_autoconnect) (struct connman_network *network, bool autoconnect); }; diff --git a/plugins/iwd.c b/plugins/iwd.c index 7b59a6eb4386..ee3ed83e5957 100644 --- a/plugins/iwd.c +++ b/plugins/iwd.c @@ -270,6 +270,46 @@ static int cm_network_connect(struct connman_network *network) return -EINPROGRESS; } +static void cm_network_forget_cb(DBusMessage *message, void *user_data) +{ + struct iwd_known_network *iwdkn; + const char *path = user_data; + + iwdkn = g_hash_table_lookup(known_networks, path); + if (!iwdkn) + return; + + if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) { + const char *dbus_error = dbus_message_get_error_name(message); + + DBG("%s failed: %s", path, dbus_error); + } +} + +static int cm_network_forget(struct connman_network *network) +{ + struct iwd_network *iwdn = connman_network_get_data(network); + struct iwd_known_network *iwdkn; + + if (!iwdn) + return -EINVAL; + + if (!iwdn->known_network) + return 0; + + iwdkn = g_hash_table_lookup(known_networks, + iwdn->known_network); + if (!iwdkn) + return 0; + + if (!g_dbus_proxy_method_call(iwdkn->proxy, "Forget", + NULL, cm_network_forget_cb, + g_strdup(iwdkn->path), g_free)) + return -EIO; + + return 0; +} + static void cm_network_disconnect_cb(DBusMessage *message, void *user_data) { const char *path = user_data; @@ -470,6 +510,7 @@ static struct connman_network_driver network_driver = { .probe = cm_network_probe, .connect = cm_network_connect, .disconnect = cm_network_disconnect, + .forget = cm_network_forget, .set_autoconnect = cm_network_set_autoconnect, }; diff --git a/src/connman.h b/src/connman.h index 33dbec694a95..6405361df5df 100644 --- a/src/connman.h +++ b/src/connman.h @@ -607,6 +607,7 @@ void __connman_network_set_device(struct connman_network *network, int __connman_network_connect(struct connman_network *network); int __connman_network_disconnect(struct connman_network *network); +int __connman_network_forget(struct connman_network *network); int __connman_network_clear_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig); int __connman_network_enable_ipconfig(struct connman_network *network, diff --git a/src/network.c b/src/network.c index 1cbdf9cfed95..2090e7fe944e 100644 --- a/src/network.c +++ b/src/network.c @@ -1848,6 +1848,19 @@ int __connman_network_disconnect(struct connman_network *network) return err; } +int __connman_network_forget(struct connman_network *network) +{ + DBG("network %p", network); + + if (!network->driver) + return -EUNATCH; + + if (network->driver->forget) + return network->driver->forget(network); + + return 0; +} + int __connman_network_clear_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig) { diff --git a/src/service.c b/src/service.c index f1abb963b817..d4387361d0c7 100644 --- a/src/service.c +++ b/src/service.c @@ -4634,6 +4634,8 @@ bool __connman_service_remove(struct connman_service *service) return false; __connman_service_disconnect(service); + if (service->network) + __connman_network_forget(service->network); g_free(service->passphrase); service->passphrase = NULL; -- 2.25.1