diff --git a/net/static-neighbor-reports/Makefile b/net/static-neighbor-reports/Makefile new file mode 100644 index 000000000..293ae1812 --- /dev/null +++ b/net/static-neighbor-reports/Makefile @@ -0,0 +1,44 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=static-neighbor-reports +PKG_VERSION:=1 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=David Bauer +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)) diff --git a/net/static-neighbor-reports/README.md b/net/static-neighbor-reports/README.md new file mode 100644 index 000000000..575d28247 --- /dev/null +++ b/net/static-neighbor-reports/README.md @@ -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. 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": [ + "", + "", + "" + ] +} +``` diff --git a/net/static-neighbor-reports/files/reload-neighbor-reports.lua b/net/static-neighbor-reports/files/reload-neighbor-reports.lua new file mode 100644 index 000000000..52b490e6d --- /dev/null +++ b/net/static-neighbor-reports/files/reload-neighbor-reports.lua @@ -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 diff --git a/net/static-neighbor-reports/files/static-neighbor-report.conf b/net/static-neighbor-reports/files/static-neighbor-report.conf new file mode 100644 index 000000000..e9c01dc24 --- /dev/null +++ b/net/static-neighbor-reports/files/static-neighbor-report.conf @@ -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' diff --git a/net/static-neighbor-reports/files/static-neighbor-reports.init b/net/static-neighbor-reports/files/static-neighbor-reports.init new file mode 100644 index 000000000..a23c14a06 --- /dev/null +++ b/net/static-neighbor-reports/files/static-neighbor-reports.init @@ -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 +}