nl80211_check_global(drv->global);
wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
"interface");
- wpa_driver_nl80211_finish_drv_init(drv, NULL, 0, NULL);
+ if (wpa_driver_nl80211_finish_drv_init(drv, NULL, 0, NULL) < 0)
+ return -1;
return 1;
}
static struct wpa_driver_nl80211_data *
-nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len)
+nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len,
+ int *init_failed)
{
struct wpa_driver_nl80211_data *drv;
+ int res;
+
+ if (init_failed)
+ *init_failed = 0;
dl_list_for_each(drv, &global->interfaces,
struct wpa_driver_nl80211_data, list) {
- if (wpa_driver_nl80211_own_ifindex(drv, idx, buf, len) ||
- have_ifidx(drv, idx, IFIDX_ANY))
+ res = wpa_driver_nl80211_own_ifindex(drv, idx, buf, len);
+ if (res < 0) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: Found matching own interface, but failed to complete reinitialization");
+ if (init_failed)
+ *init_failed = 1;
+ return drv;
+ }
+ if (res > 0 || have_ifidx(drv, idx, IFIDX_ANY))
return drv;
}
return NULL;
char namebuf[IFNAMSIZ];
char ifname[IFNAMSIZ + 1];
char extra[100], *pos, *end;
+ int init_failed;
extra[0] = '\0';
pos = extra;
(ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
(ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
- drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
+ drv = nl80211_find_drv(global, ifi->ifi_index, buf, len, &init_failed);
if (!drv)
goto event_newlink;
+ if (init_failed)
+ return; /* do not update interface state */
if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
namebuf[0] = '\0';
* dynamic interfaces
*/
drv = nl80211_find_drv(global, ifi->ifi_index,
- buf, len);
+ buf, len, NULL);
if (!drv)
return;
}
(ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
(ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
- drv = nl80211_find_drv(global, ifi->ifi_index, buf, len);
+ drv = nl80211_find_drv(global, ifi->ifi_index, buf, len, NULL);
if (ifi->ifi_family == AF_BRIDGE && brid && drv) {
/* device has been removed from bridge */