summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/network/networkd-link.c9
-rw-r--r--src/network/networkd-manager.c1
-rw-r--r--src/network/networkd-manager.h1
-rw-r--r--src/network/networkd-wifi.c13
4 files changed, 24 insertions, 0 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 95a7d75e53..e43c04567a 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -2515,6 +2515,15 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
log_link_debug(link, "Saved new link: ifindex=%i, iftype=%s(%u), kind=%s",
link->ifindex, strna(arphrd_to_name(link->iftype)), link->iftype, strna(link->kind));
+ /* If contained in this set, the link is wireless and the corresponding NL80211_CMD_NEW_INTERFACE
+ * message arrived too early. Request the wireless link information again.
+ */
+ if (set_remove(manager->new_wlan_ifindices, INT_TO_PTR(link->ifindex))) {
+ r = link_get_wlan_interface(link);
+ if (r < 0)
+ log_link_warning_errno(link, r, "Failed to get wireless interface, ignoring: %m");
+ }
+
*ret = TAKE_PTR(link);
return 0;
}
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index f82117cc1e..ad668215e7 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -614,6 +614,7 @@ Manager* manager_free(Manager *m) {
m->request_queue = ordered_set_free(m->request_queue);
m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
+ m->new_wlan_ifindices = set_free(m->new_wlan_ifindices);
m->links_by_name = hashmap_free(m->links_by_name);
m->links_by_hw_addr = hashmap_free(m->links_by_hw_addr);
m->links_by_dhcp_pd_subnet_prefix = hashmap_free(m->links_by_dhcp_pd_subnet_prefix);
diff --git a/src/network/networkd-manager.h b/src/network/networkd-manager.h
index e6183af0e4..c9cbcf9289 100644
--- a/src/network/networkd-manager.h
+++ b/src/network/networkd-manager.h
@@ -38,6 +38,7 @@ struct Manager {
bool manage_foreign_rules;
Set *dirty_links;
+ Set *new_wlan_ifindices;
char *state_file;
LinkOperationalState operational_state;
diff --git a/src/network/networkd-wifi.c b/src/network/networkd-wifi.c
index e35857261e..1a3754b29c 100644
--- a/src/network/networkd-wifi.c
+++ b/src/network/networkd-wifi.c
@@ -92,6 +92,19 @@ int manager_genl_process_nl80211_config(sd_netlink *genl, sd_netlink_message *me
if (r < 0) {
log_debug_errno(r, "nl80211: received %s(%u) message for link '%"PRIu32"' we don't know about, ignoring.",
strna(nl80211_cmd_to_string(cmd)), cmd, ifindex);
+
+ /* The NL80211_CMD_NEW_INTERFACE message might arrive before RTM_NEWLINK, in which case a
+ * link will not have been created yet. Store the interface index such that the wireless
+ * properties of the link (such as wireless interface type) are queried again after the link
+ * is created.
+ */
+ if (cmd == NL80211_CMD_NEW_INTERFACE) {
+ r = set_ensure_put(&manager->new_wlan_ifindices, NULL, INT_TO_PTR(ifindex));
+ if (r < 0)
+ log_warning_errno(r, "Failed to add new wireless interface index to set, ignoring: %m");
+ } else if (cmd == NL80211_CMD_DEL_INTERFACE)
+ set_remove(manager->new_wlan_ifindices, INT_TO_PTR(ifindex));
+
return 0;
}