mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-23 06:02:37 +01:00
manager: Refine filtered dumps
When we detect a new phy being added, we schedule a filtered dump of the newly detected WIPHY and associated INTERFACEs. This code path and related processing of the dumps was mostly shared with the un-filtered dump of all WIPHYs and INTERFACEs which is performed when iwd starts. This normally worked fine as long as a single WIPHY was created at a time. However, if multiphy new phys were detected in a short amount of time, the logic would get confused and try to process phys that have not been probed yet. This resulted in iwd trying to create devices or not detecting devices properly. Fix this by only processing the target WIPHY and related INTERFACEs when the filtered dump is performed, and not any additional ones that might still be pending. While here, remove a misleading comment: manager_wiphy_check_setup_done() would succeed only if iwd decided to keep the default interfaces created by the kernel.
This commit is contained in:
parent
9966533e6a
commit
3a91efd3a8
@ -487,6 +487,20 @@ static void manager_interface_dump_callback(struct l_genl_msg *msg,
|
|||||||
manager_get_interface_cb(msg, state);
|
manager_get_interface_cb(msg, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void manager_filtered_interface_dump_done(void *user_data)
|
||||||
|
{
|
||||||
|
struct wiphy_setup_state *state = user_data;
|
||||||
|
|
||||||
|
l_debug("");
|
||||||
|
|
||||||
|
if (!manager_wiphy_check_setup_done(state))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* We decided to keep the the default interface(s) */
|
||||||
|
l_debug("Wiphy setup complete: %s", wiphy_get_name(state->wiphy));
|
||||||
|
wiphy_setup_state_destroy(state);
|
||||||
|
}
|
||||||
|
|
||||||
static bool manager_check_create_interfaces(void *data, void *user_data)
|
static bool manager_check_create_interfaces(void *data, void *user_data)
|
||||||
{
|
{
|
||||||
struct wiphy_setup_state *state = data;
|
struct wiphy_setup_state *state = data;
|
||||||
@ -494,13 +508,14 @@ static bool manager_check_create_interfaces(void *data, void *user_data)
|
|||||||
if (!manager_wiphy_check_setup_done(state))
|
if (!manager_wiphy_check_setup_done(state))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* If we are here, there were no interfaces for this phy */
|
|
||||||
wiphy_setup_state_free(state);
|
wiphy_setup_state_free(state);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void manager_interface_dump_done(void *user_data)
|
static void manager_interface_dump_done(void *user_data)
|
||||||
{
|
{
|
||||||
|
l_debug("");
|
||||||
|
|
||||||
l_queue_foreach_remove(pending_wiphys,
|
l_queue_foreach_remove(pending_wiphys,
|
||||||
manager_check_create_interfaces, NULL);
|
manager_check_create_interfaces, NULL);
|
||||||
}
|
}
|
||||||
@ -552,17 +567,17 @@ static void manager_wiphy_filtered_dump_callback(struct l_genl_msg *msg,
|
|||||||
wiphy_update_from_genl(state->wiphy, msg);
|
wiphy_update_from_genl(state->wiphy, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void manager_wiphy_dump_done(void *user_data)
|
static void manager_filtered_wiphy_dump_done(void *user_data)
|
||||||
{
|
{
|
||||||
const struct l_queue_entry *e;
|
struct wiphy_setup_state *state = user_data;
|
||||||
|
|
||||||
for (e = l_queue_get_entries(pending_wiphys); e; e = e->next) {
|
l_debug("");
|
||||||
struct wiphy_setup_state *state = e->data;
|
|
||||||
|
|
||||||
wiphy_create_complete(state->wiphy);
|
wiphy_create_complete(state->wiphy);
|
||||||
state->use_default = use_default;
|
state->use_default = use_default;
|
||||||
|
|
||||||
/* If whitelist/blacklist were given only try to use existing
|
/*
|
||||||
|
* If whitelist/blacklist were given only try to use existing
|
||||||
* interfaces same as when the driver does not support
|
* interfaces same as when the driver does not support
|
||||||
* NEW_INTERFACE or DEL_INTERFACE, otherwise the interface
|
* NEW_INTERFACE or DEL_INTERFACE, otherwise the interface
|
||||||
* names will become meaningless after we've created our own
|
* names will become meaningless after we've created our own
|
||||||
@ -573,22 +588,38 @@ static void manager_wiphy_dump_done(void *user_data)
|
|||||||
state->use_default = true;
|
state->use_default = true;
|
||||||
|
|
||||||
if (!state->use_default)
|
if (!state->use_default)
|
||||||
state->use_default =
|
state->use_default = wiphy_uses_default_if(state->wiphy);
|
||||||
wiphy_uses_default_if(state->wiphy);
|
|
||||||
|
|
||||||
if (state->use_default)
|
if (state->use_default)
|
||||||
l_info("Wiphy %s will only use the default interface",
|
l_info("Wiphy %s will only use the default interface",
|
||||||
wiphy_get_name(state->wiphy));
|
wiphy_get_name(state->wiphy));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void manager_wiphy_dump_done(void *user_data)
|
||||||
|
{
|
||||||
|
const struct l_queue_entry *e;
|
||||||
|
|
||||||
|
l_debug("");
|
||||||
|
|
||||||
|
for (e = l_queue_get_entries(pending_wiphys); e; e = e->next)
|
||||||
|
manager_filtered_wiphy_dump_done(e->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int manager_wiphy_filtered_dump(uint32_t wiphy_id,
|
static int manager_wiphy_filtered_dump(uint32_t wiphy_id,
|
||||||
l_genl_msg_func_t cb,
|
l_genl_msg_func_t cb,
|
||||||
void *user_data)
|
struct wiphy_setup_state *state)
|
||||||
{
|
{
|
||||||
struct l_genl_msg *msg;
|
struct l_genl_msg *msg;
|
||||||
unsigned int wiphy_cmd_id;
|
unsigned int wiphy_cmd_id;
|
||||||
unsigned int iface_cmd_id;
|
unsigned int iface_cmd_id;
|
||||||
|
l_genl_destroy_func_t wiphy_done = manager_wiphy_dump_done;
|
||||||
|
l_genl_destroy_func_t interface_done = manager_interface_dump_done;
|
||||||
|
|
||||||
|
/* If state is provided, don't try to process other pending states */
|
||||||
|
if (state) {
|
||||||
|
wiphy_done = manager_filtered_wiphy_dump_done;
|
||||||
|
interface_done = manager_filtered_interface_dump_done;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Until fixed, a NEW_WIPHY event will not include all the information
|
* Until fixed, a NEW_WIPHY event will not include all the information
|
||||||
@ -599,8 +630,7 @@ static int manager_wiphy_filtered_dump(uint32_t wiphy_id,
|
|||||||
l_genl_msg_append_attr(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP, 0, NULL);
|
l_genl_msg_append_attr(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP, 0, NULL);
|
||||||
l_genl_msg_append_attr(msg, NL80211_ATTR_WIPHY, 4, &wiphy_id);
|
l_genl_msg_append_attr(msg, NL80211_ATTR_WIPHY, 4, &wiphy_id);
|
||||||
|
|
||||||
wiphy_cmd_id = l_genl_family_dump(nl80211, msg, cb, user_data,
|
wiphy_cmd_id = l_genl_family_dump(nl80211, msg, cb, state, wiphy_done);
|
||||||
manager_wiphy_dump_done);
|
|
||||||
if (!wiphy_cmd_id) {
|
if (!wiphy_cmd_id) {
|
||||||
l_error("Could not dump wiphy %u", wiphy_id);
|
l_error("Could not dump wiphy %u", wiphy_id);
|
||||||
l_genl_msg_unref(msg);
|
l_genl_msg_unref(msg);
|
||||||
@ -625,8 +655,7 @@ static int manager_wiphy_filtered_dump(uint32_t wiphy_id,
|
|||||||
|
|
||||||
iface_cmd_id = l_genl_family_dump(nl80211, msg,
|
iface_cmd_id = l_genl_family_dump(nl80211, msg,
|
||||||
manager_interface_dump_callback,
|
manager_interface_dump_callback,
|
||||||
NULL, manager_interface_dump_done);
|
state, interface_done);
|
||||||
|
|
||||||
if (!iface_cmd_id) {
|
if (!iface_cmd_id) {
|
||||||
l_error("Could not dump interface for wiphy %u", wiphy_id);
|
l_error("Could not dump interface for wiphy %u", wiphy_id);
|
||||||
l_genl_family_cancel(nl80211, wiphy_cmd_id);
|
l_genl_family_cancel(nl80211, wiphy_cmd_id);
|
||||||
|
Loading…
Reference in New Issue
Block a user