a6ccf83331fe3e515790f3ab12e89eee93fdb30a
[openwrt/staging/xback.git] / package / network / services / hostapd / patches / 600-ubus_support.patch
1 --- a/hostapd/Makefile
2 +++ b/hostapd/Makefile
3 @@ -166,6 +166,12 @@ OBJS += ../src/common/hw_features_common
4
5 OBJS += ../src/eapol_auth/eapol_auth_sm.o
6
7 +ifdef CONFIG_UBUS
8 +CFLAGS += -DUBUS_SUPPORT
9 +OBJS += ../src/utils/uloop.o
10 +OBJS += ../src/ap/ubus.o
11 +LIBS += -lubox -lubus
12 +endif
13
14 ifdef CONFIG_CODE_COVERAGE
15 CFLAGS += -O0 -fprofile-arcs -ftest-coverage
16 --- a/src/ap/hostapd.h
17 +++ b/src/ap/hostapd.h
18 @@ -18,6 +18,7 @@
19 #include "utils/list.h"
20 #include "ap_config.h"
21 #include "drivers/driver.h"
22 +#include "ubus.h"
23
24 #define OCE_STA_CFON_ENABLED(hapd) \
25 ((hapd->conf->oce & OCE_STA_CFON) && \
26 @@ -184,6 +185,7 @@ struct hostapd_data {
27 struct hostapd_iface *iface;
28 struct hostapd_config *iconf;
29 struct hostapd_bss_config *conf;
30 + struct hostapd_ubus_bss ubus;
31 int interface_added; /* virtual interface added for this BSS */
32 unsigned int started:1;
33 unsigned int disabled:1;
34 @@ -695,6 +697,7 @@ hostapd_alloc_bss_data(struct hostapd_if
35 struct hostapd_bss_config *bss);
36 int hostapd_setup_interface(struct hostapd_iface *iface);
37 int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
38 +void hostapd_set_own_neighbor_report(struct hostapd_data *hapd);
39 void hostapd_interface_deinit(struct hostapd_iface *iface);
40 void hostapd_interface_free(struct hostapd_iface *iface);
41 struct hostapd_iface * hostapd_alloc_iface(void);
42 --- a/src/ap/hostapd.c
43 +++ b/src/ap/hostapd.c
44 @@ -435,6 +435,7 @@ void hostapd_free_hapd_data(struct hosta
45 hapd->beacon_set_done = 0;
46
47 wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface);
48 + hostapd_ubus_free_bss(hapd);
49 accounting_deinit(hapd);
50 hostapd_deinit_wpa(hapd);
51 vlan_deinit(hapd);
52 @@ -1187,6 +1188,8 @@ static int hostapd_start_beacon(struct h
53 if (hapd->driver && hapd->driver->set_operstate)
54 hapd->driver->set_operstate(hapd->drv_priv, 1);
55
56 + hostapd_ubus_add_bss(hapd);
57 +
58 return 0;
59 }
60
61 @@ -2275,6 +2278,7 @@ static int hostapd_setup_interface_compl
62 if (err)
63 goto fail;
64
65 + hostapd_ubus_add_iface(iface);
66 wpa_printf(MSG_DEBUG, "Completing interface initialization");
67 if (iface->freq) {
68 #ifdef NEED_AP_MLME
69 @@ -2494,6 +2498,7 @@ dfs_offload:
70
71 fail:
72 wpa_printf(MSG_ERROR, "Interface initialization failed");
73 + hostapd_ubus_free_iface(iface);
74
75 if (iface->is_no_ir) {
76 hostapd_set_state(iface, HAPD_IFACE_NO_IR);
77 @@ -2984,6 +2989,7 @@ void hostapd_interface_deinit_free(struc
78 (unsigned int) iface->conf->num_bss);
79 driver = iface->bss[0]->driver;
80 drv_priv = iface->bss[0]->drv_priv;
81 + hostapd_ubus_free_iface(iface);
82 hostapd_interface_deinit(iface);
83 wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit",
84 __func__, driver, drv_priv);
85 --- a/src/ap/ieee802_11.c
86 +++ b/src/ap/ieee802_11.c
87 @@ -2786,7 +2786,7 @@ static void handle_auth(struct hostapd_d
88 u16 auth_alg, auth_transaction, status_code;
89 u16 resp = WLAN_STATUS_SUCCESS;
90 struct sta_info *sta = NULL;
91 - int res, reply_res;
92 + int res, reply_res, ubus_resp;
93 u16 fc;
94 const u8 *challenge = NULL;
95 u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
96 @@ -2795,6 +2795,11 @@ static void handle_auth(struct hostapd_d
97 struct radius_sta rad_info;
98 const u8 *dst, *sa, *bssid;
99 bool mld_sta = false;
100 + struct hostapd_ubus_request req = {
101 + .type = HOSTAPD_UBUS_AUTH_REQ,
102 + .mgmt_frame = mgmt,
103 + .ssi_signal = rssi,
104 + };
105
106 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
107 wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
108 @@ -2986,6 +2991,13 @@ static void handle_auth(struct hostapd_d
109 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
110 goto fail;
111 }
112 + ubus_resp = hostapd_ubus_handle_event(hapd, &req);
113 + if (ubus_resp) {
114 + wpa_printf(MSG_DEBUG, "Station " MACSTR " rejected by ubus handler.\n",
115 + MAC2STR(mgmt->sa));
116 + resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE;
117 + goto fail;
118 + }
119 if (res == HOSTAPD_ACL_PENDING)
120 return;
121
122 @@ -5161,7 +5173,7 @@ static void handle_assoc(struct hostapd_
123 int resp = WLAN_STATUS_SUCCESS;
124 u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
125 const u8 *pos;
126 - int left, i;
127 + int left, i, ubus_resp;
128 struct sta_info *sta;
129 u8 *tmp = NULL;
130 #ifdef CONFIG_FILS
131 @@ -5374,6 +5386,11 @@ static void handle_assoc(struct hostapd_
132 left = res;
133 }
134 #endif /* CONFIG_FILS */
135 + struct hostapd_ubus_request req = {
136 + .type = HOSTAPD_UBUS_ASSOC_REQ,
137 + .mgmt_frame = mgmt,
138 + .ssi_signal = rssi,
139 + };
140
141 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
142 * is used */
143 @@ -5472,6 +5489,13 @@ static void handle_assoc(struct hostapd_
144 }
145 #endif /* CONFIG_FILS */
146
147 + ubus_resp = hostapd_ubus_handle_event(hapd, &req);
148 + if (ubus_resp) {
149 + wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n",
150 + MAC2STR(mgmt->sa));
151 + resp = ubus_resp > 0 ? (u16) ubus_resp : WLAN_STATUS_UNSPECIFIED_FAILURE;
152 + goto fail;
153 + }
154 fail:
155
156 /*
157 @@ -5753,6 +5777,7 @@ static void handle_disassoc(struct hosta
158 (unsigned long) len);
159 return;
160 }
161 + hostapd_ubus_notify(hapd, "disassoc", mgmt->sa);
162
163 sta = ap_get_sta(hapd, mgmt->sa);
164 if (!sta) {
165 @@ -5784,6 +5809,8 @@ static void handle_deauth(struct hostapd
166 /* Clear the PTKSA cache entries for PASN */
167 ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE);
168
169 + hostapd_ubus_notify(hapd, "deauth", mgmt->sa);
170 +
171 sta = ap_get_sta(hapd, mgmt->sa);
172 if (!sta) {
173 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR
174 --- a/src/ap/beacon.c
175 +++ b/src/ap/beacon.c
176 @@ -1036,6 +1036,12 @@ void handle_probe_req(struct hostapd_dat
177 u16 csa_offs[2];
178 size_t csa_offs_len;
179 struct radius_sta rad_info;
180 + struct hostapd_ubus_request req = {
181 + .type = HOSTAPD_UBUS_PROBE_REQ,
182 + .mgmt_frame = mgmt,
183 + .ssi_signal = ssi_signal,
184 + .elems = &elems,
185 + };
186
187 if (hapd->iconf->rssi_ignore_probe_request && ssi_signal &&
188 ssi_signal < hapd->iconf->rssi_ignore_probe_request)
189 @@ -1222,6 +1228,12 @@ void handle_probe_req(struct hostapd_dat
190 }
191 #endif /* CONFIG_P2P */
192
193 + if (hostapd_ubus_handle_event(hapd, &req)) {
194 + wpa_printf(MSG_DEBUG, "Probe request for " MACSTR " rejected by ubus handler.\n",
195 + MAC2STR(mgmt->sa));
196 + return;
197 + }
198 +
199 /* TODO: verify that supp_rates contains at least one matching rate
200 * with AP configuration */
201
202 --- a/src/ap/drv_callbacks.c
203 +++ b/src/ap/drv_callbacks.c
204 @@ -260,6 +260,10 @@ int hostapd_notif_assoc(struct hostapd_d
205 u16 reason = WLAN_REASON_UNSPECIFIED;
206 int status = WLAN_STATUS_SUCCESS;
207 const u8 *p2p_dev_addr = NULL;
208 + struct hostapd_ubus_request req = {
209 + .type = HOSTAPD_UBUS_ASSOC_REQ,
210 + .addr = addr,
211 + };
212
213 if (addr == NULL) {
214 /*
215 @@ -396,6 +400,12 @@ int hostapd_notif_assoc(struct hostapd_d
216 goto fail;
217 }
218
219 + if (hostapd_ubus_handle_event(hapd, &req)) {
220 + wpa_printf(MSG_DEBUG, "Station " MACSTR " assoc rejected by ubus handler.\n",
221 + MAC2STR(req.addr));
222 + goto fail;
223 + }
224 +
225 #ifdef CONFIG_P2P
226 if (elems.p2p) {
227 wpabuf_free(sta->p2p_ie);
228 --- a/src/ap/sta_info.c
229 +++ b/src/ap/sta_info.c
230 @@ -471,6 +471,7 @@ void ap_handle_timer(void *eloop_ctx, vo
231 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
232 HOSTAPD_LEVEL_INFO, "deauthenticated due to "
233 "local deauth request");
234 + hostapd_ubus_notify(hapd, "local-deauth", sta->addr);
235 ap_free_sta(hapd, sta);
236 return;
237 }
238 @@ -626,6 +627,7 @@ skip_poll:
239 mlme_deauthenticate_indication(
240 hapd, sta,
241 WLAN_REASON_PREV_AUTH_NOT_VALID);
242 + hostapd_ubus_notify(hapd, "inactive-deauth", sta->addr);
243 ap_free_sta(hapd, sta);
244 break;
245 }
246 @@ -1344,15 +1346,28 @@ void ap_sta_set_authorized(struct hostap
247 sta->addr, authorized, dev_addr);
248
249 if (authorized) {
250 + static const char * const auth_algs[] = {
251 + [WLAN_AUTH_OPEN] = "open",
252 + [WLAN_AUTH_SHARED_KEY] = "shared",
253 + [WLAN_AUTH_FT] = "ft",
254 + [WLAN_AUTH_SAE] = "sae",
255 + [WLAN_AUTH_FILS_SK] = "fils-sk",
256 + [WLAN_AUTH_FILS_SK_PFS] = "fils-sk-pfs",
257 + [WLAN_AUTH_FILS_PK] = "fils-pk",
258 + [WLAN_AUTH_PASN] = "pasn",
259 + };
260 + const char *auth_alg = NULL;
261 const u8 *dpp_pkhash;
262 const char *keyid;
263 char dpp_pkhash_buf[100];
264 char keyid_buf[100];
265 char ip_addr[100];
266 + char alg_buf[100];
267
268 dpp_pkhash_buf[0] = '\0';
269 keyid_buf[0] = '\0';
270 ip_addr[0] = '\0';
271 + alg_buf[0] = '\0';
272 #ifdef CONFIG_P2P
273 if (wpa_auth_get_ip_addr(sta->wpa_sm, ip_addr_buf) == 0) {
274 os_snprintf(ip_addr, sizeof(ip_addr),
275 @@ -1362,6 +1377,13 @@ void ap_sta_set_authorized(struct hostap
276 }
277 #endif /* CONFIG_P2P */
278
279 + if (sta->auth_alg < ARRAY_SIZE(auth_algs))
280 + auth_alg = auth_algs[sta->auth_alg];
281 +
282 + if (auth_alg)
283 + os_snprintf(alg_buf, sizeof(alg_buf),
284 + " auth_alg=%s", auth_alg);
285 +
286 keyid = ap_sta_wpa_get_keyid(hapd, sta);
287 if (keyid) {
288 os_snprintf(keyid_buf, sizeof(keyid_buf),
289 @@ -1380,17 +1402,19 @@ void ap_sta_set_authorized(struct hostap
290 dpp_pkhash, SHA256_MAC_LEN);
291 }
292
293 - wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s",
294 - buf, ip_addr, keyid_buf, dpp_pkhash_buf);
295 + hostapd_ubus_notify_authorized(hapd, sta, auth_alg);
296 + wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s%s%s",
297 + buf, ip_addr, keyid_buf, dpp_pkhash_buf, alg_buf);
298
299 if (hapd->msg_ctx_parent &&
300 hapd->msg_ctx_parent != hapd->msg_ctx)
301 wpa_msg_no_global(hapd->msg_ctx_parent, MSG_INFO,
302 - AP_STA_CONNECTED "%s%s%s%s",
303 + AP_STA_CONNECTED "%s%s%s%s%s",
304 buf, ip_addr, keyid_buf,
305 - dpp_pkhash_buf);
306 + dpp_pkhash_buf, alg_buf);
307 } else {
308 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf);
309 + hostapd_ubus_notify(hapd, "disassoc", sta->addr);
310
311 if (hapd->msg_ctx_parent &&
312 hapd->msg_ctx_parent != hapd->msg_ctx)
313 --- a/src/ap/wpa_auth_glue.c
314 +++ b/src/ap/wpa_auth_glue.c
315 @@ -269,6 +269,7 @@ static void hostapd_wpa_auth_psk_failure
316 struct hostapd_data *hapd = ctx;
317 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR,
318 MAC2STR(addr));
319 + hostapd_ubus_notify(hapd, "key-mismatch", addr);
320 }
321
322
323 --- a/wpa_supplicant/Makefile
324 +++ b/wpa_supplicant/Makefile
325 @@ -192,6 +192,13 @@ ifdef CONFIG_EAPOL_TEST
326 CFLAGS += -Werror -DEAPOL_TEST
327 endif
328
329 +ifdef CONFIG_UBUS
330 +CFLAGS += -DUBUS_SUPPORT
331 +OBJS += ubus.o
332 +OBJS += ../src/utils/uloop.o
333 +LIBS += -lubox -lubus
334 +endif
335 +
336 ifdef CONFIG_CODE_COVERAGE
337 CFLAGS += -O0 -fprofile-arcs -ftest-coverage
338 LIBS += -lgcov
339 @@ -987,6 +994,9 @@ ifdef CONFIG_CTRL_IFACE_MIB
340 CFLAGS += -DCONFIG_CTRL_IFACE_MIB
341 endif
342 OBJS += ../src/ap/ctrl_iface_ap.o
343 +ifdef CONFIG_UBUS
344 +OBJS += ../src/ap/ubus.o
345 +endif
346 endif
347
348 CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY
349 --- a/wpa_supplicant/wpa_supplicant.c
350 +++ b/wpa_supplicant/wpa_supplicant.c
351 @@ -7595,6 +7595,8 @@ struct wpa_supplicant * wpa_supplicant_a
352 }
353 #endif /* CONFIG_P2P */
354
355 + wpas_ubus_add_bss(wpa_s);
356 +
357 return wpa_s;
358 }
359
360 @@ -7621,6 +7623,8 @@ int wpa_supplicant_remove_iface(struct w
361 struct wpa_supplicant *parent = wpa_s->parent;
362 #endif /* CONFIG_MESH */
363
364 + wpas_ubus_free_bss(wpa_s);
365 +
366 /* Remove interface from the global list of interfaces */
367 prev = global->ifaces;
368 if (prev == wpa_s) {
369 @@ -7967,8 +7971,12 @@ int wpa_supplicant_run(struct wpa_global
370 eloop_register_signal_terminate(wpa_supplicant_terminate, global);
371 eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
372
373 + wpas_ubus_add(global);
374 +
375 eloop_run();
376
377 + wpas_ubus_free(global);
378 +
379 return 0;
380 }
381
382 --- a/wpa_supplicant/wpa_supplicant_i.h
383 +++ b/wpa_supplicant/wpa_supplicant_i.h
384 @@ -21,6 +21,7 @@
385 #include "config_ssid.h"
386 #include "wmm_ac.h"
387 #include "pasn/pasn_common.h"
388 +#include "ubus.h"
389
390 extern const char *const wpa_supplicant_version;
391 extern const char *const wpa_supplicant_license;
392 @@ -319,6 +320,8 @@ struct wpa_global {
393 #endif /* CONFIG_WIFI_DISPLAY */
394
395 struct psk_list_entry *add_psk; /* From group formation */
396 +
397 + struct ubus_object ubus_global;
398 };
399
400
401 @@ -685,6 +688,7 @@ struct wpa_supplicant {
402 unsigned char own_addr[ETH_ALEN];
403 unsigned char perm_addr[ETH_ALEN];
404 char ifname[100];
405 + struct wpas_ubus_bss ubus;
406 #ifdef CONFIG_MATCH_IFACE
407 int matched;
408 #endif /* CONFIG_MATCH_IFACE */
409 --- a/wpa_supplicant/wps_supplicant.c
410 +++ b/wpa_supplicant/wps_supplicant.c
411 @@ -33,6 +33,7 @@
412 #include "p2p/p2p.h"
413 #include "p2p_supplicant.h"
414 #include "wps_supplicant.h"
415 +#include "ubus.h"
416
417
418 #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG
419 @@ -402,6 +403,8 @@ static int wpa_supplicant_wps_cred(void
420 wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute",
421 cred->cred_attr, cred->cred_attr_len);
422
423 + wpas_ubus_notify(wpa_s, cred);
424 +
425 if (wpa_s->conf->wps_cred_processing == 1)
426 return 0;
427
428 --- a/wpa_supplicant/main.c
429 +++ b/wpa_supplicant/main.c
430 @@ -203,7 +203,7 @@ int main(int argc, char *argv[])
431
432 for (;;) {
433 c = getopt(argc, argv,
434 - "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuv::W");
435 + "b:Bc:C:D:de:f:g:G:hi:I:KLMm:nNo:O:p:P:qsTtuv::W");
436 if (c < 0)
437 break;
438 switch (c) {
439 @@ -268,6 +268,9 @@ int main(int argc, char *argv[])
440 params.conf_p2p_dev = optarg;
441 break;
442 #endif /* CONFIG_P2P */
443 + case 'n':
444 + iface_count = 0;
445 + break;
446 case 'o':
447 params.override_driver = optarg;
448 break;
449 --- a/src/ap/rrm.c
450 +++ b/src/ap/rrm.c
451 @@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report
452 return;
453 wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s",
454 MAC2STR(addr), token, rep_mode, report);
455 + if (len < sizeof(struct rrm_measurement_beacon_report))
456 + return;
457 + hostapd_ubus_notify_beacon_report(hapd, addr, token, rep_mode, (struct rrm_measurement_beacon_report*) pos, len);
458 }
459
460
461 @@ -352,6 +355,9 @@ void hostapd_handle_radio_measurement(st
462 mgmt->u.action.u.rrm.action, MAC2STR(mgmt->sa));
463
464 switch (mgmt->u.action.u.rrm.action) {
465 + case WLAN_RRM_LINK_MEASUREMENT_REPORT:
466 + hostapd_ubus_handle_link_measurement(hapd, buf, len);
467 + break;
468 case WLAN_RRM_RADIO_MEASUREMENT_REPORT:
469 hostapd_handle_radio_msmt_report(hapd, buf, len);
470 break;
471 --- a/src/ap/vlan_init.c
472 +++ b/src/ap/vlan_init.c
473 @@ -22,6 +22,7 @@
474 static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan,
475 int existsok)
476 {
477 + bool vlan_exists = iface_exists(vlan->ifname);
478 int ret;
479 #ifdef CONFIG_WEP
480 int i;
481 @@ -36,7 +37,7 @@ static int vlan_if_add(struct hostapd_da
482 }
483 #endif /* CONFIG_WEP */
484
485 - if (!iface_exists(vlan->ifname))
486 + if (!vlan_exists)
487 ret = hostapd_vlan_if_add(hapd, vlan->ifname);
488 else if (!existsok)
489 return -1;
490 @@ -51,6 +52,9 @@ static int vlan_if_add(struct hostapd_da
491 if (hapd->wpa_auth)
492 ret = wpa_auth_ensure_group(hapd->wpa_auth, vlan->vlan_id);
493
494 + if (!ret && !vlan_exists)
495 + hostapd_ubus_add_vlan(hapd, vlan);
496 +
497 if (ret == 0)
498 return ret;
499
500 @@ -77,6 +81,8 @@ int vlan_if_remove(struct hostapd_data *
501 "WPA deinitialization for VLAN %d failed (%d)",
502 vlan->vlan_id, ret);
503
504 + hostapd_ubus_remove_vlan(hapd, vlan);
505 +
506 return hostapd_vlan_if_remove(hapd, vlan->ifname);
507 }
508
509 --- a/src/ap/dfs.c
510 +++ b/src/ap/dfs.c
511 @@ -1216,6 +1216,8 @@ int hostapd_dfs_pre_cac_expired(struct h
512 "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d",
513 freq, ht_enabled, chan_offset, chan_width, cf1, cf2);
514
515 + hostapd_ubus_notify_radar_detected(iface, freq, chan_width, cf1, cf2);
516 +
517 /* Proceed only if DFS is not offloaded to the driver */
518 if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD)
519 return 0;
520 --- a/src/ap/airtime_policy.c
521 +++ b/src/ap/airtime_policy.c
522 @@ -112,8 +112,14 @@ static void set_sta_weights(struct hosta
523 {
524 struct sta_info *sta;
525
526 - for (sta = hapd->sta_list; sta; sta = sta->next)
527 - sta_set_airtime_weight(hapd, sta, weight);
528 + for (sta = hapd->sta_list; sta; sta = sta->next) {
529 + unsigned int sta_weight = weight;
530 +
531 + if (sta->dyn_airtime_weight)
532 + sta_weight = (weight * sta->dyn_airtime_weight) / 256;
533 +
534 + sta_set_airtime_weight(hapd, sta, sta_weight);
535 + }
536 }
537
538
539 @@ -244,7 +250,10 @@ int airtime_policy_new_sta(struct hostap
540 unsigned int weight;
541
542 if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) {
543 - weight = get_weight_for_sta(hapd, sta->addr);
544 + if (sta->dyn_airtime_weight)
545 + weight = sta->dyn_airtime_weight;
546 + else
547 + weight = get_weight_for_sta(hapd, sta->addr);
548 if (weight)
549 return sta_set_airtime_weight(hapd, sta, weight);
550 }
551 --- a/src/ap/sta_info.h
552 +++ b/src/ap/sta_info.h
553 @@ -322,6 +322,7 @@ struct sta_info {
554 #endif /* CONFIG_TESTING_OPTIONS */
555 #ifdef CONFIG_AIRTIME_POLICY
556 unsigned int airtime_weight;
557 + unsigned int dyn_airtime_weight;
558 struct os_reltime backlogged_until;
559 #endif /* CONFIG_AIRTIME_POLICY */
560
561 --- a/src/ap/wnm_ap.c
562 +++ b/src/ap/wnm_ap.c
563 @@ -455,7 +455,8 @@ static void ieee802_11_rx_bss_trans_mgmt
564 MAC2STR(addr), reason, hex ? " neighbor=" : "", hex);
565 os_free(hex);
566
567 - ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token);
568 + if (!hostapd_ubus_notify_bss_transition_query(hapd, addr, dialog_token, reason, pos, end - pos))
569 + ieee802_11_send_bss_trans_mgmt_request(hapd, addr, dialog_token);
570 }
571
572
573 @@ -477,7 +478,7 @@ static void ieee802_11_rx_bss_trans_mgmt
574 size_t len)
575 {
576 u8 dialog_token, status_code, bss_termination_delay;
577 - const u8 *pos, *end;
578 + const u8 *pos, *end, *target_bssid = NULL;
579 int enabled = hapd->conf->bss_transition;
580 struct sta_info *sta;
581
582 @@ -524,6 +525,7 @@ static void ieee802_11_rx_bss_trans_mgmt
583 wpa_printf(MSG_DEBUG, "WNM: not enough room for Target BSSID field");
584 return;
585 }
586 + target_bssid = pos;
587 sta->agreed_to_steer = 1;
588 eloop_cancel_timeout(ap_sta_reset_steer_flag_timer, hapd, sta);
589 eloop_register_timeout(2, 0, ap_sta_reset_steer_flag_timer,
590 @@ -543,6 +545,10 @@ static void ieee802_11_rx_bss_trans_mgmt
591 MAC2STR(addr), status_code, bss_termination_delay);
592 }
593
594 + hostapd_ubus_notify_bss_transition_response(hapd, sta->addr, dialog_token,
595 + status_code, bss_termination_delay,
596 + target_bssid, pos, end - pos);
597 +
598 wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries",
599 pos, end - pos);
600 }
601 --- a/src/utils/eloop.c
602 +++ b/src/utils/eloop.c
603 @@ -77,6 +77,9 @@ struct eloop_sock_table {
604 struct eloop_data {
605 int max_sock;
606
607 + eloop_timeout_poll_handler timeout_poll_cb;
608 + eloop_poll_handler poll_cb;
609 +
610 size_t count; /* sum of all table counts */
611 #ifdef CONFIG_ELOOP_POLL
612 size_t max_pollfd_map; /* number of pollfds_map currently allocated */
613 @@ -1121,6 +1124,12 @@ void eloop_run(void)
614 os_reltime_sub(&timeout->time, &now, &tv);
615 else
616 tv.sec = tv.usec = 0;
617 + }
618 +
619 + if (eloop.timeout_poll_cb && eloop.timeout_poll_cb(&tv, !!timeout))
620 + timeout = (void *)1;
621 +
622 + if (timeout) {
623 #if defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL)
624 timeout_ms = tv.sec * 1000 + tv.usec / 1000;
625 #endif /* defined(CONFIG_ELOOP_POLL) || defined(CONFIG_ELOOP_EPOLL) */
626 @@ -1190,7 +1199,8 @@ void eloop_run(void)
627 eloop.exceptions.changed = 0;
628
629 eloop_process_pending_signals();
630 -
631 + if (eloop.poll_cb)
632 + eloop.poll_cb();
633
634 /* check if some registered timeouts have occurred */
635 timeout = dl_list_first(&eloop.timeout, struct eloop_timeout,
636 @@ -1252,6 +1262,14 @@ out:
637 return;
638 }
639
640 +int eloop_register_cb(eloop_poll_handler poll_cb,
641 + eloop_timeout_poll_handler timeout_cb)
642 +{
643 + eloop.poll_cb = poll_cb;
644 + eloop.timeout_poll_cb = timeout_cb;
645 +
646 + return 0;
647 +}
648
649 void eloop_terminate(void)
650 {
651 --- a/src/utils/eloop.h
652 +++ b/src/utils/eloop.h
653 @@ -65,6 +65,9 @@ typedef void (*eloop_timeout_handler)(vo
654 */
655 typedef void (*eloop_signal_handler)(int sig, void *signal_ctx);
656
657 +typedef bool (*eloop_timeout_poll_handler)(struct os_reltime *tv, bool tv_set);
658 +typedef void (*eloop_poll_handler)(void);
659 +
660 /**
661 * eloop_init() - Initialize global event loop data
662 * Returns: 0 on success, -1 on failure
663 @@ -73,6 +76,9 @@ typedef void (*eloop_signal_handler)(int
664 */
665 int eloop_init(void);
666
667 +int eloop_register_cb(eloop_poll_handler poll_cb,
668 + eloop_timeout_poll_handler timeout_cb);
669 +
670 /**
671 * eloop_register_read_sock - Register handler for read events
672 * @sock: File descriptor number for the socket
673 @@ -320,6 +326,8 @@ int eloop_register_signal_reconfig(eloop
674 */
675 int eloop_sock_requeue(void);
676
677 +void eloop_add_uloop(void);
678 +
679 /**
680 * eloop_run - Start the event loop
681 *
682 --- /dev/null
683 +++ b/src/utils/uloop.c
684 @@ -0,0 +1,64 @@
685 +#include <libubox/uloop.h>
686 +#include "includes.h"
687 +#include "common.h"
688 +#include "eloop.h"
689 +
690 +static void eloop_uloop_event_cb(int sock, void *eloop_ctx, void *sock_ctx)
691 +{
692 +}
693 +
694 +static void eloop_uloop_fd_cb(struct uloop_fd *fd, unsigned int events)
695 +{
696 + unsigned int changed = events ^ fd->flags;
697 +
698 + if (changed & ULOOP_READ) {
699 + if (events & ULOOP_READ)
700 + eloop_register_sock(fd->fd, EVENT_TYPE_READ, eloop_uloop_event_cb, fd, fd);
701 + else
702 + eloop_unregister_sock(fd->fd, EVENT_TYPE_READ);
703 + }
704 +
705 + if (changed & ULOOP_WRITE) {
706 + if (events & ULOOP_WRITE)
707 + eloop_register_sock(fd->fd, EVENT_TYPE_WRITE, eloop_uloop_event_cb, fd, fd);
708 + else
709 + eloop_unregister_sock(fd->fd, EVENT_TYPE_WRITE);
710 + }
711 +}
712 +
713 +static bool uloop_timeout_poll_handler(struct os_reltime *tv, bool tv_set)
714 +{
715 + struct os_reltime tv_uloop;
716 + int timeout_ms = uloop_get_next_timeout();
717 +
718 + if (timeout_ms < 0)
719 + return false;
720 +
721 + tv_uloop.sec = timeout_ms / 1000;
722 + tv_uloop.usec = (timeout_ms % 1000) * 1000;
723 +
724 + if (!tv_set || os_reltime_before(&tv_uloop, tv)) {
725 + *tv = tv_uloop;
726 + return true;
727 + }
728 +
729 + return false;
730 +}
731 +
732 +static void uloop_poll_handler(void)
733 +{
734 + uloop_run_timeout(0);
735 +}
736 +
737 +void eloop_add_uloop(void)
738 +{
739 + static bool init_done = false;
740 +
741 + if (!init_done) {
742 + uloop_init();
743 + uloop_fd_set_cb = eloop_uloop_fd_cb;
744 + init_done = true;
745 + }
746 +
747 + eloop_register_cb(uloop_poll_handler, uloop_timeout_poll_handler);
748 +}