3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-22 14:49:24 +01:00

manager: Initialize all default interfaces

When UseDefaultInterface is set, iwd doesn't attempt to destroy and
recreate any default interfaces it detects.  However, only a single
default interface was ever remembered & initialized.  This is fine for
most cases since the kernel would typically only create a single netdev
by default.

However, some drivers can create multiple netdevs by default, if
configured to do so.  Other usecases, such as tethering, can also
benefit if iwd initialized & managed all default netdevs that were
detected at iwd start time or device hotplug.
This commit is contained in:
Denis Kenzior 2021-10-08 13:06:25 -05:00
parent a584396147
commit a001740506

View File

@ -63,7 +63,7 @@ struct wiphy_setup_state {
* interface.
*/
bool use_default;
struct l_genl_msg *default_if_msg;
struct l_queue *default_interfaces;
};
static struct l_queue *pending_wiphys;
@ -72,8 +72,8 @@ static void wiphy_setup_state_free(void *data)
{
struct wiphy_setup_state *state = data;
if (state->default_if_msg)
l_genl_msg_unref(state->default_if_msg);
l_queue_destroy(state->default_interfaces,
(l_queue_destroy_func_t) l_genl_msg_unref);
L_WARN_ON(state->pending_cmd_count);
l_free(state);
@ -89,22 +89,30 @@ static bool manager_use_default(struct wiphy_setup_state *state)
{
uint8_t addr_buf[6];
uint8_t *addr = NULL;
const struct l_queue_entry *entry;
l_debug("");
if (!state->default_if_msg) {
if (!state->default_interfaces) {
l_error("No default interface for wiphy %u",
(unsigned int) state->id);
state->retry = true;
return false;
}
if (randomize) {
wiphy_generate_random_address(state->wiphy, addr_buf);
addr = addr_buf;
entry = l_queue_get_entries(state->default_interfaces);
while (entry) {
struct l_genl_msg *msg = entry->data;
if (randomize) {
wiphy_generate_random_address(state->wiphy, addr_buf);
addr = addr_buf;
}
netdev_create_from_genl(msg, addr);
entry = entry->next;
}
netdev_create_from_genl(state->default_if_msg, addr);
return true;
}
@ -388,10 +396,14 @@ static void manager_get_interface_cb(struct l_genl_msg *msg, void *user_data)
if ((iftype == NL80211_IFTYPE_ADHOC ||
iftype == NL80211_IFTYPE_STATION ||
iftype == NL80211_IFTYPE_AP) &&
!state->default_if_msg &&
(!whitelist_filter || whitelisted) &&
!blacklisted)
state->default_if_msg = l_genl_msg_ref(msg);
!blacklisted) {
if (!state->default_interfaces)
state->default_interfaces = l_queue_new();
l_queue_push_head(state->default_interfaces,
l_genl_msg_ref(msg));
}
delete_interface:
if (state->use_default)