From 393db0ec2a3ff601056b98e847beb0d60762f02b Mon Sep 17 00:00:00 2001 From: John Crispin Date: Sun, 2 Oct 2022 09:03:10 +0200 Subject: [PATCH 1/9] mac80211: fix typo The detection of multi_bssid was using bad syntx, this caused the wifi MAC of some boards to change. Signed-off-by: John Crispin --- feeds/wifi-ax/mac80211/files/lib/netifd/wireless/mac80211.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feeds/wifi-ax/mac80211/files/lib/netifd/wireless/mac80211.sh b/feeds/wifi-ax/mac80211/files/lib/netifd/wireless/mac80211.sh index 984b2a271..b00545561 100644 --- a/feeds/wifi-ax/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/feeds/wifi-ax/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -533,7 +533,7 @@ mac80211_generate_mac() { local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)" local mask="$(cat /sys/class/ieee80211/${phy}/address_mask)" - [ "$mask" = "00:00:00:00:00:00" -a "$multiple_bssid" -neq 1 ] && { + [ "$mask" = "00:00:00:00:00:00" -a "$multiple_bssid" != 1 ] && { mask="ff:ff:ff:ff:ff:ff"; [ "$(wc -l < /sys/class/ieee80211/${phy}/addresses)" -gt $id ] && { From a21a08e8bfd0157f531ad5034dc3b3adb99f655f Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 19 Sep 2022 18:44:27 +0200 Subject: [PATCH 2/9] ipq807x: backport sched matchall classifier support Fixes: WIFI-10190 Fixes: WIFI-10194 Signed-off-by: Felix Fietkau --- ...sched-introduce-Match-all-classifier.patch | 315 ++++++++++++++++++ 1 file changed, 315 insertions(+) create mode 100644 feeds/ipq807x/ipq807x/patches/225-net-sched-introduce-Match-all-classifier.patch diff --git a/feeds/ipq807x/ipq807x/patches/225-net-sched-introduce-Match-all-classifier.patch b/feeds/ipq807x/ipq807x/patches/225-net-sched-introduce-Match-all-classifier.patch new file mode 100644 index 000000000..512928b63 --- /dev/null +++ b/feeds/ipq807x/ipq807x/patches/225-net-sched-introduce-Match-all-classifier.patch @@ -0,0 +1,315 @@ +From: Jiri Pirko +Date: Thu, 21 Jul 2016 12:03:11 +0200 +Subject: [PATCH] net/sched: introduce Match-all classifier + +The matchall classifier matches every packet and allows the user to apply +actions on it. This filter is very useful in usecases where every packet +should be matched, for example, packet mirroring (SPAN) can be setup very +easily using that filter. + +Signed-off-by: Jiri Pirko +Signed-off-by: Yotam Gigi +Signed-off-by: David S. Miller +--- + create mode 100644 net/sched/cls_matchall.c + +--- a/include/uapi/linux/pkt_cls.h ++++ b/include/uapi/linux/pkt_cls.h +@@ -427,6 +427,17 @@ enum { + + #define TCA_FLOWER_MAX (__TCA_FLOWER_MAX - 1) + ++/* Match-all classifier */ ++ ++enum { ++ TCA_MATCHALL_UNSPEC, ++ TCA_MATCHALL_CLASSID, ++ TCA_MATCHALL_ACT, ++ __TCA_MATCHALL_MAX, ++}; ++ ++#define TCA_MATCHALL_MAX (__TCA_MATCHALL_MAX - 1) ++ + /* Extended Matches */ + + struct tcf_ematch_tree_hdr { +--- /dev/null ++++ b/net/sched/cls_matchall.c +@@ -0,0 +1,248 @@ ++/* ++ * net/sched/cls_matchll.c Match-all classifier ++ * ++ * Copyright (c) 2016 Jiri Pirko ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++struct cls_mall_filter { ++ struct tcf_exts exts; ++ struct tcf_result res; ++ u32 handle; ++ struct rcu_head rcu; ++}; ++ ++struct cls_mall_head { ++ struct cls_mall_filter *filter; ++ struct rcu_head rcu; ++}; ++ ++static int mall_classify(struct sk_buff *skb, const struct tcf_proto *tp, ++ struct tcf_result *res) ++{ ++ struct cls_mall_head *head = rcu_dereference_bh(tp->root); ++ struct cls_mall_filter *f = head->filter; ++ ++ return tcf_exts_exec(skb, &f->exts, res); ++} ++ ++static int mall_init(struct tcf_proto *tp) ++{ ++ struct cls_mall_head *head; ++ ++ head = kzalloc(sizeof(*head), GFP_KERNEL); ++ if (!head) ++ return -ENOBUFS; ++ ++ rcu_assign_pointer(tp->root, head); ++ ++ return 0; ++} ++ ++static void mall_destroy_filter(struct rcu_head *head) ++{ ++ struct cls_mall_filter *f = container_of(head, struct cls_mall_filter, rcu); ++ ++ tcf_exts_destroy(&f->exts); ++ kfree(f); ++} ++ ++static bool mall_destroy(struct tcf_proto *tp, bool force) ++{ ++ struct cls_mall_head *head = rtnl_dereference(tp->root); ++ ++ if (!force && head->filter) ++ return false; ++ ++ if (head->filter) ++ call_rcu(&head->filter->rcu, mall_destroy_filter); ++ RCU_INIT_POINTER(tp->root, NULL); ++ kfree_rcu(head, rcu); ++ return true; ++} ++ ++static unsigned long mall_get(struct tcf_proto *tp, u32 handle) ++{ ++ struct cls_mall_head *head = rtnl_dereference(tp->root); ++ struct cls_mall_filter *f = head->filter; ++ ++ if (f && f->handle == handle) ++ return (unsigned long) f; ++ return 0; ++} ++ ++static const struct nla_policy mall_policy[TCA_MATCHALL_MAX + 1] = { ++ [TCA_MATCHALL_UNSPEC] = { .type = NLA_UNSPEC }, ++ [TCA_MATCHALL_CLASSID] = { .type = NLA_U32 }, ++}; ++ ++static int mall_set_parms(struct net *net, struct tcf_proto *tp, ++ struct cls_mall_filter *f, ++ unsigned long base, struct nlattr **tb, ++ struct nlattr *est, bool ovr) ++{ ++ struct tcf_exts e; ++ int err; ++ ++ tcf_exts_init(&e, TCA_MATCHALL_ACT, 0); ++ err = tcf_exts_validate(net, tp, tb, est, &e, ovr); ++ if (err < 0) ++ return err; ++ ++ if (tb[TCA_MATCHALL_CLASSID]) { ++ f->res.classid = nla_get_u32(tb[TCA_MATCHALL_CLASSID]); ++ tcf_bind_filter(tp, &f->res, base); ++ } ++ ++ tcf_exts_change(tp, &f->exts, &e); ++ ++ return 0; ++} ++ ++static int mall_change(struct net *net, struct sk_buff *in_skb, ++ struct tcf_proto *tp, unsigned long base, ++ u32 handle, struct nlattr **tca, ++ unsigned long *arg, bool ovr) ++{ ++ struct cls_mall_head *head = rtnl_dereference(tp->root); ++ struct cls_mall_filter *fold = (struct cls_mall_filter *) *arg; ++ struct cls_mall_filter *f; ++ struct nlattr *tb[TCA_MATCHALL_MAX + 1]; ++ int err; ++ ++ if (!tca[TCA_OPTIONS]) ++ return -EINVAL; ++ ++ if (head->filter) ++ return -EBUSY; ++ ++ if (fold) ++ return -EINVAL; ++ ++ err = nla_parse_nested(tb, TCA_MATCHALL_MAX, ++ tca[TCA_OPTIONS], mall_policy); ++ if (err < 0) ++ return err; ++ ++ f = kzalloc(sizeof(*f), GFP_KERNEL); ++ if (!f) ++ return -ENOBUFS; ++ ++ tcf_exts_init(&f->exts, TCA_MATCHALL_ACT, 0); ++ ++ if (!handle) ++ handle = 1; ++ f->handle = handle; ++ ++ err = mall_set_parms(net, tp, f, base, tb, tca[TCA_RATE], ovr); ++ if (err) ++ goto errout; ++ ++ *arg = (unsigned long) f; ++ rcu_assign_pointer(head->filter, f); ++ ++ return 0; ++ ++errout: ++ kfree(f); ++ return err; ++} ++ ++static int mall_delete(struct tcf_proto *tp, unsigned long arg) ++{ ++ struct cls_mall_head *head = rtnl_dereference(tp->root); ++ struct cls_mall_filter *f = (struct cls_mall_filter *) arg; ++ ++ RCU_INIT_POINTER(head->filter, NULL); ++ tcf_unbind_filter(tp, &f->res); ++ call_rcu(&f->rcu, mall_destroy_filter); ++ return 0; ++} ++ ++static void mall_walk(struct tcf_proto *tp, struct tcf_walker *arg) ++{ ++ struct cls_mall_head *head = rtnl_dereference(tp->root); ++ struct cls_mall_filter *f = head->filter; ++ ++ if (arg->count < arg->skip) ++ goto skip; ++ if (arg->fn(tp, (unsigned long) f, arg) < 0) ++ arg->stop = 1; ++skip: ++ arg->count++; ++} ++ ++static int mall_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, ++ struct sk_buff *skb, struct tcmsg *t) ++{ ++ struct cls_mall_filter *f = (struct cls_mall_filter *) fh; ++ struct nlattr *nest; ++ ++ if (!f) ++ return skb->len; ++ ++ t->tcm_handle = f->handle; ++ ++ nest = nla_nest_start(skb, TCA_OPTIONS); ++ if (!nest) ++ goto nla_put_failure; ++ ++ if (f->res.classid && ++ nla_put_u32(skb, TCA_MATCHALL_CLASSID, f->res.classid)) ++ goto nla_put_failure; ++ ++ if (tcf_exts_dump(skb, &f->exts)) ++ goto nla_put_failure; ++ ++ nla_nest_end(skb, nest); ++ ++ if (tcf_exts_dump_stats(skb, &f->exts) < 0) ++ goto nla_put_failure; ++ ++ return skb->len; ++ ++nla_put_failure: ++ nla_nest_cancel(skb, nest); ++ return -1; ++} ++ ++static struct tcf_proto_ops cls_mall_ops __read_mostly = { ++ .kind = "matchall", ++ .classify = mall_classify, ++ .init = mall_init, ++ .destroy = mall_destroy, ++ .get = mall_get, ++ .change = mall_change, ++ .delete = mall_delete, ++ .walk = mall_walk, ++ .dump = mall_dump, ++ .owner = THIS_MODULE, ++}; ++ ++static int __init cls_mall_init(void) ++{ ++ return register_tcf_proto_ops(&cls_mall_ops); ++} ++ ++static void __exit cls_mall_exit(void) ++{ ++ unregister_tcf_proto_ops(&cls_mall_ops); ++} ++ ++module_init(cls_mall_init); ++module_exit(cls_mall_exit); ++ ++MODULE_AUTHOR("Jiri Pirko "); ++MODULE_DESCRIPTION("Match-all classifier"); ++MODULE_LICENSE("GPL v2"); +--- a/net/sched/Kconfig ++++ b/net/sched/Kconfig +@@ -526,6 +526,16 @@ config NET_CLS_FLOWER + To compile this code as a module, choose M here: the module will + be called cls_flower. + ++config NET_CLS_MATCHALL ++ tristate "Match-all classifier" ++ select NET_CLS ++ ---help--- ++ If you say Y here, you will be able to classify packets based on ++ nothing. Every packet will match. ++ ++ To compile this code as a module, choose M here: the module will ++ be called cls_matchall. ++ + config NET_EMATCH + bool "Extended Matches" + select NET_CLS +--- a/net/sched/Makefile ++++ b/net/sched/Makefile +@@ -58,6 +58,7 @@ obj-$(CONFIG_NET_CLS_FLOW) += cls_flow.o + obj-$(CONFIG_NET_CLS_CGROUP) += cls_cgroup.o + obj-$(CONFIG_NET_CLS_BPF) += cls_bpf.o + obj-$(CONFIG_NET_CLS_FLOWER) += cls_flower.o ++obj-$(CONFIG_NET_CLS_MATCHALL) += cls_matchall.o + obj-$(CONFIG_NET_EMATCH) += ematch.o + obj-$(CONFIG_NET_EMATCH_CMP) += em_cmp.o + obj-$(CONFIG_NET_EMATCH_NBYTE) += em_nbyte.o From 324df5686110f668a7b9a0f59d5a15da097c66b6 Mon Sep 17 00:00:00 2001 From: Venkat Chimata Date: Wed, 28 Sep 2022 16:13:22 +0530 Subject: [PATCH 3/9] ipq50xx: Addp support for Liteon WPX8324 AP Specifications are: * CPU: Qualcomm IPQ5018 * RAM: 512 MB * Storage: 16MB ROR, 128MB NAND-optional. * Ethernet: 2x GBe * UART header * WLAN: QCN6122 + QCN8080 * 3x LED-s Installation instructions: Connect to UART, pins are like this (from the edge on LEDS): -> GND | RX | TX | GND | VCC Settings are 115200 8n1 1. Copy openwrt-ipq807x-liteon_wpx8324-squashfs-nand-factory.bin (attached) onto the board into /tmp/ 2. At board's command prompt, issue sysupgrade -n /tmp/openwrt-ipq807x-liteon_wpx8324-squashfs-nand-factory.bin Fixes: WIFI-10929 Signed-off-by: Venkat Chimata --- .github/workflows/build-dev.yml | 2 +- .../ipq807x/base-files/etc/board.d/01_leds | 5 + .../ipq807x/base-files/etc/board.d/02_network | 1 + .../etc/hotplug.d/firmware/10-ath11k-caldata | 4 +- .../base-files/lib/upgrade/platform.sh | 2 + .../boot/dts/qcom-ipq5018-liteon-wpx8324.dts | 23 + .../dts/qcom/qcom-ipq5018-liteon-wpx8324.dts | 812 ++++++++++++++++++ feeds/ipq807x/ipq807x/image/ipq50xx.mk | 9 + feeds/wifi-ax/ath11k-wifi/Makefile | 2 + .../board-liteon-wpx8324.bin.IPQ5018 | Bin 0 -> 131072 bytes .../board-liteon-wpx8324.bin.QCN6122 | Bin 0 -> 131072 bytes profiles/liteon_wpx8324.yml | 16 + 12 files changed, 874 insertions(+), 2 deletions(-) create mode 100644 feeds/ipq807x/ipq807x/files/arch/arm/boot/dts/qcom-ipq5018-liteon-wpx8324.dts create mode 100755 feeds/ipq807x/ipq807x/files/arch/arm64/boot/dts/qcom/qcom-ipq5018-liteon-wpx8324.dts create mode 100644 feeds/wifi-ax/ath11k-wifi/board-liteon-wpx8324.bin.IPQ5018 create mode 100644 feeds/wifi-ax/ath11k-wifi/board-liteon-wpx8324.bin.QCN6122 create mode 100644 profiles/liteon_wpx8324.yml diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml index 744784040..c56061029 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', 'edgecore_ecs4100-12ph', 'edgecore_ecw5211', 'edgecore_ecw5410', 'edgecore_oap100', 'edgecore_ssw2ac2600', 'edgecore_spw2ac1200', 'edgecore_spw2ac1200-lan-poe', 'hfcl_ion4', 'hfcl_ion4xe', 'hfcl_ion4xi', 'indio_um-305ac', 'indio_um-305ax', 'indio_um-325ac', 'indio_um-510ac-v3', 'indio_um-550ac', 'linksys_ea6350-v4', 'linksys_e8450-ubi', 'linksys_ea8300', 'meshpp_s618_cp03', 'meshpp_s618_cp01', 'udaya_a5-id2', 'wallys_dr40x9', 'wallys_dr6018', 'x64_vm' ] + 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', 'indio_um-305ac', 'indio_um-305ax', 'indio_um-325ac', 'indio_um-510ac-v3', 'indio_um-550ac', 'linksys_ea6350-v4', 'linksys_e8450-ubi', 'linksys_ea8300', 'meshpp_s618_cp03', 'meshpp_s618_cp01', 'udaya_a5-id2', 'wallys_dr40x9', 'wallys_dr6018', 'x64_vm' ] steps: - uses: actions/checkout@v2 diff --git a/feeds/ipq807x/ipq807x/base-files/etc/board.d/01_leds b/feeds/ipq807x/ipq807x/base-files/etc/board.d/01_leds index 603bc9b6e..1fb1873e1 100755 --- a/feeds/ipq807x/ipq807x/base-files/etc/board.d/01_leds +++ b/feeds/ipq807x/ipq807x/base-files/etc/board.d/01_leds @@ -34,6 +34,11 @@ edgecore,eap104) ucidef_set_led_wlan "wlan5g" "WLAN5G" "green:wifi5" "phy1tpt" ucidef_set_led_netdev "wan" "wan" "yellow:uplink" "eth0" ;; +liteon,wpx8324) + ucidef_set_led_wlan "wlan2g" "WLAN2G" "orange:wifi2" "phy0tpt" + ucidef_set_led_wlan "wlan5g" "WLAN5G" "green:wifi5" "phy1tpt" + ucidef_set_led_netdev "wan" "wan" "blue:uplink" "eth0" + ;; hfcl,ion4xi|\ hfcl,ion4xe) ucidef_set_led_wlan "wlan5g" "WLAN5G" "blue:wifi5" "phy0tpt" diff --git a/feeds/ipq807x/ipq807x/base-files/etc/board.d/02_network b/feeds/ipq807x/ipq807x/base-files/etc/board.d/02_network index 61b3d77b6..b1eef6cfd 100755 --- a/feeds/ipq807x/ipq807x/base-files/etc/board.d/02_network +++ b/feeds/ipq807x/ipq807x/base-files/etc/board.d/02_network @@ -50,6 +50,7 @@ qcom_setup_interfaces() ;; edgecore,eap102|\ edgecore,eap104|\ + liteon,wpx8324|\ wallys,dr6018|\ cig,wf188n|\ cig,wf196) 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 a39bf0cbd..e42dae0dc 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 @@ -124,6 +124,7 @@ ath11k/IPQ5018/hw1.0/caldata.bin) case "$board" in cybertan,eww622-a1|\ edgecore,eap104|\ + liteon,wpx8324|\ motorola,q14|\ qcom,ipq5018-mp03.1) caldata_extract "0:ART" 0x1000 0x20000 @@ -140,7 +141,8 @@ ath11k/qcn6122/hw1.0/caldata_1.bin) ath11k/qcn6122/hw1.0/caldata_2.bin) case "$board" in motorola,q14|\ - edgecore,eap104) + edgecore,eap104|\ + liteon,wpx8324) caldata_extract "0:ART" 0x4c000 0x20000 ;; esac diff --git a/feeds/ipq807x/ipq807x/base-files/lib/upgrade/platform.sh b/feeds/ipq807x/ipq807x/base-files/lib/upgrade/platform.sh index 22531c43b..9cfc3584d 100755 --- a/feeds/ipq807x/ipq807x/base-files/lib/upgrade/platform.sh +++ b/feeds/ipq807x/ipq807x/base-files/lib/upgrade/platform.sh @@ -84,6 +84,7 @@ platform_check_image() { edgecore,eap101|\ edgecore,eap102|\ edgecore,eap104|\ + liteon,wpx8324|\ edgecore,eap106|\ hfcl,ion4xi|\ hfcl,ion4xe|\ @@ -151,6 +152,7 @@ platform_do_upgrade() { nand_upgrade_tar "$1" ;; edgecore,eap104|\ + liteon,wpx8324|\ edgecore,eap106) CI_UBIPART="rootfs1" [ "$(find_mtd_chardev rootfs)" ] && CI_UBIPART="rootfs" diff --git a/feeds/ipq807x/ipq807x/files/arch/arm/boot/dts/qcom-ipq5018-liteon-wpx8324.dts b/feeds/ipq807x/ipq807x/files/arch/arm/boot/dts/qcom-ipq5018-liteon-wpx8324.dts new file mode 100644 index 000000000..7fbff974a --- /dev/null +++ b/feeds/ipq807x/ipq807x/files/arch/arm/boot/dts/qcom-ipq5018-liteon-wpx8324.dts @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "../../../arm64/boot/dts/qcom/qcom-ipq5018-liteon-wpx8324.dts" + +/ { + pmuv8: pmu { + compatible = "arm,cortex-a7-pmu"; + }; +}; diff --git a/feeds/ipq807x/ipq807x/files/arch/arm64/boot/dts/qcom/qcom-ipq5018-liteon-wpx8324.dts b/feeds/ipq807x/ipq807x/files/arch/arm64/boot/dts/qcom/qcom-ipq5018-liteon-wpx8324.dts new file mode 100755 index 000000000..dc73934cd --- /dev/null +++ b/feeds/ipq807x/ipq807x/files/arch/arm64/boot/dts/qcom/qcom-ipq5018-liteon-wpx8324.dts @@ -0,0 +1,812 @@ +/dts-v1/; +/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "qcom-ipq5018.dtsi" + +/ { + #address-cells = <0x2>; + #size-cells = <0x2>; + model = "Liteon WPX8324"; + compatible = "liteon,wpx8324", "qcom,ipq5018-mp03.5-c1", "qcom,ipq5018"; + interrupt-parent = <&intc>; + + aliases { + sdhc1 = &sdhc_1; /* SDC1 eMMC slot */ + serial0 = &blsp1_uart1; + /*serial1 = &blsp1_uart2;*/ + ethernet0 = "/soc/dp1"; + ethernet1 = "/soc/dp2"; + }; + + chosen { + bootargs = "console=ttyMSM0,115200,n8 rw init=/init"; + #ifdef __IPQ_MEM_PROFILE_256_MB__ + bootargs-append = " swiotlb=1"; + #else + bootargs-append = " swiotlb=1 coherent_pool=2M"; + #endif + stdout-path = "serial0"; + }; + + reserved-memory { + #ifdef __IPQ_MEM_PROFILE_256_MB__ + /* 256 MB Profile + * +==========+==============+=========================+ + * | | | | + * | Region | Start Offset | Size | + * | | | | + * +----------+--------------+-------------------------+ + * | NSS | 0x40000000 | 8MB | + * +----------+--------------+-------------------------+ + * | Linux | 0x40800000 | Depends on total memory | + * +----------+--------------+-------------------------+ + * | uboot | 0x4A600000 | 4MB | + * +----------+--------------+-------------------------+ + * | SBL | 0x4AA00000 | 1MB | + * +----------+--------------+-------------------------+ + * | smem | 0x4AB00000 | 1MB | + * +----------+--------------+-------------------------+ + * | TZ | 0x4AC00000 | 4MB | + * +----------+--------------+-------------------------+ + * | Q6 | | | + * | code/ | 0x4B000000 | 20MB | + * | data | | | + * +----------+--------------+-------------------------+ + * | IPQ5018 | | | + * | data | 0x4C400000 | 13MB | + * +----------+--------------+-------------------------+ + * | IPQ5018 | | | + * | M3 Dump | 0x4D100000 | 1MB | + * +----------+--------------+-------------------------+ + * | IPQ5018 | | | + * | QDSS | 0x4D200000 | 1MB | + * +----------+--------------+-------------------------+ + * | QCN6122_1| | | + * | data | 0x4D300000 | 15MB | + * +----------+--------------+-------------------------+ + * | QCN6122_1| | | + * | M3 Dump | 0x4E200000 | 1MB | + * +----------+--------------+-------------------------+ + * | QCN6122_1| | | + * | QDSS | 0x4E300000 | 1MB | + * +----------+--------------+-------------------------+ + * | QCN6122_2| | | + * | data | 0x4E400000 | 15MB | + * +----------+--------------+-------------------------+ + * | QCN6122_2| | | + * | M3 Dump | 0x4F300000 | 1MB | + * +----------+--------------+-------------------------+ + * | QCN6122_2| | | + * | QDSS | 0x4F400000 | 1MB | + * +----------+--------------+-------------------------+ + * | | + * | Rest of the memory for Linux | + * | | + * +===================================================+ + */ + q6_mem_regions: q6_mem_regions@4B000000 { + no-map; + reg = <0x0 0x4B000000 0x0 0x4500000>; + }; + + q6_code_data: q6_code_data@4B000000 { + no-map; + reg = <0x0 0x4B000000 0x0 0x1400000>; + }; + + q6_ipq5018_data: q6_ipq5018_data@4C400000 { + no-map; + reg = <0x0 0x4C400000 0x0 0xD00000>; + }; + + m3_dump: m3_dump@4D100000 { + no-map; + reg = <0x0 0x4D100000 0x0 0x100000>; + }; + + q6_etr_region: q6_etr_dump@4D200000 { + no-map; + reg = <0x0 0x4D200000 0x0 0x100000>; + }; + + q6_qcn6122_data1: q6_qcn6122_data1@4D300000 { + no-map; + reg = <0x0 0x4D300000 0x0 0xF00000>; + }; + + m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E200000 { + no-map; + reg = <0x0 0x4E200000 0x0 0x100000>; + }; + + q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E300000 { + no-map; + reg = <0x0 0x4E300000 0x0 0x100000>; + }; + + q6_qcn6122_data2: q6_qcn6122_data2@4E400000 { + no-map; + reg = <0x0 0x4E400000 0x0 0xF00000>; + }; + + m3_dump_qcn6122_2: m3_dump_qcn6122_2@4F300000 { + no-map; + reg = <0x0 0x4F300000 0x0 0x100000>; + }; + + q6_qcn6122_etr_2: q6_qcn6122_etr_2@4F400000 { + no-map; + reg = <0x0 0x4F400000 0x0 0x100000>; + }; + #else + /* 512MB/1GB Profiles + * +==========+==============+=========================+ + * | | | | + * | Region | Start Offset | Size | + * | | | | + * +----------+--------------+-------------------------+ + * | NSS | 0x40000000 | 16MB | + * +----------+--------------+-------------------------+ + * | Linux | 0x41000000 | Depends on total memory | + * +----------+--------------+-------------------------+ + * | uboot | 0x4A600000 | 4MB | + * +----------+--------------+-------------------------+ + * | SBL | 0x4AA00000 | 1MB | + * +----------+--------------+-------------------------+ + * | smem | 0x4AB00000 | 1MB | + * +----------+--------------+-------------------------+ + * | TZ | 0x4AC00000 | 4MB | + * +----------+--------------+-------------------------+ + * | Q6 | | | + * | code/ | 0x4B000000 | 20MB | + * | data | | | + * +----------+--------------+-------------------------+ + * | IPQ5018 | | | + * | data | 0x4C400000 | 14MB | + * +----------+--------------+-------------------------+ + * | IPQ5018 | | | + * | M3 Dump | 0x4D200000 | 1MB | + * +----------+--------------+-------------------------+ + * | IPQ5018 | | | + * | QDSS | 0x4D300000 | 1MB | + * +----------+--------------+-------------------------+ + * | IPQ5018 | | | + * | Caldb | 0x4D400000 | 2MB | + * +----------+--------------+-------------------------+ + * | QCN6122_1| | | + * | data | 0x4D600000 | 16MB | + * +----------+--------------+-------------------------+ + * | QCN6122_1| | | + * | M3 Dump | 0x4E600000 | 1MB | + * +----------+--------------+-------------------------+ + * | QCN6122_1| | | + * | QDSS | 0x4E700000 | 1MB | + * +----------+--------------+-------------------------+ + * | QCN6122_1| | | + * | Caldb | 0x4E800000 | 5MB | + * +----------+--------------+-------------------------+ + * | QCN6122_2| | | + * | data | 0x4ED00000 | 16MB | + * +----------+--------------+-------------------------+ + * | QCN6122_2| | | + * | M3 Dump | 0x4FD00000 | 1MB | + * +----------+--------------+-------------------------+ + * | QCN6122_2| | | + * | QDSS | 0x4FE00000 | 1MB | + * +----------+--------------+-------------------------+ + * | QCN6122_2| | | + * | Caldb | 0x4FF00000 | 5MB | + * +----------+--------------+-------------------------+ + * | | + * | Rest of the memory for Linux | + * | | + * +===================================================+ + */ + q6_mem_regions: q6_mem_regions@4B000000 { + no-map; + reg = <0x0 0x4B000000 0x0 0x5400000>; + }; + + q6_code_data: q6_code_data@4B000000 { + no-map; + reg = <0x0 0x4B000000 0x0 01400000>; + }; + + q6_ipq5018_data: q6_ipq5018_data@4C400000 { + no-map; + reg = <0x0 0x4C400000 0x0 0xE00000>; + }; + + m3_dump: m3_dump@4D200000 { + no-map; + reg = <0x0 0x4D200000 0x0 0x100000>; + }; + + q6_etr_region: q6_etr_dump@4D300000 { + no-map; + reg = <0x0 0x4D300000 0x0 0x100000>; + }; + + q6_caldb_region: q6_caldb_region@4D400000 { + no-map; + reg = <0x0 0x4D400000 0x0 0x200000>; + }; + + q6_qcn6122_data1: q6_qcn6122_data1@4D600000 { + no-map; + reg = <0x0 0x4D600000 0x0 0x1000000>; + }; + + m3_dump_qcn6122_1: m3_dump_qcn6122_1@4E600000 { + no-map; + reg = <0x0 0x4E600000 0x0 0x100000>; + }; + + q6_qcn6122_etr_1: q6_qcn6122_etr_1@4E700000 { + no-map; + reg = <0x0 0x4E700000 0x0 0x100000>; + }; + + q6_qcn6122_caldb_1: q6_qcn6122_caldb_1@4E800000 { + no-map; + reg = <0x0 0x4E800000 0x0 0x500000>; + }; + + q6_qcn6122_data2: q6_qcn6122_data2@4E900000 { + no-map; + reg = <0x0 0x4ED00000 0x0 0x1000000>; + }; + + m3_dump_qcn6122_2: m3_dump_qcn6122_2@4FD00000 { + no-map; + reg = <0x0 0x4FD00000 0x0 0x100000>; + }; + + q6_qcn6122_etr_2: q6_qcn6122_etr_2@4FE00000 { + no-map; + reg = <0x0 0x4FE00000 0x0 0x100000>; + }; + + q6_qcn6122_caldb_2: q6_qcn6122_caldb_2@4FF00000 { + no-map; + reg = <0x0 0x4FF00000 0x0 0x500000>; + }; + + #endif + }; + + soc { + serial@78af000 { + status = "ok"; + }; + qpic_bam: dma@7984000{ + status = "ok"; + }; + + nand: qpic-nand@79b0000 { + pinctrl-0 = <&qspi_nand_pins>; + pinctrl-names = "default"; + status = "ok"; + }; + + spi_0: spi@78b5000 { /* BLSP1 QUP0 */ + pinctrl-0 = <&blsp0_spi_pins>; + pinctrl-names = "default"; + cs-select = <0>; + status = "ok"; + + m25p80@0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + compatible = "n25q128a11"; + linux,modalias = "m25p80", "n25q128a11"; + spi-max-frequency = <50000000>; + use-default-sizes; + }; + }; + + spi_2: spi@78b7000 { /* BLSP1 QUP2 */ + pinctrl-0 = <&blsp2_spi0_pins>; + pinctrl-names = "default"; + cs-select = <0>; + status = "ok"; + + tpm0: slb9670@0 { + #address-cells = <1>; + #size-cells = <1>; + reg = <1>; /* CE1 */ + compatible = "infineon,slb9670"; + linux,modalias = "slb9670", "slb9670a11"; + spi-max-frequency = <50000000>; + use-default-sizes; + }; + }; + + mdio0: mdio@88000 { + status = "ok"; + + ethernet-phy@0 { + reg = <7>; + }; + }; + + mdio1: mdio@90000 { + status = "ok"; + pinctrl-0 = <&mdio1_pins>; + pinctrl-names = "default"; + phy-reset-gpio = <&tlmm 26 0>; + + ethernet-phy@0 { + reg = <28>; + }; + }; + + ess-instance { + num_devices = <0x1>; + ess-switch@0x39c00000 { + switch_mac_mode = <0xf>; /* mac mode for uniphy instance*/ + cmnblk_clk = "internal_96MHz"; /* cmnblk clk*/ + qcom,port_phyinfo { + port@0 { + port_id = <1>; + phy_address = <7>; + mdiobus = <&mdio0>; + }; + port@1 { + port_id = <2>; + phy_address = <0x1c>; + mdiobus = <&mdio1>; + port_mac_sel = "QGMAC_PORT"; + }; + }; + led_source@0 { + source = <0>; + mode = "normal"; + speed = "all"; + blink_en = "enable"; + active = "high"; + }; + }; + }; + wifi0: wifi@c000000 { + status = "ok"; + }; + + dp1 { + device_type = "network"; + compatible = "qcom,nss-dp"; + clocks = <&gcc GCC_SNOC_GMAC0_AXI_CLK>; + clock-names = "nss-snoc-gmac-axi-clk"; + qcom,id = <1>; + reg = <0x39C00000 0x10000>; + interrupts = ; + qcom,mactype = <2>; + qcom,link-poll = <1>; + qcom,phy-mdio-addr = <7>; + mdio-bus = <&mdio0>; + local-mac-address = [000000000000]; + phy-mode = "sgmii"; + }; + + dp2 { + device_type = "network"; + compatible = "qcom,nss-dp"; + clocks = <&gcc GCC_SNOC_GMAC1_AXI_CLK>; + clock-names = "nss-snoc-gmac-axi-clk"; + qcom,id = <2>; + reg = <0x39D00000 0x10000>; + interrupts = ; + qcom,mactype = <2>; + qcom,link-poll = <1>; + qcom,phy-mdio-addr = <28>; + mdio-bus = <&mdio1>; + local-mac-address = [000000000000]; + phy-mode = "sgmii"; + }; + + qcom,test@0 { + status = "ok"; + }; + }; + + thermal-zones { + status = "ok"; + }; + leds { + compatible = "gpio-leds"; + pinctrl-0 = <&leds_pins>; + pinctrl-names = "default"; + + led_blue: led@19 { + label = "blue:uplink"; + gpios = <&tlmm 19 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + led_orange: led@18 { + label = "orange:wifi2"; + gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + led_green: led@39 { + label = "green:wifi5"; + gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; +}; + +&tlmm { + pinctrl-0 = <&blsp0_uart_pins &phy_led_pins>; + pinctrl-names = "default"; + + leds_pins: leds_pins { + led_blue { + pins = "gpio19"; + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; + led_orange { + pins = "gpio18"; + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; + led_green { + pins = "gpio39"; + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; + }; + blsp0_uart_pins: uart_pins { + blsp0_uart_rx_tx { + pins = "gpio20", "gpio21"; + function = "blsp0_uart0"; + bias-disable; + }; + }; + + blsp0_spi_pins: blsp0_spi_pins { + mux { + pins = "gpio10", "gpio11", "gpio12", "gpio13"; + function = "blsp0_spi"; + drive-strength = <2>; + bias-disable; + }; + }; + + blsp2_spi0_pins: blsp2_spi0_pins { + mux { + pins = "gpio31", "gpio32", "gpio33", "gpio34"; + function = "blsp2_spi0"; + drive-strength = <2>; + bias-disable; + }; + }; + + qspi_nand_pins: qspi_nand_pins { + qspi_clock { + pins = "gpio9"; + function = "qspi_clk"; + drive-strength = <8>; + bias-disable; + }; + qspi_cs { + pins = "gpio8"; + function = "qspi_cs"; + drive-strength = <8>; + bias-disable; + }; + qspi_data_0 { + pins = "gpio7"; + function = "qspi0"; + drive-strength = <8>; + bias-disable; + }; + qspi_data_1 { + pins = "gpio6"; + function = "qspi1"; + drive-strength = <8>; + bias-disable; + }; + qspi_data_2 { + pins = "gpio5"; + function = "qspi2"; + drive-strength = <8>; + bias-disable; + }; + qspi_data_3 { + pins = "gpio4"; + function = "qspi3"; + drive-strength = <8>; + bias-disable; + }; + }; + + mdio1_pins: mdio_pinmux { + mux_0 { + pins = "gpio36"; + function = "mdc"; + drive-strength = <8>; + bias-pull-up; + }; + + mux_1 { + pins = "gpio37"; + function = "mdio"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + phy_led_pins: phy_led_pins { + gephy_led_pin { + pins = "gpio18", "gpio19", "gpio39"; + /* function = "led0"; */ + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; + }; + + i2c_pins: i2c_pins { + i2c_scl { + pins = "gpio25"; + function = "blsp2_i2c1"; + drive-strength = <8>; + bias-disable; + }; + + i2c_sda { + pins = "gpio26"; + function = "blsp2_i2c1"; + drive-strength = <8>; + bias-disable; + }; + }; + + button_pins: button_pins { + wps_button { + pins = "gpio29"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + }; +}; + +&soc { + gpio_keys { + compatible = "gpio-keys"; + pinctrl-0 = <&button_pins>; + pinctrl-names = "default"; + + button@1 { + label = "wps"; + linux,code = ; + gpios = <&tlmm 29 GPIO_ACTIVE_LOW>; + linux,input-type = <1>; + debounce-interval = <60>; + }; + }; +}; + +&usb3 { + status = "ok"; + device-power-gpio = <&tlmm 28 0>; +}; + +&eud { + status = "ok"; +}; + +&pcie_x1 { + status = "disabled"; + perst-gpio = <&tlmm 18 1>; +}; + +&pcie_x2 { + status = "disabled"; + perst-gpio = <&tlmm 15 1>; +}; + +&dwc_0 { + /delete-property/ #phy-cells; + /delete-property/ phys; + /delete-property/ phy-names; +}; + +&hs_m31phy_0 { + status = "ok"; +}; + +&pcie_x1phy { + status = "disabled"; +}; + +&pcie_x2phy { + status = "disabled"; +}; + +&pcie_x1_rp { + status = "disabled"; + + mhi_0: qcom,mhi@0 { + reg = <0 0 0 0 0 >; + }; +}; + +&pcie_x2_rp { + status = "disabled"; + + mhi_1: qcom,mhi@1 { + reg = <0 0 0 0 0 >; + + }; +}; + +&qfprom { + status = "ok"; +}; + +&tsens { + status = "ok"; +}; + +&qcom_q6v5_wcss { + qcom,multipd_arch; + memory-region = <&q6_mem_regions>; + qcom,share_bootargs; + qcom,bootargs_smem = <507>; + boot-args = <0x1 0x4 0x3 0x0F 0x0 0x0>, + <0x2 0x4 0x2 0x12 0x0 0x0>; + /* IPQ5018 */ + q6v5_wcss_userpd1 { + m3_firmware = "IPQ5018/m3_fw.mdt"; + interrupts-extended = <&wcss_smp2p_in 8 0>, + <&wcss_smp2p_in 9 0>, + <&wcss_smp2p_in 12 0>, + <&wcss_smp2p_in 11 0>; + interrupt-names ="fatal", + "ready", + "spawn_ack", + "stop-ack"; + qcom,smem-states = <&wcss_smp2p_out 8>, + <&wcss_smp2p_out 9>, + <&wcss_smp2p_out 10>; + qcom,smem-state-names = "shutdown", + "stop", + "spawn"; + qca,asid = <1>; + qca,auto-restart; + qca,int_radio; + #ifdef __IPQ_MEM_PROFILE_256_MB__ + memory-region = <&q6_ipq5018_data>, <&m3_dump>, + <&q6_etr_region>; + #else + memory-region = <&q6_ipq5018_data>, <&m3_dump>, + <&q6_etr_region>, <&q6_caldb_region>; + #endif + }; + + /* QCN6122 6G */ + q6v5_wcss_userpd2 { + m3_firmware = "qcn6122/m3_fw.mdt"; + interrupts-extended = <&wcss_smp2p_in 16 0>, + <&wcss_smp2p_in 17 0>, + <&wcss_smp2p_in 20 0>, + <&wcss_smp2p_in 19 0>; + interrupt-names ="fatal", + "ready", + "spawn_ack", + "stop-ack"; + qcom,smem-states = <&wcss_smp2p_out 16>, + <&wcss_smp2p_out 17>, + <&wcss_smp2p_out 18>; + qcom,smem-state-names = "shutdown", + "stop", + "spawn"; + qca,asid = <2>; + qca,auto-restart; + #ifdef __IPQ_MEM_PROFILE_256_MB__ + memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>, + <&q6_qcn6122_etr_1>; + #else + memory-region = <&q6_qcn6122_data1>, <&m3_dump_qcn6122_1>, + <&q6_qcn6122_etr_1>, <&q6_qcn6122_caldb_1>; + #endif + }; + + /* QCN6122 5G */ + q6v5_wcss_userpd3 { + m3_firmware = "qcn6122/m3_fw.mdt"; + interrupts-extended = <&wcss_smp2p_in 24 0>, + <&wcss_smp2p_in 25 0>, + <&wcss_smp2p_in 28 0>, + <&wcss_smp2p_in 27 0>; + interrupt-names ="fatal", + "ready", + "spawn_ack", + "stop-ack"; + qcom,smem-states = <&wcss_smp2p_out 24>, + <&wcss_smp2p_out 25>, + <&wcss_smp2p_out 26>; + qcom,smem-state-names = "shutdown", + "stop", + "spawn"; + qca,asid = <3>; + qca,auto-restart; + #ifdef __IPQ_MEM_PROFILE_256_MB__ + memory-region = <&q6_qcn6122_data2>, <&m3_dump_qcn6122_2>, + <&q6_qcn6122_etr_2>; + #else + memory-region = <&q6_qcn6122_data2>, <&m3_dump_qcn6122_2>, + <&q6_qcn6122_etr_2>, <&q6_qcn6122_caldb_2>; + #endif + }; +}; + +&qgic_msi_0 { + status = "ok"; +}; + +&qgic_msi_1 { + status = "ok"; +}; + +&wifi0 { + /* IPQ5018 */ + qcom,multipd_arch; + qcom,userpd-subsys-name = "q6v5_wcss_userpd1"; +#ifdef __IPQ_MEM_PROFILE_256_MB__ + qcom,tgt-mem-mode = <2>; +#else + qcom,tgt-mem-mode = <1>; +#endif + qcom,board_id = <0x24>; + qcom,bdf-addr = <0x4C400000 0x4C400000 0x4C400000 0x0 0x0>; +#ifdef __CNSS2__ + qcom,caldb-addr = <0x4D400000 0x4D400000 0 0 0>; +#else + qcom,caldb-addr = <0x4D400000>; + m3-dump-addr = <0x4D200000>; +#endif + qcom,caldb-size = <0x200000>; + status = "ok"; +}; + +&wifi1 { + /* QCN6122 5G */ + qcom,multipd_arch; + qcom,userpd-subsys-name = "q6v5_wcss_userpd3"; +#ifdef __IPQ_MEM_PROFILE_256_MB__ + qcom,tgt-mem-mode = <2>; +#else + qcom,tgt-mem-mode = <1>; +#endif + qcom,board_id = <0x60>; + qcom,bdf-addr = <0x4ED00000 0x4ED00000 0x4E400000 0x0 0x0>; +#ifdef __CNSS2__ + qcom,caldb-addr = <0x4FF00000 0x4FF00000 0 0 0>; +#else + qcom,caldb-addr = <0x4FF00000>; + m3-dump-addr = <0x4FD00000>; +#endif + qcom,caldb-size = <0x500000>; + status = "ok"; +}; diff --git a/feeds/ipq807x/ipq807x/image/ipq50xx.mk b/feeds/ipq807x/ipq807x/image/ipq50xx.mk index 87b599c5f..2f609db64 100644 --- a/feeds/ipq807x/ipq807x/image/ipq50xx.mk +++ b/feeds/ipq807x/ipq807x/image/ipq50xx.mk @@ -18,6 +18,15 @@ define Device/edgecore_eap104 endef TARGET_DEVICES += edgecore_eap104 +define Device/liteon_wpx8324 + DEVICE_TITLE := Liteon WPX8324 + DEVICE_DTS := qcom-ipq5018-liteon-wpx8324 + SUPPORTED_DEVICES := liteon,wpx8324 + DEVICE_PACKAGES := ath11k-wifi-liteon-wpx8324 ath11k-firmware-ipq50xx-spruce ath11k-firmware-qcn6122 + DEVICE_DTS_CONFIG := config@mp03.5-c1 +endef +TARGET_DEVICES += liteon_wpx8324 + define Device/motorola_q14 DEVICE_TITLE := Motorola Q14 DEVICE_DTS := qcom-ipq5018-q14 diff --git a/feeds/wifi-ax/ath11k-wifi/Makefile b/feeds/wifi-ax/ath11k-wifi/Makefile index 3798680d9..aa28d87af 100644 --- a/feeds/wifi-ax/ath11k-wifi/Makefile +++ b/feeds/wifi-ax/ath11k-wifi/Makefile @@ -36,6 +36,7 @@ ALLWIFIBOARDS:= \ sercomm-wallaby \ edgecore-eap102 \ edgecore-eap104 \ + liteon-wpx8324 \ indio-um-310ax-v1 \ indio-um-510axp-v1 \ indio-um-510axm-v1 \ @@ -243,6 +244,7 @@ $(eval $(call generate-ath11k-wifi-package,wallys-dr6018-v4,Wallys DR6018 V4)) $(eval $(call generate-ath11k-wifi-package,edgecore-eap101,EdgeCore EAP101)) $(eval $(call generate-ath11k-wifi-package,edgecore-eap102,Edgecore EAP102)) $(eval $(call generate-ath11k-wifi-package,edgecore-eap104,Edgecore EAP104)) +$(eval $(call generate-ath11k-wifi-package,liteon-wpx8324,Liteon WPX8324)) $(eval $(call generate-ath11k-wifi-package,indio-um-310ax-v1,Indio UM-310AX V1)) $(eval $(call generate-ath11k-wifi-package,indio-um-510axp-v1,Indio UM-510AXP V1)) $(eval $(call generate-ath11k-wifi-package,indio-um-510axm-v1,Indio UM-510AXM V1)) diff --git a/feeds/wifi-ax/ath11k-wifi/board-liteon-wpx8324.bin.IPQ5018 b/feeds/wifi-ax/ath11k-wifi/board-liteon-wpx8324.bin.IPQ5018 new file mode 100644 index 0000000000000000000000000000000000000000..c4cf19c7a6cb36067a5f1f88e7b88b1ede7ecb80 GIT binary patch literal 131072 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 Date: Tue, 20 Sep 2022 08:39:36 +0200 Subject: [PATCH 4/9] ucode: update to latest HEAD Fixes: WIFI-10190 Fixes: WIFI-10194 Signed-off-by: John Crispin --- feeds/ucentral/ucode/Makefile | 5 +++-- feeds/ucentral/ucode/patches/0001-fixes.patch | 12 ------------ 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/feeds/ucentral/ucode/Makefile b/feeds/ucentral/ucode/Makefile index 94342744e..190cd0b32 100644 --- a/feeds/ucentral/ucode/Makefile +++ b/feeds/ucentral/ucode/Makefile @@ -12,9 +12,10 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=https://github.com/jow-/ucode.git -PKG_MIRROR_HASH:=98303ef9d5fa7eca04042792abaf8a2e66082237a23a89a7f5e72e4409714a72 +PKG_MIRROR_HASH:=413a08ee63c30c44d6f0a5de14b1c84787f9bd1fe8b125c8e4956aa2884cc933 +#PKG_MIRROR_HASH:=98303ef9d5fa7eca04042792abaf8a2e66082237a23a89a7f5e72e4409714a72 PKG_SOURCE_DATE:=2022-04-07 -PKG_SOURCE_VERSION:=456d3f1811aaf864ac0071232e6783ae1779c32a +PKG_SOURCE_VERSION:=7fa59ce44b9347528b0e4e44ebcfb04a08479f3f PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=ISC diff --git a/feeds/ucentral/ucode/patches/0001-fixes.patch b/feeds/ucentral/ucode/patches/0001-fixes.patch index 5441ebd75..ebf17876a 100644 --- a/feeds/ucentral/ucode/patches/0001-fixes.patch +++ b/feeds/ucentral/ucode/patches/0001-fixes.patch @@ -100,15 +100,3 @@ Index: ucode-2022-04-07-33f1e0b0/lib/nl80211.c static const uc_nl_nested_spec_t nl80211_sta_info_nla = { .headsize = 0, .nattrs = 35, -Index: ucode-2022-04-07-33f1e0b0/lib/rtnl.c -=================================================================== ---- ucode-2022-04-07-33f1e0b0.orig/lib/rtnl.c -+++ ucode-2022-04-07-33f1e0b0/lib/rtnl.c -@@ -682,6 +682,7 @@ static const uc_nl_nested_spec_t link_ms - { IFLA_UNSPEC, "type", DT_U16, 0, MEMBER(ifinfomsg, ifi_type) }, - { IFLA_UNSPEC, "dev", DT_NETDEV, 0, MEMBER(ifinfomsg, ifi_index) }, - { IFLA_UNSPEC, "flags", DT_FLAGS, 0, MEMBER(ifinfomsg, ifi_flags) }, -+ { IFLA_UNSPEC, "change", DT_FLAGS, 0, MEMBER(ifinfomsg, ifi_change) }, - { IFLA_ADDRESS, "address", DT_LLADDR, 0, NULL }, - { IFLA_BROADCAST, "broadcast", DT_LLADDR, 0, NULL }, - { IFLA_TXQLEN, "txqlen", DT_U32, 0, NULL }, From 0c9499c085da776dc16901f3f248adc774272dd7 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 20 Sep 2022 08:39:52 +0200 Subject: [PATCH 5/9] ratelimit: replace script with daemon Fixes: WIFI-10190 Fixes: WIFI-10194 Signed-off-by: John Crispin --- .../files/etc/hotplug.d/net/30-ratelimit | 4 +- .../ratelimit/files/etc/init.d/ratelimit | 37 ++ .../ratelimit/files/usr/bin/ratelimit | 437 ++++++++++++------ .../files/usr/libexec/ratelimit-wait.sh | 4 + .../ratelimit/files/usr/libexec/ratelimit.sh | 11 +- 5 files changed, 352 insertions(+), 141 deletions(-) create mode 100755 feeds/ucentral/ratelimit/files/etc/init.d/ratelimit create mode 100755 feeds/ucentral/ratelimit/files/usr/libexec/ratelimit-wait.sh diff --git a/feeds/ucentral/ratelimit/files/etc/hotplug.d/net/30-ratelimit b/feeds/ucentral/ratelimit/files/etc/hotplug.d/net/30-ratelimit index 0643d6071..8c1945416 100644 --- a/feeds/ucentral/ratelimit/files/etc/hotplug.d/net/30-ratelimit +++ b/feeds/ucentral/ratelimit/files/etc/hotplug.d/net/30-ratelimit @@ -3,11 +3,11 @@ [ "${INTERFACE:0:4}" == "wlan" ] || exit 0 [ "$ACTION" == remove ] && { - ratelimit deliface $INTERFACE + [ -f /tmp/run/hostapd-cli-$INTERFACE.pid ] && kill "$(cat /tmp/run/hostapd-cli-$INTERFACE.pid)" exit 0 } [ "$ACTION" == add ] && { - ratelimit waitiface $INTERFACE & + /usr/libexec/ratelimit-wait.sh $INTERFACE & exit 0 } diff --git a/feeds/ucentral/ratelimit/files/etc/init.d/ratelimit b/feeds/ucentral/ratelimit/files/etc/init.d/ratelimit new file mode 100755 index 000000000..fa313f232 --- /dev/null +++ b/feeds/ucentral/ratelimit/files/etc/init.d/ratelimit @@ -0,0 +1,37 @@ +#!/bin/sh /etc/rc.common + +START=80 + +USE_PROCD=1 +PROG=/usr/bin/ratelimit + +add_rate() { + local cfg="$1" + config_get ssid "$cfg" ssid + config_get ingress "$cfg" ingress + config_get egress "$cfg" egress + ubus call ratelimit defaults_set '{"name": "'$ssid'", "rate_ingress": "'$ingress'mbit", "rate_egress": "'$egress'mbit" }' +} + +reload_service() { + logger ratelimit reload + config_load ratelimit + config_foreach add_rate rate +} + +service_triggers() { + procd_add_reload_trigger ratelimit +} + +start_service() { + procd_open_instance + procd_set_param command "$PROG" + procd_set_param respawn + procd_close_instance +} + +service_started() { + ubus -t 10 wait_for ratelimit + [ $? = 0 ] && reload_service +} + diff --git a/feeds/ucentral/ratelimit/files/usr/bin/ratelimit b/feeds/ucentral/ratelimit/files/usr/bin/ratelimit index dcd6d9e86..372b32c4a 100755 --- a/feeds/ucentral/ratelimit/files/usr/bin/ratelimit +++ b/feeds/ucentral/ratelimit/files/usr/bin/ratelimit @@ -1,174 +1,337 @@ -#!/bin/sh +#!/usr/bin/env ucode +'use strict'; -. /lib/functions.sh +import { basename, popen } from 'fs'; +import * as ubus from 'ubus'; +import * as uloop from 'uloop'; -wrapper() { - echo calling $* - $* +let defaults = {}; +let devices = {}; + +function cmd(command, ignore_error) { +// if (ignore_error) +// command += "> /dev/null 2>&1"; + warn(`> ${command}\n`); + let rc = system(command); + return ignore_error || rc == 0; } -TC() { - wrapper tc $* +function qdisc_add_leaf(iface, id, opts) { + opts ??= ""; + return cmd(`tc class replace dev ${iface} parent 1:1 classid 1:${id} htb rate 1mbit ${opts} burst 2k prio 1`) && + cmd(`tc qdisc replace dev ${iface} parent 1:${id} handle ${id}: fq_codel flows 128 limit 800 quantum 300 noecn`); } -IP() { - wrapper ip $* +function qdisc_del_leaf(iface, id) { + cmd(`tc class del dev ${iface} parent 1:1 classid 1:${id}`, true); } -get_id() { - addr=$1 - hashval="0x$(echo "$addr" | md5sum | head -c8)" - mask=0x4ff - echo $(($hashval & $mask)) +function qdisc_add(iface) { + return cmd(`tc qdisc add dev ${iface} root handle 1: htb default 2`) && + cmd(`tc class add dev ${iface} parent 1: classid 1:1 htb rate 1000mbit burst 6k`) && + qdisc_add_leaf(iface, 2, "ceil 1000mbit"); } -delclient() { - local ifb=rateifb$1 - local iface=$1 - local mac=$2 - local id=$3 - - logger "ratelimit: delete old client entries $1 $2" - - id=$(get_id ${mac//:}) - - TC filter del dev $iface protocol all parent 1: prio 1 u32 match ether dst $mac flowid 1:$id - - TC filter del dev $ifb protocol all parent 1: prio 1 u32 match ether src $mac flowid 1:$id +function qdisc_del(iface) { + cmd(`tc qdisc del dev ${iface} root`, true); } -ingress=0 -egress=0 - -getrate() { - config_get ssid $1 ssid - [ "$ssid" == "$2" ] || return - config_get ingress $1 ingress - config_get egress $1 egress +function ifb_dev(iface) { + return "ifb-" + iface; } -addclient() { - local ifb=rateifb$1 - local iface=$1 - local mac=$2 - local ssid=$(cat /tmp/ratelimit.$iface) +function ifb_add(iface, ifbdev) { + return cmd(`ip link add ${ifbdev} type ifb`) && + cmd(`ip link set ${ifbdev} up`) && + cmd(`tc qdisc add dev ${iface} clsact`, true) && + cmd(`tc filter add dev ${iface} ingress protocol all prio 512 matchall action mirred egress redirect dev ${ifbdev}`); +} - egress=$3 - ingress=$4 +function ifb_del(iface, ifbdev) { + cmd(`tc filter del dev ${iface} ingress protocol all prio 512`); + cmd(`ip link set ${ifbdev} down`, true); + cmd(`ip link del ${ifbdev}`, true); +} - logger "ratelimit: adding client" +function macfilter_add(iface, id, type, mac) { + return cmd(`tc filter add dev ${iface} protocol all parent 1: prio 1 handle 800::${id} u32 match ether ${type} ${mac} flowid 1:${id}`); +} - [ "$egress" -eq 0 -o $ingress -eq 0 ] && { - config_load ratelimit - config_foreach getrate rate $ssid +function macfilter_del(iface, id) { + cmd(`tc filter del dev ${iface} protocol all parent 1: prio 1 handle 800::${id} u32`, true); +} + +function linux_client_del(device, client) { + let ifbdev = ifb_dev(device.name); + let id = client.id + 3; + + macfilter_del(device.name, id); + qdisc_del_leaf(device.name, id); + macfilter_del(ifbdev, id); + qdisc_del_leaf(ifbdev, id); +} + +function linux_client_set(device, client) { + let ifbdev = ifb_dev(device.name); + let id = client.id + 3; + + linux_client_del(device, client); + + let ret = qdisc_add_leaf(device.name, id, `ceil ${client.data.rate_egress}`) && + macfilter_add(device.name, id, "dst", client.address) && + qdisc_add_leaf(ifbdev, id, `ceil ${client.data.rate_ingress}`) && + macfilter_add(ifbdev, id, "src", client.address); + + if (!ret) + linux_client_del(device, client); + + return ret; +} + + +let ops = { + device: { + add: function(name) { + let ifbdev = ifb_dev(name); + + qdisc_del(name); + ifb_del(name, ifbdev); + + let ret = qdisc_add(name) && + ifb_add(name, ifbdev) && + qdisc_add(ifbdev); + + if (!ret) { + qdisc_del(name); + ifb_del(name, ifbdev); + } + + return ret; + }, + remove: function(name) { + let ifbdev = ifb_dev(name); + qdisc_del(name); + ifb_del(name, ifbdev); + } + }, + client: { + set: function(device, client) { + return linux_client_set(device, client); + }, + remove: function(device, client) { + linux_client_del(device, client); + } + } +}; + +function get_device(devices, name) { + let device = devices[name]; + + if (device) + return device; + + if (!ops.device.add(name)) + return null; + + device = { + name: name, + clients: {}, + client_order: [], + }; + + devices[name] = device; + + return device; +} + +function del_device(name) { + if (!devices[name]) + return; + ops.device.remove(name); + delete devices[name]; +} + +function get_free_idx(list) { + for (let i = 0; i < length(list); i++) + if (list[i] == null) + return i; + + return length(list); +} + +function del_client(device, address) { + let client = device.clients[address]; + + if (!client) + return false; + + delete device.clients[address]; + device.client_order[client.id] = null; + + ops.client.remove(device, client); + return true; +} + +function get_client(device, address) { + let client = device.clients[address]; + + if (client) + return client; + + let i = get_free_idx(device.client_order); + client = {}; + client.address = address; + client.id = i; + client.data = {}; + + device.clients[address] = client; + device.client_order[i] = client; + + return client; +} + +function set_client(device, client, data) { + let update = false; + + for (let key in data) { + if (client.data[key] != data[key]) + update = true; + + client.data[key] = data[key]; } - [ "$egress" -eq 0 -o $ingress -eq 0 ] && { - logger "ratelimit: no valid rates" - exit 1 + if (update && !ops.client.set(device, client)) { + del_client(device, client.address); + return false; } - local id=$(get_id ${mac//:}) - - logger "ratelimit: add new client entries for $1 $2 $egress $ingress" - - TC class add dev $iface parent 1:1 classid 1:$id htb rate 1mbit ceil ${egress}mbit burst 2k prio 1 - TC qdisc add dev $iface parent 1:$id handle $id: sfq perturb 10 - TC filter add dev $iface protocol all parent 1: prio 1 u32 match ether dst $mac flowid 1:$id - - TC class add dev $ifb parent 1:1 classid 1:$id htb rate 1mbit ceil ${ingress}mbit burst 2k prio 1 - TC filter add dev $ifb protocol all parent 1: prio 1 u32 match ether src $mac flowid 1:$id + return true; } -deliface() { - local ifb=rateifb$1 - local iface=$1 +function run_service() { + let uctx = ubus.connect(); - [ -d /sys/class/net/$ifb/ ] || return 0 + uctx.publish("ratelimit", { + defaults_set: { + call: function(req) { + let r_i = req.args.rate_ingress ?? req.args.rate; + let r_e = req.args.rate_egress ?? req.args.rate; + let name = req.args.name; - logger "ratelimit: deleting old iface settings" + if (!name || !r_i || !r_e) + return ubus.STATUS_INVALID_ARGUMENT; - IP link set $ifb down - IP link del $ifb + defaults[name] = [ r_e, r_i ]; - TC qdisc del dev $iface root &2> /dev/null + return 0; + }, + args: { + name:"", + rate:"", + rate_ingress:"", + rate_egress:"", + } + }, + client_set: { + call: function(req) { + let r_i = req.args.rate_ingress ?? req.args.rate; + let r_e = req.args.rate_egress ?? req.args.rate; - rm -f /tmp/ratelimit.$iface - [ -f /tmp/run/hostapd-cli-$iface.pid ] && kill "$(cat /tmp/run/hostapd-cli-$iface.pid)" -} + if (req.args.defaults && defaults[req.args.defaults]) { + let def = defaults[req.args.defaults]; -found=0 -find_ssid() { - local ssid - config_get ssid $1 ssid - [ "$ssid" == "$2" ] || return - found=1 -} + r_e ??= def[0]; + r_i ??= def[1]; + } -addiface() { - local ifb=rateifb$1 - local iface=$1 - local ssid + if (!req.args.device || !req.args.address || !r_i || !r_e) + return ubus.STATUS_INVALID_ARGUMENT; + let device = get_device(devices, req.args.device); + if (!device) + return ubus.STATUS_INVALID_ARGUMENT; - [ -f /tmp/ratelimit.$iface -o -d /sys/class/net/$ifb/ ] && { - return 0 + let client = get_client(device, req.args.address); + if (!client) + return ubus.STATUS_INVALID_ARGUMENT; + + let data = { + rate_ingress: r_i, + rate_egress: r_e + }; + + if (!set_client(device, client, data)) + return ubus.STATUS_UNKNOWN_ERROR; + + return 0; + }, + args: { + device:"", + defaults:"", + address:"", + rate:"", + rate_ingress:"", + rate_egress:"", + } + }, + client_delete: { + call: function(req) { + if (!req.args.address) + return ubus.STATUS_INVALID_ARGUMENT; + + if (req.args.device) { + let device = devices[req.args.device]; + if (!device) + return ubus.STATUS_NOT_FOUND; + + if (!del_client(device, req.args.address)) + return ubus.STATUS_NOT_FOUND; + } else { + for (let dev in devices) { + let device = devices[dev]; + + del_client(device, req.args.address); + } + } + + return 0; + }, + args: { + device:"", + address:"", + } + }, + device_delete: { + call: function(req) { + let name = req.args.device; + + if (!name) + return ubus.STATUS_INVALID_ARGUMENT; + + if (!devices[name]) + return ubus.STATUS_NOT_FOUND; + + del_device(name); + + return 0; + }, + args: { + device:"", + } + } + }); + + try { + uloop.run(); + } catch (e) { + warn(`Error: ${e}\n${e.stacktrace[0].context}`); } - - echo -n startup > /tmp/ratelimit.$iface - sleep 2 - ssid=$(ubus call hostapd.$iface get_status | jsonfilter -e '@.ssid') - [ -z "$ssid" ] && { - rm /tmp/ratelimit.$iface - logger "ratelimit: failed to lookup ssid" - exit 1 + for (let dev in devices) { + del_device(dev); } - config_load ratelimit - config_foreach find_ssid rate $ssid - [ "$found" -eq 0 ] && { - rm /tmp/ratelimit.$iface - exit 0 - } - logger "ratelimit: adding new iface settings" - - echo -n $ssid > /tmp/ratelimit.$iface - - IP link add name $ifb type ifb - IP link set $ifb up - - sleep 1 - - TC qdisc add dev $iface root handle 1: htb default 30 - TC class add dev $iface parent 1: classid 1:1 htb rate 1000mbit burst 6k - TC qdisc add dev $iface ingress - TC filter add dev $iface parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev $ifb - - TC qdisc add dev $ifb root handle 1: htb default 10 - TC class add dev $ifb parent 1: classid 1:1 htb rate 100mbit - hostapd_cli -a /usr/libexec/ratelimit.sh -i $iface -P /tmp/run/hostapd-cli-$iface.pid -B - - for sta in $(ubus call wifi station | jsonfilter -e '@[*][*].mac'); do - addclient $iface $sta - done } -waitiface() { - local iface=$1 - - ubus -t 120 wait_for hostapd.$1 - - [ $? -eq 0 ] || exit 0 - - addiface $iface -} - -flush() { - for a in `ls /sys/class/net/ | grep rateifb`; do - deliface ${a:7} - done -} - -cmd=$1 -shift -$cmd $@ +uloop.init(); +run_service(); +uloop.done(); diff --git a/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit-wait.sh b/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit-wait.sh new file mode 100755 index 000000000..2e9903f58 --- /dev/null +++ b/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit-wait.sh @@ -0,0 +1,4 @@ +#!/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 index f6fab5c15..241a598c0 100755 --- a/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit.sh +++ b/feeds/ucentral/ratelimit/files/usr/libexec/ratelimit.sh @@ -2,9 +2,16 @@ case $2 in AP-STA-CONNECTED) - ratelimit addclient $1 $3 $4 $5 + [ $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) - ratelimit delclient $1 $3 + ubus call ratelimit client_delete '{ "address": "'$3'" }' + logger ratelimit delclient $3 ;; esac From 708fe70e759fb027324fa194b492ac8df062b538 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 20 Sep 2022 08:40:16 +0200 Subject: [PATCH 6/9] ucentral-schema: update to latest HEAD a473fe2 restart ratelimit daemon after config apply ec58d3a do not auto-expire captive clients Fixes: WIFI-10190 Fixes: WIFI-10194 Signed-off-by: John Crispin --- feeds/ucentral/ucentral-schema/Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile index 997f66d72..7d491b415 100644 --- a/feeds/ucentral/ucentral-schema/Makefile +++ b/feeds/ucentral/ucentral-schema/Makefile @@ -4,10 +4,9 @@ PKG_NAME:=ucentral-schema PKG_RELEASE:=1 PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-schema.git -PKG_MIRROR_HASH:=7f11e36e1cb10104bcde0ba0e288f2487fb894a6471605d4dee1460b5be379e0 PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-05-29 -PKG_SOURCE_VERSION:=55b8272c9cc4500f813f5f1cccdcbb14725b595b +PKG_SOURCE_VERSION:=81a74ccd8cb7a1f5dccfb11797236eb1834db461 PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause From cd2fbd11f29b30e187843c3c5134ccc03926eb09 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Tue, 20 Sep 2022 08:41:00 +0200 Subject: [PATCH 7/9] captive: add missing UAM/ACCT/rate features Fixes: WIFI-10665 Signed-off-by: John Crispin --- feeds/ucentral/spotfilter/src/client.c | 12 +- feeds/ucentral/spotfilter/src/client.h | 4 +- feeds/ucentral/spotfilter/src/interface.c | 6 - feeds/ucentral/spotfilter/src/interface.h | 5 + feeds/ucentral/spotfilter/src/nl80211.c | 8 +- .../ucentral/spotfilter/src/spotfilter-bpf.c | 10 +- .../ucentral/spotfilter/src/spotfilter-bpf.h | 2 + feeds/ucentral/spotfilter/src/ubus.c | 16 +- feeds/ucentral/uspot/Makefile | 2 +- feeds/ucentral/uspot/files/etc/config/uspot | 19 - feeds/ucentral/uspot/files/etc/init.d/uspot | 13 + feeds/ucentral/uspot/files/usr/bin/captive | 53 +++ .../uspot/files/usr/share/uspot/accounting.uc | 211 +++++++++ .../uspot/files/usr/share/uspot/common.uc | 118 ++++- .../uspot/files/usr/share/uspot/cpd.uc | 14 +- .../files/usr/share/uspot/handler-cpd.uc | 5 + .../files/usr/share/uspot/handler-uam.uc | 48 +- .../uspot/files/usr/share/uspot/handler.uc | 26 +- .../uspot/files/usr/share/uspot/logoff.uc | 4 + feeds/ucentral/uspot/src/radius.c | 435 +++++++----------- 20 files changed, 645 insertions(+), 366 deletions(-) create mode 100755 feeds/ucentral/uspot/files/etc/init.d/uspot create mode 100755 feeds/ucentral/uspot/files/usr/bin/captive create mode 100755 feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc create mode 100644 feeds/ucentral/uspot/files/usr/share/uspot/logoff.uc diff --git a/feeds/ucentral/spotfilter/src/client.c b/feeds/ucentral/spotfilter/src/client.c index 005488e88..7c2b084d3 100644 --- a/feeds/ucentral/spotfilter/src/client.c +++ b/feeds/ucentral/spotfilter/src/client.c @@ -97,7 +97,8 @@ static void client_set_id(struct interface *iface, struct client *cl, const char } int client_set(struct interface *iface, const void *addr, const char *id, - int state, int dns_state, int accounting, struct blob_attr *data) + int state, int dns_state, int accounting, struct blob_attr *data, + const char *device, bool flush) { struct cache_entry *c; struct blob_attr *cur; @@ -142,12 +143,21 @@ int client_set(struct interface *iface, const void *addr, const char *id, kvlist_set(&cl->kvdata, blobmsg_name(cur), cur); } + if (device) + cl->device = device; if (state >= 0) cl->data.cur_class = state; if (dns_state >= 0) cl->data.dns_class = dns_state; if (accounting >= 0) cl->data.flags = accounting; + if (flush) { + kvlist_free(&cl->kvdata); + cl->data.packets_ul = 0; + cl->data.packets_dl = 0; + cl->data.bytes_ul = 0; + cl->data.bytes_dl = 0; + } spotfilter_bpf_set_client(iface, &cl->key, &cl->data); if (new_client) diff --git a/feeds/ucentral/spotfilter/src/client.h b/feeds/ucentral/spotfilter/src/client.h index 722ead082..0e45cf2d4 100644 --- a/feeds/ucentral/spotfilter/src/client.h +++ b/feeds/ucentral/spotfilter/src/client.h @@ -17,10 +17,12 @@ struct client { struct spotfilter_client_key key; struct spotfilter_client_data data; + const char *device; }; int client_set(struct interface *iface, const void *addr, const char *id, - int state, int dns_state, int accounting, struct blob_attr *data); + int state, int dns_state, int accounting, struct blob_attr *data, + const char *device, bool flush); void client_free(struct interface *iface, struct client *cl); void client_set_ipaddr(const void *mac, const void *addr, bool ipv6); void client_init_interface(struct interface *iface); diff --git a/feeds/ucentral/spotfilter/src/interface.c b/feeds/ucentral/spotfilter/src/interface.c index fed457131..f467f2a41 100644 --- a/feeds/ucentral/spotfilter/src/interface.c +++ b/feeds/ucentral/spotfilter/src/interface.c @@ -32,12 +32,6 @@ void interface_free(struct interface *iface) free(iface); } -static inline const char * -device_name(struct device *dev) -{ - return dev->node.avl.key; -} - static void interface_check_device(struct interface *iface, struct device *dev) { diff --git a/feeds/ucentral/spotfilter/src/interface.h b/feeds/ucentral/spotfilter/src/interface.h index 5f3b6cfa5..73e0e5ab8 100644 --- a/feeds/ucentral/spotfilter/src/interface.h +++ b/feeds/ucentral/spotfilter/src/interface.h @@ -64,6 +64,11 @@ static inline const char *interface_name(struct interface *iface) return iface->node.key; } +static inline const char *device_name(struct device *dev) +{ + return dev->node.avl.key; +} + void interface_add(const char *name, struct blob_attr *config, struct blob_attr *devices); void interface_free(struct interface *iface); diff --git a/feeds/ucentral/spotfilter/src/nl80211.c b/feeds/ucentral/spotfilter/src/nl80211.c index 2206b3be6..0ce416410 100644 --- a/feeds/ucentral/spotfilter/src/nl80211.c +++ b/feeds/ucentral/spotfilter/src/nl80211.c @@ -155,14 +155,12 @@ nl80211_interface_update(struct interface *iface) struct client *cl, *tmp; struct device *dev; - if (!iface->client_autoremove) - return; - avl_for_each_element_safe(&iface->clients, cl, node, tmp) { if (cl->idle++ < iface->client_timeout) continue; - client_free(iface, cl); + if (iface->client_autoremove) + client_free(iface, cl); } vlist_for_each_element(&iface->devices, dev, node) @@ -218,7 +216,7 @@ found: if (cl) cl->idle = 0; else if (iface->client_autocreate) - client_set(iface, addr, NULL, -1, -1, -1, NULL); + client_set(iface, addr, NULL, -1, -1, -1, NULL, device_name(dev), false); return NL_SKIP; } diff --git a/feeds/ucentral/spotfilter/src/spotfilter-bpf.c b/feeds/ucentral/spotfilter/src/spotfilter-bpf.c index 6b969551c..26b04919b 100644 --- a/feeds/ucentral/spotfilter/src/spotfilter-bpf.c +++ b/feeds/ucentral/spotfilter/src/spotfilter-bpf.c @@ -158,9 +158,9 @@ int spotfilter_out(struct __sk_buff *skb) return TC_ACT_UNSPEC; cl = bpf_map_lookup_elem(&client, eth->h_dest); - if (cl) { - if (cl->flags & SPOTFILTER_CLIENT_F_ACCT_DL) - cl->bytes_dl += skb->len; + if (cl && (cl->flags & SPOTFILTER_CLIENT_F_ACCT_DL)) { + cl->packets_dl++; + cl->bytes_dl += skb->len; } skb_parse_vlan(&info); @@ -204,8 +204,10 @@ int spotfilter_in(struct __sk_buff *skb) cl = bpf_map_lookup_elem(&client, eth->h_source); if (cl) { cldata = *cl; - if (cl->flags & SPOTFILTER_CLIENT_F_ACCT_UL) + if (cl->flags & SPOTFILTER_CLIENT_F_ACCT_UL) { + cl->packets_ul++; cl->bytes_ul += skb->len; + } } has_vlan = !!skb_parse_vlan(&info); diff --git a/feeds/ucentral/spotfilter/src/spotfilter-bpf.h b/feeds/ucentral/spotfilter/src/spotfilter-bpf.h index d9f4f08f3..94a4d162b 100644 --- a/feeds/ucentral/spotfilter/src/spotfilter-bpf.h +++ b/feeds/ucentral/spotfilter/src/spotfilter-bpf.h @@ -19,6 +19,8 @@ struct spotfilter_client_data { uint8_t dns_class; uint8_t flags; + uint64_t packets_ul; + uint64_t packets_dl; uint64_t bytes_ul; uint64_t bytes_dl; }; diff --git a/feeds/ucentral/spotfilter/src/ubus.c b/feeds/ucentral/spotfilter/src/ubus.c index 8083c589f..2c558ef32 100644 --- a/feeds/ucentral/spotfilter/src/ubus.c +++ b/feeds/ucentral/spotfilter/src/ubus.c @@ -88,6 +88,7 @@ enum { CLIENT_ATTR_DNS_STATE, CLIENT_ATTR_ACCOUNTING, CLIENT_ATTR_DATA, + CLIENT_ATTR_FLUSH, __CLIENT_ATTR_MAX }; @@ -99,6 +100,7 @@ static const struct blobmsg_policy client_policy[__CLIENT_ATTR_MAX] = { [CLIENT_ATTR_DNS_STATE] = { "dns_state", BLOBMSG_TYPE_INT32 }, [CLIENT_ATTR_ACCOUNTING] = { "accounting", BLOBMSG_TYPE_ARRAY }, [CLIENT_ATTR_DATA] = { "data", BLOBMSG_TYPE_TABLE }, + [CLIENT_ATTR_FLUSH] = { "flush", BLOBMSG_TYPE_BOOL }, }; static int @@ -176,6 +178,7 @@ client_ubus_update(struct ubus_context *ctx, struct ubus_object *obj, const char *id = NULL; int state = -1, dns_state = -1; int accounting = -1; + bool flush = false; int ret; ret = client_ubus_init(msg, tb, &iface, &addr, &id, &cl); @@ -203,8 +206,11 @@ client_ubus_update(struct ubus_context *ctx, struct ubus_object *obj, if (!addr) return UBUS_STATUS_INVALID_ARGUMENT; + if (tb[CLIENT_ATTR_FLUSH]) + flush = blobmsg_get_bool(tb[CLIENT_ATTR_FLUSH]); + client_set(iface, addr, id, state, dns_state, accounting, - tb[CLIENT_ATTR_DATA]); + tb[CLIENT_ATTR_DATA], NULL, flush); return 0; } @@ -241,8 +247,10 @@ static void client_dump(struct interface *iface, struct client *cl) spotfilter_bpf_get_client(iface, &cl->key, &cl->data); - if (iface->client_autoremove) - blobmsg_add_u32(&b, "idle", cl->idle); + if (cl->device) + blobmsg_add_string(&b, "device", cl->device); + + blobmsg_add_u32(&b, "idle", cl->idle); blobmsg_add_u32(&b, "state", cl->data.cur_class); blobmsg_add_u32(&b, "dns_state", cl->data.dns_class); @@ -281,6 +289,8 @@ static void client_dump(struct interface *iface, struct client *cl) interface_dump_action(&b, iface, cl->data.dns_class); blobmsg_close_table(&b, c); + blobmsg_add_u64(&b, "packets_ul", cl->data.packets_ul); + blobmsg_add_u64(&b, "packets_dl", cl->data.packets_dl); blobmsg_add_u64(&b, "bytes_ul", cl->data.bytes_ul); blobmsg_add_u64(&b, "bytes_dl", cl->data.bytes_dl); } diff --git a/feeds/ucentral/uspot/Makefile b/feeds/ucentral/uspot/Makefile index 9e0bac763..8e2761e2a 100644 --- a/feeds/ucentral/uspot/Makefile +++ b/feeds/ucentral/uspot/Makefile @@ -18,7 +18,7 @@ endef define Package/uspot/install $(INSTALL_DIR) $(1)/usr/bin/ $(1)/usr/lib/ucode - $(INSTALL_BIN) $(PKG_BUILD_DIR)/radius-client $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/radius-client $(1)/usr/bin/radius-client $(INSTALL_DATA) $(PKG_BUILD_DIR)/libuam.so $(1)/usr/lib/ucode/uam.so $(CP) ./files/* $(1) endef diff --git a/feeds/ucentral/uspot/files/etc/config/uspot b/feeds/ucentral/uspot/files/etc/config/uspot index 8cabbaef1..03734bab5 100644 --- a/feeds/ucentral/uspot/files/etc/config/uspot +++ b/feeds/ucentral/uspot/files/etc/config/uspot @@ -1,25 +1,6 @@ config uspot config - #option auth_mode 'uam' - #option auth_mode 'radius' - #option auth_mode 'credentials' - option auth_mode 'click-to-continue' config radius radius -# option auth_server 212.24.98.232 -# option auth_port 1812 -# option auth_secret secret config uam uam -# option port 3990 -# option nasid AlmondLabs -# option nasmac 903cb3bb25e3 -# option server https://customer.hotspotsystem.com/customer/hotspotlogin.php -# option secret hotsys123 -#config credential -# option username abc -# option password def - -#config credential -# option username 123 -# option password 456 diff --git a/feeds/ucentral/uspot/files/etc/init.d/uspot b/feeds/ucentral/uspot/files/etc/init.d/uspot new file mode 100755 index 000000000..fc321c0f7 --- /dev/null +++ b/feeds/ucentral/uspot/files/etc/init.d/uspot @@ -0,0 +1,13 @@ +#!/bin/sh /etc/rc.common + +START=80 + +USE_PROCD=1 +PROG=/usr/share/uspot/accounting.uc + +start_service() { + procd_open_instance + procd_set_param command "$PROG" + procd_set_param respawn + procd_close_instance +} diff --git a/feeds/ucentral/uspot/files/usr/bin/captive b/feeds/ucentral/uspot/files/usr/bin/captive new file mode 100755 index 000000000..bfedb5167 --- /dev/null +++ b/feeds/ucentral/uspot/files/usr/bin/captive @@ -0,0 +1,53 @@ +#!/usr/bin/ucode + +let ubus = require('ubus').connect(); +let uci = require('uci').cursor(); + +function restart() { + system('/etc/init.d/spotfilter restart'); + system('/etc/init.d/uhttpd restart'); +} + +switch(ARGV[0]) { +case 'dump': + let clients = ubus.call('spotfilter', 'client_list', { interface: 'hotspot'}); + printf('%.J\n', clients); + break; +case 'clients': + let clients = ubus.call('spotfilter', 'client_list', { interface: 'hotspot'}); + let res = {}; + let t = time(); + + for (let c, val in clients) { + res[c] = { + status: val.state ? 'Authenticated' : 'Garden', + idle: val.idle || 0, + time: val.data.connect ? t - val.data.connect : 0, + ip4addr: val.ip4addr || '', + ip6addr: val.ip6addr || '', + packets_ul: val.packets_ul || 0, + bytes_ul: val.bytes_ul || 0, + packets_dl: val.packets_dl || 0, + bytes_dl: val.bytes_dl || 0, + }; + } + printf('%.J\n', res); + break; +case 'remove': + ubus.call('spotfilter', 'client_remove', { interface: 'hotspot', address: ARGV[1] || ''}); + break; +case 'restart': + restart(); + break; +case 'log': + system('logread -f | grep uspot:'); + break; +case 'debugon': +case 'debugoff': + uci.set('uspot', 'config', 'debug', 1); + uci.commit(); + restart(); + break; +default: + break; +} diff --git a/feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc b/feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc new file mode 100755 index 000000000..cf1007c19 --- /dev/null +++ b/feeds/ucentral/uspot/files/usr/share/uspot/accounting.uc @@ -0,0 +1,211 @@ +#!/usr/bin/ucode + +'use strict'; + +let fs = require('fs'); +let uloop = require('uloop'); +let ubus = require('ubus').connect(); +let uci = require('uci').cursor(); +let config = uci.get_all('uspot'); +let clients = {}; + +let acct_interval = config.radius?.acct_interval || 600; +let idle_timeout = config.config.idle_timeout || 600; +let session_timeout = config.config.session_timeout || 0; + +function syslog(mac, msg) { + let log = sprintf('uspot: %s %s', mac, msg); + + system('logger ' + log); + warn(log + '\n'); +} + +function debug(mac, msg) { + if (config.config.debug) + syslog(mac, msg); +} + +function get_idle_timeout(mac) { + if (clients[mac]) + return clients[mac].idle; + return idle_timeout; +} + +function get_session_timeout(mac) { + if (clients[mac]?.session_timeout) + return clients[mac].session_timeout; + return session_timeout; +} + +function radius_init(mac, payload) { + for (let key in [ 'server', 'acct_server', 'acct_session', 'client_ip', 'called_station', 'calling_station', 'nas_ip', 'nas_id', 'username' ]) + if (clients[mac].radius[key]) + payload[key] = clients[mac].radius[key]; + return payload; +} + +function radius_call(mac, payload) { + let cfg = fs.open('/tmp/acct' + mac + '.json', 'w'); + cfg.write(payload); + cfg.close(); + + system('/usr/bin/radius-client /tmp/acct' + mac + '.json'); +} + +function radius_stop(mac) { + debug(mac, 'stopping accounting'); + + let payload = { + acct: true, + acct_type: 8, + terminate_cause: 0, + }; + radius_init(mac, payload); + radius_call(mac, payload); +} + +function radius_acct(mac, payload) { + let state = ubus.call('spotfilter', 'client_get', { + interface: 'hotspot', + address: mac + }); + if (!state) { + return false; + } + + payload = radius_init(mac, payload); + payload.acct = true; + payload.session_time = time() - state.data.connect; + payload.output_octets = state.bytes_dl & 0xffffffff; + payload.input_octets = state.bytes_ul & 0xffffffff; + payload.output_gigawords = state.bytes_dl >> 32; + payload.input_gigawords = state.bytes_ul >> 32; + payload.output_packets = state.packets_dl; + payload.input_packets = state.packets_ul; + + radius_call(mac, payload); + return true; +} + +function radius_idle_time(mac) { + let payload = { + acct_type: 2, + terminate_cause: 4, + }; + radius_acct(mac, payload); +} + +function radius_session_time(mac) { + let payload = { + acct_type: 2, + terminate_cause: 5, + }; + radius_acct(mac, payload); +} + +function radius_disconnect(mac) { + let payload = { + acct_type: 2, + terminate_cause: 1, + }; + radius_acct(mac, payload); +} + +function radius_interim(mac) { + let payload = { + acct_type: 3, + }; + if (radius_acct(mac, payload)) + debug(mac, 'iterim acct call'); + else + syslog(mac, 'failed to sent interim accounting frame\n'); + clients[mac].timeout.set(clients[mac].interval); +} + +function client_add(mac, state) { + if (state.state != 1) + return; + + let interval = (state.data?.radius?.reply['Acct-Interim-Interval'] || acct_interval) * 1000; + let idle = (state.data?.radius?.reply['Idle-Timeout'] || idle_timeout); + let session = (state.data?.radius?.reply['Session-Timeout'] || session_timeout); + let accounting = (config.radius?.acct_server && config.radius?.acct_secret); + + clients[mac] = { + accounting, + radius: state.data.radius.request, + interval, + idle, + }; + syslog(mac, 'adding client'); + if (accounting) + clients[mac].timeout = uloop.timer(interval, () => radius_interim(mac)); +} + +function client_remove(mac, reason) { + syslog(mac, reason); + if (clients[mac]) { + radius_stop(mac); + if (clients[mac].accounting) + clients[mac].timeout.cancel(); + delete clients[mac]; + } + ubus.call('spotfilter', 'client_remove', { + interface: "hotspot", + address: mac + }); +} + +function client_timeout(mac) { + syslog(mac, 'session timeout'); + if (clients[mac]) { + radius_stop(mac); + if (clients[mac].accounting) + clients[mac].timeout.cancel(); + delete clients[mac]; + } + ubus.call('spotfilter', 'client_set', { + interface: "hotspot", + state: 0, + address: mac, + accounting: [], + flush: true, + }); +} + +uloop.init(); + +uloop.timer(1000, function() { + let list = ubus.call('spotfilter', 'client_list', { interface: 'hotspot'}); + let t = time(); + + for (let k, v in list) + if (!clients[k]) + client_add(k, v); + + for (let k, v in clients) + if (!list[k] || !list[k].state) { + radius_disconnect(k); + client_remove(k, 'disconnect event'); + } + + for (let k, v in list) { + if (v.idle > get_idle_timeout(k)) { + if (clients[k]) + radius_idle_time(k); + client_remove(k, 'idle event'); + + } + let timeout = get_session_timeout(k); + if (timeout && ((t - v.data.connect) > timeout)) { + if (clients[k]) + radius_session_time(k); + client_timeout(k); + + } + } + + this.set(5000); +}); + +uloop.run(); diff --git a/feeds/ucentral/uspot/files/usr/share/uspot/common.uc b/feeds/ucentral/uspot/files/usr/share/uspot/common.uc index f0893e97c..9b4c64dbd 100644 --- a/feeds/ucentral/uspot/files/usr/share/uspot/common.uc +++ b/feeds/ucentral/uspot/files/usr/share/uspot/common.uc @@ -26,6 +26,46 @@ return { header, footer, + // syslog helper + syslog: function(ctx, msg) { + warn('uspot: ' + ctx.env.REMOTE_ADDR + ' - ' + msg + '\n'); + }, + + debug: function(ctx, msg) { + if (config.config.debug) + this.syslog(ctx, msg); + }, + + // mac re-formater + format_mac: function(mac) { + switch(config.uam.mac_format) { + case 'aabbccddeeff': + case 'AABBCCDDEEFF': + mac = replace(mac, ':', ''); + break; + case 'aa-bb-cc-dd-ee-ff': + case 'AA-BB-CC-DD-EE-FF': + mac = replace(mac, ':', '-'); + warn('uspot: ' + ctx.env.REMOTE_ADDR + ' - ' + msg + '\n'); + break; + } + + switch(config.uam.mac_format) { + case 'aabbccddeeff': + case 'aa-bb-cc-dd-ee-ff': + case 'aa:bb:cc:dd:ee:ff': + mac = lc(mac); + break; + case 'AABBCCDDEEFF': + case 'AA:BB:CC:DD:EE:FF': + case 'AA-BB-CC-DD-EE-FF': + mac = uc(mac); + break; + } + + return mac; + }, + // wrapper for scraping external tools stdout fs_popen: function(cmd) { let stdout = fs.popen(cmd); @@ -43,45 +83,79 @@ return { }, // give a client access to the internet - allow_client: function(ctx) { + allow_client: function(ctx, data) { + this.syslog(ctx, 'allow client to pass traffic'); ctx.ubus.call('spotfilter', 'client_set', { "interface": "hotspot", - "address": replace(ctx.mac, '-', ':'), + "address": ctx.mac, "state": 1, "dns_state": 1, "accounting": [ "dl", "ul"], "data": { - "connect": time() + ... data || {}, + "connect": time(), } }); if (ctx.query_string.userurl) include('redir.uc', { redir_location: ctx.query_string.userurl }); else include('allow.uc', ctx); + //data.radius.reply['WISPr-Bandwidth-Max-Up'] = "20000000"; + //data.radius.reply['WISPr-Bandwidth-Max-Down'] = "10000000"; + if (data?.radius?.reply && (+data.radius.reply['WISPr-Bandwidth-Max-Up'] && +data.radius.reply['WISPr-Bandwidth-Max-Down'])) + ctx.ubus.call('ratelimit', 'client_set', { + device: ctx.device, + address: ctx.mac, + rate_egress: sprintf('%s', data.radius.reply['WISPr-Bandwidth-Max-Down']), + rate_ingress: sprintf('%s', data.radius.reply['WISPr-Bandwidth-Max-Up']), + }); + }, + + // put a client back into pre-auth state + logoff: function(ctx, data) { + this.syslog(ctx, 'logging client off'); + ctx.ubus.call('spotfilter', 'client_set', { + interface: 'hotspot', + address: ctx.mac, + state: 0, + dns_state: 1, + accounting: [], + flush: true, + }); + include('logoff.uc', ctx); }, // generate the default radius auth payload - radius_init: function(ctx) { + radius_init: function(ctx, acct_session) { + let math = require('math'); + if (!acct_session) { + acct_session = ''; + + for (let i = 0; i < 16; i++) + acct_session += sprintf('%d', math.rand() % 10); + } + return { server: sprintf('%s:%s:%s', this.config.radius.auth_server, this.config.radius.auth_port, this.config.radius.auth_secret), - acct_session: "0123456789", + acct_server: sprintf('%s:%s:%s', this.config.radius.acct_server, this.config.radius.acct_port, this.config.radius.acct_secret), + acct_session, client_ip: ctx.env.REMOTE_ADDR, - called_station: ctx.mac, - calling_station: this.config.uam.nasmac, + called_station: this.config.uam.nasmac, + calling_station: this.format_mac(ctx.mac), nas_ip: ctx.env.SERVER_ADDR, nas_id: this.config.uam.nasid }; }, radius_call: function(ctx, payload) { - let cfg = fs.open('/tmp/' + ctx.mac + '.json', 'w'); + let cfg = fs.open('/tmp/auth' + ctx.mac + '.json', 'w'); cfg.write(payload); cfg.close(); - return this.fs_popen('/usr/bin/radius-client /tmp/' + ctx.mac + '.json'); + return this.fs_popen('/usr/bin/radius-client /tmp/auth' + ctx.mac + '.json'); }, - handle_request: function(env) { + handle_request: function(env, uam) { let mac; let form_data = {}; let query_string = {}; @@ -91,25 +165,39 @@ return { // lookup the peers MAC let macs = this.rtnl.request(this.rtnl.const.RTM_GETNEIGH, this.rtnl.const.NLM_F_DUMP, { }); for (let m in macs) - if (m.dst == env.REMOTE_HOST) - ctx.mac = replace(m.lladdr, ':', '-'); + if (m.dst == env.REMOTE_HOST && m.lladdr) + ctx.mac = m.lladdr; // if the MAC lookup failed, go to the error page if (!ctx.mac) { + this.syslog(ctx, 'failed to look up mac'); include('error.uc', ctx); return NULL; } + ctx.format_mac = this.format_mac(ctx.mac); // check if a client is already connected ctx.ubus = ubus.connect(); let connected = ctx.ubus.call('spotfilter', 'client_get', { - 'interface': 'hotspot', - 'address': ctx.mac + interface: 'hotspot', + address: ctx.mac, }); - if (connected?.state) { + if (!uam && connected?.state) { include('connected.uc', ctx); return NULL; } + if (!connected.data.ssid) { + let hapd = ctx.ubus.call('hostapd.' + connected.device, 'get_status'); + ctx.ubus.call('spotfilter', 'client_set', { + interface: 'hotspot', + address: ctx.mac, + data: { + ssid: hapd.ssid || 'unknown' + } + }); + } + ctx.device = connected.device; + ctx.ssid = connected.data.ssid; // split QUERY_STRING if (env.QUERY_STRING) diff --git a/feeds/ucentral/uspot/files/usr/share/uspot/cpd.uc b/feeds/ucentral/uspot/files/usr/share/uspot/cpd.uc index 3326e91b1..160ef5d73 100644 --- a/feeds/ucentral/uspot/files/usr/share/uspot/cpd.uc +++ b/feeds/ucentral/uspot/files/usr/share/uspot/cpd.uc @@ -1,14 +1,4 @@ -Status: 200 OK +Status: 302 Found +Location: http://{{env.SERVER_ADDR}}/hotspot/?redir={{env.headers.host}} Content-Type: text/html - - - - - - - - -HotSpot Login - - diff --git a/feeds/ucentral/uspot/files/usr/share/uspot/handler-cpd.uc b/feeds/ucentral/uspot/files/usr/share/uspot/handler-cpd.uc index 81ba42c71..aa5e44cc7 100644 --- a/feeds/ucentral/uspot/files/usr/share/uspot/handler-cpd.uc +++ b/feeds/ucentral/uspot/files/usr/share/uspot/handler-cpd.uc @@ -2,7 +2,12 @@ 'use strict'; +let uci = require('uci').cursor(); +let config = uci.get_all('uspot'); + global.handle_request = function(env) { + if (env.REMOTE_ADDR && config.config.debug) + warn('uspot: ' + env.REMOTE_ADDR + ' - CPD redirect\n'); include('cpd.uc', { env }); }; %} diff --git a/feeds/ucentral/uspot/files/usr/share/uspot/handler-uam.uc b/feeds/ucentral/uspot/files/usr/share/uspot/handler-uam.uc index 1b4ad5ae8..9e533975c 100644 --- a/feeds/ucentral/uspot/files/usr/share/uspot/handler-uam.uc +++ b/feeds/ucentral/uspot/files/usr/share/uspot/handler-uam.uc @@ -12,10 +12,10 @@ function auth_client(ctx) { let password; let payload = portal.radius_init(ctx); + payload.logoff_url = sprintf('http://%s:3990/logoff', ctx.env.SERVER_ADDR); if (ctx.query_string.username && ctx.query_string.response) { - let challenge = uam.md5(portal.config.uam.challenge, ctx.mac); + let challenge = uam.md5(portal.config.uam.challenge, ctx.format_mac); - payload.type = 'uam-chap-auth'; payload.username = ctx.query_string.username; payload.chap_password = ctx.query_string.response; if (portal.config.uam.secret) @@ -23,24 +23,44 @@ function auth_client(ctx) { else payload.chap_challenge = challenge; } else if (ctx.query_string.username && ctx.query_string.password) { - payload.type = 'uam-auth'; - payload.username = ctx.mac; - payload.password = uam.password(uam.md5(portal.config.uam.challenge, ctx.mac), ctx.query_string.password, portal.config.uam.uam_secret); - } + payload.username = ctx.query_string.username; + payload.password = uam.password(uam.md5(portal.config.uam.challenge, ctx.format_mac), ctx.query_string.password, portal.config.uam.uam_secret); + } else + include('error.uc', ctx); - let reply = portal.radius_call(ctx, payload); - if (reply['access-accept']) { - portal.allow_client(ctx); - return; - } + let radius = portal.radius_call(ctx, payload); + if (radius['access-accept']) { + portal.allow_client(ctx, { radius: { reply: radius.reply, request: payload } } ); + + payload = portal.radius_init(ctx, payload.acct_session); + payload.acct = true; + payload.username = ctx.query_string.username; + payload.acct_type = 1; + portal.radius_call(ctx, payload); + return; + } include('error.uc', ctx); } -global.handle_request = function(env) { - let ctx = portal.handle_request(env); +// disconnect client +function deauth_client(ctx) { + portal.logoff(ctx); +} - if (ctx) +global.handle_request = function(env) { + let ctx = portal.handle_request(env, true); + + switch (split(ctx.env.REQUEST_URI, '?')[0] || '') { + case '/logon': auth_client(ctx); + break; + case '/logoff': + deauth_client(ctx); + break; + default: + include('error.uc', ctx); + break; + } }; %} diff --git a/feeds/ucentral/uspot/files/usr/share/uspot/handler.uc b/feeds/ucentral/uspot/files/usr/share/uspot/handler.uc index 5a7d444e5..a629b9aa4 100644 --- a/feeds/ucentral/uspot/files/usr/share/uspot/handler.uc +++ b/feeds/ucentral/uspot/files/usr/share/uspot/handler.uc @@ -7,6 +7,7 @@ let portal = require('common'); // delegate an initial connection to the correct handler function request_start(ctx) { + portal.debug(ctx, 'start ' + (portal.config?.config?.auth_mode || '') + ' flow'); switch (portal.config?.config?.auth_mode) { case 'click-to-continue': include('click.uc', ctx); @@ -22,12 +23,14 @@ function request_start(ctx) { '?res=notyet' + '&uamip=' + ctx.env.SERVER_ADDR + '&uamport=' + portal.config.uam.uam_port + - '&challenge=' + portal.uam.md5(portal.config.uam.challenge, ctx.mac) + - '&mac=' + replace(ctx.mac, ':', '-') + + '&challenge=' + portal.uam.md5(portal.config.uam.challenge, ctx.format_mac) + + '&mac=' + ctx.format_mac + '&ip=' + ctx.env.REMOTE_ADDR + '&called=' + portal.config.uam.nasmac + - '&nasid=' + portal.config.uam.nasid; - ctx.redir_location += '&md=' + portal.uam.md5(ctx.uam_location, portal.config.uam.uam_secret); + '&nasid=' + portal.config.uam.nasid + + '&ssid=' + ctx.ssid; + if (portal.config.uam.uam_secret) + ctx.redir_location += '&md=' + portal.uam.md5(ctx.redir_location, portal.config.uam.uam_secret); include('redir.uc', ctx); return; default: @@ -46,6 +49,7 @@ function request_click(ctx) { // check if a username and password was provided if (ctx.form_data.accept_terms != 'clicked') { + portal.debug(ctx, 'user did not accept conditions'); request_start({ ...ctx, error: 1 }); return; } @@ -62,6 +66,7 @@ function request_credentials(ctx) { // check if a username and password was provided if (!ctx.form_data.username || !ctx.form_data.password) { + portal.debug(ctx, 'missing credentials\n'); request_start({ ...ctx, error: 1 }); return; } @@ -76,11 +81,12 @@ function request_credentials(ctx) { ctx.form_data.password != cred.password) continue; - portal.allow_client(ctx); + portal.allow_client(ctx, { username: ctx.form_data.username }); return; } // auth failed + portal.debug(ctx, 'invalid credentials\n'); request_start({ ...ctx, error: 1 }); } @@ -94,23 +100,25 @@ function request_radius(ctx) { // check if a username and password was provided if (!ctx.form_data.username || !ctx.form_data.password) { + portal.debug(ctx, 'missing credentials\n'); request_start({ ...ctx, error: 1 }); return; } // trigger the radius auth - let payload = radius_init(ctx); + let payload = portal.radius_init(ctx); payload.type = 'auth'; payload.username = ctx.form_data.username; payload.password = ctx.form_data.password; - let reply = portal.radius_call(ctx, payload); - if (reply['access-accept']) { - portal.allow_client(ctx); + let radius = portal.radius_call(ctx, payload); + if (radius['access-accept']) { + portal.allow_client(ctx, { username: ctx.form_data.username, radius: { reply: radius.reply, request: payload } } ); return; } // auth failed + portal.debug(ctx, 'invalid credentials\n'); request_start({ ...ctx, error: 1 }); } diff --git a/feeds/ucentral/uspot/files/usr/share/uspot/logoff.uc b/feeds/ucentral/uspot/files/usr/share/uspot/logoff.uc new file mode 100644 index 000000000..302c936b6 --- /dev/null +++ b/feeds/ucentral/uspot/files/usr/share/uspot/logoff.uc @@ -0,0 +1,4 @@ +Status: 200 OK +Content-Type: text/html + +

