From d6b3e97c34d94bb78b894eab4c5c435f1f6f09ff Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 12 Dec 2022 07:44:17 +0100 Subject: [PATCH 01/14] ucentral-schema: update to latest HEAD 195ed80 fix multicast to unicast conversion on wifi Fixes: WIFI-11550 Signed-off-by: John Crispin --- feeds/ucentral/ucentral-schema/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile index ba6cb4fbc..9047eeea1 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:=8820ade9a13093dfab1178b3049db734d87e5ae0d509cd5248b0858277b0c8fe +PKG_MIRROR_HASH:=fbffc49b6479557d90b0ed8be68da1ce44254f3620680943665b2af013dbc42c PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-05-29 -PKG_SOURCE_VERSION:=f3c99724dc985ed08834b5fa04bee696b0fccf0b +PKG_SOURCE_VERSION:=195ed803a3e8c6ea46973e08a5ac84d7f8e0df86 PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause From bc45e11824690d5d86a05e379aea5ea3e51f8f58 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 12 Dec 2022 08:22:56 +0100 Subject: [PATCH 02/14] ucentral-schema: update to latest HEAD e336aa4 add username to captive state Fixes: WIFI-11896 Signed-off-by: John Crispin --- feeds/ucentral/ucentral-schema/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile index 9047eeea1..adb1d7c62 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:=fbffc49b6479557d90b0ed8be68da1ce44254f3620680943665b2af013dbc42c +PKG_MIRROR_HASH:=a73aa3df44a3c8497558660c1ff71a1ee34cc50aa0628447bf6360570bc8c84f PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-05-29 -PKG_SOURCE_VERSION:=195ed803a3e8c6ea46973e08a5ac84d7f8e0df86 +PKG_SOURCE_VERSION:=e336aa487f07a9846abea2845277e0daf1f5af15 PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause From e8b0f5da60e84f04d58c9dc502da7766b47f1f01 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 12 Dec 2022 10:43:34 +0100 Subject: [PATCH 03/14] ucentral-schema: update to latest HEAD 53e3bb4 radio.channel should not be an array Signed-off-by: John Crispin --- feeds/ucentral/ucentral-schema/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile index adb1d7c62..36382a9ee 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:=a73aa3df44a3c8497558660c1ff71a1ee34cc50aa0628447bf6360570bc8c84f +PKG_MIRROR_HASH:=e0da520ace57c4439c9b3620853987e44afd482f4aca789883bceaa4b5dd7a99 PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-05-29 -PKG_SOURCE_VERSION:=e336aa487f07a9846abea2845277e0daf1f5af15 +PKG_SOURCE_VERSION:=53e3bb434a0dc32a2fc6d806019f6427d3fb92bb PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause From c230825486133ac0d3ea8d31d4fcfc93c9207c4a Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 12 Dec 2022 10:58:17 +0100 Subject: [PATCH 04/14] uspot: do not send accounting off upon logoff Fixes: WIFI-11907 Signed-off-by: John Crispin --- .../ucentral/uspot/files/usr/share/uspot/accounting.uc | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc b/feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc index f62a5b263..52eb54bae 100755 --- a/feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc +++ b/feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc @@ -62,14 +62,6 @@ function radius_stop(mac) { debug(mac, 'stopping accounting'); if (clients[mac].accounting) clients[mac].timeout.cancel(); - - let payload = { - acct: true, - acct_type: 8, - terminate_cause: 0, - }; - radius_init(mac, payload); - radius_call(mac, payload); } function radius_acct(mac, payload) { @@ -122,7 +114,7 @@ function radius_logoff(mac) { return; let payload = { acct_type: 2, - terminate_cause: 0, + terminate_cause: 1, }; radius_acct(mac, payload); } From 8b3ac5ea360f5f3dc55e585d587aff25d961c7ef Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 12 Dec 2022 11:45:05 +0100 Subject: [PATCH 05/14] uspot: purge pending flows during flush Fixes: WIFI-11908 Signed-off-by: John Crispin --- feeds/ucentral/ucentral-schema/Makefile | 4 +- feeds/ucentral/uspot/Makefile | 2 +- .../uspot/files/usr/share/uspot/accounting.uc | 54 ++++++++++--------- .../uspot/files/usr/share/uspot/firewall.ipt | 3 ++ 4 files changed, 34 insertions(+), 29 deletions(-) create mode 100644 feeds/ucentral/uspot/files/usr/share/uspot/firewall.ipt diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile index 36382a9ee..1df78b11f 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:=e0da520ace57c4439c9b3620853987e44afd482f4aca789883bceaa4b5dd7a99 +PKG_MIRROR_HASH:=9890eca665cdc87f18608e620bbc26a4650977b05ad4da1bf2780877a44ea4a9 PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-05-29 -PKG_SOURCE_VERSION:=53e3bb434a0dc32a2fc6d806019f6427d3fb92bb +PKG_SOURCE_VERSION:=d698ad24a281cf936c9ad2ce47bf1a0325fad7ab PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause diff --git a/feeds/ucentral/uspot/Makefile b/feeds/ucentral/uspot/Makefile index 8e2761e2a..977648182 100644 --- a/feeds/ucentral/uspot/Makefile +++ b/feeds/ucentral/uspot/Makefile @@ -13,7 +13,7 @@ define Package/uspot SECTION:=net CATEGORY:=Network TITLE:=hotspot daemon - DEPENDS:=+spotfilter +uhttpd-mod-ucode +libradcli + DEPENDS:=+spotfilter +uhttpd-mod-ucode +libradcli +iptables-mod-conntrack-extra +conntrack endef define Package/uspot/install diff --git a/feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc b/feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc index 52eb54bae..7981f3c5b 100755 --- a/feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc +++ b/feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc @@ -56,12 +56,15 @@ function radius_call(mac, payload) { system('/usr/bin/radius-client /tmp/acct' + mac + '.json'); } -function radius_stop(mac) { +function radius_stop(mac, payload) { if (!radius_available(mac)) return; debug(mac, 'stopping accounting'); + ubus.call('spotfilter', 'client_set', payload); + system('conntrack -D -s ' + clients[mac].ip4addr + ' -m 2'); if (clients[mac].accounting) clients[mac].timeout.cancel(); + delete clients[mac]; } function radius_acct(mac, payload) { @@ -166,6 +169,10 @@ function client_add(mac, state) { idle, max_total, }; + if (state.ip4addr) + clients[mac].ip4addr = state.ip4addr; + if (state.ip6addr) + clients[mac].ip6addr = state.ip6addr; if (state.data?.radius?.request) clients[mac].radius= state.data.radius.request; syslog(mac, 'adding client'); @@ -175,39 +182,34 @@ function client_add(mac, state) { function client_remove(mac, reason) { syslog(mac, reason); - radius_stop(mac); - delete clients[mac]; - ubus.call('spotfilter', 'client_remove', { - interface: "hotspot", - address: mac - }); + radius_stop(mac, { + interface: "hotspot", + address: mac + }); } function client_flush(mac) { syslog(mac, 'logoff event'); - radius_stop(mac); - ubus.call('spotfilter', 'client_set', { - interface: 'hotspot', - address: mac, - state: 0, - dns_state: 1, - accounting: [], - flush: true - }); + radius_stop(mac, { + interface: 'hotspot', + address: mac, + state: 0, + dns_state: 1, + accounting: [], + flush: true + }); } function client_timeout(mac, reason) { syslog(mac, reason); - radius_stop(mac); - delete clients[mac]; - ubus.call('spotfilter', 'client_set', { - interface: "hotspot", - state: 0, - dns_state: 1, - address: mac, - accounting: [], - flush: true, - }); + radius_stop(mac, { + interface: "hotspot", + state: 0, + dns_state: 1, + address: mac, + accounting: [], + flush: true, + }); } uloop.init(); diff --git a/feeds/ucentral/uspot/files/usr/share/uspot/firewall.ipt b/feeds/ucentral/uspot/files/usr/share/uspot/firewall.ipt new file mode 100644 index 000000000..3023396ad --- /dev/null +++ b/feeds/ucentral/uspot/files/usr/share/uspot/firewall.ipt @@ -0,0 +1,3 @@ +*mangle +-A POSTROUTING -m mark --mark 0x2 -j CONNMARK --set-mark 0x2 +COMMIT From 8c9cd8f9d24436f53acfb8a41cafd07bf83e61d3 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 13 Dec 2022 16:50:13 +0100 Subject: [PATCH 06/14] ratelimit: fix syntax error during parsing of wlanX-Y Fixes: WIFI-11965 Signed-off-by: John Crispin --- feeds/ucentral/ratelimit/files/usr/libexec/ratelimit.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit.sh b/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit.sh index 241a598c0..7f6d10f30 100755 --- a/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit.sh +++ b/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit.sh @@ -3,7 +3,7 @@ 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")'" }' + 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 } From 5469af35f1ed202fea46de93ae11216fcd56a9f9 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 14 Dec 2022 11:53:19 +0100 Subject: [PATCH 07/14] ucentral-schema: update to latest HEAD 6049cd7 various state improvements Fixes: WIFI-11967 Signed-off-by: John Crispin --- feeds/ucentral/ucentral-schema/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile index 1df78b11f..4531eec0e 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:=9890eca665cdc87f18608e620bbc26a4650977b05ad4da1bf2780877a44ea4a9 +PKG_MIRROR_HASH:=87c22ae9c1788b8976d3ebe33284b1066d7d5ff96a535eb10062e9f1a32cdfbe PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-05-29 -PKG_SOURCE_VERSION:=d698ad24a281cf936c9ad2ce47bf1a0325fad7ab +PKG_SOURCE_VERSION:=6049cd75c2b0bf0407ba35f544dafd3a8e608eb6 PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause From e5336b7351740233553142b4e1f60d87dd914893 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 14 Dec 2022 17:09:46 +0100 Subject: [PATCH 08/14] ucentral-schema: update to latest HEAD b539203 include APVLAN associations inside state messages Fixes: WIFI-11861 Signed-off-by: John Crispin --- feeds/ucentral/ucentral-schema/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile index 4531eec0e..7141b3a33 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:=87c22ae9c1788b8976d3ebe33284b1066d7d5ff96a535eb10062e9f1a32cdfbe +PKG_MIRROR_HASH:=eb96374be5c07d58ad112597803c298d61137b887b4a919d7f05eaff89865274 PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-05-29 -PKG_SOURCE_VERSION:=6049cd75c2b0bf0407ba35f544dafd3a8e608eb6 +PKG_SOURCE_VERSION:=b5392037b4751d2d0590f7dd4e80c076eb7ef71e PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause From e42051d3a9ca2bfce90ac048a508a2cc01984d45 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Thu, 15 Dec 2022 12:03:31 +0100 Subject: [PATCH 09/14] hostapd: add dynamic_own_ip support Signed-off-by: John Crispin --- feeds/wifi-ax/hostapd/files/hostapd.sh | 11 +- .../hostapd/patches/760-dynamic_own_ip.patch | 109 ++++++++++++++++++ 2 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 feeds/wifi-ax/hostapd/patches/760-dynamic_own_ip.patch diff --git a/feeds/wifi-ax/hostapd/files/hostapd.sh b/feeds/wifi-ax/hostapd/files/hostapd.sh index fa0dbfb75..31afd77df 100644 --- a/feeds/wifi-ax/hostapd/files/hostapd.sh +++ b/feeds/wifi-ax/hostapd/files/hostapd.sh @@ -552,11 +552,13 @@ append_radius_server() { json_get_vars \ auth_server auth_secret auth_port \ dae_client dae_secret dae_port \ - ownip radius_client_addr \ + dynamic_ownip ownip radius_client_addr \ eap_reauth_period request_cui \ erp_domain mobility_domain \ fils_realm fils_dhcp + set_default dynamic_ownip 1 + # legacy compatibility [ -n "$auth_server" ] || json_get_var auth_server server [ -n "$auth_port" ] || json_get_var auth_port port @@ -605,7 +607,12 @@ append_radius_server() { } json_for_each_item append_radius_auth_req_attr radius_auth_req_attr - [ -n "$ownip" ] && append bss_conf "own_ip_addr=$ownip" "$N" + if [ -n "$ownip" ]; then + append bss_conf "own_ip_addr=$ownip" "$N" + elif [ "$dynamic_ownip" -gt 0 ]; then + append bss_conf "dynamic_own_ip_addr=$dynamic_ownip" "$N" + fi + [ -n "$radius_client_addr" ] && append bss_conf "radius_client_addr=$radius_client_addr" "$N" [ "$macfilter" = radius ] && append bss_conf "macaddr_acl=2" "$N" } diff --git a/feeds/wifi-ax/hostapd/patches/760-dynamic_own_ip.patch b/feeds/wifi-ax/hostapd/patches/760-dynamic_own_ip.patch new file mode 100644 index 000000000..3d2b59e8c --- /dev/null +++ b/feeds/wifi-ax/hostapd/patches/760-dynamic_own_ip.patch @@ -0,0 +1,109 @@ +--- a/src/ap/ap_config.h ++++ b/src/ap/ap_config.h +@@ -311,6 +311,7 @@ struct hostapd_bss_config { + unsigned int eap_sim_db_timeout; + int eap_server_erp; /* Whether ERP is enabled on internal EAP server */ + struct hostapd_ip_addr own_ip_addr; ++ int dynamic_own_ip_addr; + char *nas_identifier; + struct hostapd_radius_servers *radius; + int acct_interim_interval; +--- a/src/radius/radius_client.c ++++ b/src/radius/radius_client.c +@@ -163,6 +163,8 @@ struct radius_client_data { + */ + void *ctx; + ++ struct hostapd_ip_addr local_ip; ++ + /** + * conf - RADIUS client configuration (list of RADIUS servers to use) + */ +@@ -720,6 +722,30 @@ static void radius_client_list_add(struc + + + /** ++ * radius_client_send - Get local address for the RADIUS auth socket ++ * @radius: RADIUS client context from radius_client_init() ++ * @addr: pointer to store the address ++ * ++ * This function returns the local address for the connection to the RADIUS ++ * auth server. It also opens the socket if it's not available yet. ++ */ ++int radius_client_get_local_addr(struct radius_client_data *radius, ++ struct hostapd_ip_addr *addr) ++{ ++ struct hostapd_radius_servers *conf = radius->conf; ++ ++ if (conf->auth_server && radius->auth_sock < 0) ++ radius_client_init_auth(radius); ++ ++ if (radius->auth_sock < 0) ++ return -1; ++ ++ memcpy(addr, &radius->local_ip, sizeof(*addr)); ++ ++ return 0; ++} ++ ++/** + * radius_client_send - Send a RADIUS request + * @radius: RADIUS client context from radius_client_init() + * @msg: RADIUS message to be sent +@@ -1238,6 +1264,10 @@ radius_change_server(struct radius_clien + wpa_printf(MSG_DEBUG, "RADIUS local address: %s:%u", + inet_ntoa(claddr.sin_addr), + ntohs(claddr.sin_port)); ++ if (auth) { ++ radius->local_ip.af = AF_INET; ++ radius->local_ip.u.v4 = claddr.sin_addr; ++ } + } + break; + #ifdef CONFIG_IPV6 +@@ -1249,6 +1279,10 @@ radius_change_server(struct radius_clien + inet_ntop(AF_INET6, &claddr6.sin6_addr, + abuf, sizeof(abuf)), + ntohs(claddr6.sin6_port)); ++ if (auth) { ++ radius->local_ip.af = AF_INET6; ++ radius->local_ip.u.v6 = claddr6.sin6_addr; ++ } + } + break; + } +--- a/src/radius/radius_client.h ++++ b/src/radius/radius_client.h +@@ -249,6 +249,8 @@ int radius_client_register(struct radius + void radius_client_set_interim_error_cb(struct radius_client_data *radius, + void (*cb)(const u8 *addr, void *ctx), + void *ctx); ++int radius_client_get_local_addr(struct radius_client_data *radius, ++ struct hostapd_ip_addr * addr); + int radius_client_send(struct radius_client_data *radius, + struct radius_msg *msg, + RadiusType msg_type, const u8 *addr); +--- a/src/ap/ieee802_1x.c ++++ b/src/ap/ieee802_1x.c +@@ -535,6 +535,10 @@ int add_common_radius_attr(struct hostap + struct hostapd_radius_attr *attr; + int len; + ++ if (hapd->conf->dynamic_own_ip_addr) ++ radius_client_get_local_addr(hapd->radius, ++ &hapd->conf->own_ip_addr); ++ + if (!hostapd_config_get_radius_attr(req_attr, + RADIUS_ATTR_NAS_IP_ADDRESS) && + hapd->conf->own_ip_addr.af == AF_INET && +--- a/hostapd/config_file.c ++++ b/hostapd/config_file.c +@@ -2681,6 +2681,8 @@ static int hostapd_config_fill(struct ho + } else if (os_strcmp(buf, "iapp_interface") == 0) { + wpa_printf(MSG_INFO, "DEPRECATED: iapp_interface not used"); + #endif /* CONFIG_IAPP */ ++ } else if (os_strcmp(buf, "dynamic_own_ip_addr") == 0) { ++ bss->dynamic_own_ip_addr = atoi(pos); + } else if (os_strcmp(buf, "own_ip_addr") == 0) { + if (hostapd_parse_ip_addr(pos, &bss->own_ip_addr)) { + wpa_printf(MSG_ERROR, From a62503328ba676d38f6df78ef860e821f62d61c2 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Fri, 16 Dec 2022 16:15:47 +0100 Subject: [PATCH 10/14] .github/workflows: add cig,wf194c4 Fixes: WIFI-11983 Signed-off-by: John Crispin --- .github/workflows/build-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 411289238..61c9a4d69 100644 --- a/.github/workflows/build-dev.yml +++ b/.github/workflows/build-dev.yml @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - target: ['actiontec_web7200', 'cig_wf188n', 'cig_wf196', 'cig_wf610d', 'cig_wf808', 'cybertan_eww622-a1', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'liteon_wpx8324', 'edgecore_ecs4100-12ph', 'edgecore_ecw5211', 'edgecore_ecw5410', 'edgecore_oap100', 'edgecore_ssw2ac2600', 'edgecore_spw2ac1200', 'edgecore_spw2ac1200-lan-poe', 'hfcl_ion4', 'hfcl_ion4xe', 'hfcl_ion4xi', 'hfcl_ion4x', 'hfcl_ion4x_2', 'indio_um-305ac', 'indio_um-305ax', 'indio_um-325ac', 'indio_um-510ac-v3', 'indio_um-550ac', 'indio_um-310ax-v1', 'indio_um-510axp-v1', 'indio_um-510axm-v1', 'linksys_ea6350-v4', 'linksys_e8450-ubi', 'linksys_ea8300', 'meshpp_s618_cp03', 'meshpp_s618_cp01', 'udaya_a5-id2', 'wallys_dr40x9', 'wallys_dr6018', 'wallys_dr6018_v4', 'x64_vm', 'yuncore_ax840', 'yuncore_fap640', 'yuncore_fap650' ] + target: ['actiontec_web7200', 'cig_wf188n', 'cig_wf194c4', 'cig_wf196', 'cig_wf610d', 'cig_wf808', 'cybertan_eww622-a1', 'edgecore_eap101', 'edgecore_eap102', 'edgecore_eap104', 'liteon_wpx8324', 'edgecore_ecs4100-12ph', 'edgecore_ecw5211', 'edgecore_ecw5410', 'edgecore_oap100', 'edgecore_ssw2ac2600', 'edgecore_spw2ac1200', 'edgecore_spw2ac1200-lan-poe', 'hfcl_ion4', 'hfcl_ion4xe', 'hfcl_ion4xi', 'hfcl_ion4x', 'hfcl_ion4x_2', 'indio_um-305ac', 'indio_um-305ax', 'indio_um-325ac', 'indio_um-510ac-v3', 'indio_um-550ac', 'indio_um-310ax-v1', 'indio_um-510axp-v1', 'indio_um-510axm-v1', 'linksys_ea6350-v4', 'linksys_e8450-ubi', 'linksys_ea8300', 'meshpp_s618_cp03', 'meshpp_s618_cp01', 'udaya_a5-id2', 'wallys_dr40x9', 'wallys_dr6018', 'wallys_dr6018_v4', 'x64_vm', 'yuncore_ax840', 'yuncore_fap640', 'yuncore_fap650' ] steps: - uses: actions/checkout@v3 From e973110de7ef2b5436723cad05f2a17bf45da33d Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sat, 17 Dec 2022 10:43:04 +0100 Subject: [PATCH 11/14] ath11k: fix mac assignment on cig wf196 Fixes: WIFI-11976 Signed-off-by: John Crispin --- .../etc/hotplug.d/firmware/10-ath11k-caldata | 3 ++- .../patches/pending/203-ath11k-mac.patch | 25 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/feeds/ipq807x/ipq807x/base-files/etc/hotplug.d/firmware/10-ath11k-caldata b/feeds/ipq807x/ipq807x/base-files/etc/hotplug.d/firmware/10-ath11k-caldata index 6e46264a5..335709ae0 100755 --- a/feeds/ipq807x/ipq807x/base-files/etc/hotplug.d/firmware/10-ath11k-caldata +++ b/feeds/ipq807x/ipq807x/base-files/etc/hotplug.d/firmware/10-ath11k-caldata @@ -194,7 +194,8 @@ ath11k-macs) ath11k_generate_macs ;; cig,wf194c|\ - cig,wf194c) + cig,wf194c4|\ + cig,wf196) ath11k_generate_macs_wf194 ;; plasmacloud,pax1800-v1|\ diff --git a/feeds/wifi-ax/mac80211/patches/pending/203-ath11k-mac.patch b/feeds/wifi-ax/mac80211/patches/pending/203-ath11k-mac.patch index 972830c79..c5a99c6a6 100644 --- a/feeds/wifi-ax/mac80211/patches/pending/203-ath11k-mac.patch +++ b/feeds/wifi-ax/mac80211/patches/pending/203-ath11k-mac.patch @@ -2,11 +2,22 @@ Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/q =================================================================== --- backports-20210222_001-4.4.60-b157d2276.orig/drivers/net/wireless/ath/ath11k/qmi.c +++ backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/qmi.c -@@ -3161,6 +3161,12 @@ out_req: +@@ -3161,6 +3161,23 @@ out_req: return ret; } +static const struct firmware *fw_macs; ++static int fw_macs_num = 0; ++ ++int ath11k_get_custom_macs_num(int num) ++{ ++ int ret = fw_macs_num; ++ ++ fw_macs_num += num; ++ ++ return ret; ++} ++ +const struct firmware* ath11k_get_custom_macs(void) +{ + return fw_macs; @@ -15,7 +26,7 @@ Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/q static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab) { char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE]; -@@ -3188,6 +3194,8 @@ static int ath11k_qmi_load_bdf_qmi(struc +@@ -3188,6 +3205,8 @@ static int ath11k_qmi_load_bdf_qmi(struc goto out; } @@ -36,11 +47,12 @@ Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/w struct wmi_tlv_policy { size_t min_len; -@@ -7278,11 +7279,14 @@ mem_free: +@@ -7268,11 +7269,15 @@ mem_free: return ret; } +const struct firmware* ath11k_get_custom_macs(void); ++int ath11k_get_custom_macs_num(int num); + static int ath11k_wmi_tlv_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len, const void *ptr, void *data) @@ -51,17 +63,18 @@ Index: backports-20210222_001-4.4.60-b157d2276/drivers/net/wireless/ath/ath11k/w struct wmi_mac_addr *addr_list; struct ath11k_pdev *pdev; u32 num_mac_addr; -@@ -7307,6 +7311,19 @@ static int ath11k_wmi_tlv_rdy_parse(stru +@@ -7297,6 +7302,20 @@ static int ath11k_wmi_tlv_rdy_parse(stru addr_list = (struct wmi_mac_addr *)ptr; num_mac_addr = rdy_parse->num_extra_mac_addr; + fw_entry = ath11k_get_custom_macs(); + if (fw_entry) { ++ int num = ath11k_get_custom_macs_num(ab->num_radios); + printk("applying ath11k-macs\n"); -+ if (fw_entry->size >= (ab->num_radios * 6)) { ++ if (fw_entry->size >= ((num + ab->num_radios) * 6)) { + for (i = 0; i < ab->num_radios; i++) { + pdev = &ab->pdevs[i]; -+ ether_addr_copy(pdev->mac_addr, &fw_entry->data[i * 6]); ++ ether_addr_copy(pdev->mac_addr, &fw_entry->data[(num + i) * 6]); + } + } + ab->pdevs_macaddr_valid = true; From 4967fcd2be5dd983e57060ab4575534d6c1c59c6 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 18 Dec 2022 15:25:27 +0100 Subject: [PATCH 12/14] hostapd: improve multi CoA support Signed-off-by: John Crispin --- feeds/wifi-ax/hostapd/files/hostapd.sh | 5 +- .../hostapd/patches/900-coa_multi.patch | 344 ++++++++++++++---- 2 files changed, 286 insertions(+), 63 deletions(-) diff --git a/feeds/wifi-ax/hostapd/files/hostapd.sh b/feeds/wifi-ax/hostapd/files/hostapd.sh index 31afd77df..267836932 100644 --- a/feeds/wifi-ax/hostapd/files/hostapd.sh +++ b/feeds/wifi-ax/hostapd/files/hostapd.sh @@ -705,7 +705,9 @@ hostapd_set_bss_options() { [ -n "$wpa_strict_rekey" ] && append bss_conf "wpa_strict_rekey=$wpa_strict_rekey" "$N" } - [ -n "$nasid" ] && append bss_conf "nas_identifier=$nasid" "$N" + set_default nasid "${macaddr//\:}" + append bss_conf "nas_identifier=$nasid" "$N" + [ -n "$acct_server" ] && { append bss_conf "acct_server_addr=$acct_server" "$N" append bss_conf "acct_server_port=$acct_port" "$N" @@ -923,7 +925,6 @@ hostapd_set_bss_options() { append bss_conf "ft_psk_generate_local=$ft_psk_generate_local" "$N" append bss_conf "ft_over_ds=$ft_over_ds" "$N" append bss_conf "reassociation_deadline=$reassociation_deadline" "$N" - [ -n "$nasid" ] || append bss_conf "nas_identifier=${macaddr//\:}" "$N" if [ "$skip_kh_setup" -eq "0" ]; then json_get_vars r0_key_lifetime r1_key_holder pmk_r1_push diff --git a/feeds/wifi-ax/hostapd/patches/900-coa_multi.patch b/feeds/wifi-ax/hostapd/patches/900-coa_multi.patch index 2b0131de0..7516b7349 100644 --- a/feeds/wifi-ax/hostapd/patches/900-coa_multi.patch +++ b/feeds/wifi-ax/hostapd/patches/900-coa_multi.patch @@ -1,76 +1,298 @@ -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 -@@ -862,7 +862,6 @@ static int hostapd_das_nas_mismatch(stru - return 0; - } - -- - static struct sta_info * hostapd_das_find_sta(struct hostapd_data *hapd, - struct radius_das_attrs *attr, - int *multi) -@@ -1050,6 +1049,24 @@ static int hostapd_das_disconnect_pmksa( - } +--- a/src/radius/radius_das.h ++++ b/src/radius/radius_das.h +@@ -44,6 +44,7 @@ struct radius_das_attrs { + struct radius_das_conf { + int port; + const u8 *shared_secret; ++ const u8 *nas_identifier; + size_t shared_secret_len; + const struct hostapd_ip_addr *client_addr; + unsigned int time_window; +--- a/src/ap/hostapd.c ++++ b/src/ap/hostapd.c +@@ -1367,6 +1367,7 @@ static int hostapd_setup_bss(struct host + struct radius_das_conf das_conf; + os_memset(&das_conf, 0, sizeof(das_conf)); + das_conf.port = conf->radius_das_port; ++ das_conf.nas_identifier = conf->nas_identifier; + das_conf.shared_secret = conf->radius_das_shared_secret; + das_conf.shared_secret_len = + conf->radius_das_shared_secret_len; +--- a/src/radius/radius_das.c ++++ b/src/radius/radius_das.c +@@ -12,13 +12,26 @@ + #include "utils/common.h" + #include "utils/eloop.h" + #include "utils/ip_addr.h" ++#include "utils/list.h" + #include "radius.h" + #include "radius_das.h" -+static struct hostapd_data * ap_get_hapd(struct hostapd_data *hapd, struct radius_das_attrs *attr) -+{ -+ size_t i; -+ int multi; +-struct radius_das_data { ++static struct dl_list das_ports = DL_LIST_HEAD_INIT(das_ports); + -+ for (i = 0; i < hapd->iface->num_bss; i++) { -+ if (!hapd->iface->bss[i]->iface->bss[i]->radius_das) -+ continue; -+ if (hapd->conf->radius_das_port !=hapd->iface->bss[i]->iface->bss[i]->conf->radius_das_port) -+ continue; -+ if (hostapd_das_find_sta(hapd, attr, &multi)) -+ return hapd->iface->bss[i]; ++struct radius_das_port { ++ struct dl_list list; ++ struct dl_list das_data; ++ ++ int port; + int sock; ++}; ++ ++struct radius_das_data { ++ struct dl_list list; ++ struct radius_das_port *port; + u8 *shared_secret; ++ u8 *nas_identifier; + size_t shared_secret_len; + struct hostapd_ip_addr client_addr; + unsigned int time_window; +@@ -378,56 +391,17 @@ fail: + } + + +-static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) ++static void ++radius_das_receive_msg(struct radius_das_data *das, struct radius_msg *msg, ++ struct sockaddr *from, socklen_t fromlen, ++ char *abuf, int from_port) + { +- struct radius_das_data *das = eloop_ctx; +- u8 buf[1500]; +- union { +- struct sockaddr_storage ss; +- struct sockaddr_in sin; +-#ifdef CONFIG_IPV6 +- struct sockaddr_in6 sin6; +-#endif /* CONFIG_IPV6 */ +- } from; +- char abuf[50]; +- int from_port = 0; +- socklen_t fromlen; +- int len; +- struct radius_msg *msg, *reply = NULL; ++ struct radius_msg *reply = NULL; + struct radius_hdr *hdr; + struct wpabuf *rbuf; ++ struct os_time now; + u32 val; + int res; +- struct os_time now; +- +- fromlen = sizeof(from); +- len = recvfrom(sock, buf, sizeof(buf), 0, +- (struct sockaddr *) &from.ss, &fromlen); +- if (len < 0) { +- wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno)); +- return; +- } +- +- os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); +- from_port = ntohs(from.sin.sin_port); +- +- wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d", +- len, abuf, from_port); +- if (das->client_addr.u.v4.s_addr && +- das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) { +- wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); +- return; +- } +- +- msg = radius_msg_parse(buf, len); +- if (msg == NULL) { +- wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet " +- "from %s:%d failed", abuf, from_port); +- return; +- } +- +- if (wpa_debug_level <= MSG_MSGDUMP) +- radius_msg_dump(msg); + + if (radius_msg_verify_das_req(msg, das->shared_secret, + das->shared_secret_len, +@@ -494,9 +468,8 @@ static void radius_das_receive(int sock, + radius_msg_dump(reply); + + rbuf = radius_msg_get_buf(reply); +- res = sendto(das->sock, wpabuf_head(rbuf), +- wpabuf_len(rbuf), 0, +- (struct sockaddr *) &from.ss, fromlen); ++ res = sendto(das->port->sock, wpabuf_head(rbuf), ++ wpabuf_len(rbuf), 0, from, fromlen); + if (res < 0) { + wpa_printf(MSG_ERROR, "DAS: sendto(to %s:%d): %s", + abuf, from_port, strerror(errno)); +@@ -508,6 +481,72 @@ fail: + radius_msg_free(reply); + } + ++static void radius_das_receive(int sock, void *eloop_ctx, void *sock_ctx) ++{ ++ struct radius_das_port *p = eloop_ctx; ++ struct radius_das_data *das; ++ u8 buf[1500]; ++ union { ++ struct sockaddr_storage ss; ++ struct sockaddr_in sin; ++#ifdef CONFIG_IPV6 ++ struct sockaddr_in6 sin6; ++#endif /* CONFIG_IPV6 */ ++ } from; ++ struct radius_msg *msg; ++ size_t nasid_len = 0; ++ u8 *nasid_buf = NULL; ++ char abuf[50]; ++ int from_port = 0; ++ socklen_t fromlen; ++ int found = 0; ++ int len; ++ ++ fromlen = sizeof(from); ++ len = recvfrom(sock, buf, sizeof(buf), 0, ++ (struct sockaddr *) &from.ss, &fromlen); ++ if (len < 0) { ++ wpa_printf(MSG_ERROR, "DAS: recvfrom: %s", strerror(errno)); ++ return; + } -+ return hapd; ++ ++ os_strlcpy(abuf, inet_ntoa(from.sin.sin_addr), sizeof(abuf)); ++ from_port = ntohs(from.sin.sin_port); ++ ++ msg = radius_msg_parse(buf, len); ++ if (msg == NULL) { ++ wpa_printf(MSG_DEBUG, "DAS: Parsing incoming RADIUS packet " ++ "from %s:%d failed", abuf, from_port); ++ return; ++ } ++ ++ wpa_printf(MSG_DEBUG, "DAS: Received %d bytes from %s:%d", ++ len, abuf, from_port); ++ ++ if (wpa_debug_level <= MSG_MSGDUMP) ++ radius_msg_dump(msg); ++ ++ radius_msg_get_attr_ptr(msg, RADIUS_ATTR_NAS_IDENTIFIER, ++ &nasid_buf, &nasid_len, NULL); ++ dl_list_for_each(das, &p->das_data, struct radius_das_data, list) { ++ if (das->client_addr.u.v4.s_addr && ++ das->client_addr.u.v4.s_addr != from.sin.sin_addr.s_addr) ++ continue; ++ ++ if (das->nas_identifier && nasid_buf && ++ (nasid_len != os_strlen(das->nas_identifier) || ++ os_memcmp(das->nas_identifier, nasid_buf, nasid_len) != 0)) ++ continue; ++ ++ found = 1; ++ radius_das_receive_msg(das, msg, (struct sockaddr *)&from.ss, ++ fromlen, abuf, from_port); ++ } ++ ++ if (!found) ++ wpa_printf(MSG_DEBUG, "DAS: Drop message from unknown client"); +} + -+ -+ - static enum radius_das_res - hostapd_das_disconnect(void *ctx, struct radius_das_attrs *attr) + + static int radius_das_open_socket(int port) { -@@ -1057,6 +1074,10 @@ hostapd_das_disconnect(void *ctx, struct - struct sta_info *sta; - int multi; +@@ -533,6 +572,49 @@ static int radius_das_open_socket(int po + } -+ hapd = ap_get_hapd(hapd, attr); -+ if (!hapd) -+ return RADIUS_DAS_SESSION_NOT_FOUND; + ++static struct radius_das_port * ++radius_das_open_port(int port) ++{ ++ struct radius_das_port *p; + - if (hostapd_das_nas_mismatch(hapd, attr)) - return RADIUS_DAS_NAS_MISMATCH; - -@@ -1096,6 +1117,10 @@ hostapd_das_coa(void *ctx, struct radius - struct sta_info *sta; - int multi; - -+ hapd = ap_get_hapd(hapd, attr); -+ if (!hapd) -+ return RADIUS_DAS_SESSION_NOT_FOUND; ++ dl_list_for_each(p, &das_ports, struct radius_das_port, list) { ++ if (p->port == port) ++ return p; ++ } + - if (hostapd_das_nas_mismatch(hapd, attr)) - return RADIUS_DAS_NAS_MISMATCH; ++ p = os_zalloc(sizeof(*p)); ++ if (p == NULL) ++ return NULL; ++ ++ dl_list_init(&p->das_data); ++ p->port = port; ++ p->sock = radius_das_open_socket(port); ++ if (p->sock < 0) ++ goto free_port; ++ ++ if (eloop_register_read_sock(p->sock, radius_das_receive, p, NULL)) ++ goto close_port; ++ ++ dl_list_add(&das_ports, &p->list); ++ ++ return p; ++ ++close_port: ++ close(p->sock); ++free_port: ++ os_free(p); ++ ++ return NULL; ++} ++ ++static void radius_das_close_port(struct radius_das_port *p) ++{ ++ dl_list_del(&p->list); ++ eloop_unregister_read_sock(p->sock); ++ close(p->sock); ++ free(p); ++} ++ + struct radius_das_data * + radius_das_init(struct radius_das_conf *conf) + { +@@ -553,6 +635,8 @@ radius_das_init(struct radius_das_conf * + das->ctx = conf->ctx; + das->disconnect = conf->disconnect; + das->coa = conf->coa; ++ if (conf->nas_identifier) ++ das->nas_identifier = os_strdup(conf->nas_identifier); -Index: hostapd-2021-02-20-59e9794c/src/radius/radius_das.c -=================================================================== ---- hostapd-2021-02-20-59e9794c.orig/src/radius/radius_das.c -+++ hostapd-2021-02-20-59e9794c/src/radius/radius_das.c -@@ -568,10 +568,9 @@ radius_das_init(struct radius_das_conf * + os_memcpy(&das->client_addr, conf->client_addr, + sizeof(das->client_addr)); +@@ -565,19 +649,15 @@ radius_das_init(struct radius_das_conf * + } + das->shared_secret_len = conf->shared_secret_len; - das->sock = radius_das_open_socket(conf->port); - if (das->sock < 0) { -- wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS " -+ wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS - reusing existing port " +- das->sock = radius_das_open_socket(conf->port); +- if (das->sock < 0) { ++ das->port = radius_das_open_port(conf->port); ++ if (!das->port) { + wpa_printf(MSG_ERROR, "Failed to open UDP socket for RADIUS " "DAS"); -- radius_das_deinit(das); -- return NULL; -+ return das; + radius_das_deinit(das); + return NULL; } - if (eloop_register_read_sock(das->sock, radius_das_receive, das, NULL)) +- if (eloop_register_read_sock(das->sock, radius_das_receive, das, NULL)) +- { +- radius_das_deinit(das); +- return NULL; +- } ++ dl_list_add(&das->port->das_data, &das->list); + + return das; + } +@@ -588,11 +668,14 @@ void radius_das_deinit(struct radius_das + if (das == NULL) + return; + +- if (das->sock >= 0) { +- eloop_unregister_read_sock(das->sock); +- close(das->sock); ++ if (das->port) { ++ dl_list_del(&das->list); ++ ++ if (dl_list_empty(&das->port->das_data)) ++ radius_das_close_port(das->port); + } + ++ os_free(das->nas_identifier); + os_free(das->shared_secret); + os_free(das); + } From 74eb6f96ab58c6e36407205a076d50e261cbf92c Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 19 Dec 2022 13:01:49 +0100 Subject: [PATCH 13/14] atfpolicy: reduce ubus_wait timeout to 2s Signed-off-by: John Crispin --- feeds/ucentral/atfpolicy/files/atfpolicy.init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds/ucentral/atfpolicy/files/atfpolicy.init b/feeds/ucentral/atfpolicy/files/atfpolicy.init index 498ad7118..89113eb10 100644 --- a/feeds/ucentral/atfpolicy/files/atfpolicy.init +++ b/feeds/ucentral/atfpolicy/files/atfpolicy.init @@ -52,6 +52,6 @@ start_service() { } service_started() { - ubus -t 10 wait_for atfpolicy + ubus -t 2 wait_for atfpolicy [ $? = 0 ] && reload_service } From f9b46fd6b08cf38c6f862314632da12023a2313c Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 19 Dec 2022 13:02:10 +0100 Subject: [PATCH 14/14] ucentral-schema: update to latest HEAD 39dad34 wireguard: fix reload after reboot Fixes: WIFI-12002 Signed-off-by: John Crispin --- feeds/ucentral/ucentral-schema/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile index 7141b3a33..a4b093f3a 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:=eb96374be5c07d58ad112597803c298d61137b887b4a919d7f05eaff89865274 +PKG_MIRROR_HASH:=7dc3e99b5b5937b230a465486fa4ac0f6a25ce2e6d6adf8c6999a32408cd293d PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-05-29 -PKG_SOURCE_VERSION:=b5392037b4751d2d0590f7dd4e80c076eb7ef71e +PKG_SOURCE_VERSION:=39dad34a2c866ddc77443c54e930a3efcff9b463 PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause