]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Make processing RTM link event per-BSS
authorAlexander Savchenko <oleksandr.savchenko.dn@bp.renesas.com>
Thu, 22 May 2025 11:19:40 +0000 (14:19 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 29 Sep 2025 19:46:24 +0000 (22:46 +0300)
In virtual AP mode, driver nl80211 did not handle RTM link events for
non-first BSSs. This leads to the situation when the non-first BSS does
not move into DOWN/UP/LOWER_UP state when netlink reports it and the
interface is left in NO-CARRIER state (e.g., after CAC finished). Also
fix ifindex updating for non-first BSS when it changes, for example,
after rmmod/insmod a wireless driver.

Signed-off-by: Alexander Savchenko <oleksandr.savchenko.dn@bp.renesas.com>
src/drivers/driver_nl80211.c
src/drivers/driver_nl80211.h

index 349877bf43df42c948069f0252dde6fe4f90b30f..d7692054f1192f1a16bf02891e696847324dc6a4 100644 (file)
@@ -163,8 +163,8 @@ static int wpa_driver_nl80211_set_mode_ibss(struct i802_bss *bss,
                                            struct hostapd_freq_params *freq);
 
 static int
-wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
-                                  const u8 *set_addr, int first,
+wpa_driver_nl80211_finish_drv_init(struct i802_bss *bss,
+                                  const u8 *set_addr,
                                   const char *driver_params,
                                   enum wpa_p2p_mode p2p_mode);
 static int nl80211_send_frame_cmd(struct i802_bss *bss,
@@ -1142,22 +1142,22 @@ int get_sta_mlo_interface_info(struct i802_bss *bss)
 
 
 static void wpa_driver_nl80211_event_newlink(
-       struct nl80211_global *global, struct wpa_driver_nl80211_data *drv,
+       struct nl80211_global *global, struct i802_bss *bss,
        int ifindex, const char *ifname)
 {
        union wpa_event_data event;
 
-       if (drv && os_strcmp(drv->first_bss->ifname, ifname) == 0) {
-               if (if_nametoindex(drv->first_bss->ifname) == 0) {
+       if (bss && os_strcmp(bss->ifname, ifname) == 0) {
+               if (if_nametoindex(bss->ifname) == 0) {
                        wpa_printf(MSG_DEBUG, "nl80211: Interface %s does not exist - ignore RTM_NEWLINK",
-                                  drv->first_bss->ifname);
+                                  bss->ifname);
                        return;
                }
-               if (!drv->if_removed)
+               if (!bss->if_removed)
                        return;
                wpa_printf(MSG_DEBUG, "nl80211: Mark if_removed=0 for %s based on RTM_NEWLINK event",
-                          drv->first_bss->ifname);
-               drv->if_removed = 0;
+                          bss->ifname);
+               bss->if_removed = 0;
        }
 
        os_memset(&event, 0, sizeof(event));
@@ -1165,8 +1165,8 @@ static void wpa_driver_nl80211_event_newlink(
        os_strlcpy(event.interface_status.ifname, ifname,
                   sizeof(event.interface_status.ifname));
        event.interface_status.ievent = EVENT_INTERFACE_ADDED;
-       if (drv)
-               wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
+       if (bss)
+               wpa_supplicant_event(bss->ctx, EVENT_INTERFACE_STATUS, &event);
        else
                wpa_supplicant_event_global(global->ctx, EVENT_INTERFACE_STATUS,
                                            &event);
@@ -1174,20 +1174,20 @@ static void wpa_driver_nl80211_event_newlink(
 
 
 static void wpa_driver_nl80211_event_dellink(
-       struct nl80211_global *global, struct wpa_driver_nl80211_data *drv,
+       struct nl80211_global *global, struct i802_bss *bss,
        int ifindex, const char *ifname)
 {
        union wpa_event_data event;
 
-       if (drv && os_strcmp(drv->first_bss->ifname, ifname) == 0) {
-               if (drv->if_removed) {
+       if (bss && os_strcmp(bss->ifname, ifname) == 0) {
+               if (bss->if_removed) {
                        wpa_printf(MSG_DEBUG, "nl80211: if_removed already set - ignore RTM_DELLINK event for %s",
                                   ifname);
                        return;
                }
                wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed - mark if_removed=1",
                           ifname);
-               drv->if_removed = 1;
+               bss->if_removed = 1;
        } else {
                wpa_printf(MSG_DEBUG, "RTM_DELLINK: Interface '%s' removed",
                           ifname);
@@ -1198,15 +1198,15 @@ static void wpa_driver_nl80211_event_dellink(
        os_strlcpy(event.interface_status.ifname, ifname,
                   sizeof(event.interface_status.ifname));
        event.interface_status.ievent = EVENT_INTERFACE_REMOVED;
-       if (drv)
-               wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_STATUS, &event);
+       if (bss)
+               wpa_supplicant_event(bss->ctx, EVENT_INTERFACE_STATUS, &event);
        else
                wpa_supplicant_event_global(global->ctx, EVENT_INTERFACE_STATUS,
                                            &event);
 }
 
 
-static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
+static int wpa_driver_nl80211_own_ifname(const char *ifname,
                                         u8 *buf, size_t len)
 {
        int attrlen, rta_len;
@@ -1218,8 +1218,7 @@ static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
        rta_len = RTA_ALIGN(sizeof(struct rtattr));
        while (RTA_OK(attr, attrlen)) {
                if (attr->rta_type == IFLA_IFNAME) {
-                       if (os_strcmp(((char *) attr) + rta_len,
-                                     drv->first_bss->ifname) == 0)
+                       if (os_strcmp(((char *) attr) + rta_len, ifname) == 0)
                                return 1;
                        else
                                break;
@@ -1231,18 +1230,23 @@ static int wpa_driver_nl80211_own_ifname(struct wpa_driver_nl80211_data *drv,
 }
 
 
-static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
+static int wpa_driver_nl80211_own_ifindex(struct i802_bss *bss,
                                          int ifindex, u8 *buf, size_t len)
 {
-       if (drv->ifindex == ifindex)
+       if (bss->ifindex == ifindex)
                return 1;
 
-       if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
-               nl80211_check_global(drv->global);
+       if (bss->if_removed &&
+           wpa_driver_nl80211_own_ifname(bss->ifname, buf, len)) {
+               struct wpa_driver_nl80211_data *drv = bss->drv;
+
+               if (drv->first_bss == bss)
+                       nl80211_check_global(drv->global);
+
                wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
                           "interface");
-               del_ifidx(drv, drv->ifindex, IFIDX_ANY);
-               if (wpa_driver_nl80211_finish_drv_init(drv, NULL, 0, NULL,
+               del_ifidx(drv, bss->ifindex, IFIDX_ANY);
+               if (wpa_driver_nl80211_finish_drv_init(bss, NULL, NULL,
                                                       WPA_P2P_MODE_WFD_R1) < 0)
                        return -1;
                return 1;
@@ -1252,8 +1256,8 @@ static int wpa_driver_nl80211_own_ifindex(struct wpa_driver_nl80211_data *drv,
 }
 
 
-static struct wpa_driver_nl80211_data *
-nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len,
+static struct i802_bss *
+nl80211_find_bss(struct nl80211_global *global, int idx, u8 *buf, size_t len,
                 int *init_failed)
 {
        struct wpa_driver_nl80211_data *drv;
@@ -1263,16 +1267,21 @@ nl80211_find_drv(struct nl80211_global *global, int idx, u8 *buf, size_t len,
                *init_failed = 0;
        dl_list_for_each(drv, &global->interfaces,
                         struct wpa_driver_nl80211_data, list) {
-               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;
+               struct i802_bss *bss;
+
+               for (bss = drv->first_bss; bss; bss = bss->next) {
+                       res = wpa_driver_nl80211_own_ifindex(bss, 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 bss;
+                       }
+                       if (res > 0)
+                               return bss;
                }
-               if (res > 0 || nl80211_has_ifidx(drv, idx, IFIDX_ANY))
-                       return drv;
        }
        return NULL;
 }
@@ -1311,7 +1320,8 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
                                                 u8 *buf, size_t len)
 {
        struct nl80211_global *global = ctx;
-       struct wpa_driver_nl80211_data *drv;
+       struct wpa_driver_nl80211_data *drv = NULL;
+       struct i802_bss *bss = NULL;
        int attrlen;
        struct rtattr *attr;
        u32 brid = 0;
@@ -1363,36 +1373,34 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
                   (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
                   (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
 
-       drv = nl80211_find_drv(global, ifi->ifi_index, buf, len, &init_failed);
-       if (!drv)
+       bss = nl80211_find_bss(global, ifi->ifi_index, buf, len, &init_failed);
+       if (!bss)
                goto event_newlink;
        if (init_failed)
                return; /* do not update interface state */
 
-       if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
+       drv = bss->drv;
+
+       if (!bss->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
                namebuf[0] = '\0';
                if (if_indextoname(ifi->ifi_index, namebuf) &&
                    linux_iface_up(drv->global->ioctl_sock, namebuf) > 0) {
                        wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
                                   "event since interface %s is up", namebuf);
-                       drv->ignore_if_down_event = 0;
+                       bss->ignore_if_down_event = 0;
                        /* Re-read MAC address as it may have changed */
                        nl80211_refresh_mac(drv, ifi->ifi_index, 1);
                        return;
                }
                wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
                           namebuf, ifname);
-               if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
-                       wpa_printf(MSG_DEBUG,
-                                  "nl80211: Not the main interface (%s) - do not indicate interface down",
-                                  drv->first_bss->ifname);
-               } else if (drv->ignore_if_down_event) {
+               if (bss->ignore_if_down_event) {
                        wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
                                   "event generated by mode change");
-                       drv->ignore_if_down_event = 0;
+                       bss->ignore_if_down_event = 0;
                } else {
-                       drv->if_disabled = 1;
-                       wpa_supplicant_event(drv->ctx,
+                       bss->if_disabled = 1;
+                       wpa_supplicant_event(bss->ctx,
                                             EVENT_INTERFACE_DISABLED, NULL);
 
                        /*
@@ -1400,14 +1408,17 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
                         * part of the EVENT_INTERFACE_DISABLED handling for
                         * dynamic interfaces
                         */
-                       drv = nl80211_find_drv(global, ifi->ifi_index,
-                                              buf, len, NULL);
-                       if (!drv)
+                       drv = NULL;
+                       bss = nl80211_find_bss(global, ifi->ifi_index, buf, len,
+                                              &init_failed);
+                       if (!bss)
                                return;
+
+                       drv = bss->drv;
                }
        }
 
-       if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
+       if (bss->if_disabled && (ifi->ifi_flags & IFF_UP)) {
                namebuf[0] = '\0';
                if (if_indextoname(ifi->ifi_index, namebuf) &&
                    linux_iface_up(drv->global->ioctl_sock, namebuf) == 0) {
@@ -1418,24 +1429,20 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
                }
                wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
                           namebuf, ifname);
-               if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
-                       wpa_printf(MSG_DEBUG,
-                                  "nl80211: Not the main interface (%s) - do not indicate interface up",
-                                  drv->first_bss->ifname);
-               } else if (if_nametoindex(drv->first_bss->ifname) == 0) {
+               if (if_nametoindex(bss->ifname) == 0) {
                        wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
                                   "event since interface %s does not exist",
-                                  drv->first_bss->ifname);
-               } else if (drv->if_removed) {
+                                  bss->ifname);
+               } else if (bss->if_removed) {
                        wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
                                   "event since interface %s is marked "
-                                  "removed", drv->first_bss->ifname);
+                                  "removed", bss->ifname);
                } else {
                        /* Re-read MAC address as it may have changed */
                        nl80211_refresh_mac(drv, ifi->ifi_index, 0);
 
-                       drv->if_disabled = 0;
-                       wpa_supplicant_event(drv->ctx, EVENT_INTERFACE_ENABLED,
+                       bss->if_disabled = 0;
+                       wpa_supplicant_event(bss->ctx, EVENT_INTERFACE_ENABLED,
                                             NULL);
                }
        }
@@ -1446,22 +1453,20 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
         * fails. This will hit us when wpa_supplicant does not need to do
         * IEEE 802.1X authentication
         */
-       if (drv->operstate == 1 &&
+       if (bss->operstate == 1 &&
            (ifi->ifi_flags & (IFF_LOWER_UP | IFF_DORMANT)) == IFF_LOWER_UP &&
            !(ifi->ifi_flags & IFF_RUNNING)) {
                wpa_printf(MSG_DEBUG, "nl80211: Set IF_OPER_UP again based on ifi_flags and expected operstate");
-               netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
+               netlink_send_oper_ifla(drv->global->netlink, bss->ifindex,
                                       -1, IF_OPER_UP);
        }
 
 event_newlink:
        if (ifname[0])
-               wpa_driver_nl80211_event_newlink(global, drv, ifi->ifi_index,
+               wpa_driver_nl80211_event_newlink(global, bss, ifi->ifi_index,
                                                 ifname);
 
-       if (ifi->ifi_family == AF_BRIDGE && brid && drv) {
-               struct i802_bss *bss;
-
+       if (ifi->ifi_family == AF_BRIDGE && brid && drv && bss) {
                /* device has been added to bridge */
                if (!if_indextoname(brid, namebuf)) {
                        wpa_printf(MSG_DEBUG,
@@ -1473,12 +1478,8 @@ event_newlink:
                           brid, namebuf);
                add_ifidx(drv, brid, ifi->ifi_index);
 
-               for (bss = drv->first_bss; bss; bss = bss->next) {
-                       if (os_strcmp(ifname, bss->ifname) == 0) {
-                               os_strlcpy(bss->brname, namebuf, IFNAMSIZ);
-                               break;
-                       }
-               }
+               if (os_strcmp(ifname, bss->ifname) == 0)
+                       os_strlcpy(bss->brname, namebuf, IFNAMSIZ);
        }
 }
 
@@ -1488,7 +1489,8 @@ static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
                                                 u8 *buf, size_t len)
 {
        struct nl80211_global *global = ctx;
-       struct wpa_driver_nl80211_data *drv;
+       struct wpa_driver_nl80211_data *drv = NULL;
+       struct i802_bss *bss = NULL;
        int attrlen;
        struct rtattr *attr;
        u32 brid = 0;
@@ -1535,7 +1537,9 @@ static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
                   (ifi->ifi_flags & IFF_LOWER_UP) ? "[LOWER_UP]" : "",
                   (ifi->ifi_flags & IFF_DORMANT) ? "[DORMANT]" : "");
 
-       drv = nl80211_find_drv(global, ifi->ifi_index, buf, len, NULL);
+       bss = nl80211_find_bss(global, ifi->ifi_index, buf, len, NULL);
+       if (bss)
+               drv = bss->drv;
 
        if (ifi->ifi_family == AF_BRIDGE && brid && drv) {
                /* device has been removed from bridge */
@@ -1554,7 +1558,7 @@ static void wpa_driver_nl80211_event_rtm_dellink(void *ctx,
        }
 
        if (ifi->ifi_family != AF_BRIDGE || !brid)
-               wpa_driver_nl80211_event_dellink(global, drv, ifi->ifi_index,
+               wpa_driver_nl80211_event_dellink(global, bss, ifi->ifi_index,
                                                 ifname);
 }
 
@@ -2424,7 +2428,7 @@ static void * wpa_driver_nl80211_drv_init(void *ctx, const char *ifname,
        if (nl80211_init_bss(bss))
                goto failed;
 
-       if (wpa_driver_nl80211_finish_drv_init(drv, set_addr, 1, driver_params,
+       if (wpa_driver_nl80211_finish_drv_init(bss, set_addr, driver_params,
                                               p2p_mode))
                goto failed;
 
@@ -3112,23 +3116,25 @@ fail:
 
 
 static int
-wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
-                                  const u8 *set_addr, int first,
+wpa_driver_nl80211_finish_drv_init(struct i802_bss *bss, const u8 *set_addr,
                                   const char *driver_params,
                                   enum wpa_p2p_mode p2p_mode)
 {
-       struct i802_bss *bss = drv->first_bss;
+       struct wpa_driver_nl80211_data *drv = bss->drv;
        int send_rfkill_event = 0;
        enum nl80211_iftype nlmode;
+       bool first = drv->first_bss == bss;
 
-       drv->ifindex = if_nametoindex(bss->ifname);
-       bss->ifindex = drv->ifindex;
+       bss->ifindex = if_nametoindex(bss->ifname);
+       if (first)
+               drv->ifindex = bss->ifindex;
        bss->wdev_id = drv->global->if_add_wdevid;
        bss->wdev_id_set = drv->global->if_add_wdevid_set;
 
        bss->if_dynamic = drv->ifindex == drv->global->if_add_ifindex;
        bss->if_dynamic = bss->if_dynamic || drv->global->if_add_wdevid_set;
-       drv->global->if_add_wdevid_set = 0;
+       if (first)
+               drv->global->if_add_wdevid_set = 0;
 
        if (!bss->if_dynamic && nl80211_get_ifmode(bss) == NL80211_IFTYPE_AP)
                bss->static_ap = 1;
@@ -3136,9 +3142,9 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
        if (first &&
            nl80211_get_ifmode(bss) != NL80211_IFTYPE_P2P_DEVICE &&
            linux_iface_up(drv->global->ioctl_sock, bss->ifname) > 0)
-               drv->start_iface_up = 1;
+               bss->start_iface_up = 1;
 
-       if (wpa_driver_nl80211_capa(drv))
+       if (first && wpa_driver_nl80211_capa(drv))
                return -1;
 
        if (driver_params && nl80211_set_param(bss, driver_params) < 0)
@@ -3164,7 +3170,7 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
        else
                nlmode = NL80211_IFTYPE_STATION;
 
-       if (wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
+       if (first && wpa_driver_nl80211_set_mode(bss, nlmode) < 0) {
                wpa_printf(MSG_ERROR, "nl80211: Could not configure driver mode");
                return -1;
        }
@@ -3197,26 +3203,26 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv,
                wpa_printf(MSG_DEBUG, "nl80211: Could not yet enable "
                           "interface '%s' due to rfkill", bss->ifname);
                if (nlmode != NL80211_IFTYPE_P2P_DEVICE)
-                       drv->if_disabled = 1;
+                       bss->if_disabled = 1;
 
                send_rfkill_event = 1;
        }
 
        if (!drv->hostapd && nlmode != NL80211_IFTYPE_P2P_DEVICE)
-               netlink_send_oper_ifla(drv->global->netlink, drv->ifindex,
+               netlink_send_oper_ifla(drv->global->netlink, bss->ifindex,
                                       1, IF_OPER_DORMANT);
 
        if (nlmode != NL80211_IFTYPE_P2P_DEVICE) {
                if (linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname,
                                       bss->addr))
                        return -1;
-               os_memcpy(drv->perm_addr, bss->addr, ETH_ALEN);
+               if (first)
+                       os_memcpy(drv->perm_addr, bss->addr, ETH_ALEN);
        }
 
-       if (send_rfkill_event) {
+       if (send_rfkill_event)
                eloop_register_timeout(0, 0, wpa_driver_nl80211_send_rfkill,
-                                      drv, drv->ctx);
-       }
+                                      drv, bss->ctx);
 
        if (drv->vendor_cmd_test_avail)
                qca_vendor_test(drv);
@@ -3331,14 +3337,14 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
        if (drv->disabled_11b_rates)
                nl80211_disable_11b_rates(drv, drv->ifindex, 0);
 
-       netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, 0,
+       netlink_send_oper_ifla(drv->global->netlink, bss->ifindex, 0,
                               IF_OPER_UP);
        eloop_cancel_timeout(wpa_driver_nl80211_send_rfkill, drv, drv->ctx);
        rfkill_deinit(drv->rfkill);
 
-       eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, bss->ctx);
+       eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
 
-       if (!drv->start_iface_up)
+       if (!bss->start_iface_up)
                (void) i802_set_iface_flags(bss, 0);
 
        if (drv->addr_changed) {
@@ -7692,7 +7698,7 @@ static int wpa_driver_nl80211_set_mode_impl(
                wpa_printf(MSG_DEBUG, "nl80211: Mode change succeeded while "
                           "interface is down");
                drv->nlmode = nlmode;
-               drv->ignore_if_down_event = 1;
+               bss->ignore_if_down_event = 1;
        }
 
        /* Bring the interface back up */
@@ -7811,10 +7817,10 @@ static int wpa_driver_nl80211_set_operstate(void *priv, int state)
        struct wpa_driver_nl80211_data *drv = bss->drv;
 
        wpa_printf(MSG_DEBUG, "nl80211: Set %s operstate %d->%d (%s)",
-                  bss->ifname, drv->operstate, state,
+                  bss->ifname, bss->operstate, state,
                   state ? "UP" : "DORMANT");
-       drv->operstate = state;
-       return netlink_send_oper_ifla(drv->global->netlink, drv->ifindex, -1,
+       bss->operstate = state;
+       return netlink_send_oper_ifla(drv->global->netlink, bss->ifindex, -1,
                                      state ? IF_OPER_UP : IF_OPER_DORMANT);
 }
 
@@ -11386,7 +11392,7 @@ static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
                          drv->phyname,
                          MAC2STR(drv->perm_addr),
                          drv->ifindex,
-                         drv->operstate,
+                         bss->operstate,
                          scan_state_str(drv->scan_state),
                          MAC2STR(drv->auth_bssid),
                          MAC2STR(drv->auth_attempt_bssid),
@@ -11396,7 +11402,7 @@ static int wpa_driver_nl80211_status(void *priv, char *buf, size_t buflen)
                          drv->assoc_freq,
                          drv->last_mgmt_freq,
                          drv->eapol_tx_sock,
-                         drv->ignore_if_down_event ?
+                         bss->ignore_if_down_event ?
                          "ignore_if_down_event=1\n" : "",
                          drv->scan_complete_events ?
                          "scan_complete_events=1\n" : "",
index 13d8aab40d2d62da722f694b9be1325e761d243c..2ef326c9384b0896fb855525c7c50100e56120a7 100644 (file)
@@ -73,7 +73,10 @@ struct i802_bss {
        struct i802_link *flink, *scan_link;
 
        int ifindex;
+       int ignore_if_down_event;
        int br_ifindex;
+       int if_removed;
+       int if_disabled;
        u64 wdev_id;
        char ifname[IFNAMSIZ + 1];
        char brname[IFNAMSIZ];
@@ -89,6 +92,7 @@ struct i802_bss {
        u8 prev_addr[ETH_ALEN];
 
        int if_dynamic;
+       int operstate;
 
        void *ctx;
        struct nl_sock *nl_preq, *nl_mgmt, *nl_connect;
@@ -97,6 +101,8 @@ struct i802_bss {
        struct nl80211_wiphy_data *wiphy_data;
        struct dl_list wiphy_list;
        u8 rand_addr[ETH_ALEN];
+
+       unsigned int start_iface_up:1;
 };
 
 struct drv_nl80211_if_info {
@@ -114,9 +120,6 @@ struct wpa_driver_nl80211_data {
        u8 perm_addr[ETH_ALEN];
        void *ctx;
        int ifindex;
-       int if_removed;
-       int if_disabled;
-       int ignore_if_down_event;
        struct rfkill_data *rfkill;
        struct wpa_driver_capa capa;
        u8 *extended_capa, *extended_capa_mask;
@@ -133,9 +136,6 @@ struct wpa_driver_nl80211_data {
 
        int has_capability;
        int has_driver_key_mgmt;
-
-       int operstate;
-
        int scan_complete_events;
        enum scan_states {
                NO_SCAN, SCAN_REQUESTED, SCAN_STARTED, SCAN_COMPLETED,
@@ -165,7 +165,6 @@ struct wpa_driver_nl80211_data {
        unsigned int retry_auth:1;
        unsigned int hostapd:1;
        unsigned int start_mode_sta:1;
-       unsigned int start_iface_up:1;
        unsigned int test_use_roc_tx:1;
        unsigned int ignore_deauth_event:1;
        unsigned int vendor_cmd_test_avail:1;