You are now logged-off

diff --git a/feeds/ucentral/uspot/src/radius.c b/feeds/ucentral/uspot/src/radius.c index f11b98eee..d55fc31d6 100644 --- a/feeds/ucentral/uspot/src/radius.c +++ b/feeds/ucentral/uspot/src/radius.c @@ -9,8 +9,10 @@ #include enum { - RADIUS_TYPE, + RADIUS_ACCT, RADIUS_SERVER, + RADIUS_ACCT_SERVER, + RADIUS_ACCT_TYPE, RADIUS_USERNAME, RADIUS_PASSWORD, RADIUS_CHAP_PASSWORD, @@ -21,12 +23,23 @@ enum { RADIUS_CALLING_STATION, RADIUS_NAS_IP, RADIUS_NAS_ID, + RADIUS_TERMINATE_CAUSE, + RADIUS_SESSION_TIME, + RADIUS_INPUT_OCTETS, + RADIUS_OUTPUT_OCTETS, + RADIUS_INPUT_GIGAWORDS, + RADIUS_OUTPUT_GIGAWORDS, + RADIUS_INPUT_PACKETS, + RADIUS_OUTPUT_PACKETS, + RADIUS_LOGOFF_URL, __RADIUS_MAX, }; static const struct blobmsg_policy radius_policy[__RADIUS_MAX] = { - [RADIUS_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING }, + [RADIUS_ACCT] = { .name = "acct", .type = BLOBMSG_TYPE_BOOL }, [RADIUS_SERVER] = { .name = "server", .type = BLOBMSG_TYPE_STRING }, + [RADIUS_ACCT_SERVER] = { .name = "acct_server", .type = BLOBMSG_TYPE_STRING }, + [RADIUS_ACCT_TYPE] = { .name = "acct_type", .type = BLOBMSG_TYPE_INT32 }, [RADIUS_USERNAME] = { .name = "username", .type = BLOBMSG_TYPE_STRING }, [RADIUS_PASSWORD] = { .name = "password", .type = BLOBMSG_TYPE_STRING }, [RADIUS_CHAP_PASSWORD] = { .name = "chap_password", .type = BLOBMSG_TYPE_STRING }, @@ -37,23 +50,17 @@ static const struct blobmsg_policy radius_policy[__RADIUS_MAX] = { [RADIUS_CALLING_STATION] = { .name = "calling_station", .type = BLOBMSG_TYPE_STRING }, [RADIUS_NAS_IP] = { .name = "nas_ip", .type = BLOBMSG_TYPE_STRING }, [RADIUS_NAS_ID] = { .name = "nas_id", .type = BLOBMSG_TYPE_STRING }, + [RADIUS_TERMINATE_CAUSE] = { .name = "terminate_cause", .type = BLOBMSG_TYPE_INT32 }, + [RADIUS_SESSION_TIME] = { .name = "session_time", .type = BLOBMSG_TYPE_INT32 }, + [RADIUS_INPUT_OCTETS] = { .name = "input_octets", .type = BLOBMSG_TYPE_INT32 }, + [RADIUS_OUTPUT_OCTETS] = { .name = "output_octets", .type = BLOBMSG_TYPE_INT32 }, + [RADIUS_INPUT_GIGAWORDS] = { .name = "input_gigawords", .type = BLOBMSG_TYPE_INT32 }, + [RADIUS_OUTPUT_GIGAWORDS] = { .name = "output_gigawords", .type = BLOBMSG_TYPE_INT32 }, + [RADIUS_INPUT_PACKETS] = { .name = "input_packets", .type = BLOBMSG_TYPE_INT32 }, + [RADIUS_OUTPUT_PACKETS] = { .name = "output_packets", .type = BLOBMSG_TYPE_INT32 }, + [RADIUS_LOGOFF_URL] = { .name = "logoff_url", .type = BLOBMSG_TYPE_STRING }, }; -static struct config { - char *type; - char *server; - char *username; - char *password; - char chap_password[17]; - char chap_challenge[16]; - char *acct_session; - struct sockaddr_in client_ip; - char *called_station; - char *calling_station; - struct sockaddr_in nas_ip; - char *nas_id; -} config; - static struct blob_buf b = {}; static struct blob_attr *tb[__RADIUS_MAX] = {}; @@ -104,266 +111,158 @@ result(rc_handle const *rh, int accept, VALUE_PAIR *pair) return accept; } -static void -config_load(void) -{ - if (tb[RADIUS_TYPE]) - config.type = blobmsg_get_string(tb[RADIUS_TYPE]); - - if (tb[RADIUS_SERVER]) - config.server = blobmsg_get_string(tb[RADIUS_SERVER]); - - if (tb[RADIUS_USERNAME]) - config.username = blobmsg_get_string(tb[RADIUS_USERNAME]); - - if (tb[RADIUS_PASSWORD]) - config.password = blobmsg_get_string(tb[RADIUS_PASSWORD]); - - if (tb[RADIUS_CHAP_PASSWORD]) { - *config.chap_password = '\0'; - str_to_hex(blobmsg_get_string(tb[RADIUS_CHAP_PASSWORD]), &config.chap_password[1], 16); - } - - if (tb[RADIUS_CHAP_CHALLENGE]) - str_to_hex(blobmsg_get_string(tb[RADIUS_CHAP_CHALLENGE]), config.chap_challenge, 16); - - if (tb[RADIUS_ACCT_SESSION]) - config.acct_session = blobmsg_get_string(tb[RADIUS_ACCT_SESSION]); - - if (tb[RADIUS_CLIENT_IP]) { - inet_pton(AF_INET, blobmsg_get_string(tb[RADIUS_CLIENT_IP]), &(config.client_ip.sin_addr)); - config.client_ip.sin_addr.s_addr = ntohl(config.client_ip.sin_addr.s_addr); - } - - if (tb[RADIUS_CALLED_STATION]) - config.called_station = blobmsg_get_string(tb[RADIUS_CALLED_STATION]); - - if (tb[RADIUS_CALLING_STATION]) - config.calling_station = blobmsg_get_string(tb[RADIUS_CALLING_STATION]); - - if (tb[RADIUS_NAS_IP]) { - inet_pton(AF_INET, blobmsg_get_string(tb[RADIUS_NAS_IP]), &(config.nas_ip.sin_addr)); - config.nas_ip.sin_addr.s_addr = ntohl(config.nas_ip.sin_addr.s_addr); - } - - if (tb[RADIUS_NAS_ID]) - config.nas_id = blobmsg_get_string(tb[RADIUS_NAS_ID]); -} - -static rc_handle * -radius_init(void) +static int +radius(void) { + VALUE_PAIR *send = NULL, *received; + struct sockaddr_in client_ip = {}; + struct sockaddr_in nas_ip = {}; + char chap_challenge[16] = {}; + char chap_password[17] = {}; rc_handle *rh = rc_new(); + uint32_t val; + if (rh == NULL) - return NULL; + return result(rh, 0, NULL);; rh = rc_config_init(rh); if (rh == NULL) - return NULL; + return result(rh, 0, NULL);; - rc_add_config(rh, "authserver", config.server, "code", __LINE__); + if (tb[RADIUS_SERVER]) + rc_add_config(rh, "authserver", blobmsg_get_string(tb[RADIUS_SERVER]), "code", __LINE__); + + if (tb[RADIUS_ACCT_SERVER]) + rc_add_config(rh, "acctserver", blobmsg_get_string(tb[RADIUS_ACCT_SERVER]), "code", __LINE__); rc_add_config(rh, "servers", "/tmp/radius.servers", "code", __LINE__); rc_add_config(rh, "dictionary", "/etc/radcli/dictionary", "code", __LINE__); - rc_add_config(rh, "radius_timeout", "5", "code", __LINE__); + rc_add_config(rh, "radius_timeout", "2", "code", __LINE__); rc_add_config(rh, "radius_retries", "1", "code", __LINE__); rc_add_config(rh, "bindaddr", "*", "code", __LINE__); if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0) - return NULL; - - return rh; -} - -static int -auth(void) -{ - VALUE_PAIR *send = NULL, *received; - rc_handle *rh = NULL; - - if (!config.server || !config.username || !config.password) - return result(NULL, 0, NULL); - - rh = radius_init(); - if (!rh) - return result(NULL, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_USER_NAME, config.username, -1, 0) == NULL) return result(rh, 0, NULL); - if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, config.password, -1, 0) == NULL) + if (tb[RADIUS_ACCT_TYPE]) { + val = blobmsg_get_u32(tb[RADIUS_ACCT_TYPE]); + if (rc_avpair_add(rh, &send, PW_ACCT_STATUS_TYPE, &val, 4, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_USERNAME]) + if (rc_avpair_add(rh, &send, PW_USER_NAME, blobmsg_get_string(tb[RADIUS_USERNAME]), -1, 0) == NULL) + return result(rh, 0, NULL); + + if (tb[RADIUS_PASSWORD]) + if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, blobmsg_get_string(tb[RADIUS_PASSWORD]), -1, 0) == NULL) + return result(rh, 0, NULL); + + if (tb[RADIUS_CHAP_PASSWORD]) { + str_to_hex(blobmsg_get_string(tb[RADIUS_CHAP_PASSWORD]), &chap_password[1], 16); + if (rc_avpair_add(rh, &send, PW_CHAP_PASSWORD, chap_password, 17, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_CHAP_CHALLENGE]) { + str_to_hex(blobmsg_get_string(tb[RADIUS_CHAP_CHALLENGE]), chap_challenge, 16); + if (rc_avpair_add(rh, &send, PW_CHAP_CHALLENGE, chap_challenge, 16, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_ACCT_SESSION]) + if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_ID, blobmsg_get_string(tb[RADIUS_ACCT_SESSION]), -1, 0) == NULL) + return result(rh, 0, NULL); + + if (tb[RADIUS_CLIENT_IP]) { + inet_pton(AF_INET, blobmsg_get_string(tb[RADIUS_CLIENT_IP]), &(client_ip.sin_addr)); + client_ip.sin_addr.s_addr = ntohl(client_ip.sin_addr.s_addr); + if (rc_avpair_add(rh, &send, PW_FRAMED_IP_ADDRESS, &client_ip.sin_addr, 4, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_CALLED_STATION]) + if (rc_avpair_add(rh, &send, PW_CALLED_STATION_ID, blobmsg_get_string(tb[RADIUS_CALLED_STATION]), -1, 0) == NULL) + return result(rh, 0, NULL); + + if (tb[RADIUS_LOGOFF_URL]) + if (rc_avpair_add(rh, &send, 3, blobmsg_get_string(tb[RADIUS_LOGOFF_URL]), -1, 14122) == NULL) + return result(rh, 0, NULL); + + if (tb[RADIUS_CALLING_STATION]) + if (rc_avpair_add(rh, &send, PW_CALLING_STATION_ID, blobmsg_get_string(tb[RADIUS_CALLING_STATION]), -1, 0) == NULL) + return result(rh, 0, NULL); + + if (tb[RADIUS_NAS_IP]) { + inet_pton(AF_INET, blobmsg_get_string(tb[RADIUS_NAS_IP]), &(nas_ip.sin_addr)); + nas_ip.sin_addr.s_addr = ntohl(nas_ip.sin_addr.s_addr); + if (rc_avpair_add(rh, &send, PW_NAS_IP_ADDRESS, &nas_ip.sin_addr, 4, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_NAS_ID]) + if (rc_avpair_add(rh, &send, PW_NAS_IDENTIFIER, blobmsg_get_string(tb[RADIUS_NAS_ID]), -1, 0) == NULL) + return result(rh, 0, NULL); + + if (tb[RADIUS_TERMINATE_CAUSE]) { + val = blobmsg_get_u32(tb[RADIUS_TERMINATE_CAUSE]); + if (rc_avpair_add(rh, &send, PW_ACCT_TERMINATE_CAUSE, &val, 4, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_SESSION_TIME]) { + val = blobmsg_get_u32(tb[RADIUS_SESSION_TIME]); + if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_TIME, &val, 4, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_INPUT_OCTETS]) { + val = blobmsg_get_u32(tb[RADIUS_INPUT_OCTETS]); + if (rc_avpair_add(rh, &send, PW_ACCT_INPUT_OCTETS, &val, 4, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_OUTPUT_OCTETS]) { + val = blobmsg_get_u32(tb[RADIUS_OUTPUT_OCTETS]); + if (rc_avpair_add(rh, &send, PW_ACCT_OUTPUT_OCTETS, &val, 4, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_INPUT_GIGAWORDS]) { + val = blobmsg_get_u32(tb[RADIUS_INPUT_GIGAWORDS]); + if (rc_avpair_add(rh, &send, PW_ACCT_INPUT_GIGAWORDS, &val, 4, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_OUTPUT_GIGAWORDS]) { + val = blobmsg_get_u32(tb[RADIUS_OUTPUT_GIGAWORDS]); + if (rc_avpair_add(rh, &send, PW_ACCT_OUTPUT_GIGAWORDS, &val, 4, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_INPUT_PACKETS]) { + val = blobmsg_get_u32(tb[RADIUS_INPUT_PACKETS]); + if (rc_avpair_add(rh, &send, PW_ACCT_INPUT_PACKETS, &val, 4, 0) == NULL) + return result(rh, 0, NULL); + } + + if (tb[RADIUS_OUTPUT_PACKETS]) { + val = blobmsg_get_u32(tb[RADIUS_OUTPUT_PACKETS]); + if (rc_avpair_add(rh, &send, PW_ACCT_OUTPUT_PACKETS, &val, 4, 0) == NULL) + return result(rh, 0, NULL); + } + + val = 19; + if (rc_avpair_add(rh, &send, PW_NAS_PORT_TYPE, &val, 4, 0) == NULL) return result(rh, 0, NULL); rc_apply_config(rh); - if (rc_auth(rh, 0, send, &received, NULL) == OK_RC) - return result(rh, 1, received); - - return result(rh, 0, NULL); -} - -static int -uam_auth(void) -{ - VALUE_PAIR *send = NULL, *received; - rc_handle *rh = NULL; - - if (!config.server || !config.username || !config.password || - !config.acct_session || !config.called_station || - !config.calling_station || !config.nas_id) - return result(NULL, 0, NULL); - - rh = radius_init(); - if (!rh) - return result(NULL, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_USER_NAME, config.username, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, config.password, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_ID, config.acct_session, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_FRAMED_IP_ADDRESS, &config.client_ip.sin_addr, 4, 0) == NULL) - return result(rh, 0, NULL); - - //if (rc_avpair_add(rh, &send, PW_NAS_PORT_TYPE, , -1, 0) == NULL) - // return result(rh, 0, NULL); - - //if (rc_avpair_add(rh, &send, PW_NAS_PORT, , -1, 0) == NULL) - // return result(rh, 0, NULL); - -// if (rc_avpair_add(rh, &send, PW_NAS_PORT_ID_STRING, , -1, 0) == NULL) -// return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_CALLED_STATION_ID, config.called_station, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_CALLING_STATION_ID, config.calling_station, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_NAS_IP_ADDRESS, &config.nas_ip.sin_addr, 4, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_NAS_IDENTIFIER, config.nas_id, -1, 0) == NULL) - return result(rh, 0, NULL); - - rc_apply_config(rh); - if (rc_auth(rh, 0, send, &received, NULL) == OK_RC) - return result(rh, 1, received); - - return result(rh, 0, NULL); -} - -static int -uam_chap_auth(void) -{ - VALUE_PAIR *send = NULL, *received; - rc_handle *rh = NULL; - - if (!config.server || !config.username || - !config.acct_session || !config.called_station || - !config.calling_station || !config.nas_id) - return result(NULL, 0, NULL); - - rh = radius_init(); - if (!rh) - return result(NULL, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_USER_NAME, config.username, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_CHAP_PASSWORD, config.chap_password, 17, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_CHAP_CHALLENGE, config.chap_challenge, 16, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_ID, config.acct_session, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_FRAMED_IP_ADDRESS, &config.client_ip.sin_addr, 4, 0) == NULL) - return result(rh, 0, NULL); - - //if (rc_avpair_add(rh, &send, PW_NAS_PORT_TYPE, , -1, 0) == NULL) - // return result(rh, 0, NULL); - - //if (rc_avpair_add(rh, &send, PW_NAS_PORT, , -1, 0) == NULL) - // return result(rh, 0, NULL); - -// if (rc_avpair_add(rh, &send, PW_NAS_PORT_ID_STRING, , -1, 0) == NULL) -// return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_CALLED_STATION_ID, config.called_station, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_CALLING_STATION_ID, config.calling_station, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_NAS_IP_ADDRESS, &config.nas_ip.sin_addr, 4, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_NAS_IDENTIFIER, config.nas_id, -1, 0) == NULL) - return result(rh, 0, NULL); - - rc_apply_config(rh); - if (rc_auth(rh, 0, send, &received, NULL) == OK_RC) - return result(rh, 1, received); - - return result(rh, 0, NULL); -} - -static int -uam_acct(void) -{ - VALUE_PAIR *send = NULL, *received; - rc_handle *rh = NULL; - - if (!config.server || !config.username || !config.password || - !config.acct_session || !config.called_station || - !config.calling_station || !config.nas_id) - return result(NULL, 0, NULL); - - rh = radius_init(); - if (!rh) - return result(NULL, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_USER_NAME, config.username, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, config.password, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_ACCT_SESSION_ID, config.acct_session, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_FRAMED_IP_ADDRESS, &config.client_ip.sin_addr, 4, 0) == NULL) - return result(rh, 0, NULL); - - //if (rc_avpair_add(rh, &send, PW_NAS_PORT_TYPE, , -1, 0) == NULL) - // return result(rh, 0, NULL); - - //if (rc_avpair_add(rh, &send, PW_NAS_PORT, , -1, 0) == NULL) - // return result(rh, 0, NULL); - -// if (rc_avpair_add(rh, &send, PW_NAS_PORT_ID_STRING, , -1, 0) == NULL) -// return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_CALLED_STATION_ID, config.called_station, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_CALLING_STATION_ID, config.calling_station, -1, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_NAS_IP_ADDRESS, &config.nas_ip.sin_addr, 4, 0) == NULL) - return result(rh, 0, NULL); - - if (rc_avpair_add(rh, &send, PW_NAS_IDENTIFIER, config.nas_id, -1, 0) == NULL) - return result(rh, 0, NULL); - - rc_apply_config(rh); - if (rc_auth(rh, 0, send, &received, NULL) == OK_RC) - return result(rh, 1, received); + if (tb[RADIUS_ACCT] && blobmsg_get_bool(tb[RADIUS_ACCT])) { + if (rc_acct(rh, 0, send) == OK_RC) + return result(rh, 1, NULL); + } else { + if (rc_auth(rh, 0, send, &received, NULL) == OK_RC) + return result(rh, 1, received); + } return result(rh, 0, NULL); } @@ -380,21 +279,5 @@ main(int argc, char **argv) blobmsg_parse(radius_policy, __RADIUS_MAX, tb, blob_data(b.head), blob_len(b.head)); - config_load(); - if (!config.type) - return result(NULL, 0, NULL); - - if (!strcmp(config.type, "auth")) - return auth(); - - if (!strcmp(config.type, "uam-auth")) - return uam_auth(); - - if (!strcmp(config.type, "uam-chap-auth")) - return uam_chap_auth(); - - if (!strcmp(config.type, "uam-acct")) - return uam_acct(); - - return result(NULL, 0, NULL); + return radius(); } From 736ab2b803fd420afd481ecaabaf844a19afaba0 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 3 Oct 2022 08:45:03 +0200 Subject: [PATCH 8/9] uhttpd: update to latest HEAD Fixes: WIFI-10665 Signed-off-by: John Crispin --- .../base/0025-uhttpd-backport-2-fixes.patch | 207 ------------------ .../0025-uhttpd-update-to-latest-HEAD.patch | 31 +-- 2 files changed, 16 insertions(+), 222 deletions(-) delete mode 100644 patches/base/0025-uhttpd-backport-2-fixes.patch diff --git a/patches/base/0025-uhttpd-backport-2-fixes.patch b/patches/base/0025-uhttpd-backport-2-fixes.patch deleted file mode 100644 index 5b4039e4e..000000000 --- a/patches/base/0025-uhttpd-backport-2-fixes.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 2238d38eca53468d8a52209478f801580a54c1ed Mon Sep 17 00:00:00 2001 -From: John Crispin -Date: Wed, 17 Aug 2022 16:31:37 +0200 -Subject: [PATCH] uhttpd: backport 2 fixes - -Signed-off-by: John Crispin ---- - .../services/uhttpd/patches/error.patch | 165 ++++++++++++++++++ - .../services/uhttpd/patches/path.patch | 14 ++ - 2 files changed, 179 insertions(+) - create mode 100644 package/network/services/uhttpd/patches/error.patch - create mode 100644 package/network/services/uhttpd/patches/path.patch - -diff --git a/package/network/services/uhttpd/patches/error.patch b/package/network/services/uhttpd/patches/error.patch -new file mode 100644 -index 0000000000..374aca0a51 ---- /dev/null -+++ b/package/network/services/uhttpd/patches/error.patch -@@ -0,0 +1,165 @@ -+From c5eac5d27fb3967d796fe3c75f4cc1bdcd18ed01 Mon Sep 17 00:00:00 2001 -+From: Jo-Philipp Wich -+Date: Wed, 10 Aug 2022 21:00:32 +0200 -+Subject: [PATCH] file: support using dynamic script handlers as error pages -+ -+Rework the current request handler code to not require an error page path -+to be an actual file system entity. -+ -+Signed-off-by: Jo-Philipp Wich -+--- -+ file.c | 42 ++++++++++++++++++++++++++---------------- -+ 1 file changed, 26 insertions(+), 16 deletions(-) -+ -+diff --git a/file.c b/file.c -+index 1548900..ac781c1 100644 -+--- a/file.c -++++ b/file.c -+@@ -49,6 +49,7 @@ struct deferred_request { -+ struct dispatch_handler *d; -+ struct client *cl; -+ struct path_info pi; -++ char *url; -+ bool called, path; -+ }; -+ -+@@ -631,7 +632,7 @@ static void uh_file_data(struct client *cl, struct path_info *pi, int fd) -+ file_write_cb(cl); -+ } -+ -+-static bool __handle_file_request(struct client *cl, char *url); -++static bool __handle_file_request(struct client *cl, char *url, bool is_error_handler); -+ -+ static void uh_file_request(struct client *cl, const char *url, -+ struct path_info *pi, struct blob_attr **tb) -+@@ -684,7 +685,7 @@ error: -+ req->redirect_status = 403; -+ error_handler = alloca(strlen(conf.error_handler) + 1); -+ strcpy(error_handler, conf.error_handler); -+- if (__handle_file_request(cl, error_handler)) -++ if (__handle_file_request(cl, error_handler, true)) -+ return; -+ } -+ -+@@ -728,10 +729,8 @@ dispatch_find(const char *url, struct path_info *pi) -+ } -+ -+ static void -+-uh_invoke_script(struct client *cl, struct dispatch_handler *d, struct path_info *pi) -++uh_invoke_script(struct client *cl, struct dispatch_handler *d, char *url, struct path_info *pi) -+ { -+- char *url = blobmsg_data(blob_data(cl->hdr.head)); -+- -+ n_requests++; -+ d->handle_request(cl, url, pi); -+ } -+@@ -752,7 +751,7 @@ static void uh_complete_request(struct client *cl) -+ cl = dr->cl; -+ dr->called = true; -+ cl->dispatch.data_blocked = false; -+- uh_invoke_script(cl, dr->d, dr->path ? &dr->pi : NULL); -++ uh_invoke_script(cl, dr->d, dr->url, dr->path ? &dr->pi : NULL); -+ client_poll_post_data(cl); -+ ustream_poll(cl->us); -+ } -+@@ -787,10 +786,10 @@ static int field_len(const char *ptr) -+ _field(query) -+ -+ static void -+-uh_defer_script(struct client *cl, struct dispatch_handler *d, struct path_info *pi) -++uh_defer_script(struct client *cl, struct dispatch_handler *d, char *url, struct path_info *pi) -+ { -+ struct deferred_request *dr; -+- char *_root, *_phys, *_name, *_info, *_query; -++ char *_url, *_root, *_phys, *_name, *_info, *_query; -+ -+ cl->dispatch.req_free = uh_free_pending_request; -+ -+@@ -798,7 +797,7 @@ uh_defer_script(struct client *cl, struct dispatch_handler *d, struct path_info -+ /* allocate enough memory to duplicate all path_info strings in one block */ -+ #undef _field -+ #define _field(_name) &_##_name, field_len(pi->_name), -+- dr = calloc_a(sizeof(*dr), path_info_fields NULL); -++ dr = calloc_a(sizeof(*dr), &_url, strlen(url), path_info_fields NULL); -+ -+ memcpy(&dr->pi, pi, sizeof(*pi)); -+ dr->path = true; -+@@ -808,11 +807,12 @@ uh_defer_script(struct client *cl, struct dispatch_handler *d, struct path_info -+ #define _field(_name) if (pi->_name) dr->pi._name = strcpy(_##_name, pi->_name); -+ path_info_fields -+ } else { -+- dr = calloc(1, sizeof(*dr)); -++ dr = calloc_a(sizeof(*dr), &_url, strlen(url), NULL); -+ } -+ -+ cl->dispatch.req_data = dr; -+ cl->dispatch.data_blocked = true; -++ dr->url = strcpy(_url, url); -+ dr->cl = cl; -+ dr->d = d; -+ list_add(&dr->list, &pending_requests); -+@@ -825,13 +825,13 @@ uh_invoke_handler(struct client *cl, struct dispatch_handler *d, char *url, stru -+ return d->handle_request(cl, url, pi); -+ -+ if (n_requests >= conf.max_script_requests) -+- return uh_defer_script(cl, d, pi); -++ return uh_defer_script(cl, d, url, pi); -+ -+ cl->dispatch.req_free = uh_complete_request; -+- uh_invoke_script(cl, d, pi); -++ uh_invoke_script(cl, d, url, pi); -+ } -+ -+-static bool __handle_file_request(struct client *cl, char *url) -++static bool __handle_file_request(struct client *cl, char *url, bool is_error_handler) -+ { -+ static const struct blobmsg_policy hdr_policy[__HDR_MAX] = { -+ [HDR_AUTHORIZATION] = { "authorization", BLOBMSG_TYPE_STRING }, -+@@ -846,6 +846,16 @@ static bool __handle_file_request(struct client *cl, char *url) -+ struct path_info *pi; -+ char *user, *pass, *auth; -+ -++ if (is_error_handler) { -++ d = dispatch_find(url, NULL); -++ -++ if (d) { -++ uh_invoke_handler(cl, d, url, NULL); -++ -++ return true; -++ } -++ } -++ -+ pi = uh_path_lookup(cl, url); -+ if (!pi) -+ return false; -+@@ -931,7 +941,7 @@ void uh_handle_request(struct client *cl) -+ if (d) -+ return uh_invoke_handler(cl, d, url, NULL); -+ -+- if (__handle_file_request(cl, url)) -++ if (__handle_file_request(cl, url, false)) -+ return; -+ -+ if (uh_handler_run(cl, &url, true)) { -+@@ -939,7 +949,7 @@ void uh_handle_request(struct client *cl) -+ return; -+ -+ uh_handler_run(cl, &url, false); -+- if (__handle_file_request(cl, url)) -++ if (__handle_file_request(cl, url, false)) -+ return; -+ } -+ -+@@ -947,7 +957,7 @@ void uh_handle_request(struct client *cl) -+ if (conf.error_handler) { -+ error_handler = alloca(strlen(conf.error_handler) + 1); -+ strcpy(error_handler, conf.error_handler); -+- if (__handle_file_request(cl, error_handler)) -++ if (__handle_file_request(cl, error_handler, true)) -+ return; -+ } -+ -+-- -+2.35.1 -+ -+ -diff --git a/package/network/services/uhttpd/patches/path.patch b/package/network/services/uhttpd/patches/path.patch -new file mode 100644 -index 0000000000..27eebb56d8 ---- /dev/null -+++ b/package/network/services/uhttpd/patches/path.patch -@@ -0,0 +1,14 @@ -+diff --git a/utils.c b/utils.c -+index 142a410..6502d94 100644 -+--- a/utils.c -++++ b/utils.c -+@@ -215,7 +215,7 @@ bool uh_path_match(const char *prefix, const char *url) -+ if (strncmp(url, prefix, len) != 0) -+ return false; -+ -+- return url[len] == '/' || url[len] == 0; -++ return url[len] == '/' || url[len] == '?' || url[len] == 0; -+ } -+ -+ char *uh_split_header(char *str) -+ --- -2.25.1 - diff --git a/patches/base/0025-uhttpd-update-to-latest-HEAD.patch b/patches/base/0025-uhttpd-update-to-latest-HEAD.patch index 30a8f8777..96f3a377e 100644 --- a/patches/base/0025-uhttpd-update-to-latest-HEAD.patch +++ b/patches/base/0025-uhttpd-update-to-latest-HEAD.patch @@ -1,20 +1,24 @@ -From 3cd6c3dc3cb38799bce6e728d3794d50b829678b Mon Sep 17 00:00:00 2001 +From 3a4a31f26f1699b9a4a7d6684a380a990bb9ac86 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 10 Aug 2022 09:50:13 +0200 -Subject: [PATCH] uhttpd: update to latest HEAD +Subject: [PATCH 85/85] uhttpd: update to latest HEAD Signed-off-by: John Crispin --- - package/network/services/uhttpd/Makefile | 44 ++++++++++++++----- - .../services/uhttpd/files/uhttpd.config | 8 ++++ - .../network/services/uhttpd/files/uhttpd.init | 15 +++++++ - 3 files changed, 57 insertions(+), 10 deletions(-) + package/network/services/uhttpd/Makefile | 43 +++-- + .../services/uhttpd/files/uhttpd.config | 8 + + .../network/services/uhttpd/files/uhttpd.init | 15 ++ + .../services/uhttpd/patches/error.patch | 165 ------------------ + .../services/uhttpd/patches/path.patch | 14 -- + 5 files changed, 56 insertions(+), 189 deletions(-) + delete mode 100644 package/network/services/uhttpd/patches/error.patch + delete mode 100644 package/network/services/uhttpd/patches/path.patch diff --git a/package/network/services/uhttpd/Makefile b/package/network/services/uhttpd/Makefile -index de666a480d..860b41f1a4 100644 +index de666a480d..0ae076ca8b 100644 --- a/package/network/services/uhttpd/Makefile +++ b/package/network/services/uhttpd/Makefile -@@ -8,19 +8,19 @@ +@@ -8,19 +8,18 @@ include $(TOPDIR)/rules.mk PKG_NAME:=uhttpd @@ -27,8 +31,7 @@ index de666a480d..860b41f1a4 100644 -PKG_SOURCE_VERSION:=15346de8d3ba422002496526ee24c62a3601ab8c -PKG_MIRROR_HASH:=819424d071ed7c8888f9ca66f679907831becc59a67dd4a5ec521d5fba0a3171 +PKG_SOURCE_DATE:=2022-06-01 -+PKG_SOURCE_VERSION:=d59d732a10a4a2b9f18af6dfc3facf696108f31e -+PKG_MIRROR_HASH:=31caa46ca025a1a7657bd5252d59d4a67d0f1c4b87c15a1bc94663ba3cc899ee ++PKG_SOURCE_VERSION:=e3395cd90bed9b7b9fc319e79528fedcc0d947fe PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=ISC @@ -39,7 +42,7 @@ index de666a480d..860b41f1a4 100644 include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/cmake.mk -@@ -49,8 +49,20 @@ define Package/uhttpd/config +@@ -49,8 +48,20 @@ define Package/uhttpd/config depends on PACKAGE_uhttpd-mod-lua bool "Enable Integrated Lua interpreter" default y @@ -60,7 +63,7 @@ index de666a480d..860b41f1a4 100644 define Package/uhttpd-mod-lua $(Package/uhttpd/default) TITLE+= (Lua plugin) -@@ -73,19 +85,25 @@ define Package/uhttpd-mod-ubus/description +@@ -73,19 +84,25 @@ define Package/uhttpd-mod-ubus/description session.* namespace and procedures. endef @@ -91,7 +94,7 @@ index de666a480d..860b41f1a4 100644 define Package/uhttpd/install $(INSTALL_DIR) $(1)/etc/init.d -@@ -108,7 +126,13 @@ define Package/uhttpd-mod-ubus/install +@@ -108,7 +125,13 @@ define Package/uhttpd-mod-ubus/install $(INSTALL_DATA) ./files/ubus.default $(1)/etc/uci-defaults/00_uhttpd_ubus endef @@ -157,6 +160,4 @@ index 30fd7b4259..8dbc23f59c 100755 append_arg "$cfg" script_timeout "-t" append_arg "$cfg" network_timeout "-T" append_arg "$cfg" http_keepalive "-k" --- -2.25.1 From a4b663b824ae0e784bd3f48fcde7a2cebfa89d94 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Mon, 3 Oct 2022 08:45:35 +0200 Subject: [PATCH 9/9] ucentral-schema: update to latest HEAD 329dffa add captive portal info to state messages f3ee560 start the uspot service if captive is enabled 7da0185 allow defining the format of MAC sent to AAA in captive mode 2dfbeff rename wlancaptive -> wlanc, netdev name got too long when creating the IFB device 1784f7e add 'none' mode to wifi-steering abeb712 broadband: the DNS was not getting applied in static configuration 0fbe7d5 various captive portal improvements Fixes: WIFI-10665 Signed-off-by: John Crispin --- feeds/ucentral/ucentral-schema/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feeds/ucentral/ucentral-schema/Makefile b/feeds/ucentral/ucentral-schema/Makefile index 7d491b415..694393bbe 100644 --- a/feeds/ucentral/ucentral-schema/Makefile +++ b/feeds/ucentral/ucentral-schema/Makefile @@ -4,9 +4,10 @@ PKG_NAME:=ucentral-schema PKG_RELEASE:=1 PKG_SOURCE_URL=https://github.com/Telecominfraproject/wlan-ucentral-schema.git +PKG_MIRROR_HASH:=ebad6fff601a64d3d87778a7413cdd308ed5d4a5187a7ed81070c7899d1b7013 PKG_SOURCE_PROTO:=git PKG_SOURCE_DATE:=2022-05-29 -PKG_SOURCE_VERSION:=81a74ccd8cb7a1f5dccfb11797236eb1834db461 +PKG_SOURCE_VERSION:=329dffaf4327bea8ffaa5b59d7bda918e5786150 PKG_MAINTAINER:=John Crispin PKG_LICENSE:=BSD-3-Clause