]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Make wpa_driver_nl80211_data::first_bss pointer
authorKyeyoon Park <kyeyoonp@qca.qualcomm.com>
Wed, 30 Oct 2013 00:41:39 +0000 (17:41 -0700)
committerJouni Malinen <j@w1.fi>
Thu, 31 Oct 2013 20:00:31 +0000 (22:00 +0200)
This is needed to allow the first BSS to be removed and replaced by the
next one in the list.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/drivers/driver_nl80211.c

index 5ae9c61a051ec2e2aef16e92e3049d76c57c0627..99351d95c306aecb0bf68c9b218d12bb2b2e76f5 100644 (file)
@@ -294,7 +294,7 @@ struct wpa_driver_nl80211_data {
        struct wpa_driver_scan_filter *filter_ssids;
        size_t num_filter_ssids;
 
-       struct i802_bss first_bss;
+       struct i802_bss *first_bss;
 
        int eapol_tx_sock;
 
@@ -1036,7 +1036,8 @@ static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
                   event.interface_status.ifname,
                   del ? "removed" : "added");
 
-       if (os_strcmp(drv->first_bss.ifname, event.interface_status.ifname) == 0) {
+       if (os_strcmp(drv->first_bss->ifname, event.interface_status.ifname) ==
+           0) {
                if (del) {
                        if (drv->if_removed) {
                                wpa_printf(MSG_DEBUG, "nl80211: if_removed "
@@ -1045,11 +1046,11 @@ static void wpa_driver_nl80211_event_link(struct wpa_driver_nl80211_data *drv,
                        }
                        drv->if_removed = 1;
                } else {
-                       if (if_nametoindex(drv->first_bss.ifname) == 0) {
+                       if (if_nametoindex(drv->first_bss->ifname) == 0) {
                                wpa_printf(MSG_DEBUG, "nl80211: Interface %s "
                                           "does not exist - ignore "
                                           "RTM_NEWLINK",
-                                          drv->first_bss.ifname);
+                                          drv->first_bss->ifname);
                                return;
                        }
                        if (!drv->if_removed) {
@@ -1077,8 +1078,8 @@ 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,
+                                     drv->first_bss->ifname) == 0)
                                return 1;
                        else
                                break;
@@ -1150,7 +1151,7 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
        if (!drv->if_disabled && !(ifi->ifi_flags & IFF_UP)) {
                if (if_indextoname(ifi->ifi_index, namebuf) &&
                    linux_iface_up(drv->global->ioctl_sock,
-                                  drv->first_bss.ifname) > 0) {
+                                  drv->first_bss->ifname) > 0) {
                        wpa_printf(MSG_DEBUG, "nl80211: Ignore interface down "
                                   "event since interface %s is up", namebuf);
                        return;
@@ -1170,18 +1171,18 @@ static void wpa_driver_nl80211_event_rtm_newlink(void *ctx,
        if (drv->if_disabled && (ifi->ifi_flags & IFF_UP)) {
                if (if_indextoname(ifi->ifi_index, namebuf) &&
                    linux_iface_up(drv->global->ioctl_sock,
-                                  drv->first_bss.ifname) == 0) {
+                                  drv->first_bss->ifname) == 0) {
                        wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
                                   "event since interface %s is down",
                                   namebuf);
-               } else if (if_nametoindex(drv->first_bss.ifname) == 0) {
+               } else if (if_nametoindex(drv->first_bss->ifname) == 0) {
                        wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
                                   "event since interface %s does not exist",
-                                  drv->first_bss.ifname);
+                                  drv->first_bss->ifname);
                } else if (drv->if_removed) {
                        wpa_printf(MSG_DEBUG, "nl80211: Ignore interface up "
                                   "event since interface %s is marked "
-                                  "removed", drv->first_bss.ifname);
+                                  "removed", drv->first_bss->ifname);
                } else {
                        wpa_printf(MSG_DEBUG, "nl80211: Interface up");
                        drv->if_disabled = 0;
@@ -1681,7 +1682,7 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
 
        if (type == EVENT_DISASSOC) {
                event.disassoc_info.locally_generated =
-                       !os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN);
+                       !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
                event.disassoc_info.addr = bssid;
                event.disassoc_info.reason_code = reason_code;
                if (frame + len > mgmt->u.disassoc.variable) {
@@ -1691,7 +1692,7 @@ static void mlme_event_deauth_disassoc(struct wpa_driver_nl80211_data *drv,
                }
        } else {
                event.deauth_info.locally_generated =
-                       !os_memcmp(mgmt->sa, drv->first_bss.addr, ETH_ALEN);
+                       !os_memcmp(mgmt->sa, drv->first_bss->addr, ETH_ALEN);
                event.deauth_info.addr = bssid;
                event.deauth_info.reason_code = reason_code;
                if (frame + len > mgmt->u.deauth.variable) {
@@ -2623,7 +2624,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd,
        if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&
            (cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
             cmd == NL80211_CMD_SCAN_ABORTED)) {
-               wpa_driver_nl80211_set_mode(&drv->first_bss,
+               wpa_driver_nl80211_set_mode(drv->first_bss,
                                            drv->ap_scan_as_station);
                drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
        }
@@ -2775,7 +2776,7 @@ static int process_drv_event(struct nl_msg *msg, void *arg)
        if (tb[NL80211_ATTR_IFINDEX]) {
                ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
 
-               for (bss = &drv->first_bss; bss; bss = bss->next)
+               for (bss = drv->first_bss; bss; bss = bss->next)
                        if (ifidx == -1 || ifidx == bss->ifindex) {
                                do_process_drv_event(bss, gnlh->cmd, tb);
                                return NL_SKIP;
@@ -2786,7 +2787,7 @@ static int process_drv_event(struct nl_msg *msg, void *arg)
        } else if (tb[NL80211_ATTR_WDEV]) {
                u64 wdev_id = nla_get_u64(tb[NL80211_ATTR_WDEV]);
                wpa_printf(MSG_DEBUG, "nl80211: Process event on P2P device");
-               for (bss = &drv->first_bss; bss; bss = bss->next) {
+               for (bss = drv->first_bss; bss; bss = bss->next) {
                        if (bss->wdev_id_set && wdev_id == bss->wdev_id) {
                                do_process_drv_event(bss, gnlh->cmd, tb);
                                return NL_SKIP;
@@ -2824,7 +2825,7 @@ static int process_global_event(struct nl_msg *msg, void *arg)
 
        dl_list_for_each_safe(drv, tmp, &global->interfaces,
                              struct wpa_driver_nl80211_data, list) {
-               for (bss = &drv->first_bss; bss; bss = bss->next) {
+               for (bss = drv->first_bss; bss; bss = bss->next) {
                        if ((ifidx == -1 && !wdev_id_set) ||
                            ifidx == bss->ifindex ||
                            (wdev_id_set && bss->wdev_id_set &&
@@ -3319,7 +3320,7 @@ static int wpa_driver_nl80211_get_info(struct wpa_driver_nl80211_data *drv,
                nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_WIPHY);
 
        NLA_PUT_FLAG(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
-       if (nl80211_set_iface_id(msg, &drv->first_bss) < 0)
+       if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
                goto nla_put_failure;
 
        if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info))
@@ -3575,7 +3576,7 @@ static void wpa_driver_nl80211_rfkill_unblocked(void *ctx)
 {
        struct wpa_driver_nl80211_data *drv = ctx;
        wpa_printf(MSG_DEBUG, "nl80211: RFKILL unblocked");
-       if (i802_set_iface_flags(&drv->first_bss, 1)) {
+       if (i802_set_iface_flags(drv->first_bss, 1)) {
                wpa_printf(MSG_DEBUG, "nl80211: Could not set interface UP "
                           "after rfkill unblock");
                return;
@@ -3687,7 +3688,13 @@ static void * wpa_driver_nl80211_init(void *ctx, const char *ifname,
                return NULL;
        drv->global = global_priv;
        drv->ctx = ctx;
-       bss = &drv->first_bss;
+
+       drv->first_bss = os_zalloc(sizeof(*drv->first_bss));
+       if (!drv->first_bss) {
+               os_free(drv);
+               return NULL;
+       }
+       bss = drv->first_bss;
        bss->drv = drv;
        bss->ctx = ctx;
 
@@ -4108,7 +4115,7 @@ wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
 #ifndef HOSTAPD
        enum nl80211_iftype nlmode = NL80211_IFTYPE_STATION;
 #endif /* HOSTAPD */
-       struct i802_bss *bss = &drv->first_bss;
+       struct i802_bss *bss = drv->first_bss;
        int send_rfkill_event = 0;
 
        drv->ifindex = if_nametoindex(bss->ifname);
@@ -4275,7 +4282,7 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
        }
        nl_cb_put(drv->nl_cb);
 
-       nl80211_destroy_bss(&drv->first_bss);
+       nl80211_destroy_bss(drv->first_bss);
 
        os_free(drv->filter_ssids);
 
@@ -4286,6 +4293,7 @@ static void wpa_driver_nl80211_deinit(struct i802_bss *bss)
 
        os_free(drv->extended_capa);
        os_free(drv->extended_capa_mask);
+       os_free(drv->first_bss);
        os_free(drv);
 }
 
@@ -4302,7 +4310,7 @@ static void wpa_driver_nl80211_scan_timeout(void *eloop_ctx, void *timeout_ctx)
 {
        struct wpa_driver_nl80211_data *drv = eloop_ctx;
        if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED) {
-               wpa_driver_nl80211_set_mode(&drv->first_bss,
+               wpa_driver_nl80211_set_mode(drv->first_bss,
                                            drv->ap_scan_as_station);
                drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;
        }
@@ -4907,7 +4915,7 @@ nl80211_get_scan_results(struct wpa_driver_nl80211_data *drv)
                goto nla_put_failure;
 
        nl80211_cmd(drv, msg, NLM_F_DUMP, NL80211_CMD_GET_SCAN);
-       if (nl80211_set_iface_id(msg, &drv->first_bss) < 0)
+       if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
                goto nla_put_failure;
 
        arg.drv = drv;
@@ -5550,7 +5558,7 @@ static int wpa_driver_nl80211_authenticate_retry(
        struct wpa_driver_nl80211_data *drv)
 {
        struct wpa_driver_auth_params params;
-       struct i802_bss *bss = &drv->first_bss;
+       struct i802_bss *bss = drv->first_bss;
        int i;
 
        wpa_printf(MSG_DEBUG, "nl80211: Try to authenticate again");
@@ -6999,7 +7007,7 @@ static int nl80211_create_iface_once(struct wpa_driver_nl80211_data *drv,
                return -1;
 
        nl80211_cmd(drv, msg, 0, NL80211_CMD_NEW_INTERFACE);
-       if (nl80211_set_iface_id(msg, &drv->first_bss) < 0)
+       if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
                goto nla_put_failure;
        NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, ifname);
        NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, iftype);
@@ -7412,17 +7420,17 @@ nl80211_create_monitor_interface(struct wpa_driver_nl80211_data *drv)
                return 0;
        }
 
-       if (os_strncmp(drv->first_bss.ifname, "p2p-", 4) == 0) {
+       if (os_strncmp(drv->first_bss->ifname, "p2p-", 4) == 0) {
                /*
                 * P2P interface name is of the format p2p-%s-%d. For monitor
                 * interface name corresponding to P2P GO, replace "p2p-" with
                 * "mon-" to retain the same interface name length and to
                 * indicate that it is a monitor interface.
                 */
-               snprintf(buf, IFNAMSIZ, "mon-%s", drv->first_bss.ifname + 4);
+               snprintf(buf, IFNAMSIZ, "mon-%s", drv->first_bss->ifname + 4);
        } else {
                /* Non-P2P interface with AP functionality. */
-               snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss.ifname);
+               snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss->ifname);
        }
 
        buf[IFNAMSIZ - 1] = '\0';
@@ -7719,14 +7727,14 @@ static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
                nlmode = NL80211_IFTYPE_AP;
 
        old_mode = drv->nlmode;
-       if (wpa_driver_nl80211_set_mode(&drv->first_bss, nlmode)) {
+       if (wpa_driver_nl80211_set_mode(drv->first_bss, nlmode)) {
                nl80211_remove_monitor_interface(drv);
                return -1;
        }
 
-       if (wpa_driver_nl80211_set_freq(&drv->first_bss, &freq)) {
+       if (wpa_driver_nl80211_set_freq(drv->first_bss, &freq)) {
                if (old_mode != nlmode)
-                       wpa_driver_nl80211_set_mode(&drv->first_bss, old_mode);
+                       wpa_driver_nl80211_set_mode(drv->first_bss, old_mode);
                nl80211_remove_monitor_interface(drv);
                return -1;
        }
@@ -7758,7 +7766,7 @@ static int nl80211_leave_ibss(struct wpa_driver_nl80211_data *drv)
        wpa_printf(MSG_DEBUG, "nl80211: Leave IBSS request sent successfully");
 
 nla_put_failure:
-       if (wpa_driver_nl80211_set_mode(&drv->first_bss,
+       if (wpa_driver_nl80211_set_mode(drv->first_bss,
                                        NL80211_IFTYPE_STATION)) {
                wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
                           "station mode");
@@ -7778,7 +7786,7 @@ static int wpa_driver_nl80211_ibss(struct wpa_driver_nl80211_data *drv,
 
        wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
 
-       if (wpa_driver_nl80211_set_mode(&drv->first_bss,
+       if (wpa_driver_nl80211_set_mode(drv->first_bss,
                                        NL80211_IFTYPE_ADHOC)) {
                wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
                           "IBSS mode");
@@ -8291,7 +8299,7 @@ static int nl80211_set_mode(struct wpa_driver_nl80211_data *drv,
                return -ENOMEM;
 
        nl80211_cmd(drv, msg, 0, NL80211_CMD_SET_INTERFACE);
-       if (nl80211_set_iface_id(msg, &drv->first_bss) < 0)
+       if (nl80211_set_iface_id(msg, drv->first_bss) < 0)
                goto nla_put_failure;
        NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, mode);
 
@@ -9202,7 +9210,7 @@ static int nl80211_addr_in_use(struct nl80211_global *global, const u8 *addr)
        struct wpa_driver_nl80211_data *drv;
        dl_list_for_each(drv, &global->interfaces,
                         struct wpa_driver_nl80211_data, list) {
-               if (os_memcmp(addr, drv->first_bss.addr, ETH_ALEN) == 0)
+               if (os_memcmp(addr, drv->first_bss->addr, ETH_ALEN) == 0)
                        return 1;
        }
        return 0;
@@ -9217,9 +9225,9 @@ static int nl80211_p2p_interface_addr(struct wpa_driver_nl80211_data *drv,
        if (!drv->global)
                return -1;
 
-       os_memcpy(new_addr, drv->first_bss.addr, ETH_ALEN);
+       os_memcpy(new_addr, drv->first_bss->addr, ETH_ALEN);
        for (idx = 0; idx < 64; idx++) {
-               new_addr[0] = drv->first_bss.addr[0] | 0x02;
+               new_addr[0] = drv->first_bss->addr[0] | 0x02;
                new_addr[0] ^= idx << 2;
                if (!nl80211_addr_in_use(drv->global, new_addr))
                        break;
@@ -9372,10 +9380,10 @@ static int wpa_driver_nl80211_if_add(void *priv, enum wpa_driver_if_type type,
                os_memcpy(new_bss->addr, if_addr, ETH_ALEN);
                new_bss->ifindex = ifidx;
                new_bss->drv = drv;
-               new_bss->next = drv->first_bss.next;
-               new_bss->freq = drv->first_bss.freq;
+               new_bss->next = drv->first_bss->next;
+               new_bss->freq = drv->first_bss->freq;
                new_bss->ctx = bss_ctx;
-               drv->first_bss.next = new_bss;
+               drv->first_bss->next = new_bss;
                if (drv_priv)
                        *drv_priv = new_bss;
                nl80211_init_bss(new_bss);
@@ -9423,10 +9431,10 @@ static int wpa_driver_nl80211_if_remove(struct i802_bss *bss,
                                   bss->brname, strerror(errno));
        }
 
-       if (bss != &drv->first_bss) {
+       if (bss != drv->first_bss) {
                struct i802_bss *tbss;
 
-               for (tbss = &drv->first_bss; tbss; tbss = tbss->next) {
+               for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
                        if (tbss->next == bss) {
                                tbss->next = bss->next;
                                /* Unsubscribe management frames */
@@ -10029,10 +10037,10 @@ static int wpa_driver_nl80211_shared_freq(void *priv)
 
                wpa_printf(MSG_DEBUG, "nl80211: Found a match for PHY %s - %s "
                           MACSTR,
-                          driver->phyname, driver->first_bss.ifname,
-                          MAC2STR(driver->first_bss.addr));
+                          driver->phyname, driver->first_bss->ifname,
+                          MAC2STR(driver->first_bss->addr));
                if (is_ap_interface(driver->nlmode))
-                       freq = driver->first_bss.freq;
+                       freq = driver->first_bss->freq;
                else
                        freq = nl80211_get_assoc_freq(driver);
                wpa_printf(MSG_DEBUG, "nl80211: Shared freq for PHY %s: %d",