e459721b89a47c2083a2fe0bfeef7ab5b8a54e86
[openwrt/openwrt.git] / package / network / services / hostapd / patches / 601-ucode_support.patch
1 --- a/hostapd/Makefile
2 +++ b/hostapd/Makefile
3 @@ -168,9 +168,21 @@ OBJS += ../src/eapol_auth/eapol_auth_sm.
4
5 ifdef CONFIG_UBUS
6 CFLAGS += -DUBUS_SUPPORT
7 -OBJS += ../src/utils/uloop.o
8 OBJS += ../src/ap/ubus.o
9 -LIBS += -lubox -lubus
10 +LIBS += -lubus
11 +NEED_ULOOP:=y
12 +endif
13 +
14 +ifdef CONFIG_UCODE
15 +CFLAGS += -DUCODE_SUPPORT
16 +OBJS += ../src/utils/ucode.o
17 +OBJS += ../src/ap/ucode.o
18 +NEED_ULOOP:=y
19 +endif
20 +
21 +ifdef NEED_ULOOP
22 +OBJS += ../src/utils/uloop.o
23 +LIBS += -lubox
24 endif
25
26 ifdef CONFIG_CODE_COVERAGE
27 --- a/hostapd/main.c
28 +++ b/hostapd/main.c
29 @@ -1014,6 +1014,7 @@ int main(int argc, char *argv[])
30 }
31
32 hostapd_global_ctrl_iface_init(&interfaces);
33 + hostapd_ucode_init(&interfaces);
34
35 if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
36 wpa_printf(MSG_ERROR, "Failed to start eloop");
37 @@ -1023,6 +1024,7 @@ int main(int argc, char *argv[])
38 ret = 0;
39
40 out:
41 + hostapd_ucode_free();
42 hostapd_global_ctrl_iface_deinit(&interfaces);
43 /* Deinitialize all interfaces */
44 for (i = 0; i < interfaces.count; i++) {
45 --- a/src/ap/hostapd.h
46 +++ b/src/ap/hostapd.h
47 @@ -19,6 +19,7 @@
48 #include "ap_config.h"
49 #include "drivers/driver.h"
50 #include "ubus.h"
51 +#include "ucode.h"
52
53 #define OCE_STA_CFON_ENABLED(hapd) \
54 ((hapd->conf->oce & OCE_STA_CFON) && \
55 @@ -51,6 +52,10 @@ struct hapd_interfaces {
56 struct hostapd_config * (*config_read_cb)(const char *config_fname);
57 int (*ctrl_iface_init)(struct hostapd_data *hapd);
58 void (*ctrl_iface_deinit)(struct hostapd_data *hapd);
59 + int (*ctrl_iface_recv)(struct hostapd_data *hapd,
60 + char *buf, char *reply, int reply_size,
61 + struct sockaddr_storage *from,
62 + socklen_t fromlen);
63 int (*for_each_interface)(struct hapd_interfaces *interfaces,
64 int (*cb)(struct hostapd_iface *iface,
65 void *ctx), void *ctx);
66 @@ -186,6 +191,7 @@ struct hostapd_data {
67 struct hostapd_config *iconf;
68 struct hostapd_bss_config *conf;
69 struct hostapd_ubus_bss ubus;
70 + struct hostapd_ucode_bss ucode;
71 int interface_added; /* virtual interface added for this BSS */
72 unsigned int started:1;
73 unsigned int disabled:1;
74 @@ -518,6 +524,7 @@ struct hostapd_sta_info {
75 */
76 struct hostapd_iface {
77 struct hapd_interfaces *interfaces;
78 + struct hostapd_ucode_iface ucode;
79 void *owner;
80 char *config_fname;
81 struct hostapd_config *conf;
82 @@ -718,6 +725,8 @@ struct hostapd_iface * hostapd_init(stru
83 struct hostapd_iface *
84 hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
85 const char *config_fname, int debug);
86 +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon);
87 +void hostapd_bss_deinit(struct hostapd_data *hapd);
88 void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
89 int reassoc);
90 void hostapd_interface_deinit_free(struct hostapd_iface *iface);
91 --- a/src/ap/hostapd.c
92 +++ b/src/ap/hostapd.c
93 @@ -255,6 +255,8 @@ int hostapd_reload_config(struct hostapd
94 struct hostapd_config *newconf, *oldconf;
95 size_t j;
96
97 + hostapd_ucode_reload_bss(hapd);
98 +
99 if (iface->config_fname == NULL) {
100 /* Only in-memory config in use - assume it has been updated */
101 hostapd_clear_old(iface);
102 @@ -493,6 +495,7 @@ void hostapd_free_hapd_data(struct hosta
103 hapd->beacon_set_done = 0;
104
105 wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
106 + hostapd_ucode_free_bss(hapd);
107 hostapd_ubus_free_bss(hapd);
108 accounting_deinit(hapd);
109 hostapd_deinit_wpa(hapd);
110 @@ -687,6 +690,7 @@ void hostapd_cleanup_iface_partial(struc
111 static void hostapd_cleanup_iface(struct hostapd_iface *iface)
112 {
113 wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
114 + hostapd_ucode_free_iface(iface);
115 eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
116 NULL);
117
118 @@ -1276,6 +1280,7 @@ static int hostapd_start_beacon(struct h
119 hapd->driver->set_operstate(hapd->drv_priv, 1);
120
121 hostapd_ubus_add_bss(hapd);
122 + hostapd_ucode_add_bss(hapd);
123
124 return 0;
125 }
126 @@ -1298,8 +1303,7 @@ static int hostapd_start_beacon(struct h
127 * initialized. Most of the modules that are initialized here will be
128 * deinitialized in hostapd_cleanup().
129 */
130 -static int hostapd_setup_bss(struct hostapd_data *hapd, int first,
131 - bool start_beacon)
132 +int hostapd_setup_bss(struct hostapd_data *hapd, int first, bool start_beacon)
133 {
134 struct hostapd_bss_config *conf = hapd->conf;
135 u8 ssid[SSID_MAX_LEN + 1];
136 @@ -2790,7 +2794,7 @@ hostapd_alloc_bss_data(struct hostapd_if
137 }
138
139
140 -static void hostapd_bss_deinit(struct hostapd_data *hapd)
141 +void hostapd_bss_deinit(struct hostapd_data *hapd)
142 {
143 if (!hapd)
144 return;
145 @@ -3608,7 +3612,8 @@ int hostapd_remove_iface(struct hapd_int
146 hapd_iface = interfaces->iface[i];
147 if (hapd_iface == NULL)
148 return -1;
149 - if (!os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
150 + if (!os_strcmp(hapd_iface->phy, buf) ||
151 + !os_strcmp(hapd_iface->conf->bss[0]->iface, buf)) {
152 wpa_printf(MSG_INFO, "Remove interface '%s'", buf);
153 hapd_iface->driver_ap_teardown =
154 !!(hapd_iface->drv_flags &
155 --- a/wpa_supplicant/Makefile
156 +++ b/wpa_supplicant/Makefile
157 @@ -192,8 +192,20 @@ endif
158 ifdef CONFIG_UBUS
159 CFLAGS += -DUBUS_SUPPORT
160 OBJS += ubus.o
161 +LIBS += -lubus
162 +NEED_ULOOP:=y
163 +endif
164 +
165 +ifdef CONFIG_UCODE
166 +CFLAGS += -DUCODE_SUPPORT
167 +OBJS += ../src/utils/ucode.o
168 +OBJS += ucode.o
169 +NEED_ULOOP:=y
170 +endif
171 +
172 +ifdef NEED_ULOOP
173 OBJS += ../src/utils/uloop.o
174 -LIBS += -lubox -lubus
175 +LIBS += -lubox
176 endif
177
178 ifdef CONFIG_CODE_COVERAGE
179 @@ -1053,6 +1065,9 @@ OBJS += ../src/ap/ctrl_iface_ap.o
180 ifdef CONFIG_UBUS
181 OBJS += ../src/ap/ubus.o
182 endif
183 +ifdef CONFIG_UCODE
184 +OBJS += ../src/ap/ucode.o
185 +endif
186 endif
187
188 CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
189 --- a/wpa_supplicant/wpa_supplicant.c
190 +++ b/wpa_supplicant/wpa_supplicant.c
191 @@ -1060,6 +1060,7 @@ void wpa_supplicant_set_state(struct wpa
192 sme_sched_obss_scan(wpa_s, 0);
193 }
194 wpa_s->wpa_state = state;
195 + wpas_ucode_update_state(wpa_s);
196
197 #ifdef CONFIG_BGSCAN
198 if (state == WPA_COMPLETED && wpa_s->current_ssid != wpa_s->bgscan_ssid)
199 @@ -7717,6 +7718,7 @@ struct wpa_supplicant * wpa_supplicant_a
200 #endif /* CONFIG_P2P */
201
202 wpas_ubus_add_bss(wpa_s);
203 + wpas_ucode_add_bss(wpa_s);
204
205 return wpa_s;
206 }
207 @@ -7744,6 +7746,7 @@ int wpa_supplicant_remove_iface(struct w
208 struct wpa_supplicant *parent = wpa_s->parent;
209 #endif /* CONFIG_MESH */
210
211 + wpas_ucode_free_bss(wpa_s);
212 wpas_ubus_free_bss(wpa_s);
213
214 /* Remove interface from the global list of interfaces */
215 @@ -8054,6 +8057,7 @@ struct wpa_global * wpa_supplicant_init(
216
217 eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
218 wpas_periodic, global, NULL);
219 + wpas_ucode_init(global);
220
221 return global;
222 }
223 @@ -8092,12 +8096,8 @@ int wpa_supplicant_run(struct wpa_global
224 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
225 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
226
227 - wpas_ubus_add(global);
228 -
229 eloop_run();
230
231 - wpas_ubus_free(global);
232 -
233 return 0;
234 }
235
236 @@ -8130,6 +8130,8 @@ void wpa_supplicant_deinit(struct wpa_gl
237
238 wpas_notify_supplicant_deinitialized(global);
239
240 + wpas_ucode_free();
241 +
242 eap_peer_unregister_methods();
243 #ifdef CONFIG_AP
244 eap_server_unregister_methods();
245 --- a/wpa_supplicant/wpa_supplicant_i.h
246 +++ b/wpa_supplicant/wpa_supplicant_i.h
247 @@ -22,6 +22,7 @@
248 #include "wmm_ac.h"
249 #include "pasn/pasn_common.h"
250 #include "ubus.h"
251 +#include "ucode.h"
252
253 extern const char *const wpa_supplicant_version;
254 extern const char *const wpa_supplicant_license;
255 @@ -697,6 +698,7 @@ struct wpa_supplicant {
256 unsigned char perm_addr[ETH_ALEN];
257 char ifname[100];
258 struct wpas_ubus_bss ubus;
259 + struct wpas_ucode_bss ucode;
260 #ifdef CONFIG_MATCH_IFACE
261 int matched;
262 #endif /* CONFIG_MATCH_IFACE */
263 --- a/hostapd/ctrl_iface.c
264 +++ b/hostapd/ctrl_iface.c
265 @@ -5487,6 +5487,7 @@ try_again:
266 return -1;
267 }
268
269 + interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process;
270 wpa_msg_register_cb(hostapd_ctrl_iface_msg_cb);
271
272 return 0;
273 @@ -5588,6 +5589,7 @@ fail:
274 os_free(fname);
275
276 interface->global_ctrl_sock = s;
277 + interface->ctrl_iface_recv = hostapd_ctrl_iface_receive_process;
278 eloop_register_read_sock(s, hostapd_global_ctrl_iface_receive,
279 interface, NULL);
280
281 --- a/src/drivers/driver.h
282 +++ b/src/drivers/driver.h
283 @@ -3853,6 +3853,25 @@ struct wpa_driver_ops {
284 const char *ifname);
285
286 /**
287 + * if_rename - Rename a virtual interface
288 + * @priv: Private driver interface data
289 + * @type: Interface type
290 + * @ifname: Interface name of the virtual interface to be renamed
291 + * (NULL when renaming the AP BSS interface)
292 + * @new_name: New interface name of the virtual interface
293 + * Returns: 0 on success, -1 on failure
294 + */
295 + int (*if_rename)(void *priv, enum wpa_driver_if_type type,
296 + const char *ifname, const char *new_name);
297 +
298 + /**
299 + * set_first_bss - Make a virtual interface the first (primary) bss
300 + * @priv: Private driver interface data
301 + * Returns: 0 on success, -1 on failure
302 + */
303 + int (*set_first_bss)(void *priv);
304 +
305 + /**
306 * set_sta_vlan - Bind a station into a specific interface (AP only)
307 * @priv: Private driver interface data
308 * @ifname: Interface (main or virtual BSS or VLAN)
309 @@ -6507,6 +6526,7 @@ union wpa_event_data {
310
311 /**
312 * struct ch_switch
313 + * @count: Count until channel switch activates
314 * @freq: Frequency of new channel in MHz
315 * @ht_enabled: Whether this is an HT channel
316 * @ch_offset: Secondary channel offset
317 @@ -6517,6 +6537,7 @@ union wpa_event_data {
318 * @punct_bitmap: Puncturing bitmap
319 */
320 struct ch_switch {
321 + int count;
322 int freq;
323 int ht_enabled;
324 int ch_offset;
325 --- a/src/drivers/driver_nl80211_event.c
326 +++ b/src/drivers/driver_nl80211_event.c
327 @@ -1196,6 +1196,7 @@ static void mlme_event_ch_switch(struct
328 struct nlattr *bw, struct nlattr *cf1,
329 struct nlattr *cf2,
330 struct nlattr *punct_bitmap,
331 + struct nlattr *count,
332 int finished)
333 {
334 struct i802_bss *bss;
335 @@ -1259,6 +1260,8 @@ static void mlme_event_ch_switch(struct
336 data.ch_switch.cf1 = nla_get_u32(cf1);
337 if (cf2)
338 data.ch_switch.cf2 = nla_get_u32(cf2);
339 + if (count)
340 + data.ch_switch.count = nla_get_u32(count);
341
342 if (finished)
343 bss->flink->freq = data.ch_switch.freq;
344 @@ -3961,6 +3964,7 @@ static void do_process_drv_event(struct
345 tb[NL80211_ATTR_CENTER_FREQ1],
346 tb[NL80211_ATTR_CENTER_FREQ2],
347 tb[NL80211_ATTR_PUNCT_BITMAP],
348 + tb[NL80211_ATTR_CH_SWITCH_COUNT],
349 0);
350 break;
351 case NL80211_CMD_CH_SWITCH_NOTIFY:
352 @@ -3973,6 +3977,7 @@ static void do_process_drv_event(struct
353 tb[NL80211_ATTR_CENTER_FREQ1],
354 tb[NL80211_ATTR_CENTER_FREQ2],
355 tb[NL80211_ATTR_PUNCT_BITMAP],
356 + NULL,
357 1);
358 break;
359 case NL80211_CMD_DISCONNECT:
360 --- a/wpa_supplicant/events.c
361 +++ b/wpa_supplicant/events.c
362 @@ -5955,6 +5955,7 @@ void supplicant_event(void *ctx, enum wp
363 event_to_string(event), event);
364 #endif /* CONFIG_NO_STDOUT_DEBUG */
365
366 + wpas_ucode_event(wpa_s, event, data);
367 switch (event) {
368 case EVENT_AUTH:
369 #ifdef CONFIG_FST
370 --- a/src/ap/ap_drv_ops.h
371 +++ b/src/ap/ap_drv_ops.h
372 @@ -399,6 +399,23 @@ static inline int hostapd_drv_stop_ap(st
373 return hapd->driver->stop_ap(hapd->drv_priv, link_id);
374 }
375
376 +static inline int hostapd_drv_if_rename(struct hostapd_data *hapd,
377 + enum wpa_driver_if_type type,
378 + const char *ifname,
379 + const char *new_name)
380 +{
381 + if (!hapd->driver || !hapd->driver->if_rename || !hapd->drv_priv)
382 + return -1;
383 + return hapd->driver->if_rename(hapd->drv_priv, type, ifname, new_name);
384 +}
385 +
386 +static inline int hostapd_drv_set_first_bss(struct hostapd_data *hapd)
387 +{
388 + if (!hapd->driver || !hapd->driver->set_first_bss || !hapd->drv_priv)
389 + return 0;
390 + return hapd->driver->set_first_bss(hapd->drv_priv);
391 +}
392 +
393 static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,
394 struct wpa_channel_info *ci)
395 {
396 --- a/src/drivers/driver_nl80211.c
397 +++ b/src/drivers/driver_nl80211.c
398 @@ -75,6 +75,16 @@ enum nlmsgerr_attrs {
399
400 #endif /* ANDROID */
401
402 +static void handle_nl_debug_hook(struct nl_msg *msg, int tx)
403 +{
404 + const struct nlmsghdr *nlh;
405 +
406 + if (!wpa_netlink_hook)
407 + return;
408 +
409 + nlh = nlmsg_hdr(msg);
410 + wpa_netlink_hook(tx, nlh, nlh->nlmsg_len);
411 +}
412
413 static struct nl_sock * nl_create_handle(struct nl_cb *cb, const char *dbg)
414 {
415 @@ -429,6 +439,11 @@ static int no_seq_check(struct nl_msg *m
416 return NL_OK;
417 }
418
419 +static int debug_handler(struct nl_msg *msg, void *arg)
420 +{
421 + handle_nl_debug_hook(msg, 0);
422 + return NL_OK;
423 +}
424
425 static void nl80211_nlmsg_clear(struct nl_msg *msg)
426 {
427 @@ -502,6 +517,8 @@ int send_and_recv(struct nl80211_global
428 if (!msg)
429 return -ENOMEM;
430
431 + handle_nl_debug_hook(msg, 1);
432 +
433 err.err = -ENOMEM;
434
435 s_nl_cb = nl_socket_get_cb(nl_handle);
436 @@ -536,6 +553,7 @@ int send_and_recv(struct nl80211_global
437 err.orig_msg = msg;
438 err.err_info = err_info;
439
440 + nl_cb_set(cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
441 nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
442 nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err.err);
443 if (ack_handler_custom) {
444 @@ -939,6 +957,7 @@ nl80211_get_wiphy_data_ap(struct i802_bs
445 os_free(w);
446 return NULL;
447 }
448 + nl_cb_set(w->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
449 nl_cb_set(w->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
450 no_seq_check, NULL);
451 nl_cb_set(w->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
452 @@ -1353,7 +1372,7 @@ static void wpa_driver_nl80211_event_rtm
453 }
454 wpa_printf(MSG_DEBUG, "nl80211: Interface down (%s/%s)",
455 namebuf, ifname);
456 - if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
457 + if (drv->first_bss->ifindex != ifi->ifi_index) {
458 wpa_printf(MSG_DEBUG,
459 "nl80211: Not the main interface (%s) - do not indicate interface down",
460 drv->first_bss->ifname);
461 @@ -1389,7 +1408,7 @@ static void wpa_driver_nl80211_event_rtm
462 }
463 wpa_printf(MSG_DEBUG, "nl80211: Interface up (%s/%s)",
464 namebuf, ifname);
465 - if (os_strcmp(drv->first_bss->ifname, ifname) != 0) {
466 + if (drv->first_bss->ifindex != ifi->ifi_index) {
467 wpa_printf(MSG_DEBUG,
468 "nl80211: Not the main interface (%s) - do not indicate interface up",
469 drv->first_bss->ifname);
470 @@ -2035,6 +2054,7 @@ static int wpa_driver_nl80211_init_nl_gl
471 genl_family_put(family);
472 nl_cache_free(cache);
473
474 + nl_cb_set(global->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
475 nl_cb_set(global->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
476 no_seq_check, NULL);
477 nl_cb_set(global->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
478 @@ -2205,6 +2225,7 @@ static int nl80211_init_bss(struct i802_
479 if (!bss->nl_cb)
480 return -1;
481
482 + nl_cb_set(bss->nl_cb, NL_CB_MSG_IN, NL_CB_CUSTOM, debug_handler, NULL);
483 nl_cb_set(bss->nl_cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM,
484 no_seq_check, NULL);
485 nl_cb_set(bss->nl_cb, NL_CB_VALID, NL_CB_CUSTOM,
486 @@ -8554,6 +8575,7 @@ static void *i802_init(struct hostapd_da
487 char master_ifname[IFNAMSIZ];
488 int ifindex, br_ifindex = 0;
489 int br_added = 0;
490 + int err;
491
492 bss = wpa_driver_nl80211_drv_init(hapd, params->ifname,
493 params->global_priv, 1,
494 @@ -8613,21 +8635,17 @@ static void *i802_init(struct hostapd_da
495 (params->num_bridge == 0 || !params->bridge[0]))
496 add_ifidx(drv, br_ifindex, drv->ifindex);
497
498 - if (bss->added_if_into_bridge || bss->already_in_bridge) {
499 - int err;
500 -
501 - drv->rtnl_sk = nl_socket_alloc();
502 - if (drv->rtnl_sk == NULL) {
503 - wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
504 - goto failed;
505 - }
506 + drv->rtnl_sk = nl_socket_alloc();
507 + if (drv->rtnl_sk == NULL) {
508 + wpa_printf(MSG_ERROR, "nl80211: Failed to allocate nl_sock");
509 + goto failed;
510 + }
511
512 - err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
513 - if (err) {
514 - wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
515 - nl_geterror(err));
516 - goto failed;
517 - }
518 + err = nl_connect(drv->rtnl_sk, NETLINK_ROUTE);
519 + if (err) {
520 + wpa_printf(MSG_ERROR, "nl80211: Failed to connect nl_sock to NETLINK_ROUTE: %s",
521 + nl_geterror(err));
522 + goto failed;
523 }
524
525 if (drv->capa.flags2 & WPA_DRIVER_FLAGS2_CONTROL_PORT_RX) {
526 @@ -8992,6 +9010,50 @@ static int wpa_driver_nl80211_if_remove(
527 return 0;
528 }
529
530 +static int wpa_driver_nl80211_if_rename(struct i802_bss *bss,
531 + enum wpa_driver_if_type type,
532 + const char *ifname, const char *new_name)
533 +{
534 + struct wpa_driver_nl80211_data *drv = bss->drv;
535 + struct ifinfomsg ifi = {
536 + .ifi_family = AF_UNSPEC,
537 + .ifi_index = bss->ifindex,
538 + };
539 + struct nl_msg *msg;
540 + int res = -ENOMEM;
541 +
542 + if (ifname)
543 + ifi.ifi_index = if_nametoindex(ifname);
544 +
545 + msg = nlmsg_alloc_simple(RTM_SETLINK, 0);
546 + if (!msg)
547 + return res;
548 +
549 + if (nlmsg_append(msg, &ifi, sizeof(ifi), NLMSG_ALIGNTO) < 0)
550 + goto out;
551 +
552 + if (nla_put_string(msg, IFLA_IFNAME, new_name))
553 + goto out;
554 +
555 + res = nl_send_auto_complete(drv->rtnl_sk, msg);
556 + if (res < 0)
557 + goto out;
558 +
559 + res = nl_wait_for_ack(drv->rtnl_sk);
560 + if (res) {
561 + wpa_printf(MSG_INFO,
562 + "nl80211: Renaming device %s to %s failed: %s",
563 + ifname ? ifname : bss->ifname, new_name, nl_geterror(res));
564 + goto out;
565 + }
566 +
567 + if (type == WPA_IF_AP_BSS && !ifname)
568 + os_strlcpy(bss->ifname, new_name, sizeof(bss->ifname));
569 +
570 +out:
571 + nlmsg_free(msg);
572 + return res;
573 +}
574
575 static int cookie_handler(struct nl_msg *msg, void *arg)
576 {
577 @@ -10688,6 +10750,37 @@ static int driver_nl80211_if_remove(void
578 }
579
580
581 +static int driver_nl80211_if_rename(void *priv, enum wpa_driver_if_type type,
582 + const char *ifname, const char *new_name)
583 +{
584 + struct i802_bss *bss = priv;
585 + return wpa_driver_nl80211_if_rename(bss, type, ifname, new_name);
586 +}
587 +
588 +
589 +static int driver_nl80211_set_first_bss(void *priv)
590 +{
591 + struct i802_bss *bss = priv, *tbss;
592 + struct wpa_driver_nl80211_data *drv = bss->drv;
593 +
594 + if (drv->first_bss == bss)
595 + return 0;
596 +
597 + for (tbss = drv->first_bss; tbss; tbss = tbss->next) {
598 + if (tbss->next != bss)
599 + continue;
600 +
601 + tbss->next = bss->next;
602 + bss->next = drv->first_bss;
603 + drv->first_bss = bss;
604 + drv->ctx = bss->ctx;
605 + return 0;
606 + }
607 +
608 + return -1;
609 +}
610 +
611 +
612 static int driver_nl80211_send_mlme(void *priv, const u8 *data,
613 size_t data_len, int noack,
614 unsigned int freq,
615 @@ -13881,6 +13974,8 @@ const struct wpa_driver_ops wpa_driver_n
616 .set_acl = wpa_driver_nl80211_set_acl,
617 .if_add = wpa_driver_nl80211_if_add,
618 .if_remove = driver_nl80211_if_remove,
619 + .if_rename = driver_nl80211_if_rename,
620 + .set_first_bss = driver_nl80211_set_first_bss,
621 .send_mlme = driver_nl80211_send_mlme,
622 .get_hw_feature_data = nl80211_get_hw_feature_data,
623 .sta_add = wpa_driver_nl80211_sta_add,
624 --- a/src/utils/wpa_debug.c
625 +++ b/src/utils/wpa_debug.c
626 @@ -26,6 +26,10 @@ static FILE *wpa_debug_tracing_file = NU
627 #define WPAS_TRACE_PFX "wpas <%d>: "
628 #endif /* CONFIG_DEBUG_LINUX_TRACING */
629
630 +void (*wpa_printf_hook)(int level, const char *fmt, va_list ap);
631 +void (*wpa_hexdump_hook)(int level, const char *title, const void *buf,
632 + size_t len);
633 +void (*wpa_netlink_hook)(int tx, const void *data, size_t len);
634
635 int wpa_debug_level = MSG_INFO;
636 int wpa_debug_show_keys = 0;
637 @@ -210,6 +214,12 @@ void _wpa_printf(int level, const char *
638 {
639 va_list ap;
640
641 + if (wpa_printf_hook) {
642 + va_start(ap, fmt);
643 + wpa_printf_hook(level, fmt, ap);
644 + va_end(ap);
645 + }
646 +
647 if (level >= wpa_debug_level) {
648 #ifdef CONFIG_ANDROID_LOG
649 va_start(ap, fmt);
650 @@ -260,6 +270,9 @@ void _wpa_hexdump(int level, const char
651 {
652 size_t i;
653
654 + if (wpa_hexdump_hook)
655 + wpa_hexdump_hook(level, title, buf, len);
656 +
657 #ifdef CONFIG_DEBUG_LINUX_TRACING
658 if (wpa_debug_tracing_file != NULL) {
659 fprintf(wpa_debug_tracing_file,
660 --- a/src/utils/wpa_debug.h
661 +++ b/src/utils/wpa_debug.h
662 @@ -11,6 +11,10 @@
663
664 #include "wpabuf.h"
665
666 +extern void (*wpa_printf_hook)(int level, const char *fmt, va_list ap);
667 +extern void (*wpa_hexdump_hook)(int level, const char *title,
668 + const void *buf, size_t len);
669 +extern void (*wpa_netlink_hook)(int tx, const void *data, size_t len);
670 extern int wpa_debug_level;
671 extern int wpa_debug_show_keys;
672 extern int wpa_debug_timestamp;