mac80211: add support for the noscan option for skipping the initial scan on hostapd...
[librecmc/librecmc.git] / package / hostapd / patches / 150-mbss_driver_handling.patch
1 --- a/src/drivers/driver_nl80211.c
2 +++ b/src/drivers/driver_nl80211.c
3 @@ -59,8 +59,10 @@
4  #endif
5  
6  struct i802_bss {
7 +       struct wpa_driver_nl80211_data *drv;
8         struct i802_bss *next;
9         int ifindex;
10 +       char ifname[IFNAMSIZ + 1];
11         unsigned int beacon_set:1;
12  };
13  
14 @@ -68,7 +70,6 @@ struct wpa_driver_nl80211_data {
15         void *ctx;
16         struct netlink_data *netlink;
17         int ioctl_sock; /* socket for ioctl() use */
18 -       char ifname[IFNAMSIZ + 1];
19         char brname[IFNAMSIZ];
20         int ifindex;
21         int if_removed;
22 @@ -107,6 +108,8 @@ struct wpa_driver_nl80211_data {
23  
24         u64 remain_on_chan_cookie;
25  
26 +       struct i802_bss first_bss;
27 +
28  #ifdef HOSTAPD
29         int eapol_sock; /* socket for EAPOL frames */
30  
31 @@ -114,8 +117,6 @@ struct wpa_driver_nl80211_data {
32         int *if_indices;
33         int num_if_indices;
34  
35 -       struct i802_bss bss;
36 -
37         int last_freq;
38         int last_freq_ht;
39  #endif /* HOSTAPD */
40 @@ -135,8 +136,6 @@ static void nl80211_remove_monitor_inter
41  #ifdef HOSTAPD
42  static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
43  static void del_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx);
44 -static struct i802_bss * get_bss(struct wpa_driver_nl80211_data *drv,
45 -                                int ifindex);
46  static int i802_set_freq(void *priv, struct hostapd_freq_params *freq);
47  static int wpa_driver_nl80211_if_remove(void *priv,
48                                         enum wpa_driver_if_type type,
49 @@ -278,7 +277,8 @@ nla_put_failure:
50  
51  static int wpa_driver_nl80211_get_bssid(void *priv, u8 *bssid)
52  {
53 -       struct wpa_driver_nl80211_data *drv = priv;
54 +       struct i802_bss *bss = priv;
55 +       struct wpa_driver_nl80211_data *drv = bss->drv;
56         if (!drv->associated)
57                 return -1;
58         os_memcpy(bssid, drv->bssid, ETH_ALEN);
59 @@ -288,7 +288,8 @@ static int wpa_driver_nl80211_get_bssid(
60  
61  static int wpa_driver_nl80211_get_ssid(void *priv, u8 *ssid)
62  {
63 -       struct wpa_driver_nl80211_data *drv = priv;
64 +       struct i802_bss *bss = priv;
65 +       struct wpa_driver_nl80211_data *drv = bss->drv;
66         if (!drv->associated)
67                 return -1;
68         os_memcpy(ssid, drv->ssid, drv->ssid_len);
69 @@ -313,7 +314,7 @@ static void wpa_driver_nl80211_event_lin
70                    event.interface_status.ifname,
71                    del ? "removed" : "added");
72  
73 -       if (os_strcmp(drv->ifname, event.interface_status.ifname) == 0) {
74 +       if (os_strcmp(drv->first_bss.ifname, event.interface_status.ifname) == 0) {
75                 if (del)
76                         drv->if_removed = 1;
77                 else
78 @@ -336,7 +337,7 @@ static int wpa_driver_nl80211_own_ifname
79         rta_len = RTA_ALIGN(sizeof(struct rtattr));
80         while (RTA_OK(attr, attrlen)) {
81                 if (attr->rta_type == IFLA_IFNAME) {
82 -                       if (os_strcmp(((char *) attr) + rta_len, drv->ifname)
83 +                       if (os_strcmp(((char *) attr) + rta_len, drv->first_bss.ifname)
84                             == 0)
85                                 return 1;
86                         else
87 @@ -356,7 +357,7 @@ static int wpa_driver_nl80211_own_ifinde
88                 return 1;
89  
90         if (drv->if_removed && wpa_driver_nl80211_own_ifname(drv, buf, len)) {
91 -               drv->ifindex = if_nametoindex(drv->ifname);
92 +               drv->first_bss.ifindex = if_nametoindex(drv->first_bss.ifname);
93                 wpa_printf(MSG_DEBUG, "nl80211: Update ifindex for a removed "
94                            "interface");
95                 wpa_driver_nl80211_finish_drv_init(drv);
96 @@ -785,7 +786,7 @@ static int process_event(struct nl_msg *
97         if (drv->ap_scan_as_station &&
98             (gnlh->cmd == NL80211_CMD_NEW_SCAN_RESULTS ||
99              gnlh->cmd == NL80211_CMD_SCAN_ABORTED)) {
100 -               wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_AP);
101 +               wpa_driver_nl80211_set_mode(&drv->first_bss, IEEE80211_MODE_AP);
102                 drv->ap_scan_as_station = 0;
103         }
104  
105 @@ -889,7 +890,8 @@ static void wpa_driver_nl80211_event_rec
106   */
107  static int wpa_driver_nl80211_set_country(void *priv, const char *alpha2_arg)
108  {
109 -       struct wpa_driver_nl80211_data *drv = priv;
110 +       struct i802_bss *bss = priv;
111 +       struct wpa_driver_nl80211_data *drv = bss->drv;
112         char alpha2[3];
113         struct nl_msg *msg;
114  
115 @@ -978,7 +980,7 @@ static int wpa_driver_nl80211_get_info(s
116         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
117                     0, NL80211_CMD_GET_WIPHY, 0);
118  
119 -       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
120 +       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->first_bss.ifindex);
121  
122         if (send_and_recv_msgs(drv, msg, wiphy_info_handler, info) == 0)
123                 return 0;
124 @@ -1152,15 +1154,18 @@ static void * wpa_driver_nl80211_init(vo
125  {
126         struct wpa_driver_nl80211_data *drv;
127         struct netlink_config *cfg;
128 +       struct i802_bss *bss;
129  
130         drv = os_zalloc(sizeof(*drv));
131         if (drv == NULL)
132                 return NULL;
133         drv->ctx = ctx;
134 -       os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
135 +       bss = &drv->first_bss;
136 +       os_strlcpy(bss->ifname, ifname, sizeof(bss->ifname));
137         drv->monitor_ifidx = -1;
138         drv->monitor_sock = -1;
139         drv->ioctl_sock = -1;
140 +       drv->first_bss.drv = drv;
141  
142         if (wpa_driver_nl80211_init_nl(drv, ctx)) {
143                 os_free(drv);
144 @@ -1187,7 +1192,7 @@ static void * wpa_driver_nl80211_init(vo
145         if (wpa_driver_nl80211_finish_drv_init(drv))
146                 goto failed;
147  
148 -       return drv;
149 +       return bss;
150  
151  failed:
152         netlink_deinit(drv->netlink);
153 @@ -1207,17 +1212,19 @@ failed:
154  static int
155  wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv)
156  {
157 -       drv->ifindex = if_nametoindex(drv->ifname);
158 +       struct i802_bss *bss = &drv->first_bss;
159 +
160 +       drv->ifindex = if_nametoindex(drv->first_bss.ifname);
161  
162  #ifndef HOSTAPD
163 -       if (wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA) < 0) {
164 +       if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA) < 0) {
165                 wpa_printf(MSG_DEBUG, "nl80211: Could not configure driver to "
166                            "use managed mode");
167         }
168  
169 -       if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1)) {
170 +       if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1)) {
171                 wpa_printf(MSG_ERROR, "Could not set interface '%s' UP",
172 -                          drv->ifname);
173 +                          bss->ifname);
174                 return -1;
175         }
176  
177 @@ -1232,20 +1239,6 @@ wpa_driver_nl80211_finish_drv_init(struc
178  }
179  
180  
181 -#ifdef HOSTAPD
182 -static void wpa_driver_nl80211_free_bss(struct wpa_driver_nl80211_data *drv)
183 -{
184 -       struct i802_bss *bss, *prev;
185 -       bss = drv->bss.next;
186 -       while (bss) {
187 -               prev = bss;
188 -               bss = bss->next;
189 -               os_free(bss);
190 -       }
191 -}
192 -#endif /* HOSTAPD */
193 -
194 -
195  static int wpa_driver_nl80211_del_beacon(struct wpa_driver_nl80211_data *drv)
196  {
197         struct nl_msg *msg;
198 @@ -1273,14 +1266,15 @@ static int wpa_driver_nl80211_del_beacon
199   */
200  static void wpa_driver_nl80211_deinit(void *priv)
201  {
202 -       struct wpa_driver_nl80211_data *drv = priv;
203 +       struct i802_bss *bss = priv;
204 +       struct wpa_driver_nl80211_data *drv = bss->drv;
205  
206         if (drv->added_if_into_bridge) {
207 -               if (linux_br_del_if(drv->ioctl_sock, drv->brname, drv->ifname)
208 +               if (linux_br_del_if(drv->ioctl_sock, drv->brname, bss->ifname)
209                     < 0)
210                         wpa_printf(MSG_INFO, "nl80211: Failed to remove "
211                                    "interface %s from bridge %s: %s",
212 -                                  drv->ifname, drv->brname, strerror(errno));
213 +                                  bss->ifname, drv->brname, strerror(errno));
214         }
215         if (drv->added_bridge) {
216                 if (linux_br_del(drv->ioctl_sock, drv->brname) < 0)
217 @@ -1310,8 +1304,6 @@ static void wpa_driver_nl80211_deinit(vo
218  
219         if (drv->if_indices != drv->default_if_indices)
220                 os_free(drv->if_indices);
221 -
222 -       wpa_driver_nl80211_free_bss(drv);
223  #endif /* HOSTAPD */
224  
225         if (drv->disable_11b_rates)
226 @@ -1322,8 +1314,8 @@ static void wpa_driver_nl80211_deinit(vo
227  
228         eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx);
229  
230 -       (void) linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0);
231 -       wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA);
232 +       (void) linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0);
233 +       wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_INFRA);
234  
235         if (drv->ioctl_sock >= 0)
236                 close(drv->ioctl_sock);
237 @@ -1355,7 +1347,7 @@ static void wpa_driver_nl80211_scan_time
238  {
239         struct wpa_driver_nl80211_data *drv = eloop_ctx;
240         if (drv->ap_scan_as_station) {
241 -               wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_AP);
242 +               wpa_driver_nl80211_set_mode(&drv->first_bss, IEEE80211_MODE_AP);
243                 drv->ap_scan_as_station = 0;
244         }
245         wpa_printf(MSG_DEBUG, "Scan timeout - try to get results");
246 @@ -1372,7 +1364,8 @@ static void wpa_driver_nl80211_scan_time
247  static int wpa_driver_nl80211_scan(void *priv,
248                                    struct wpa_driver_scan_params *params)
249  {
250 -       struct wpa_driver_nl80211_data *drv = priv;
251 +       struct i802_bss *bss = priv;
252 +       struct wpa_driver_nl80211_data *drv = bss->drv;
253         int ret = 0, timeout;
254         struct nl_msg *msg, *ssids, *freqs;
255         size_t i;
256 @@ -1421,12 +1414,12 @@ static int wpa_driver_nl80211_scan(void 
257                          * mac80211 does not allow scan requests in AP mode, so
258                          * try to do this in station mode.
259                          */
260 -                       if (wpa_driver_nl80211_set_mode(drv,
261 +                       if (wpa_driver_nl80211_set_mode(bss,
262                                                         IEEE80211_MODE_INFRA))
263                                 goto nla_put_failure;
264  
265                         if (wpa_driver_nl80211_scan(drv, params)) {
266 -                               wpa_driver_nl80211_set_mode(drv,
267 +                               wpa_driver_nl80211_set_mode(bss,
268                                                             IEEE80211_MODE_AP);
269                                 goto nla_put_failure;
270                         }
271 @@ -1662,7 +1655,8 @@ static void wpa_scan_results_free(struct
272  static struct wpa_scan_results *
273  wpa_driver_nl80211_get_scan_results(void *priv)
274  {
275 -       struct wpa_driver_nl80211_data *drv = priv;
276 +       struct i802_bss *bss = priv;
277 +       struct wpa_driver_nl80211_data *drv = bss->drv;
278         struct nl_msg *msg;
279         struct wpa_scan_results *res;
280         int ret;
281 @@ -1701,7 +1695,8 @@ static int wpa_driver_nl80211_set_key(co
282                                       const u8 *seq, size_t seq_len,
283                                       const u8 *key, size_t key_len)
284  {
285 -       struct wpa_driver_nl80211_data *drv = priv;
286 +       struct i802_bss *bss = priv;
287 +       struct wpa_driver_nl80211_data *drv = bss->drv;
288         int ifindex = if_nametoindex(ifname);
289         struct nl_msg *msg;
290         int ret;
291 @@ -1958,7 +1953,8 @@ static int wpa_driver_nl80211_disconnect
292  static int wpa_driver_nl80211_deauthenticate(void *priv, const u8 *addr,
293                                              int reason_code)
294  {
295 -       struct wpa_driver_nl80211_data *drv = priv;
296 +       struct i802_bss *bss = priv;
297 +       struct wpa_driver_nl80211_data *drv = bss->drv;
298         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
299                 return wpa_driver_nl80211_disconnect(drv, addr, reason_code);
300         wpa_printf(MSG_DEBUG, "%s", __func__);
301 @@ -1971,7 +1967,8 @@ static int wpa_driver_nl80211_deauthenti
302  static int wpa_driver_nl80211_disassociate(void *priv, const u8 *addr,
303                                            int reason_code)
304  {
305 -       struct wpa_driver_nl80211_data *drv = priv;
306 +       struct i802_bss *bss = priv;
307 +       struct wpa_driver_nl80211_data *drv = bss->drv;
308         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME))
309                 return wpa_driver_nl80211_disconnect(drv, addr, reason_code);
310         wpa_printf(MSG_DEBUG, "%s", __func__);
311 @@ -1984,7 +1981,8 @@ static int wpa_driver_nl80211_disassocia
312  static int wpa_driver_nl80211_authenticate(
313         void *priv, struct wpa_driver_auth_params *params)
314  {
315 -       struct wpa_driver_nl80211_data *drv = priv;
316 +       struct i802_bss *bss = priv;
317 +       struct wpa_driver_nl80211_data *drv = bss->drv;
318         int ret = -1, i;
319         struct nl_msg *msg;
320         enum nl80211_auth_type type;
321 @@ -1996,7 +1994,7 @@ static int wpa_driver_nl80211_authentica
322         if (drv->nlmode != NL80211_IFTYPE_STATION)
323                 wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA);
324  
325 -       if (wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA) < 0)
326 +       if (wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA) < 0)
327                 return -1;
328  
329  retry:
330 @@ -2013,7 +2011,7 @@ retry:
331         for (i = 0; i < 4; i++) {
332                 if (!params->wep_key[i])
333                         continue;
334 -               wpa_driver_nl80211_set_key(drv->ifname, drv, WPA_ALG_WEP, NULL,
335 +               wpa_driver_nl80211_set_key(bss->ifname, drv, WPA_ALG_WEP, NULL,
336                                            i,
337                                            i == params->wep_tx_keyidx, NULL, 0,
338                                            params->wep_key[i],
339 @@ -2348,7 +2346,8 @@ wpa_driver_nl80211_add_11b(struct hostap
340  static struct hostapd_hw_modes *
341  wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
342  {
343 -       struct wpa_driver_nl80211_data *drv = priv;
344 +       struct i802_bss *bss = priv;
345 +       struct wpa_driver_nl80211_data *drv = bss->drv;
346         struct nl_msg *msg;
347         struct phy_info_arg result = {
348                 .num_modes = num_modes,
349 @@ -2417,7 +2416,8 @@ static int wpa_driver_nl80211_send_frame
350  static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data,
351                                         size_t data_len)
352  {
353 -       struct wpa_driver_nl80211_data *drv = priv;
354 +       struct i802_bss *bss = priv;
355 +       struct wpa_driver_nl80211_data *drv = bss->drv;
356         struct ieee80211_mgmt *mgmt;
357         int encrypt = 1;
358         u16 fc;
359 @@ -2448,23 +2448,15 @@ static int wpa_driver_nl80211_set_beacon
360                                          const u8 *tail, size_t tail_len,
361                                          int dtim_period, int beacon_int)
362  {
363 -       struct wpa_driver_nl80211_data *drv = priv;
364 +       struct i802_bss *bss = priv;
365 +       struct wpa_driver_nl80211_data *drv = bss->drv;
366         struct nl_msg *msg;
367         u8 cmd = NL80211_CMD_NEW_BEACON;
368         int ret;
369         int beacon_set;
370         int ifindex = if_nametoindex(ifname);
371 -#ifdef HOSTAPD
372 -       struct i802_bss *bss;
373  
374 -       bss = get_bss(drv, ifindex);
375 -       if (bss == NULL)
376 -               return -ENOENT;
377         beacon_set = bss->beacon_set;
378 -#else /* HOSTAPD */
379 -       beacon_set = drv->beacon_set;
380 -#endif /* HOSTAPD */
381 -
382         msg = nlmsg_alloc();
383         if (!msg)
384                 return -ENOMEM;
385 @@ -2487,11 +2479,7 @@ static int wpa_driver_nl80211_set_beacon
386                 wpa_printf(MSG_DEBUG, "nl80211: Beacon set failed: %d (%s)",
387                            ret, strerror(-ret));
388         } else {
389 -#ifdef HOSTAPD
390                 bss->beacon_set = 1;
391 -#else /* HOSTAPD */
392 -               drv->beacon_set = 1;
393 -#endif /* HOSTAPD */
394         }
395         return ret;
396   nla_put_failure:
397 @@ -2545,7 +2533,8 @@ nla_put_failure:
398  static int wpa_driver_nl80211_sta_add(const char *ifname, void *priv,
399                                       struct hostapd_sta_add_params *params)
400  {
401 -       struct wpa_driver_nl80211_data *drv = priv;
402 +       struct i802_bss *bss = priv;
403 +       struct wpa_driver_nl80211_data *drv = bss->drv;
404         struct nl_msg *msg;
405         int ret = -ENOBUFS;
406  
407 @@ -2582,7 +2571,8 @@ static int wpa_driver_nl80211_sta_add(co
408  
409  static int wpa_driver_nl80211_sta_remove(void *priv, const u8 *addr)
410  {
411 -       struct wpa_driver_nl80211_data *drv = priv;
412 +       struct i802_bss *bss = priv;
413 +       struct wpa_driver_nl80211_data *drv = bss->drv;
414         struct nl_msg *msg;
415         int ret;
416  
417 @@ -2594,7 +2584,7 @@ static int wpa_driver_nl80211_sta_remove
418                     0, NL80211_CMD_DEL_STATION, 0);
419  
420         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
421 -                   if_nametoindex(drv->ifname));
422 +                   if_nametoindex(bss->ifname));
423         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
424  
425         ret = send_and_recv_msgs(drv, msg, NULL, NULL);
426 @@ -3032,7 +3022,7 @@ nl80211_create_monitor_interface(struct 
427         int optval;
428         socklen_t optlen;
429  
430 -       snprintf(buf, IFNAMSIZ, "mon.%s", drv->ifname);
431 +       snprintf(buf, IFNAMSIZ, "mon.%s", drv->first_bss.ifname);
432         buf[IFNAMSIZ - 1] = '\0';
433  
434         drv->monitor_ifidx =
435 @@ -3092,7 +3082,8 @@ static int wpa_driver_nl80211_hapd_send_
436         void *priv, const u8 *addr, const u8 *data,
437         size_t data_len, int encrypt, const u8 *own_addr)
438  {
439 -       struct wpa_driver_nl80211_data *drv = priv;
440 +       struct i802_bss *bss = priv;
441 +       struct wpa_driver_nl80211_data *drv = bss->drv;
442         struct ieee80211_hdr *hdr;
443         size_t len;
444         u8 *pos;
445 @@ -3177,7 +3168,8 @@ static int wpa_driver_nl80211_sta_set_fl
446                                             int total_flags, int flags_or,
447                                             int flags_and)
448  {
449 -       struct wpa_driver_nl80211_data *drv = priv;
450 +       struct i802_bss *bss = priv;
451 +       struct wpa_driver_nl80211_data *drv = bss->drv;
452         struct nl_msg *msg, *flags = NULL;
453         struct nl80211_sta_flag_update upd;
454  
455 @@ -3195,7 +3187,7 @@ static int wpa_driver_nl80211_sta_set_fl
456                     0, NL80211_CMD_SET_STATION, 0);
457  
458         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
459 -                   if_nametoindex(drv->ifname));
460 +                   if_nametoindex(bss->ifname));
461         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
462  
463         /*
464 @@ -3234,7 +3226,7 @@ static int wpa_driver_nl80211_sta_set_fl
465  static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
466                                  struct wpa_driver_associate_params *params)
467  {
468 -       if (wpa_driver_nl80211_set_mode(drv, params->mode) ||
469 +       if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode) ||
470             wpa_driver_nl80211_set_freq(drv, params->freq, 0, 0)) {
471                 nl80211_remove_monitor_interface(drv);
472                 return -1;
473 @@ -3285,7 +3277,7 @@ static int wpa_driver_nl80211_ibss(struc
474  
475         wpa_printf(MSG_DEBUG, "nl80211: Join IBSS (ifindex=%d)", drv->ifindex);
476  
477 -       if (wpa_driver_nl80211_set_mode(drv, params->mode)) {
478 +       if (wpa_driver_nl80211_set_mode(&drv->first_bss, params->mode)) {
479                 wpa_printf(MSG_INFO, "nl80211: Failed to set interface into "
480                            "IBSS mode");
481                 return -1;
482 @@ -3499,7 +3491,8 @@ nla_put_failure:
483  static int wpa_driver_nl80211_associate(
484         void *priv, struct wpa_driver_associate_params *params)
485  {
486 -       struct wpa_driver_nl80211_data *drv = priv;
487 +       struct i802_bss *bss = priv;
488 +       struct wpa_driver_nl80211_data *drv = bss->drv;
489         int ret = -1;
490         struct nl_msg *msg;
491  
492 @@ -3510,7 +3503,7 @@ static int wpa_driver_nl80211_associate(
493                 return wpa_driver_nl80211_ibss(drv, params);
494  
495         if (!(drv->capa.flags & WPA_DRIVER_FLAGS_SME)) {
496 -               if (wpa_driver_nl80211_set_mode(drv, params->mode) < 0)
497 +               if (wpa_driver_nl80211_set_mode(priv, params->mode) < 0)
498                         return -1;
499                 return wpa_driver_nl80211_connect(drv, params);
500         }
501 @@ -3611,7 +3604,8 @@ nla_put_failure:
502  
503  static int wpa_driver_nl80211_set_mode(void *priv, int mode)
504  {
505 -       struct wpa_driver_nl80211_data *drv = priv;
506 +       struct i802_bss *bss = priv;
507 +       struct wpa_driver_nl80211_data *drv = bss->drv;
508         int ret = -1;
509         int nlmode;
510  
511 @@ -3646,10 +3640,10 @@ static int wpa_driver_nl80211_set_mode(v
512          * take the device down, try to set the mode again, and bring the
513          * device back up.
514          */
515 -       if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0) == 0) {
516 +       if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0) == 0) {
517                 /* Try to set the mode again while the interface is down */
518                 ret = nl80211_set_mode(drv, drv->ifindex, nlmode);
519 -               if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1))
520 +               if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1))
521                         ret = -1;
522         }
523  
524 @@ -3684,7 +3678,8 @@ done:
525  static int wpa_driver_nl80211_get_capa(void *priv,
526                                        struct wpa_driver_capa *capa)
527  {
528 -       struct wpa_driver_nl80211_data *drv = priv;
529 +       struct i802_bss *bss = priv;
530 +       struct wpa_driver_nl80211_data *drv = bss->drv;
531         if (!drv->has_capability)
532                 return -1;
533         os_memcpy(capa, &drv->capa, sizeof(*capa));
534 @@ -3694,7 +3689,8 @@ static int wpa_driver_nl80211_get_capa(v
535  
536  static int wpa_driver_nl80211_set_operstate(void *priv, int state)
537  {
538 -       struct wpa_driver_nl80211_data *drv = priv;
539 +       struct i802_bss *bss = priv;
540 +       struct wpa_driver_nl80211_data *drv = bss->drv;
541  
542         wpa_printf(MSG_DEBUG, "%s: operstate %d->%d (%s)",
543                    __func__, drv->operstate, state, state ? "UP" : "DORMANT");
544 @@ -3706,7 +3702,8 @@ static int wpa_driver_nl80211_set_operst
545  
546  static int wpa_driver_nl80211_set_supp_port(void *priv, int authorized)
547  {
548 -       struct wpa_driver_nl80211_data *drv = priv;
549 +       struct i802_bss *bss = priv;
550 +       struct wpa_driver_nl80211_data *drv = bss->drv;
551         struct nl_msg *msg;
552         struct nl80211_sta_flag_update upd;
553  
554 @@ -3718,7 +3715,7 @@ static int wpa_driver_nl80211_set_supp_p
555                     0, NL80211_CMD_SET_STATION, 0);
556  
557         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
558 -                   if_nametoindex(drv->ifname));
559 +                   if_nametoindex(bss->ifname));
560         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, drv->bssid);
561  
562         os_memset(&upd, 0, sizeof(upd));
563 @@ -3735,20 +3732,6 @@ static int wpa_driver_nl80211_set_supp_p
564  
565  #ifdef HOSTAPD
566  
567 -static struct i802_bss * get_bss(struct wpa_driver_nl80211_data *drv,
568 -                                int ifindex)
569 -{
570 -       struct i802_bss *bss = &drv->bss;
571 -       while (bss) {
572 -               if (ifindex == bss->ifindex)
573 -                       return bss;
574 -               bss = bss->next;
575 -       }
576 -       wpa_printf(MSG_DEBUG, "nl80211: get_bss(%d) failed", ifindex);
577 -       return NULL;
578 -}
579 -
580 -
581  static void add_ifidx(struct wpa_driver_nl80211_data *drv, int ifidx)
582  {
583         int i;
584 @@ -3842,7 +3825,8 @@ static int get_key_handler(struct nl_msg
585  static int i802_get_seqnum(const char *iface, void *priv, const u8 *addr,
586                            int idx, u8 *seq)
587  {
588 -       struct wpa_driver_nl80211_data *drv = priv;
589 +       struct i802_bss *bss = priv;
590 +       struct wpa_driver_nl80211_data *drv = bss->drv;
591         struct nl_msg *msg;
592  
593         msg = nlmsg_alloc();
594 @@ -3868,7 +3852,8 @@ static int i802_get_seqnum(const char *i
595  static int i802_set_rate_sets(void *priv, int *supp_rates, int *basic_rates,
596                               int mode)
597  {
598 -       struct wpa_driver_nl80211_data *drv = priv;
599 +       struct i802_bss *bss = priv;
600 +       struct wpa_driver_nl80211_data *drv = bss->drv;
601         struct nl_msg *msg;
602         u8 rates[NL80211_MAX_SUPP_RATES];
603         u8 rates_len = 0;
604 @@ -3887,7 +3872,7 @@ static int i802_set_rate_sets(void *priv
605         NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, rates_len, rates);
606  
607         /* TODO: multi-BSS support */
608 -       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname));
609 +       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
610  
611         return send_and_recv_msgs(drv, msg, NULL, NULL);
612   nla_put_failure:
613 @@ -3898,7 +3883,8 @@ static int i802_set_rate_sets(void *priv
614  /* Set kernel driver on given frequency (MHz) */
615  static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
616  {
617 -       struct wpa_driver_nl80211_data *drv = priv;
618 +       struct i802_bss *bss = priv;
619 +       struct wpa_driver_nl80211_data *drv = bss->drv;
620         return wpa_driver_nl80211_set_freq(drv, freq->freq, freq->ht_enabled,
621                                            freq->sec_channel_offset);
622  }
623 @@ -3906,7 +3892,8 @@ static int i802_set_freq(void *priv, str
624  
625  static int i802_set_rts(void *priv, int rts)
626  {
627 -       struct wpa_driver_nl80211_data *drv = priv;
628 +       struct i802_bss *bss = priv;
629 +       struct wpa_driver_nl80211_data *drv = bss->drv;
630         struct nl_msg *msg;
631         int ret = -ENOBUFS;
632         u32 val;
633 @@ -3937,7 +3924,8 @@ nla_put_failure:
634  
635  static int i802_set_frag(void *priv, int frag)
636  {
637 -       struct wpa_driver_nl80211_data *drv = priv;
638 +       struct i802_bss *bss = priv;
639 +       struct wpa_driver_nl80211_data *drv = bss->drv;
640         struct nl_msg *msg;
641         int ret = -ENOBUFS;
642         u32 val;
643 @@ -3968,7 +3956,8 @@ nla_put_failure:
644  
645  static int i802_flush(void *priv)
646  {
647 -       struct wpa_driver_nl80211_data *drv = priv;
648 +       struct i802_bss *bss = priv;
649 +       struct wpa_driver_nl80211_data *drv = bss->drv;
650         struct nl_msg *msg;
651  
652         msg = nlmsg_alloc();
653 @@ -3982,7 +3971,7 @@ static int i802_flush(void *priv)
654          * XXX: FIX! this needs to flush all VLANs too
655          */
656         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
657 -                   if_nametoindex(drv->ifname));
658 +                   if_nametoindex(bss->ifname));
659  
660         return send_and_recv_msgs(drv, msg, NULL, NULL);
661   nla_put_failure:
662 @@ -4044,7 +4033,8 @@ static int get_sta_handler(struct nl_msg
663  static int i802_read_sta_data(void *priv, struct hostap_sta_driver_data *data,
664                               const u8 *addr)
665  {
666 -       struct wpa_driver_nl80211_data *drv = priv;
667 +       struct i802_bss *bss = priv;
668 +       struct wpa_driver_nl80211_data *drv = bss->drv;
669         struct nl_msg *msg;
670  
671         os_memset(data, 0, sizeof(*data));
672 @@ -4056,7 +4046,7 @@ static int i802_read_sta_data(void *priv
673                     0, NL80211_CMD_GET_STATION, 0);
674  
675         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
676 -       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname));
677 +       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
678  
679         return send_and_recv_msgs(drv, msg, get_sta_handler, data);
680   nla_put_failure:
681 @@ -4067,7 +4057,8 @@ static int i802_read_sta_data(void *priv
682  static int i802_set_tx_queue_params(void *priv, int queue, int aifs,
683                                     int cw_min, int cw_max, int burst_time)
684  {
685 -       struct wpa_driver_nl80211_data *drv = priv;
686 +       struct i802_bss *bss = priv;
687 +       struct wpa_driver_nl80211_data *drv = bss->drv;
688         struct nl_msg *msg;
689         struct nlattr *txq, *params;
690  
691 @@ -4078,7 +4069,7 @@ static int i802_set_tx_queue_params(void
692         genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
693                     0, NL80211_CMD_SET_WIPHY, 0);
694  
695 -       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname));
696 +       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
697  
698         txq = nla_nest_start(msg, NL80211_ATTR_WIPHY_TXQ_PARAMS);
699         if (!txq)
700 @@ -4110,7 +4101,8 @@ static int i802_set_tx_queue_params(void
701  
702  static int i802_set_bss(void *priv, int cts, int preamble, int slot)
703  {
704 -       struct wpa_driver_nl80211_data *drv = priv;
705 +       struct i802_bss *bss = priv;
706 +       struct wpa_driver_nl80211_data *drv = bss->drv;
707         struct nl_msg *msg;
708  
709         msg = nlmsg_alloc();
710 @@ -4128,7 +4120,7 @@ static int i802_set_bss(void *priv, int 
711                 NLA_PUT_U8(msg, NL80211_ATTR_BSS_SHORT_SLOT_TIME, slot);
712  
713         /* TODO: multi-BSS support */
714 -       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(drv->ifname));
715 +       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(bss->ifname));
716  
717         return send_and_recv_msgs(drv, msg, NULL, NULL);
718   nla_put_failure:
719 @@ -4157,7 +4149,8 @@ static int i802_set_short_slot_time(void
720  static int i802_set_sta_vlan(void *priv, const u8 *addr,
721                              const char *ifname, int vlan_id)
722  {
723 -       struct wpa_driver_nl80211_data *drv = priv;
724 +       struct i802_bss *bss = priv;
725 +       struct wpa_driver_nl80211_data *drv = bss->drv;
726         struct nl_msg *msg;
727  
728         msg = nlmsg_alloc();
729 @@ -4168,7 +4161,7 @@ static int i802_set_sta_vlan(void *priv,
730                     0, NL80211_CMD_SET_STATION, 0);
731  
732         NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX,
733 -                   if_nametoindex(drv->ifname));
734 +                   if_nametoindex(bss->ifname));
735         NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
736         NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN,
737                     if_nametoindex(ifname));
738 @@ -4181,18 +4174,19 @@ static int i802_set_sta_vlan(void *priv,
739  
740  static int i802_set_wds_sta(void *priv, const u8 *addr, int aid, int val)
741  {
742 -       struct wpa_driver_nl80211_data *drv = priv;
743 +       struct i802_bss *bss = priv;
744 +       struct wpa_driver_nl80211_data *drv = bss->drv;
745         char name[16];
746  
747 -       os_snprintf(name, sizeof(name), "%s.sta%d", drv->ifname, aid);
748 +       os_snprintf(name, sizeof(name), "%s.sta%d", bss->ifname, aid);
749         if (val) {
750 -               if (nl80211_create_iface(priv, name, NL80211_IFTYPE_AP_VLAN,
751 +               if (nl80211_create_iface(drv, name, NL80211_IFTYPE_AP_VLAN,
752                                          NULL, 1) < 0)
753                         return -1;
754                 linux_set_iface_flags(drv->ioctl_sock, name, 1);
755                 return i802_set_sta_vlan(priv, addr, name, 0);
756         } else {
757 -               i802_set_sta_vlan(priv, addr, drv->ifname, 0);
758 +               i802_set_sta_vlan(priv, addr, bss->ifname, 0);
759                 return wpa_driver_nl80211_if_remove(priv, WPA_IF_AP_VLAN,
760                                                     name);
761         }
762 @@ -4244,7 +4238,8 @@ static int i802_sta_clear_stats(void *pr
763  static int i802_sta_deauth(void *priv, const u8 *own_addr, const u8 *addr,
764                            int reason)
765  {
766 -       struct wpa_driver_nl80211_data *drv = priv;
767 +       struct i802_bss *bss = priv;
768 +       struct wpa_driver_nl80211_data *drv = bss->drv;
769         struct ieee80211_mgmt mgmt;
770  
771         memset(&mgmt, 0, sizeof(mgmt));
772 @@ -4254,7 +4249,7 @@ static int i802_sta_deauth(void *priv, c
773         memcpy(mgmt.sa, own_addr, ETH_ALEN);
774         memcpy(mgmt.bssid, own_addr, ETH_ALEN);
775         mgmt.u.deauth.reason_code = host_to_le16(reason);
776 -       return wpa_driver_nl80211_send_mlme(drv, (u8 *) &mgmt,
777 +       return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
778                                             IEEE80211_HDRLEN +
779                                             sizeof(mgmt.u.deauth));
780  }
781 @@ -4263,7 +4258,8 @@ static int i802_sta_deauth(void *priv, c
782  static int i802_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
783                              int reason)
784  {
785 -       struct wpa_driver_nl80211_data *drv = priv;
786 +       struct i802_bss *bss = priv;
787 +       struct wpa_driver_nl80211_data *drv = bss->drv;
788         struct ieee80211_mgmt mgmt;
789  
790         memset(&mgmt, 0, sizeof(mgmt));
791 @@ -4273,7 +4269,7 @@ static int i802_sta_disassoc(void *priv,
792         memcpy(mgmt.sa, own_addr, ETH_ALEN);
793         memcpy(mgmt.bssid, own_addr, ETH_ALEN);
794         mgmt.u.disassoc.reason_code = host_to_le16(reason);
795 -       return wpa_driver_nl80211_send_mlme(drv, (u8 *) &mgmt,
796 +       return wpa_driver_nl80211_send_mlme(bss, (u8 *) &mgmt,
797                                             IEEE80211_HDRLEN +
798                                             sizeof(mgmt.u.disassoc));
799  }
800 @@ -4335,17 +4331,17 @@ static void *i802_init(struct hostapd_da
801                        struct wpa_init_params *params)
802  {
803         struct wpa_driver_nl80211_data *drv;
804 +       struct i802_bss *bss;
805         size_t i;
806         char brname[IFNAMSIZ];
807         int ifindex, br_ifindex;
808         int br_added = 0;
809  
810 -       drv = wpa_driver_nl80211_init(hapd, params->ifname);
811 -       if (drv == NULL)
812 +       bss = wpa_driver_nl80211_init(hapd, params->ifname);
813 +       if (bss == NULL)
814                 return NULL;
815  
816 -       drv->bss.ifindex = drv->ifindex;
817 -
818 +       drv = bss->drv;
819         if (linux_br_get(brname, params->ifname) == 0) {
820                 wpa_printf(MSG_DEBUG, "nl80211: Interface %s is in bridge %s",
821                            params->ifname, brname);
822 @@ -4373,18 +4369,18 @@ static void *i802_init(struct hostapd_da
823         /* start listening for EAPOL on the default AP interface */
824         add_ifidx(drv, drv->ifindex);
825  
826 -       if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0))
827 +       if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 0))
828                 goto failed;
829  
830         if (params->bssid) {
831 -               if (linux_set_ifhwaddr(drv->ioctl_sock, drv->ifname,
832 +               if (linux_set_ifhwaddr(drv->ioctl_sock, bss->ifname,
833                                        params->bssid))
834                         goto failed;
835         }
836  
837 -       if (wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_AP)) {
838 +       if (wpa_driver_nl80211_set_mode(bss, IEEE80211_MODE_AP)) {
839                 wpa_printf(MSG_ERROR, "nl80211: Failed to set interface %s "
840 -                          "into AP mode", drv->ifname);
841 +                          "into AP mode", bss->ifname);
842                 goto failed;
843         }
844  
845 @@ -4392,7 +4388,7 @@ static void *i802_init(struct hostapd_da
846             i802_check_bridge(drv, params->bridge[0], params->ifname) < 0)
847                 goto failed;
848  
849 -       if (linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1))
850 +       if (linux_set_iface_flags(drv->ioctl_sock, bss->ifname, 1))
851                 goto failed;
852  
853         drv->eapol_sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_PAE));
854 @@ -4407,10 +4403,10 @@ static void *i802_init(struct hostapd_da
855                 goto failed;
856         }
857  
858 -       if (linux_get_ifhwaddr(drv->ioctl_sock, drv->ifname, params->own_addr))
859 +       if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, params->own_addr))
860                 goto failed;
861  
862 -       return drv;
863 +       return bss;
864  
865  failed:
866         nl80211_remove_monitor_interface(drv);
867 @@ -4453,27 +4449,30 @@ static enum nl80211_iftype wpa_driver_nl
868  static int wpa_driver_nl80211_if_add(const char *iface, void *priv,
869                                      enum wpa_driver_if_type type,
870                                      const char *ifname, const u8 *addr,
871 -                                    void *bss_ctx)
872 +                                    void *bss_ctx, void **drv_priv)
873  {
874 -       struct wpa_driver_nl80211_data *drv = priv;
875 +       struct i802_bss *bss = priv;
876 +       struct wpa_driver_nl80211_data *drv = bss->drv;
877         int ifidx;
878  #ifdef HOSTAPD
879 -       struct i802_bss *bss = NULL;
880 +       struct i802_bss *new_bss = NULL;
881  
882         if (type == WPA_IF_AP_BSS) {
883 -               bss = os_zalloc(sizeof(*bss));
884 -               if (bss == NULL)
885 +               new_bss = os_zalloc(sizeof(*new_bss));
886 +               if (new_bss == NULL)
887                         return -1;
888         }
889 -#endif /* HOSTAPD */
890 +#endif
891  
892         ifidx = nl80211_create_iface(drv, ifname,
893                                      wpa_driver_nl80211_if_type(type), addr,
894                                      0);
895 +
896         if (ifidx < 0) {
897  #ifdef HOSTAPD
898 -               os_free(bss);
899 -#endif /* HOSTAPD */
900 +               if (type == WPA_IF_AP_BSS)
901 +                       os_free(new_bss);
902 +#endif
903                 return -1;
904         }
905  
906 @@ -4481,12 +4480,15 @@ static int wpa_driver_nl80211_if_add(con
907         if (type == WPA_IF_AP_BSS) {
908                 if (linux_set_iface_flags(drv->ioctl_sock, ifname, 1)) {
909                         nl80211_remove_iface(drv, ifidx);
910 -                       os_free(bss);
911 +                       os_free(new_bss);
912                         return -1;
913                 }
914 -               bss->ifindex = ifidx;
915 -               bss->next = drv->bss.next;
916 -               drv->bss.next = bss;
917 +               strncpy(new_bss->ifname, ifname, IFNAMSIZ);
918 +               new_bss->ifindex = ifidx;
919 +               new_bss->drv = drv;
920 +               new_bss->next = drv->first_bss.next;
921 +               drv->first_bss.next = new_bss;
922 +               *drv_priv = new_bss;
923         }
924  #endif /* HOSTAPD */
925  
926 @@ -4498,27 +4500,27 @@ static int wpa_driver_nl80211_if_remove(
927                                         enum wpa_driver_if_type type,
928                                         const char *ifname)
929  {
930 -       struct wpa_driver_nl80211_data *drv = priv;
931 +       struct i802_bss *bss = priv;
932 +       struct wpa_driver_nl80211_data *drv = bss->drv;
933         int ifindex = if_nametoindex(ifname);
934  
935         nl80211_remove_iface(drv, ifindex);
936  
937 -#ifdef HOSTAPD
938 -       if (type == WPA_IF_AP_BSS) {
939 -               struct i802_bss *bss, *prev;
940 -               prev = &drv->bss;
941 -               bss = drv->bss.next;
942 -               while (bss) {
943 -                       if (ifindex == bss->ifindex) {
944 -                               prev->next = bss->next;
945 -                               os_free(bss);
946 -                               break;
947 -                       }
948 -                       prev = bss;
949 -                       bss = bss->next;
950 +       if (type != WPA_IF_AP_BSS)
951 +               return 0;
952 +
953 +       if (bss != &drv->first_bss) {
954 +               struct i802_bss *tbss = &drv->first_bss;
955 +
956 +               while (tbss) {
957 +                       if (tbss->next != bss)
958 +                               continue;
959 +
960 +                       tbss->next = bss->next;
961 +                       os_free(bss);
962 +                       break;
963                 }
964         }
965 -#endif /* HOSTAPD */
966  
967         return 0;
968  }
969 @@ -4540,7 +4542,8 @@ static int cookie_handler(struct nl_msg 
970  static int wpa_driver_nl80211_remain_on_channel(void *priv, unsigned int freq,
971                                                 unsigned int duration)
972  {
973 -       struct wpa_driver_nl80211_data *drv = priv;
974 +       struct i802_bss *bss = priv;
975 +       struct wpa_driver_nl80211_data *drv = bss->drv;
976         struct nl_msg *msg;
977         int ret;
978         u64 cookie;
979 @@ -4574,7 +4577,8 @@ nla_put_failure:
980  
981  static int wpa_driver_nl80211_cancel_remain_on_channel(void *priv)
982  {
983 -       struct wpa_driver_nl80211_data *drv = priv;
984 +       struct i802_bss *bss = priv;
985 +       struct wpa_driver_nl80211_data *drv = bss->drv;
986         struct nl_msg *msg;
987         int ret;
988  
989 @@ -4629,7 +4633,8 @@ static void wpa_driver_nl80211_probe_req
990  
991  static int wpa_driver_nl80211_probe_req_report(void *priv, int report)
992  {
993 -       struct wpa_driver_nl80211_data *drv = priv;
994 +       struct i802_bss *bss = priv;
995 +       struct wpa_driver_nl80211_data *drv = bss->drv;
996  
997         if (drv->nlmode != NL80211_IFTYPE_STATION) {
998                 wpa_printf(MSG_DEBUG, "nl80211: probe_req_report control only "
999 @@ -4666,9 +4671,10 @@ static int wpa_driver_nl80211_probe_req_
1000  
1001  static int wpa_driver_nl80211_alloc_interface_addr(void *priv, u8 *addr)
1002  {
1003 -       struct wpa_driver_nl80211_data *drv = priv;
1004 +       struct i802_bss *bss = priv;
1005 +       struct wpa_driver_nl80211_data *drv = bss->drv;
1006  
1007 -       if (linux_get_ifhwaddr(drv->ioctl_sock, drv->ifname, addr) < 0)
1008 +       if (linux_get_ifhwaddr(drv->ioctl_sock, bss->ifname, addr) < 0)
1009                 return -1;
1010  
1011         if (addr[0] & 0x02) {
1012 @@ -4738,7 +4744,8 @@ nla_put_failure:
1013  
1014  static int wpa_driver_nl80211_disable_11b_rates(void *priv, int disabled)
1015  {
1016 -       struct wpa_driver_nl80211_data *drv = priv;
1017 +       struct i802_bss *bss = priv;
1018 +       struct wpa_driver_nl80211_data *drv = bss->drv;
1019         drv->disable_11b_rates = disabled;
1020         return nl80211_disable_11b_rates(drv, drv->ifindex, disabled);
1021  }
1022 @@ -4746,11 +4753,12 @@ static int wpa_driver_nl80211_disable_11
1023  
1024  static int wpa_driver_nl80211_deinit_ap(void *priv)
1025  {
1026 -       struct wpa_driver_nl80211_data *drv = priv;
1027 +       struct i802_bss *bss = priv;
1028 +       struct wpa_driver_nl80211_data *drv = bss->drv;
1029         if (drv->nlmode != NL80211_IFTYPE_AP)
1030                 return -1;
1031         wpa_driver_nl80211_del_beacon(drv);
1032 -       return wpa_driver_nl80211_set_mode(drv, IEEE80211_MODE_INFRA);
1033 +       return wpa_driver_nl80211_set_mode(priv, IEEE80211_MODE_INFRA);
1034  }
1035  
1036  
1037 --- a/src/drivers/driver.h
1038 +++ b/src/drivers/driver.h
1039 @@ -1472,11 +1472,12 @@ struct wpa_driver_ops {
1040          * @addr: Local address to use for the interface or %NULL to use the
1041          *      parent interface address
1042          * @bss_ctx: BSS context for %WPA_IF_AP_BSS interfaces
1043 +        * @drv_priv: Pointer for overwriting the driver context
1044          * Returns: 0 on success, -1 on failure
1045          */
1046         int (*if_add)(const char *iface, void *priv,
1047                       enum wpa_driver_if_type type, const char *ifname,
1048 -                     const u8 *addr, void *bss_ctx);
1049 +                     const u8 *addr, void *bss_ctx, void **drv_priv);
1050  
1051         /**
1052          * if_remove - Remove a virtual interface
1053 --- a/src/drivers/driver_test.c
1054 +++ b/src/drivers/driver_test.c
1055 @@ -1030,7 +1030,7 @@ static int test_driver_bss_remove(void *
1056  
1057  static int test_driver_if_add(const char *iface, void *priv,
1058                               enum wpa_driver_if_type type, const char *ifname,
1059 -                             const u8 *addr, void *bss_ctx)
1060 +                             const u8 *addr, void *bss_ctx, void **drv_priv)
1061  {
1062         wpa_printf(MSG_DEBUG, "%s(iface=%s type=%d ifname=%s bss_ctx=%p)",
1063                    __func__, iface, type, ifname, bss_ctx);
1064 --- a/src/ap/ap_drv_ops.c
1065 +++ b/src/ap/ap_drv_ops.c
1066 @@ -242,7 +242,8 @@ static int hostapd_set_beacon(const char
1067  
1068  static int hostapd_vlan_if_add(struct hostapd_data *hapd, const char *ifname)
1069  {
1070 -       return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, NULL, NULL);
1071 +       return hostapd_if_add(hapd, WPA_IF_AP_VLAN, ifname, NULL, NULL,
1072 +                             &hapd->drv_priv);
1073  }
1074  
1075  static int hostapd_vlan_if_remove(struct hostapd_data *hapd,
1076 @@ -407,12 +408,13 @@ int hostapd_set_ssid(struct hostapd_data
1077  
1078  
1079  int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
1080 -                  const char *ifname, const u8 *addr, void *bss_ctx)
1081 +                  const char *ifname, const u8 *addr, void *bss_ctx,
1082 +                  void **drv_priv)
1083  {
1084         if (hapd->driver == NULL || hapd->driver->if_add == NULL)
1085                 return -1;
1086         return hapd->driver->if_add(hapd->conf->iface, hapd->drv_priv, type,
1087 -                                   ifname, addr, bss_ctx);
1088 +                                   ifname, addr, bss_ctx, drv_priv);
1089  }
1090  
1091  
1092 --- a/src/ap/ap_drv_ops.h
1093 +++ b/src/ap/ap_drv_ops.h
1094 @@ -26,7 +26,8 @@ int hostapd_set_generic_elem(struct host
1095  int hostapd_get_ssid(struct hostapd_data *hapd, u8 *buf, size_t len);
1096  int hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len);
1097  int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
1098 -                  const char *ifname, const u8 *addr, void *bss_ctx);
1099 +                  const char *ifname, const u8 *addr, void *bss_ctx,
1100 +                  void **drv_priv);
1101  int hostapd_if_remove(struct hostapd_data *hapd, enum wpa_driver_if_type type,
1102                       const char *ifname);
1103  int hostapd_set_ieee8021x(struct hostapd_data *hapd,
1104 --- a/src/ap/hostapd.c
1105 +++ b/src/ap/hostapd.c
1106 @@ -484,7 +484,8 @@ static int hostapd_setup_bss(struct host
1107  
1108                 hapd->interface_added = 1;
1109                 if (hostapd_if_add(hapd->iface->bss[0], WPA_IF_AP_BSS,
1110 -                                  hapd->conf->iface, hapd->own_addr, hapd)) {
1111 +                                  hapd->conf->iface, hapd->own_addr, hapd,
1112 +                                  &hapd->drv_priv)) {
1113                         wpa_printf(MSG_ERROR, "Failed to add BSS (BSSID="
1114                                    MACSTR ")", MAC2STR(hapd->own_addr));
1115                         return -1;