diff --git a/src/main.c b/src/main.c index 78157aaf..1908ff84 100644 --- a/src/main.c +++ b/src/main.c @@ -29,12 +29,17 @@ #include #include +#include "linux/nl80211.h" + #include "src/netdev.h" #include "src/wiphy.h" #include "src/kdbus.h" #include "src/dbus.h" #include "src/agent.h" #include "src/network.h" +#include "src/eapol.h" +#include "src/scan.h" +#include "src/wsc.h" static struct l_timeout *timeout = NULL; @@ -77,6 +82,38 @@ static const struct option main_options[] = { { } }; +static void do_debug(const char *str, void *user_data) +{ + const char *prefix = user_data; + + l_info("%s%s", prefix, str); +} + +static void nl80211_appeared(void *user_data) +{ + struct l_genl_family *nl80211 = user_data; + + l_debug("Found nl80211 interface"); + + if (!wiphy_init(nl80211)) + l_error("Unable to init wiphy functionality"); + + if (!scan_init(nl80211)) + l_error("Unable to init scan functionality"); + + if (!wsc_init(nl80211)) + l_error("Unable to init WSC functionality"); +} + +static void nl80211_vanished(void *user_data) +{ + l_debug("Lost nl80211 interface"); + + wsc_exit(); + scan_exit(); + wiphy_exit(); +} + int main(int argc, char *argv[]) { bool enable_kdbus = false; @@ -84,6 +121,8 @@ int main(int argc, char *argv[]) struct l_signal *signal; sigset_t mask; int exit_status; + struct l_genl *genl; + struct l_genl_family *nl80211; for (;;) { int opt; @@ -138,7 +177,7 @@ int main(int argc, char *argv[]) bus_name = kdbus_lookup_bus(); if (!bus_name) { exit_status = EXIT_FAILURE; - goto destroy; + goto fail_dbus; } l_debug("Bus location: %s", bus_name); @@ -149,38 +188,63 @@ int main(int argc, char *argv[]) if (!result) { exit_status = EXIT_FAILURE; - goto destroy; + goto fail_dbus; } } if (!dbus_init(enable_dbus_debug)) { exit_status = EXIT_FAILURE; - goto destroy; + goto fail_dbus; } + genl = l_genl_new_default(); + if (!genl) { + l_error("Failed to open generic netlink socket"); + exit_status = EXIT_FAILURE; + goto fail_genl; + } + + if (getenv("IWD_GENL_DEBUG")) + l_genl_set_debug(genl, do_debug, "[GENL] ", NULL); + + l_debug("Opening nl80211 interface"); + + nl80211 = l_genl_family_new(genl, NL80211_GENL_NAME); + if (!nl80211) { + l_error("Failed to open nl80211 interface"); + exit_status = EXIT_FAILURE; + goto fail_nl80211; + } + + l_genl_family_set_watches(nl80211, nl80211_appeared, nl80211_vanished, + nl80211, NULL); + if (!netdev_init()) { exit_status = EXIT_FAILURE; - goto destroy; - } - - if (!wiphy_init()) { - netdev_exit(); - exit_status = EXIT_FAILURE; - goto destroy; + goto fail_netdev; } + eapol_init(); network_init(); + exit_status = EXIT_SUCCESS; l_main_run(); network_exit(); - wiphy_exit(); + eapol_exit(); + netdev_exit(); + +fail_netdev: + l_genl_family_unref(nl80211); + +fail_nl80211: + l_genl_unref(genl); + +fail_genl: dbus_exit(); - exit_status = EXIT_SUCCESS; - -destroy: +fail_dbus: if (enable_kdbus) kdbus_destroy_bus(); diff --git a/src/wiphy.c b/src/wiphy.c index b0038944..ab7a5dc6 100644 --- a/src/wiphy.c +++ b/src/wiphy.c @@ -49,7 +49,6 @@ #include "src/storage.h" #include "src/network.h" -static struct l_genl *genl = NULL; static struct l_genl_family *nl80211 = NULL; struct network { @@ -110,13 +109,6 @@ static struct l_queue *wiphy_list = NULL; static bool new_scan_results(uint32_t wiphy_id, uint32_t ifindex, struct l_queue *bss_list, void *userdata); -static void do_debug(const char *str, void *user_data) -{ - const char *prefix = user_data; - - l_info("%s%s", prefix, str); -} - static bool eapol_read(struct l_io *io, void *user_data) { struct netdev *netdev = user_data; @@ -2245,12 +2237,10 @@ static void protocol_features_callback(struct l_genl_msg *msg, void *user_data) l_debug("Found split wiphy dump support"); } -static void nl80211_appeared(void *user_data) +bool wiphy_init(struct l_genl_family *in) { struct l_genl_msg *msg; - l_debug("Found nl80211 interface"); - /* * This is an extra sanity check so that no memory is leaked * in case the generic netlink handling gets confused. @@ -2260,6 +2250,8 @@ static void nl80211_appeared(void *user_data) l_queue_destroy(wiphy_list, NULL); } + nl80211 = in; + if (!l_genl_family_register(nl80211, "config", wiphy_config_notify, NULL, NULL)) l_error("Registering for config notification failed"); @@ -2272,8 +2264,9 @@ static void nl80211_appeared(void *user_data) wiphy_regulatory_notify, NULL, NULL)) l_error("Registering for regulatory notification failed"); - if (!scan_init(nl80211)) - l_error("Unable to init scan functionality"); + __eapol_set_install_tk_func(wiphy_set_tk); + __eapol_set_install_gtk_func(wiphy_set_gtk); + __eapol_set_deauthenticate_func(handshake_failed); wiphy_list = l_queue_new(); @@ -2295,85 +2288,16 @@ static void nl80211_appeared(void *user_data) if (!l_genl_family_dump(nl80211, msg, interface_dump_callback, NULL, NULL)) l_error("Getting all interface information failed"); -} - -static void nl80211_vanished(void *user_data) -{ - l_debug("Lost nl80211 interface"); - - scan_exit(); - - l_queue_destroy(wiphy_list, wiphy_free); - wiphy_list = NULL; -} - -bool wiphy_init(void) -{ - if (genl) - return false; - - genl = l_genl_new_default(); - if (!genl) { - l_error("Failed to open generic netlink socket"); - return false; - } - - if (getenv("IWD_GENL_DEBUG")) - l_genl_set_debug(genl, do_debug, "[GENL] ", NULL); - - l_debug("Opening nl80211 interface"); - - nl80211 = l_genl_family_new(genl, NL80211_GENL_NAME); - if (!nl80211) { - l_error("Failed to open nl80211 interface"); - goto failed; - } - - l_genl_family_set_watches(nl80211, nl80211_appeared, nl80211_vanished, - NULL, NULL); - - eapol_init(); - __eapol_set_install_tk_func(wiphy_set_tk); - __eapol_set_install_gtk_func(wiphy_set_gtk); - __eapol_set_deauthenticate_func(handshake_failed); return true; - -failed: - l_genl_unref(genl); - genl = NULL; - - return false; } bool wiphy_exit(void) { - eapol_exit(); + l_queue_destroy(wiphy_list, wiphy_free); + wiphy_list = NULL; - if (!genl) - return false; - - l_debug("Closing nl80211 interface"); - - scan_exit(); - - /* - * The generic netlink master object keeps track of all families - * and closing it will take care of freeing all associated resources. - */ - l_genl_unref(genl); - genl = NULL; - - /* - * This is an extra sanity check so that no memory is leaked - * in case the generic netlink handling forgets to call the - * vanished callback. - */ - if (wiphy_list) { - l_warn("Found leftover list of wiphy devices"); - l_queue_destroy(wiphy_list, wiphy_free); - wiphy_list = NULL; - } + nl80211 = NULL; return true; } diff --git a/src/wiphy.h b/src/wiphy.h index 89c0aa16..df7e40de 100644 --- a/src/wiphy.h +++ b/src/wiphy.h @@ -27,7 +27,7 @@ struct netdev; typedef void (*iwd_device_foreach_func)(struct netdev *, void *data); -bool wiphy_init(void); +bool wiphy_init(struct l_genl_family *in); bool wiphy_exit(void); void wiphy_notify_dellink(uint32_t index);