diff --git a/feeds/ucentral/dynamic-vlan/Makefile b/feeds/ucentral/dynamic-vlan/Makefile deleted file mode 100644 index 2bedc6af6..000000000 --- a/feeds/ucentral/dynamic-vlan/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=dynamic-vlan -PKG_RELEASE:=1 - -PKG_SOURCE_URL=https://github.com/blogic/dynamic-vlan.git -PKG_MIRROR_HASH:=2129d5e4b397afad76825a042dab6fb57c63e57c686d354f3d0d77a5754ab760 -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2021-06-04 -PKG_SOURCE_VERSION:=7202189d1b710c52f8ddc3c7040821708c3f438b - -PKG_MAINTAINER:=John Crispin -PKG_LICENSE:=BSD-3-Clause - -include $(INCLUDE_DIR)/package.mk -include $(INCLUDE_DIR)/cmake.mk - -define Package/dynamic-vlan - SECTION:=ucentral - CATEGORY:=uCentral - TITLE:=dynamic VLAN netifd helper - DEPENDS:=+libubox +libubus -endef - -define Package/dynamic-vlan/install - $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d - $(INSTALL_BIN) $(PKG_BUILD_DIR)/dynamic-vlan $(1)/usr/sbin/ - $(INSTALL_BIN) ./files/dynamic-vlan $(1)/etc/init.d/ -endef - -$(eval $(call BuildPackage,dynamic-vlan)) diff --git a/feeds/ucentral/dynamic-vlan/files/dynamic-vlan b/feeds/ucentral/dynamic-vlan/files/dynamic-vlan deleted file mode 100644 index 84695301d..000000000 --- a/feeds/ucentral/dynamic-vlan/files/dynamic-vlan +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh /etc/rc.common - -START=80 - -USE_PROCD=1 -PROG=/usr/sbin/dynamic-vlan - -start_service() { - wan=$(cat /etc/board.json | jsonfilter -e '@.network.wan.device') - [ -z "$wan" ] && eval $(jsonfilter -i /etc/board.json -e 'wan=@.network.wan.ports.*') - procd_open_instance - procd_set_param command "$PROG" - for w in $wan; do - procd_append_param command $w - done - procd_set_param respawn - procd_close_instance -} diff --git a/feeds/ucentral/dynamic-vlan/git-src b/feeds/ucentral/dynamic-vlan/git-src deleted file mode 120000 index 76c68c205..000000000 --- a/feeds/ucentral/dynamic-vlan/git-src +++ /dev/null @@ -1 +0,0 @@ -/ucentral/dynamic-vlan/.git \ No newline at end of file diff --git a/feeds/ucentral/ratelimit/files/etc/hotplug.d/net/30-ratelimit b/feeds/ucentral/ratelimit/files/etc/hotplug.d/net/30-ratelimit deleted file mode 100644 index 17dd72ee9..000000000 --- a/feeds/ucentral/ratelimit/files/etc/hotplug.d/net/30-ratelimit +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -[ "${INTERFACE:0:4}" == "wlan" ] || exit 0 - -[ "$ACTION" == remove ] && { - [ -f /tmp/run/hostapd-cli-$INTERFACE.pid ] || return - kill "$(cat /tmp/run/hostapd-cli-$INTERFACE.pid)" - rm /tmp/run/hostapd-cli-$INTERFACE.pid - exit 0 -} - -[ "$ACTION" == add ] && { - [ -f /tmp/run/hostapd-cli-$INTERFACE.pid ] && return - touch /tmp/run/hostapd-cli-$INTERFACE.pid - /usr/libexec/ratelimit-wait.sh $INTERFACE & - exit 0 -} diff --git a/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit-wait.sh b/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit-wait.sh deleted file mode 100755 index 2e9903f58..000000000 --- a/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit-wait.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -[ -f /tmp/run/hostapd-cli-$1.pid ] && kill "$(cat /tmp/run/hostapd-cli-$1.pid)" -ubus -t 120 wait_for hostapd.$1 -[ $? = 0 ] && hostapd_cli -a /usr/libexec/ratelimit.sh -i $1 -P /tmp/run/hostapd-cli-$1.pid -B diff --git a/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit.sh b/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit.sh deleted file mode 100755 index 7f6d10f30..000000000 --- a/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -case $2 in -AP-STA-CONNECTED) - [ $4 = 0 -o $5 = 0 ] && { - ubus call ratelimit client_set '{"device": "'$1'", "address": "'$3'", "defaults": "'$(ubus call wifi iface | jsonfilter -e "@['$1'].ssid")'" }' - logger ratelimit addclient $1 $3 $ssid - return - } - ubus call ratelimit client_set '{"device": "'$1'", "address": "'$3'", "rate_ingress": "'$4'mbit", "rate_egress": "'$5'mbit" }' - logger ratelimit addclient $1 $3 $4 $5 - ;; -AP-STA-DISCONNECTED) - ubus call ratelimit client_delete '{ "address": "'$3'" }' - logger ratelimit delclient $3 - ;; -esac diff --git a/feeds/ucentral/ucentral-client/Makefile b/feeds/ucentral/ucentral-client/Makefile index 321e60f8d..e46174e06 100644 --- a/feeds/ucentral/ucentral-client/Makefile +++ b/feeds/ucentral/ucentral-client/Makefile @@ -4,10 +4,9 @@ PKG_NAME:=ucentral-client PKG_RELEASE:=1 PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-client.git -PKG_MIRROR_HASH:=1ac4e41123dc9717bac880a013eee586a53135cc87220ba6693468f1e6f6fb99 PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-06-22 -PKG_SOURCE_VERSION:=568a84a312ebd8c15ba1fc0ee77f3d309f9c46b0 +PKG_SOURCE_VERSION:=8f5ab3f8fe87cad5c3a6c56463294c946459c725 PKG_LICENSE:=BSD-3-Clause PKG_MAINTAINER:=John Crispin diff --git a/feeds/ucentral/ucentral-event/Makefile b/feeds/ucentral/ucentral-event/Makefile index 308db9af2..0b07d4b81 100644 --- a/feeds/ucentral/ucentral-event/Makefile +++ b/feeds/ucentral/ucentral-event/Makefile @@ -3,34 +3,27 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ucentral-event PKG_RELEASE:=1 -PKG_SOURCE_URL=https://github.com/blogic/ucentral-event.git -PKG_MIRROR_HASH:=8cb470d7cc6c458fe748ee6f54e4bf79bec5500735d7b992d83c1aa10f700c6b -PKG_SOURCE_PROTO:=git -PKG_SOURCE_DATE:=2021-04-13 -PKG_SOURCE_VERSION:=24b7fb36e456d99b470c212674b3bf50bac64c74 - PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause include $(INCLUDE_DIR)/package.mk -include $(INCLUDE_DIR)/cmake.mk define Package/ucentral-event SECTION:=ucentral CATEGORY:=uCentral TITLE:=uCentral event gathering daemon - DEPENDS:=+libubox +libubus +libuci +libblobmsg-json endef -TARGET_CFLAGS += \ - -I$(STAGING_DIR)/usr/include \ - -I$(STAGING_DIR)/usr/include/libnl-tiny +define Build/Compile + +endef define Package/ucentral-event/install $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config - $(INSTALL_BIN) $(PKG_BUILD_DIR)/ucentral-event $(1)/usr/sbin/ - $(INSTALL_BIN) ./files/ucentral-event $(1)/etc/init.d/ + $(INSTALL_BIN) ./files/ucentral-event $(1)/usr/sbin/ + $(INSTALL_BIN) ./files/ucentral-event.init $(1)/etc/init.d/ucentral-event $(INSTALL_DATA) ./files/event $(1)/etc/config/ + $(INSTALL_DATA) ./files/events.json $(1)/etc/ endef $(eval $(call BuildPackage,ucentral-event)) diff --git a/feeds/ucentral/ucentral-event/files/event b/feeds/ucentral/ucentral-event/files/event index d593ea696..d61b3dc2b 100644 --- a/feeds/ucentral/ucentral-event/files/event +++ b/feeds/ucentral/ucentral-event/files/event @@ -1,4 +1,4 @@ -#config event wifi +config event wifi # option type 'wifi' # list filter 'probe' # list filter 'auth' @@ -11,7 +11,7 @@ # list filter 'beacon-report' # list filter 'radar-detected' -#config event dhcp +config event dhcp # option type 'dhcp' # list filter 'ack' # list filter 'discover' @@ -20,3 +20,11 @@ # list filter 'solicit' # list filter 'reply' # list filter 'renew' + +config config config + +config event realtime +# list filter 'client.*' + +config event bulk +# list filter 'ssh' diff --git a/feeds/ucentral/ucentral-event/files/events.json b/feeds/ucentral/ucentral-event/files/events.json new file mode 100644 index 000000000..e82d5cae6 --- /dev/null +++ b/feeds/ucentral/ucentral-event/files/events.json @@ -0,0 +1,6 @@ +[ + "ssh", + "health","healt.dns", "health.dhcp", "health.radius", "health.memory", + "client", "client.join", "client.leave", "client.key-mismatch", + "wifi", "wifi.start", "wifi.stop" +] diff --git a/feeds/ucentral/ucentral-event/files/ucentral-event b/feeds/ucentral/ucentral-event/files/ucentral-event old mode 100644 new mode 100755 index e6e23c933..ec1ac6d2f --- a/feeds/ucentral/ucentral-event/files/ucentral-event +++ b/feeds/ucentral/ucentral-event/files/ucentral-event @@ -1,21 +1,306 @@ -#!/bin/sh /etc/rc.common +#!/usr/bin/ucode -START=80 +'use strict'; -USE_PROCD=1 -PROG=/usr/sbin/ucentral-event +import * as libubus from 'ubus'; +import * as libuci from 'uci'; +import * as uloop from 'uloop'; +import * as nl80211 from 'nl80211'; -service_triggers() { - procd_add_reload_trigger event +let ubus = libubus.connect(); +let uci = libuci.cursor(); + +let hostapd = {}; +let hapd_subscriber; +let dhcp_subscriber; +let log_subscriber; +let ratelimit = false; +let config; +let wan_ports; + +function config_load() { + uci.load('event'); + config = uci.get_all('event'); + wan_ports = config.config?.wan_ports || [ 'eth0' ]; + + if (config.wifi?.filter == '*') + config.wifi.filter = [ 'probe', 'auth', 'assoc', 'disassoc', 'deauth', 'local-deauth', 'inactive-deauth', 'key-mismatch', 'beacon-report', 'radar-detected' ]; + + if (config.dhcp?.filter == '*') + config.dhcp.filter = [ 'ack', 'discover', 'offer', 'request', 'solicit', 'reply', 'renew' ]; } -start_service() { - procd_open_instance - procd_set_param command "$PROG" - procd_set_param respawn - procd_close_instance +function match(object, type, list) { + if (object in list || type in list) + return true; + return false; } -reload_service() { - restart +function event(object, verb, payload) { + let type = object; + if (verb) + type += '.' + verb; + if (match(object, type, config.bulk?.filter)) + ubus.call('ucentral', 'telemetry', { + event: 'event', + payload: { + type, + payload + } + }); + else if (match(object, type, config.realtime?.filter)) + ubus.call('ucentral', 'event', { + type, + payload + }); } + +let handlers = { + 'sta-authorized': function(notify, hapd) { + event('client', 'join', { + client: notify.data.address, + ssid: hapd.ssid, + }); + if (ratelimit) { + let msg = { + device: hapd.ifname, + address: notify.data.address, + }; + if (notify.data['rate-limit']) { + msg.rate_ingress = notify.data['rate-limit'][0] / 1000; + msg.rate_egress = notify.data['rate-limit'][1] / 1000; + } else + msg.defaults = hapd.ssid; + ubus.call('ratelimit', 'client_set', msg); + } + }, + + disassoc: function(notify, hapd) { + if (ratelimit) { + let msg = { + address: notify.data.address, + }; + ubus.call('ratelimit', 'client_delete', msg); + } + }, + + 'key-mismatch': function(notify, hapd) { + event('client', 'key-mismatch', { + client: notify.data.address, + ssid: hapd.ssid, + }); + }, + + vlan_add: function(notify) { + for (let wan in wan_ports) { + let msg = { + name: wan, + vlan: [ `${notify.data.vlan_id}:t` ] + }; + ubus.call('network.interface.up_none', 'add_device', msg); + } + + let msg = { + name: notify.data.ifname, + 'link-ext': true, + vlan: [ `${notify.data.vlan_id}` ] + }; + ubus.call('network.interface.up_none', 'add_device', msg); + }, + + disassoc: function(notify, hapd) { + if (ratelimit) { + let msg = { + address: notify.data.address, + }; + ubus.call('ratelimit', 'client_delete', msg); + } + }, +}; + + +function hapd_subscriber_notify_cb(notify) { + if (config.wifi?.filter == '*' || index(config.wifi?.filter || [], notify.type) > 0) { + let payload = {}; + payload[notify.type] = notify.data; + ubus.call('ucentral', 'telemetry', { + event: 'wifi-frames', + payload + }); + } + if (notify.type == 'probe') + return true; + let handler = handlers[notify.type]; + if (!handler) + return true; + let hapd = hostapd[notify.data.ifname]; + handler(notify, hapd); + + return true; +} + +function hostapd_event(ifname, type) { + let payload = {}; + for (let p in [ 'ssid', 'bssid', 'channel', 'band' ]) + payload[p] = hostapd[ifname][p]; + + event('wifi', type, payload); +} + +function hostapd_add(path, obj) { + let ifname = obj[1]; + + hostapd[ifname] = ubus.call(path, 'get_status'); + hostapd[ifname].ifname = ifname; + hostapd[ifname].path = path; + + if (hostapd[ifname].op_class >= 81 && + hostapd[ifname].op_class <= 84) + hostapd[ifname].band = '2G'; + + else if (hostapd[ifname].op_class >= 115 && + hostapd[ifname].op_class <= 127) + hostapd[ifname].band = '5G'; + + else if (hostapd[ifname].op_class >= 133 && + hostapd[ifname].op_class <= 136) + hostapd[ifname].band = '6G'; + + else + hostapd[ifname].band = 'unknown'; + + hostapd_event(ifname, 'start'); + + printf('adding %s\n', path); + hapd_subscriber.subscribe(path); +} + +function hostapd_remove(path, obj) { + let ifname = obj[1]; + hostapd_event(ifname, 'stop'); + printf('removing %s\n', path); + delete hostapd[ifname]; +} + +function hapd_subscriber_remove_cb(remove) { + printf('remove: %.J\n', remove); +} + +function dhcp_subscriber_notify_cb(notify) { + if (config.dhcp?.filter == '*' || index(config.dhcp?.filter || [], notify.type) > 0) { + notify.data.type = notify.type; + ubus.call('ucentral', 'telemetry', { + event: 'dhcp-snooping', + payload: notify.data, + }); + } +} + +function dhcp_subscriber_remove_cb(remove) { + printf('dhcp remove: %.J\n', remove); +} + +function log_subscriber_notify_cb(notify) { + let msg = split(notify.data.msg, ': ', 2); + let daemon = split(msg[0], '[')[0]; + + switch(daemon) { + case 'dropbear': + event('ssh', '', msg[1]); + break; + } +} + +function log_subscriber_remove_cb(remove) { + printf('dhcp remove: %.J\n', remove); +} + +function unsub_object(add, id, path) { + let object = split(path, '.'); + + switch (path) { + case 'ratelimit': + ratelimit = add; + break; + case 'dhcpsnoop': + printf('adding %s\n', path); + dhcp_subscriber.subscribe(path); + break; + case 'log': + printf('adding %s\n', path); + log_subscriber.subscribe(path); + break; + } + if (object[0] == 'hostapd' && object[1]) { + if (add) + hostapd_add(path, object); + else + hostapd_remove(path, object); + } +} + +function listener_cb(event, payload) { + unsub_object(event == 'ubus.object.add', payload.id, payload.path); +} + +function nl_cb(msg) { + let mac = msg.msg.mac; + let sinfo = msg.msg.sta_info; + let payload = { + client: mac, + tx_bytes: sinfo.tx_bytes64, + rx_bytes: sinfo.rx_bytes64, + tx_packets: sinfo.tx_packets, + rx_packets: sinfo.rx_packets, + connected_time: sinfo.connected_time, + }; + event('client', 'leave', payload); +} + +let ubus_methods = { + event: { + call: function(req) { + if (!req.args.object || !req.args.payload) + return ubus.STATUS_INVALID_ARGUMENT; + + event(req.args.object, req.args.verb, req.args.payload); + return 0; + }, + args: { + object:"", + verb:"", + payload:{}, + } + }, + + reload: { + call: function(req) { + config_load(); + }, + args: { + + } + }, +}; + +uloop.init(); + +config_load(); + +hapd_subscriber = ubus.subscriber(hapd_subscriber_notify_cb, hapd_subscriber_remove_cb); +dhcp_subscriber = ubus.subscriber(dhcp_subscriber_notify_cb, dhcp_subscriber_remove_cb); +log_subscriber = ubus.subscriber(log_subscriber_notify_cb, log_subscriber_remove_cb); + +let list = ubus.list(); +for (let k, path in list) + unsub_object(true, 0, path); + +ubus.listener('ubus.object.add', listener_cb); +ubus.listener('ubus.object.remove', listener_cb); + +ubus.publish("event", ubus_methods); + +let l = nl80211.listener(nl_cb, [ nl80211.const.NL80211_CMD_DEL_STATION ]); + +uloop.run(); +uloop.done(); diff --git a/feeds/ucentral/ucentral-event/files/ucentral-event.init b/feeds/ucentral/ucentral-event/files/ucentral-event.init new file mode 100644 index 000000000..792c1e4de --- /dev/null +++ b/feeds/ucentral/ucentral-event/files/ucentral-event.init @@ -0,0 +1,32 @@ +#!/bin/sh /etc/rc.common + +START=80 + +USE_PROCD=1 +PROG=/usr/sbin/ucentral-event + +service_triggers() { + procd_add_reload_trigger event +} + +reload_service() { + . /lib/functions.sh + config_load 'event' + config_get interval 'bulk' 'interval' 0 + json_init + json_add_int telemetry $interval + ubus call ucentral config "$(json_dump)" + ubus call event reload +} + +start_service() { + procd_open_instance + procd_set_param command "$PROG" + procd_set_param respawn + procd_close_instance +} + +service_started() { + ubus -t 10 wait_for event + [ $? = 0 ] && reload_service +} diff --git a/feeds/ucentral/ucentral-event/git-src b/feeds/ucentral/ucentral-event/git-src deleted file mode 120000 index 2a130417e..000000000 --- a/feeds/ucentral/ucentral-event/git-src +++ /dev/null @@ -1 +0,0 @@ -/ucentral/ucentral-event/.git \ No newline at end of file diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile index 50edc113b..8eea229eb 100644 --- a/feeds/ucentral/ucentral-schema/Makefile +++ b/feeds/ucentral/ucentral-schema/Makefile @@ -4,10 +4,10 @@ PKG_NAME:=ucentral-schema PKG_RELEASE:=1 PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-schema.git -PKG_MIRROR_HASH:=75b74836c8b3897996d9dde6b84c3e95392f24358bec279455477ca4614bbb7b +PKG_MIRROR_HASH:=10913b519ba030f1418c71cbaa83978845abae5c1eda2155d1ac9bb188615da1 PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-05-29 -PKG_SOURCE_VERSION:=f2dd1c63ca8792ebecd370115be58378cd66b551 +PKG_SOURCE_VERSION:=a431b1a5fc0d304c5d387de48bf49c152beb3efa PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause diff --git a/feeds/ucentral/ucentral-schema/files/etc/ucentral/examples/telemetry.json b/feeds/ucentral/ucentral-schema/files/etc/ucentral/examples/telemetry.json new file mode 100644 index 000000000..b200d802d --- /dev/null +++ b/feeds/ucentral/ucentral-schema/files/etc/ucentral/examples/telemetry.json @@ -0,0 +1,96 @@ +{ + "uuid": 2, + "radios": [ + { + "band": "2G", + "country": "CA", + "channel-mode": "HE", + "channel-width": 80, + "channel": 36 + } + ], + + "interfaces": [ + { + "name": "WAN", + "role": "upstream", + "services": [ "lldp", "dhcp-snooping" ], + "ethernet": [ + { + "select-ports": [ + "WAN*" + ] + } + ], + "ipv4": { + "addressing": "dynamic" + }, + "ssids": [ + { + "name": "OpenWifi", + "wifi-bands": [ + "2G" + ], + "bss-mode": "ap", + "encryption": { + "proto": "psk2", + "key": "OpenWifi", + "ieee80211w": "optional" + } + } + ] + }, + { + "name": "LAN", + "role": "downstream", + "services": [ "ssh", "lldp" ], + "ethernet": [ + { + "select-ports": [ + "LAN*" + ] + } + ], + "ipv4": { + "addressing": "static", + "subnet": "192.168.1.1/24", + "dhcp": { + "lease-first": 10, + "lease-count": 100, + "lease-time": "6h" + } + } + } + ], + "metrics": { + "statistics": { + "interval": 120, + "types": [ "ssids", "lldp", "clients" ] + }, + "dhcp-snooping": { + "filters": [ "ack", "discover", "offer", "request", "solicit", "reply", "renew" ] + }, + "wifi-frames": { + "filters": [ "probe", "auth", "assoc", "disassoc", "deauth", "local-deauth", "inactive-deauth", "key-mismatch", "beacon-report", "radar-detected"] + }, + "telemetry": { + "interval": 15, + "types": [ "ssh", "health", "wifi" ] + }, + "realtime": { + "types": [ "client.join", "client.leave", "client.key-mismatch" ] + }, + "health": { + "interval": 120 + } + }, + "services": { + "lldp": { + "describe": "uCentral", + "location": "universe" + }, + "ssh": { + "port": 22 + } + } +} diff --git a/feeds/ucentral/ucentral-schema/files/etc/uci-defaults/99-ucentral-event b/feeds/ucentral/ucentral-schema/files/etc/uci-defaults/99-ucentral-event new file mode 100644 index 000000000..0004442ec --- /dev/null +++ b/feeds/ucentral/ucentral-schema/files/etc/uci-defaults/99-ucentral-event @@ -0,0 +1,7 @@ +#!/bin/sh + +wan=$(cat /etc/board.json | jsonfilter -e '@.network.wan.device') +[ -z "$wan" ] && eval $(jsonfilter -i /etc/board.json -e 'wan=@.network.wan.ports.*') +for w in $wan; do + uci add_list event.config.wan_port=$w +done diff --git a/feeds/ucentral/ucode/Makefile b/feeds/ucentral/ucode/Makefile index 190cd0b32..02a3c584f 100644 --- a/feeds/ucentral/ucode/Makefile +++ b/feeds/ucentral/ucode/Makefile @@ -80,7 +80,7 @@ endef define Package/ucode-mod-nl80211 $(Package/ucode/default) TITLE+= (nl80211 module) - DEPENDS:=ucode +libnl-tiny +kmod-mac80211 + DEPENDS:=ucode +libnl-tiny +kmod-mac80211 +libubox endef define Package/ucode-mod-nl80211/description diff --git a/feeds/ucentral/ucode/patches/0005-nl80211-uploop.patch b/feeds/ucentral/ucode/patches/0005-nl80211-uploop.patch new file mode 100644 index 000000000..68878d1e3 --- /dev/null +++ b/feeds/ucentral/ucode/patches/0005-nl80211-uploop.patch @@ -0,0 +1,164 @@ +From ec167d39b803df4ebdfba0741be8d620e51cd2a7 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Tue, 17 Jan 2023 11:44:26 +0100 +Subject: [PATCH] nl80211: refactor command bitmask handling + +- add missing overflow check +- make array size dynamic +- set all bits if command id is not specified +- add helper function for filling command bits + +Signed-off-by: Felix Fietkau +--- + lib/nl80211.c | 88 +++++++++++++++++++++++++++++---------------------- + 1 file changed, 50 insertions(+), 38 deletions(-) + +diff --git a/lib/nl80211.c b/lib/nl80211.c +index d182d7a..58e49bb 100644 +--- a/lib/nl80211.c ++++ b/lib/nl80211.c +@@ -43,6 +43,8 @@ limitations under the License. + + #include "ucode/module.h" + ++#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) ++ + #define err_return(code, ...) do { set_error(code, __VA_ARGS__); return NULL; } while(0) + + /* Modified downstream nl80211.h headers may disable certain unsupported +@@ -51,6 +53,8 @@ limitations under the License. + + #define NL80211_ATTR_NOT_IMPLEMENTED 0x10000 + ++#define NL80211_CMDS_BITMAP_SIZE DIV_ROUND_UP(NL80211_CMD_MAX + 1, 32) ++ + static struct { + int code; + char *msg; +@@ -2149,7 +2153,7 @@ struct waitfor_ctx { + uint8_t cmd; + uc_vm_t *vm; + uc_value_t *res; +- uint32_t cmds[8]; ++ uint32_t cmds[NL80211_CMDS_BITMAP_SIZE]; + }; + + static int +@@ -2158,28 +2162,25 @@ cb_event(struct nl_msg *msg, void *arg) + struct nlmsghdr *hdr = nlmsg_hdr(msg); + struct genlmsghdr *gnlh = nlmsg_data(hdr); + struct waitfor_ctx *s = arg; +- bool rv, match = true; ++ bool rv; + uc_value_t *o; + +- if (s->cmds[0] || s->cmds[1] || s->cmds[2] || s->cmds[3] || +- s->cmds[4] || s->cmds[5] || s->cmds[6] || s->cmds[7]) { +- match = (s->cmds[gnlh->cmd / 32] & (1 << (gnlh->cmd % 32))); +- } ++ if (gnlh->cmd > NL80211_CMD_MAX || ++ !(s->cmds[gnlh->cmd / 32] & (1 << (gnlh->cmd % 32)))) ++ return NL_SKIP; + +- if (match) { +- o = ucv_object_new(s->vm); ++ o = ucv_object_new(s->vm); + +- rv = uc_nl_convert_attrs(msg, +- genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), +- 0, nl80211_msg.attrs, nl80211_msg.nattrs, s->vm, o); ++ rv = uc_nl_convert_attrs(msg, ++ genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), ++ 0, nl80211_msg.attrs, nl80211_msg.nattrs, s->vm, o); + +- if (rv) +- s->res = o; +- else +- ucv_put(o); ++ if (rv) ++ s->res = o; ++ else ++ ucv_put(o); + +- s->cmd = gnlh->cmd; +- } ++ s->cmd = gnlh->cmd; + + return NL_SKIP; + } +@@ -2190,6 +2191,35 @@ cb_seq(struct nl_msg *msg, void *arg) + return NL_OK; + } + ++static bool ++uc_nl_fill_cmds(uint32_t *cmd_bits, uc_value_t *cmds) ++{ ++ if (ucv_type(cmds) == UC_ARRAY) { ++ for (size_t i = 0; i < ucv_array_length(cmds); i++) { ++ int64_t n = ucv_int64_get(ucv_array_get(cmds, i)); ++ ++ if (errno || n < 0 || n > NL80211_CMD_MAX) ++ return false; ++ ++ cmd_bits[n / 32] |= (1 << (n % 32)); ++ } ++ } ++ else if (ucv_type(cmds) == UC_INTEGER) { ++ int64_t n = ucv_int64_get(cmds); ++ ++ if (errno || n < 0 || n > 255) ++ return false; ++ ++ cmd_bits[n / 32] |= (1 << (n % 32)); ++ } ++ else if (!cmds) ++ memset(cmd_bits, 0xff, NL80211_CMDS_BITMAP_SIZE * sizeof(*cmd_bits)); ++ else ++ return false; ++ ++ return true; ++} ++ + static uc_value_t * + uc_nl_waitfor(uc_vm_t *vm, size_t nargs) + { +@@ -2200,11 +2230,9 @@ uc_nl_waitfor(uc_vm_t *vm, size_t nargs) + struct waitfor_ctx ctx = { .vm = vm }; + struct nl_cb *cb; + int ms = -1, err; +- int64_t n; +- size_t i; + + if (timeout) { +- n = ucv_int64_get(timeout); ++ int64_t n = ucv_int64_get(timeout); + + if (ucv_type(timeout) != UC_INTEGER || n < INT32_MIN || n > INT32_MAX) + err_return(NLE_INVAL, "Invalid timeout specified"); +@@ -2212,24 +2240,8 @@ uc_nl_waitfor(uc_vm_t *vm, size_t nargs) + ms = (int)n; + } + +- if (ucv_type(cmds) == UC_ARRAY) { +- for (i = 0; i < ucv_array_length(cmds); i++) { +- n = ucv_int64_get(ucv_array_get(cmds, i)); +- +- if (n < 0 || n > 255) +- err_return(NLE_INVAL, "Invalid command ID specified"); +- +- ctx.cmds[n / 32] |= (1 << (n % 32)); +- } +- } +- else if (ucv_type(cmds) == UC_INTEGER) { +- n = ucv_int64_get(cmds); +- +- if (n < 0 || n > 255) +- err_return(NLE_INVAL, "Invalid command ID specified"); +- +- ctx.cmds[n / 32] |= (1 << (n % 32)); +- } ++ if (!uc_nl_fill_cmds(ctx.cmds, cmds)) ++ err_return(NLE_INVAL, "Invalid command ID specified"); + + if (!nl80211_conn.evsock) { + if (!uc_nl_connect_sock(&nl80211_conn.evsock, true) || diff --git a/feeds/ucentral/ucode/patches/0006-nl80211-uploop.patch b/feeds/ucentral/ucode/patches/0006-nl80211-uploop.patch new file mode 100644 index 000000000..3b7ebdb4b --- /dev/null +++ b/feeds/ucentral/ucode/patches/0006-nl80211-uploop.patch @@ -0,0 +1,358 @@ +From 6704ec0d5b2923100fda9e2cb7efead7b9836da2 Mon Sep 17 00:00:00 2001 +From: Felix Fietkau +Date: Thu, 19 Jan 2023 11:01:20 +0100 +Subject: [PATCH] nl80211: add support for registering an uloop based listener + +Can be used to capture nl80211 messages in an event driven program + +Signed-off-by: Felix Fietkau +--- + CMakeLists.txt | 3 +- + lib/nl80211.c | 246 +++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 228 insertions(+), 21 deletions(-) + +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 6506b1a..6d76f3a 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -154,13 +154,14 @@ ENDIF() + + IF(NL80211_SUPPORT) + FIND_LIBRARY(nl NAMES nl-tiny) ++ FIND_LIBRARY(ubox NAMES ubox) + FIND_PATH(nl_include_dir NAMES netlink/msg.h PATH_SUFFIXES libnl-tiny) + INCLUDE_DIRECTORIES(${nl_include_dir}) + SET(LIBRARIES ${LIBRARIES} nl80211_lib) + ADD_LIBRARY(nl80211_lib MODULE lib/nl80211.c) + SET_TARGET_PROPERTIES(nl80211_lib PROPERTIES OUTPUT_NAME nl80211 PREFIX "") + TARGET_LINK_OPTIONS(nl80211_lib PRIVATE ${UCODE_MODULE_LINK_OPTIONS}) +- TARGET_LINK_LIBRARIES(nl80211_lib ${nl}) ++ TARGET_LINK_LIBRARIES(nl80211_lib ${nl} ${ubox}) + ENDIF() + + IF(RESOLV_SUPPORT) +diff --git a/lib/nl80211.c b/lib/nl80211.c +index 58e49bb..f3e63bb 100644 +--- a/lib/nl80211.c ++++ b/lib/nl80211.c +@@ -40,6 +40,7 @@ limitations under the License. + + #include + #include ++#include + + #include "ucode/module.h" + +@@ -76,6 +77,15 @@ set_error(int errcode, const char *fmt, ...) { + } + } + ++static uc_resource_type_t *listener_type; ++static uc_value_t *listener_registry; ++static uc_vm_t *listener_vm; ++ ++typedef struct { ++ uint32_t cmds[NL80211_CMDS_BITMAP_SIZE]; ++ size_t index; ++} uc_nl_listener_t; ++ + static bool + uc_nl_parse_u32(uc_value_t *val, uint32_t *n) + { +@@ -1817,6 +1827,8 @@ static struct { + struct nl_cache *cache; + struct genl_family *nl80211; + struct genl_family *nlctrl; ++ struct uloop_fd evsock_fd; ++ struct nl_cb *evsock_cb; + } nl80211_conn; + + typedef enum { +@@ -2156,29 +2168,90 @@ struct waitfor_ctx { + uint32_t cmds[NL80211_CMDS_BITMAP_SIZE]; + }; + ++static uc_value_t * ++uc_nl_prepare_event(uc_vm_t *vm, struct nl_msg *msg) ++{ ++ struct nlmsghdr *hdr = nlmsg_hdr(msg); ++ struct genlmsghdr *gnlh = nlmsg_data(hdr); ++ uc_value_t *o = ucv_object_new(vm); ++ ++ if (!uc_nl_convert_attrs(msg, genlmsg_attrdata(gnlh, 0), ++ genlmsg_attrlen(gnlh, 0), 0, ++ nl80211_msg.attrs, nl80211_msg.nattrs, vm, o)) { ++ ucv_put(o); ++ return NULL; ++ } ++ ++ return o; ++} ++ ++static int ++cb_listener_event(struct nl_msg *msg, void *arg) ++{ ++ struct nlmsghdr *hdr = nlmsg_hdr(msg); ++ struct genlmsghdr *gnlh = nlmsg_data(hdr); ++ uc_vm_t *vm = listener_vm; ++ ++ if (!nl80211_conn.evsock_fd.registered || !vm) ++ return NL_SKIP; ++ ++ for (size_t i = 0; i < ucv_array_length(listener_registry); i += 2) { ++ uc_value_t *this = ucv_array_get(listener_registry, i); ++ uc_value_t *func = ucv_array_get(listener_registry, i + 1); ++ uc_nl_listener_t *l; ++ uc_value_t *o, *data; ++ ++ l = ucv_resource_data(this, "nl80211.listener"); ++ if (!l) ++ continue; ++ ++ if (gnlh->cmd > NL80211_CMD_MAX || ++ !(l->cmds[gnlh->cmd / 32] & (1 << (gnlh->cmd % 32)))) ++ continue; ++ ++ if (!ucv_is_callable(func)) ++ continue; ++ ++ data = uc_nl_prepare_event(vm, msg); ++ if (!data) ++ return NL_SKIP; ++ ++ o = ucv_object_new(vm); ++ ucv_object_add(o, "cmd", ucv_int64_new(gnlh->cmd)); ++ ucv_object_add(o, "msg", data); ++ ++ uc_vm_stack_push(vm, ucv_get(this)); ++ uc_vm_stack_push(vm, ucv_get(func)); ++ uc_vm_stack_push(vm, o); ++ ++ if (uc_vm_call(vm, true, 1) != EXCEPTION_NONE) { ++ uloop_end(); ++ return NL_STOP; ++ } ++ ++ ucv_put(uc_vm_stack_pop(vm)); ++ } ++ ++ return NL_SKIP; ++} ++ + static int + cb_event(struct nl_msg *msg, void *arg) + { + struct nlmsghdr *hdr = nlmsg_hdr(msg); + struct genlmsghdr *gnlh = nlmsg_data(hdr); + struct waitfor_ctx *s = arg; +- bool rv; + uc_value_t *o; + ++ cb_listener_event(msg, arg); ++ + if (gnlh->cmd > NL80211_CMD_MAX || + !(s->cmds[gnlh->cmd / 32] & (1 << (gnlh->cmd % 32)))) + return NL_SKIP; + +- o = ucv_object_new(s->vm); +- +- rv = uc_nl_convert_attrs(msg, +- genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), +- 0, nl80211_msg.attrs, nl80211_msg.nattrs, s->vm, o); +- +- if (rv) ++ o = uc_nl_prepare_event(s->vm, msg); ++ if (o) + s->res = o; +- else +- ucv_put(o); + + s->cmd = gnlh->cmd; + +@@ -2220,6 +2293,29 @@ uc_nl_fill_cmds(uint32_t *cmd_bits, uc_value_t *cmds) + return true; + } + ++static bool ++uc_nl_evsock_init(void) ++{ ++ if (nl80211_conn.evsock) ++ return true; ++ ++ if (!uc_nl_connect_sock(&nl80211_conn.evsock, true)) ++ return false; ++ ++ if (!uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "config") || ++ !uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "scan") || ++ !uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "regulatory") || ++ !uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "mlme") || ++ !uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "vendor") || ++ !uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "nan")) { ++ nl_socket_free(nl80211_conn.evsock); ++ nl80211_conn.evsock = NULL; ++ return false; ++ } ++ ++ return true; ++} ++ + static uc_value_t * + uc_nl_waitfor(uc_vm_t *vm, size_t nargs) + { +@@ -2243,16 +2339,8 @@ uc_nl_waitfor(uc_vm_t *vm, size_t nargs) + if (!uc_nl_fill_cmds(ctx.cmds, cmds)) + err_return(NLE_INVAL, "Invalid command ID specified"); + +- if (!nl80211_conn.evsock) { +- if (!uc_nl_connect_sock(&nl80211_conn.evsock, true) || +- !uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "config") || +- !uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "scan") || +- !uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "regulatory") || +- !uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "mlme") || +- !uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "vendor") || +- !uc_nl_subscribe(nl80211_conn.evsock, "nl80211", "nan")) +- return NULL; +- } ++ if (!uc_nl_evsock_init()) ++ return NULL; + + cb = nl_cb_alloc(NL_CB_DEFAULT); + +@@ -2380,6 +2468,113 @@ uc_nl_request(uc_vm_t *vm, size_t nargs) + } + } + ++static void ++uc_nl_listener_cb(struct uloop_fd *fd, unsigned int events) ++{ ++ nl_recvmsgs(nl80211_conn.evsock, nl80211_conn.evsock_cb); ++} ++ ++static uc_value_t * ++uc_nl_listener(uc_vm_t *vm, size_t nargs) ++{ ++ struct uloop_fd *fd = &nl80211_conn.evsock_fd; ++ uc_nl_listener_t *l; ++ uc_value_t *cb_func = uc_fn_arg(0); ++ uc_value_t *cmds = uc_fn_arg(1); ++ uc_value_t *rv; ++ size_t i; ++ ++ if (!ucv_is_callable(cb_func)) { ++ uc_vm_raise_exception(vm, EXCEPTION_TYPE, "Invalid callback"); ++ return NULL; ++ } ++ ++ if (!uc_nl_evsock_init()) ++ return NULL; ++ ++ if (!fd->registered) { ++ fd->fd = nl_socket_get_fd(nl80211_conn.evsock); ++ fd->cb = uc_nl_listener_cb; ++ uloop_fd_add(fd, ULOOP_READ); ++ } ++ ++ if (!nl80211_conn.evsock_cb) { ++ struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT); ++ ++ if (!cb) ++ err_return(NLE_NOMEM, NULL); ++ ++ nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, cb_seq, NULL); ++ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cb_listener_event, NULL); ++ nl80211_conn.evsock_cb = cb; ++ } ++ ++ for (i = 0; i < ucv_array_length(listener_registry); i += 2) { ++ if (!ucv_array_get(listener_registry, i)) ++ break; ++ } ++ ++ ucv_array_set(listener_registry, i + 1, cb_func); ++ l = xalloc(sizeof(*l)); ++ l->index = i; ++ if (!uc_nl_fill_cmds(l->cmds, cmds)) { ++ uc_vm_raise_exception(vm, EXCEPTION_TYPE, "Invalid command ID"); ++ free(l); ++ return NULL; ++ } ++ ++ rv = uc_resource_new(listener_type, l); ++ ucv_array_set(listener_registry, i, rv); ++ listener_vm = vm; ++ ++ return rv; ++} ++ ++static void ++uc_nl_listener_free(void *arg) ++{ ++ uc_nl_listener_t *l = arg; ++ ++ ucv_array_set(listener_registry, l->index, NULL); ++ ucv_array_set(listener_registry, l->index + 1, NULL); ++ free(l); ++} ++ ++static uc_value_t * ++uc_nl_listener_set_commands(uc_vm_t *vm, size_t nargs) ++{ ++ uc_nl_listener_t *l = uc_fn_thisval("nl80211.listener"); ++ uc_value_t *cmds = uc_fn_arg(0); ++ ++ if (!l) ++ return NULL; ++ ++ memset(l->cmds, 0, sizeof(l->cmds)); ++ if (!uc_nl_fill_cmds(l->cmds, cmds)) ++ uc_vm_raise_exception(vm, EXCEPTION_TYPE, "Invalid command ID"); ++ ++ return NULL; ++} ++ ++static uc_value_t * ++uc_nl_listener_close(uc_vm_t *vm, size_t nargs) ++{ ++ uc_nl_listener_t **lptr = uc_fn_this("nl80211.listener"); ++ uc_nl_listener_t *l; ++ ++ if (!lptr) ++ return NULL; ++ ++ l = *lptr; ++ if (!l) ++ return NULL; ++ ++ *lptr = NULL; ++ uc_nl_listener_free(l); ++ ++ return NULL; ++} ++ + + static void + register_constants(uc_vm_t *vm, uc_value_t *scope) +@@ -2530,12 +2725,23 @@ static const uc_function_list_t global_fns[] = { + { "error", uc_nl_error }, + { "request", uc_nl_request }, + { "waitfor", uc_nl_waitfor }, ++ { "listener", uc_nl_listener }, + }; + + ++static const uc_function_list_t listener_fns[] = { ++ { "set_commands", uc_nl_listener_set_commands }, ++ { "close", uc_nl_listener_close }, ++}; ++ + void uc_module_init(uc_vm_t *vm, uc_value_t *scope) + { + uc_function_list_register(scope, global_fns); + ++ listener_type = uc_type_declare(vm, "nl80211.listener", listener_fns, uc_nl_listener_free); ++ listener_registry = ucv_array_new(vm); ++ ++ uc_vm_registry_set(vm, "nl80211.registry", listener_registry); ++ + register_constants(vm, scope); + } diff --git a/feeds/wifi-ax/hostapd/patches/600-ubus_support.patch b/feeds/wifi-ax/hostapd/patches/600-ubus_support.patch index 6a0acbb31..0c80c82b2 100644 --- a/feeds/wifi-ax/hostapd/patches/600-ubus_support.patch +++ b/feeds/wifi-ax/hostapd/patches/600-ubus_support.patch @@ -1,5 +1,7 @@ ---- a/hostapd/Makefile -+++ b/hostapd/Makefile +Index: hostapd-2021-02-20-59e9794c/hostapd/Makefile +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/hostapd/Makefile ++++ hostapd-2021-02-20-59e9794c/hostapd/Makefile @@ -166,6 +166,11 @@ OBJS += ../src/common/hw_features_common OBJS += ../src/eapol_auth/eapol_auth_sm.o @@ -12,8 +14,10 @@ ifdef CONFIG_CODE_COVERAGE CFLAGS += -O0 -fprofile-arcs -ftest-coverage ---- a/src/ap/hostapd.h -+++ b/src/ap/hostapd.h +Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.h ++++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.h @@ -17,6 +17,7 @@ #include "utils/list.h" #include "ap_config.h" @@ -31,7 +35,7 @@ }; enum hostapd_chan_status { -@@ -171,6 +172,7 @@ struct hostapd_data { +@@ -169,6 +170,7 @@ struct hostapd_data { struct hostapd_iface *iface; struct hostapd_config *iconf; struct hostapd_bss_config *conf; @@ -39,7 +43,7 @@ int interface_added; /* virtual interface added for this BSS */ unsigned int started:1; unsigned int disabled:1; -@@ -630,6 +632,7 @@ hostapd_alloc_bss_data(struct hostapd_if +@@ -626,6 +628,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); @@ -47,9 +51,11 @@ 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 -+++ b/src/ap/hostapd.c -@@ -396,6 +396,7 @@ void hostapd_free_hapd_data(struct hosta +Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c ++++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c +@@ -395,6 +395,7 @@ void hostapd_free_hapd_data(struct hosta hapd->beacon_set_done = 0; wpa_printf(MSG_DEBUG, "%s(%s)", __func__, hapd->conf->iface); @@ -57,7 +63,7 @@ accounting_deinit(hapd); hostapd_deinit_wpa(hapd); vlan_deinit(hapd); -@@ -1422,6 +1423,8 @@ static int hostapd_setup_bss(struct host +@@ -1417,6 +1418,8 @@ static int hostapd_setup_bss(struct host if (hapd->driver && hapd->driver->set_operstate) hapd->driver->set_operstate(hapd->drv_priv, 1); @@ -66,7 +72,7 @@ return 0; } -@@ -2028,6 +2031,7 @@ static int hostapd_setup_interface_compl +@@ -2002,6 +2005,7 @@ static int hostapd_setup_interface_compl if (err) goto fail; @@ -74,7 +80,7 @@ wpa_printf(MSG_DEBUG, "Completing interface initialization"); if (iface->freq) { #ifdef NEED_AP_MLME -@@ -2225,6 +2229,7 @@ dfs_offload: +@@ -2199,6 +2203,7 @@ dfs_offload: fail: wpa_printf(MSG_ERROR, "Interface initialization failed"); @@ -82,7 +88,7 @@ hostapd_set_state(iface, HAPD_IFACE_DISABLED); wpa_msg(hapd->msg_ctx, MSG_INFO, AP_EVENT_DISABLED); #ifdef CONFIG_FST -@@ -2700,6 +2705,7 @@ void hostapd_interface_deinit_free(struc +@@ -2672,6 +2677,7 @@ void hostapd_interface_deinit_free(struc (unsigned int) iface->conf->num_bss); driver = iface->bss[0]->driver; drv_priv = iface->bss[0]->drv_priv; @@ -90,9 +96,11 @@ hostapd_interface_deinit(iface); wpa_printf(MSG_DEBUG, "%s: driver=%p drv_priv=%p -> hapd_deinit", __func__, driver, drv_priv); ---- a/src/ap/ieee802_11.c -+++ b/src/ap/ieee802_11.c -@@ -3553,13 +3553,18 @@ static void handle_auth(struct hostapd_d +Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/ieee802_11.c ++++ hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c +@@ -3421,13 +3421,18 @@ static void handle_auth(struct hostapd_d u16 auth_alg, auth_transaction, status_code; u16 resp = WLAN_STATUS_SUCCESS; struct sta_info *sta = NULL; @@ -112,7 +120,7 @@ if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) { wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)", -@@ -3727,6 +3732,13 @@ static void handle_auth(struct hostapd_d +@@ -3595,6 +3600,13 @@ static void handle_auth(struct hostapd_d resp = WLAN_STATUS_UNSPECIFIED_FAILURE; goto fail; } @@ -126,7 +134,7 @@ if (res == HOSTAPD_ACL_PENDING) return; -@@ -5447,7 +5459,7 @@ static void handle_assoc(struct hostapd_ +@@ -5322,7 +5334,7 @@ static void handle_assoc(struct hostapd_ int resp = WLAN_STATUS_SUCCESS; u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE; const u8 *pos; @@ -135,7 +143,7 @@ struct sta_info *sta; u8 *tmp = NULL; #ifdef CONFIG_FILS -@@ -5660,6 +5672,11 @@ static void handle_assoc(struct hostapd_ +@@ -5535,6 +5547,11 @@ static void handle_assoc(struct hostapd_ left = res; } #endif /* CONFIG_FILS */ @@ -147,7 +155,7 @@ /* followed by SSID and Supported rates; and HT capabilities if 802.11n * is used */ -@@ -5758,6 +5775,13 @@ static void handle_assoc(struct hostapd_ +@@ -5633,6 +5650,13 @@ static void handle_assoc(struct hostapd_ } #endif /* CONFIG_FILS */ @@ -161,7 +169,7 @@ fail: /* -@@ -5851,6 +5875,7 @@ static void handle_disassoc(struct hosta +@@ -5726,6 +5750,7 @@ static void handle_disassoc(struct hosta wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d", MAC2STR(mgmt->sa), le_to_host16(mgmt->u.disassoc.reason_code)); @@ -169,18 +177,20 @@ sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { -@@ -5920,6 +5945,8 @@ static void handle_deauth(struct hostapd - /* Clear the PTKSA cache entries for PASN */ - ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE); +@@ -5792,6 +5817,8 @@ static void handle_deauth(struct hostapd + " reason_code=%d", + MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code)); + hostapd_ubus_notify(hapd, "deauth", mgmt->sa); + sta = ap_get_sta(hapd, mgmt->sa); if (sta == NULL) { wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying " ---- a/src/ap/beacon.c -+++ b/src/ap/beacon.c -@@ -852,6 +852,12 @@ void handle_probe_req(struct hostapd_dat +Index: hostapd-2021-02-20-59e9794c/src/ap/beacon.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/beacon.c ++++ hostapd-2021-02-20-59e9794c/src/ap/beacon.c +@@ -823,6 +823,12 @@ void handle_probe_req(struct hostapd_dat u16 csa_offs[2]; size_t csa_offs_len; struct radius_sta rad_info; @@ -193,7 +203,7 @@ if (hapd->iconf->rssi_ignore_probe_request && ssi_signal && ssi_signal < hapd->iconf->rssi_ignore_probe_request) -@@ -1038,6 +1044,12 @@ void handle_probe_req(struct hostapd_dat +@@ -1009,6 +1015,12 @@ void handle_probe_req(struct hostapd_dat } #endif /* CONFIG_P2P */ @@ -206,8 +216,10 @@ /* TODO: verify that supp_rates contains at least one matching rate * with AP configuration */ ---- a/src/ap/drv_callbacks.c -+++ b/src/ap/drv_callbacks.c +Index: hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/drv_callbacks.c ++++ hostapd-2021-02-20-59e9794c/src/ap/drv_callbacks.c @@ -145,6 +145,10 @@ int hostapd_notif_assoc(struct hostapd_d u16 reason = WLAN_REASON_UNSPECIFIED; int status = WLAN_STATUS_SUCCESS; @@ -232,8 +244,10 @@ #ifdef CONFIG_P2P if (elems.p2p) { wpabuf_free(sta->p2p_ie); ---- a/src/ap/sta_info.c -+++ b/src/ap/sta_info.c +Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.c ++++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.c @@ -458,6 +458,7 @@ void ap_handle_timer(void *eloop_ctx, vo hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_INFO, "deauthenticated due to " @@ -250,7 +264,15 @@ ap_free_sta(hapd, sta); break; } -@@ -1329,6 +1331,7 @@ void ap_sta_set_authorized(struct hostap +@@ -1319,6 +1321,7 @@ void ap_sta_set_authorized(struct hostap + " keyid=%s", keyid); + } + ++ hostapd_ubus_notify_authorized(hapd, sta); + wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_CONNECTED "%s%s%s", + buf, ip_addr, keyid_buf); + +@@ -1329,6 +1332,7 @@ void ap_sta_set_authorized(struct hostap buf, ip_addr, keyid_buf); } else { wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED "%s", buf); @@ -258,8 +280,10 @@ if (hapd->msg_ctx_parent && hapd->msg_ctx_parent != hapd->msg_ctx) ---- a/src/ap/wpa_auth_glue.c -+++ b/src/ap/wpa_auth_glue.c +Index: hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_glue.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/wpa_auth_glue.c ++++ hostapd-2021-02-20-59e9794c/src/ap/wpa_auth_glue.c @@ -265,6 +265,7 @@ static void hostapd_wpa_auth_psk_failure struct hostapd_data *hapd = ctx; wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POSSIBLE_PSK_MISMATCH MACSTR, @@ -268,9 +292,11 @@ } ---- a/wpa_supplicant/Makefile -+++ b/wpa_supplicant/Makefile -@@ -176,6 +176,12 @@ ifdef CONFIG_EAPOL_TEST +Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/Makefile ++++ hostapd-2021-02-20-59e9794c/wpa_supplicant/Makefile +@@ -171,6 +171,12 @@ ifdef CONFIG_EAPOL_TEST CFLAGS += -Werror -DEAPOL_TEST endif @@ -283,7 +309,7 @@ ifdef CONFIG_CODE_COVERAGE CFLAGS += -O0 -fprofile-arcs -ftest-coverage LIBS += -lgcov -@@ -962,6 +968,9 @@ ifdef CONFIG_CTRL_IFACE_MIB +@@ -948,6 +954,9 @@ ifdef CONFIG_CTRL_IFACE_MIB CFLAGS += -DCONFIG_CTRL_IFACE_MIB endif OBJS += ../src/ap/ctrl_iface_ap.o @@ -293,9 +319,11 @@ endif CFLAGS += -DEAP_SERVER -DEAP_SERVER_IDENTITY ---- a/wpa_supplicant/wpa_supplicant.c -+++ b/wpa_supplicant/wpa_supplicant.c -@@ -7241,6 +7241,8 @@ struct wpa_supplicant * wpa_supplicant_a +Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c ++++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c +@@ -7012,6 +7012,8 @@ struct wpa_supplicant * wpa_supplicant_a } #endif /* CONFIG_P2P */ @@ -304,7 +332,7 @@ return wpa_s; } -@@ -7267,6 +7269,8 @@ int wpa_supplicant_remove_iface(struct w +@@ -7038,6 +7040,8 @@ int wpa_supplicant_remove_iface(struct w struct wpa_supplicant *parent = wpa_s->parent; #endif /* CONFIG_MESH */ @@ -313,7 +341,7 @@ /* Remove interface from the global list of interfaces */ prev = global->ifaces; if (prev == wpa_s) { -@@ -7570,8 +7574,12 @@ int wpa_supplicant_run(struct wpa_global +@@ -7341,8 +7345,12 @@ int wpa_supplicant_run(struct wpa_global eloop_register_signal_terminate(wpa_supplicant_terminate, global); eloop_register_signal_reconfig(wpa_supplicant_reconfig, global); @@ -326,8 +354,10 @@ return 0; } ---- a/wpa_supplicant/wpa_supplicant_i.h -+++ b/wpa_supplicant/wpa_supplicant_i.h +Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant_i.h ++++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant_i.h @@ -19,6 +19,7 @@ #include "wps/wps_defs.h" #include "config_ssid.h" @@ -336,7 +366,7 @@ extern const char *const wpa_supplicant_version; extern const char *const wpa_supplicant_license; -@@ -322,6 +323,8 @@ struct wpa_global { +@@ -321,6 +322,8 @@ struct wpa_global { #endif /* CONFIG_WIFI_DISPLAY */ struct psk_list_entry *add_psk; /* From group formation */ @@ -345,7 +375,7 @@ }; -@@ -708,6 +711,7 @@ struct wpa_supplicant { +@@ -601,6 +604,7 @@ struct wpa_supplicant { unsigned char own_addr[ETH_ALEN]; unsigned char perm_addr[ETH_ALEN]; char ifname[100]; @@ -353,8 +383,10 @@ #ifdef CONFIG_MATCH_IFACE int matched; #endif /* CONFIG_MATCH_IFACE */ ---- a/wpa_supplicant/wps_supplicant.c -+++ b/wpa_supplicant/wps_supplicant.c +Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wps_supplicant.c ++++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wps_supplicant.c @@ -33,6 +33,7 @@ #include "p2p/p2p.h" #include "p2p_supplicant.h" @@ -363,7 +395,7 @@ #ifndef WPS_PIN_SCAN_IGNORE_SEL_REG -@@ -393,6 +394,8 @@ static int wpa_supplicant_wps_cred(void +@@ -392,6 +393,8 @@ static int wpa_supplicant_wps_cred(void wpa_hexdump_key(MSG_DEBUG, "WPS: Received Credential attribute", cred->cred_attr, cred->cred_attr_len); @@ -372,8 +404,10 @@ if (wpa_s->conf->wps_cred_processing == 1) return 0; ---- a/hostapd/main.c -+++ b/hostapd/main.c +Index: hostapd-2021-02-20-59e9794c/hostapd/main.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/hostapd/main.c ++++ hostapd-2021-02-20-59e9794c/hostapd/main.c @@ -895,6 +895,7 @@ int main(int argc, char *argv[]) } @@ -390,8 +424,10 @@ hostapd_global_ctrl_iface_deinit(&interfaces); /* Deinitialize all interfaces */ for (i = 0; i < interfaces.count; i++) { ---- a/wpa_supplicant/main.c -+++ b/wpa_supplicant/main.c +Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/main.c ++++ hostapd-2021-02-20-59e9794c/wpa_supplicant/main.c @@ -203,7 +203,7 @@ int main(int argc, char *argv[]) for (;;) { @@ -411,8 +447,10 @@ case 'o': params.override_driver = optarg; break; ---- a/src/ap/rrm.c -+++ b/src/ap/rrm.c +Index: hostapd-2021-02-20-59e9794c/src/ap/rrm.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/rrm.c ++++ hostapd-2021-02-20-59e9794c/src/ap/rrm.c @@ -89,6 +89,9 @@ static void hostapd_handle_beacon_report return; wpa_msg(hapd->msg_ctx, MSG_INFO, BEACON_RESP_RX MACSTR " %u %02x %s", @@ -423,8 +461,10 @@ } ---- a/src/ap/vlan_init.c -+++ b/src/ap/vlan_init.c +Index: hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/vlan_init.c ++++ hostapd-2021-02-20-59e9794c/src/ap/vlan_init.c @@ -22,6 +22,7 @@ static int vlan_if_add(struct hostapd_data *hapd, struct hostapd_vlan *vlan, int existsok) @@ -461,9 +501,11 @@ return hostapd_vlan_if_remove(hapd, vlan->ifname); } ---- a/src/ap/dfs.c -+++ b/src/ap/dfs.c -@@ -1196,6 +1196,8 @@ int hostapd_dfs_radar_detected(struct ho +Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/dfs.c ++++ hostapd-2021-02-20-59e9794c/src/ap/dfs.c +@@ -1193,6 +1193,8 @@ int hostapd_dfs_radar_detected(struct ho "freq=%d ht_enabled=%d chan_offset=%d chan_width=%d cf1=%d cf2=%d", freq, ht_enabled, chan_offset, chan_width, cf1, cf2); @@ -472,9 +514,11 @@ /* Proceed only if DFS is not offloaded to the driver */ if (iface->drv_flags & WPA_DRIVER_FLAGS_DFS_OFFLOAD) return 0; ---- a/src/ap/airtime_policy.c -+++ b/src/ap/airtime_policy.c -@@ -112,8 +112,14 @@ static void set_sta_weights(struct hosta +Index: hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/airtime_policy.c ++++ hostapd-2021-02-20-59e9794c/src/ap/airtime_policy.c +@@ -108,8 +108,14 @@ static void set_sta_weights(struct hosta { struct sta_info *sta; @@ -491,7 +535,7 @@ } -@@ -244,7 +250,10 @@ int airtime_policy_new_sta(struct hostap +@@ -240,7 +246,10 @@ int airtime_policy_new_sta(struct hostap unsigned int weight; if (hapd->iconf->airtime_mode == AIRTIME_MODE_STATIC) { @@ -503,9 +547,11 @@ if (weight) return sta_set_airtime_weight(hapd, sta, weight); } ---- a/src/ap/sta_info.h -+++ b/src/ap/sta_info.h -@@ -324,6 +324,7 @@ struct sta_info { +Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.h +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.h ++++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.h +@@ -323,6 +323,7 @@ struct sta_info { #endif /* CONFIG_TESTING_OPTIONS */ #ifdef CONFIG_AIRTIME_POLICY unsigned int airtime_weight; @@ -513,8 +559,10 @@ struct os_reltime backlogged_until; #endif /* CONFIG_AIRTIME_POLICY */ ---- a/src/ap/wnm_ap.c -+++ b/src/ap/wnm_ap.c +Index: hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c +=================================================================== +--- hostapd-2021-02-20-59e9794c.orig/src/ap/wnm_ap.c ++++ hostapd-2021-02-20-59e9794c/src/ap/wnm_ap.c @@ -442,7 +442,8 @@ static void ieee802_11_rx_bss_trans_mgmt wpa_hexdump(MSG_DEBUG, "WNM: BSS Transition Candidate List Entries", pos, end - pos); diff --git a/feeds/wifi-ax/hostapd/patches/750-wispr.patch b/feeds/wifi-ax/hostapd/patches/750-wispr.patch index d5772a4c0..59537cede 100644 --- a/feeds/wifi-ax/hostapd/patches/750-wispr.patch +++ b/feeds/wifi-ax/hostapd/patches/750-wispr.patch @@ -111,16 +111,3 @@ Index: hostapd-2021-02-20-59e9794c/src/radius/radius.h int radius_msg_add_mppe_keys(struct radius_msg *msg, const u8 *req_authenticator, const u8 *secret, size_t secret_len, -Index: hostapd-2021-02-20-59e9794c/src/ap/sta_info.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/ap/sta_info.c -+++ hostapd-2021-02-20-59e9794c/src/ap/sta_info.c -@@ -1292,7 +1292,7 @@ void ap_sta_set_authorized(struct hostap - MAC2STR(sta->addr), MAC2STR(dev_addr)); - else - #endif /* CONFIG_P2P */ -- os_snprintf(buf, sizeof(buf), MACSTR, MAC2STR(sta->addr)); -+ os_snprintf(buf, sizeof(buf), MACSTR " %d %d", MAC2STR(sta->addr), sta->bandwidth[0] / 1000000, sta->bandwidth[1] / 1000000); - - if (hapd->sta_authorized_cb) - hapd->sta_authorized_cb(hapd->sta_authorized_cb_ctx, diff --git a/feeds/wifi-ax/hostapd/src/src/ap/ubus.c b/feeds/wifi-ax/hostapd/src/src/ap/ubus.c index fdc2a3fd2..9c770ccaa 100644 --- a/feeds/wifi-ax/hostapd/src/src/ap/ubus.c +++ b/feeds/wifi-ax/hostapd/src/src/ap/ubus.c @@ -1843,10 +1843,24 @@ void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 * blob_buf_init(&b, 0); blobmsg_add_macaddr(&b, "address", addr); + blobmsg_add_string(&b, "ifname", hapd->conf->iface); ubus_notify(ctx, &hapd->ubus.obj, type, b.head, -1); } + +void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta) +{ + if (!hapd->ubus.obj.has_subscribers) + return; + + blob_buf_init(&b, 0); + blobmsg_add_macaddr(&b, "address", sta->addr); + blobmsg_add_string(&b, "ifname", hapd->conf->iface); + + ubus_notify(ctx, &hapd->ubus.obj, "sta-authorized", b.head, -1); +} + void hostapd_ubus_notify_beacon_report( struct hostapd_data *hapd, const u8 *addr, u8 token, u8 rep_mode, struct rrm_measurement_beacon_report *rep, size_t len) diff --git a/feeds/wifi-ax/hostapd/src/src/ap/ubus.h b/feeds/wifi-ax/hostapd/src/src/ap/ubus.h index f1bc093e5..af48a0964 100644 --- a/feeds/wifi-ax/hostapd/src/src/ap/ubus.h +++ b/feeds/wifi-ax/hostapd/src/src/ap/ubus.h @@ -48,6 +48,7 @@ void hostapd_ubus_remove_vlan(struct hostapd_data *hapd, struct hostapd_vlan *vl int hostapd_ubus_handle_event(struct hostapd_data *hapd, struct hostapd_ubus_request *req); void hostapd_ubus_notify(struct hostapd_data *hapd, const char *type, const u8 *mac); +void hostapd_ubus_notify_authorized(struct hostapd_data *hapd, struct sta_info *sta); void hostapd_ubus_notify_beacon_report(struct hostapd_data *hapd, const u8 *addr, u8 token, u8 rep_mode, struct rrm_measurement_beacon_report *rep, diff --git a/patches/base/0028-ubox-update-to-latest-HEAD.patch b/patches/base/0028-ubox-update-to-latest-HEAD.patch new file mode 100644 index 000000000..605eb0f5d --- /dev/null +++ b/patches/base/0028-ubox-update-to-latest-HEAD.patch @@ -0,0 +1,29 @@ +From b2cea8e521532dfa4f4156933bbd0f2a8c560644 Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Mon, 23 Jan 2023 11:58:34 +0100 +Subject: [PATCH] ubox: update to latest HEAD + +Signed-off-by: John Crispin +--- + package/system/ubox/Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/package/system/ubox/Makefile b/package/system/ubox/Makefile +index 9ba4abdd58..766ca1c2e7 100644 +--- a/package/system/ubox/Makefile ++++ b/package/system/ubox/Makefile +@@ -5,9 +5,9 @@ PKG_RELEASE:=2 + + PKG_SOURCE_PROTO:=git + PKG_SOURCE_URL=$(PROJECT_GIT)/project/ubox.git ++PKG_MIRROR_HASH:=aeabb4f0b0bb163fa62e2672cb3f0fd0bed3622bd7ad95d13a36e00978b4f864 + PKG_SOURCE_DATE:=2020-10-25 +-PKG_SOURCE_VERSION:=9ef886819dd48303d8ced4cdbc9afbf32682535c +-PKG_MIRROR_HASH:=e2d93b798b91de98cb003f7b3be97d3d8a2413c8612b527d096c86ac5365cbdd ++PKG_SOURCE_VERSION:=cc34fb7b922f183e6ece5fa0fec31d4eb95c5823 + CMAKE_INSTALL:=1 + + PKG_LICENSE:=GPL-2.0 +-- +2.34.1 +