Signed-off-by: David Bauer <mail@david-bauer.net>lilik-openwrt-22.03
@ -0,0 +1,44 @@ | |||
include $(TOPDIR)/rules.mk | |||
PKG_NAME:=static-neighbor-reports | |||
PKG_VERSION:=1 | |||
PKG_RELEASE:=1 | |||
PKG_MAINTAINER:=David Bauer <mail@david-bauer.net> | |||
PKG_LICENSE:=GPL-2.0-only | |||
include $(INCLUDE_DIR)/package.mk | |||
Build/Compile= | |||
define Package/static-neighbor-reports/Default | |||
endef | |||
define Package/static-neighbor-reports | |||
SECTION:=net | |||
CATEGORY:=Network | |||
TITLE:=Configure static 802.11k neighbor reports | |||
PKGARCH:=all | |||
DEPENDS:=+libuci-lua +libubus-lua | |||
endef | |||
define Package/static-neighbor-reports/install | |||
$(INSTALL_DIR) $(1)/etc/config | |||
$(INSTALL_CONF) ./files/static-neighbor-report.conf $(1)/etc/config/static-neighbor-report | |||
$(INSTALL_DIR) $(1)/etc/init.d | |||
$(INSTALL_BIN) ./files/static-neighbor-reports.init $(1)/etc/init.d/static-neighbor-reports | |||
$(INSTALL_DIR) $(1)/usr/lib | |||
$(INSTALL_BIN) ./files/reload-neighbor-reports.lua $(1)/usr/lib/reload-neighbor-reports.lua | |||
endef | |||
define Package/static-neighbor-reports/conffiles | |||
/etc/config/static-neighbor-report | |||
endef | |||
define Package/static-neighbor-reports/description | |||
Allows to configure static neighbor reports for hostapd interfaces. | |||
These neighbor reports are avilable to clients using IEEE 802.11k. | |||
endef | |||
$(eval $(call BuildPackage,static-neighbor-reports)) |
@ -0,0 +1,49 @@ | |||
# static-neighbor-reports | |||
The `static-neighbor-reports` package allows a user to configure static neighbor reports which | |||
are available for clients to be polled in case they support IEEE802.11k. This greatly improves | |||
the wireless experiences in terms of mobility. | |||
Make sure to enable `ieee80211k` for each VAP neighbor reports should be installed to. | |||
## Configuring | |||
The uci config name is `static-neighbor-report`. There's currently only the section | |||
type `neighbor`. | |||
### neighbor | |||
The followign options are supported for `neighbor` sections: | |||
#### neighbor_report | |||
This is the binary neighbor report element from a foreign AP. It is required for each neighbor. | |||
#### disabled | |||
Values other than `0` disable the neighbor. It won't be installed into hostapd in this case. | |||
If this option is missing, the neighbor is implicitly active. | |||
#### bssid | |||
The BSSID of the foreign AP. This option can usually be omitted, as it's implicitly present in | |||
the first 6 bytes of the binary neighbor report element. | |||
#### ssid | |||
The SSID of the foreign AP. This option can be omitted, in case it matches the SSID used on the local AP. | |||
#### iface | |||
Space seperated list of hostapd interfaces the neighbor should be installed to. | |||
## Retrieving neighbor information | |||
To retrieve the neighbor informations of an AP to be isntalled on a foreign AP, make sure the UCI option | |||
`ieee80211k` is set to `1` on the VAP. | |||
Execute `ubus call hostapd.<ifname> rrm_nr_get_own` on the AP. To get a list of all available interfaces, | |||
execute `ubus list`. | |||
The returned information follows this format: | |||
```json | |||
{ | |||
"value": [ | |||
"<BSSID>", | |||
"<SSID>", | |||
"<Neighbot report element>" | |||
] | |||
} | |||
``` |
@ -0,0 +1,37 @@ | |||
#!/usr/bin/lua | |||
local uci = require 'uci'.cursor() | |||
local ubus = require('ubus').connect() | |||
local neighbor_reports = {} | |||
local function hasKey(tab, key) | |||
for k, _ in pairs(tab) do | |||
if k == key then return true end | |||
end | |||
return false | |||
end | |||
uci:foreach('static-neighbor-report', 'neighbor', function (config) | |||
if hasKey(config, "disabled") and config.disabled ~= '0' then | |||
return | |||
end | |||
local bssid = '' | |||
local ssid = '' | |||
local neighbor_report = config['neighbor_report'] | |||
if hasKey(config, 'bssid') then bssid = config.bssid end | |||
if hasKey(config, 'ssid') then ssid = config.ssid end | |||
for iface in config.iface:gmatch("%S+") do | |||
if not hasKey(neighbor_reports, iface) then | |||
neighbor_reports[iface] = {} | |||
end | |||
table.insert(neighbor_reports[iface], {bssid, ssid, neighbor_report}) | |||
end | |||
end) | |||
for k, v in pairs(neighbor_reports) do | |||
ubus:call('hostapd.' .. k, 'rrm_nr_set', {list=v}) | |||
end |
@ -0,0 +1,6 @@ | |||
config neighbor ap1 | |||
option bssid 'f2:9e:c0:a5:a9:2c' | |||
option ssid 'Network' | |||
option neighbor_report 'f29ec0a5a92cff1900007a64090603016600' | |||
option iface 'net0 net1' | |||
option disabled '1' |
@ -0,0 +1,24 @@ | |||
#!/bin/sh /etc/rc.common | |||
START=60 | |||
USE_PROCD=1 | |||
start_service() { | |||
procd_open_instance | |||
procd_set_param command /usr/lib/reload-neighbor-reports.lua | |||
procd_set_param stdout 1 | |||
procd_set_param stderr 1 | |||
procd_close_instance | |||
} | |||
reload_service() { | |||
stop | |||
start | |||
} | |||
service_triggers() { | |||
procd_add_raw_trigger "hostapd.*" 3000 /etc/init.d/static-neighbor-reports restart | |||
} |