3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-10-03 01:48:49 +02: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. * interface.
*/ */
bool use_default; bool use_default;
struct l_genl_msg *default_if_msg; struct l_queue *default_interfaces;
}; };
static struct l_queue *pending_wiphys; static struct l_queue *pending_wiphys;
@ -72,8 +72,8 @@ static void wiphy_setup_state_free(void *data)
{ {
struct wiphy_setup_state *state = data; struct wiphy_setup_state *state = data;
if (state->default_if_msg) l_queue_destroy(state->default_interfaces,
l_genl_msg_unref(state->default_if_msg); (l_queue_destroy_func_t) l_genl_msg_unref);
L_WARN_ON(state->pending_cmd_count); L_WARN_ON(state->pending_cmd_count);
l_free(state); 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_buf[6];
uint8_t *addr = NULL; uint8_t *addr = NULL;
const struct l_queue_entry *entry;
l_debug(""); l_debug("");
if (!state->default_if_msg) { if (!state->default_interfaces) {
l_error("No default interface for wiphy %u", l_error("No default interface for wiphy %u",
(unsigned int) state->id); (unsigned int) state->id);
state->retry = true; state->retry = true;
return false; return false;
} }
entry = l_queue_get_entries(state->default_interfaces);
while (entry) {
struct l_genl_msg *msg = entry->data;
if (randomize) { if (randomize) {
wiphy_generate_random_address(state->wiphy, addr_buf); wiphy_generate_random_address(state->wiphy, addr_buf);
addr = addr_buf; addr = addr_buf;
} }
netdev_create_from_genl(state->default_if_msg, addr); netdev_create_from_genl(msg, addr);
entry = entry->next;
}
return true; 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 || if ((iftype == NL80211_IFTYPE_ADHOC ||
iftype == NL80211_IFTYPE_STATION || iftype == NL80211_IFTYPE_STATION ||
iftype == NL80211_IFTYPE_AP) && iftype == NL80211_IFTYPE_AP) &&
!state->default_if_msg &&
(!whitelist_filter || whitelisted) && (!whitelist_filter || whitelisted) &&
!blacklisted) !blacklisted) {
state->default_if_msg = l_genl_msg_ref(msg); if (!state->default_interfaces)
state->default_interfaces = l_queue_new();
l_queue_push_head(state->default_interfaces,
l_genl_msg_ref(msg));
}
delete_interface: delete_interface:
if (state->use_default) if (state->use_default)