initial events support

Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
John Crispin
2023-01-23 09:23:20 +01:00
parent 0e75b82eb6
commit fbcfddfbdc
24 changed files with 1144 additions and 206 deletions

View File

@@ -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 <john@phrozen.org>
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))

View File

@@ -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
}

View File

@@ -1 +0,0 @@
/ucentral/dynamic-vlan/.git

View File

@@ -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
}

View File

@@ -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

View File

@@ -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

View File

@@ -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 <john@phrozen.org>

View File

@@ -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 <john@phrozen.org>
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))

View File

@@ -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'

View File

@@ -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"
]

311
feeds/ucentral/ucentral-event/files/ucentral-event Normal file → Executable file
View File

@@ -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();

View File

@@ -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
}

View File

@@ -1 +0,0 @@
/ucentral/ucentral-event/.git

View File

@@ -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 <john@phrozen.org>
PKG_LICENSE:=BSD-3-Clause

View File

@@ -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
}
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,164 @@
From ec167d39b803df4ebdfba0741be8d620e51cd2a7 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
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 <nbd@nbd.name>
---
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) ||

View File

@@ -0,0 +1,358 @@
From 6704ec0d5b2923100fda9e2cb7efead7b9836da2 Mon Sep 17 00:00:00 2001
From: Felix Fietkau <nbd@nbd.name>
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 <nbd@nbd.name>
---
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 <linux/nl80211.h>
#include <linux/ieee80211.h>
+#include <libubox/uloop.h>
#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);
}

View File

@@ -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);

View File

@@ -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,

View File

@@ -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)

View File

@@ -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,

View File

@@ -0,0 +1,29 @@
From b2cea8e521532dfa4f4156933bbd0f2a8c560644 Mon Sep 17 00:00:00 2001
From: John Crispin <john@phrozen.org>
Date: Mon, 23 Jan 2023 11:58:34 +0100
Subject: [PATCH] ubox: update to latest HEAD
Signed-off-by: John Crispin <john@phrozen.org>
---
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