hostapd: add support for turning on 802.11k/v features via ubus
Neighbor reports are enabled implicitly on use, beacon reports and BSS transition management need to be enabled explicitly Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
526921f20e
commit
6b1816f8a3
2 changed files with 125 additions and 7 deletions
|
@ -39,6 +39,14 @@
|
||||||
enum hostapd_iface_state {
|
enum hostapd_iface_state {
|
||||||
HAPD_IFACE_UNINITIALIZED,
|
HAPD_IFACE_UNINITIALIZED,
|
||||||
HAPD_IFACE_DISABLED,
|
HAPD_IFACE_DISABLED,
|
||||||
|
@@ -518,6 +522,7 @@ hostapd_alloc_bss_data(struct hostapd_if
|
||||||
|
struct hostapd_bss_config *bss);
|
||||||
|
int hostapd_setup_interface(struct hostapd_iface *iface);
|
||||||
|
int hostapd_setup_interface_complete(struct hostapd_iface *iface, int err);
|
||||||
|
+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd);
|
||||||
|
void hostapd_interface_deinit(struct hostapd_iface *iface);
|
||||||
|
void hostapd_interface_free(struct hostapd_iface *iface);
|
||||||
|
struct hostapd_iface * hostapd_alloc_iface(void);
|
||||||
--- a/src/ap/hostapd.c
|
--- a/src/ap/hostapd.c
|
||||||
+++ b/src/ap/hostapd.c
|
+++ b/src/ap/hostapd.c
|
||||||
@@ -309,6 +309,7 @@ static void hostapd_free_hapd_data(struc
|
@@ -309,6 +309,7 @@ static void hostapd_free_hapd_data(struc
|
||||||
|
@ -58,6 +66,15 @@
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1600,7 +1603,7 @@ static enum nr_chan_width hostapd_get_nr
|
||||||
|
#endif /* NEED_AP_MLME */
|
||||||
|
|
||||||
|
|
||||||
|
-static void hostapd_set_own_neighbor_report(struct hostapd_data *hapd)
|
||||||
|
+void hostapd_set_own_neighbor_report(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
#ifdef NEED_AP_MLME
|
||||||
|
u16 capab = hostapd_own_capab_info(hapd);
|
||||||
@@ -1711,6 +1714,7 @@ static int hostapd_setup_interface_compl
|
@@ -1711,6 +1714,7 @@ static int hostapd_setup_interface_compl
|
||||||
if (err)
|
if (err)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -469,6 +469,110 @@ hostapd_rrm_print_nr(struct hostapd_neighbor_entry *nr)
|
||||||
blobmsg_add_string_buffer(&b);
|
blobmsg_add_string_buffer(&b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BSS_MGMT_EN_NEIGHBOR,
|
||||||
|
BSS_MGMT_EN_BEACON,
|
||||||
|
#ifdef CONFIG_WNM_AP
|
||||||
|
BSS_MGMT_EN_BSS_TRANSITION,
|
||||||
|
#endif
|
||||||
|
__BSS_MGMT_EN_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
__hostapd_bss_mgmt_enable_f(struct hostapd_data *hapd, int flag)
|
||||||
|
{
|
||||||
|
struct hostapd_bss_config *bss = hapd->conf;
|
||||||
|
uint32_t flags;
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
|
case BSS_MGMT_EN_NEIGHBOR:
|
||||||
|
if (bss->radio_measurements[0] &
|
||||||
|
WLAN_RRM_CAPS_NEIGHBOR_REPORT)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bss->radio_measurements[0] |=
|
||||||
|
WLAN_RRM_CAPS_NEIGHBOR_REPORT;
|
||||||
|
hostapd_set_own_neighbor_report(hapd);
|
||||||
|
return true;
|
||||||
|
case BSS_MGMT_EN_BEACON:
|
||||||
|
flags = WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
|
||||||
|
WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE |
|
||||||
|
WLAN_RRM_CAPS_BEACON_REPORT_TABLE;
|
||||||
|
|
||||||
|
if (bss->radio_measurements[0] & flags == flags)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bss->radio_measurements[0] |= (u8) flags;
|
||||||
|
return true;
|
||||||
|
#ifdef CONFIG_WNM_AP
|
||||||
|
case BSS_MGMT_EN_BSS_TRANSITION:
|
||||||
|
if (bss->bss_transition)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bss->bss_transition = 1;
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
__hostapd_bss_mgmt_enable(struct hostapd_data *hapd, uint32_t flags)
|
||||||
|
{
|
||||||
|
bool update = false;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < __BSS_MGMT_EN_MAX; i++) {
|
||||||
|
if (!(flags & (1 << i)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
update |= __hostapd_bss_mgmt_enable_f(hapd, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update)
|
||||||
|
ieee802_11_update_beacons(hapd->iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const struct blobmsg_policy bss_mgmt_enable_policy[__BSS_MGMT_EN_MAX] = {
|
||||||
|
[BSS_MGMT_EN_NEIGHBOR] = { "neighbor_report", BLOBMSG_TYPE_BOOL },
|
||||||
|
[BSS_MGMT_EN_BEACON] = { "beacon_report", BLOBMSG_TYPE_BOOL },
|
||||||
|
#ifdef CONFIG_WNM_AP
|
||||||
|
[BSS_MGMT_EN_BSS_TRANSITION] = { "bss_transition", BLOBMSG_TYPE_BOOL },
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
hostapd_bss_mgmt_enable(struct ubus_context *ctx, struct ubus_object *obj,
|
||||||
|
struct ubus_request_data *req, const char *method,
|
||||||
|
struct blob_attr *msg)
|
||||||
|
|
||||||
|
{
|
||||||
|
struct hostapd_data *hapd = get_hapd_from_object(obj);
|
||||||
|
struct blob_attr *tb[__BSS_MGMT_EN_MAX];
|
||||||
|
struct blob_attr *cur;
|
||||||
|
uint32_t flags = 0;
|
||||||
|
int i;
|
||||||
|
bool neigh = false, beacon = false;
|
||||||
|
|
||||||
|
blobmsg_parse(bss_mgmt_enable_policy, __BSS_MGMT_EN_MAX, tb, blob_data(msg), blob_len(msg));
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(tb); i++) {
|
||||||
|
if (!tb[i] || !blobmsg_get_bool(tb[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
flags |= (1 << i);
|
||||||
|
}
|
||||||
|
|
||||||
|
__hostapd_bss_mgmt_enable(hapd, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
hostapd_rrm_nr_enable(struct hostapd_data *hapd)
|
||||||
|
{
|
||||||
|
__hostapd_bss_mgmt_enable(hapd, 1 << BSS_MGMT_EN_NEIGHBOR);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
hostapd_rrm_nr_get_own(struct ubus_context *ctx, struct ubus_object *obj,
|
hostapd_rrm_nr_get_own(struct ubus_context *ctx, struct ubus_object *obj,
|
||||||
struct ubus_request_data *req, const char *method,
|
struct ubus_request_data *req, const char *method,
|
||||||
|
@ -478,8 +582,7 @@ hostapd_rrm_nr_get_own(struct ubus_context *ctx, struct ubus_object *obj,
|
||||||
struct hostapd_neighbor_entry *nr;
|
struct hostapd_neighbor_entry *nr;
|
||||||
void *c;
|
void *c;
|
||||||
|
|
||||||
if (!(hapd->conf->radio_measurements[0] & WLAN_RRM_CAPS_NEIGHBOR_REPORT))
|
hostapd_rrm_nr_enable(hapd);
|
||||||
return UBUS_STATUS_NOT_SUPPORTED;
|
|
||||||
|
|
||||||
nr = hostapd_neighbor_get(hapd, hapd->own_addr, NULL);
|
nr = hostapd_neighbor_get(hapd, hapd->own_addr, NULL);
|
||||||
if (!nr)
|
if (!nr)
|
||||||
|
@ -505,9 +608,7 @@ hostapd_rrm_nr_list(struct ubus_context *ctx, struct ubus_object *obj,
|
||||||
struct hostapd_neighbor_entry *nr;
|
struct hostapd_neighbor_entry *nr;
|
||||||
void *c;
|
void *c;
|
||||||
|
|
||||||
if (!(hapd->conf->radio_measurements[0] & WLAN_RRM_CAPS_NEIGHBOR_REPORT))
|
hostapd_rrm_nr_enable(hapd);
|
||||||
return UBUS_STATUS_NOT_SUPPORTED;
|
|
||||||
|
|
||||||
blob_buf_init(&b, 0);
|
blob_buf_init(&b, 0);
|
||||||
|
|
||||||
c = blobmsg_open_array(&b, "list");
|
c = blobmsg_open_array(&b, "list");
|
||||||
|
@ -570,8 +671,7 @@ hostapd_rrm_nr_set(struct ubus_context *ctx, struct ubus_object *obj,
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int rem;
|
int rem;
|
||||||
|
|
||||||
if (!(hapd->conf->radio_measurements[0] & WLAN_RRM_CAPS_NEIGHBOR_REPORT))
|
hostapd_rrm_nr_enable(hapd);
|
||||||
return UBUS_STATUS_NOT_SUPPORTED;
|
|
||||||
|
|
||||||
blobmsg_parse(nr_set_policy, __NR_SET_LIST_MAX, tb_l, blob_data(msg), blob_len(msg));
|
blobmsg_parse(nr_set_policy, __NR_SET_LIST_MAX, tb_l, blob_data(msg), blob_len(msg));
|
||||||
if (!tb_l[NR_SET_LIST])
|
if (!tb_l[NR_SET_LIST])
|
||||||
|
@ -625,6 +725,7 @@ static const struct ubus_method bss_methods[] = {
|
||||||
#endif
|
#endif
|
||||||
UBUS_METHOD("set_vendor_elements", hostapd_vendor_elements, ve_policy),
|
UBUS_METHOD("set_vendor_elements", hostapd_vendor_elements, ve_policy),
|
||||||
UBUS_METHOD("notify_response", hostapd_notify_response, notify_policy),
|
UBUS_METHOD("notify_response", hostapd_notify_response, notify_policy),
|
||||||
|
UBUS_METHOD("bss_mgmt_enable", hostapd_bss_mgmt_enable, bss_mgmt_enable_policy),
|
||||||
UBUS_METHOD_NOARG("rrm_nr_get_own", hostapd_rrm_nr_get_own),
|
UBUS_METHOD_NOARG("rrm_nr_get_own", hostapd_rrm_nr_get_own),
|
||||||
UBUS_METHOD_NOARG("rrm_nr_list", hostapd_rrm_nr_list),
|
UBUS_METHOD_NOARG("rrm_nr_list", hostapd_rrm_nr_list),
|
||||||
UBUS_METHOD("rrm_nr_set", hostapd_rrm_nr_set, nr_set_policy),
|
UBUS_METHOD("rrm_nr_set", hostapd_rrm_nr_set, nr_set_policy),
|
||||||
|
|
Loading…
Reference in a new issue